[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] master f5fd862: * externals-list: Move more :subtrees to :externa
From: |
Stefan Monnier |
Subject: |
[elpa] master f5fd862: * externals-list: Move more :subtrees to :external. |
Date: |
Fri, 27 Nov 2020 19:19:21 -0500 (EST) |
branch: master
commit f5fd86205e61950151fd2a97b9bc1bae584a36cc
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>
* externals-list: Move more :subtrees to :external.
The affected subtrees are:
aggressive-indent coffee-mode compact-docstrings company
context-coloring diffview diff-hl dts-mode eldoc-eval
f90-interface-browser ioccur js2-mode math-symbol-lists
names on-screen vcl-mode web-server websocket
---
externals-list | 36 +-
packages/aggressive-indent/README.md | 65 -
packages/aggressive-indent/aggressive-indent.el | 451 -
packages/aggressive-indent/c-example.gif | Bin 88739 -> 0 bytes
packages/aggressive-indent/lisp-example.gif | Bin 493302 -> 0 bytes
packages/coffee-mode/README.md | 284 -
packages/coffee-mode/coffee-mode.el | 640 -
packages/coffee-mode/examples/basic.coffee | 118 -
packages/coffee-mode/examples/edge.coffee | 16 -
packages/coffee-mode/examples/imenu.coffee | 33 -
packages/compact-docstrings/.gitignore | 1 -
packages/compact-docstrings/Cask | 6 -
packages/compact-docstrings/Makefile | 6 -
packages/compact-docstrings/README.rst | 23 -
packages/compact-docstrings/compact-docstrings.el | 90 -
packages/compact-docstrings/etc/after.py | 14 -
packages/compact-docstrings/etc/before.py | 14 -
.../etc/compact-docstrings-screenshot.el | 99 -
.../compact-docstrings/etc/compact-docstrings.png | Bin 25863 -> 0 bytes
packages/company/.dir-locals.el | 4 -
packages/company/.elpaignore | 5 -
packages/company/.gitignore | 2 -
packages/company/.travis.yml | 23 -
packages/company/Makefile | 31 -
packages/company/NEWS.md | 520 -
packages/company/README.md | 4 -
packages/company/company-abbrev.el | 50 -
packages/company/company-bbdb.el | 63 -
packages/company/company-capf.el | 208 -
packages/company/company-clang.el | 389 -
packages/company/company-cmake.el | 206 -
packages/company/company-css.el | 446 -
packages/company/company-dabbrev-code.el | 104 -
packages/company/company-dabbrev.el | 206 -
packages/company/company-eclim.el | 186 -
packages/company/company-elisp.el | 226 -
packages/company/company-etags.el | 108 -
packages/company/company-files.el | 151 -
packages/company/company-gtags.el | 119 -
packages/company/company-ispell.el | 82 -
packages/company/company-keywords.el | 314 -
packages/company/company-nxml.el | 143 -
packages/company/company-oddmuse.el | 57 -
packages/company/company-semantic.el | 168 -
packages/company/company-template.el | 272 -
packages/company/company-tempo.el | 71 -
packages/company/company-tests.el | 39 -
packages/company/company-tng.el | 197 -
packages/company/company-xcode.el | 123 -
packages/company/company-yasnippet.el | 176 -
packages/company/company.el | 3247 -----
packages/company/test/all.el | 30 -
packages/company/test/async-tests.el | 221 -
packages/company/test/bbdb-tests.el | 46 -
packages/company/test/capf-tests.el | 148 -
packages/company/test/clang-tests.el | 51 -
packages/company/test/cmake-tests.el | 44 -
packages/company/test/core-tests.el | 593 -
packages/company/test/elisp-tests.el | 190 -
packages/company/test/files-tests.el | 48 -
packages/company/test/frontends-tests.el | 393 -
packages/company/test/keywords-tests.el | 32 -
packages/company/test/template-tests.el | 170 -
packages/company/test/transformers-tests.el | 58 -
packages/context-coloring/.elpaignore | 10 -
packages/context-coloring/.gitignore | 6 -
packages/context-coloring/.travis.yml | 24 -
packages/context-coloring/Cask | 7 -
packages/context-coloring/LICENSE | 674 -
packages/context-coloring/Makefile | 50 -
packages/context-coloring/README.md | 68 -
.../context-coloring/context-coloring-benchmark.el | 165 -
.../context-coloring/context-coloring-coverage.el | 155 -
.../context-coloring-emacs-lisp.el | 773 --
.../context-coloring-javascript.el | 239 -
packages/context-coloring/context-coloring-test.el | 931 --
packages/context-coloring/context-coloring.el | 494 -
packages/context-coloring/fixtures/.nosearch | 0
.../fixtures/benchmark/.dir-locals.el | 1 -
.../fixtures/benchmark/async-0.9.0.js | 1123 --
.../context-coloring/fixtures/benchmark/faces.el | 2764 ----
.../fixtures/benchmark/jquery-2.1.1.js | 9190 -------------
.../context-coloring/fixtures/benchmark/lisp.el | 930 --
.../fixtures/benchmark/lodash-2.4.1.js | 6785 ----------
.../fixtures/benchmark/mkdirp-0.5.0.js | 97 -
.../context-coloring/fixtures/benchmark/simple.el | 7901 ------------
.../context-coloring/fixtures/benchmark/subr.el | 4800 -------
packages/context-coloring/fixtures/test/README | 4 -
.../context-coloring/fixtures/test/block-scopes.js | 7 -
packages/context-coloring/fixtures/test/catch.js | 8 -
packages/context-coloring/fixtures/test/changed.el | 5 -
packages/context-coloring/fixtures/test/comment.el | 3 -
.../fixtures/test/comments-and-strings.js | 4 -
packages/context-coloring/fixtures/test/cond.el | 8 -
.../fixtures/test/condition-case.el | 10 -
.../context-coloring/fixtures/test/defadvice.el | 3 -
packages/context-coloring/fixtures/test/defun.el | 8 -
packages/context-coloring/fixtures/test/dolist.el | 3 -
packages/context-coloring/fixtures/test/empty | 0
.../fixtures/test/empty-varlist.el | 6 -
.../fixtures/test/function-scopes.js | 5 -
packages/context-coloring/fixtures/test/global.js | 3 -
packages/context-coloring/fixtures/test/ignored.el | 2 -
.../fixtures/test/initial-level.js | 2 -
.../context-coloring/fixtures/test/iteration.el | 2 -
.../context-coloring/fixtures/test/key-names.js | 6 -
.../context-coloring/fixtures/test/key-values.js | 8 -
packages/context-coloring/fixtures/test/lambda.el | 3 -
.../context-coloring/fixtures/test/let-star.el | 11 -
packages/context-coloring/fixtures/test/let.el | 13 -
.../fixtures/test/macroexp-let2.el | 6 -
.../fixtures/test/narrow-to-region.js | 3 -
.../fixtures/test/prettify-symbols.el | 1 -
.../fixtures/test/property-lookup.js | 5 -
packages/context-coloring/fixtures/test/quote.el | 15 -
packages/context-coloring/fixtures/test/sexp.el | 4 -
packages/context-coloring/fixtures/test/splice.el | 2 -
packages/context-coloring/fixtures/test/string.el | 2 -
.../fixtures/test/unbalanced-parenthesis.el | 2 -
.../fixtures/test/unterminated-comment.js | 6 -
.../fixtures/test/varlist-spacing.el | 8 -
packages/context-coloring/screenshot.png | Bin 22006 -> 0 bytes
packages/diff-hl/.elpaignore | 2 -
packages/diff-hl/LICENSE | 674 -
packages/diff-hl/README.md | 118 -
packages/diff-hl/diff-hl-amend.el | 68 -
packages/diff-hl/diff-hl-dired.el | 184 -
packages/diff-hl/diff-hl-flydiff.el | 176 -
packages/diff-hl/diff-hl-margin.el | 153 -
packages/diff-hl/diff-hl.el | 643 -
packages/diff-hl/screenshot-dired.png | Bin 57595 -> 0 bytes
packages/diff-hl/screenshot-margin.png | Bin 96375 -> 0 bytes
packages/diff-hl/screenshot.png | Bin 58512 -> 0 bytes
packages/diffview/Makefile | 13 -
packages/diffview/README.md | 59 -
packages/diffview/diffview.el | 200 -
packages/diffview/screenshots/diffview-after.png | Bin 199810 -> 0 bytes
packages/diffview/screenshots/diffview-before.png | Bin 184048 -> 0 bytes
packages/dts-mode/README.mkd | 12 -
packages/dts-mode/dts-mode.el | 177 -
packages/eldoc-eval/README.md | 42 -
packages/eldoc-eval/eldoc-eval.el | 225 -
packages/f90-interface-browser/README.org | 82 -
.../f90-interface-browser/f90-interface-browser.el | 1032 --
packages/f90-interface-browser/f90-tests.el | 120 -
packages/ioccur/ioccur.el | 1116 --
packages/js2-mode/.dir-locals.el | 1 -
packages/js2-mode/.elpaignore | 4 -
packages/js2-mode/.gitignore | 1 -
packages/js2-mode/.travis.yml | 24 -
packages/js2-mode/LICENSE | 674 -
packages/js2-mode/Makefile | 23 -
packages/js2-mode/NEWS.md | 265 -
packages/js2-mode/README.md | 58 -
packages/js2-mode/js2-imenu-extras.el | 349 -
packages/js2-mode/js2-mode.el | 12852 -------------------
packages/js2-mode/js2-old-indent.el | 712 -
packages/js2-mode/tests/consume.el | 84 -
packages/js2-mode/tests/externs.el | 126 -
packages/js2-mode/tests/indent.el | 291 -
packages/js2-mode/tests/jsdoc.el | 113 -
packages/js2-mode/tests/json-path.el | 64 -
packages/js2-mode/tests/navigation.el | 110 -
packages/js2-mode/tests/parser.el | 1429 ---
packages/math-symbol-lists/.dir-locals.el | 3 -
packages/math-symbol-lists/.gitignore | 5 -
packages/math-symbol-lists/math-symbol-lists.el | 3700 ------
packages/math-symbol-lists/msl-build.el | 168 -
packages/math-symbol-lists/readme.md | 15 -
packages/names/Other-Packages.org | 25 -
packages/names/Readme.org | 123 -
packages/names/TheNittyGritty.org | 197 -
packages/names/Todo.org | 38 -
packages/names/UsageExample.org | 219 -
packages/names/names-dev.el | 254 -
packages/names/names.el | 1322 --
packages/names/package-example.png | Bin 83634 -> 0 bytes
packages/on-screen/.gitignore | 1 -
packages/on-screen/on-screen.el | 667 -
packages/vcl-mode/vcl-mode.el | 423 -
packages/web-server/.elpaignore | 14 -
packages/web-server/.github/workflows/test.yml | 20 -
packages/web-server/.gitignore | 4 -
packages/web-server/COPYING | 674 -
packages/web-server/Makefile | 47 -
packages/web-server/NOTES | 325 -
packages/web-server/README | 43 -
packages/web-server/doc/.gitignore | 5 -
packages/web-server/doc/Makefile | 14 -
packages/web-server/doc/doclicense.texi | 508 -
packages/web-server/doc/gpl.texi | 717 --
packages/web-server/doc/web-server.texi | 601 -
packages/web-server/examples/000-hello-world.el | 9 -
.../web-server/examples/001-hello-world-utf8.el | 22 -
.../web-server/examples/002-hello-world-html.el | 16 -
packages/web-server/examples/003-file-server.el | 15 -
packages/web-server/examples/004-url-param-echo.el | 18 -
packages/web-server/examples/005-post-echo.el | 20 -
.../examples/006-basic-authentication.el | 14 -
.../examples/007-org-mode-file-server.el | 45 -
packages/web-server/examples/008-file-upload.el | 13 -
packages/web-server/examples/009-web-socket.el | 57 -
packages/web-server/examples/010-current-buffer.el | 15 -
packages/web-server/examples/011-org-agenda.el | 18 -
packages/web-server/examples/012-search-bbdb.el | 23 -
.../web-server/examples/013-org-export-service.el | 46 -
packages/web-server/examples/014-org-json.el | 26 -
.../web-server/examples/015-auto-mode-server.el | 30 -
.../examples/016-content-encoding-gzip.el | 26 -
.../examples/017-transfer-encoding-chunked.el | 31 -
packages/web-server/examples/018-web-shell.el | 74 -
packages/web-server/examples/018-web-shell.html | 15 -
packages/web-server/examples/018-web-shell.js | 22 -
packages/web-server/web-server-status-codes.el | 106 -
packages/web-server/web-server-test.el | 348 -
packages/web-server/web-server.el | 744 --
packages/websocket/COPYING | 339 -
packages/websocket/README.org | 35 -
packages/websocket/testserver.py | 34 -
packages/websocket/websocket-functional-test.el | 163 -
packages/websocket/websocket.el | 1065 --
221 files changed, 18 insertions(+), 85004 deletions(-)
diff --git a/externals-list b/externals-list
index 5c21e60..dfe6402 100644
--- a/externals-list
+++ b/externals-list
@@ -33,7 +33,7 @@
;; diverged).
(("ack" :external "https://github.com/leoliu/ack-el")
- ("aggressive-indent" :subtree
"https://github.com/Malabarba/aggressive-indent-mode")
+ ("aggressive-indent" :external
"https://github.com/Malabarba/aggressive-indent-mode")
("async" :external "https://github.com/jwiegley/emacs-async")
("auctex" :external "git://git.sv.gnu.org/auctex.git")
("bbdb" :external "git://git.savannah.nongnu.org/bbdb.git")
@@ -62,35 +62,35 @@
;; ("cobol-mode" :subtree
"https://gist.github.com/Edward-H/6768e7dc53ea3dd2adca")
("cl-print" :core "lisp/emacs-lisp/cl-print.el")
("clipboard-collector" :external
"https://github.com/clemera/clipboard-collector")
- ("coffee-mode" :subtree
"https://github.com/defunkt/coffee-mode")
- ("compact-docstrings" :subtree
"https://github.com/cpitclaudel/compact-docstrings")
- ("company" :subtree
"https://github.com/company-mode/company-mode.git")
+ ("coffee-mode" :external
"https://github.com/defunkt/coffee-mode")
+ ("compact-docstrings" :external
"https://github.com/cpitclaudel/compact-docstrings")
+ ("company" :external
"https://github.com/company-mode/company-mode.git")
("company-math" :external "https://github.com/vspinu/company-math.git")
- ("context-coloring" :subtree
"https://github.com/jacksonrayhamilton/context-coloring.git")
+ ("context-coloring" :external
"https://github.com/jacksonrayhamilton/context-coloring.git")
("cpio-mode" :external "https://github.com/dlewan/cpio-mode")
("darkroom" :external
"https://github.com/capitaomorte/darkroom.git")
("dash" :external "https://github.com/magnars/dash.el.git")
("dbus-codegen" :subtree "https://github.com/ueno/dbus-codegen-el.git")
("delight" :external "https://git.savannah.gnu.org/r/delight.git")
- ("diffview" :subtree "https://github.com/mgalgs/diffview-mode.git")
- ("diff-hl" :subtree "https://github.com/dgutov/diff-hl.git")
+ ("diffview" :external
"https://github.com/mgalgs/diffview-mode.git")
+ ("diff-hl" :external "https://github.com/dgutov/diff-hl.git")
("dired-git-info" :external "https://github.com/clemera/dired-git-info")
("disk-usage" :external
"https://gitlab.com/ambrevar/emacs-disk-usage")
("dismal" :external nil)
- ("dts-mode" :subtree "https://github.com/bgamari/dts-mode.git")
+ ("dts-mode" :external "https://github.com/bgamari/dts-mode.git")
("easy-kill" :external "https://github.com/leoliu/easy-kill")
("ebdb" :external "https://github.com/girzel/ebdb.git")
("eev" :external "https://github.com/edrx/eev.git")
;branch UTF-8
("eglot" :external "https://github.com/joaotavora/eglot.git")
("eldoc" :core "lisp/emacs-lisp/eldoc.el")
- ("eldoc-eval" :subtree
"https://github.com/thierryvolpiatto/eldoc-eval.git")
+ ("eldoc-eval" :external
"https://github.com/thierryvolpiatto/eldoc-eval.git")
("elisp-benchmarks" :external nil)
("emms" :external "https://git.savannah.gnu.org/git/emms.git")
("enwc" :subtree
"bzr::bzr://bzr.savannah.nongnu.org/enwc/trunk")
("ergoemacs-mode" :external
"https://github.com/ergoemacs/ergoemacs-mode.git")
("expand-region" :external "https://github.com/magnars/expand-region.el")
("exwm" :external "https://github.com/ch11ng/exwm.git")
- ("f90-interface-browser" :subtree "https://github.com/wence-/f90-iface")
+ ("f90-interface-browser" :external "https://github.com/wence-/f90-iface")
("flymake" :core "lisp/progmodes/flymake.el")
("frog-menu" :external "https://github.com/clemera/frog-menu")
("gcmh" :external "https://gitlab.com/koral/gcmh")
@@ -103,27 +103,27 @@
("guess-language" :external
"https://github.com/tmalsburg/guess-language.el")
("highlight-escape-sequences" :external
"https://github.com/dgutov/highlight-escape-sequences/")
("hyperbole" :external
"http://git.savannah.gnu.org/r/hyperbole.git")
- ("ioccur" :subtree
"https://github.com/thierryvolpiatto/ioccur.git")
+ ("ioccur" :external
"https://github.com/thierryvolpiatto/ioccur.git")
("ivy-explorer" :external "https://github.com/clemera/ivy-explorer")
("ivy-posframe" :external "https://github.com/tumashu/ivy-posframe")
- ("js2-mode" :subtree "https://github.com/mooz/js2-mode.git")
+ ("js2-mode" :external "https://github.com/mooz/js2-mode.git")
("jsonrpc" :core "lisp/jsonrpc.el")
("leaf" :external "https://github.com/conao3/leaf.el")
("let-alist" :core "lisp/emacs-lisp/let-alist.el")
("map" :core "lisp/emacs-lisp/map.el")
- ("math-symbol-lists" :subtree
"https://github.com/vspinu/math-symbol-lists.git")
+ ("math-symbol-lists" :external
"https://github.com/vspinu/math-symbol-lists.git")
("mmm-mode" :external "https://github.com/purcell/mmm-mode.git")
("modus-operandi-theme":external
"https://gitlab.com/protesilaos/modus-themes")
("modus-vivendi-theme" :external
"https://gitlab.com/protesilaos/modus-themes")
("muse" :subtree "https://github.com/alexott/muse")
("nameless" :external "https://github.com/Malabarba/Nameless")
- ("names" :subtree "http://github.com/Malabarba/names")
+ ("names" :external "http://github.com/Malabarba/names")
("objed" :external "https://github.com/clemera/objed")
("omn-mode" :external nil)
("orgalist" :external nil)
("org-edna" :external
"https://savannah.nongnu.org/projects/org-edna-el") ;URL?
("ntlm" :core "lisp/net/ntlm.el")
- ("on-screen" :subtree
"https://github.com/michael-heerdegen/on-screen.el.git")
+ ("on-screen" :external
"https://github.com/michael-heerdegen/on-screen.el.git")
("pabbrev" :external "https://github.com/phillord/pabbrev.git")
("parsec" :external
"https://github.com/cute-jumper/parsec.el.git")
("peg" :external) ;Was in
"https://github.com/ellerh/peg.el"
@@ -170,15 +170,15 @@
("temp-buffer-browse" :external
"https://github.com/leoliu/temp-buffer-browse")
("test-simple" :external "https://github.com/rocky/emacs-test-simple")
("vdiff" :external "https://github.com/justbur/emacs-vdiff")
- ("vcl-mode" :subtree "git://git.gnu.org.ua/vcl-mode")
+ ("vcl-mode" :external "git://git.gnu.org.ua/vcl-mode")
("tramp" :external
"https://git.savannah.gnu.org/cgit/tramp.git/?h=elpa")
("transient" :external "https://github.com/magit/transient")
;;FIXME:("vlf" :subtree ??)
("verilog-mode" :core "lisp/progmodes/verilog-mode.el")
("wcheck-mode" :external
"https://github.com/tlikonen/wcheck-mode")
- ("web-server" :subtree
"https://github.com/eschulte/emacs-web-server.git")
+ ("web-server" :external
"https://github.com/eschulte/emacs-web-server.git")
("webfeeder" :external
"https://gitlab.com/ambrevar/emacs-webfeeder.git")
- ("websocket" :subtree
"https://github.com/ahyatt/emacs-websocket.git")
+ ("websocket" :external
"https://github.com/ahyatt/emacs-websocket.git")
("windower" :external "https://gitlab.com/ambrevar/emacs-windower")
("wisitoken-grammar-mode" :external nil)
("which-key" :external "https://github.com/justbur/emacs-which-key")
diff --git a/packages/aggressive-indent/README.md
b/packages/aggressive-indent/README.md
deleted file mode 100644
index 68e07ad..0000000
--- a/packages/aggressive-indent/README.md
+++ /dev/null
@@ -1,65 +0,0 @@
-aggressive-indent-mode
[![Melpa](http://melpa.org/packages/aggressive-indent-badge.svg)](http://melpa.org/#/aggressive-indent)
[![Melpa-Stable](http://stable.melpa.org/packages/aggressive-indent-badge.svg)](http://stable.melpa.org/#/aggressive-indent)
-======================
-
-`electric-indent-mode` is enough to keep your code nicely aligned when
-all you do is type. However, once you start shifting blocks around,
-transposing lines, or slurping and barfing sexps, indentation is bound
-to go wrong.
-
-**`aggressive-indent-mode`** is a minor mode that keeps your code **always**
-indented. It reindents after every change, making it more reliable
-than `electric-indent-mode`.
-
-### Demonstration ###
-
-- An example of Lisp mode (Emacs Lisp):
-![Lisp Code Example](lisp-example.gif)
-
-- An example of non-Lisp mode (C):
-![C Code Example](c-example.gif)
-
-### Instructions ###
-
-This package is available fom Melpa, you may install it by calling
-
- M-x package-install RET aggressive-indent
-
-Then activate it with
-
- (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
- (add-hook 'css-mode-hook #'aggressive-indent-mode)
-
-You can use this hook on any mode you want, `aggressive-indent` is not
-exclusive to emacs-lisp code. In fact, if you want to turn it on for
-every programming mode, you can do something like:
-
- (global-aggressive-indent-mode 1)
- (add-to-list 'aggressive-indent-excluded-modes 'html-mode)
-
-#### Manual Installation ####
-
-If you don't want to install from Melpa, you can download it manually,
-place it in your `load-path` along with its dependency `cl-lib` (which
-you should already have if your `emacs-version` is at least 24.3).
-
-Then require it with:
-
- (require 'aggressive-indent)
-
-### Customization ###
-
-The variable `aggressive-indent-dont-indent-if` lets you customize
-when you **don't** want indentation to happen.
-For instance, if you think it's annoying that lines jump around in
-`c++-mode` because you haven't typed the `;` yet, you could add the
-following clause:
-
- (add-to-list
- 'aggressive-indent-dont-indent-if
- '(and (derived-mode-p 'c++-mode)
- (null (string-match "\\([;{}]\\|\\b\\(if\\|for\\|while\\)\\b\\)"
- (thing-at-point 'line)))))
-
-## Contribute ##
-
-[![Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.1.3/dist/gratipay.png)](https://gratipay.com/Malabarba)
diff --git a/packages/aggressive-indent/aggressive-indent.el
b/packages/aggressive-indent/aggressive-indent.el
deleted file mode 100644
index a066c58..0000000
--- a/packages/aggressive-indent/aggressive-indent.el
+++ /dev/null
@@ -1,451 +0,0 @@
-;;; aggressive-indent.el --- Minor mode to aggressively keep your code always
indented -*- lexical-binding:t -*-
-
-;; Copyright (C) 2014, 2015, 2016 Free Software Foundation, Inc
-
-;; Author: Artur Malabarba <emacs@endlessparentheses.com>
-;; URL: https://github.com/Malabarba/aggressive-indent-mode
-;; Version: 1.8.3
-;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
-;; Keywords: indent lisp maint tools
-;; Prefix: aggressive-indent
-;; Separator: -
-
-;;; Commentary:
-;;
-;; `electric-indent-mode' is enough to keep your code nicely aligned when
-;; all you do is type. However, once you start shifting blocks around,
-;; transposing lines, or slurping and barfing sexps, indentation is bound
-;; to go wrong.
-;;
-;; `aggressive-indent-mode' is a minor mode that keeps your code always
-;; indented. It reindents after every change, making it more reliable
-;; than `electric-indent-mode'.
-;;
-;; ### Instructions ###
-;;
-;; This package is available fom Melpa, you may install it by calling
-;;
-;; M-x package-install RET aggressive-indent
-;;
-;; Then activate it with
-;;
-;; (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
-;; (add-hook 'css-mode-hook #'aggressive-indent-mode)
-;;
-;; You can use this hook on any mode you want, `aggressive-indent' is not
-;; exclusive to emacs-lisp code. In fact, if you want to turn it on for
-;; every programming mode, you can do something like:
-;;
-;; (global-aggressive-indent-mode 1)
-;; (add-to-list 'aggressive-indent-excluded-modes 'html-mode)
-;;
-;; ### Manual Installation ###
-;;
-;; If you don't want to install from Melpa, you can download it manually,
-;; place it in your `load-path' and require it with
-;;
-;; (require 'aggressive-indent)
-
-;;; Instructions:
-;;
-;; INSTALLATION
-;;
-;; This package is available fom Melpa, you may install it by calling
-;; M-x package-install RET aggressive-indent.
-;;
-;; Then activate it with
-;; (add-hook 'emacs-lisp-mode-hook #'aggressive-indent-mode)
-;;
-;; You can also use an equivalent hook for another mode,
-;; `aggressive-indent' is not exclusive to emacs-lisp code.
-;;
-;; Alternatively, you can download it manually, place it in your
-;; `load-path' and require it with
-;;
-;; (require 'aggressive-indent)
-
-;;; License:
-;;
-;; 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.
-;;
-
-;;; Code:
-
-(require 'cl-lib)
-
-(defgroup aggressive-indent nil
- "Customization group for aggressive-indent."
- :prefix "aggressive-indent-"
- :group 'electricity
- :group 'indent)
-
-(defun aggressive-indent-bug-report ()
- "Opens github issues page in a web browser. Please send any bugs you find.
-Please include your Emacs and `aggressive-indent' versions."
- (interactive)
- (message "Your `aggressive-indent-version' is: %s, and your emacs version
is: %s.
-Please include this in your report!"
- (eval-when-compile
- (ignore-errors
- (require 'lisp-mnt)
- (lm-version)))
- emacs-version)
- (browse-url
"https://github.com/Malabarba/aggressive-indent-mode/issues/new"))
-
-(defvar aggressive-indent-mode)
-
-;;; Configuring indentarion
-(defcustom aggressive-indent-dont-electric-modes nil
- "List of major-modes where `electric-indent' should be disabled."
- :type '(choice
- (const :tag "Never use `electric-indent-mode'." t)
- (repeat :tag "List of major-modes to avoid `electric-indent-mode'."
symbol))
- :package-version '(aggressive-indent . "0.3.1"))
-
-(defcustom aggressive-indent-excluded-modes
- '(
- bibtex-mode
- cider-repl-mode
- coffee-mode
- comint-mode
- conf-mode
- Custom-mode
- diff-mode
- doc-view-mode
- dos-mode
- erc-mode
- feature-mode
- fortran-mode
- f90-mode
- jabber-chat-mode
- haml-mode
- haskell-mode
- haskell-interactive-mode
- image-mode
- inf-ruby-mode
- makefile-mode
- makefile-gmake-mode
- minibuffer-inactive-mode
- netcmd-mode
- python-mode
- sass-mode
- scala-mode
- slim-mode
- special-mode
- shell-mode
- snippet-mode
- eshell-mode
- tabulated-list-mode
- term-mode
- TeX-output-mode
- text-mode
- yaml-mode
- )
- "Modes in which `aggressive-indent-mode' should not be activated.
-This variable is only used if `global-aggressive-indent-mode' is
-active. If the minor mode is turned on with the local command,
-`aggressive-indent-mode', this variable is ignored."
- :type '(repeat symbol)
- :package-version '(aggressive-indent . "0.3.1"))
-
-(defcustom aggressive-indent-protected-commands '(undo undo-tree-undo
undo-tree-redo whitespace-cleanup)
- "Commands after which indentation will NOT be performed.
-Aggressive indentation could break things like `undo' by locking
-the user in a loop, so this variable is used to control which
-commands will NOT be followed by a re-indent."
- :type '(repeat symbol)
- :package-version '(aggressive-indent . "0.1"))
-
-(defcustom aggressive-indent-comments-too nil
- "If non-nil, aggressively indent in comments as well."
- :type 'boolean
- :package-version '(aggressive-indent . "0.3"))
-
-(defcustom aggressive-indent-modes-to-prefer-defun
- '(emacs-lisp-mode lisp-mode scheme-mode clojure-mode)
- "List of major-modes in which indenting defun is preferred.
-Add here any major modes with very good definitions of
-`end-of-defun' and `beginning-of-defun', or modes which bug out
-if you have `after-change-functions' (such as paredit).
-
-If current major mode is derived from one of these,
-`aggressive-indent' will call `aggressive-indent-indent-defun'
-after every command. Otherwise, it will call
-`aggressive-indent-indent-region-and-on' after every buffer
-change."
- :type '(repeat symbol)
- :package-version '(aggressive-indent . "0.3"))
-
-;;; Preventing indentation
-(defconst aggressive-indent--internal-dont-indent-if
- '((memq this-command aggressive-indent-protected-commands)
- (region-active-p)
- buffer-read-only
- undo-in-progress
- (null (buffer-modified-p))
- (and (boundp 'smerge-mode) smerge-mode)
- (let ((line (thing-at-point 'line)))
- (and (stringp line)
- ;; If the user is starting to type a comment.
- (stringp comment-start)
- (string-match (concat "\\`[[:blank:]]*"
- (substring comment-start 0 1)
- "[[:blank:]]*$")
- line)))
- (let ((sp (syntax-ppss)))
- ;; Comments.
- (or (and (not aggressive-indent-comments-too) (elt sp 4))
- ;; Strings.
- (elt sp 3))))
- "List of forms which prevent indentation when they evaluate to non-nil.
-This is for internal use only. For user customization, use
-`aggressive-indent-dont-indent-if' instead.")
-
-(eval-after-load 'yasnippet
- '(when (boundp 'yas--active-field-overlay)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- '(and
- (overlayp yas--active-field-overlay)
- (overlay-end yas--active-field-overlay))
- 'append)))
-(eval-after-load 'company
- '(when (boundp 'company-candidates)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- 'company-candidates)))
-(eval-after-load 'auto-complete
- '(when (boundp 'ac-completing)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- 'ac-completing)))
-(eval-after-load 'multiple-cursors-core
- '(when (boundp 'multiple-cursors-mode)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- 'multiple-cursors-mode)))
-(eval-after-load 'iedit
- '(when (boundp 'iedit-mode)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- 'iedit-mode)))
-(eval-after-load 'evil
- '(when (boundp 'iedit-mode)
- (add-to-list 'aggressive-indent--internal-dont-indent-if
- 'iedit-mode)))
-(eval-after-load 'coq
- '(add-to-list 'aggressive-indent--internal-dont-indent-if
- '(and (derived-mode-p 'coq-mode)
- (not (string-match "\\.[[:space:]]*$"
- (thing-at-point 'line))))))
-(eval-after-load 'ruby-mode
- '(add-to-list 'aggressive-indent--internal-dont-indent-if
- '(when (derived-mode-p 'ruby-mode)
- (let ((line (thing-at-point 'line)))
- (and (stringp line)
- (string-match "\\b\\(if\\|case\\|do\\|begin\\) *$"
line))))))
-
-(defcustom aggressive-indent-dont-indent-if '()
- "List of variables and functions to prevent aggressive indenting.
-This variable is a list where each element is a Lisp form.
-As long as any one of these forms returns non-nil,
-aggressive-indent will not perform any indentation.
-
-See `aggressive-indent--internal-dont-indent-if' for usage examples."
- :type '(repeat sexp)
- :package-version '(aggressive-indent . "0.2"))
-
-(defvar aggressive-indent--error-message "One of the forms in
`aggressive-indent-dont-indent-if' had the following error, I've disabled it
until you fix it: %S"
- "Error message thrown by `aggressive-indent-dont-indent-if'.")
-
-(defvar aggressive-indent--has-errored nil
- "Keep track of whether `aggressive-indent-dont-indent-if' is throwing.
-This is used to prevent an infinite error loop on the user.")
-
-(defun aggressive-indent--run-user-hooks ()
- "Safely run forms in `aggressive-indent-dont-indent-if'.
-If any of them errors out, we only report it once until it stops
-erroring again."
- (and aggressive-indent-dont-indent-if
- (condition-case er
- (prog1 (eval (cons 'or aggressive-indent-dont-indent-if))
- (setq aggressive-indent--has-errored nil))
- (error (unless aggressive-indent--has-errored
- (setq aggressive-indent--has-errored t)
- (message aggressive-indent--error-message er))))))
-
-;;; Indenting defun
-;;;###autoload
-(defun aggressive-indent-indent-defun (&optional l r)
- "Indent current defun.
-Throw an error if parentheses are unbalanced.
-If L and R are provided, use them for finding the start and end of defun."
- (interactive)
- (let ((p (point-marker)))
- (set-marker-insertion-type p t)
- (indent-region
- (save-excursion
- (when l (goto-char l))
- (beginning-of-defun 1) (point))
- (save-excursion
- (when r (goto-char r))
- (end-of-defun 1) (point)))
- (goto-char p)))
-
-(defun aggressive-indent--softly-indent-defun (&optional l r)
- "Indent current defun unobstrusively.
-Like `aggressive-indent-indent-defun', but without errors or
-messages. L and R passed to `aggressive-indent-indent-defun'."
- (cl-letf (((symbol-function 'message) #'ignore))
- (ignore-errors (aggressive-indent-indent-defun l r))))
-
-;;; Indenting region
-;;;###autoload
-(defun aggressive-indent-indent-region-and-on (l r)
- "Indent region between L and R, and then some.
-Call `indent-region' between L and R, and then keep indenting
-until nothing more happens."
- (interactive "r")
- (let ((p (point-marker)))
- (set-marker-insertion-type p t)
- (unwind-protect
- (progn
- (unless (= l r)
- (when (= (char-before r) ?\n)
- (cl-decf r)))
- ;; If L is at the end of a line, skip that line.
- (unless (= l r)
- (when (= (char-after l) ?\n)
- (cl-incf l)))
- ;; Indent the affected region.
- (goto-char r)
- (unless (= l r) (indent-region l r))
- ;; And then we indent each following line until nothing happens.
- (forward-line 1)
- (skip-chars-forward "[:blank:]\n\r\xc")
- (let* ((eod (ignore-errors
- (save-excursion (end-of-defun)
- (point-marker))))
- (point-limit (if (and eod (< (point) eod))
- eod (point-max-marker))))
- (while (and (null (eobp))
- (let ((op (point))
- (np (progn (indent-according-to-mode)
- (point))))
- ;; As long as we're indenting things to the
- ;; left, keep indenting.
- (or (< np op)
- ;; If we're indenting to the right, or
- ;; not at all, stop at the limit.
- (< (point) point-limit))))
- (forward-line 1)
- (skip-chars-forward "[:blank:]\n\r\f"))))
- (goto-char p))))
-
-(defun aggressive-indent--softly-indent-region-and-on (l r &rest _)
- "Indent region between L and R, and a bit more.
-Like `aggressive-indent-indent-region-and-on', but without errors
-or messages."
- (cl-letf (((symbol-function 'message) #'ignore))
- (ignore-errors (aggressive-indent-indent-region-and-on l r))))
-
-;;; Tracking changes
-(defvar aggressive-indent--changed-list nil
- "List of (left right) limit of regions changed in the last command loop.")
-(make-variable-buffer-local 'aggressive-indent--changed-list)
-
-(defun aggressive-indent--proccess-changed-list-and-indent ()
- "Indent the regions in `aggressive-indent--changed-list'."
- (let ((inhibit-modification-hooks t)
- (inhibit-point-motion-hooks t)
- (indent-function
- (if (cl-member-if #'derived-mode-p
aggressive-indent-modes-to-prefer-defun)
- #'aggressive-indent--softly-indent-defun
#'aggressive-indent--softly-indent-region-and-on)))
- ;; Take the 10 most recent changes.
- (let ((cell (nthcdr 10 aggressive-indent--changed-list)))
- (when cell (setcdr cell nil)))
- ;; (message "----------")
- (while aggressive-indent--changed-list
- ;; (message "%S" (car aggressive-indent--changed-list))
- (apply indent-function (car aggressive-indent--changed-list))
- (setq aggressive-indent--changed-list
- (cdr aggressive-indent--changed-list)))))
-
-(defcustom aggressive-indent-sit-for-time 0.05
- "Time, in seconds, to wait before indenting.
-If you feel aggressive-indent is causing Emacs to hang while
-typing, try tweaking this number."
- :type 'float)
-
-(defun aggressive-indent--indent-if-changed ()
- "Indent any region that changed in the last command loop."
- (when aggressive-indent--changed-list
- (save-excursion
- (save-selected-window
- (unless (or (run-hook-wrapped
'aggressive-indent--internal-dont-indent-if #'eval)
- (aggressive-indent--run-user-hooks))
- (while-no-input
- (sit-for aggressive-indent-sit-for-time t)
- (redisplay)
- (aggressive-indent--proccess-changed-list-and-indent)))))))
-
-(defun aggressive-indent--keep-track-of-changes (l r &rest _)
- "Store the limits (L and R) of each change in the buffer."
- (when aggressive-indent-mode
- (push (list l r) aggressive-indent--changed-list)))
-
-;;; Minor modes
-;;;###autoload
-(define-minor-mode aggressive-indent-mode
- nil nil " =>"
- `((,(kbd "C-c C-q") . aggressive-indent-indent-defun)
- ([backspace]
- menu-item "maybe-delete-indentation" ignore :filter
- (lambda (&optional _)
- (when (and (looking-back "^[[:blank:]]+")
- ;; Wherever we don't want to indent, we probably also
- ;; want the default backspace behavior.
- (not (run-hook-wrapped
'aggressive-indent--internal-dont-indent-if #'eval))
- (not (aggressive-indent--run-user-hooks)))
- #'delete-indentation))))
- (if aggressive-indent-mode
- (if (and global-aggressive-indent-mode
- (or (cl-member-if #'derived-mode-p
aggressive-indent-excluded-modes)
- (memq major-mode '(text-mode fundamental-mode))
- buffer-read-only))
- (aggressive-indent-mode -1)
- ;; Should electric indent be ON or OFF?
- (if (or (eq aggressive-indent-dont-electric-modes t)
- (cl-member-if #'derived-mode-p
aggressive-indent-dont-electric-modes))
- (aggressive-indent--local-electric nil)
- (aggressive-indent--local-electric t))
- (add-hook 'after-change-functions
#'aggressive-indent--keep-track-of-changes nil 'local)
- (add-hook 'before-save-hook
#'aggressive-indent--proccess-changed-list-and-indent nil 'local)
- (add-hook 'post-command-hook #'aggressive-indent--indent-if-changed
nil 'local))
- ;; Clean the hooks
- (remove-hook 'after-change-functions
#'aggressive-indent--keep-track-of-changes 'local)
- (remove-hook 'before-save-hook
#'aggressive-indent--proccess-changed-list-and-indent 'local)
- (remove-hook 'post-command-hook #'aggressive-indent--indent-if-changed
'local)
- (remove-hook 'post-command-hook #'aggressive-indent--softly-indent-defun
'local)))
-
-(defun aggressive-indent--local-electric (on)
- "Turn variable `electric-indent-mode' on or off locally, as per boolean ON."
- (if (fboundp 'electric-indent-local-mode)
- (electric-indent-local-mode (if on 1 -1))
- (set (make-local-variable 'electric-indent-mode) on)))
-
-;;;###autoload
-(define-globalized-minor-mode global-aggressive-indent-mode
- aggressive-indent-mode aggressive-indent-mode)
-
-;;;###autoload
-(defalias 'aggressive-indent-global-mode
- #'global-aggressive-indent-mode)
-
-(provide 'aggressive-indent)
-;;; aggressive-indent.el ends here
diff --git a/packages/aggressive-indent/c-example.gif
b/packages/aggressive-indent/c-example.gif
deleted file mode 100644
index f72e143..0000000
Binary files a/packages/aggressive-indent/c-example.gif and /dev/null differ
diff --git a/packages/aggressive-indent/lisp-example.gif
b/packages/aggressive-indent/lisp-example.gif
deleted file mode 100644
index 220289a..0000000
Binary files a/packages/aggressive-indent/lisp-example.gif and /dev/null differ
diff --git a/packages/coffee-mode/README.md b/packages/coffee-mode/README.md
deleted file mode 100644
index 51a7322..0000000
--- a/packages/coffee-mode/README.md
+++ /dev/null
@@ -1,284 +0,0 @@
-CoffeeScript Major Mode
-=======================
-
-An Emacs major mode for [CoffeeScript][cs], unfancy JavaScript.
-
-Provides syntax highlighting, indentation support, imenu support,
-a menu bar, and a few cute commands.
-
-![Screenshot](http://img.skitch.com/20100308-fcr622c95ibey4m474d5m1m1qt.png)
-
-## Installation
-
-In your shell:
-
- $ cd ~/.emacs.d/vendor
- $ git clone git://github.com/defunkt/coffee-mode.git
-
-In your emacs config:
-
- (add-to-list 'load-path "~/.emacs.d/vendor/coffee-mode")
- (require 'coffee-mode)
-
-If `coffee-mode` is not enabled automatically for any files ending in
-".coffee" or named "Cakefile", add this to your emacs config as well:
-
- (add-to-list 'auto-mode-alist '("\\.coffee$" . coffee-mode))
- (add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))
-
-[coffee-mode used to offer automatic deletion of trailing whitespace.
-This is now left to whitespace-mode. See its documentation for full
-details, but as a hint, configure:
-
- (setq whitespace-action '(auto-cleanup)) ;; automatically clean up bad
whitespace
- (setq whitespace-style '(trailing space-before-tab indentation empty
space-after-tab)) ;; only show bad whitespace
-
-Then turn on whitespace-mode, or global-whitespace-mode.]
-
-## Indentation
-
-### TAB Theory
-
-It goes like this: when you press `TAB`, we indent the line unless
-doing so would make the current line more than two indentation levels
-deepers than the previous line. If that's the case, remove all
-indentation.
-
-Consider this code, with point at the position indicated by the
-caret:
-
- line1()
- line2()
- line3()
- ^
-
-Pressing `TAB` will produce the following code:
-
- line1()
- line2()
- line3()
- ^
-
-Pressing `TAB` again will produce this code:
-
- line1()
- line2()
- line3()
- ^
-
-And so on. I think this is a pretty good way of getting decent
-indentation with a whitespace-sensitive language.
-
-### Newline and Indent
-
-We all love hitting `RET` and having the next line indented
-properly. Given this code and cursor position:
-
- line1()
- line2()
- line3()
- ^
-
-Pressing `RET` would insert a newline and place our cursor at the
-following position:
-
- line1()
- line2()
- line3()
-
- ^
-
-In other words, the level of indentation is maintained. This
-applies to comments as well. Combined with the `TAB` you should be
-able to get things where you want them pretty easily.
-
-### Indenters
-
-`class`, `for`, `if`, and possibly other keywords cause the next line
-to be indented a level deeper automatically.
-
-For example, given this code and cursor position::
-
- class Animal
- ^
-
-Pressing enter would produce the following:
-
- class Animal
-
- ^
-
-That is, indented a column deeper.
-
-This also applies to lines ending in `->`, `=>`, `{`, `[`, and
-possibly more characters.
-
-So this code and cursor position:
-
- $('#demo').click ->
- ^
-
-On enter would produce this:
-
- $('#demo').click ->
-
- ^
-
-Pretty slick.
-
-## imenu
-
-If you're using imenu, `coffee-mode` should work just fine. This
-means users of [textmate.el][tm] will find that `⇧⌘T`
-(`textmate-go-to-symbol`) mostly works as expected.
-
-If you're not using imenu check out [this page][im] or textmate.el for
-a really awesome way to jump quickly to a function's definition in a
-file.
-
-## Commands
-
-If you have `easymenu` you can get to any of these commands from the
-menu bar:
-
-![coffee-mode menu
bar](http://img.skitch.com/20100308-tt5yn51h2jww2pmjqaawed6eq8.png)
-
-### coffee-compile-file
-
-Compiles the current file as a JavaScript file. Doesn't open it or
-anything special for you.
-
-Operating on "basic.coffee" and running this command will save a
-"basic.js" in the same directory. Subsequent runs will overwrite the
-file.
-
-If there are compilation errors and we the compiler have returned a
-line number to us for the first error, the point is moved to that
-line, so you can investigate. If this annoys you, you can set
-`coffee-compile-jump-to-error` to `nil`.
-
-### coffee-compile-buffer
-
-Compiles the current buffer to JavaScript using the command specified
-by the `coffee-command` variable and opens the contents in a new
-buffer using the mode configured for ".js" files.
-
-Bind it:
-
- (define-key coffee-mode-map [(meta r)] 'coffee-compile-buffer)
-
-### coffee-compile-region
-
-Compiles the selected region to JavaScript using the same
-configuration variables as `coffee-compile-buffer`.
-
-Bind it:
-
- (define-key coffee-mode-map [(meta R)] 'coffee-compile-region)
-
-### Compile-on-save
-
-Hitting the key sequence `C-c C-o C-s` turns on (toggles) the
-compile-on-save minor mode in `coffee-mode`. To enable it by default:
-
- (add-hook 'coffee-mode-hook '(lambda () (coffee-cos-mode t)))
-
-### coffee-repl
-
-Starts a repl in a new buffer using `coffee-command`.
-
-## Hooks
-
-### coffee-mode-hook
-
-Naturally. Example:
-
- (defun coffee-custom ()
- "coffee-mode-hook"
-
- ;; CoffeeScript uses two spaces.
- (make-local-variable 'tab-width)
- (set 'tab-width 2)
-
- ;; If you don't want your compiled files to be wrapped
- (setq coffee-args-compile '("-c" "--bare"))
-
- ;; Emacs key binding
- (define-key coffee-mode-map [(meta r)] 'coffee-compile-buffer)
-
- ;; Riding edge.
- (setq coffee-command "~/dev/coffee")
-
- ;; Compile '.coffee' files on every save
- (and (file-exists-p (buffer-file-name))
- (file-exists-p (coffee-compiled-file-name))
- (coffee-cos-mode t)))
-
- (add-hook 'coffee-mode-hook 'coffee-custom)
-
-## Configuration
-
-You can customize any of the following options using `M-x
-customize-group` with "coffee" as the group.
-
-You can also customize then with `coffee-mode-hook`, as demonstrated
-above.
-
-### coffee-tab-width
-
-The tab width to use when indenting.
-
-Default: `tab-width`
-
-### coffee-command
-
-The CoffeeScript command used for evaluating code. Must be in your
-path.
-
-Default: `"coffee"`
-
-### coffee-args-repl
-
-The command line arguments to pass to `coffee-command' to start a
-REPL.
-
-Default: `'("-i")`
-
-### coffee-args-compile
-
-The command line arguments to pass to `coffee-command' when compiling a file.
-
-Default: `'("-c")`
-
-### coffee-compiled-buffer-name
-
-The name of the scratch buffer used when compiling CoffeeScript.
-
-Default: `"*coffee-compiled*"`
-
-### coffee-compile-jump-to-error
-
-Whether to jump to the first error if compilation fails. Please note
-that the coffee compiler doesn't always give a line number for the
-issue and in that case it is not possible to jump to the error, of
-course.
-
-Default: `t`
-
-## Thanks
-
-* Jeremy Ashkenas for CoffeeScript
-* <http://xahlee.org/emacs/elisp_syntax_coloring.html> for instructions.
-* Jason Blevins for the guidance his markdown-mode.el gave.
-* Steve Yegge for js2
-
-## Bugs
-
-Prototype accessor assignments like `String::length: -> 10` don't look
-great.
-
-Please file bugs at <http://github.com/defunkt/coffee-mode/issues>
-
-[cs]: http://jashkenas.github.com/coffee-script/
-[tm]: http://github.com/defunkt/textmate.el
-[im]: http://chopmo.blogspot.com/2008/09/quickly-jumping-to-symbols.html
diff --git a/packages/coffee-mode/coffee-mode.el
b/packages/coffee-mode/coffee-mode.el
deleted file mode 100644
index cf8b5a8..0000000
--- a/packages/coffee-mode/coffee-mode.el
+++ /dev/null
@@ -1,640 +0,0 @@
-;;; coffee-mode.el --- Major mode for CoffeeScript files
-
-;; Copyright (C) 2010-2013 Free Software Foundation, Inc.
-
-;; Version: 0.4.1.1
-;; Keywords: CoffeeScript major mode
-;; Author: Chris Wanstrath <chris@ozmm.org>
-;; URL: http://github.com/defunkt/coffee-mode
-
-;; 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
-
-;; CoffeeScript mode is an Emacs major mode for [CoffeeScript][cs],
-;; unfancy JavaScript. It provides syntax highlighting, indentation
-;; support, imenu support, a menu bar, and a few cute commands.
-
-;; Installing this package enables CoffeeScript mode for file named
-;; *.coffee and Cakefile.
-
-;; Commands:
-
-;; M-x coffee-compile-file compiles the current file as a JavaScript
-;; file. Operating on "basic.coffee" and running this command will
-;; save a "basic.js" in the same directory. Subsequent runs will
-;; overwrite the file.
-;;
-;; If there are compilation errors and we the compiler have returned a
-;; line number to us for the first error, the point is moved to that
-;; line, so you can investigate. If this annoys you, you can set
-;; `coffee-compile-jump-to-error` to `nil`.
-;;
-;; M-x coffee-compile-buffer compiles the current buffer to JavaScript
-;; using the command specified by the `coffee-command` variable, and
-;; opens the contents in a new buffer using the mode configured for
-;; ".js" files.
-;;
-;; M-x coffee-compile-region compiles the selected region to
-;; JavaScript using the same configuration variables as
-;; `coffee-compile-buffer`.
-;;
-;; `C-c C-o C-s' (coffee-cos-mode) toggles a minor mode implementing
-;; "compile-on-save" behavior.
-;;
-;; M-x coffee-repl starts a repl via `coffee-command` in a new buffer.
-
-;; Options:
-;;
-;; `coffee-tab-width' - Tab width to use when indenting.
-;; `coffee-command' - CoffeeScript command for evaluating code.
-;; Must be in your path.
-;; `coffee-args-repl' - Command line arguments for `coffee-command'
-;; when starting a REPL.
-;; `coffee-args-compile' - Arguments for `coffee-command'
-;; when compiling a file.
-;; `coffee-compiled-buffer-name' - Name of the scratch buffer used
-;; when compiling CoffeeScript.
-;; `coffee-compile-jump-to-error' - Whether to jump to the first error
-;; if compilation fails.
-
-;; Please file bugs at <http://github.com/defunkt/coffee-mode/issues>
-
-;; Thanks:
-
-;; Major thanks to http://xahlee.org/emacs/elisp_syntax_coloring.html
-;; the instructions.
-
-;; Also thanks to Jason Blevins's markdown-mode.el and Steve Yegge's
-;; js2-mode for guidance.
-
-;; TODO:
-;; - Execute {buffer,region,line} and show output in new buffer
-;; - Make prototype accessor assignments like `String::length: -> 10` pretty.
-;; - mirror-mode - close brackets and parens automatically
-
-;;; Code:
-
-(require 'comint)
-(require 'easymenu)
-(require 'font-lock)
-
-(eval-when-compile
- (require 'cl))
-
-;;
-;; Customizable Variables
-;;
-
-(defconst coffee-mode-version "0.4.1"
- "The version of `coffee-mode'.")
-
-(defgroup coffee nil
- "A CoffeeScript major mode."
- :group 'languages)
-
-(defcustom coffee-tab-width tab-width
- "The tab width to use when indenting."
- :type 'integer
- :group 'coffee)
-
-(defcustom coffee-command "coffee"
- "The CoffeeScript command used for evaluating code."
- :type 'string
- :group 'coffee)
-
-(defcustom js2coffee-command "js2coffee"
- "The js2coffee command used for evaluating code."
- :type 'string
- :group 'coffee)
-
-(defcustom coffee-args-repl '("-i")
- "The arguments to pass to `coffee-command' to start a REPL."
- :type 'list
- :group 'coffee)
-
-(defcustom coffee-args-compile '("-c")
- "The arguments to pass to `coffee-command' to compile a file."
- :type 'list
- :group 'coffee)
-
-(defcustom coffee-compiled-buffer-name "*coffee-compiled*"
- "The name of the scratch buffer used for compiled CoffeeScript."
- :type 'string
- :group 'coffee)
-
-(defcustom coffee-compile-jump-to-error t
- "Whether to jump to the first error if compilation fails.
-Please note that the coffee compiler doesn't always give a line
-number for the issue and in that case it is not possible to jump
-to the error."
- :type 'boolean
- :group 'coffee)
-
-(defcustom coffee-watch-buffer-name "*coffee-watch*"
- "The name of the scratch buffer used when using the --watch flag
-with CoffeeScript."
- :type 'string
- :group 'coffee)
-
-(defcustom coffee-mode-hook nil
- "Hook called by `coffee-mode'."
- :type 'hook
- :group 'coffee)
-
-(defvar coffee-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "A-r") 'coffee-compile-buffer)
- (define-key map (kbd "A-R") 'coffee-compile-region)
- (define-key map (kbd "A-M-r") 'coffee-repl)
- (define-key map "\C-m" 'coffee-newline-and-indent)
- (define-key map "\C-c\C-o\C-s" 'coffee-cos-mode)
- map)
- "Keymap for CoffeeScript major mode.")
-
-(defvar coffee-mode-syntax-table
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?# "< b" st)
- (modify-syntax-entry ?\n "> b" st)
- (modify-syntax-entry ?' "\"" st)
- st))
-
-;;
-;; Commands
-;;
-
-(defun coffee-repl ()
- "Launch a CoffeeScript REPL using `coffee-command' as an inferior mode."
- (interactive)
-
- (unless (comint-check-proc "*CoffeeREPL*")
- (set-buffer
- (apply 'make-comint "CoffeeREPL"
- coffee-command nil coffee-args-repl)))
-
- (pop-to-buffer "*CoffeeREPL*"))
-
-(defun coffee-compiled-file-name (&optional filename)
- "Returns the name of the JavaScript file compiled from a CoffeeScript file.
-If FILENAME is omitted, the current buffer's file name is used."
- (concat (file-name-sans-extension (or filename (buffer-file-name))) ".js"))
-
-(defun coffee-compile-file ()
- "Compiles and saves the current file to disk."
- (interactive)
- (let ((compiler-output (shell-command-to-string (coffee-command-compile
(buffer-file-name)))))
- (if (string= compiler-output "")
- (message "Compiled and saved %s" (coffee-compiled-file-name))
- (let* ((msg (car (split-string compiler-output "[\n\r]+")))
- (line (and (string-match "on line \\([0-9]+\\)" msg)
- (string-to-number (match-string 1 msg)))))
- (message msg)
- (when (and coffee-compile-jump-to-error line (> line 0))
- (goto-char (point-min))
- (forward-line (1- line)))))))
-
-(defun coffee-compile-buffer ()
- "Compiles the current buffer and displays the JavaScript in a buffer
-called `coffee-compiled-buffer-name'."
- (interactive)
- (save-excursion
- (coffee-compile-region (point-min) (point-max))))
-
-(defun coffee-compile-region (start end)
- "Compiles a region and displays the JavaScript in a buffer called
-`coffee-compiled-buffer-name'."
- (interactive "r")
-
- (let ((buffer (get-buffer coffee-compiled-buffer-name)))
- (when buffer
- (kill-buffer buffer)))
-
- (apply (apply-partially 'call-process-region start end coffee-command nil
- (get-buffer-create coffee-compiled-buffer-name)
- nil)
- (append coffee-args-compile (list "-s" "-p")))
- (switch-to-buffer (get-buffer coffee-compiled-buffer-name))
- (let ((buffer-file-name "tmp.js")) (set-auto-mode))
- (goto-char (point-min)))
-
-(defun coffee-js2coffee-replace-region (start end)
- "Convert JavaScript in the region into CoffeeScript."
- (interactive "r")
-
- (let ((buffer (get-buffer coffee-compiled-buffer-name)))
- (when buffer
- (kill-buffer buffer)))
-
- (call-process-region start end
- js2coffee-command nil
- (current-buffer))
- (delete-region start end))
-
-(defun coffee-version ()
- "Show the `coffee-mode' version in the echo area."
- (interactive)
- (message (concat "coffee-mode version " coffee-mode-version)))
-
-(defun coffee-watch (dir-or-file)
- "Run `coffee-run-cmd' with the --watch flag on a directory or file."
- (interactive "fDirectory or File: ")
- (let ((coffee-compiled-buffer-name coffee-watch-buffer-name)
- (args (mapconcat 'identity (append coffee-args-compile (list "--watch"
(expand-file-name dir-or-file))) " ")))
- (coffee-run-cmd args)))
-
-;;
-;; Menubar
-;;
-
-(easy-menu-define coffee-mode-menu coffee-mode-map
- "Menu for CoffeeScript mode"
- '("CoffeeScript"
- ["Compile File" coffee-compile-file]
- ["Compile Buffer" coffee-compile-buffer]
- ["Compile Region" coffee-compile-region]
- ["REPL" coffee-repl]
- "---"
- ["Version" coffee-show-version]
- ))
-
-;;
-;; Define Language Syntax
-;;
-
-;; String literals
-(defvar coffee-string-regexp
"\"\\([^\\]\\|\\\\.\\)*?\"\\|'\\([^\\]\\|\\\\.\\)*?'")
-
-;; Instance variables (implicit this)
-(defvar coffee-this-regexp "@\\(\\w\\|_\\)*\\|this")
-
-;; Prototype::access
-(defvar coffee-prototype-regexp "\\(\\(\\w\\|\\.\\|_\\|
\\|$\\)+?\\)::\\(\\(\\w\\|\\.\\|_\\| \\|$\\)+?\\):")
-
-;; Assignment
-(defvar coffee-assign-regexp "\\(\\(\\w\\|\\.\\|_\\|$\\)+?\s*\\):")
-
-;; Lambda
-(defvar coffee-lambda-regexp "\\((.+)\\)?\\s *\\(->\\|=>\\)")
-
-;; Namespaces
-(defvar coffee-namespace-regexp "\\b\\(class\\s +\\(\\S +\\)\\)\\b")
-
-;; Booleans
-(defvar coffee-boolean-regexp
"\\b\\(true\\|false\\|yes\\|no\\|on\\|off\\|null\\|undefined\\)\\b")
-
-;; Regular Expressions
-(defvar coffee-regexp-regexp
"\\/\\(\\\\.\\|\\[\\(\\\\.\\|.\\)+?\\]\\|[^/]\\)+?\\/")
-
-;; JavaScript Keywords
-(defvar coffee-js-keywords
- '("if" "else" "new" "return" "try" "catch"
- "finally" "throw" "break" "continue" "for" "in" "while"
- "delete" "instanceof" "typeof" "switch" "super" "extends"
- "class" "until" "loop"))
-
-;; Reserved keywords either by JS or CS.
-(defvar coffee-js-reserved
- '("case" "default" "do" "function" "var" "void" "with"
- "const" "let" "debugger" "enum" "export" "import" "native"
- "__extends" "__hasProp"))
-
-;; CoffeeScript keywords.
-(defvar coffee-cs-keywords
- '("then" "unless" "and" "or" "is"
- "isnt" "not" "of" "by" "where" "when"))
-
-;; Regular expression combining the above three lists.
-(defvar coffee-keywords-regexp (regexp-opt
- (append
- coffee-js-reserved
- coffee-js-keywords
- coffee-cs-keywords) 'words))
-
-
-;; Create the list for font-lock. Each class of keyword is given a
-;; particular face.
-(defvar coffee-font-lock-keywords
- ;; *Note*: order below matters. `coffee-keywords-regexp' goes last
- ;; because otherwise the keyword "state" in the function
- ;; "state_entry" would be highlighted.
- `((,coffee-string-regexp . font-lock-string-face)
- (,coffee-this-regexp . font-lock-variable-name-face)
- (,coffee-prototype-regexp . font-lock-variable-name-face)
- (,coffee-assign-regexp . font-lock-type-face)
- (,coffee-regexp-regexp . font-lock-constant-face)
- (,coffee-boolean-regexp . font-lock-constant-face)
- (,coffee-keywords-regexp . font-lock-keyword-face)))
-
-;;
-;; Helper Functions
-;;
-
-(defun coffee-command-compile (file-name)
- "Run `coffee-command' to compile FILE."
- (let ((full-file-name (expand-file-name file-name)))
- (mapconcat 'identity (append (list coffee-command) coffee-args-compile
(list full-file-name)) " ")))
-
-(defun coffee-run-cmd (args)
- "Run `coffee-command' with the given arguments, and display the
-output in a compilation buffer."
- (interactive "sArguments: ")
- (let ((compilation-buffer-name-function
- (lambda (_this-mode)
- (generate-new-buffer-name coffee-compiled-buffer-name))))
- (compile (concat coffee-command " " args))))
-
-;;
-;; imenu support
-;;
-
-;; This is a pretty naive but workable way of doing it. First we look
-;; for any lines that starting with `coffee-assign-regexp' that include
-;; `coffee-lambda-regexp' then add those tokens to the list.
-;;
-;; Should cover cases like these:
-;;
-;; minus: (x, y) -> x - y
-;; String::length: -> 10
-;; block: ->
-;; print('potion')
-;;
-;; Next we look for any line that starts with `class' or
-;; `coffee-assign-regexp' followed by `{` and drop into a
-;; namespace. This means we search one indentation level deeper for
-;; more assignments and add them to the alist prefixed with the
-;; namespace name.
-;;
-;; Should cover cases like these:
-;;
-;; class Person
-;; print: ->
-;; print 'My name is ' + this.name + '.'
-;;
-;; class Policeman extends Person
-;; constructor: (rank) ->
-;; @rank: rank
-;; print: ->
-;; print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
-;;
-;; TODO:
-;; app = {
-;; window: {width: 200, height: 200}
-;; para: -> 'Welcome.'
-;; button: -> 'OK'
-;; }
-
-(defun coffee-imenu-create-index ()
- "Create an imenu index of all methods in the buffer."
- (interactive)
-
- ;; This function is called within a `save-excursion' so we're safe.
- (goto-char (point-min))
-
- (let ((index-alist '()) assign pos indent ns-name ns-indent)
- ;; Go through every assignment that includes -> or => on the same
- ;; line or starts with `class'.
- (while (re-search-forward
- (concat "^\\(\\s *\\)"
- "\\("
- coffee-assign-regexp
- ".+?"
- coffee-lambda-regexp
- "\\|"
- coffee-namespace-regexp
- "\\)")
- (point-max)
- t)
-
- ;; If this is the start of a new namespace, save the namespace's
- ;; indentation level and name.
- (when (match-string 8)
- ;; Set the name.
- (setq ns-name (match-string 8))
-
- ;; If this is a class declaration, add :: to the namespace.
- (setq ns-name (concat ns-name "::"))
-
- ;; Save the indentation level.
- (setq ns-indent (length (match-string 1))))
-
- ;; If this is an assignment, save the token being
- ;; assigned. `Please.print:` will be `Please.print`, `block:`
- ;; will be `block`, etc.
- (when (setq assign (match-string 3))
- ;; The position of the match in the buffer.
- (setq pos (match-beginning 3))
-
- ;; The indent level of this match
- (setq indent (length (match-string 1)))
-
- ;; If we're within the context of a namespace, add that to the
- ;; front of the assign, e.g.
- ;; constructor: => Policeman::constructor
- (when (and ns-name (> indent ns-indent))
- (setq assign (concat ns-name assign)))
-
- ;; Clear the namespace if we're no longer indented deeper
- ;; than it.
- (when (and ns-name (<= indent ns-indent))
- (setq ns-name nil)
- (setq ns-indent nil))
-
- ;; Add this to the alist. Done.
- (push (cons assign pos) index-alist)))
-
- ;; Return the alist.
- index-alist))
-
-;;
-;; Indentation
-;;
-
-;;; The theory is explained in the README.
-
-(defun coffee-indent-line ()
- "Indent current line as CoffeeScript."
- (interactive)
-
- (if (= (point) (point-at-bol))
- (insert-tab)
- (save-excursion
- (let ((prev-indent (coffee-previous-indent)))
- ;; Shift one column to the left
- (beginning-of-line)
- (insert-tab)
-
- (when (= (point-at-bol) (point))
- (forward-char coffee-tab-width))
-
- ;; We're too far, remove all indentation.
- (when (> (- (current-indentation) prev-indent) coffee-tab-width)
- (backward-to-indentation 0)
- (delete-region (point-at-bol) (point)))))))
-
-(defun coffee-previous-indent ()
- "Return the indentation level of the previous non-blank line."
- (save-excursion
- (forward-line -1)
- (if (bobp)
- 0
- (progn
- (while (and (looking-at "^[ \t]*$") (not (bobp))) (forward-line -1))
- (current-indentation)))))
-
-(defun coffee-newline-and-indent ()
- "Insert a newline and indent it to the same level as the previous line."
- (interactive)
-
- ;; Remember the current line indentation level,
- ;; insert a newline, and indent the newline to the same
- ;; level as the previous line.
- (let ((prev-indent (current-indentation)))
- (delete-horizontal-space t)
- (newline)
- (insert-tab (/ prev-indent coffee-tab-width))
-
- ;; We need to insert an additional tab because the last line was special.
- (when (coffee-line-wants-indent)
- (insert-tab)))
-
- ;; Last line was a comment so this one should probably be,
- ;; too. Makes it easy to write multi-line comments (like the one I'm
- ;; writing right now).
- (when (coffee-previous-line-is-comment)
- (insert "# ")))
-
-;; Indenters help determine whether the current line should be
-;; indented further based on the content of the previous line. If a
-;; line starts with `class', for instance, you're probably going to
-;; want to indent the next line.
-
-(defvar coffee-indenters-bol '("class" "for" "if" "try")
- "Keywords or syntax whose presence at the start of a line means the
-next line should probably be indented.")
-
-(defun coffee-indenters-bol-regexp ()
- "Builds a regexp out of `coffee-indenters-bol' words."
- (regexp-opt coffee-indenters-bol 'words))
-
-(defvar coffee-indenters-eol '(?> ?{ ?\[)
- "Single characters at the end of a line that mean the next line
-should probably be indented.")
-
-(defun coffee-line-wants-indent ()
- "Return t if the current line should be indented relative to the
-previous line."
- (interactive)
-
- (save-excursion
- (let ((indenter-at-bol) (indenter-at-eol))
- ;; Go back a line and to the first character.
- (forward-line -1)
- (backward-to-indentation 0)
-
- ;; If the next few characters match one of our magic indenter
- ;; keywords, we want to indent the line we were on originally.
- (when (looking-at (coffee-indenters-bol-regexp))
- (setq indenter-at-bol t))
-
- ;; If that didn't match, go to the back of the line and check to
- ;; see if the last character matches one of our indenter
- ;; characters.
- (when (not indenter-at-bol)
- (end-of-line)
-
- ;; Optimized for speed - checks only the last character.
- (let ((indenters coffee-indenters-eol))
- (while indenters
- (if (/= (char-before) (car indenters))
- (setq indenters (cdr indenters))
- (setq indenter-at-eol t)
- (setq indenters nil)))))
-
- ;; If we found an indenter, return `t'.
- (or indenter-at-bol indenter-at-eol))))
-
-(defun coffee-previous-line-is-comment ()
- "Return t if the previous line is a CoffeeScript comment."
- (save-excursion
- (forward-line -1)
- (coffee-line-is-comment)))
-
-(defun coffee-line-is-comment ()
- "Return t if the current line is a CoffeeScript comment."
- (save-excursion
- (backward-to-indentation 0)
- (= (char-after) (string-to-char "#"))))
-
-;;
-;; Define Major Mode
-;;
-
-(unless (fboundp 'prog-mode) (defalias 'prog-mode 'fundamental-mode))
-
-(defvar electric-indent-inhibit)
-
-;;;###autoload
-(define-derived-mode coffee-mode prog-mode
- "Coffee"
- "Major mode for editing CoffeeScript."
-
- ;; code for syntax highlighting
- (setq font-lock-defaults '((coffee-font-lock-keywords)))
-
- ;; perl style comment: "# ..."
- (set (make-local-variable 'comment-start) "#")
-
- ;; Indentation.
- (set (make-local-variable 'indent-line-function) 'coffee-indent-line)
- (set (make-local-variable 'tab-width) coffee-tab-width)
- ;; Because indentation is not redundant, we cannot safely reindent code.
- (setq-local electric-indent-inhibit t)
-
- ;; imenu
- (make-local-variable 'imenu-create-index-function)
- (setq imenu-create-index-function 'coffee-imenu-create-index)
-
- ;; no tabs
- (setq indent-tabs-mode nil))
-
-;;
-;; Compile-on-Save minor mode
-;;
-
-(defvar coffee-cos-mode-line " CoS")
-(make-variable-buffer-local 'coffee-cos-mode-line)
-
-(define-minor-mode coffee-cos-mode
- "Toggle compile-on-save for coffee-mode."
- :group 'coffee-cos :lighter coffee-cos-mode-line
- (cond
- (coffee-cos-mode
- (add-hook 'after-save-hook 'coffee-compile-file nil t))
- (t
- (remove-hook 'after-save-hook 'coffee-compile-file t))))
-
-;;
-;; On Load
-;;
-
-;; Run coffee-mode for files ending in .coffee.
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.coffee\\'" . coffee-mode))
-;;;###autoload
-(add-to-list 'auto-mode-alist '("Cakefile" . coffee-mode))
-
-(provide 'coffee-mode)
-;;; coffee-mode.el ends here
diff --git a/packages/coffee-mode/examples/basic.coffee
b/packages/coffee-mode/examples/basic.coffee
deleted file mode 100644
index d275632..0000000
--- a/packages/coffee-mode/examples/basic.coffee
+++ /dev/null
@@ -1,118 +0,0 @@
-# These examples are taken from
-# http://jashkenas.github.com/coffee-script/
-
-song = ["do", "re", "mi", "fa", "so"]
-
-ages = {
- max: 10
- ida: 9
- tim: 11
-}
-
-matrix = [
- 1, 0, 1
- 0, 0, 1
- 1, 1, 0
-]
-
-eldest = if 24 > 21 then "Liz" else "Ike"
-
-six = (one = 1) + (two = 2) + (three = 3)
-
-My.mood = greatly_improved if true
-
-# Unfancy JavaScript
-if happy and knows_it
- cha_cha_cha()
- false
-
-Account = (customer, cart) ->
- @customer: customer
- @cart: cart
-
- $('.shopping_cart').bind 'click', (event) =>
- @customer.purchase @cart
-
-class Animal
- move: (meters) ->
- alert @name + " moved " + meters + "m."
-
- randomify: ->
- @name.replace(/^[\w_-]*$/g, "-")
-
-class Snake extends Animal
- constructor: (name) ->
- @name: name
-
- move: ->
- alert "Slithering..."
- super 5
-
-class Horse extends Animal
- constructor: (name) ->
- @name: name
-
- move: ->
- alert "Galloping..."
- super 45
-
-sam = new Snake "Sammy the Python"
-tom = new Horse "Tommy the Palomino"
-
-sam.move()
-tom.move()
-if car.speed < speed_limit then accelerate()
-
-print "My name is " + @name
-
-gold = silver = the_field = "unknown"
-
-award_medals = (first, second, rest...) ->
- gold: first
- silver: second
- the_field: rest
-
-contenders = [
- "Michael Phelps"
- "Liu Xiang"
-]
-
-award_medals contenders...
-
-alert "Gold: " + gold
-alert "Silver: " + silver
-alert "The Field: " + the_field
-
-# Eat lunch.
-# what up
-# love it.
-lunch = eat food for food in ['toast', 'cheese', 'wine']
-
-$('#demo').click ->
- asd
-# sup
- # asd
- # asdasd
-blah = true
-
-okay
-
-
-# Naive collision detection.
-for roid in asteroids
- for roid2 in asteroids when roid isnt roid2
- roid.explode() if roid.overlaps roid2
-
-years_old = max: 10, ida: 9, tim: 11
-
-ages = for child, age of years_old
- child + " is " + age
-
-grade = (student) ->
- if student.excellent_work
- "A+"
- else if student.okay_stuff
- if student.tried_hard then "B" else "B-"
- else
- "C"
-
diff --git a/packages/coffee-mode/examples/edge.coffee
b/packages/coffee-mode/examples/edge.coffee
deleted file mode 100644
index 7682a58..0000000
--- a/packages/coffee-mode/examples/edge.coffee
+++ /dev/null
@@ -1,16 +0,0 @@
-# Edge cases
-
-if string.match /\// or string.match /\x1b/ or string.match /a\/b/
- console.log "matched"
-
-string = "Something with a \"double quote"
-console.log string
-
-string = 'Something with a \'single quote'
-console.log string
-
-# TODO
-heredoc = """
- Heredoc with a " double quote
-"""
-console.log heredoc
diff --git a/packages/coffee-mode/examples/imenu.coffee
b/packages/coffee-mode/examples/imenu.coffee
deleted file mode 100644
index fdf0025..0000000
--- a/packages/coffee-mode/examples/imenu.coffee
+++ /dev/null
@@ -1,33 +0,0 @@
-# Testing imenu
-regexp = /asdas/
-two = 4 / 2
-
-minus = (x, y) -> x - y
-
-String::length = -> 10
-
-class Person
- print: ->
- print 'My name is ' + this.name + '.'
-
-app =
- window: {width: 200, height: 200}
- para: 'Welcome.'
- button: 'OK'
-
-block = ->
- print('potion')
-
-Please = {}
-Please.print = (word) ->
- print(word)
-
-HomePage::get = (url) ->
- session: url.query.session if url.query?
-
-class Policeman extends Person
- constructor: (rank) ->
- @rank: rank
-
- print: ->
- print 'My name is ' + this.name + " and I'm a " + this.rank + '.'
diff --git a/packages/compact-docstrings/.gitignore
b/packages/compact-docstrings/.gitignore
deleted file mode 100644
index 64b1053..0000000
--- a/packages/compact-docstrings/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/.cask/
diff --git a/packages/compact-docstrings/Cask b/packages/compact-docstrings/Cask
deleted file mode 100644
index 9fd0c8c..0000000
--- a/packages/compact-docstrings/Cask
+++ /dev/null
@@ -1,6 +0,0 @@
-(source gnu)
-(source melpa)
-
-(package-file "compact-docstrings.el")
-
-(development)
diff --git a/packages/compact-docstrings/Makefile
b/packages/compact-docstrings/Makefile
deleted file mode 100644
index 4677e7f..0000000
--- a/packages/compact-docstrings/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-EMACS ?= emacs
-CASK = env --unset INSIDE_EMACS EMACS=$(EMACS) cask
-
-screenshot:
- $(CASK) exec $(EMACS) --debug-init -Q \
- -L . -l etc/screenshot.el
diff --git a/packages/compact-docstrings/README.rst
b/packages/compact-docstrings/README.rst
deleted file mode 100644
index 7a56b5a..0000000
--- a/packages/compact-docstrings/README.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-=============================
- Compact docstrings in Emacs
-=============================
-
-Shrink blank lines in docstrings and doc comments
-
-.. image:: etc/compact-docstrings.png
-
-Setup
-=====
-
-Enable locally with ``compact-docstrings-mode``::
-
- (add-hook 'some-mode-hook #'compact-docstrings-mode)
-
-Enable globally (in all programming modes) with
``global-compact-docstrings-mode``::
-
- (add-hook 'after-init-hook #'global-compact-docstrings-mode)
-
-Customization
-=============
-
-Enable compaction of all comments and strings by setting
``compact-docstrings-only-doc-blocks`` to ``nil``. Change the compact line
height by customizing ``compact-docstrings-face``.
diff --git a/packages/compact-docstrings/compact-docstrings.el
b/packages/compact-docstrings/compact-docstrings.el
deleted file mode 100644
index 7df3537..0000000
--- a/packages/compact-docstrings/compact-docstrings.el
+++ /dev/null
@@ -1,90 +0,0 @@
-;;; compact-docstrings.el --- Shrink blank lines in docstrings and doc
comments -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2016-2020 Free Software Foundation, Inc.
-
-;; Author: Clément Pit-Claudel <clement.pitclaudel@live.com>
-;; Maintainer: Clément Pit-Claudel <clement.pitclaudel@live.com>
-;; URL: https://github.com/cpitclaudel/compact-docstrings
-;; Package-Version: 0.2
-;; Keywords: convenience, faces, lisp, maint, c
-
-;; 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:
-
-;; Shrink blank lines in docstrings and doc comments
-;;
-;; Enable locally with `compact-docstrings-mode':
-;; (add-hook 'some-mode-hook #'compact-docstrings-mode)
-;;
-;; Enable globally (in all programming modes) with
-;; (add-hook 'after-init-hook #'global-compact-docstrings--mode)
-
-;;; Code:
-
-(defgroup compact-docstrings nil
- "Shrink empty lines in docstrings and doc comments."
- :group 'faces)
-
-(defface compact-docstrings-face
- '((t :height 0.5))
- "Face applied to blank lines in docstrings.")
-
-(defcustom compact-docstrings-only-doc-blocks t
- "When nil, also shrink blank lines in regular strings and comments."
- :type 'boolean)
-
-(defun compact-docstrings--matcher (bound)
- "Find blank line in docstring, looking in point .. BOUND."
- (let ((found nil))
- (while (and (not found) (re-search-forward "^\n" bound t))
- (let ((syntax (syntax-ppss)))
- (when (and (or (nth 3 syntax) ;; In string
- (nth 4 syntax)) ;; In comment
- (or (not compact-docstrings-only-doc-blocks)
- (let ((face (get-text-property (point) 'face)))
- (or (eq face 'font-lock-doc-face)
- (and (listp face) (memq 'font-lock-doc-face
face))))))
- (setq found t))))
- found))
-
-(defconst compact-docstrings--keywords
- '((compact-docstrings--matcher 0 'compact-docstrings-face prepend)) 'append)
-
-;;;###autoload
-(define-minor-mode compact-docstrings-mode
- "Shrink empty lines in docstrings and doc comments."
- :lighter " →∥←"
- (if compact-docstrings-mode
- (font-lock-add-keywords nil compact-docstrings--keywords 'append)
- (font-lock-remove-keywords nil compact-docstrings--keywords))
- (if (fboundp #'font-lock-flush)
- (font-lock-flush)
- (with-no-warnings (font-lock-fontify-buffer))))
-
-(defun compact-docstrings--mode-on ()
- "Turn on `compact-docstrings-mode', if appropriate."
- (when (derived-mode-p #'prog-mode)
- (compact-docstrings-mode)))
-
-;;;###autoload
-(defalias 'shrink-docstrings #'compact-docstrings--mode-on)
-
-;;;###autoload
-(define-globalized-minor-mode global-compact-docstrings-mode
compact-docstrings-mode
- compact-docstrings--mode-on
- :init-value nil)
-
-(provide 'compact-docstrings)
-;;; compact-docstrings.el ends here
diff --git a/packages/compact-docstrings/etc/after.py
b/packages/compact-docstrings/etc/after.py
deleted file mode 100644
index 26a7ae2..0000000
--- a/packages/compact-docstrings/etc/after.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# With compact docstrings
-def complex(real=0.0, imag=0.0):
- """Form a complex number.
-
- Keyword arguments:
- real -- the real part (default 0.0)
- imag -- the imaginary part (default 0.0)
-
- Some more description text, artificially
- lengthened to make it span two lines.
-
- Another paragraph.
- """
- pass
diff --git a/packages/compact-docstrings/etc/before.py
b/packages/compact-docstrings/etc/before.py
deleted file mode 100644
index 66bebaa..0000000
--- a/packages/compact-docstrings/etc/before.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# With regular docstrings
-def complex(real=0.0, imag=0.0):
- """Form a complex number.
-
- Keyword arguments:
- real -- the real part (default 0.0)
- imag -- the imaginary part (default 0.0)
-
- Some more description text, artificially
- lengthened to make it span two lines.
-
- Another paragraph.
- """
- pass
diff --git a/packages/compact-docstrings/etc/compact-docstrings-screenshot.el
b/packages/compact-docstrings/etc/compact-docstrings-screenshot.el
deleted file mode 100644
index 6764b07..0000000
--- a/packages/compact-docstrings/etc/compact-docstrings-screenshot.el
+++ /dev/null
@@ -1,99 +0,0 @@
-;;; compact-docstrings-screenshot.el --- Make a screenshot of
compact-docstrings
-
-;; Copyright (C) 2016 Free Software Foundation, Inc.
-
-;; 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 just makes a screenshot for this package's homepage.
-
-;;; Code:
-
-(defvar cds-fringe-width 6)
-
-(defconst cds-script-dir
- (file-name-directory (or load-file-name
- buffer-file-name)))
-
-(defun cds-cleanup ()
- (dolist (buffer (buffer-list))
- (kill-buffer buffer)))
-
-(defun cds-prepare-UI ()
- "Prepare UI for taking a screenshot."
- (ido-mode)
- (tool-bar-mode -1)
- (menu-bar-mode -1)
- (scroll-bar-mode -1)
- (column-number-mode)
- (fringe-mode (cons cds-fringe-width cds-fringe-width))
- (blink-cursor-mode -1)
- (setq-default cursor-type 'bar
- split-width-threshold 80
- truncate-partial-width-windows t
- frame-title-format (format "Compact docstrings @ Emacs %s"
emacs-version)
- x-gtk-use-system-tooltips nil)
- (load-theme 'tango t)
- ;; (set-face-attribute 'tooltip nil :height 60)
- (set-face-attribute 'match nil :background "yellow1")
- (set-face-attribute 'default nil :family "Ubuntu Mono" :height 110)
- (set-face-attribute 'mode-line nil :foreground "gray60" :background "black")
- (set-face-attribute 'mode-line-inactive nil :foreground "gray60" :background
"#404045")
- (set-face-attribute 'mode-line-buffer-id nil :foreground "#eab700")
- (set-fontset-font t 'unicode "Ubuntu Mono")
- (set-frame-size nil 100 13)
- (redisplay t))
-
-(defun cds-load-package ()
- "Load package."
- (package-initialize)
- (load-library "compact-docstrings"))
-
-(defun cds-load-example ()
- "Prepare files and layout windows."
- (find-file "etc/before.py")
- (setq buffer-name "Regular docstrings")
- (find-file-other-window "after.py")
- (setq buffer-name "Compact docstrings")
- (compact-docstrings-mode))
-
-(defun cds-prepare-screenshot-1 ()
- "Prepare for taking a screenshot."
- (cds-prepare-UI)
- (cds-load-package)
- (cds-load-example)
- (message nil))
-
-(defun cds-save-screenshot ()
- "Save screenshot of current frame."
- (let ((fname (expand-file-name "compact-docstrings.png" cds-script-dir)))
- (process-lines "import" "-window" (frame-parameter nil 'outer-window-id)
- fname)
- (process-lines "mogrify" "-strip" "-matte"
- "-bordercolor" (face-attribute 'fringe :background)
- "-border" (format "0x%d" cds-fringe-width) fname)
- (process-lines "optipng" "-o3" fname))
- (kill-emacs))
-
-(defun cds-take-screenshot ()
- (cds-prepare-screenshot-1)
- (redisplay t)
- (run-with-idle-timer 1 nil #'cds-save-screenshot))
-
-(print default-directory)
-(run-with-idle-timer 0 nil #'cds-take-screenshot)
-
-(provide 'compact-docstrings-screenshot)
-;; compact-docstrings-screenshot.el ends here
diff --git a/packages/compact-docstrings/etc/compact-docstrings.png
b/packages/compact-docstrings/etc/compact-docstrings.png
deleted file mode 100644
index fd86dd3..0000000
Binary files a/packages/compact-docstrings/etc/compact-docstrings.png and
/dev/null differ
diff --git a/packages/company/.dir-locals.el b/packages/company/.dir-locals.el
deleted file mode 100644
index 79d9a12..0000000
--- a/packages/company/.dir-locals.el
+++ /dev/null
@@ -1,4 +0,0 @@
-((nil . ((indent-tabs-mode . nil)
- (fill-column . 80)
- (sentence-end-double-space . t)
- (emacs-lisp-docstring-fill-column . 75))))
diff --git a/packages/company/.elpaignore b/packages/company/.elpaignore
deleted file mode 100644
index 2203be3..0000000
--- a/packages/company/.elpaignore
+++ /dev/null
@@ -1,5 +0,0 @@
-.travis.yml
-.gitignore
-Makefile
-test
-company-tests.el
diff --git a/packages/company/.gitignore b/packages/company/.gitignore
deleted file mode 100644
index 2ecd291..0000000
--- a/packages/company/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.elc
-ert.el
diff --git a/packages/company/.travis.yml b/packages/company/.travis.yml
deleted file mode 100644
index 18e928d..0000000
--- a/packages/company/.travis.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-language: generic
-
-env:
- global:
- - CURL="curl -fsSkL --retry 9 --retry-delay 9"
- matrix:
- - EMACS_VERSION=24.5
- - EMACS_VERSION=25.3
- - EMACS_VERSION=26.1
- - EMACS_VERSION=master
-
-matrix:
- allow_failures:
- - env: EMACS_VERSION=master
-
-install:
- - $CURL -O
https://github.com/npostavs/emacs-travis/releases/download/bins/emacs-bin-${EMACS_VERSION}.tar.gz
- - tar -xaf emacs-bin-${EMACS_VERSION}.tar.gz -C /
- - export EMACS=/tmp/emacs/bin/emacs
- - $EMACS --version
-
-script:
- make test-batch EMACS=${EMACS}
diff --git a/packages/company/Makefile b/packages/company/Makefile
deleted file mode 100644
index 015f3ac..0000000
--- a/packages/company/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-EMACS=emacs
-
-.PHONY: ert test test-batch
-
-package: *.el
- @ver=`grep -o "Version: .*" company.el | cut -c 10-`; \
- tar cjvf company-$$ver.tar.bz2 --mode 644 $$(find . -name \*.el)
-
-elpa: *.el
- @version=`grep -o "Version: .*" company.el | cut -c 10-`; \
- dir=company-$$version; \
- mkdir -p "$$dir"; \
- cp $$(find . -name \*.el) company-$$version; \
- echo "(define-package \"company\" \"$$version\" \
- \"Modular in-buffer completion framework\")" \
- > "$$dir"/company-pkg.el; \
- tar cvf company-$$version.tar --mode 644 "$$dir"
-
-clean:
- @rm -rf company-*/ company-*.tar company-*.tar.bz2 *.elc ert.el
-
-test:
- ${EMACS} -Q -nw -L . -l test/all.el \
- --eval "(let (pop-up-windows) (ert t))"
-
-test-batch:
- ${EMACS} -Q --batch -L . -l test/all.el \
- --eval "(ert-run-tests-batch-and-exit '(not (tag interactive)))"
-
-compile:
- ${EMACS} -Q --batch -L . -f batch-byte-compile company.el company-*.el
diff --git a/packages/company/NEWS.md b/packages/company/NEWS.md
deleted file mode 100644
index f1f1d05..0000000
--- a/packages/company/NEWS.md
+++ /dev/null
@@ -1,520 +0,0 @@
-# History of user-visible changes
-
-## 2020-07-26 (0.9.13)
-
-* `company-clang`: error handling is more permissive.
-* `company-tng` stops disabling `post-completion` in backends
- ([#946](https://github.com/company-mode/company-mode/pull/946)). Instead,
- `company-tng-configure-default` disables snippet expansion in most popular
- backends. If a backend you use needs this and is not covered, and you use
- `company-tng`, disable snippet insertion by customizing a relevant option
- provided by the backend. The result is better compatibility with LSP backends
- because they currently depend on `post-completion` in all cases.
-* `company-keywords`: additions for C and C++.
-* `company-yasnippet` supports the `doc-buffer` action.
-* `company-bbdb` supports more headers.
-
-## 2020-02-07 (0.9.12)
-
-* Tooltip rendering bugfix.
-* `company-indent-or-complete-common` is better compatible with
- `indent-for-tab-command`
-
([comment](https://github.com/company-mode/company-mode/issues/94#issuecomment-571265393)).
-
-## 2020-01-03 (0.9.11)
-
-* New value for option `company-show-numbers` to show numbers on the left.
-* `company-gtags` has some minor fixes.
-* Face definitions have moved to a separate group: `company-faces`.
-* `company-capf`'s `:exit-function` handling has been improved
- ([#935](https://github.com/company-mode/company-mode/issues/935)).
-* New user option `company-clang-use-compile-flags-txt`
- ([#933](https://github.com/company-mode/company-mode/issues/933)).
-* Support for completion style specific sorting (Emacs 27 feature).
-* Snippet/template field interaction is inhibited while completion is active
- (where by default `TAB` calls `company-complete-common`, clashing with
snippet
- map binding `TAB` to "jump to the next field"). Affects both
- `company-template` and `yasnippet` (requires version 0.14.0).
-
-## 2019-04-15 (0.9.10)
-
-* `company-clang`: better compatibility with Clang 8
- ([#885](https://github.com/company-mode/company-mode/issues/885)).
-* The change in `company-clang` regarding identity #defines is reverted because
- it affected other completions as well
- ([#884](https://github.com/company-mode/company-mode/issues/884)).
-* `company-idle-delay` now accepts a function which generates the idle time or
- nil indicating no idle completion.
-* Add custom variable `company-show-numbers-function` to make numbers of
- candidates customizable.
-* When a symbol is already typed in full, calling `M-x company-complete` will
- now run its post-completion action (e.g. inserting method parameters
- template). Calling `M-x company-manual-begin` or invoking a backend command
- directly will show the popup
- ([#150](https://github.com/company-mode/company-mode/issues/150),
- [#476](https://github.com/company-mode/company-mode/issues/476)).
-
-## 2018-12-13 (0.9.9)
-
-* Fix for the changes in the previous release.
-* New hook `company-after-completion-hook`.
-* `company-clang` removes identity preprocessor #defines from completions
- ([#841](https://github.com/company-mode/company-mode/issues/841)).
-
-## 2018-12-08 (0.9.8)
-
-* CAPF backend fixed to use the right `:exit-function`. It can now safely be a
- closure with lexical context capturing the buffer state at the moment when
the
- completion table was returned
- ([#845](https://github.com/company-mode/company-mode/pull/845)).
-
-## 2018-11-06 (0.9.7)
-
-* For more sophisticated highlighting in non-prefix completion, a backend may
- now respond to a `match` request with a list of regions. See
- `company-backends`.
- ([#798](https://github.com/company-mode/company-mode/issues/798),
- [#762](https://github.com/company-mode/company-mode/issues/762))
-* The `company-capf` backend will pick up on a `:company-match` metadata
element
- on the capf function (similar to `:company-location` or
`:company-doc-buffer`)
- and use it as a response to aforementioned `match` request.
-* `company-cmake` supports completion inside string interpolations
- ([#714](https://github.com/company-mode/company-mode/pull/714)).
-* Workaround for the conflict between `inferior-python-mode`'s completion code
- and `company-sort-by-occurrence`.
-* In Emacs 26 and newer, `company-css` is removed from `company-backends`.
- `company-capf` is used instead.
-* Same for `company-nxml`.
-
-## 2018-02-23 (0.9.6)
-
-* Workaround for Emacs' ([bug#23980](https://debbugs.gnu.org/23980)) triggered
- in combination with Flyspell.
-
-## 2018-02-18 (0.9.5)
-
-* The most common case of tooltip flickering with asynchronous backends (and
- disabled built-in cache) is fixed
- ([#510](https://github.com/company-mode/company-mode/issues/510),
- [#654](https://github.com/company-mode/company-mode/issues/654)).
-* `company-keywords` added entries for `go-mode`, `swift-mode` and
- `kotlin-mode`.
-* Native line numbers compatibility fixes.
-* `company-dabbrev` and `company-dabbrev-code` are more responsive when user
- input is pending
- ([#720](https://github.com/company-mode/company-mode/pull/720)).
-* New feature `company-tng`. It contains a frontend and some helper code.
- The frontend triggers insertion of the candidate as soon as it's selected, so
- you only need to press TAB. Add `(company-tng-configure-default)` to your
- init script to give it a try
- ([#706](https://github.com/company-mode/company-mode/issues/706)).
-* New user option `company-tooltip-maximum-width`.
-
-## 2017-07-15 (0.9.4)
-
-* Compatibility with native line numbers display in Emacs 26.
-* `company-files` allows completion after `=`.
-* `company-template` has a new shortcut (`C-d`) for deleting an unmodified
- template field while cursor is on it.
-
-## 2017-03-29 (0.9.3)
-
-* New user option `company-echo-truncate-lines`.
-* `company-auto-complete` improved compatibility with `electric-pair-mode`.
-* Use of `overriding-terminal-local-map` does not disable completion.
-* `company-clang` and `company-gtags` can work over Tramp.
-* New frontend `company-preview-common-frontend`.
-* `company-clang` calls Clang using a pipe instead of pty.
-* The minimum required version of Emacs is now 24.3.
-
-## 2016-11-14 (0.9.2)
-
-* Miscellaneous fixes and docstring improvements.
-
-## 2016-11-12 (0.9.1)
-
-* `company-indent-or-complete-common` skips trying to indent if
- `indent-line-function` is `indent-relative` or `indent-relative-maybe`.
-* Better visualization of search matches. New face
`company-tooltip-search-selection`.
-* New user option `company-files-exclusions`.
-* `company-next-page` and `company-previous-page` adhere to
- `company-selection-wrap-around` docstring more closely and only wrap around
- when the selection is at the start of the end of the list.
-* `company-pseudo-tooltip-unless-just-one-frontend-with-delay` handles custom
- frontends derived from `company-preview-frontend` better.
-* `company-idle-delay` is automatically adjusted to a non-zero value.
-
-## 2016-06-23 (0.9.0)
-
-* Group of backends can now contain keyword `:separate`, which makes candidates
- from different backends sorted separately in the combined list.
-* New frontend `company-pseudo-tooltip-unless-just-one-frontend-with-delay`.
-* New transformer `company-sort-prefer-same-case-prefix`.
-* The value of `company-dabbrev-ignore-buffers` can also be a function.
-* `company-files` has been moved to right after `company-capf` in
- `company-backends`
- ([#463](https://github.com/company-mode/company-mode/issues/463)).
-* `company-semantic-insert-arguments`: New option. Like in `company-clang`.
-* `company-semantic-begin-after-member-access`: New option. Similar to the one
- in `company-clang`.
-* `company-capf` accepts `:company-prefix-length` property value.
-* New face `company-tooltip-annotation-selection`, used for the annotation in
- the selected tooltip line.
-* `company-clang-objc-templatify` has been renamed to
- `company-template-objc-templatify`.
-* New user option `company-etags-everywhere`.
-* `company-yasnippet` supports `yas-key-syntaxes` better. But we use them in
the
- reverse order, preferring the longest key prefix that matches anything. And
we
- only consider trigger key prefixes that are at least as long as the symbol at
- point, which effectively means skipping the `"w"` element
- ([#422](https://github.com/company-mode/company-mode/issues/422)).
-* New user option `company-search-regexp-function`.
-* Completion is not started automatically when a keyboard macro is being
- recorded ([#374](https://github.com/company-mode/company-mode/issues/374)).
-* New command `company-indent-or-complete-common`.
-* Backend command `doc-buffer` now can also return a cons of buffer and window
- start position.
-* Backend command `ignore-case` has been documented.
-* `company-template-c-like-templatify` does not replace the default argument
- values with `argN` anymore
- ([#336](https://github.com/company-mode/company-mode/issues/336)). This
- affects `company-clang` and all third-party backends that use this function.
-* Likewise for `company-clang-objc-templatify`.
-* `company-template-add-field` calling convention has changed.
-* New user option `company-dabbrev-ignore-invisible`.
-* `company-ropemacs` was removed. `ropemacs` supports completion via
- `completion-at-point-functions` starting with version 0.8.
-* `company-pysmell` was removed.
-* `company-select-next`, `company-select-previous`,
- `company-select-next-or-abort`, `company-select-previous-or-abort` and
- `company-complete-common-or-cycle` accept a numeric argument.
-* The documentation buffer window can be scrolled with the mouse wheel.
-* New command `company-diag`. Use it in bug reports.
-
-## 2015-02-02 (0.8.10)
-
-* New variable `company-lighter-base`.
-* Better tracking of the current selection.
-* Pressing `M-0`...`M-9` works in the search mode.
-* Pressing `<up>` or `<down>` doesn't quit the search mode.
-
-## 2015-01-23 (0.8.9)
-
-* New commands `company-next-page` and `company-previous-page`, remapping
- `scroll-up-command` and `scroll-down-command` during completion.
-
-## 2015-01-13 (0.8.8)
-
-* Pressing `M-n` or `M-p` doesn't quit the search mode.
-* New command `company-complete-common-or-cycle`. No default binding.
-* `company-search-toggle-filtering` replaced `company-search-kill-others`.
-* Quitting the search mode resets the filtering.
-* Pressing `backspace` in the search mode deletes the character at the end of
- the search string.
-* `company-semantic` displays function arguments as annotations.
-* New user option, `company-bbdb-modes`.
-* `company-show-numbers` and `company-complete-number` now use visual numbering
- of the candidates, taking into account only the ones currently displayed.
-* `company-complete-number` can be bound to keypad numbers directly, with or
- without modifiers.
-* `company-cmake` expands `<LANG>` and `<CONFIG>` placeholders inside variable
- names.
-
-## 2014-10-15 (0.8.6)
-
-* `company-clang` and `company-template-c-like-templatify` support templated
- functions and arguments.
-* `company-dabbrev` ignores "uninteresting" buffers by default. Depends on the
- new user option, `company-dabbrev-ignore-buffers`.
-* `company-files` checks directory's last modification time.
-* `company-files` supports relative paths and Windows drive letters.
-
-## 2014-08-13 (0.8.4)
-
-* `company-ropemacs` is only used when `ropemacs-mode` is on.
-* `company-gtags` is enabled in all `prog-mode` derivatives by default.
-* `company-end-of-buffer-workaround` is not used anymore.
-* `company-begin-commands` includes some of `cc-mode` commands.
-
-## 2014-08-27 (0.8.3)
-
-* On Emacs 24.4 or newer, tooltip positioning takes line-spacing into account.
-* New face `company-tooltip-search`, used for the search string in the tooltip.
-* The default value of `company-dabbrev-minimum-length` is set to 4,
independent
- of the `company-minimum-prefix-length` value.
-
-## 2014-07-26 (0.8.2)
-
-* New user option `company-occurrence-weight-function`, allowing to tweak the
- behavior of the transformer `company-sort-by-occurrence`.
-* Setting `company-idle-delay` to `t` is deprecated. Use the value 0 instead.
-
-## 2014-07-01 (0.8.1)
-
-* `company-require-match` is not in effect when the new input doesn't continue
- the previous prefix, and that prefix was a match.
-* The meaning of `company-begin-commands` value t has slightly changed.
-* New transformer, `company-sort-by-backend-importance`.
-* When grouped back-ends are used, the back-end of the current candidate is
- indicated in the mode-line, enclosed in angle brackets.
-* New user option `company-gtags-insert-arguments`, t by default.
-* `company-css` knows about CSS3.
-* `company-gtags` supports `meta` and `annotation`.
-* User option `company-dabbrev-code-other-buffers` can have a new value:
`code`.
-* New user option `company-tooltip-flip-when-above`.
-* `company-clang` uses the standard header search paths by default.
-* `C-h` is bound to `company-show-doc-buffer` (like `f1`).
-
-## 2014-04-19 (0.8.0)
-
-* `company-capf` is included in `company-backends` in any supported Emacs
- version (>= 24.1). `company-elisp` goes before it if Emacs version is < 24.4.
-* New user option `company-clang-insert-arguments`, by default t.
-* Default value of `company-idle-delay` lowered to `0.5`.
-* New user option `company-tooltip-minimum-width`, by default 0.
-* New function `company-grab-symbol-cons`.
-* `company-clang` fetches completion candidates asynchronously.
-* Added support for asynchronous back-ends (experimental).
-* Support for back-end command `crop` dropped (it was never documented).
-* Support for Emacs 23 dropped.
-* New user option `company-abort-manual-when-too-short`.
-
-## 2014-03-25 (0.7.3)
-
-* New user option `company-etags-ignore-case`.
-
-## 2014-03-19 (0.7.2)
-
-* Support for Emacs 22 officially dropped.
-* `company-clang` supports `indent-tabs-mode` and multibyte chars before point.
-
-## 2014-03-18 (0.7.1)
-
-* Group of back-ends can now contain keyword `:with`, which makes all back-ends
- after it to be skipped for prefix calculation.
-* New function `company-version`.
-* New bundled back-end `company-yasnippet`.
-* Completion candidates returned from grouped back-ends are tagged to remember
- which back-end each came from.
-* New user option `company-tooltip-align-annotations`, off by default.
-* New bundled back-end `company-bbdb`.
-
-## 2014-02-18 (0.7)
-
-* New back-end command, `match`, for non-prefix completion.
-* New user option `company-continue-commands`. The default value aborts
- completion on buffer saving commands.
-* New back-end command, `annotation`, for text displayed inline in the popup
- that's not a part of completion candidate.
-* `company-capf`, `company-clang` and `company-eclim` use `annotation`.
-* `company-preview*` faces inherit from `company-tooltip-selection` and
- `company-tooltip-common-selection` on light themes.
-* New user option `company-transformers`.
-* First transformer, `company-sort-by-occurrence`.
-* New user options controlling `company-dabbrev` and `company-dabbrev-code`.
-
-## 2014-01-25 (0.6.14)
-
-* The tooltip front-end is rendered with scrollbar, controlled by the user
- option `company-tooltip-offset-display`.
-* The tooltip front-end is rendered with margins, controlled by the user option
- `company-tooltip-margin`.
-
-## 2014-01-14 (0.6.13)
-
-* Experimental support for non-prefix completion.
-* Starting with Emacs version 24.4, `company-capf` is included in
- `company-backends` and replaces `company-elisp`.
-* `company-capf` supports completion tables that return non-default boundaries.
-* `company-elisp` is enabled in `inferior-emacs-lisp-mode`.
-
-## 2013-09-28 (0.6.12)
-
-* Default value of `company-begin-commands` changed to `(self-insert-command)`.
-* Further improvement in `org-indent-mode` compatibility.
-
-## 2013-08-18 (0.6.11)
-
-* `company-template-c-like-templatify` removes all text after closing paren,
for
- use in backends that display additional info there.
-* `company-cmake` is now bundled.
-* Better `linum` compatibility in Emacs <= 24.2.
-* `company-global-modes`: New option.
-
-## 2013-05-26 (0.6.10)
-
-* Plays nicer with `org-indent-mode`.
-* Works in horizontally scrolled windows.
-
-## 2013-05-10 (0.6.9)
-
-* `company-capf` respects `:exit-function` completion property.
-* `company-backends`: `prefix` command can return `t` in the cdr.
-* `company-clang-begin-after-member-access`: New option.
-* Mouse click outside the tooltip aborts completion.
-* `company-clang` uses standard input to pass the contents of current buffer to
- Clang 2.9+, otherwise saves the buffer and passes the path to the file.
-* `company-clang-auto-save` option has been removed.
-* Better interaction with `outline-minor-mode`.
-* `company-dabbrev-code` supports all `prog-mode` derivatives.
-
-## 2013-04-16 (0.6.8)
-
-* `company-auto-complete` is disabled by default.
-* `company-auto-complete-chars` default value includes fewer syntax classes.
-* In expanded function calls, arguments skipped by the user default to "argN".
-* `company-eclim` and `company-clang` do not strip argument types from fields.
-* `company-clang` expands function calls for all three modes now.
-* `company-clang` supports `c++-mode` by default.
-
-## 2013-04-05 (0.6.7)
-
-* Two `company-elisp` tweaks.
-
-## 2013-04-01 (0.6.6)
-
-* `company-elisp` doesn't offer completions when typing the name and the
- arguments of a new function or macro definition, allowing to fall back to
- other back-ends like `company-dabbrev-code`.
-
-## 2013-03-30 (0.6.5)
-
-* Fixed keybindings when running in a terminal.
-* `company-elisp-show-locals-first`: new customizable variable.
-* `company-elisp` shows more accurate and comprehensive candidates list.
-
-## 2013-03-26 (0.6.4)
-
-* `company-eclim` shows valid completions after an opening paren.
-* Expanded template does not get removed until the point leaves it. After your
- input the last argument in a method call expanded by `company-eclim`, you can
- press `<tab>` once more, to jump after the closing paren. No other bundled
- back-ends are affected.
-
-## 2013-03-25 (0.6.3)
-
-* New tooltip face colors used on themes with light background.
-* Pseudo-tooltip stays up-to-date when text is inserted after the point.
-* Fixed `company-require-match` mechanics.
-
-## 2013-03-24 (0.6.2)
-
-* `global-company-mode` is now autoloaded.
-
-## 2013-03-23 (0.6.1)
-
-* Documented `init` and `post-completion` back-end commands.
-* `company-eclim` and `company-clang` only expand the template on explicit user
- action (such as `company-complete-{selection,number,mouse}`).
-* `company-template` has some breaking changes. When point is at one of the
- fields, it's displayed at the beginning, not right after it; `<tab>` jumps to
- the next field, `forward-word` and `subword-forward` remappings are removed;
- when you jump to the next field, if the current one hasn't been edited, the
- overlay gets removed but the text remains.
-* `company-eclim` shows method overloads and expands templates for calls.
-* `company-clang-objc-templatify` does not insert spaces after colons anymore.
-* `company-clang` is now only initialized in supported buffers.
- So, no error messages if you don't have Clang until you open a C file.
-* `company-clang` recognizes Clang included in recent Xcode.
-* New commands `company-select-previous-or-abort` and
- `company-select-next-or-abort`, bound to `<up>` and `<down>`.
-
-## 2013-03-19 (0.6)
-
-* Across-the-board bugfixing.
-* `company-pysmell` is not used by default anymore.
-* Loading of `nxml`, `semantic`, `pymacs` and `ropemacs` is now deferred.
-* Candidates from grouped back-ends are merged more conservatively: only
- back-ends that return the same prefix at point are used.
-* `company-clang` now shows meta information, too.
-* Some performance improvements.
-* Fixed two old tooltip annoyances.
-* Instead of `overrriding-terminal-local-map`, we're now using
- `emulation-mode-map-alists` (experimental). This largely means that when the
- completion keymap is active, other minor modes' keymaps are still used, so,
- for example, it's not as easy to accidentally circumvent `paredit-mode`
- when it's enabled.
-* `company-elisp` has seen some improvements.
-* Added `company-capf`: completion adapter using
- `completion-at-point-functions`. (Stefan Monnier)
-* Clang completions now include macros and are case-sensitive.
-* Switching between tag files now works correctly with `company-etags`.
-
-## 2010-02-24 (0.5)
-
-* `company-ropemacs` now provides location and docs. (Fernando H. Silva)
-* Added `company-with-candidate-inserted` macro.
-* Added `company-clang` back-end.
-* Added new mechanism for non-consecutive insertion.
- (So far only used by clang for ObjC.)
-* The semantic back-end now shows meta information for local symbols.
-* Added compatibility for CEDET in Emacs 23.2 and from CVS. (Oleg Andreev)
-
-## 2009-05-07 (0.4.3)
-
-* Added `company-other-backend`.
-* Idle completion no longer interrupts multi-key command input.
-* Added `company-ropemacs` and `company-pysmell` back-ends.
-
-## 2009-04-25 (0.4.2)
-
-* In C modes . and -> now count towards `company-minimum-prefix-length`.
-* Reverted default front-end back to `company-preview-if-just-one-frontend`.
-* The pseudo tooltip will no longer be clipped at the right window edge.
-* Added `company-tooltip-minimum`.
-* Windows compatibility fixes.
-
-## 2009-04-19 (0.4.1)
-
-* Added `global-company-mode`.
-* Performance enhancements.
-* Added `company-eclim` back-end.
-* Added safer workaround for Emacs `posn-col-row` bug.
-
-## 2009-04-18 (0.4)
-
-* Automatic completion is now aborted if the prefix gets too short.
-* Added option `company-dabbrev-time-limit`.
-* `company-backends` now supports merging back-ends.
-* Added back-end `company-dabbrev-code` for generic code.
-* Fixed `company-begin-with`.
-
-## 2009-04-15 (0.3.1)
-
-* Added 'stop prefix to prevent dabbrev from completing inside of symbols.
-* Fixed issues with tabbar-mode and line-spacing.
-* Performance enhancements.
-
-## 2009-04-12 (0.3)
-
-* Added `company-begin-commands` option.
-* Added abbrev, tempo and Xcode back-ends.
-* Back-ends are now interactive. You can start them with M-x backend-name.
-* Added `company-begin-with` for starting company from elisp-code.
-* Added hooks.
-* Added `company-require-match` and `company-auto-complete` options.
-
-## 2009-04-05 (0.2.1)
-
-* Improved Emacs Lisp back-end behavior for local variables.
-* Added `company-elisp-detect-function-context` option.
-* The mouse can now be used for selection.
-
-## 2009-03-22 (0.2)
-
-* Added `company-show-location`.
-* Added etags back-end.
-* Added work-around for end-of-buffer bug.
-* Added `company-filter-candidates`.
-* More local Lisp variables are now included in the candidates.
-
-## 2009-03-21 (0.1.5)
-
-* Fixed elisp documentation buffer always showing the same doc.
-* Added `company-echo-strip-common-frontend`.
-* Added `company-show-numbers` option and M-0 ... M-9 default bindings.
-* Don't hide the echo message if it isn't shown.
-
-## 2009-03-20 (0.1)
-
-* Initial release.
diff --git a/packages/company/README.md b/packages/company/README.md
deleted file mode 100644
index 1e0e5e6..0000000
--- a/packages/company/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-See the [homepage](http://company-mode.github.com/).
-
-[![Build
Status](https://travis-ci.org/company-mode/company-mode.png?branch=master)](https://travis-ci.org/company-mode/company-mode)
-[![Melpa
Status](http://melpa.milkbox.net/packages/company-badge.svg)](http://melpa.milkbox.net/#/company)
diff --git a/packages/company/company-abbrev.el
b/packages/company/company-abbrev.el
deleted file mode 100644
index 386feb6..0000000
--- a/packages/company/company-abbrev.el
+++ /dev/null
@@ -1,50 +0,0 @@
-;;; company-abbrev.el --- company-mode completion backend for abbrev
-
-;; Copyright (C) 2009-2011, 2015 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))))
- (meta (abbrev-expansion arg))))
-
-(provide 'company-abbrev)
-;;; company-abbrev.el ends here
diff --git a/packages/company/company-bbdb.el b/packages/company/company-bbdb.el
deleted file mode 100644
index 7160231..0000000
--- a/packages/company/company-bbdb.el
+++ /dev/null
@@ -1,63 +0,0 @@
-;;; company-bbdb.el --- company-mode completion backend for BBDB in
message-mode
-
-;; Copyright (C) 2013-2014, 2016 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/packages/company/company-capf.el b/packages/company/company-capf.el
deleted file mode 100644
index 7d34f9c..0000000
--- a/packages/company/company-capf.el
+++ /dev/null
@@ -1,208 +0,0 @@
-;;; company-capf.el --- company-mode completion-at-point-functions backend -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2013-2019 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--capf-data-real ()
- (cl-letf* (((default-value 'completion-at-point-functions)
- ;; 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)))
- (completion-at-point-functions (company--capf-workaround))
- (data (run-hook-wrapped 'completion-at-point-functions
- ;; Ignore misbehaving functions.
- #'completion--capf-wrapper 'optimist)))
- (when (and (consp (cdr data)) (integer-or-marker-p (nth 1 data))) data)))
-
-(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
- (let ((f (plist-get (nthcdr 4 company-capf--current-completion-data)
- :annotation-function)))
- (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--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/packages/company/company-clang.el
b/packages/company/company-clang.el
deleted file mode 100644
index d7391b3..0000000
--- a/packages/company/company-clang.el
+++ /dev/null
@@ -1,389 +0,0 @@
-;;; company-clang.el --- company-mode completion backend for Clang -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011, 2013-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 '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, 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-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
- "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)
- 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)))
- (when (and meta (not (string= match meta)))
- (put-text-property 0 1 'meta
- (company-clang--strip-formatting meta)
- match)))
- (push match lines)))
- 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.
- (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 company-clang--version
- (`(apple . ,ver) (>= ver apple-min))
- (`(normal . ,ver) (>= ver min))
- (_ (error "pcase-exhaustive is not in Emacs 24.3!"))))
-
-(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))
- (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))))))))
-
-(provide 'company-clang)
-;;; company-clang.el ends here
diff --git a/packages/company/company-cmake.el
b/packages/company/company-cmake.el
deleted file mode 100644
index 2e69b6d..0000000
--- a/packages/company/company-cmake.el
+++ /dev/null
@@ -1,206 +0,0 @@
-;;; company-cmake.el --- company-mode completion backend for CMake
-
-;; Copyright (C) 2013-2014, 2017-2018 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-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/packages/company/company-css.el b/packages/company/company-css.el
deleted file mode 100644
index c98040b..0000000
--- a/packages/company/company-css.el
+++ /dev/null
@@ -1,446 +0,0 @@
-;;; company-css.el --- company-mode completion backend for css-mode -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011, 2014, 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/packages/company/company-dabbrev-code.el
b/packages/company/company-dabbrev-code.el
deleted file mode 100644
index 6d250ce..0000000
--- a/packages/company/company-dabbrev-code.el
+++ /dev/null
@@ -1,104 +0,0 @@
-;;; company-dabbrev-code.el --- dabbrev-like company-mode backend for code
-*- lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011, 2014 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))))
- (ignore-case company-dabbrev-code-ignore-case)
- (duplicates t)))
-
-(provide 'company-dabbrev-code)
-;;; company-dabbrev-code.el ends here
diff --git a/packages/company/company-dabbrev.el
b/packages/company/company-dabbrev.el
deleted file mode 100644
index 88b7419..0000000
--- a/packages/company/company-dabbrev.el
+++ /dev/null
@@ -1,206 +0,0 @@
-;;; company-dabbrev.el --- dabbrev-like company-mode completion backend -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011, 2014, 2015, 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)
-
-(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)))
- (ignore-case company-dabbrev-ignore-case)
- (duplicates t)))
-
-(provide 'company-dabbrev)
-;;; company-dabbrev.el ends here
diff --git a/packages/company/company-eclim.el
b/packages/company/company-eclim.el
deleted file mode 100644
index 4763e97..0000000
--- a/packages/company/company-eclim.el
+++ /dev/null
@@ -1,186 +0,0 @@
-;;; company-eclim.el --- company-mode completion backend for Eclim
-
-;; Copyright (C) 2009, 2011, 2013, 2015 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:
-;;
-;; Using `emacs-eclim' together with (or instead of) this backend is
-;; recommended, as it allows you to use other Eclim features.
-;;
-;; The alternative backend provided by `emacs-eclim' uses `yasnippet'
-;; instead of `company-template' to expand function calls, and it supports
-;; some languages other than Java.
-
-;;; Code:
-
-(require 'company)
-(require 'company-template)
-(require 'cl-lib)
-
-(defgroup company-eclim nil
- "Completion backend for Eclim."
- :group 'company)
-
-(defun company-eclim-executable-find ()
- (let (file)
- (cl-dolist (eclipse-root '("/Applications/eclipse" "/usr/lib/eclipse"
- "/usr/local/lib/eclipse"))
- (and (file-exists-p (setq file (expand-file-name "plugins"
eclipse-root)))
- (setq file (car (last (directory-files file t "^org.eclim_"))))
- (file-exists-p (setq file (expand-file-name "bin/eclim" file)))
- (cl-return file)))))
-
-(defcustom company-eclim-executable
- (or (bound-and-true-p eclim-executable)
- (executable-find "eclim")
- (company-eclim-executable-find))
- "Location of eclim executable."
- :type 'file)
-
-(defcustom company-eclim-auto-save t
- "Determines whether to save the buffer when retrieving completions.
-eclim can only complete correctly when the buffer has been saved."
- :type '(choice (const :tag "Off" nil)
- (const :tag "On" t)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar-local company-eclim--project-dir 'unknown)
-
-(defvar-local company-eclim--project-name nil)
-
-(declare-function json-read "json")
-(defvar json-array-type)
-
-(defun company-eclim--call-process (&rest args)
- (let ((coding-system-for-read 'utf-8)
- res)
- (require 'json)
- (with-temp-buffer
- (if (= 0 (setq res (apply 'call-process company-eclim-executable nil t
nil
- "-command" args)))
- (let ((json-array-type 'list))
- (goto-char (point-min))
- (unless (eobp)
- (json-read)))
- (message "Company-eclim command failed with error %d:\n%s" res
- (buffer-substring (point-min) (point-max)))
- nil))))
-
-(defun company-eclim--project-list ()
- (company-eclim--call-process "project_list"))
-
-(defun company-eclim--project-dir ()
- (if (eq company-eclim--project-dir 'unknown)
- (let ((dir (locate-dominating-file buffer-file-name ".project")))
- (when dir
- (setq company-eclim--project-dir
- (directory-file-name
- (expand-file-name dir)))))
- company-eclim--project-dir))
-
-(defun company-eclim--project-name ()
- (or company-eclim--project-name
- (let ((dir (company-eclim--project-dir)))
- (when dir
- (setq company-eclim--project-name
- (cl-loop for project in (company-eclim--project-list)
- when (equal (cdr (assoc 'path project)) dir)
- return (cdr (assoc 'name project))))))))
-
-(defun company-eclim--candidates (prefix)
- (interactive "d")
- (let ((project-file (file-relative-name buffer-file-name
- (company-eclim--project-dir)))
- completions)
- (when company-eclim-auto-save
- (when (buffer-modified-p)
- (basic-save-buffer))
- ;; FIXME: Sometimes this isn't finished when we complete.
- (company-eclim--call-process "java_src_update"
- "-p" (company-eclim--project-name)
- "-f" project-file))
- (dolist (item (cdr (assoc 'completions
- (company-eclim--call-process
- "java_complete" "-p"
(company-eclim--project-name)
- "-f" project-file
- "-o" (number-to-string
- (company-eclim--search-point prefix))
- "-e" "utf-8"
- "-l" "standard"))))
- (let* ((meta (cdr (assoc 'info item)))
- (completion meta))
- (when (string-match " ?[(:-]" completion)
- (setq completion (substring completion 0 (match-beginning 0))))
- (put-text-property 0 1 'meta meta completion)
- (push completion completions)))
- (let ((completion-ignore-case nil))
- (all-completions prefix completions))))
-
-(defun company-eclim--search-point (prefix)
- (if (or (cl-plusp (length prefix)) (eq (char-before) ?.))
- (1- (point))
- (point)))
-
-(defun company-eclim--meta (candidate)
- (get-text-property 0 'meta candidate))
-
-(defun company-eclim--annotation (candidate)
- (let ((meta (company-eclim--meta candidate)))
- (when (string-match "\\(([^-]*\\) -" meta)
- (substring meta (match-beginning 1) (match-end 1)))))
-
-(defun company-eclim--prefix ()
- (let ((prefix (company-grab-symbol)))
- (when prefix
- ;; Completion candidates for annotations don't include '@'.
- (when (eq ?@ (string-to-char prefix))
- (setq prefix (substring prefix 1)))
- prefix)))
-
-(defun company-eclim (command &optional arg &rest ignored)
- "`company-mode' completion backend for Eclim.
-Eclim provides access to Eclipse Java IDE features for other editors.
-
-Eclim version 1.7.13 or newer (?) is required.
-
-Completions only work correctly when the buffer has been saved.
-`company-eclim-auto-save' determines whether to do this automatically."
- (interactive (list 'interactive))
- (cl-case command
- (interactive (company-begin-backend 'company-eclim))
- (prefix (and (derived-mode-p 'java-mode 'jde-mode)
- buffer-file-name
- company-eclim-executable
- (company-eclim--project-name)
- (not (company-in-string-or-comment))
- (or (company-eclim--prefix) 'stop)))
- (candidates (company-eclim--candidates arg))
- (meta (company-eclim--meta arg))
- ;; because "" doesn't return everything
- (no-cache (equal arg ""))
- (annotation (company-eclim--annotation arg))
- (post-completion (let ((anno (company-eclim--annotation arg)))
- (when anno
- (insert anno)
- (company-template-c-like-templatify anno))))))
-
-(provide 'company-eclim)
-;;; company-eclim.el ends here
diff --git a/packages/company/company-elisp.el
b/packages/company/company-elisp.el
deleted file mode 100644
index c024d66..0000000
--- a/packages/company/company-elisp.el
+++ /dev/null
@@ -1,226 +0,0 @@
-;;; company-elisp.el --- company-mode completion backend for Emacs Lisp -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011-2013, 2017 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/packages/company/company-etags.el
b/packages/company/company-etags.el
deleted file mode 100644
index 55a1279..0000000
--- a/packages/company/company-etags.el
+++ /dev/null
@@ -1,108 +0,0 @@
-;;; company-etags.el --- company-mode completion backend for etags
-
-;; Copyright (C) 2009-2011, 2014 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/packages/company/company-files.el
b/packages/company/company-files.el
deleted file mode 100644
index 3d74c4d..0000000
--- a/packages/company/company-files.el
+++ /dev/null
@@ -1,151 +0,0 @@
-;;; company-files.el --- company-mode completion backend for file names
-
-;; Copyright (C) 2009-2011, 2014-2015 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
- "File name extensions and directory names to ignore.
-The values should use the same format as `completion-ignored-extensions'."
- :type '(const string)
- :package-version '(company . "0.9.1"))
-
-(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-delete-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 (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))
- (sorted t)
- (no-cache t)))
-
-(provide 'company-files)
-;;; company-files.el ends here
diff --git a/packages/company/company-gtags.el
b/packages/company/company-gtags.el
deleted file mode 100644
index eb3c453..0000000
--- a/packages/company/company-gtags.el
+++ /dev/null
@@ -1,119 +0,0 @@
-;;; company-gtags.el --- company-mode completion backend for GNU Global
-
-;; Copyright (C) 2009-2011, 2014-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:
-;;
-
-;;; 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)
-
-(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))
-
-(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)
- (match-string 1 meta))))
-
-;;;###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/packages/company/company-ispell.el
b/packages/company/company-ispell.el
deleted file mode 100644
index 4d0bc22..0000000
--- a/packages/company/company-ispell.el
+++ /dev/null
@@ -1,82 +0,0 @@
-;;; company-ispell.el --- company-mode completion backend using Ispell
-
-;; 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 '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))))
- (sorted t)
- (ignore-case 'keep-prefix)))
-
-(provide 'company-ispell)
-;;; company-ispell.el ends here
diff --git a/packages/company/company-keywords.el
b/packages/company/company-keywords.el
deleted file mode 100644
index 80a0103..0000000
--- a/packages/company/company-keywords.el
+++ /dev/null
@@ -1,314 +0,0 @@
-;;; company-keywords.el --- A company backend for programming language keywords
-
-;; Copyright (C) 2009-2011, 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)
-
-(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")
- (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
- "__CLASS__" "__DIR__" "__FILE__" "__FUNCTION__" "__LINE__" "__METHOD__"
- "__NAMESPACE__" "_once" "abstract" "and" "array" "as" "break" "case"
- "catch" "cfunction" "class" "clone" "const" "continue" "declare"
- "default" "die" "do" "echo" "else" "elseif" "empty" "enddeclare"
- "endfor" "endforeach" "endif" "endswitch" "endwhile" "eval" "exception"
- "exit" "extends" "final" "for" "foreach" "function" "global"
- "goto" "if" "implements" "include" "instanceof" "interface"
- "isset" "list" "namespace" "new" "old_function" "or" "php_user_filter"
- "print" "private" "protected" "public" "require" "require_once" "return"
- "static" "switch" "this" "throw" "try" "unset" "use" "var" "while" "xor")
- (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)
- (enh-ruby-mode . ruby-mode))
- "Alist mapping major-modes to sorted keywords for `company-keywords'.")
-
-;;;###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 nil)
- (symbols (cdr (assq major-mode company-keywords-alist))))
- (all-completions arg (if (consp symbols)
- symbols
- (cdr (assq symbols company-keywords-alist))))))
- (sorted t)))
-
-(provide 'company-keywords)
-;;; company-keywords.el ends here
diff --git a/packages/company/company-nxml.el b/packages/company/company-nxml.el
deleted file mode 100644
index d05f57c..0000000
--- a/packages/company/company-nxml.el
+++ /dev/null
@@ -1,143 +0,0 @@
-;;; company-nxml.el --- company-mode completion backend for nxml-mode
-
-;; 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:
-;;
-;; 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/packages/company/company-oddmuse.el
b/packages/company/company-oddmuse.el
deleted file mode 100644
index 787ca91..0000000
--- a/packages/company/company-oddmuse.el
+++ /dev/null
@@ -1,57 +0,0 @@
-;;; company-oddmuse.el --- company-mode completion backend for oddmuse-mode
-
-;; Copyright (C) 2009-2011, 2014 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/packages/company/company-semantic.el
b/packages/company/company-semantic.el
deleted file mode 100644
index 86cc8c6..0000000
--- a/packages/company/company-semantic.el
+++ /dev/null
@@ -1,168 +0,0 @@
-;;; company-semantic.el --- company-mode completion backend using Semantic
-
-;; 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 '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/packages/company/company-template.el
b/packages/company/company-template.el
deleted file mode 100644
index 4cd9292..0000000
--- a/packages/company/company-template.el
+++ /dev/null
@@ -1,272 +0,0 @@
-;;; company-template.el --- utility library for template expansion
-
-;; Copyright (C) 2009, 2010, 2014-2017 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/packages/company/company-tempo.el
b/packages/company/company-tempo.el
deleted file mode 100644
index fc8f227..0000000
--- a/packages/company/company-tempo.el
+++ /dev/null
@@ -1,71 +0,0 @@
-;;; company-tempo.el --- company-mode completion backend for tempo
-
-;; Copyright (C) 2009-2011, 2015 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/packages/company/company-tests.el
b/packages/company/company-tests.el
deleted file mode 100644
index 7859e93..0000000
--- a/packages/company/company-tests.el
+++ /dev/null
@@ -1,39 +0,0 @@
-;;; company-tests.el --- company-mode test helpers -*- lexical-binding: t -*-
-
-;; Copyright (C) 2011, 2013-2016 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/>.
-
-(require 'company)
-
-(defvar company-dir (file-name-directory (or load-file-name
- buffer-file-name)))
-
-(defun company--column (&optional pos)
- (car (company--col-row pos)))
-
-(defun company-call (name &rest args)
- (let* ((maybe (intern (format "company-%s" name)))
- (command (if (fboundp maybe) maybe name)))
- (let ((this-command command))
- (run-hooks 'pre-command-hook))
- (apply command args)
- (let ((this-command command))
- (run-hooks 'post-command-hook))))
-
-(provide 'company-tests)
diff --git a/packages/company/company-tng.el b/packages/company/company-tng.el
deleted file mode 100644
index bd325c7..0000000
--- a/packages/company/company-tng.el
+++ /dev/null
@@ -1,197 +0,0 @@
-;;; company-tng.el --- company-mode configuration for single-button interaction
-
-;; Copyright (C) 2017-2020 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:
-;;
-;; To apply the default configuration for company-tng call
-;; `company-tng-configure-default' from your init script.
-;;
-;; You can also configure company-tng manually:
-;;
-;; Add `company-tng-frontend' to `company-frontends':
-;;
-;; (add-to-list 'company-frontends 'company-tng-frontend)
-;;
-;; 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-configure-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))
- (advice-add 'company-select-next :before-until
'company-tng--allow-unselected)
- (advice-add 'company-fill-propertize :filter-args
'company-tng--adjust-tooltip-highlight))
- (update
- (let ((ov company-tng--overlay)
- (selected (nth company-selection company-candidates))
- (prefix (length company-prefix)))
- (move-overlay ov (- (point) prefix) (point))
- (overlay-put ov
- (if (= prefix 0) 'after-string 'display)
- (and company-selection-changed selected))))
- (hide
- (when company-tng--overlay
- (delete-overlay company-tng--overlay)
- (kill-local-variable 'company-tng--overlay))
- (advice-remove 'company-select-next 'company-tng--allow-unselected)
- (advice-remove 'company-fill-propertize
'company-tng--adjust-tooltip-highlight))
- (pre-command
- (when (and company-selection-changed
- (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)
-
-;;;###autoload
-(defun company-tng-configure-default ()
- "Applies the default configuration to enable company-tng."
- (setq company-require-match nil)
- (setq company-frontends '(company-tng-frontend
- company-pseudo-tooltip-frontend
- company-echo-metadata-frontend))
- (setq 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)
- (let ((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)))
-
-(defun company-tng--allow-unselected (&optional arg)
- "Advice `company-select-next' to allow for an 'unselected'
-state. Unselected means that no user interaction took place on the
-completion candidates and it's marked by setting
-`company-selection-changed' to nil. This advice will call the underlying
-`company-select-next' unless we need to transition to or from an unselected
-state.
-
-Possible state transitions:
-- (arg > 0) unselected -> first candidate selected
-- (arg < 0) first candidate selected -> unselected
-- (arg < 0 wrap-round) unselected -> last candidate selected
-- (arg < 0 no wrap-round) unselected -> unselected
-
-There is no need to advice `company-select-previous' because it calls
-`company-select-next' internally."
- (cond
- ;; Selecting next
- ((or (not arg) (> arg 0))
- (unless company-selection-changed
- (company-set-selection (1- (or arg 1)) 'force-update)
- t))
- ;; Selecting previous
- ((< arg 0)
- (when (and company-selection-changed
- (< (+ company-selection arg) 0))
- (company-set-selection 0)
- (setq company-selection-changed nil)
- (company-call-frontends 'update)
- t)
- )))
-
-(defun company-tng--adjust-tooltip-highlight (args)
- "Prevent the tooltip from highlighting the current selection if it wasn't
-made explicitly (i.e. `company-selection-changed' is true)"
- (unless company-selection-changed
- ;; The 4th arg of `company-fill-propertize' is selected
- (setf (nth 3 args) nil))
- args)
-
-(provide 'company-tng)
-;;; company-tng.el ends here
diff --git a/packages/company/company-xcode.el
b/packages/company/company-xcode.el
deleted file mode 100644
index ea89bcb..0000000
--- a/packages/company/company-xcode.el
+++ /dev/null
@@ -1,123 +0,0 @@
-;;; company-xcode.el --- company-mode completion backend for Xcode projects
-
-;; Copyright (C) 2009-2011, 2014 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-xcode nil
- "Completion backend for Xcode projects."
- :group 'company)
-
-(defcustom company-xcode-xcodeindex-executable (executable-find "xcodeindex")
- "Location of xcodeindex executable."
- :type 'file)
-
-(defvar company-xcode-tags nil)
-
-(defun company-xcode-reset ()
- "Reset the cached tags."
- (interactive)
- (setq company-xcode-tags nil))
-
-(defcustom company-xcode-types
- '("Class" "Constant" "Enum" "Macro" "Modeled Class" "Structure"
- "Type" "Union" "Function")
- "The types of symbols offered by `company-xcode'.
-No context-enabled completion is available. Types like methods will be
-offered regardless of whether the class supports them. The defaults should be
-valid in most contexts."
- :set (lambda (variable value)
- (set variable value)
- (company-xcode-reset))
- :type '(set (const "Category") (const "Class") (const "Class Method")
- (const "Class Variable") (const "Constant") (const "Enum")
- (const "Field") (const "Instance Method")
- (const "Instance Variable") (const "Macro")
- (const "Modeled Class") (const "Modeled Method")
- (const "Modeled Property") (const "Property") (const "Protocol")
- (const "Structure") (const "Type") (const "Union")
- (const "Variable") (const "Function")))
-
-(defvar-local company-xcode-project 'unknown)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun company-xcode-fetch (project-bundle)
- (setq project-bundle (directory-file-name project-bundle))
- (message "Retrieving dump from %s..." project-bundle)
- (with-temp-buffer
- (let ((default-directory (file-name-directory project-bundle)))
- (call-process company-xcode-xcodeindex-executable nil (current-buffer)
- nil "dump" "-project"
- (file-name-nondirectory project-bundle) "-quiet")
- (goto-char (point-min))
- (let ((regexp (concat "^\\([^\t\n]*\\)\t[^\t\n]*\t"
- (regexp-opt company-xcode-types)
- "\t[^\t\n]*\t[^\t\n]*"))
- candidates)
- (while (re-search-forward regexp nil t)
- (cl-pushnew (match-string 1) candidates :test #'equal))
- (message "Retrieving dump from %s...done" project-bundle)
- candidates))))
-
-(defun company-xcode-find-project ()
- (let ((dir (if buffer-file-name
- (file-name-directory buffer-file-name)
- (expand-file-name default-directory)))
- (prev-dir nil)
- file)
- (while (not (or file (equal dir prev-dir)))
- (setq file (car (directory-files dir t ".xcodeproj\\'" t))
- prev-dir dir
- dir (file-name-directory (directory-file-name dir))))
- file))
-
-(defun company-xcode-tags ()
- (when (eq company-xcode-project 'unknown)
- (setq company-xcode-project (company-xcode-find-project)))
- (when company-xcode-project
- (cdr (or (assoc company-xcode-project company-xcode-tags)
- (car (push (cons company-xcode-project
- (company-xcode-fetch company-xcode-project))
- company-xcode-tags))))))
-;;;###autoload
-(defun company-xcode (command &optional arg &rest ignored)
- "`company-mode' completion backend for Xcode projects."
- (interactive (list 'interactive))
- (cl-case command
- (interactive (company-begin-backend 'company-xcode))
- (prefix (and company-xcode-xcodeindex-executable
- (company-xcode-tags)
- (not (company-in-string-or-comment))
- (or (company-grab-symbol) 'stop)))
- (candidates (let ((completion-ignore-case nil))
- (company-xcode-tags)
- (all-completions arg (company-xcode-tags))))))
-
-
-(provide 'company-xcode)
-;;; company-xcode.el ends here
diff --git a/packages/company/company-yasnippet.el
b/packages/company/company-yasnippet.el
deleted file mode 100644
index 197ae78..0000000
--- a/packages/company/company-yasnippet.el
+++ /dev/null
@@ -1,176 +0,0 @@
-;;; company-yasnippet.el --- company-mode completion backend for Yasnippet
-
-;; Copyright (C) 2014, 2015, 2020 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")
-
-(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))
- res)
- (when keyhash
- (maphash
- (lambda (key value)
- (when (and (stringp key)
- (string-prefix-p key-prefix key))
- (maphash
- (lambda (name template)
- (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)))
- (with-current-buffer (company-doc-buffer)
- (let ((buffer-file-name file-name))
- (yas-minor-mode 1)
- (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)
- (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/packages/company/company.el b/packages/company/company.el
deleted file mode 100644
index b96983b..0000000
--- a/packages/company/company.el
+++ /dev/null
@@ -1,3247 +0,0 @@
-;;; company.el --- Modular text completion framework -*- lexical-binding: t
-*-
-
-;; Copyright (C) 2009-2020 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 "24.3"))
-
-;; 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 'newcomment)
-(require 'pcase)
-
-;;; Compatibility
-(eval-and-compile
- ;; Defined in Emacs 24.4
- (unless (fboundp 'string-suffix-p)
- (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)))))))
-
-(defgroup company nil
- "Extensible inline text completion mechanism."
- :group 'abbrev
- :group 'convenience
- :group 'matching)
-
-(defgroup company-faces nil
- "Faces used by Company."
- :group 'company
- :group 'faces)
-
-(defface company-tooltip
- '((default :foreground "black")
- (((class color) (min-colors 88) (background light))
- (:background "cornsilk"))
- (((class color) (min-colors 88) (background dark))
- (:background "yellow"))
- (t
- (: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 "orange1"))
- (t (:background "green")))
- "Face used for the selection in the tooltip.")
-
-(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 "red"))
- "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 "red4"))
- "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-scrollbar-fg
- '((((background light))
- :background "darkred")
- (((background dark))
- :background "red"))
- "Face used for the tooltip scrollbar thumb.")
-
-(defface company-scrollbar-bg
- '((((background light))
- :background "wheat")
- (((background dark))
- :background "gold"))
- "Face used for the tooltip scrollbar background.")
-
-(defface company-preview
- '((((background light))
- :inherit (company-tooltip-selection company-tooltip))
- (((background dark))
- :background "blue4"
- :foreground "wheat"))
- "Face used for the completion preview.")
-
-(defface company-preview-common
- '((((background light))
- :inherit company-tooltip-common-selection)
- (((background dark))
- :inherit company-preview
- :foreground "red"))
- "Face used for the common part of the completion preview.")
-
-(defface company-preview-search
- '((((background light))
- :inherit company-tooltip-common-selection)
- (((background dark))
- :inherit company-preview
- :background "blue1"))
- "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 dark)) (:foreground "firebrick1"))
- (((background light)) (:background "firebrick4")))
- "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.
-
-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
- "The minimum height of the tooltip.
-If this many lines are not available, prefer to display the tooltip above."
- :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-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")
- (company-dabbrev . "dabbrev for plain text")
- (company-dabbrev-code . "dabbrev for code")
- (company-eclim . "Eclim (an Eclipse interface)")
- (company-elisp . "Emacs Lisp")
- (company-etags . "etags")
- (company-files . "Files")
- (company-gtags . "GNU Global")
- (company-ispell . "Ispell")
- (company-keywords . "Programming language keywords")
- (company-nxml . "nxml")
- (company-oddmuse . "Oddmuse")
- (company-semantic . "Semantic")
- (company-tempo . "Tempo templates")
- (company-xcode . "Xcode")))
-(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 `(,@(unless (version< "24.3.51" emacs-version)
- (list 'company-elisp))
- company-bbdb
- ,@(unless (version<= "26" emacs-version)
- (list 'company-nxml))
- ,@(unless (version<= "26" emacs-version)
- (list 'company-css))
- company-eclim company-semantic company-clang
- company-xcode company-cmake
- company-capf
- 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.
-
-`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.
-
-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-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-auto-complete' 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)))
-
-(defcustom company-auto-complete nil
- "Determines when to auto-complete.
-If this is enabled, all characters from `company-auto-complete-chars'
-trigger insertion of the selected completion candidate.
-This can also be a function."
- :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)))
-
-(defcustom company-auto-complete-chars '(?\ ?\) ?.)
- "Determines which characters trigger auto-completion.
-See `company-auto-complete'. If this is a string, each string character
-triggers auto-completion. If it is a list of syntax description characters
(see
-`modify-syntax-entry'), all characters with that syntax auto-complete.
-
-This can also be a function, which is called with the new input and should
-return non-nil if company should auto-complete.
-
-A character that is part of a valid candidate never triggers auto-completion."
- :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")))
-
-(defcustom company-idle-delay .5
- "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)))
-
-(defcustom company-show-numbers nil
- "If enabled, show quick-access numbers for the first ten candidates."
- :type '(choice (const :tag "off" nil)
- (const :tag "left" 'left)
- (const :tag "on" 't)))
-
-(defcustom company-show-numbers-function #'company--show-numbers
- "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)
-
-(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)))
-
-(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)
- (define-key keymap (kbd "M-p") 'company-select-previous)
- (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)
- (dotimes (i 10)
- (define-key keymap (read-kbd-macro (format "M-%d" i))
'company-complete-number))
- keymap)
- "Keymap that is enabled during an active completion.")
-
-(defvar company--disabled-backends nil)
-
-(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)
- (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}"
- nil company-lighter company-mode-map
- (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))))
-
-;; Hack:
-;; Emacs calculates the active keymaps before reading the event. That means we
-;; cannot change the keymap from a timer. So we send a bogus command.
-;; XXX: Seems not to be needed anymore in Emacs 24.4
-;; Apparently, starting with emacs-mirror/emacs@99d0d6dc23.
-(defun company-ignore ()
- (interactive)
- (setq this-command last-command))
-
-(global-set-key '[company-dummy-event] 'company-ignore)
-
-(defun company-input-noop ()
- (push 'company-dummy-event unread-command-events))
-
-;; 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 (and header-line-format (version< emacs-version "24.3.93.3"))
- ;; http://debbugs.gnu.org/18384
- (cl-decf row))
- (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))
- (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-local company-selection 0)
-
-(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 company--auto-completion nil
- "Non-nil when current candidate is being inserted automatically.
-Controlled by `company-auto-complete'.")
-
-(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)
- (dolist (frontend company-frontends)
- (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)
- (setq selection
- (if company-selection-wrap-around
- (mod selection company-candidates-length)
- (max 0 (min (1- company-candidates-length) selection))))
- (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 (nth company-selection company-candidates)))
- (setq company-selection 0
- company-candidates candidates)
- (when selected
- (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 0
- company-selection-changed nil))))
- (setq company-selection 0
- 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)))))
- (progn
- ;; No cache match, call the backend.
- (setq candidates (company--preprocess-candidates
- (company--fetch-candidates prefix)))
- ;; 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--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)
- (annos 'unk))
- (while c2
- (setcdr c2
- (let ((str (pop c2)))
- (while (let ((str2 (car c2)))
- (if (not (equal str str2))
- (progn
- (setq annos 'unk)
- nil)
- (when (eq annos 'unk)
- (setq annos (list (company-call-backend
- 'annotation str))))
- (let ((anno2 (company-call-backend
- 'annotation str2)))
- (if (member anno2 annos)
- t
- (push anno2 annos)
- 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)))
-
-(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)
- (when (catch 'done
- (goto-char w-start)
- (while (search-forward candidate w-end t)
- (when (and (not (eq (point) start-point))
- (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))
- (when (company-auto-begin)
- (when (version< emacs-version "24.3.50")
- (company-input-noop))
- (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-auto-complete-p (input)
- "Return non-nil if INPUT should trigger auto-completion."
- (and (if (functionp company-auto-complete)
- (funcall company-auto-complete)
- company-auto-complete)
- (if (functionp company-auto-complete-chars)
- (funcall company-auto-complete-chars input)
- (if (consp company-auto-complete-chars)
- (memq (char-syntax (string-to-char input))
- company-auto-complete-chars)
- (string-match (regexp-quote (substring input 0 1))
- company-auto-complete-chars)))))
-
-(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
- ((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-auto-complete-p (string last-command-event)))
- ;; auto-complete
- (save-excursion
- (goto-char company-point)
- (let ((company--auto-completion t))
- (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--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 0
- 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-number)
- "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)
- (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 (length company-prefix))
- (cl-return i))
- (cl-incf i))))
-
-(defun company-search-keypad ()
- (interactive)
- (let* ((name (symbol-name last-command-event))
- (last-command-event (aref name (1- (length name)))))
- (company-search-printing-char)))
-
-(defun company-search-printing-char ()
- (interactive)
- (company--search-assert-enabled)
- (let ((ss (concat company-search-string (string last-command-event))))
- (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* ((pos (company--search new (nthcdr company-selection
company-candidates))))
- (if (null pos)
- (ding)
- (setq company-search-string new)
- (company-set-selection (+ company-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 ((pos (company--search company-search-string
- (cdr (nthcdr company-selection
- company-candidates)))))
- (if (null pos)
- (ding)
- (company-set-selection (+ company-selection pos 1) t))))
-
-(defun company-search-repeat-backward ()
- "Repeat the incremental search in completion candidates backwards."
- (interactive)
- (company--search-assert-input)
- (let ((pos (company--search company-search-string
- (nthcdr (- company-candidates-length
- company-selection)
- (reverse company-candidates)))))
- (if (null pos)
- (ding)
- (company-set-selection (- company-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 (read (format "[kp-%s]" i)) 'company-search-keypad))
- (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 "M-n") 'company-select-next)
- (define-key keymap (kbd "M-p") 'company-select-previous)
- (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)
- (dotimes (i 10)
- (define-key keymap (read-kbd-macro (format "M-%d" i))
'company-complete-number))
- 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'."
- nil company-search-lighter nil
- (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))
-
-(defvar company-filter-map
- (let ((keymap (make-keymap)))
- (define-key keymap [remap company-search-printing-char]
- 'company-filter-printing-char)
- (set-keymap-parent keymap company-search-map)
- keymap)
- "Keymap used for incrementally searching the completion candidates.")
-
-(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."
- (interactive "p")
- (when (company-manual-begin)
- (company-set-selection (+ (or arg 1) company-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 (> 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-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))))))
-
-(defvar company-pseudo-tooltip-overlay)
-
-(defvar company-tooltip-offset)
-
-(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--event-col-row (event)
- (company--posn-col-row (event-start event)))
-
-(defun company-select-mouse (event)
- "Select the candidate picked by the mouse."
- (interactive "e")
- (let ((event-col-row (company--event-col-row event))
- (ovl-row (company--row))
- (ovl-height (and company-pseudo-tooltip-overlay
- (min (overlay-get company-pseudo-tooltip-overlay
- 'company-height)
- company-candidates-length))))
- (if (and ovl-height
- (company--inside-tooltip-p event-col-row ovl-row ovl-height))
- (progn
- (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)
- (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 (company-manual-begin)
- (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-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)))))
-
-(defun company-complete-number (n)
- "Insert the Nth candidate visible in the tooltip.
-To show the number next to the candidates in some backends, enable
-`company-show-numbers'. When called interactively, uses the last typed
-character, stripping the modifiers. That character must be a digit."
- (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))))))
- (n (- char ?0)))
- (if (zerop n) 10 n))))
- (when (company-manual-begin)
- (and (or (< n 1) (> n (- company-candidates-length
- company-tooltip-offset)))
- (user-error "No candidate number %d" n))
- (cl-decf n)
- (company-finish (nth (+ n 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 company-selection 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)
- (company--electric-do
- (let* ((selected (nth company-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))))
- 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 completion-at-point-functions)))
- (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-pseudo-tooltip-overlay nil)
-
-(defvar-local company-tooltip-offset 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
-
-(defsubst 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-fill-propertize (value annotation width selected left right)
- (let* ((margin (length left))
- (common (or (company-call-backend 'match value)
- (if company-common
- (string-width company-common)
- 0)))
- (_ (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)))
-
- ;; TODO: Use add-face-text-property in Emacs 24.4
- (font-lock-append-text-property 0 width 'mouse-face
- 'company-tooltip-mouse
- line)
- (when (< ann-start ann-end)
- (font-lock-append-text-property ann-start ann-end 'face
- (if selected
- 'company-tooltip-annotation-selection
- 'company-tooltip-annotation)
- line))
- (cl-loop
- with width = (- width (length right))
- for (comp-beg . comp-end) in (if (integerp common) `((0 . ,common))
common)
- for inline-beg = (+ margin comp-beg)
- for inline-end = (min (+ margin comp-end) width)
- when (< inline-beg width)
- do (font-lock-prepend-text-property inline-beg inline-end 'face
- (if selected
- 'company-tooltip-common-selection
- 'company-tooltip-common)
- line))
- (when (let ((re (funcall company-search-regexp-function
- company-search-string)))
- (and (not (string= re ""))
- (string-match re value (length company-prefix))))
- (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
- (let ((beg (+ margin mbeg))
- (end (+ margin mend))
- (width (- width (length right))))
- (when (< beg width)
- (font-lock-prepend-text-property beg (min end width) 'face
- (if selected
-
'company-tooltip-search-selection
- 'company-tooltip-search)
- line)))))
- (when selected
- (font-lock-append-text-property 0 width 'face
- 'company-tooltip-selection
- line))
- (font-lock-append-text-property 0 width 'face
- 'company-tooltip
- 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.
- "\u2017")
- ((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 " %d" (mod numbered 10)))
-
-(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))))
- (unless (or (display-graphic-p)
- (version< "24.3.1" emacs-version))
- ;; Emacs 24.3 and earlier included margins
- ;; in window-width when in TTY.
- (cl-decf ww
- (let ((margins (window-margins)))
- (+ (or (car margins) 0)
- (or (cdr margins) 0)))))
- (when (and word-wrap
- (version< emacs-version "24.4.51.5"))
- ;; http://debbugs.gnu.org/19300
- (cl-decf ww))
- ;; 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--replacement-string (lines old column nl &optional align-top)
- (cl-decf column company-tooltip-margin)
-
- (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 ((offset (and (< column 0) (- column)))
- new)
- (when offset
- (setq column 0))
- (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)
- (company--offset-line (pop lines) offset)
- column)
- new))
- ;; Append whole new lines.
- (while lines
- (push (concat (company-space-string column)
- (company--offset-line (pop lines) offset))
- new))
-
- (let ((str (concat (when nl " \n")
- (mapconcat 'identity (nreverse new) "\n")
- "\n")))
- (when nl (put-text-property 0 1 'cursor t str))
- str)))
-
-(defun company--offset-line (line offset)
- (if (and offset line)
- (substring line offset)
- line))
-
-(defun company--create-lines (selection limit)
- (let ((len company-candidates-length)
- (window-width (company--window-width))
- lines
- width
- lines-copy
- items
- previous
- remainder
- scrollbar-bounds)
-
- ;; Maybe clear old offset.
- (when (< len (+ company-tooltip-offset limit))
- (setq company-tooltip-offset 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))))))
-
- (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)
-
- (cl-decf window-width (* 2 company-tooltip-margin))
- (when scrollbar-bounds (cl-decf window-width))
-
- (dotimes (_ len)
- (let* ((value (pop lines-copy))
- (annotation (company-call-backend 'annotation value)))
- (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 (comment-string-strip annotation t nil))))
- (push (cons value annotation) 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-numbers
- (+ 2 width)
- width))))
-
- (let ((items (nreverse items))
- (numbered (if company-show-numbers 0 99999))
- new)
- (when previous
- (push (company--scrollpos-line previous width) new))
-
- (dotimes (i len)
- (let* ((item (pop items))
- (str (car item))
- (annotation (cdr item))
- (margin (company-space-string company-tooltip-margin))
- (left margin)
- (right margin)
- (width width))
- (when (< numbered 10)
- (cl-decf width 2)
- (cl-incf numbered)
- (setf (if (eq company-show-numbers 'left) left right)
- (concat (funcall company-show-numbers-function numbered)
- margin)))
- (push (concat
- (company-fill-propertize str annotation
- width (equal i selection)
- left
- right)
- (when scrollbar-bounds
- (company--scrollbar i scrollbar-bounds)))
- new)))
-
- (when remainder
- (push (company--scrollpos-line remainder width) new))
-
- (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-scrollbar-fg
- 'company-scrollbar-bg)))
-
-(defun company--scrollpos-line (text width)
- (propertize (concat (company-space-string company-tooltip-margin)
- (company-safe-substring text 0 width)
- (company-space-string company-tooltip-margin))
- 'face 'company-tooltip))
-
-;; show
-
-(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))
-
- (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 (company--create-lines selection (abs height))))
- (overlay-put ov 'company-display
- (apply 'company--replacement-string lines 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 (company--create-lines selection (abs height))))
- (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
- (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 'after-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)
- ;; No (extra) prefix for the first line.
- (overlay-put ov 'line-prefix "")
- ;; `display' is better
- ;; (http://debbugs.gnu.org/18285, http://debbugs.gnu.org/20847),
- ;; but it doesn't work on 0-length overlays.
- (if (< (overlay-start ov) (overlay-end ov))
- (overlay-put ov 'display disp)
- (overlay-put ov 'after-string disp)
- (overlay-put ov 'invisible t))
- (overlay-put ov 'face 'default)
- (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))
- (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))
- (hide (company-pseudo-tooltip-hide)
- (setq company-tooltip-offset 0))
- (update (when (overlayp company-pseudo-tooltip-overlay)
- (company-pseudo-tooltip-edit company-selection)))))
-
-(defun company-pseudo-tooltip-unless-just-one-frontend (command)
- "`company-pseudo-tooltip-frontend', but not shown for single candidates."
- (unless (and (eq command 'post-command)
- (company--show-inline-p))
- (company-pseudo-tooltip-frontend 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-unless-just-one-frontend-with-delay
- 'post-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)
-
- (setq completion (copy-sequence (company--pre-render completion)))
- (font-lock-append-text-property 0 (length completion)
- 'face 'company-preview
- completion)
- (font-lock-prepend-text-property 0 (length company-common)
- 'face 'company-preview-common
- completion)
-
- ;; Add search string
- (and (string-match (funcall company-search-regexp-function
- company-search-string)
- completion)
- (pcase-dolist (`(,mbeg . ,mend) (company--search-chunks))
- (font-lock-prepend-text-property mbeg mend
- 'face 'company-preview-search
- completion)))
-
- (setq completion (company-strip-prefix 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))
- (`post-command (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 (eq command 'post-command))
- (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 (eq command 'post-command))
- (company-preview-common--show-p))
- (pcase command
- (`pre-command (company-preview-hide))
- (`post-command (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)
- (company-echo-cancel)
- (setq company-echo-timer (run-with-timer 0 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-show-when-idle (&optional getter)
- (company-echo-cancel)
- (setq company-echo-timer
- (run-with-idle-timer company-echo-delay nil 'company-echo-show
getter)))
-
-(defun company-echo-format ()
-
- (let ((limit (window-body-width (minibuffer-window)))
- (len -1)
- ;; Roll to selection.
- (candidates (nthcdr company-selection company-candidates))
- (i (if company-show-numbers company-selection 99999))
- comp msg)
-
- (while candidates
- (setq comp (company-reformat (company--clean-string (pop candidates)))
- len (+ len 1 (length comp)))
- (if (< i 10)
- ;; Add number.
- (progn
- (setq comp (propertize (format "%d: %s" i comp)
- 'face 'company-echo))
- (cl-incf len 3)
- (cl-incf i)
- (add-text-properties 3 (+ 3 (string-width company-common))
- '(face company-echo-common) comp))
- (setq comp (propertize comp 'face 'company-echo))
- (add-text-properties 0 (string-width company-common)
- '(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 ((limit (window-body-width (minibuffer-window)))
- (len (+ (length company-prefix) 2))
- ;; Roll to selection.
- (candidates (nthcdr company-selection company-candidates))
- (i (if company-show-numbers company-selection 99999))
- msg comp)
-
- (while candidates
- (setq comp (company-strip-prefix (pop candidates))
- len (+ len 2 (length comp)))
- (when (< i 10)
- ;; Add number.
- (setq comp (format "%s (%d)" comp i))
- (cl-incf len 4)
- (cl-incf i))
- (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))
- (`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))
- (`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-when-idle 'company-fetch-metadata))
- (`hide (company-echo-hide))))
-
-(provide 'company)
-;;; company.el ends here
diff --git a/packages/company/test/all.el b/packages/company/test/all.el
deleted file mode 100644
index 29dc916..0000000
--- a/packages/company/test/all.el
+++ /dev/null
@@ -1,30 +0,0 @@
-;;; all-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015 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/>.
-
-(defvar company-test-path
- (file-name-directory (or load-file-name buffer-file-name)))
-
-(require 'ert)
-
-(dolist (test-file (directory-files company-test-path t "-tests.el$"))
- (unless (and (= emacs-major-version 24)
- (equal (file-name-base test-file) "capf-tests"))
- (load test-file nil t)))
diff --git a/packages/company/test/async-tests.el
b/packages/company/test/async-tests.el
deleted file mode 100644
index be9c2b5..0000000
--- a/packages/company/test/async-tests.el
+++ /dev/null
@@ -1,221 +0,0 @@
-;;; async-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015, 2016, 2018 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/>.
-
-(require 'company-tests)
-
-(defun company-async-backend (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb)
- (run-with-timer 0.05 nil
- #'funcall cb '("abc" "abd")))))))
-
-(ert-deftest company-call-backend-forces-sync ()
- (let ((company-backend 'company-async-backend)
- (company-async-timeout 0.1))
- (should (equal '("abc" "abd") (company-call-backend 'candidates)))))
-
-(ert-deftest company-call-backend-errors-on-timeout ()
- (with-temp-buffer
- (let* ((company-backend (lambda (command &optional _arg)
- (pcase command
- (`candidates (cons :async 'ignore)))))
- (company-async-timeout 0.1)
- (err (should-error (company-call-backend 'candidates "foo"))))
- (should (string-match-p "async timeout" (cadr err))))))
-
-(ert-deftest company-call-backend-raw-passes-return-value-verbatim ()
- (let ((company-backend 'company-async-backend))
- (should (equal "foo" (company-call-backend-raw 'prefix)))
- (should (equal :async (car (company-call-backend-raw 'candidates "foo"))))
- (should (equal 'closure (cadr (company-call-backend-raw 'candidates
"foo"))))))
-
-(ert-deftest company-manual-begin-forces-async-candidates-to-sync ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- company-transformers
- (company-backends (list 'company-async-backend)))
- (company-manual-begin)
- (should (equal "foo" company-prefix))
- (should (equal '("abc" "abd") company-candidates)))))
-
-(ert-deftest company-idle-begin-allows-async-candidates ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- company-transformers
- (company-backends (list 'company-async-backend))
- unread-command-events
- noninteractive
- (start-time (current-time)))
- (company-idle-begin (current-buffer) (selected-window)
- (buffer-chars-modified-tick) (point))
- (should (< (time-to-seconds
- (time-subtract (current-time) start-time))
- 0.1))
- (should (equal "foo" company-prefix))
- (should (equal '("abc" "abd") company-candidates)))))
-
-(ert-deftest company-idle-begin-with-async-aborts-on-user-input ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- (company-backends (list 'company-async-backend))
- noninteractive
- (unread-command-events (list 'company-dummy-event)))
- (company-idle-begin (current-buffer) (selected-window)
- (buffer-chars-modified-tick) (point))
- (should (null company-candidates)))))
-
-(ert-deftest company-idle-begin-async-allows-immediate-callbacks ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional arg)
- (pcase command
- (`prefix (buffer-substring (point-min) (point)))
- (`candidates
- (let ((c (all-completions arg '("abc" "def"))))
- (cons :async
- (lambda (cb) (funcall cb c)))))
- (`no-cache t)))))
- (company-minimum-prefix-length 0)
- (unread-command-events (list 'company-dummy-event)))
- (company-idle-begin (current-buffer) (selected-window)
- (buffer-chars-modified-tick) (point))
- (should (equal '("abc" "def") company-candidates))
- (let ((last-command-event ?a))
- (company-call 'self-insert-command 1))
- (should (equal '("abc") company-candidates)))))
-
-(ert-deftest company-multi-backend-forces-prefix-to-sync ()
- (with-temp-buffer
- (let ((company-backend (list 'ignore
- (lambda (command)
- (should (eq command 'prefix))
- (cons :async
- (lambda (cb)
- (run-with-timer
- 0.01 nil
- (lambda () (funcall cb nil))))))
- (lambda (command)
- (should (eq command 'prefix))
- "foo"))))
- (should (equal "foo" (company-call-backend-raw 'prefix))))
- (let ((company-backend (list (lambda (_command)
- (cons :async
- (lambda (cb)
- (run-with-timer
- 0.01 nil
- (lambda () (funcall cb "bar"))))))
- (lambda (_command)
- "foo"))))
- (should (equal "bar" (company-call-backend-raw 'prefix))))))
-
-(ert-deftest company-multi-backend-merges-deferred-candidates ()
- (with-temp-buffer
- (let* ((immediate (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb) (funcall cb '("f"))))))))
- (company-backend (list 'ignore
- (lambda (command &optional arg)
- (pcase command
- (`prefix "foo")
- (`candidates
- (should (equal arg "foo"))
- (cons :async
- (lambda (cb)
- (run-with-timer
- 0.01 nil
- (lambda () (funcall cb '("a"
"b")))))))))
- (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates '("c" "d" "e"))))
- immediate)))
- (should (equal :async (car (company-call-backend-raw 'candidates
"foo"))))
- (should (equal '("a" "b" "c" "d" "e" "f")
- (company-call-backend 'candidates "foo")))
- (let ((company-backend (list immediate)))
- (should (equal '("f") (company-call-backend 'candidates "foo")))))))
-
-(ert-deftest company-multi-backend-merges-deferred-candidates-2 ()
- (with-temp-buffer
- (let ((company-backend (list (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb) (funcall cb '("a"
"b")))))))
- (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb) (funcall cb '("c"
"d")))))))
- (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb) (funcall cb '("e"
"f"))))))))))
- (should (equal :async (car (company-call-backend-raw 'candidates
"foo"))))
- (should (equal '("a" "b" "c" "d" "e" "f")
- (company-call-backend 'candidates "foo"))))))
-
-(ert-deftest company-multi-backend-merges-deferred-candidates-3 ()
- (with-temp-buffer
- (let ((company-backend (list (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb) (funcall cb '("a"
"b")))))))
- (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb)
- (run-with-timer
- 0.01 nil
- (lambda ()
- (funcall cb '("c" "d")))))))))
- (lambda (command &optional _)
- (pcase command
- (`prefix "foo")
- (`candidates
- (cons :async
- (lambda (cb)
- (run-with-timer
- 0.01 nil
- (lambda ()
- (funcall cb '("e"
"f"))))))))))))
- (should (equal :async (car (company-call-backend-raw 'candidates
"foo"))))
- (should (equal '("a" "b" "c" "d" "e" "f")
- (company-call-backend 'candidates "foo"))))))
diff --git a/packages/company/test/bbdb-tests.el
b/packages/company/test/bbdb-tests.el
deleted file mode 100644
index 90af209..0000000
--- a/packages/company/test/bbdb-tests.el
+++ /dev/null
@@ -1,46 +0,0 @@
-;;; bbdb-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 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/>.
-
-(require 'company-tests)
-(require 'company-bbdb)
-
-(provide 'bbdb-com)
-
-(ert-deftest company-bbdb-prefix-looks-in-header-value ()
- (with-temp-buffer
- (insert "To: J")
- (setq-local major-mode 'message-mode)
- (should (equal (company-bbdb 'prefix)
- "J"))))
-
-(ert-deftest company-bbdb-prefix-includes-space ()
- (with-temp-buffer
- (insert "To: John Sm")
- (setq-local major-mode 'message-mode)
- (should (equal (company-bbdb 'prefix)
- "John Sm"))))
-
-(ert-deftest company-bbdb-prefix-begins-after-comma-or-semi ()
- (with-temp-buffer
- (insert "To: John Smythe <jsm@y.the>, Jess C")
- (setq-local major-mode 'message-mode)
- (should (equal (company-bbdb 'prefix)
- "Jess C"))))
diff --git a/packages/company/test/capf-tests.el
b/packages/company/test/capf-tests.el
deleted file mode 100644
index 80a204d..0000000
--- a/packages/company/test/capf-tests.el
+++ /dev/null
@@ -1,148 +0,0 @@
-;;; capf-tests.el --- company tests for the company-capf backend -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2018 Free Software Foundation, Inc.
-
-;; Author: João Távora <joaotavora@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 'company-tests)
-(require 'company-capf)
-(require 'cl-lib)
-
-(defmacro company-capf-with-buffer (contents &rest body)
- (declare (indent 0) (debug (sexp &rest form)))
- `(with-temp-buffer
- (insert ,contents)
- (emacs-lisp-mode)
- (re-search-backward "|")
- (replace-match "")
- (let ((completion-at-point-functions '(elisp-completion-at-point))
- (company-backends '(company-capf)))
- ,@body)))
-
-(ert-deftest company-basic-capf ()
- "Test basic `company-capf' support."
- (company-capf-with-buffer
- "(with-current-buffer|)"
- (company-mode)
- (company-complete)
- (should company-candidates)))
-
-(ert-deftest company-non-prefix-capf ()
- "Test non-prefix `company-capf' in elisp"
- (company-capf-with-buffer
- "(w-c-b|)"
- (company-mode)
- (company-complete)
- (should company-candidates)
- (should (member "with-current-buffer" company-candidates))))
-
-(defun company--remove-but-these-properties (string keep)
- "Remove from STRING all text properties but the ones in KEEP."
- (remove-list-of-text-properties
- 0 (length string)
- (cl-set-difference
- (cl-loop for start = 0 then (next-property-change start string)
- while start
- append (cl-loop for (k _v) on (text-properties-at start string)
- by #'cddr collect k))
- keep)
- string)
- string)
-
-(ert-deftest company-basic-capf-highlighting ()
- "Test basic `company-capf' support, with basic prefix completion."
- (company-capf-with-buffer
- "(with|)"
- (company-mode)
- (company-complete)
- (should company-candidates)
- (let* ((cand (car (member "with-current-buffer" company-candidates)))
- (render
- (and cand
- (company-fill-propertize cand nil (length cand) nil nil
nil))))
- ;; remove text properties that aren't relevant to our test
- (company--remove-but-these-properties render '(face))
- (should
- (ert-equal-including-properties
- render
- #("with-current-buffer"
- 0 4 (face (company-tooltip-common company-tooltip)) ; "with"
- 4 19 (face (company-tooltip))))))))
-
-
-
-;; Re. "perfect" highlighting of the non-prefix in company-capf matches, it is
-;; only working-out-of-the box (i.e. without the `:company-match' meta) in
-;; recent Emacsen containing the following commit. The two tests that follow
-;; reflect that.
-;;
-;; commit 325ef57b0e3977f9509f1049c826999e8b7c226d
-;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
-;; Date: Tue Nov 7 12:17:34 2017 -0500
-
-(ert-deftest company-non-prefix-fancy-capf-highlighting ()
- "Test highlighting for non-prefix `company-capf' in elisp"
- (skip-unless (version<= "27.0" emacs-version))
- (company-capf-with-buffer
- "(w-c-b|)"
- (company-mode)
- (company-complete)
- (let* ((cand (car (member "with-current-buffer" company-candidates)))
- (render
- (and cand
- (company-fill-propertize cand nil (length cand) nil nil
nil))))
- ;; remove text properties that aren't relevant to our test
- (company--remove-but-these-properties render '(face))
- (should
- (ert-equal-including-properties
- render
- #("with-current-buffer"
- 0 1 (face (company-tooltip-common company-tooltip)) ; "w"
- 1 4 (face (company-tooltip)) ; "ith"
- 4 6 (face (company-tooltip-common company-tooltip)) ; "-c"
- 6 12 (face (company-tooltip)) ; "urrent"
- 12 14 (face (company-tooltip-common company-tooltip)) ; "-b"
- 14 19 (face (company-tooltip)))))))) ; "uffer"
-
-(ert-deftest company-non-prefix-modest-capf-highlighting ()
- "Test highlighting for non-prefix `company-capf' in elisp"
- (skip-unless (version< emacs-version "27.0"))
- (company-capf-with-buffer
- "(w-c-b|)"
- (company-mode)
- (company-complete)
- (let* ((cand (car (member "with-current-buffer" company-candidates)))
- (render
- (and cand
- (company-fill-propertize cand nil (length cand) nil nil
nil))))
- ;; remove text properties that aren't relevant to our test
- (company--remove-but-these-properties render '(face))
- (should
- (ert-equal-including-properties
- render
- #("with-current-buffer"
- 0 14 (face (company-tooltip-common company-tooltip));
"with-current-b"
- 14 19 (face (company-tooltip)))))))) ; "uffer"
-
-(provide 'capf-tests)
-;;; capf-tests.el ends here
diff --git a/packages/company/test/clang-tests.el
b/packages/company/test/clang-tests.el
deleted file mode 100644
index 028f57e..0000000
--- a/packages/company/test/clang-tests.el
+++ /dev/null
@@ -1,51 +0,0 @@
-;;; clang-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015 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/>.
-
-(require 'company-tests)
-(require 'company-clang)
-
-(ert-deftest company-clang-simple-annotation ()
- (let ((str (propertize
- "foo" 'meta
- "wchar_t * wmemchr(wchar_t *__p, wchar_t __c, size_t __n)")))
- (should (equal (company-clang 'annotation str)
- "(wchar_t *__p, wchar_t __c, size_t __n)"))))
-
-(ert-deftest company-clang-generic-annotation ()
- (let ((str (propertize
- "foo" 'meta
- "shared_ptr<_Tp> make_shared<typename _Tp>(_Args &&__args...)")))
- (should (equal (company-clang 'annotation str)
- "<typename _Tp>(_Args &&__args...)"))))
-
-(ert-deftest company-clang-func-ptr-annotation ()
- (let ((str (propertize "foo" 'meta "void (*)(int) foo")))
- (should (equal (company-clang 'annotation str) "(*)(int)"))))
-
-(ert-deftest company-clang-null-annotation ()
- (let ((str "char"))
- (should (null (company-clang 'annotation str)))))
-
-(ert-deftest company-clang-anon-union-annotation ()
- (let ((u (propertize "u" 'meta "union (anonymous) u"))
- (s (propertize "s" 'meta "struct (anonymous) s")))
- (should (null (company-clang 'annotation u)))
- (should (null (company-clang 'annotation s)))))
diff --git a/packages/company/test/cmake-tests.el
b/packages/company/test/cmake-tests.el
deleted file mode 100644
index 83e5d64..0000000
--- a/packages/company/test/cmake-tests.el
+++ /dev/null
@@ -1,44 +0,0 @@
-;;; cmake-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2017 Free Software Foundation, Inc.
-
-;; Author: Zuogong Yue
-
-;; 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-tests)
-(require 'company-cmake)
-
-(ert-deftest company-cmake-complete-in-string-prefix-quotes ()
- (with-temp-buffer
- (insert "set(MyFlags \"${CMAKE_CXX_FLAGS_R")
- (setq-local major-mode 'cmake-mode)
- (should (equal (company-cmake 'prefix)
- "CMAKE_CXX_FLAGS_R"))))
-
-(ert-deftest company-cmake-complete-in-string-more-prefix ()
- (with-temp-buffer
- (insert "set(MyFlags \"${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_R")
- (setq-local major-mode 'cmake-mode)
- (should (equal (company-cmake 'prefix)
- "CMAKE_CXX_FLAGS_R"))))
-
-(ert-deftest company-cmake-complete-in-string-more-prefix-2 ()
- (with-temp-buffer
- (insert "set(MyFlags \"${CMAKE_CXX_FLAGS} CMAKE_CXX_FLAGS_R")
- (setq-local major-mode 'cmake-mode)
- (should (equal (company-cmake 'prefix)
- nil))))
diff --git a/packages/company/test/core-tests.el
b/packages/company/test/core-tests.el
deleted file mode 100644
index 63feca2..0000000
--- a/packages/company/test/core-tests.el
+++ /dev/null
@@ -1,593 +0,0 @@
-;;; core-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015, 2016, 2017 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/>.
-
-(require 'company-tests)
-
-(ert-deftest company-good-prefix ()
- (let ((company-minimum-prefix-length 5)
- company-abort-manual-when-too-short
- company--manual-action ;idle begin
- (company-selection-changed t)) ;has no effect
- (should (eq t (company--good-prefix-p "!@#$%")))
- (should (eq nil (company--good-prefix-p "abcd")))
- (should (eq nil (company--good-prefix-p 'stop)))
- (should (eq t (company--good-prefix-p '("foo" . 5))))
- (should (eq nil (company--good-prefix-p '("foo" . 4))))
- (should (eq t (company--good-prefix-p '("foo" . t))))))
-
-(ert-deftest company--manual-prefix-set-and-unset ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc" "abd")))))))
- (company-manual-begin)
- (should (equal "ab" company--manual-prefix))
- (company-abort)
- (should (null company--manual-prefix)))))
-
-(ert-deftest company-auto-begin-unique-cancels ()
- (with-temp-buffer
- (insert "abc")
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc")))))))
- (company-auto-begin)
- (should (equal nil company-candidates)))))
-
-(ert-deftest company-manual-begin-unique-shows-completion ()
- (with-temp-buffer
- (insert "abc")
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc")))))))
- (company-manual-begin)
- (should (equal '("abc") company-candidates)))))
-
-(ert-deftest company-abort-manual-when-too-short ()
- (let ((company-minimum-prefix-length 5)
- (company-abort-manual-when-too-short t)
- (company-selection-changed t)) ;has not effect
- (let ((company--manual-action nil)) ;idle begin
- (should (eq t (company--good-prefix-p "!@#$%")))
- (should (eq t (company--good-prefix-p '("foo" . 5))))
- (should (eq t (company--good-prefix-p '("foo" . t)))))
- (let ((company--manual-action t)
- (company--manual-prefix "abc")) ;manual begin from this prefix
- (should (eq t (company--good-prefix-p "!@#$")))
- (should (eq nil (company--good-prefix-p "ab")))
- (should (eq nil (company--good-prefix-p 'stop)))
- (should (eq t (company--good-prefix-p '("foo" . 4))))
- (should (eq t (company--good-prefix-p "abcd")))
- (should (eq t (company--good-prefix-p "abc")))
- (should (eq t (company--good-prefix-p '("bar" . t)))))))
-
-(ert-deftest company-common-with-non-prefix-completion ()
- (let ((company-backend #'ignore)
- (company-prefix "abc")
- company-candidates
- company-candidates-length
- company-candidates-cache
- company-common)
- (company-update-candidates '("abc" "def-abc"))
- (should (null company-common))
- (company-update-candidates '("abc" "abe-c"))
- (should (null company-common))
- (company-update-candidates '("abcd" "abcde" "abcdf"))
- (should (equal "abcd" company-common))))
-
-(ert-deftest company-multi-backend-with-lambdas ()
- (let ((company-backend
- (list (lambda (command &optional _ &rest _r)
- (cl-case command
- (prefix "z")
- (candidates '("a" "b"))))
- (lambda (command &optional _ &rest _r)
- (cl-case command
- (prefix "z")
- (candidates '("c" "d")))))))
- (should (equal (company-call-backend 'candidates "z") '("a" "b" "c"
"d")))))
-
-(ert-deftest company-multi-backend-filters-backends-by-prefix ()
- (let ((company-backend
- (list (lambda (command &optional _ &rest _r)
- (cl-case command
- (prefix (cons "z" t))
- (candidates '("a" "b"))))
- (lambda (command &optional _ &rest _r)
- (cl-case command
- (prefix "t")
- (candidates '("c" "d"))))
- (lambda (command &optional _ &rest _r)
- (cl-case command
- (prefix "z")
- (candidates '("e" "f")))))))
- (should (equal (company-call-backend 'candidates "z") '("a" "b" "e"
"f")))))
-
-(ert-deftest company-multi-backend-remembers-candidate-backend ()
- (let ((company-backend
- (list (lambda (command &optional _)
- (cl-case command
- (ignore-case nil)
- (annotation "1")
- (candidates '("a" "c"))
- (post-completion "13")))
- (lambda (command &optional _)
- (cl-case command
- (ignore-case t)
- (annotation "2")
- (candidates '("b" "d"))
- (post-completion "42")))
- (lambda (command &optional _)
- (cl-case command
- (annotation "3")
- (candidates '("e"))
- (post-completion "74"))))))
- (let ((candidates (company-calculate-candidates nil nil)))
- (should (equal candidates '("a" "b" "c" "d" "e")))
- (should (equal t (company-call-backend 'ignore-case)))
- (should (equal "1" (company-call-backend 'annotation (nth 0
candidates))))
- (should (equal "2" (company-call-backend 'annotation (nth 1
candidates))))
- (should (equal "13" (company-call-backend 'post-completion (nth 2
candidates))))
- (should (equal "42" (company-call-backend 'post-completion (nth 3
candidates))))
- (should (equal "3" (company-call-backend 'annotation (nth 4
candidates))))
- (should (equal "74" (company-call-backend 'post-completion (nth 4
candidates)))))))
-
-(ert-deftest company-multi-backend-handles-keyword-with ()
- (let ((primo (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (candidates '("abb" "abc" "abd")))))
- (secundo (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (candidates '("acc" "acd"))))))
- (let ((company-backend (list 'ignore 'ignore :with secundo)))
- (should (null (company-call-backend 'prefix))))
- (let ((company-backend (list 'ignore primo :with secundo)))
- (should (equal "a" (company-call-backend 'prefix)))
- (should (equal '("abb" "abc" "abd" "acc" "acd")
- (company-call-backend 'candidates "a"))))))
-
-(ert-deftest company-multi-backend-handles-keyword-separate ()
- (let ((one (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (candidates (list "aa" "ca" "ba")))))
- (two (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (candidates (list "bb" "ab")))))
- (tri (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (sorted t)
- (candidates (list "cc" "bc" "ac"))))))
- (let ((company-backend (list one two tri :separate)))
- (should (company-call-backend 'sorted))
- (should-not (company-call-backend 'duplicates))
- (should (equal '("aa" "ba" "ca" "ab" "bb" "cc" "bc" "ac")
- (company-call-backend 'candidates "a"))))))
-
-(ert-deftest company-begin-backend-failure-doesnt-break-company-backends ()
- (with-temp-buffer
- (insert "a")
- (company-mode)
- (should-error
- (company-begin-backend #'ignore))
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix "a")
- (candidates '("a" "ab" "ac")))))))
- (let (this-command)
- (company-call 'complete))
- (should (eq 3 company-candidates-length)))))
-
-(ert-deftest company-require-match-explicit ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-require-match 'company-explicit-action-p)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc" "abd")))))))
- (let (this-command)
- (company-complete))
- (let ((last-command-event ?e))
- (company-call 'self-insert-command 1))
- (should (eq 2 company-candidates-length))
- (should (eq 3 (point))))))
-
-(ert-deftest company-dont-require-match-when-idle ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-minimum-prefix-length 2)
- (company-require-match 'company-explicit-action-p)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc" "abd")))))))
- (company-idle-begin (current-buffer) (selected-window)
- (buffer-chars-modified-tick) (point))
- (should (eq 2 company-candidates-length))
- (let ((last-command-event ?e))
- (company-call 'self-insert-command 1))
- (should (eq nil company-candidates-length))
- (should (eq 4 (point))))))
-
-(ert-deftest company-dont-require-match-if-was-a-match-and-old-prefix-ended ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- company-auto-complete
- (company-require-match t)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (company-grab-word))
- (candidates '("abc" "ab" "abd"))
- (sorted t))))))
- (let (this-command)
- (company-complete))
- (let ((last-command-event ?e))
- (company-call 'self-insert-command 1))
- (should (eq 3 company-candidates-length))
- (should (eq 3 (point)))
- (let ((last-command-event ? ))
- (company-call 'self-insert-command 1))
- (should (null company-candidates-length))
- (should (eq 4 (point))))))
-
-(ert-deftest company-dont-require-match-if-was-a-match-and-new-prefix-is-stop
()
- (with-temp-buffer
- (company-mode)
- (insert "c")
- (let (company-frontends
- (company-require-match t)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (if (> (point) 2)
- 'stop
- (buffer-substring (point-min) (point))))
- (candidates '("a" "b" "c")))))))
- (let (this-command)
- (company-complete))
- (should (eq 3 company-candidates-length))
- (let ((last-command-event ?e))
- (company-call 'self-insert-command 1))
- (should (not company-candidates)))))
-
-(ert-deftest company-should-complete-whitelist ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- company-begin-commands
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc" "abd")))))))
- (let ((company-continue-commands nil))
- (let (this-command)
- (company-complete))
- (company-call 'backward-delete-char 1)
- (should (null company-candidates-length)))
- (let ((company-continue-commands '(backward-delete-char)))
- (let (this-command)
- (company-complete))
- (company-call 'backward-delete-char 1)
- (should (eq 2 company-candidates-length))))))
-
-(ert-deftest company-should-complete-blacklist ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- company-begin-commands
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abc" "abd")))))))
- (let ((company-continue-commands '(not backward-delete-char)))
- (let (this-command)
- (company-complete))
- (company-call 'backward-delete-char 1)
- (should (null company-candidates-length)))
- (let ((company-continue-commands '(not backward-delete-char-untabify)))
- (let (this-command)
- (company-complete))
- (company-call 'backward-delete-char 1)
- (should (eq 2 company-candidates-length))))))
-
-(ert-deftest company-backspace-into-bad-prefix ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-minimum-prefix-length 2)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abcd" "abef")))))))
- (let ((company-idle-delay 'now))
- (company-auto-begin))
- (company-call 'backward-delete-char-untabify 1)
- (should (string= "a" (buffer-string)))
- (should (null company-candidates)))))
-
-(ert-deftest company-auto-complete-explicit ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-auto-complete 'company-explicit-action-p)
- (company-auto-complete-chars '(? ))
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abcd" "abef")))))))
- (let (this-command)
- (company-complete))
- (let ((last-command-event ? ))
- (company-call 'self-insert-command 1))
- (should (string= "abcd " (buffer-string))))))
-
-(ert-deftest company-auto-complete-with-electric-pair ()
- (with-temp-buffer
- (insert "foo(ab)")
- (forward-char -1)
- (company-mode)
- (let (company-frontends
- (company-auto-complete t)
- (company-auto-complete-chars '(? ?\)))
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring 5 (point)))
- (candidates '("abcd" "abef"))))))
- (electric-pair electric-pair-mode))
- (unwind-protect
- (progn
- (electric-pair-mode)
- (let (this-command)
- (company-complete))
- (let ((last-command-event ?\)))
- (company-call 'self-insert-command 1)))
- (unless electric-pair
- (electric-pair-mode -1)))
- (should (string= "foo(abcd)" (buffer-string))))))
-
-(ert-deftest company-no-auto-complete-when-idle ()
- (with-temp-buffer
- (insert "ab")
- (company-mode)
- (let (company-frontends
- (company-auto-complete 'company-explicit-action-p)
- (company-auto-complete-chars '(? ))
- (company-minimum-prefix-length 2)
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abcd" "abef")))))))
- (company-idle-begin (current-buffer) (selected-window)
- (buffer-chars-modified-tick) (point))
- (let ((last-command-event ? ))
- (company-call 'self-insert-command 1))
- (should (string= "ab " (buffer-string))))))
-
-(ert-deftest company-clears-explicit-action-when-no-matches ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- company-backends)
- (company-call 'manual-begin) ;; fails
- (should (null company-candidates))
- (should (null (company-explicit-action-p))))))
-
-(ert-deftest company-ignore-case-replaces-prefix ()
- (with-temp-buffer
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abcd" "abef"))
- (ignore-case t))))))
- (insert "A")
- (let (this-command)
- (company-complete))
- (should (string= "ab" (buffer-string)))
- (delete-char -2)
- (insert "A") ; hack, to keep it in one test
- (company-complete-selection)
- (should (string= "abcd" (buffer-string))))))
-
-(ert-deftest company-ignore-case-with-keep-prefix ()
- (with-temp-buffer
- (insert "AB")
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("abcd" "abef"))
- (ignore-case 'keep-prefix))))))
- (let (this-command)
- (company-complete))
- (company-complete-selection)
- (should (string= "ABcd" (buffer-string))))))
-
-(ert-deftest company-non-prefix-completion ()
- (with-temp-buffer
- (insert "tc")
- (company-mode)
- (let (company-frontends
- (company-backends
- (list (lambda (command &optional _)
- (cl-case command
- (prefix (buffer-substring (point-min) (point)))
- (candidates '("tea-cup" "teal-color")))))))
- (let (this-command)
- (company-complete))
- (should (string= "tc" (buffer-string)))
- (company-complete-selection)
- (should (string= "tea-cup" (buffer-string))))))
-
-(defvar ct-sorted nil)
-
-(defun ct-equal-including-properties (list1 list2)
- (or (and (not list1) (not list2))
- (and (ert-equal-including-properties (car list1) (car list2))
- (ct-equal-including-properties (cdr list1) (cdr list2)))))
-
-(ert-deftest company-strips-duplicates-returns-nil ()
- (should (null (company--preprocess-candidates nil))))
-
-(ert-deftest company-strips-duplicates-within-groups ()
- (let* ((kvs '(("a" . "b")
- ("a" . nil)
- ("a" . "b")
- ("a" . "c")
- ("a" . "b")
- ("b" . "c")
- ("b" . nil)
- ("a" . "b")))
- (fn (lambda (kvs)
- (mapcar (lambda (kv) (propertize (car kv) 'ann (cdr kv)))
- kvs)))
- (company-backend
- (lambda (command &optional arg)
- (pcase command
- (`prefix "")
- (`sorted ct-sorted)
- (`duplicates t)
- (`annotation (get-text-property 0 'ann arg)))))
- (reference '(("a" . "b")
- ("a" . nil)
- ("a" . "c")
- ("b" . "c")
- ("b" . nil)
- ("a" . "b"))))
- (let ((ct-sorted t))
- (should (ct-equal-including-properties
- (company--preprocess-candidates (funcall fn kvs))
- (funcall fn reference))))
- (should (ct-equal-including-properties
- (company--preprocess-candidates (funcall fn kvs))
- (funcall fn (butlast reference))))))
-
-;;; Row and column
-
-(ert-deftest company-column-with-composition ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "lambda ()")
- (compose-region 1 (1+ (length "lambda")) "\\")
- (should (= (company--column) 4)))))
-
-(ert-deftest company-column-with-line-prefix ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "foo")
- (put-text-property (point-min) (point) 'line-prefix " ")
- (should (= (company--column) 5)))))
-
-(ert-deftest company-column-with-line-prefix-on-empty-line ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "\n")
- (forward-char -1)
- (put-text-property (point-min) (point-max) 'line-prefix " ")
- (should (= (company--column) 2)))))
-
-(ert-deftest company-column-with-tabs ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "|\t|\t|\t(")
- (let ((tab-width 8))
- (should (= (company--column) 25))))))
-
-(ert-deftest company-row-with-header-line-format ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (should (= (company--row) 0))
- (setq header-line-format "aaaaaaa")
- (should (= (company--row) 0)))))
-
-(ert-deftest company-column-with-line-numbers-display ()
- :tags '(interactive)
- (skip-unless (fboundp 'display-line-numbers-mode))
- (with-temp-buffer
- (display-line-numbers-mode)
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (should (= (company--column) 0)))))
-
-(ert-deftest company-row-and-column-with-line-numbers-display ()
- :tags '(interactive)
- (skip-unless (fboundp 'display-line-numbers-mode))
- (with-temp-buffer
- (display-line-numbers-mode)
- (insert (make-string (+ (company--window-width)
(line-number-display-width)) ?a))
- (insert ?\n)
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (should (= (company--column) 0))
- (should (= (company--row) 2)))))
diff --git a/packages/company/test/elisp-tests.el
b/packages/company/test/elisp-tests.el
deleted file mode 100644
index 5cc9181..0000000
--- a/packages/company/test/elisp-tests.el
+++ /dev/null
@@ -1,190 +0,0 @@
-;;; elisp-tests.el --- company-elisp tests
-
-;; Copyright (C) 2013-2015 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/>.
-
-;;; Code:
-
-(require 'company-tests)
-(require 'company-elisp)
-
-(defmacro company-elisp-with-buffer (contents &rest body)
- (declare (indent 0))
- `(with-temp-buffer
- (insert ,contents)
- (setq major-mode 'emacs-lisp-mode)
- (re-search-backward "|")
- (replace-match "")
- (let ((company-elisp-detect-function-context t))
- ,@body)))
-
-(ert-deftest company-elisp-candidates-predicate ()
- (company-elisp-with-buffer
- "(foo ba|)"
- (should (eq (company-elisp--candidates-predicate "ba")
- 'boundp))
- (should (eq (let (company-elisp-detect-function-context)
- (company-elisp--candidates-predicate "ba"))
- 'company-elisp--predicate)))
- (company-elisp-with-buffer
- "(foo| )"
- (should (eq (company-elisp--candidates-predicate "foo")
- 'fboundp))
- (should (eq (let (company-elisp-detect-function-context)
- (company-elisp--candidates-predicate "foo"))
- 'company-elisp--predicate)))
- (company-elisp-with-buffer
- "(foo 'b|)"
- (should (eq (company-elisp--candidates-predicate "b")
- 'company-elisp--predicate))))
-
-(ert-deftest company-elisp-candidates-predicate-in-docstring ()
- (company-elisp-with-buffer
- "(def foo () \"Doo be doo `ide|"
- (should (eq 'company-elisp--predicate
- (company-elisp--candidates-predicate "ide")))))
-
-;; This one's also an integration test.
-(ert-deftest company-elisp-candidates-recognizes-binding-form ()
- (let ((company-elisp-detect-function-context t)
- (obarray [when what whelp])
- (what 1)
- (whelp 2)
- (wisp 3))
- (company-elisp-with-buffer
- "(let ((foo 7) (wh| )))"
- (should (equal '("what" "whelp")
- (company-elisp-candidates "wh"))))
- (company-elisp-with-buffer
- "(cond ((null nil) (wh| )))"
- (should (equal '("when")
- (company-elisp-candidates "wh"))))))
-
-(ert-deftest company-elisp-candidates-predicate-binding-without-value ()
- (cl-loop for (text prefix predicate) in '(("(let (foo|" "foo" boundp)
- ("(let (foo (bar|" "bar" boundp)
- ("(let (foo) (bar|" "bar" fboundp))
- do
- (eval `(company-elisp-with-buffer
- ,text
- (should (eq ',predicate
- (company-elisp--candidates-predicate
,prefix)))))))
-
-(ert-deftest company-elisp-finds-vars ()
- (let ((obarray [boo bar baz backquote])
- (boo t)
- (bar t)
- (baz t))
- (should (equal '("bar" "baz")
- (company-elisp--globals "ba" 'boundp)))))
-
-(ert-deftest company-elisp-finds-functions ()
- (let ((obarray [when what whelp])
- (what t)
- (whelp t))
- (should (equal '("when")
- (company-elisp--globals "wh" 'fboundp)))))
-
-(ert-deftest company-elisp-finds-things ()
- (let ((obarray [when what whelp])
- (what t)
- (whelp t))
- (should (equal '("what" "whelp" "when")
- (sort (company-elisp--globals "wh"
'company-elisp--predicate)
- 'string<)))))
-
-(ert-deftest company-elisp-locals-vars ()
- (company-elisp-with-buffer
- "(let ((foo 5) (bar 6))
- (cl-labels ((borg ()))
- (lambda (boo baz)
- b|)))"
- (should (equal '("bar" "baz" "boo")
- (company-elisp--locals "b" nil)))))
-
-(ert-deftest company-elisp-locals-single-var ()
- (company-elisp-with-buffer
- "(dotimes (itk 100)
- (dolist (item items)
- it|))"
- (should (equal '("itk" "item")
- (company-elisp--locals "it" nil)))))
-
-(ert-deftest company-elisp-locals-funs ()
- (company-elisp-with-buffer
- "(cl-labels ((foo ())
- (fee ()))
- (let ((fun 4))
- (f| )))"
- (should (equal '("fee" "foo")
- (sort (company-elisp--locals "f" t) 'string<)))))
-
-(ert-deftest company-elisp-locals-skips-current-varlist ()
- (company-elisp-with-buffer
- "(let ((foo 1)
- (f| )))"
- (should (null (company-elisp--locals "f" nil)))))
-
-(ert-deftest company-elisp-show-locals-first ()
- (company-elisp-with-buffer
- "(let ((floo 1)
- (flop 2)
- (flee 3))
- fl|)"
- (let ((obarray [float-pi]))
- (let (company-elisp-show-locals-first)
- (should (eq nil (company-elisp 'sorted))))
- (let ((company-elisp-show-locals-first t))
- (should (eq t (company-elisp 'sorted)))
- (should (equal '("flee" "floo" "flop" "float-pi")
- (company-elisp-candidates "fl")))))))
-
-(ert-deftest company-elisp-candidates-no-duplicates ()
- (company-elisp-with-buffer
- "(let ((float-pi 4))
- f|)"
- (let ((obarray [float-pi])
- (company-elisp-show-locals-first t))
- (should (equal '("float-pi") (company-elisp-candidates "f"))))))
-
-(ert-deftest company-elisp-shouldnt-complete-defun-name ()
- (company-elisp-with-buffer
- "(defun foob|)"
- (should (null (company-elisp 'prefix)))))
-
-(ert-deftest company-elisp-should-complete-def-call ()
- (company-elisp-with-buffer
- "(defu|"
- (should (equal "defu" (company-elisp 'prefix)))))
-
-(ert-deftest company-elisp-should-complete-in-defvar ()
- ;; It will also complete the var name, at least for now.
- (company-elisp-with-buffer
- "(defvar abc de|"
- (should (equal "de" (company-elisp 'prefix)))))
-
-(ert-deftest company-elisp-shouldnt-complete-in-defun-arglist ()
- (company-elisp-with-buffer
- "(defsubst foobar (ba|"
- (should (null (company-elisp 'prefix)))))
-
-(ert-deftest company-elisp-prefix-in-defun-body ()
- (company-elisp-with-buffer
- "(defun foob ()|)"
- (should (equal "" (company-elisp 'prefix)))))
diff --git a/packages/company/test/files-tests.el
b/packages/company/test/files-tests.el
deleted file mode 100644
index b5dd484..0000000
--- a/packages/company/test/files-tests.el
+++ /dev/null
@@ -1,48 +0,0 @@
-;;; filtes-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2016 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/>.
-
-(require 'company-tests)
-(require 'company-files)
-
-(ert-deftest company-files-candidates-normal ()
- (let (company-files--completion-cache)
- (should (member (expand-file-name "test/" company-dir)
- (company-files 'candidates
- company-dir)))))
-
-(ert-deftest company-files-candidates-normal-root ()
- (let (company-files--completion-cache)
- (should (member "/bin/"
- (company-files 'candidates "/")))))
-
-(ert-deftest company-files-candidates-excluding-dir ()
- (let ((company-files-exclusions '("test/"))
- company-files--completion-cache)
- (should-not (member (expand-file-name "test/" company-dir)
- (company-files 'candidates
- company-dir)))))
-
-(ert-deftest company-files-candidates-excluding-files ()
- (let ((company-files-exclusions '(".el"))
- company-files--completion-cache)
- (should-not (member (expand-file-name "company.el" company-dir)
- (company-files 'candidates
- company-dir)))))
diff --git a/packages/company/test/frontends-tests.el
b/packages/company/test/frontends-tests.el
deleted file mode 100644
index e74b024..0000000
--- a/packages/company/test/frontends-tests.el
+++ /dev/null
@@ -1,393 +0,0 @@
-;;; frontends-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015, 2016 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/>.
-
-(require 'company-tests)
-
-(ert-deftest company-pseudo-tooltip-does-not-get-displaced ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (save-excursion (insert " ff"))
- (company-mode)
- (let ((company-frontends '(company-pseudo-tooltip-frontend))
- (company-begin-commands '(self-insert-command))
- (company-backends
- (list (lambda (c &rest _)
- (cl-case c (prefix "") (candidates '("a" "b" "c")))))))
- (let (this-command)
- (company-call 'complete))
- (company-call 'open-line 1)
- (should (eq 2 (overlay-start company-pseudo-tooltip-overlay)))))))
-
-(ert-deftest company-pseudo-tooltip-show ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "aaaa\n bb\nccccccc\nddd")
- (search-backward "bb")
- (let ((col (company--column))
- (company-candidates-length 2)
- (company-candidates '("123" "45"))
- (company-backend 'ignore))
- (company-pseudo-tooltip-show (company--row) col 0)
- (let ((ov company-pseudo-tooltip-overlay))
- ;; With margins.
- (should (eq (overlay-get ov 'company-width) 5))
- ;; FIXME: Make it 2?
- (should (eq (overlay-get ov 'company-height) company-tooltip-limit))
- (should (eq (overlay-get ov 'company-column) col))
- (should (string= (overlay-get ov 'company-display)
- " 123 \nc 45 c\nddd\n")))))))
-
-(ert-deftest company-pseudo-tooltip-edit-updates-width ()
- :tags '(interactive)
- (with-temp-buffer
- (set-window-buffer nil (current-buffer))
- (let ((company-candidates-length 5)
- (company-candidates '("123" "45" "67" "89" "1011"))
- (company-backend 'ignore)
- (company-tooltip-limit 4)
- (company-tooltip-offset-display 'scrollbar))
- (company-pseudo-tooltip-show (company--row)
- (company--column)
- 0)
- (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
- 6))
- (company-pseudo-tooltip-edit 4)
- (should (eq (overlay-get company-pseudo-tooltip-overlay 'company-width)
- 7)))))
-
-(ert-deftest company-preview-show-with-annotations ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (save-excursion (insert "\n"))
- (let ((company-backend #'ignore))
- (company-preview-show-at-point (point) "123")
- (let* ((ov company-preview-overlay)
- (str (overlay-get ov 'after-string)))
- (should (string= str "123"))
- (should (eq (get-text-property 0 'cursor str) 1)))))))
-
-(ert-deftest company-pseudo-tooltip-show-with-annotations ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert " ")
- (save-excursion (insert "\n"))
- (let ((company-candidates-length 2)
- (company-backend (lambda (action &optional arg &rest _ignore)
- (when (eq action 'annotation)
- (cdr (assoc arg '(("123" . "(4)")))))))
- (company-candidates '("123" "45"))
- company-tooltip-align-annotations)
- (company-pseudo-tooltip-show-at-point (point) 0)
- (let ((ov company-pseudo-tooltip-overlay))
- ;; With margins.
- (should (eq (overlay-get ov 'company-width) 8))
- (should (string= (overlay-get ov 'company-display)
- " 123(4) \n 45 \n")))))))
-
-(ert-deftest company-pseudo-tooltip-show-with-annotations-right-aligned ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert " ")
- (save-excursion (insert "\n"))
- (let ((company-candidates-length 3)
- (company-backend (lambda (action &optional arg &rest _ignore)
- (when (eq action 'annotation)
- (cdr (assoc arg '(("123" . "(4)")
- ("67" . "(891011)")))))))
- (company-candidates '("123" "45" "67"))
- (company-tooltip-align-annotations t))
- (company-pseudo-tooltip-show-at-point (point) 0)
- (let ((ov company-pseudo-tooltip-overlay))
- ;; With margins.
- (should (eq (overlay-get ov 'company-width) 13))
- (should (string= (overlay-get ov 'company-display)
- " 123 (4) \n 45 \n 67 (891011)
\n")))))))
-
-(ert-deftest company-create-lines-shows-numbers ()
- (let ((company-show-numbers t)
- (company-candidates '("x" "y" "z"))
- (company-candidates-length 3)
- (company-backend 'ignore))
- (should (equal '(" x 1 " " y 2 " " z 3 ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-create-lines-shows-numbers-on-the-left ()
- (let ((company-show-numbers 'left)
- (company-candidates '("x" "y" "z"))
- (company-candidates-length 3)
- (company-backend 'ignore))
- (should (equal '(" 1 x " " 2 y " " 3 z ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-create-lines-truncates-annotations ()
- (let* ((ww (company--window-width))
- (data `(("1" . "(123)")
- ("2" . nil)
- ("3" . ,(concat "(" (make-string (- ww 2) ?4) ")"))
- (,(make-string ww ?4) . "<4>")))
- (company-candidates (mapcar #'car data))
- (company-candidates-length 4)
- (company-tooltip-margin 1)
- (company-backend (lambda (cmd &optional arg &rest _)
- (when (eq cmd 'annotation)
- (cdr (assoc arg data)))))
- company-tooltip-align-annotations)
- (should (equal (list (format " 1(123)%s " (company-space-string (- ww 8)))
- (format " 2%s " (company-space-string (- ww 3)))
- (format " 3(444%s " (make-string (- ww 7) ?4))
- (format " %s " (make-string (- ww 2) ?4)))
- (company--create-lines 0 999)))
- (let ((company-tooltip-align-annotations t))
- (should (equal (list (format " 1%s(123) " (company-space-string (- ww
8)))
- (format " 2%s " (company-space-string (- ww 3)))
- (format " 3 (444%s " (make-string (- ww 8) ?4))
- (format " %s " (make-string (- ww 2) ?4)))
- (company--create-lines 0 999))))))
-
-(ert-deftest company-create-lines-truncates-common-part ()
- (let* ((ww (company--window-width))
- (company-candidates-length 2)
- (company-tooltip-margin 1)
- (company-backend #'ignore))
- (let* ((company-common (make-string (- ww 3) ?1))
- (company-candidates `(,(concat company-common "2")
- ,(concat company-common "3"))))
- (should (equal (list (format " %s2 " (make-string (- ww 3) ?1))
- (format " %s3 " (make-string (- ww 3) ?1)))
- (company--create-lines 0 999))))
- (let* ((company-common (make-string (- ww 2) ?1))
- (company-candidates `(,(concat company-common "2")
- ,(concat company-common "3"))))
- (should (equal (list (format " %s " company-common)
- (format " %s " company-common))
- (company--create-lines 0 999))))
- (let* ((company-common (make-string ww ?1))
- (company-candidates `(,(concat company-common "2")
- ,(concat company-common "3")))
- (res (company--create-lines 0 999)))
- (should (equal (list (format " %s " (make-string (- ww 2) ?1))
- (format " %s " (make-string (- ww 2) ?1)))
- res))
- (should (equal '(company-tooltip-common-selection
- company-tooltip-selection
- company-tooltip)
- (get-text-property (- ww 2) 'face
- (car res))))
- (should (equal '(company-tooltip-selection
- company-tooltip)
- (get-text-property (1- ww) 'face
- (car res))))
- )))
-
-(ert-deftest company-create-lines-clears-out-non-printables ()
- :tags '(interactive)
- (let (company-show-numbers
- (company-candidates (list
- (decode-coding-string "avalis\351e" 'utf-8)
- "avatar"))
- (company-candidates-length 2)
- (company-backend 'ignore))
- (should (equal '(" avalis‗e "
- " avatar ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-create-lines-handles-multiple-width ()
- :tags '(interactive)
- (let (company-show-numbers
- (company-candidates '("蛙蛙蛙蛙" "蛙abc"))
- (company-candidates-length 2)
- (company-backend 'ignore))
- (should (equal '(" 蛙蛙蛙蛙 "
- " 蛙abc ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-create-lines-handles-multiple-width-in-annotation ()
- (let* (company-show-numbers
- (alist '(("a" . " ︸") ("b" . " ︸︸")))
- (company-candidates (mapcar #'car alist))
- (company-candidates-length 2)
- (company-backend (lambda (c &optional a &rest _)
- (when (eq c 'annotation)
- (assoc-default a alist)))))
- (should (equal '(" a ︸ "
- " b ︸︸ ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-create-lines-with-multiple-width-and-keep-prefix ()
- :tags '(interactive)
- (let* (company-show-numbers
- (company-candidates '("MIRAI発売1カ月"
- "MIRAI発売2カ月"))
- (company-candidates-length 2)
- (company-prefix "MIRAI発")
- (company-backend (lambda (c &rest _)
- (pcase c
- (`ignore-case 'keep-prefix)))))
- (should (equal '(" MIRAI発売1カ月 "
- " MIRAI発売2カ月 ")
- (company--create-lines 0 999)))))
-
-(ert-deftest company-fill-propertize-truncates-search-highlight ()
- (let ((company-search-string "foo")
- (company-backend #'ignore)
- (company-prefix ""))
- (should (ert-equal-including-properties
- (company-fill-propertize "barfoo" nil 6 t nil nil)
- #("barfoo"
- 0 3 (face (company-tooltip-selection company-tooltip)
mouse-face (company-tooltip-mouse))
- 3 6 (face (company-tooltip-search-selection
company-tooltip-selection company-tooltip) mouse-face
(company-tooltip-mouse)))))
- (should (ert-equal-including-properties
- (company-fill-propertize "barfoo" nil 5 t "" " ")
- #("barfo "
- 0 3 (face (company-tooltip-selection company-tooltip)
mouse-face (company-tooltip-mouse))
- 3 5 (face (company-tooltip-search-selection
company-tooltip-selection company-tooltip) mouse-face (company-tooltip-mouse))
- 5 6 (face (company-tooltip-selection company-tooltip)
mouse-face (company-tooltip-mouse)))))
- (should (ert-equal-including-properties
- (company-fill-propertize "barfoo" nil 3 t " " " ")
- #(" bar "
- 0 5 (face (company-tooltip-selection company-tooltip)
mouse-face (company-tooltip-mouse)))))))
-
-(ert-deftest company-fill-propertize-overrides-face-property ()
- (let ((company-backend #'ignore)
- (company-prefix "")
- (str1 (propertize "str1" 'face 'foo))
- (str2 (propertize "str2" 'face 'foo)))
- (should (ert-equal-including-properties
- (company-fill-propertize str1 str2 8 nil nil nil)
- #("str1str2"
- 0 4 (face (company-tooltip) mouse-face (company-tooltip-mouse))
- 4 8 (face (company-tooltip-annotation company-tooltip)
- mouse-face (company-tooltip-mouse)))))))
-
-(ert-deftest company-fill-propertize-delegates-to-pre-render ()
- (let ((company-backend
- (lambda (command &rest args)
- (pcase command
- (`pre-render
- (propertize (car args)
- 'face (if (cadr args)
- 'annotation
- 'value))))))
- (company-prefix "")
- (str1 (propertize "str1" 'foo 'bar))
- (str2 (propertize "str2" 'foo 'bar)))
- (let ((res (company-fill-propertize str1 str2 8 nil nil nil)))
- ;; Could use `ert-equal-including-properties' as well.
- (should (eq (get-text-property 0 'foo res) 'bar))
- (should (eq (get-text-property 4 'foo res) 'bar))
- (should (equal (get-text-property 0 'face res)
- '(value company-tooltip)))
- (should (equal (get-text-property 4 'face res)
- '(annotation company-tooltip-annotation
company-tooltip))))))
-
-(ert-deftest company-column-with-composition ()
- :tags '(interactive)
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "lambda ()")
- (compose-region 1 (1+ (length "lambda")) "\\")
- (should (= (company--column) 4)))))
-
-(ert-deftest company-plainify ()
- (let ((tab-width 8))
- (should (equal-including-properties
- (company-plainify "\tabc\td\t")
- (concat " "
- "abc "
- "d "))))
- (should (equal-including-properties
- (company-plainify (propertize "foobar" 'line-prefix "-*-"))
- "-*-foobar")))
-
-(ert-deftest company-buffer-lines-with-lines-folded ()
- :tags '(interactive)
- (with-temp-buffer
- (insert (propertize "aaa\nbbb\nccc\nddd\n" 'display "aaa+\n"))
- (insert "eee\nfff\nggg")
- (should (equal (company-buffer-lines (point-min) (point-max))
- '("aaa" "eee" "fff" "ggg")))))
-
-(ert-deftest company-buffer-lines-with-multiline-display ()
- :tags '(interactive)
- (with-temp-buffer
- (insert (propertize "a" 'display "bbb\nccc\ndddd\n"))
- (insert "eee\nfff\nggg")
- (should (equal (company-buffer-lines (point-min) (point-max))
- '("a" "" "" "eee" "fff" "ggg")))))
-
-(ert-deftest company-buffer-lines-with-multiline-after-string-at-eob ()
- :tags '(interactive)
- (with-temp-buffer
- (insert "a\nb\nc\n")
- (let ((ov (make-overlay (point-max) (point-max) nil t t)))
- (overlay-put ov 'after-string "~\n~\n~"))
- (should (equal (company-buffer-lines (point-min) (point-max))
- '("a" "b" "c")))))
-
-(ert-deftest company-buffer-lines-with-line-wrapping ()
- :tags '(interactive)
- (with-temp-buffer
- (let ((ww (company--window-width)))
- (insert (make-string (* 3 ww) ?a))
- (should (equal (company-buffer-lines (point-min) (point-max))
- (list (make-string ww ?a)
- (make-string ww ?a)
- (make-string ww ?a)))))))
-
-(ert-deftest company-modify-line ()
- (let ((str "-*-foobar"))
- (should (equal-including-properties
- (company-modify-line str "zz" 4)
- "-*-fzzbar"))
- (should (equal-including-properties
- (company-modify-line str "xx" 0)
- "xx-foobar"))
- (should (equal-including-properties
- (company-modify-line str "zz" 10)
- "-*-foobar zz"))))
-
-(ert-deftest company-modify-line-with-invisible-prop ()
- (let ((str "-*-foobar")
- (buffer-invisibility-spec '((outline . t) t)))
- (put-text-property 1 2 'invisible 'foo str)
- (should (equal
- (company-modify-line str "zz" 4)
- "-*-fzzbar"))))
-
-(ert-deftest company-scrollbar-bounds ()
- (should (equal nil (company--scrollbar-bounds 0 3 3)))
- (should (equal nil (company--scrollbar-bounds 0 4 3)))
- (should (equal '(0 . 0) (company--scrollbar-bounds 0 1 2)))
- (should (equal '(1 . 1) (company--scrollbar-bounds 2 2 4)))
- (should (equal '(2 . 3) (company--scrollbar-bounds 7 4 12)))
- (should (equal '(1 . 2) (company--scrollbar-bounds 3 4 12)))
- (should (equal '(1 . 3) (company--scrollbar-bounds 4 5 11))))
diff --git a/packages/company/test/keywords-tests.el
b/packages/company/test/keywords-tests.el
deleted file mode 100644
index 1c69f0f..0000000
--- a/packages/company/test/keywords-tests.el
+++ /dev/null
@@ -1,32 +0,0 @@
-;;; keywords-tests.el --- company-keywords tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2011, 2013-2015 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/>.
-
-(require 'company-keywords)
-
-(ert-deftest company-sorted-keywords ()
- "Test that keywords in `company-keywords-alist' are in alphabetical order."
- (dolist (pair company-keywords-alist)
- (when (consp (cdr pair))
- (let ((prev (cadr pair)))
- (dolist (next (cddr pair))
- (should (not (equal prev next)))
- (should (string< prev next))
- (setq prev next))))))
diff --git a/packages/company/test/template-tests.el
b/packages/company/test/template-tests.el
deleted file mode 100644
index 975c3ff..0000000
--- a/packages/company/test/template-tests.el
+++ /dev/null
@@ -1,170 +0,0 @@
-;;; template-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015 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/>.
-
-(require 'company-tests)
-(require 'company-template)
-
-(defun company-template-field-assert-text (str &optional pos)
- (let ((field (company-template-field-at pos)))
- (should (equal (buffer-substring-no-properties
- (overlay-start field)
- (overlay-end field))
- str))))
-
-(ert-deftest company-template-removed-after-the-last-jump ()
- (with-temp-buffer
- (insert "{ }")
- (goto-char 2)
- (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
- (save-excursion
- (dotimes (_ 2)
- (insert " foo")
- (company-template-add-field tpl (- (point) 3) (point))))
- (company-call 'template-forward-field)
- (should (= 3 (point)))
- (company-call 'template-forward-field)
- (should (= 7 (point)))
- (company-call 'template-forward-field)
- (should (= 11 (point)))
- (should (zerop (length (overlay-get tpl 'company-template-fields))))
- (should (null (overlay-buffer tpl))))))
-
-(ert-deftest company-template-removed-after-input-and-jump ()
- (with-temp-buffer
- (insert "{ }")
- (goto-char 2)
- (let ((tpl (company-template-declare-template (point) (1- (point-max)))))
- (save-excursion
- (insert " bar")
- (company-template-add-field tpl (- (point) 3) (point)))
- (company-call 'template-move-to-first tpl)
- (should (= 3 (point)))
- (dolist (c (string-to-list "tee"))
- (let ((last-command-event c))
- (company-call 'self-insert-command 1)))
- (should (string= "{ tee }" (buffer-string)))
- (should (overlay-buffer tpl))
- (company-call 'template-forward-field)
- (should (= 7 (point)))
- (should (null (overlay-buffer tpl))))))
-
-(ert-deftest company-template-c-like-templatify ()
- (with-temp-buffer
- (let ((text "foo(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (should (equal "foo(int a, short b)" (buffer-string)))
- (company-template-field-assert-text "int a"))))
-
-(ert-deftest company-template-c-like-templatify-trims-after-closing-paren ()
- (with-temp-buffer
- (let ((text "foo(int a, short b)!@ #1334 a"))
- (insert text)
- (company-template-c-like-templatify text)
- (should (equal "foo(int a, short b)" (buffer-string)))
- (company-template-field-assert-text "int a"))))
-
-(ert-deftest company-template-c-like-templatify-generics ()
- (with-temp-buffer
- (let ((text "foo<TKey, TValue>(int i, Dict<TKey, TValue>, long l)"))
- (insert text)
- (company-template-c-like-templatify text)
- (should (equal (buffer-string) text))
- (company-template-field-assert-text "TKey")
- (search-forward "Dict")
- (forward-char -1)
- (company-template-field-assert-text "Dict<TKey, TValue>"))))
-
-(ert-deftest company-template-c-like-func-ptr ()
- (with-temp-buffer
- (let ((text "foo(*)(int)"))
- (insert text)
- (company-template-c-like-templatify text)
- (should (equal (buffer-string) "foo(int)"))
- (company-template-field-assert-text "int"))))
-
-(ert-deftest company-clang-objc-templatify-empty-args ()
- (with-temp-buffer
- (let ((text "createBookWithTitle:andAuthor:"))
- (insert text)
- (company-template-objc-templatify text)
- (should (equal "createBookWithTitle:arg0 andAuthor:arg1"
(buffer-string)))
- (should (looking-at "arg0"))
- (should (null (overlay-get (company-template-field-at) 'display))))))
-
-(ert-deftest company-template-objc-templatify ()
- (with-temp-buffer
- (let ((text "createBookWithTitle:(NSString) andAuthor:(id)"))
- (insert text)
- (company-template-objc-templatify text)
- (should (equal (buffer-string) text))
- (company-template-field-assert-text "(NSString)"))))
-
-(ert-deftest company-template-clear-field-c-like-first-arg ()
- (with-temp-buffer
- (let ((text "foo(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (company-template-clear-field)
- (should (equal "foo(short b)" (buffer-string))))))
-
-(ert-deftest company-template-clear-field-c-like-last-arg ()
- (with-temp-buffer
- (let ((text "foo(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (insert "42")
- (company-template-forward-field)
- (company-template-clear-field)
- (should (equal "foo(42)" (buffer-string))))))
-
-(ert-deftest company-template-clear-field-c-like-generic-1 ()
- (with-temp-buffer
- (let ((text "foo<TValue>(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (company-template-clear-field)
- (should (equal "foo<>(int a, short b)" (buffer-string))))))
-
-(ert-deftest company-template-clear-field-c-like-generic-2 ()
- (with-temp-buffer
- (let ((text "foo<TKey, TValue>(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (company-template-clear-field)
- (should (equal "foo<TValue>(int a, short b)" (buffer-string))))))
-
-(ert-deftest company-template-clear-field-objc-first-arg ()
- (with-temp-buffer
- (let ((text "createBookWithTitle:andAuthor:"))
- (insert text)
- (company-template-objc-templatify text)
- (company-template-clear-field)
- (should (equal "createBookWithTitle: andAuthor:arg1" (buffer-string))))))
-
-(ert-deftest company-template-insert-hook-c-like-field ()
- (with-temp-buffer
- (let ((text "foo(int a, short b)"))
- (insert text)
- (company-template-c-like-templatify text)
- (let ((ovl (company-template-field-at (point))))
- (company-template-insert-hook ovl nil)
- (should (equal "foo(, short b)" (buffer-string)))))))
diff --git a/packages/company/test/transformers-tests.el
b/packages/company/test/transformers-tests.el
deleted file mode 100644
index 9a3f9c6..0000000
--- a/packages/company/test/transformers-tests.el
+++ /dev/null
@@ -1,58 +0,0 @@
-;;; transformers-tests.el --- company-mode tests -*- lexical-binding: t -*-
-
-;; Copyright (C) 2015 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/>.
-
-(require 'company-tests)
-
-(ert-deftest company-occurrence-prefer-closest-above ()
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "foo0
-foo1
-")
- (save-excursion
- (insert "
-foo3
-foo2"))
- (let ((company-backend 'company-dabbrev)
- (company-occurrence-weight-function
- 'company-occurrence-prefer-closest-above))
- (should (equal '("foo1" "foo0" "foo3" "foo2" "foo4")
- (company-sort-by-occurrence
- '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))
-
-(ert-deftest company-occurrence-prefer-any-closest ()
- (with-temp-buffer
- (save-window-excursion
- (set-window-buffer nil (current-buffer))
- (insert "foo0
-foo1
-")
- (save-excursion
- (insert "
-foo3
-foo2"))
- (let ((company-backend 'company-dabbrev)
- (company-occurrence-weight-function
- 'company-occurrence-prefer-any-closest))
- (should (equal '("foo1" "foo3" "foo0" "foo2" "foo4")
- (company-sort-by-occurrence
- '("foo0" "foo1" "foo2" "foo3" "foo4"))))))))
diff --git a/packages/context-coloring/.elpaignore
b/packages/context-coloring/.elpaignore
deleted file mode 100644
index bad5d87..0000000
--- a/packages/context-coloring/.elpaignore
+++ /dev/null
@@ -1,10 +0,0 @@
-.elpaignore
-.gitignore
-.travis.yml
-Cask
-context-coloring-benchmark.el
-context-coloring-coverage.el
-context-coloring-test.el
-fixtures
-Makefile
-screenshot.png
diff --git a/packages/context-coloring/.gitignore
b/packages/context-coloring/.gitignore
deleted file mode 100644
index b9fedca..0000000
--- a/packages/context-coloring/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-*-autoloads.el
-*-pkg.el
-*.elc
-.cask/
-/benchmark/
-/coverage/
diff --git a/packages/context-coloring/.travis.yml
b/packages/context-coloring/.travis.yml
deleted file mode 100644
index 70d1f6d..0000000
--- a/packages/context-coloring/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-sudo: false
-
-language: emacs-lisp
-
-env:
- - EVM_EMACS=emacs-24.3-travis
- - EVM_EMACS=emacs-24.4-travis
- - EVM_EMACS=emacs-24.5-travis
- - EVM_EMACS=emacs-25.1-travis
-
-before_install:
- - export PATH="/home/travis/.evm/bin:$PATH"
- - export PATH="/home/travis/.cask/bin:$PATH"
- - git clone https://github.com/rejeep/evm.git /home/travis/.evm
- - evm config path /tmp
- - evm install ${EVM_EMACS} --use --skip
- - curl -fsSkL https://raw.github.com/cask/cask/master/go | python
-
-install:
- - cask
-
-script:
- - emacs --version
- - make test
diff --git a/packages/context-coloring/Cask b/packages/context-coloring/Cask
deleted file mode 100644
index 55ff4c5..0000000
--- a/packages/context-coloring/Cask
+++ /dev/null
@@ -1,7 +0,0 @@
-(source melpa)
-
-(package-file "context-coloring.el")
-
-(development
- (depends-on "js2-mode")
- (depends-on "undercover"))
diff --git a/packages/context-coloring/LICENSE
b/packages/context-coloring/LICENSE
deleted file mode 100644
index 94a9ed0..0000000
--- a/packages/context-coloring/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 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.
-
- 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 <http://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
-<http://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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/context-coloring/Makefile
b/packages/context-coloring/Makefile
deleted file mode 100644
index 9763be1..0000000
--- a/packages/context-coloring/Makefile
+++ /dev/null
@@ -1,50 +0,0 @@
-EMACS ?= emacs
-CASK ?= EMACS=${EMACS} cask
-DEPENDENCIES = .cask/
-SOURCE_FILES = \
- context-coloring.el \
- context-coloring-javascript.el \
- context-coloring-emacs-lisp.el
-
-all: uncompile compile test
-
-bench: ${DEPENDENCIES}
- ${CASK} exec ${EMACS} -Q \
- -L . \
- -l context-coloring \
- -l context-coloring-benchmark \
- -f context-coloring-benchmark-run
-
-compile: ${DEPENDENCIES}
- ${CASK} exec ${EMACS} -Q -batch \
- -L . \
- -f batch-byte-compile ${SOURCE_FILES}
-
-uncompile:
- rm -f *.elc
-
-clean: uncompile
- rm -rf ${DEPENDENCIES}
-
-${DEPENDENCIES}:
- ${CASK}
-
-test: ${DEPENDENCIES}
- ${CASK} exec ${EMACS} -Q -batch \
- -L . \
- -l ert \
- -l context-coloring-coverage \
- -f context-coloring-coverage-ci-init \
- -l context-coloring-test \
- -f ert-run-tests-batch-and-exit
-
-cover: ${DEPENDENCIES}
- ${CASK} exec ${EMACS} -Q -batch \
- -L . \
- -l ert \
- -l context-coloring-coverage \
- -f context-coloring-coverage-local-init \
- -l context-coloring-test \
- -f ert-run-tests-batch-and-exit
-
-.PHONY: all bench compile uncompile clean test cover
diff --git a/packages/context-coloring/README.md
b/packages/context-coloring/README.md
deleted file mode 100644
index bfbb4fb..0000000
--- a/packages/context-coloring/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Context Coloring [![Build
Status](https://travis-ci.org/jacksonrayhamilton/context-coloring.png?branch=master)](https://travis-ci.org/jacksonrayhamilton/context-coloring)
[![Coverage
Status](https://coveralls.io/repos/jacksonrayhamilton/context-coloring/badge.svg?branch=master)](https://coveralls.io/r/jacksonrayhamilton/context-coloring?branch=master)
-
-<p align="center">
- <img alt="Screenshot of JavaScript code highlighted by context."
src="screenshot.png" title="Screenshot">
-</p>
-
-Highlights code by scope. Top-level scopes are one color, second-level scopes
-are another color, and so on. Variables retain the color of the scope in which
-they are defined. A variable defined in an outer scope referenced by an inner
-scope is colored the same as the outer scope.
-
-By default, comments and strings are still highlighted syntactically.
-
-## Features
-
-- Light and dark customizable color schemes.
-- JavaScript support:
- - Script, function and block scopes (and even `catch` block scopes).
- - Node.js "file-level" scope detection.
-- Emacs Lisp support:
- - `defun`, `lambda`, `let`, `let*`, `cond`, `condition-case`, `defadvice`,
- `dolist`, `quote`, `backquote` and backquote splicing.
- - Works in `eval-expression` too.
-
-## Installation
-
-Requires Emacs 24.3+. JavaScript language support requires
-[js2-mode](https://github.com/mooz/js2-mode) (or, if you use
-[Tern](http://ternjs.net/), you may be interested in
-[tern-context-coloring](https://github.com/jacksonrayhamilton/tern-context-coloring)).
-
-To install, run the command `M-x package-install RET context-coloring RET`, and
-then add the following to your init file:
-
-```lisp
-;; JavaScript:
-(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
-(add-hook 'js2-mode-hook #'context-coloring-mode)
-
-;; Emacs Lisp:
-(add-hook 'emacs-lisp-mode-hook #'context-coloring-mode)
-
-;; eval-expression:
-(add-hook 'eval-expression-minibuffer-setup-hook #'context-coloring-mode) ;
24.4+
-(add-hook 'minibuffer-setup-hook #'context-coloring-mode) ;
24.3
-```
-
-## Color Schemes
-
-The [Zenburn](https://github.com/bbatsov/zenburn-emacs) theme, featured in the
-screenshot above, now supports context coloring.
-
-You can define your own colors by customizing faces like
-`context-coloring-level-N-face`, where N is a number starting from 0.
-
-[See here](https://gist.github.com/jacksonrayhamilton/6b89ca3b85182c490816) for
-some color schemes for popular custom themes.
-
-## Options
-
-- `context-coloring-syntactic-comments` (default: `t`): If non-nil, also color
- comments using `font-lock`.
-- `context-coloring-syntactic-strings` (default: `t`): If non-nil, also color
- strings using `font-lock`.
-- `context-coloring-javascript-block-scopes` (default: `nil`): If non-nil, also
- color block scopes in the scope hierarchy in JavaScript.
-- `context-coloring-javascript-detect-top-level-scope` (default: `t`): If
- non-nil, detect when to use file-level scope.
diff --git a/packages/context-coloring/context-coloring-benchmark.el
b/packages/context-coloring/context-coloring-benchmark.el
deleted file mode 100644
index dafc959..0000000
--- a/packages/context-coloring/context-coloring-benchmark.el
+++ /dev/null
@@ -1,165 +0,0 @@
-;;; context-coloring-benchmark.el --- Benchmarks for context coloring -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; This file is 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:
-
-;; Benchmarks for context coloring.
-
-;; Use with `make bench'.
-
-;;; Code:
-
-(require 'context-coloring)
-(require 'context-coloring-javascript)
-(require 'context-coloring-emacs-lisp)
-(require 'elp)
-
-
-(defconst context-coloring-benchmark-path
- (file-name-directory (or load-file-name buffer-file-name))
- "This file's directory.")
-
-(defun context-coloring-benchmark-resolve-path (path)
- "Resolve PATH from this file's directory."
- (expand-file-name path context-coloring-benchmark-path))
-
-(defun context-coloring-benchmark-log-results (result-file fixture statistics)
- "Log results to RESULT-FILE for FIXTURE with STATISTICS."
- (let ((results (prog1
- (progn
- (elp-results)
- (buffer-substring-no-properties (point-min)
(point-max)))
- (kill-buffer))))
- (make-directory (context-coloring-benchmark-resolve-path "./benchmark") t)
- (append-to-file
- (with-temp-buffer
- (goto-char (point-min))
- (insert (format "For fixture \"%s\":\n" fixture))
- (insert "\n")
- (insert "General statistics:\n")
- (insert (format "File size: %s bytes\n" (plist-get statistics
:file-size)))
- (insert (format "Lines: %s\n" (plist-get statistics :lines)))
- (insert (format "Words: %s\n" (plist-get statistics :words)))
- (insert (format "Colorization times: %s\n"
- (context-coloring-join
- (mapcar (lambda (number)
- (format "%.4f" number))
- (plist-get statistics :colorization-times)) ",
")))
- (insert (format "Average colorization time: %.4f\n"
- (plist-get statistics :average-colorization-time)))
- (insert "\n")
- (insert "Function statistics:\n")
- (insert "(Function Name / Call Count / Elapsed Time / Average Time):\n")
- (insert results)
- (insert "\n")
- (buffer-substring-no-properties (point-min) (point-max)))
- nil result-file)))
-
-(defun context-coloring-benchmark (title fixtures)
- "Execute a benchmark titled TITLE against FIXTURES."
- (let ((result-file (context-coloring-benchmark-resolve-path
- (format "./benchmark/results-%s-%s.log"
- title (format-time-string "%s")))))
- (mapc
- (lambda (path)
- (let ((fixture (context-coloring-benchmark-resolve-path path))
- colorization-start-time
- (colorization-times '())
- advice)
- (setq
- advice
- (let ((count 0))
- (lambda (original-function)
- (funcall original-function)
- (setq count (+ count 1))
- ;; First 5 runs are for gathering real coloring times,
- ;; unaffected by elp instrumentation.
- (when (<= count 5)
- (push (- (float-time) colorization-start-time)
colorization-times))
- (cond
- ((= count 10)
- (advice-remove #'context-coloring-colorize advice)
- (context-coloring-benchmark-log-results
- result-file
- fixture
- (list
- :file-size (nth 7 (file-attributes fixture))
- :lines (count-lines (point-min) (point-max))
- :words (count-words (point-min) (point-max))
- :colorization-times colorization-times
- :average-colorization-time (/ (apply #'+ colorization-times)
5)))
- (elp-restore-all)
- (kill-buffer))
- ;; The last 5 runs are for gathering function call and
- ;; duration statistics.
- ((= count 5)
- (elp-instrument-package "context-coloring-")
- (context-coloring-colorize))
- (t
- (setq colorization-start-time (float-time))
- (context-coloring-colorize))))))
- (advice-add #'context-coloring-colorize :around advice)
- (setq colorization-start-time (float-time))
- (find-file fixture)))
- fixtures)))
-
-(defconst context-coloring-benchmark-javascript-fixtures
- '("./fixtures/benchmark/jquery-2.1.1.js"
- "./fixtures/benchmark/lodash-2.4.1.js"
- "./fixtures/benchmark/async-0.9.0.js"
- "./fixtures/benchmark/mkdirp-0.5.0.js")
- "Arbitrary JavaScript files for performance scrutiny.")
-
-(defun context-coloring-benchmark-js2-mode-run ()
- "Benchmark `js2-mode'."
- (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
- (add-hook 'js2-mode-hook #'context-coloring-mode)
- (let ((js2-mode-show-parse-errors nil)
- (js2-mode-show-strict-warnings nil))
- (context-coloring-benchmark
- "js2-mode"
- context-coloring-benchmark-javascript-fixtures))
- (setq auto-mode-alist (delete '("\\.js\\'" . js2-mode)
- auto-mode-alist))
- (remove-hook 'js2-mode-hook #'context-coloring-mode))
-
-(defconst context-coloring-benchmark-emacs-lisp-fixtures
- '("./fixtures/benchmark/lisp.el"
- "./fixtures/benchmark/faces.el"
- "./fixtures/benchmark/subr.el"
- "./fixtures/benchmark/simple.el")
- "Arbitrary Emacs Lisp files for performance scrutiny.")
-
-(defun context-coloring-benchmark-emacs-lisp-mode-run ()
- "Benchmark `emacs-lisp-mode', then call CALLBACK."
- (add-hook 'emacs-lisp-mode-hook #'context-coloring-mode)
- (context-coloring-benchmark
- "emacs-lisp-mode"
- context-coloring-benchmark-emacs-lisp-fixtures)
- (remove-hook 'emacs-lisp-mode-hook #'context-coloring-mode))
-
-(defun context-coloring-benchmark-run ()
- "Benchmark all modes, then exit."
- (context-coloring-benchmark-js2-mode-run)
- (context-coloring-benchmark-emacs-lisp-mode-run)
- (kill-emacs))
-
-(provide 'context-coloring-benchmark)
-
-;;; context-coloring-benchmark.el ends here
diff --git a/packages/context-coloring/context-coloring-coverage.el
b/packages/context-coloring/context-coloring-coverage.el
deleted file mode 100644
index e74024d..0000000
--- a/packages/context-coloring/context-coloring-coverage.el
+++ /dev/null
@@ -1,155 +0,0 @@
-;;; context-coloring-coverage.el --- Test coverage for context coloring -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; This file is 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:
-
-;; Test coverage support for context coloring.
-
-;; Use with `make cover'.
-
-;;; Code:
-
-(require 'json)
-(require 'undercover nil 'noerror) ;Don't signal an error during compilation.
-
-
-(defconst context-coloring-coverage-directory
- (file-name-directory (or load-file-name buffer-file-name))
- "This file's directory.")
-
-(defun context-coloring-coverage-resolve-path (path)
- "Resolve PATH from this file's directory."
- (expand-file-name path context-coloring-coverage-directory))
-
-(defconst context-coloring-coverage-output-file-prefix
- (format-time-string "%s"))
-
-(defconst context-coloring-coverage-output-directory
- (context-coloring-coverage-resolve-path "./coverage/"))
-
-(defconst context-coloring-coverage-output-file
- (concat context-coloring-coverage-output-directory
- context-coloring-coverage-output-file-prefix ".json"))
-
-(defconst context-coloring-coverage-report-file
- (concat context-coloring-coverage-output-directory
- context-coloring-coverage-output-file-prefix ".txt"))
-
-(defun context-coloring-coverage-join (strings delimiter)
- "Join a list of STRINGS with the string DELIMITER."
- (mapconcat #'identity strings delimiter))
-
-(defun context-coloring-coverage-percentage (dividend divisor)
- "Get the percentage of DIVIDEND / DIVISOR with precision 2."
- (let ((percentage (/ (float (round (* (/ (float dividend) divisor) 10000)))
100)))
- (number-to-string
- (cond
- ((= (mod percentage 1) 0)
- ;; Get an integer because we don't like dangling zeros.
- (round percentage))
- (t
- percentage)))))
-
-(defun context-coloring-coverage-format-source-file (source-file)
- "Generate a report for SOURCE-FILE's line coverage."
- (let* ((source-lines (split-string (cdr (assq 'source source-file)) "\n"))
- (coverage (cdr (assq 'coverage source-file)))
- (results (list "Hits | Source"
- (context-coloring-coverage-join (make-vector 80 "-")
"")))
- (lines-hit 0)
- (lines-hittable 0)
- hits
- source-line)
- (while coverage
- (setq hits (car coverage))
- (setq coverage (cdr coverage))
- (setq source-line (car source-lines))
- (setq source-lines (cdr source-lines))
- (when (not (null hits))
- (setq lines-hittable (+ lines-hittable 1))
- (when (> hits 0)
- (setq lines-hit (+ lines-hit 1))))
- (setq results
- (append results
- (list (format
- "%-5s %s %s"
- (if hits hits "N/A")
- (if (and hits (= hits 0)) "~" "|")
- source-line)))))
- (setq results
- (append results
- (list
- ""
- (format
- "Lines: %s / %s"
- lines-hit
- lines-hittable)
- (format
- "Coverage: %s%%"
- (context-coloring-coverage-percentage lines-hit
lines-hittable)))))
- (context-coloring-coverage-join results "\n")))
-
-(defun context-coloring-coverage-format (coverage-data)
- "Generate reports for all files in COVERAGE-DATA."
- (context-coloring-coverage-join
- (mapcar
- #'context-coloring-coverage-format-source-file
- (cdr (assq 'source_files coverage-data)))
- "\n\n"))
-
-(defun context-coloring-coverage-local-init ()
- "Initialize test coverage for local viewing."
- (make-directory context-coloring-coverage-output-directory t)
- (setq undercover-force-coverage t)
- (setenv "COVERALLS_REPO_TOKEN" "noop")
- (undercover "*.el"
- (:report-file context-coloring-coverage-output-file)
- (:send-report nil))
- (add-hook
- 'kill-emacs-hook
- (lambda ()
- (let (original-json-array-type
- coverage-data
- report)
- (with-temp-buffer
- (insert-file-contents-literally context-coloring-coverage-output-file)
- (setq original-json-array-type json-array-type)
- (setq json-array-type 'list)
- (setq coverage-data
- (json-read-from-string
- (buffer-substring-no-properties (point-min) (point-max))))
- (setq json-array-type original-json-array-type)
- (setq report
- (context-coloring-coverage-format coverage-data))
- (setq report (concat report "\n")))
- (princ report)
- (with-temp-buffer
- (insert report)
- (write-file context-coloring-coverage-report-file))))
- t)
- (require 'context-coloring))
-
-(defun context-coloring-coverage-ci-init ()
- "Initialize test coverage for continuous integration."
- (undercover "*.el")
- (require 'context-coloring))
-
-(provide 'context-coloring-coverage)
-
-;;; context-coloring-coverage.el ends here
diff --git a/packages/context-coloring/context-coloring-emacs-lisp.el
b/packages/context-coloring/context-coloring-emacs-lisp.el
deleted file mode 100644
index 05caa5a..0000000
--- a/packages/context-coloring/context-coloring-emacs-lisp.el
+++ /dev/null
@@ -1,773 +0,0 @@
-;;; context-coloring-emacs-lisp.el --- Emacs Lisp support -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; This file is 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:
-
-;; Add Emacs Lisp context coloring support.
-
-;;; Code:
-
-(require 'context-coloring)
-
-
-;;; Emacs Lisp colorization
-
-(defconst context-coloring-WORD-CODE 2)
-(defconst context-coloring-SYMBOL-CODE 3)
-(defconst context-coloring-OPEN-PARENTHESIS-CODE 4)
-(defconst context-coloring-CLOSE-PARENTHESIS-CODE 5)
-(defconst context-coloring-EXPRESSION-PREFIX-CODE 6)
-(defconst context-coloring-STRING-QUOTE-CODE 7)
-(defconst context-coloring-ESCAPE-CODE 9)
-(defconst context-coloring-COMMENT-START-CODE 11)
-(defconst context-coloring-COMMENT-END-CODE 12)
-
-(defconst context-coloring-OCTOTHORPE-CHAR (string-to-char "#"))
-(defconst context-coloring-APOSTROPHE-CHAR (string-to-char "'"))
-(defconst context-coloring-OPEN-PARENTHESIS-CHAR (string-to-char "("))
-(defconst context-coloring-COMMA-CHAR (string-to-char ","))
-(defconst context-coloring-AT-CHAR (string-to-char "@"))
-(defconst context-coloring-BACKTICK-CHAR (string-to-char "`"))
-
-(defsubst context-coloring-get-syntax-code ()
- "Get the syntax code at point."
- (syntax-class
- ;; Faster version of `syntax-after':
- (aref (syntax-table) (char-after (point)))))
-
-(defsubst context-coloring-forward-sws ()
- "Move forward through whitespace and comments."
- (while (forward-comment 1)))
-
-(defsubst context-coloring-elisp-colorize-comments-and-strings
- (&optional min max)
- "Color comments and strings from MIN to MAX."
- (context-coloring-colorize-comments-and-strings min max t))
-
-(defsubst context-coloring-elisp-forward-sws ()
- "Move through whitespace and comments, coloring comments."
- (let ((start (point)))
- (context-coloring-forward-sws)
- (context-coloring-elisp-colorize-comments-and-strings start (point))))
-
-(defsubst context-coloring-elisp-forward-sexp ()
- "Skip/ignore missing sexps, coloring comments and strings."
- (let ((start (point)))
- (when (= (context-coloring-get-syntax-code)
- context-coloring-EXPRESSION-PREFIX-CODE)
- ;; `forward-sexp' does not skip an unfinished expression (e.g. when the
- ;; name of a symbol or the parentheses of a list do not follow a single
- ;; quote).
- (forward-char))
- (condition-case nil
- (forward-sexp)
- (scan-error (context-coloring-forward-sws)))
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start (point))))
-
-(defsubst context-coloring-exact-regexp (word)
- "Create a regexp matching exactly WORD."
- (concat "\\`" (regexp-quote word) "\\'"))
-
-(defsubst context-coloring-exact-or-regexp (words)
- "Create a regexp matching any exact word in WORDS."
- (context-coloring-join
- (mapcar #'context-coloring-exact-regexp words) "\\|"))
-
-(defconst context-coloring-elisp-ignored-word-regexp
- (context-coloring-join (list "\\`[-+]?[0-9]"
- "\\`[&:].+"
- (context-coloring-exact-or-regexp
- '("t" "nil" "." "?")))
- "\\|")
- "Match symbols that can't be bound as variables.")
-
-(defsubst context-coloring-elisp-identifier-p (syntax-code)
- "Check if SYNTAX-CODE is an elisp identifier constituent."
- (or (= syntax-code context-coloring-WORD-CODE)
- (= syntax-code context-coloring-SYMBOL-CODE)))
-
-(defconst context-coloring-elisp-sexps-per-pause 350
- "Pause after this many iterations to check for user input.
-If user input is pending, stop the parse. This makes for a
-smoother user experience for large files.
-
-This number should trigger pausing at about 60 frames per
-second.")
-
-(defvar context-coloring-elisp-sexp-count 0
- "Current number of sexps leading up to the next pause.")
-
-(defsubst context-coloring-elisp-increment-sexp-count ()
- "Maybe check if the user interrupted the current parse."
- (setq context-coloring-elisp-sexp-count
- (1+ context-coloring-elisp-sexp-count))
- (when (and (zerop (% context-coloring-elisp-sexp-count
- context-coloring-elisp-sexps-per-pause))
- context-coloring-interruptable-p
- (input-pending-p))
- (throw 'interrupted t)))
-
-(defvar context-coloring-elisp-scope-stack '()
- "List of scopes in the current parse.")
-
-(defsubst context-coloring-elisp-make-scope (level)
- "Make a scope object for LEVEL."
- (list
- :level level
- :variables '()))
-
-(defsubst context-coloring-elisp-scope-get-level (scope)
- "Get the level of SCOPE object."
- (plist-get scope :level))
-
-(defsubst context-coloring-elisp-scope-add-variable (scope variable)
- "Add to SCOPE a VARIABLE."
- (plist-put scope :variables (cons variable (plist-get scope :variables))))
-
-(defsubst context-coloring-elisp-scope-has-variable (scope variable)
- "Check if SCOPE has VARIABLE."
- (member variable (plist-get scope :variables)))
-
-(defsubst context-coloring-elisp-get-variable-level (variable)
- "Return the level of VARIABLE, or 0 if it isn't found."
- (let* ((scope-stack context-coloring-elisp-scope-stack)
- scope
- level)
- (while (and scope-stack (not level))
- (setq scope (car scope-stack))
- (cond
- ((context-coloring-elisp-scope-has-variable scope variable)
- (setq level (context-coloring-elisp-scope-get-level scope)))
- (t
- (setq scope-stack (cdr scope-stack)))))
- ;; Assume a global variable.
- (or level 0)))
-
-(defsubst context-coloring-elisp-get-current-scope-level ()
- "Get the nesting level of the current scope."
- (cond
- ((car context-coloring-elisp-scope-stack)
- (context-coloring-elisp-scope-get-level (car
context-coloring-elisp-scope-stack)))
- (t
- 0)))
-
-(defsubst context-coloring-elisp-push-scope ()
- "Add a new scope to the bottom of the scope chain."
- (push (context-coloring-elisp-make-scope
- (1+ (context-coloring-elisp-get-current-scope-level)))
- context-coloring-elisp-scope-stack))
-
-(defsubst context-coloring-elisp-pop-scope ()
- "Remove the scope on the bottom of the scope chain."
- (pop context-coloring-elisp-scope-stack))
-
-(defsubst context-coloring-elisp-add-variable (variable)
- "Add VARIABLE to the current scope."
- (context-coloring-elisp-scope-add-variable
- (car context-coloring-elisp-scope-stack)
- variable))
-
-(defsubst context-coloring-elisp-parse-bindable (callback)
- "Parse the symbol at point.
-If the symbol can be bound, invoke CALLBACK with it."
- (let* ((arg-string (buffer-substring-no-properties
- (point)
- (progn (context-coloring-elisp-forward-sexp)
- (point)))))
- (when (not (string-match-p
- context-coloring-elisp-ignored-word-regexp
- arg-string))
- (funcall callback arg-string))))
-
-(defun context-coloring-elisp-parse-let-varlist (type)
- "Parse the list of variable initializers at point.
-If TYPE is `let', all the variables are bound after all their
-initializers are parsed; if TYPE is `let*', each variable is
-bound immediately after its own initializer is parsed."
- (let ((varlist '())
- syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (var)
- (push var varlist)))
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (/= syntax-code context-coloring-CLOSE-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-sexp)))
- (context-coloring-elisp-forward-sws)
- ;; Skip past the closing parenthesis.
- (forward-char))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (var)
- (push var varlist))))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (when (eq type 'let*)
- (context-coloring-elisp-add-variable (pop varlist)))
- (context-coloring-elisp-forward-sws))
- (when (eq type 'let)
- (while varlist
- (context-coloring-elisp-add-variable (pop varlist))))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-parse-arglist ()
- "Parse the list of function arguments at point."
- (let (syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (arg)
- (context-coloring-elisp-add-variable arg))))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-skip-callee-name ()
- "Skip past the opening parenthesis and name of a function."
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- ;; Skip past the function name.
- (forward-sexp)
- (context-coloring-elisp-forward-sws))
-
-(defun context-coloring-elisp-colorize-scope (callback)
- "Color the whole scope at point with its one color.
-Handle a header in CALLBACK."
- (let ((start (point))
- (end (progn (forward-sexp)
- (point))))
- (context-coloring-elisp-push-scope)
- ;; Splash the whole thing in one color.
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- ;; Even if the parse is interrupted, this region should still be colored
- ;; syntactically.
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start
- end)
- (goto-char start)
- (context-coloring-elisp-skip-callee-name)
- (funcall callback)
- (context-coloring-elisp-colorize-region (point) (1- end))
- ;; Exit.
- (forward-char)
- (context-coloring-elisp-pop-scope)))
-
-(defun context-coloring-elisp-parse-header (callback)
- "Parse a function header at point with CALLBACK."
- (when (= (context-coloring-get-syntax-code)
context-coloring-OPEN-PARENTHESIS-CODE)
- (funcall callback)))
-
-(defun context-coloring-elisp-colorize-defun-like (callback)
- "Color the defun-like function at point.
-Parse the header with CALLBACK."
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (when (context-coloring-elisp-identifier-p
(context-coloring-get-syntax-code))
- ;; Color the defun's name with the top-level color.
- (context-coloring-colorize-region
- (point)
- (progn (forward-sexp)
- (point))
- 0)
- (context-coloring-elisp-forward-sws)
- (context-coloring-elisp-parse-header callback)))))
-
-(defun context-coloring-elisp-colorize-defun ()
- "Color the `defun' at point."
- (context-coloring-elisp-colorize-defun-like
- 'context-coloring-elisp-parse-arglist))
-
-(defun context-coloring-elisp-colorize-defadvice ()
- "Color the `defadvice' at point."
- (context-coloring-elisp-colorize-defun-like
- (lambda ()
- (let (syntax-code)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-parse-arglist))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))))))
-
-(defun context-coloring-elisp-colorize-lambda-like (callback)
- "Color the lambda-like function at point.
-Parsing the header with CALLBACK."
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (context-coloring-elisp-parse-header callback))))
-
-(defun context-coloring-elisp-colorize-lambda ()
- "Color the `lambda' at point."
- (context-coloring-elisp-colorize-lambda-like
- 'context-coloring-elisp-parse-arglist))
-
-(defun context-coloring-elisp-colorize-let ()
- "Color the `let' at point."
- (context-coloring-elisp-colorize-lambda-like
- (lambda ()
- (context-coloring-elisp-parse-let-varlist 'let))))
-
-(defun context-coloring-elisp-colorize-let* ()
- "Color the `let*' at point."
- (context-coloring-elisp-colorize-lambda-like
- (lambda ()
- (context-coloring-elisp-parse-let-varlist 'let*))))
-
-(defun context-coloring-elisp-colorize-macroexp-let2 ()
- "Color the `macroexp-let2' at point."
- (let (syntax-code
- variable)
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (and
- (progn
- (setq syntax-code (context-coloring-get-syntax-code))
- (context-coloring-elisp-identifier-p syntax-code))
- (progn
- (context-coloring-elisp-colorize-sexp)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (context-coloring-elisp-identifier-p syntax-code))
- (progn
- (context-coloring-elisp-parse-bindable
- (lambda (parsed-variable)
- (setq variable parsed-variable)))
- (context-coloring-elisp-forward-sws)
- (when variable
- (context-coloring-elisp-add-variable variable))))))))
-
-(defun context-coloring-elisp-colorize-cond ()
- "Color the `cond' at point."
- (let (syntax-code)
- (context-coloring-elisp-skip-callee-name)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- ;; Colorize inside the parens.
- (let ((start (point)))
- (forward-sexp)
- (context-coloring-elisp-colorize-region
- (1+ start) (1- (point)))
- ;; Exit.
- (forward-char)))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))
- ;; Exit.
- (forward-char)))
-
-(defun context-coloring-elisp-colorize-condition-case ()
- "Color the `condition-case' at point."
- (let (syntax-code
- variable
- case-pos
- case-end)
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (setq syntax-code (context-coloring-get-syntax-code))
- ;; Gracefully ignore missing variables.
- (when (context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-parse-bindable
- (lambda (parsed-variable)
- (setq variable parsed-variable)))
- (context-coloring-elisp-forward-sws))
- (context-coloring-elisp-colorize-sexp)
- (context-coloring-elisp-forward-sws)
- ;; Parse the handlers with the error variable in scope.
- (when variable
- (context-coloring-elisp-add-variable variable))
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (setq case-pos (point))
- (context-coloring-elisp-forward-sexp)
- (setq case-end (point))
- (goto-char case-pos)
- ;; Enter.
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (/= syntax-code context-coloring-CLOSE-PARENTHESIS-CODE)
- ;; Skip the condition name(s).
- (context-coloring-elisp-forward-sexp)
- ;; Color the remaining portion of the handler.
- (context-coloring-elisp-colorize-region
- (point)
- (1- case-end)))
- ;; Exit.
- (forward-char))
- (t
- ;; Ignore artifacts.
- (context-coloring-elisp-forward-sexp)))
- (context-coloring-elisp-forward-sws))))))
-
-(defun context-coloring-elisp-colorize-dolist ()
- "Color the `dolist' at point."
- (let (syntax-code
- (index 0))
- (context-coloring-elisp-colorize-scope
- (lambda ()
- (setq syntax-code (context-coloring-get-syntax-code))
- (when (= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (forward-char)
- (context-coloring-elisp-forward-sws)
- (while (/= (setq syntax-code (context-coloring-get-syntax-code))
- context-coloring-CLOSE-PARENTHESIS-CODE)
- (cond
- ((and
- (or (= index 0) (= index 2))
- (context-coloring-elisp-identifier-p syntax-code))
- ;; Add the first or third name to the scope.
- (context-coloring-elisp-parse-bindable
- (lambda (variable)
- (context-coloring-elisp-add-variable variable))))
- (t
- ;; Color artifacts.
- (context-coloring-elisp-colorize-sexp)))
- (context-coloring-elisp-forward-sws)
- (setq index (1+ index)))
- ;; Exit.
- (forward-char))))))
-
-(defun context-coloring-elisp-colorize-quote ()
- "Color the `quote' at point."
- (let* ((start (point))
- (end (progn (forward-sexp)
- (point))))
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- (context-coloring-elisp-colorize-comments-and-strings-in-region start
end)))
-
-(defvar context-coloring-elisp-callee-dispatch-hash-table
- (let ((table (make-hash-table :test 'equal)))
- (dolist (callee '("defun" "defun*" "defsubst" "defmacro" "cl-defun"
"cl-defsubst" "cl-defmacro"))
- (puthash callee #'context-coloring-elisp-colorize-defun table))
- (dolist (callee '("condition-case" "condition-case-unless-debug"))
- (puthash callee #'context-coloring-elisp-colorize-condition-case table))
- (dolist (callee '("dolist" "dotimes"))
- (puthash callee #'context-coloring-elisp-colorize-dolist table))
- (dolist (callee '("let" "gv-letplace"))
- (puthash callee #'context-coloring-elisp-colorize-let table))
- (puthash "let*" #'context-coloring-elisp-colorize-let* table)
- (puthash "macroexp-let2" #'context-coloring-elisp-colorize-macroexp-let2
table)
- (puthash "lambda" #'context-coloring-elisp-colorize-lambda table)
- (puthash "cond" #'context-coloring-elisp-colorize-cond table)
- (puthash "defadvice" #'context-coloring-elisp-colorize-defadvice table)
- (puthash "quote" #'context-coloring-elisp-colorize-quote table)
- (puthash "backquote" #'context-coloring-elisp-colorize-backquote table)
- table)
- "Map function names to their coloring functions.")
-
-(defun context-coloring-elisp-colorize-parenthesized-sexp ()
- "Color the sexp enclosed by parenthesis at point."
- (context-coloring-elisp-increment-sexp-count)
- (let* ((start (point))
- (end (progn (forward-sexp)
- (point)))
- (syntax-code (progn (goto-char start)
- (forward-char)
- ;; Coloring is unnecessary here, it'll happen
- ;; presently.
- (context-coloring-forward-sws)
- (context-coloring-get-syntax-code)))
- dispatch-function)
- ;; Figure out if the sexp is a special form.
- (cond
- ((and (context-coloring-elisp-identifier-p syntax-code)
- (setq dispatch-function (gethash
- (buffer-substring-no-properties
- (point)
- (progn (forward-sexp)
- (point)))
-
context-coloring-elisp-callee-dispatch-hash-table)))
- (goto-char start)
- (funcall dispatch-function))
- ;; Not a special form; just colorize the remaining region.
- (t
- (context-coloring-colorize-region
- start
- end
- (context-coloring-elisp-get-current-scope-level))
- (context-coloring-elisp-colorize-region (point) (1- end))
- (forward-char)))))
-
-(defun context-coloring-elisp-colorize-symbol ()
- "Color the symbol at point."
- (context-coloring-elisp-increment-sexp-count)
- (let* ((symbol-pos (point))
- (symbol-end (progn (forward-sexp)
- (point)))
- (symbol-string (buffer-substring-no-properties
- symbol-pos
- symbol-end)))
- (cond
- ((string-match-p context-coloring-elisp-ignored-word-regexp
symbol-string))
- (t
- (context-coloring-colorize-region
- symbol-pos
- symbol-end
- (context-coloring-elisp-get-variable-level
- symbol-string))))))
-
-(defun context-coloring-elisp-colorize-backquote-form ()
- "Color the backquote form at point."
- (let ((start (point))
- (end (progn (forward-sexp)
- (point)))
- char)
- (goto-char start)
- (while (> end (progn (forward-char)
- (point)))
- (setq char (char-after))
- (when (= char context-coloring-COMMA-CHAR)
- (forward-char)
- (when (= (char-after) context-coloring-AT-CHAR)
- ;; If we don't do this "@" could be interpreted as a symbol.
- (forward-char))
- (context-coloring-elisp-forward-sws)
- (context-coloring-elisp-colorize-sexp)))
- ;; We could probably do this as part of the above loop but it'd be
- ;; repetitive.
- (context-coloring-elisp-colorize-comments-and-strings-in-region
- start end)))
-
-(defun context-coloring-elisp-colorize-backquote ()
- "Color the `backquote' at point."
- (context-coloring-elisp-skip-callee-name)
- (context-coloring-elisp-colorize-backquote-form)
- ;; Exit.
- (forward-char))
-
-(defun context-coloring-elisp-colorize-expression-prefix ()
- "Color the expression prefix and expression at point.
-It could be a quoted or backquoted expression."
- (context-coloring-elisp-increment-sexp-count)
- (cond
- ((/= (char-after) context-coloring-BACKTICK-CHAR)
- (context-coloring-elisp-forward-sexp))
- (t
- (context-coloring-elisp-colorize-backquote-form))))
-
-(defun context-coloring-elisp-colorize-comment ()
- "Color the comment at point."
- (context-coloring-elisp-increment-sexp-count)
- (context-coloring-elisp-forward-sws))
-
-(defun context-coloring-elisp-colorize-string ()
- "Color the string at point."
- (context-coloring-elisp-increment-sexp-count)
- (let ((start (point)))
- (forward-sexp)
- (context-coloring-elisp-colorize-comments-and-strings start (point))))
-
-;; Elisp has whitespace, words, symbols, open/close parenthesis, expression
-;; prefix, string quote, comment starters/enders and escape syntax classes
only.
-
-(defun context-coloring-elisp-colorize-sexp ()
- "Color the sexp at point."
- (let ((syntax-code (context-coloring-get-syntax-code)))
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-parenthesized-sexp))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-colorize-symbol))
- ((= syntax-code context-coloring-EXPRESSION-PREFIX-CODE)
- (context-coloring-elisp-colorize-expression-prefix))
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2)))))
-
-(defun context-coloring-elisp-colorize-comments-and-strings-in-region (start
end)
- "Color comments and strings between START and END."
- (let (syntax-code)
- (goto-char start)
- (while (> end (progn (skip-syntax-forward "^\"<\\" end)
- (point)))
- (setq syntax-code (context-coloring-get-syntax-code))
- (cond
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-COMMENT-START-CODE)
- (context-coloring-elisp-colorize-comment))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2))))))
-
-(defun context-coloring-elisp-colorize-region (start end)
- "Color everything between START and END."
- (let (syntax-code)
- (goto-char start)
- (while (> end (progn (skip-syntax-forward "^w_('\"<\\" end)
- (point)))
- (setq syntax-code (context-coloring-get-syntax-code))
- (cond
- ((= syntax-code context-coloring-OPEN-PARENTHESIS-CODE)
- (context-coloring-elisp-colorize-parenthesized-sexp))
- ((context-coloring-elisp-identifier-p syntax-code)
- (context-coloring-elisp-colorize-symbol))
- ((= syntax-code context-coloring-EXPRESSION-PREFIX-CODE)
- (context-coloring-elisp-colorize-expression-prefix))
- ((= syntax-code context-coloring-STRING-QUOTE-CODE)
- (context-coloring-elisp-colorize-string))
- ((= syntax-code context-coloring-COMMENT-START-CODE)
- (context-coloring-elisp-colorize-comment))
- ((= syntax-code context-coloring-ESCAPE-CODE)
- (forward-char 2))))))
-
-(defun context-coloring-elisp-colorize-region-initially (start end)
- "Begin coloring everything between START and END."
- (setq context-coloring-elisp-sexp-count 0)
- (setq context-coloring-elisp-scope-stack '())
- (let ((inhibit-point-motion-hooks t)
- (case-fold-search nil)
- ;; This is a recursive-descent parser, so give it a big stack.
- (max-lisp-eval-depth (max max-lisp-eval-depth 3000))
- (max-specpdl-size (max max-specpdl-size 3000)))
- (context-coloring-elisp-colorize-region start end)))
-
-(defun context-coloring-elisp-colorize-guard (callback)
- "Silently color in CALLBACK."
- (with-silent-modifications
- (save-excursion
- (condition-case nil
- (funcall callback)
- ;; Scan errors can happen virtually anywhere if parenthesis are
- ;; unbalanced. Just swallow them. (`progn' for test coverage.)
- (scan-error (progn))))))
-
-;;;###autoload
-(defun context-coloring-elisp-colorize ()
- "Color the current Emacs Lisp buffer."
- (interactive)
- (context-coloring-elisp-colorize-guard
- (lambda ()
- (cond
- ;; Just colorize the changed region.
- (context-coloring-changed-p
- (let* (;; Prevent `beginning-of-defun' from making poor assumptions.
- (open-paren-in-column-0-is-defun-start nil)
- ;; Seek the beginning and end of the previous and next
- ;; offscreen defuns, so just enough is colored.
- (start (progn (goto-char context-coloring-changed-start)
- (while (and (< (point-min) (point))
- (pos-visible-in-window-p))
- (end-of-line 0))
- (beginning-of-defun)
- (point)))
- (end (progn (goto-char context-coloring-changed-end)
- (while (and (> (point-max) (point))
- (pos-visible-in-window-p))
- (forward-line 1))
- (end-of-defun)
- (point))))
- (context-coloring-elisp-colorize-region-initially start end)
- ;; Fast coloring is nice, but if the code is not well-formed
- ;; (e.g. an unclosed string literal is parsed at any time) then
- ;; there could be leftover incorrectly-colored code offscreen. So
- ;; do a clean sweep as soon as appropriate.
- (context-coloring-schedule-coloring context-coloring-default-delay)))
- (t
- (context-coloring-elisp-colorize-region-initially (point-min)
(point-max)))))))
-
-;;;###autoload
-(puthash
- 'emacs-lisp
- (list :modes '(emacs-lisp-mode lisp-interaction-mode)
- :colorizer #'context-coloring-elisp-colorize
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
- context-coloring-dispatch-hash-table)
-
-
-;;; eval-expression colorization
-
-(defun context-coloring-eval-expression-match ()
- "Determine expression start in `eval-expression'."
- (string-match "\\`Eval: " (buffer-string)))
-
-;;;###autoload
-(defun context-coloring-eval-expression-colorize ()
- "Color the `eval-expression' minibuffer prompt as elisp."
- (interactive)
- (context-coloring-elisp-colorize-guard
- (lambda ()
- (context-coloring-elisp-colorize-region-initially
- (progn
- (context-coloring-eval-expression-match)
- (1+ (match-end 0)))
- (point-max)))))
-
-;; `eval-expression-minibuffer-setup-hook' is not available in Emacs 24.3, so
-;; the backwards-compatible recommendation is to use `minibuffer-setup-hook'
and
-;; rely on this predicate instead.
-;;;###autoload
-(defun context-coloring-eval-expression-predicate ()
- "Non-nil if the minibuffer is for `eval-expression'."
- ;; Kinda better than checking `this-command', because `this-command' changes.
- (context-coloring-eval-expression-match))
-
-;;;###autoload
-(puthash
- 'eval-expression
- (list :predicate #'context-coloring-eval-expression-predicate
- :colorizer #'context-coloring-eval-expression-colorize
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
- context-coloring-dispatch-hash-table)
-
-(provide 'context-coloring-emacs-lisp)
-
-;;; context-coloring-emacs-lisp.el ends here
diff --git a/packages/context-coloring/context-coloring-javascript.el
b/packages/context-coloring/context-coloring-javascript.el
deleted file mode 100644
index 29bafb8..0000000
--- a/packages/context-coloring/context-coloring-javascript.el
+++ /dev/null
@@ -1,239 +0,0 @@
-;;; context-coloring-javascript.el --- JavaScript support -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; This file is 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:
-
-;; Add JavaScript context coloring support with js2-mode.
-
-;;; Code:
-
-(require 'context-coloring)
-(require 'js2-mode)
-
-
-;;; JavaScript colorization
-
-(defvar-local context-coloring-js2-scope-level-hash-table nil
- "Associate `js2-scope' structures and with their scope
- levels.")
-
-(defcustom context-coloring-javascript-block-scopes nil
- "If non-nil, also color block scopes in the scope hierarchy in JavaScript.
-
-The block-scoped `let' and `const' are introduced in ES6. Enable
-this for ES6 code; disable it elsewhere."
- :type 'boolean
- :safe #'booleanp
- :group 'context-coloring)
-
-(defsubst context-coloring-js2-scope-level (scope initial)
- "Return the level of SCOPE, starting from INITIAL."
- (cond ((gethash scope context-coloring-js2-scope-level-hash-table))
- (t
- (let ((level initial)
- (current-scope scope)
- enclosing-scope)
- (while (and current-scope
- (js2-node-parent current-scope)
- (setq enclosing-scope
- (js2-node-get-enclosing-scope current-scope)))
- (when (or context-coloring-javascript-block-scopes
- (let ((type (js2-scope-type current-scope)))
- (or (= type js2-SCRIPT)
- (= type js2-FUNCTION)
- (= type js2-CATCH))))
- (setq level (+ level 1)))
- (setq current-scope enclosing-scope))
- (puthash scope level
context-coloring-js2-scope-level-hash-table)))))
-
-(defsubst context-coloring-js2-local-name-node-p (node)
- "Determine if NODE represents a local variable."
- (and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (or (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left parent)))
- (and (js2-prop-get-node-p parent)
- ;; For nested property lookup, the node on the left is a
- ;; `js2-prop-get-node', so this always works.
- (eq node (js2-prop-get-node-right parent))))))))
-
-(defvar-local context-coloring-point-min nil
- "Cached value of `point-min'.")
-
-(defvar-local context-coloring-point-max nil
- "Cached value of `point-max'.")
-
-(defsubst context-coloring-js2-bounded-point (point)
- "Make POINT safe to set text properties.
-POINT may be unsafe if a JS2 node extends beyond the end of the
-buffer (in the case of an unterminated multiline comment). The
-region could also be narrowed and the node thus obscured."
- (min (max point context-coloring-point-min) context-coloring-point-max))
-
-(defsubst context-coloring-js2-colorize-node (node level)
- "Color NODE with the color for LEVEL."
- (let* ((start (js2-node-abs-pos node))
- (end (+ start (js2-node-len node))))
- (context-coloring-colorize-region
- (context-coloring-js2-bounded-point start)
- (context-coloring-js2-bounded-point end)
- level)))
-
-(defun context-coloring-js2-colorize-ast ()
- "Color the buffer using the `js2-mode' abstract syntax tree."
- ;; Reset the hash table; the old one could be obsolete.
- (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test
#'eq))
- (setq context-coloring-point-min (point-min))
- (setq context-coloring-point-max (point-max))
- (with-silent-modifications
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (when (null end-p)
- (cond
- ((js2-scope-p node)
- (context-coloring-js2-colorize-node
- node
- (context-coloring-js2-scope-level node
context-coloring-initial-level)))
- ((context-coloring-js2-local-name-node-p node)
- (let* ((enclosing-scope (js2-node-get-enclosing-scope node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope
- (js2-name-node-name node))))
- ;; The tree seems to be walked lexically, so an entire scope will
- ;; be colored, including its name nodes, before they are reached.
- ;; Coloring the nodes defined in that scope would be redundant, so
- ;; don't do it.
- (when (not (eq defining-scope enclosing-scope))
- (context-coloring-js2-colorize-node
- node
- ;; Use `0' as an initial level so global variables are always
at
- ;; the highest level (even if `context-coloring-initial-level'
- ;; specifies an initial level for the rest of the code).
- (context-coloring-js2-scope-level defining-scope 0))))))
- ;; The `t' indicates to search children.
- t)))
- (context-coloring-colorize-comments-and-strings)))
-
-(defconst context-coloring-node-comment-regexp
- (concat
- ;; Ensure the "//" or "/*" comment starts with the directive.
- "\\(//[[:space:]]*\\|/\\*[[:space:]]*\\)"
- ;; Support multiple directive formats.
- "\\("
- ;; JSLint and JSHint support a JSON-like format.
- "\\(jslint\\|jshint\\)[[:space:]].*?node:[[:space:]]*true"
- "\\|"
- ;; ESLint just specifies the option name.
- "eslint-env[[:space:]].*?node"
- "\\)")
- "Match a comment body hinting at a Node.js program.")
-
-(defun context-coloring-js2-top-level-local-p ()
- "Guess whether top-level variables are local.
-For instance, the current file could be a Node.js program."
- (or
- ;; A shebang is a pretty obvious giveaway.
- (string-equal
- "node"
- (save-excursion
- (goto-char (point-min))
- (when (looking-at auto-mode-interpreter-regexp)
- (match-string 2))))
- ;; Otherwise, perform static analysis.
- (progn
- (setq context-coloring-js2-scope-level-hash-table (make-hash-table :test
#'eq))
- (catch 'node-program-p
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (when (null end-p)
- (when
- (cond
- ;; Infer based on inline linter configuration.
- ((js2-comment-node-p node)
- (string-match-p
- context-coloring-node-comment-regexp
- (js2-node-string node)))
- ;; Infer based on the prescence of certain variables.
- ((and (js2-name-node-p node)
- (let ((parent (js2-node-parent node)))
- (not (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left
parent))))))
- (let ((name (js2-name-node-name node))
- (parent (js2-node-parent node)))
- (and
- (cond
- ;; Check whether this is "exports.something" or
- ;; "module.exports".
- ((js2-prop-get-node-p parent)
- (and
- (eq node (js2-prop-get-node-left parent))
- (or (string-equal name "exports")
- (let* ((property (js2-prop-get-node-right parent))
- (property-name (js2-name-node-name
property)))
- (and (string-equal name "module")
- (string-equal property-name "exports"))))))
- ;; Check whether it's a "require('module')" call.
- ((js2-call-node-p parent)
- (or (string-equal name "require"))))
- (let* ((enclosing-scope (js2-node-get-enclosing-scope
node))
- (defining-scope (js2-get-defining-scope
- enclosing-scope name)))
- ;; The variable also must be global.
- (null defining-scope))))))
- (throw 'node-program-p t))
- ;; The `t' indicates to search children.
- t)))
- ;; Default to returning nil from the catch body.
- nil))))
-
-(defcustom context-coloring-javascript-detect-top-level-scope t
- "If non-nil, detect when to use file-level scope."
- :type 'boolean
- :group 'context-coloring)
-
-;;;###autoload
-(defun context-coloring-js2-colorize ()
- "Color the buffer using the `js2-mode'."
- (cond
- ;; Increase the initial level if we should.
- ((and context-coloring-javascript-detect-top-level-scope
- (context-coloring-js2-top-level-local-p))
- (let ((context-coloring-initial-level 1))
- (context-coloring-js2-colorize-ast)))
- (t
- (context-coloring-js2-colorize-ast))))
-
-;;;###autoload
-(puthash
- 'javascript
- (list :modes '(js2-mode js2-jsx-mode)
- :colorizer #'context-coloring-js2-colorize
- :setup
- (lambda ()
- (add-hook 'js2-post-parse-callbacks #'context-coloring-colorize nil
t))
- :teardown
- (lambda ()
- (remove-hook 'js2-post-parse-callbacks #'context-coloring-colorize
t)))
- context-coloring-dispatch-hash-table)
-
-(provide 'context-coloring-javascript)
-
-;;; context-coloring-javascript.el ends here
diff --git a/packages/context-coloring/context-coloring-test.el
b/packages/context-coloring/context-coloring-test.el
deleted file mode 100644
index fabf55b..0000000
--- a/packages/context-coloring/context-coloring-test.el
+++ /dev/null
@@ -1,931 +0,0 @@
-;;; context-coloring-test.el --- Tests for context coloring -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; This file is 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:
-
-;; Tests for context coloring.
-
-;; Use with `make test'.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'context-coloring)
-(require 'context-coloring-javascript)
-(require 'context-coloring-emacs-lisp)
-(require 'ert)
-
-
-;;; Test running utilities
-
-(defconst context-coloring-test-path
- (file-name-directory (or load-file-name buffer-file-name))
- "This file's directory.")
-
-(defun context-coloring-test-read-file (path)
- "Return the file's contents from PATH as a string."
- (with-temp-buffer
- (insert-file-contents (expand-file-name path context-coloring-test-path))
- (buffer-string)))
-
-(defmacro context-coloring-test-with-fixture (fixture &rest body)
- "With relative FIXTURE, evaluate BODY in a temporary buffer."
- `(with-temp-buffer
- (progn
- (insert (context-coloring-test-read-file ,fixture))
- ,@body)))
-
-
-;;; Test defining utilities
-
-(cl-defmacro context-coloring-test-define-deftest (name
- &key mode
- &key extension
- &key no-fixture
- &key
enable-context-coloring-mode
- &key before-each
- &key after-each)
- "Define a deftest defmacro for tests prefixed with NAME. MODE
-is called to set up tests' environments. EXTENSION denotes the
-suffix for tests' fixture files. If NO-FIXTURE is non-nil, don't
-use a fixture. If ENABLE-CONTEXT-COLORING-MODE is non-nil,
-`context-coloring-mode' is activated before tests. Functions
-BEFORE-EACH and AFTER-EACH run before the major mode is activated
-before each test, and after each test, even if an error is
-signaled."
- (declare (indent defun))
- (let ((macro-name (intern (format "context-coloring-test-deftest%s"
- (cond
- ;; No name means no dash.
- ((eq name nil) "")
- (t (format "-%s" name)))))))
- `(cl-defmacro ,macro-name (name
- body
- &key fixture
- &key before
- &key after)
- (declare (indent defun))
- ;; Commas in nested backquotes are not evaluated. Binding the variables
- ;; here is probably the cleanest workaround.
- (let ((mode ,mode)
- (before-each ',before-each)
- (after-each ',after-each)
- (test-name (intern (format ,(format "%s-%%s"
- (cond
- (name)
- (t "generic"))) name)))
- (fixture (cond
- (fixture (format "./fixtures/test/%s" fixture))
- (,no-fixture "./fixtures/test/empty")
- (t (format ,(format "./fixtures/test/%%s.%s" extension)
name)))))
- ,@`((let ((enable-context-coloring-mode
,enable-context-coloring-mode))
- `(ert-deftest ,test-name ()
- (context-coloring-test-with-fixture
- ,fixture
- (when ,before-each (funcall ,before-each))
- (,mode)
- (when ,before (funcall ,before))
- (when ,enable-context-coloring-mode (context-coloring-mode))
- (unwind-protect
- (progn
- (funcall ,body))
- (when ,after (funcall ,after))
- (when ,after-each (funcall ,after-each)))))))))))
-
-(context-coloring-test-define-deftest nil
- :mode #'fundamental-mode
- :no-fixture t)
-
-(defun context-coloring-test-js2-mode ()
- "Enable js2-mode and parse synchronously."
- (js2-mode)
- (js2-reparse))
-
-(context-coloring-test-define-deftest javascript
- :mode #'context-coloring-test-js2-mode
- :extension "js"
- :enable-context-coloring-mode t
- :before-each (lambda ()
- (setq js2-mode-show-parse-errors nil)
- (setq js2-mode-show-strict-warnings nil)))
-
-(context-coloring-test-define-deftest emacs-lisp
- :mode #'emacs-lisp-mode
- :extension "el"
- :enable-context-coloring-mode t)
-
-(context-coloring-test-define-deftest eval-expression
- :mode #'fundamental-mode
- :no-fixture t)
-
-
-;;; Assertion functions
-
-(defun context-coloring-test-get-last-message ()
- "Get the last message in the current messages bufffer."
- (let ((messages (split-string
- (buffer-substring-no-properties
- (point-min)
- (point-max))
- "\n")))
- (car (nthcdr (- (length messages) 2) messages))))
-
-(defun context-coloring-test-assert-message (expected buffer)
- "Assert that message EXPECTED is at the end of BUFFER."
- (when (null (get-buffer buffer))
- (ert-fail
- (format
- (concat
- "Expected buffer `%s' to have message \"%s\", "
- "but the buffer did not have any messages.")
- buffer expected)))
- (with-current-buffer buffer
- (let ((message (context-coloring-test-get-last-message)))
- (when (not (equal message expected))
- (ert-fail
- (format
- (concat
- "Expected buffer `%s' to have message \"%s\", "
- "but instead it was \"%s\"")
- buffer expected
- message))))))
-
-(defun context-coloring-test-assert-not-message (expected buffer)
- "Assert that message EXPECTED is not at the end of BUFFER."
- (when (get-buffer buffer)
- (with-current-buffer buffer
- (let ((message (context-coloring-test-get-last-message)))
- (when (equal message expected)
- (ert-fail
- (format
- (concat
- "Expected buffer `%s' not to have message \"%s\", "
- "but it did")
- buffer expected)))))))
-
-(defun context-coloring-test-assert-error (body error-message)
- "Assert that BODY signals ERROR-MESSAGE."
- (let ((error-signaled-p nil))
- (condition-case err
- (progn
- (funcall body))
- (error
- (setq error-signaled-p t)
- (when (not (string-equal (cadr err) error-message))
- (ert-fail (format (concat "Expected the error \"%s\" to be thrown, "
- "but instead it was \"%s\".")
- error-message
- (cadr err))))))
- (when (not error-signaled-p)
- (ert-fail "Expected an error to be thrown, but there wasn't."))))
-
-
-;;; Miscellaneous tests
-
-(defmacro context-coloring-test-define-derived-mode (name)
- "Define a derived mode exclusively for any test with NAME."
- (let ((name (intern (format "context-coloring-test-%s-mode" name))))
- `(define-derived-mode ,name fundamental-mode "Testing")))
-
-(defvar context-coloring-test-caused-p nil
- "If non-nil, coloring was caused.")
-
-(defmacro context-coloring-test-assert-causes-coloring (&rest body)
- "Assert that BODY causes coloring."
- `(progn
- ;; Gross, but I want this to pass on 24.3.
- (ad-add-advice #'context-coloring-colorize
- '(assert-causes-coloring
- nil t
- (advice . (lambda ()
- (setq context-coloring-test-caused-p t))))
- 'after
- 0)
- (ad-activate #'context-coloring-colorize)
- ,@body
- (when (not context-coloring-test-caused-p)
- (ert-fail "Expected to have colorized, but it didn't."))))
-
-(defun context-coloring-test-cleanup-assert-causes-coloring ()
- "Undo `context-coloring-test-assert-causes-coloring'."
- (ad-unadvise #'context-coloring-colorize)
- (setq context-coloring-test-caused-p nil))
-
-(context-coloring-test-define-derived-mode mode-startup)
-
-(context-coloring-test-deftest mode-startup
- (lambda ()
- (puthash
- 'mode-startup
- (list :modes '(context-coloring-test-mode-startup-mode))
- context-coloring-dispatch-hash-table)
- (context-coloring-test-mode-startup-mode)
- (context-coloring-test-assert-causes-coloring
- (context-coloring-mode)))
- :after (lambda ()
- (context-coloring-test-cleanup-assert-causes-coloring)))
-
-(context-coloring-test-define-derived-mode change-detection)
-
-(context-coloring-test-deftest change-detection
- (lambda ()
- (puthash
- 'idle-change
- (list :modes '(context-coloring-test-change-detection-mode)
- :setup #'context-coloring-setup-idle-change-detection
- :teardown #'context-coloring-teardown-idle-change-detection)
- context-coloring-dispatch-hash-table)
- (context-coloring-test-change-detection-mode)
- (context-coloring-mode)
- (context-coloring-test-assert-causes-coloring
- (insert " ")
- ;; Simply cannot figure out how to trigger an idle timer; would much
rather
- ;; test that. But (current-idle-time) always returns nil in these tests.
- (context-coloring-maybe-colorize-with-buffer (current-buffer))))
- :after (lambda ()
- (context-coloring-test-cleanup-assert-causes-coloring)))
-
-(context-coloring-test-deftest unsupported-mode
- (lambda ()
- (context-coloring-mode)
- (context-coloring-test-assert-message
- "Context coloring is unavailable here"
- "*Messages*")))
-
-(context-coloring-test-deftest unavailable-message-ignored
- (lambda ()
- (minibuffer-with-setup-hook
- (lambda ()
- (context-coloring-mode)
- (context-coloring-test-assert-not-message
- "Context coloring is unavailable here"
- "*Messages*"))
- (execute-kbd-macro
- (vconcat
- [?\C-u]
- [?\M-!])))))
-
-(context-coloring-test-define-derived-mode disable-mode)
-
-(context-coloring-test-deftest disable-mode
- (lambda ()
- (let (torn-down)
- (puthash
- 'disable-mode
- (list :modes '(context-coloring-test-disable-mode-mode)
- :teardown (lambda ()
- (setq torn-down t)))
- context-coloring-dispatch-hash-table)
- (context-coloring-test-disable-mode-mode)
- (context-coloring-mode)
- (context-coloring-mode -1)
- (when (not torn-down)
- (ert-fail "Expected teardown function to have been called, but it
wasn't.")))))
-
-(defun context-coloring-test-assert-maximum-face (expected)
- "Assert that `context-coloring-maximum-face' is EXPECTED."
- (when (not (= context-coloring-maximum-face expected))
- (ert-fail (format "Expected maximum face to be %s, but it was %s"
- expected context-coloring-maximum-face))))
-
-(deftheme context-coloring-test-custom-theme)
-
-(context-coloring-test-define-derived-mode custom-theme)
-
-(context-coloring-test-deftest custom-theme
- (lambda ()
- (custom-theme-set-faces
- 'context-coloring-test-custom-theme
- '(context-coloring-level-0-face ((t :foreground "#aaaaaa")))
- '(context-coloring-level-1-face ((t :foreground "#bbbbbb"))))
- (custom-set-faces
- '(context-coloring-level-0-face ((t :foreground "#aaaaaa"))))
- (enable-theme 'context-coloring-test-custom-theme)
- (puthash
- 'theme
- (list :modes '(context-coloring-test-custom-theme-mode))
- context-coloring-dispatch-hash-table)
- (context-coloring-test-custom-theme-mode)
- (context-coloring-colorize)
- (context-coloring-test-assert-maximum-face 1)
- ;; This theme should now be ignored in favor of the `user' theme.
- (custom-theme-reset-faces
- 'context-coloring-test-custom-theme
- '(context-coloring-level-0-face nil)
- '(context-coloring-level-1-face nil))
- (context-coloring-colorize)
- ;; Maximum face for `user'.
- (context-coloring-test-assert-maximum-face 0)
- ;; Now `user' should be ignored too.
- (custom-reset-faces
- '(context-coloring-level-0-face nil))
- (context-coloring-colorize)
- ;; Expect the package's defaults.
- (context-coloring-test-assert-maximum-face
- context-coloring-default-maximum-face))
- :after (lambda ()
- (custom-reset-faces
- '(context-coloring-level-0-face nil))
- (disable-theme 'context-coloring-test-custom-theme)))
-
-(when (fboundp 'prettify-symbols-mode)
-
- (defun context-coloring-test-assert-prettify-symbols-coloring ()
- (context-coloring-test-assert-coloring "
-(111111 () (222222 ()))"))
-
- (defun context-coloring-test-assert-prettify-symbols-text-properties ()
- (unless (cond
- ((version< emacs-version "25.0")
- (get-text-property 2 'composition))
- (t
- (and (get-text-property 2 'prettify-symbols-start)
- (get-text-property 2 'prettify-symbols-end))))
- (ert-fail "Expected buffer to have it's symbols prettified, but it
didn't.")))
-
- (context-coloring-test-deftest prettify-symbols-enabled-before
- (lambda ()
- (context-coloring-test-with-fixture
- "./fixtures/test/prettify-symbols.el"
- (emacs-lisp-mode)
- (prettify-symbols-mode)
- (context-coloring-mode)
-
(context-coloring-test-assert-prettify-symbols-text-properties)
-
(context-coloring-test-assert-prettify-symbols-coloring))))
-
- (context-coloring-test-deftest prettify-symbols-enabled-after
- (lambda ()
- (context-coloring-test-with-fixture
- "./fixtures/test/prettify-symbols.el"
- (emacs-lisp-mode)
- (context-coloring-mode)
- (prettify-symbols-mode)
-
(context-coloring-test-assert-prettify-symbols-text-properties)
-
(context-coloring-test-assert-prettify-symbols-coloring)))))
-
-
-;;; Coloring tests
-
-(defun context-coloring-test-face-to-level (face)
- "Convert FACE symbol to its corresponding level, or nil."
- (when face
- (let* ((face-string (symbol-name face))
- (matches (string-match
- context-coloring-level-face-regexp
- face-string)))
- (when matches
- (string-to-number (match-string 1 face-string))))))
-
-(defun context-coloring-test-assert-position-level (position level)
- "Assert that POSITION has LEVEL."
- (let* ((face (get-text-property position 'face))
- (actual-level (context-coloring-test-face-to-level face)))
- (when (not (= level actual-level))
- (ert-fail (format (concat "Expected level at position %s, "
- "which is \"%s\", to be %s; "
- "but it was %s")
- position
- (buffer-substring-no-properties position (1+
position)) level
- actual-level)))))
-
-(defun context-coloring-test-assert-position-face (position face-regexp)
- "Assert that the face at POSITION satisfies FACE-REGEXP."
- (let ((face (get-text-property position 'face)))
- (when (or
- ;; Pass a non-string to do an `equal' check (against a symbol or
nil).
- (unless (stringp face-regexp)
- (not (equal face-regexp face)))
- ;; Otherwise do the matching.
- (when (stringp face-regexp)
- (not (string-match-p face-regexp (symbol-name face)))))
- (ert-fail (format (concat "Expected face at position %s, "
- "which is \"%s\", to be %s; "
- "but it was %s")
- position
- (buffer-substring-no-properties position (1+
position)) face-regexp
- face)))))
-
-(defun context-coloring-test-assert-position-comment (position)
- "Assert that the face at POSITION is a comment."
- (context-coloring-test-assert-position-face
- position "\\`font-lock-comment\\(-delimiter\\)?-face\\'"))
-
-(defun context-coloring-test-assert-position-constant-comment (position)
- "Assert that the face at POSITION is a constant comment."
- (context-coloring-test-assert-position-face position
'(font-lock-constant-face
-
font-lock-comment-face)))
-
-(defun context-coloring-test-assert-position-string (position)
- "Assert that the face at POSITION is a string."
- (context-coloring-test-assert-position-face position 'font-lock-string-face))
-
-(defun context-coloring-test-assert-position-nil (position)
- "Assert that the face at POSITION is nil."
- (context-coloring-test-assert-position-face position nil))
-
-(defun context-coloring-test-assert-coloring (map)
- "Assert that the current buffer's coloring will match MAP.
-
-MAP's newlines should correspond to the current fixture.
-
-The following characters appearing in MAP assert coloring for
-corresponding points in the fixture:
-
-0-9: Level equals number.
-C: Face is constant comment.
-c: Face is comment.
-n: Face is nil.
-s: Face is string.
-
-Any other characters are discarded. Characters \"x\" and any
-other non-letters are guaranteed to always be discarded."
- ;; Omit the superfluous, formatting-related leading newline. Can't use
- ;; `save-excursion' here because if an assertion fails it will cause future
- ;; tests to get messed up.
- (goto-char (point-min))
- (let* ((map (substring map 1))
- (index 0)
- char-string
- char)
- (while (< index (length map))
- (setq char-string (substring map index (1+ index)))
- (setq char (string-to-char char-string))
- (cond
- ;; Newline
- ((= char 10)
- (forward-line)
- (beginning-of-line))
- ;; Number
- ((and (>= char 48)
- (<= char 57))
- (context-coloring-test-assert-position-level
- (point) (string-to-number char-string))
- (forward-char))
- ;; 'C' = Constant comment
- ((= char 67)
- (context-coloring-test-assert-position-constant-comment (point))
- (forward-char))
- ;; 'c' = Comment
- ((= char 99)
- (context-coloring-test-assert-position-comment (point))
- (forward-char))
- ;; 'n' = nil
- ((= char 110)
- (context-coloring-test-assert-position-nil (point))
- (forward-char))
- ;; 's' = String
- ((= char 115)
- (context-coloring-test-assert-position-string (point))
- (forward-char))
- (t
- (forward-char)))
- (setq index (1+ index)))))
-
-(context-coloring-test-deftest-javascript function-scopes
- (lambda ()
- (context-coloring-test-assert-coloring "
-000 0 0 11111111 11 110
-11111111 011 1
- 111 1 1 22222222 22 221
- 22222222 122 22
-1")))
-
-(context-coloring-test-deftest-javascript global
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- 111 1 1 0000001xxx11
-}());")))
-
-(context-coloring-test-deftest-javascript block-scopes
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- 11 111 2
- 222 12
- 222 22
- 22222 22
- 2
-}());"))
- :before (lambda ()
- (setq context-coloring-javascript-block-scopes t))
- :after (lambda ()
- (setq context-coloring-javascript-block-scopes nil)))
-
-(context-coloring-test-deftest-javascript catch
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- 111 11 22222 222 2
- 222 1 2 22
- 222 22 33333 333 3
- 333 1 3 33
- 3
- 2
-}());")))
-
-(context-coloring-test-deftest-javascript key-names
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- 111111 1
- 11 11
- 1 1 1
- 11
-}());")))
-
-(context-coloring-test-deftest-javascript property-lookup
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- 0000001111111
- 0000001 111111
- 00000011111111111
-}());")))
-
-(context-coloring-test-deftest-javascript key-values
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxxxx () {
- xxx x;
- (xxxxxxxx () {
- xxxxxx {
- x: 1
- };
- }());
-}());")))
-
-(context-coloring-test-deftest-javascript syntactic-comments-and-strings
- (lambda ()
- (context-coloring-test-assert-coloring "
-0000 00
-ccccccc
-cccccccccc
-ssssssssssss0"))
- :fixture "comments-and-strings.js")
-
-(context-coloring-test-deftest-javascript syntactic-comments
- (lambda ()
- (context-coloring-test-assert-coloring "
-0000 00
-ccccccc
-cccccccccc
-0000000000000"))
- :fixture "comments-and-strings.js"
- :before (lambda ()
- (setq context-coloring-syntactic-strings nil))
- :after (lambda ()
- (setq context-coloring-syntactic-strings t)))
-
-(context-coloring-test-deftest-javascript syntactic-strings
- (lambda ()
- (context-coloring-test-assert-coloring "
-0000 00
-0000000
-0000000000
-ssssssssssss0"))
- :fixture "comments-and-strings.js"
- :before (lambda ()
- (setq context-coloring-syntactic-comments nil))
- :after (lambda ()
- (setq context-coloring-syntactic-comments t)))
-
-(context-coloring-test-deftest-javascript unterminated-comment
- ;; As long as `add-text-properties' doesn't signal an error, this test
passes.
- (lambda ()))
-
-(defun context-coloring-test-assert-javascript-elevated-level ()
- "Assert that the \"initial-level.js\" file has elevated scope."
- (context-coloring-test-assert-coloring "
-
-111 1 1 0000001xxx11"))
-
-(defun context-coloring-test-assert-javascript-global-level ()
- "Assert that the \"initial-level.js\" file has global scope."
- (context-coloring-test-assert-coloring "
-
-000 0 0 0000000xxx00"))
-
-(context-coloring-test-deftest-javascript initial-level
- (lambda ()
- (context-coloring-test-assert-javascript-elevated-level))
- :fixture "initial-level.js"
- :before (lambda ()
- (setq context-coloring-initial-level 1))
- :after (lambda ()
- (setq context-coloring-initial-level 0)))
-
-(defun context-coloring-test-setup-top-level-scope (string)
- "Make STRING the first line and colorize again."
- (goto-char (point-min))
- (kill-whole-line 0)
- (insert string)
- ;; Reparsing triggers recoloring.
- (js2-reparse))
-
-(context-coloring-test-deftest-javascript top-level-scope
- (lambda ()
- (let ((positive-indicators
- (list "#!/usr/bin/env node"
- "/*jslint node: true */"
- "// jshint node: true"
- "/*eslint-env node */"
- "module.exports"
- "module.exports.a"
- "exports.a"
- "require('a')"))
- (negative-indicators
- (list "// Blah blah jshint blah."
- "module"
- "exports"
- "var require; require('a')")))
- (dolist (indicator positive-indicators)
- (context-coloring-test-setup-top-level-scope indicator)
- (context-coloring-test-assert-javascript-elevated-level))
- (dolist (indicator negative-indicators)
- (context-coloring-test-setup-top-level-scope indicator)
- (context-coloring-test-assert-javascript-global-level))))
- :fixture "initial-level.js")
-
-(context-coloring-test-deftest-javascript narrow-to-region
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111111 0 11 11
-11111111 0 11 11
-11111111 0 11 1"))
- :before (lambda ()
- (narrow-to-region (+ (point-min) 1) (- (point-max) 2))))
-
-(context-coloring-test-deftest-emacs-lisp defun
- (lambda ()
- (context-coloring-test-assert-coloring "
-111111 000 1111 111 111111111 1111
- 11 111 111 111 000011
-
-0000 0 0 00
-
-111111 01
-111111 111
-111111 0 1sss11")))
-
-(context-coloring-test-deftest-emacs-lisp defadvice
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111111111 0 1111111 111111 11111 111 111111111
- 2222 222 122
- 22 1 2221")))
-
-(context-coloring-test-deftest-emacs-lisp lambda
- (lambda ()
- (context-coloring-test-assert-coloring "
-00000000 1111111 1111
- 11111111 11 2222222 2222
- 222 22 12 2221 111 0 00")))
-
-(context-coloring-test-deftest-emacs-lisp quote
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxx 0000000 00 00000)
-(xxx () (xxxxxxxxx (,0000)))
-
-(xxxxx x (x)
- (xx (xx x 111
- 111111 1 111 111
- 111111 1 1111111111 11 111 1 111 1 00001 10000 11 00001 1 10000
- sss ccc
- 1111
-
-(xxxxxx '(sss cc
- sss cc
- ))
-
-(xxxxxx () 111111 11111)")))
-
-(context-coloring-test-deftest-emacs-lisp splice
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxxx ()
- 111111 00001 100001)")))
-
-(context-coloring-test-deftest-emacs-lisp comment
- (lambda ()
- ;; Just check that the comment isn't parsed syntactically.
- (context-coloring-test-assert-coloring "
-(xxxxx x ()
- (xx (x xxxxx-xxxx xx) cccccccccc
- 11 00000-0000 11))) cccccccccc")))
-
-(context-coloring-test-deftest-emacs-lisp string
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxx x (x)
- (xxxxxx x x sss 1 0 sssss 0 1 sssssss11")))
-
-(context-coloring-test-deftest-emacs-lisp ignored
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxxxx x ()
- (x x 1 11 11 111 111 11 11 11 1 111 (1 1 1)))")))
-
-(context-coloring-test-deftest-emacs-lisp sexp
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxx ()
- `,@sss
- `,@11
- `,@11)")))
-
-(context-coloring-test-deftest-emacs-lisp let
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111 11
- 11 01
- 11 00001
- 11 2222 22
- 22 02
- 22 000022
- 2222 2 2 2 00002211
- 1111 1 1 1 000011
-
-1111 cc ccccccc
- 1sss11")))
-
-(context-coloring-test-deftest-emacs-lisp empty-varlist
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111111 1 11
-1111111 111
-
-1111 1cc
- 11
-1111111 111")))
-
-(context-coloring-test-deftest-emacs-lisp varlist-spacing
- (lambda ()
- (context-coloring-test-assert-coloring "
-(111 (
- (1 (222222 ()))))
-
-(111111 ( 1 1 )
- 1 1)
-
-(111111111 0 ( (1) )
- 1)")))
-
-(context-coloring-test-deftest-emacs-lisp let*
- (lambda ()
- (context-coloring-test-assert-coloring "
-11111 11
- 11 11
- 11 000011
- 1111 1 1 1 0 0 00001
- 22222 22
- 22 12
- 22 00002
- 22 02
- 22 222
- 2222 1 1 2 2 2 000022
- 1111 1 1 1 0 0 000011"))
- :fixture "let-star.el")
-
-(context-coloring-test-deftest-emacs-lisp macroexp-let2
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111 11111
- 222222222-2222 00000000-00000000-0 2 111
- 2 11121
-
-(11111111-1111 00000000-00000000-0)
-(11111111-1111)")))
-
-(context-coloring-test-deftest-emacs-lisp cond
- (lambda ()
- (context-coloring-test-assert-coloring "
-(xxx (x)
- 11111
- 11 11
- 10000 11
- 1111 1 00001 11
- 11 11111 1 000011
- cc c
- sss1)")))
-
-(context-coloring-test-deftest-emacs-lisp condition-case
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111111111-1111 111
- 111111 000 00001
- 111111 111 00001
- 1111111 111111 111 000011
-
-(111111111-1111-111111-11111 111
- cc c
- (xxx () 222)
- (11111 (xxx () 222))
- sss)")))
-
-(context-coloring-test-deftest-emacs-lisp dolist
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111111 111111
- 2222222 2222 1111 2222222
- 3333333 33 33 222 1111 2222223321")))
-
-(defun context-coloring-test-insert-unread-space ()
- "Simulate the insertion of a space as if by a user."
- (setq unread-command-events (cons '(t . 32)
- unread-command-events)))
-
-(defun context-coloring-test-remove-faces ()
- "Remove all faces in the current buffer."
- (remove-text-properties (point-min) (point-max) '(face nil)))
-
-(context-coloring-test-deftest-emacs-lisp iteration
- (lambda ()
- (let ((context-coloring-elisp-sexps-per-pause 2))
- (context-coloring-colorize)
- (context-coloring-test-assert-coloring "
-cc `CC' `CC'
-(xxxxx x ())")
- (context-coloring-test-remove-faces)
- (context-coloring-test-insert-unread-space)
- (context-coloring-colorize)
- ;; Coloring is interrupted after the first "sexp" (the comment in this
- ;; case).
- (context-coloring-test-assert-coloring "
-cc `CC' `CC'
-nnnnnn n nnn"))))
-
-(context-coloring-test-deftest-emacs-lisp changed
- (lambda ()
- (context-coloring-test-remove-faces)
- ;; Goto line 3.
- (goto-char (point-min))
- (forward-line (1- 3))
- (insert " ")
- ;; Mock `pos-visible-in-window-p' because in batch mode `get-buffer-window'
- ;; returns nil. Emacs must not have a window in that environment.
- (cl-letf (((symbol-function 'pos-visible-in-window-p)
- (let ((calls 0))
- (lambda ()
- (prog1
- ;; First and third calls start from center. Second and
- ;; fourth calls are made immediately after moving past
- ;; the first defun in either direction "off screen".
- (cond
- ((= calls 0) t)
- ((= calls 1) nil)
- ((= calls 2) t)
- ((= calls 4) nil))
- (setq calls (1+ calls)))))))
- (context-coloring-colorize))
- (context-coloring-test-assert-coloring "
-nnnn n nnn nnnnnnnn
-0000
-
-0000
-nnnnn n nnn nnnnnnnn")))
-
-(context-coloring-test-deftest-emacs-lisp unbalanced-parenthesis
- (lambda ()
- (context-coloring-test-assert-coloring "
-1111 111
-nnnn nn")))
-
-(context-coloring-test-deftest-eval-expression let
- (lambda ()
- (minibuffer-with-setup-hook
- (lambda ()
- ;; Perform the test in a hook as it's the only way I know of
examining
- ;; the minibuffer's contents. The contents are implicitly submitted,
- ;; so we have to ignore the errors in the arbitrary test subject
code.
- (insert "(ignore-errors (let (a) (message a free)))")
- (context-coloring-mode)
- (context-coloring-test-assert-coloring "
-xxxx: 0000000-000000 1111 111 11111111 1 0000110"))
- ;; Simulate user input because `call-interactively' is blocking and
- ;; doesn't seem to run the hook.
- (execute-kbd-macro
- (vconcat
- [?\C-u] ;; Don't output the result of the arbitrary test subject code.
- [?\M-:])))))
-
-(provide 'context-coloring-test)
-
-;;; context-coloring-test.el ends here
diff --git a/packages/context-coloring/context-coloring.el
b/packages/context-coloring/context-coloring.el
deleted file mode 100644
index ac24364..0000000
--- a/packages/context-coloring/context-coloring.el
+++ /dev/null
@@ -1,494 +0,0 @@
-;;; context-coloring.el --- Highlight by scope -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
-
-;; Author: Jackson Ray Hamilton <jackson@jacksonrayhamilton.com>
-;; Version: 8.1.0
-;; Keywords: convenience faces tools
-;; Package-Requires: ((emacs "24.3"))
-;; URL: https://github.com/jacksonrayhamilton/context-coloring
-
-;; This file is 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:
-
-;; Highlights code by scope. Top-level scopes are one color, second-level
-;; scopes are another color, and so on. Variables retain the color of the
scope
-;; in which they are defined. A variable defined in an outer scope referenced
-;; by an inner scope is colored the same as the outer scope.
-
-;; By default, comments and strings are still highlighted syntactically.
-
-;;; Code:
-
-
-;;; Utilities
-
-(defun context-coloring-join (strings delimiter)
- "Join a list of STRINGS with the string DELIMITER."
- (mapconcat #'identity strings delimiter))
-
-(defun context-coloring-check-predicates (predicates)
- "Call PREDICATES until one returns t, otherwise return nil."
- (let ((satisfied-p nil))
- (while (and predicates
- (not satisfied-p))
- (setq satisfied-p (funcall (pop predicates))))
- satisfied-p))
-
-
-;;; Faces
-
-(defun context-coloring-defface (level light dark tty)
- "Define a face for LEVEL with LIGHT, DARK and TTY colors."
- (let ((face (intern (format "context-coloring-level-%s-face" level)))
- (doc (format "Context coloring face, level %s." level)))
- (custom-declare-face
- face
- `((((type tty)) (:foreground ,tty))
- (((background light)) (:foreground ,light))
- (((background dark)) (:foreground ,dark)))
- doc
- :group 'context-coloring)))
-
-;; Provide some default colors based off Emacs's defaults.
-(context-coloring-defface 0 "#000000" "#ffffff" nil)
-(context-coloring-defface 1 "#008b8b" "#00ffff" "yellow")
-(context-coloring-defface 2 "#0000ff" "#87cefa" "green")
-(context-coloring-defface 3 "#483d8b" "#b0c4de" "cyan")
-(context-coloring-defface 4 "#a020f0" "#eedd82" "blue")
-(context-coloring-defface 5 "#a0522d" "#98fb98" "magenta")
-(context-coloring-defface 6 "#228b22" "#7fffd4" "red")
-(context-coloring-defface 7 "#3f3f3f" "#cdcdcd" nil)
-
-(defconst context-coloring-default-maximum-face 7
- "Maximum face when there are no custom faces.")
-
-;; Create placeholder faces for users and theme authors.
-(dotimes (level 18)
- (let* ((level (+ level 8))
- (face (intern (format "context-coloring-level-%s-face" level)))
- (doc (format "Context coloring face, level %s." level)))
- (custom-declare-face face nil doc :group 'context-coloring)))
-
-(defvar-local context-coloring-maximum-face nil
- "Dynamic index of the highest face available for coloring.")
-
-(defsubst context-coloring-level-face (level)
- "Return symbol for face with LEVEL."
- ;; `concat' is faster than `format' here.
- (intern-soft
- (concat "context-coloring-level-" (number-to-string level) "-face")))
-
-(defsubst context-coloring-bounded-level-face (level)
- "Return symbol for face with LEVEL, bounded by the maximum."
- (context-coloring-level-face (min level context-coloring-maximum-face)))
-
-(defconst context-coloring-level-face-regexp
- "context-coloring-level-\\([[:digit:]]+\\)-face"
- "Extract a level from a face.")
-
-(defun context-coloring-theme-highest-level (theme)
- "Return the highest coloring level for THEME, or -1."
- (let* ((settings (get theme 'theme-settings))
- (tail settings)
- face-string
- number
- (found -1))
- (while tail
- (and (eq (nth 0 (car tail)) 'theme-face)
- (setq face-string (symbol-name (nth 1 (car tail))))
- (string-match
- context-coloring-level-face-regexp
- face-string)
- (setq number (string-to-number
- (substring face-string
- (match-beginning 1)
- (match-end 1))))
- (> number found)
- (setq found number))
- (setq tail (cdr tail)))
- found))
-
-(defun context-coloring-update-maximum-face ()
- "Save the highest possible face for the current theme."
- (let ((themes (append custom-enabled-themes '(user)))
- (continue t)
- theme
- highest-level)
- (while continue
- (setq theme (car themes))
- (setq themes (cdr themes))
- (setq highest-level (context-coloring-theme-highest-level theme))
- (setq continue (and themes (= highest-level -1))))
- (setq context-coloring-maximum-face
- (cond
- ((= highest-level -1)
- context-coloring-default-maximum-face)
- (t
- highest-level)))))
-
-
-;;; Change detection
-
-(defvar-local context-coloring-changed-p nil
- "Indication that the buffer has changed recently, which implies
-that it should be colored again by
-`context-coloring-maybe-colorize-idle-timer' if that timer is
-being used.")
-
-(defvar-local context-coloring-changed-start nil
- "Beginning of last text that changed.")
-
-(defvar-local context-coloring-changed-end nil
- "End of last text that changed.")
-
-(defvar-local context-coloring-changed-length nil
- "Length of last text that changed.")
-
-(defun context-coloring-change-function (start end length)
- "Register a change so that a buffer can be colorized soon.
-
-START, END and LENGTH are recorded for later use."
- ;; Tokenization is obsolete if there was a change.
- (setq context-coloring-changed-start start)
- (setq context-coloring-changed-end end)
- (setq context-coloring-changed-length length)
- (setq context-coloring-changed-p t))
-
-(defun context-coloring-maybe-colorize-with-buffer (buffer)
- "Color BUFFER and if it has changed."
- (when (and (eq buffer (current-buffer))
- context-coloring-changed-p)
- (context-coloring-colorize-with-buffer buffer)
- (setq context-coloring-changed-p nil)
- (setq context-coloring-changed-start nil)
- (setq context-coloring-changed-end nil)
- (setq context-coloring-changed-length nil)))
-
-(defvar-local context-coloring-maybe-colorize-idle-timer nil
- "The currently-running idle timer for conditional coloring.")
-
-(defvar-local context-coloring-colorize-idle-timer nil
- "The currently-running idle timer for unconditional coloring.")
-
-(defcustom context-coloring-default-delay 0.25
- "Default delay between a buffer update and colorization.
-
-Increase this if your machine is high-performing. Decrease it if
-it ain't."
- :type 'float
- :group 'context-coloring)
-
-(defun context-coloring-cancel-timer (timer)
- "Cancel TIMER."
- (when timer
- (cancel-timer timer)))
-
-(defun context-coloring-schedule-coloring (time)
- "Schedule coloring to occur once after Emacs is idle for TIME."
- (context-coloring-cancel-timer context-coloring-colorize-idle-timer)
- (setq context-coloring-colorize-idle-timer
- (run-with-idle-timer
- time
- nil
- #'context-coloring-colorize-with-buffer
- (current-buffer))))
-
-(defun context-coloring-setup-idle-change-detection ()
- "Setup idle change detection."
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (add-hook
- 'after-change-functions #'context-coloring-change-function nil t)
- (add-hook
- 'kill-buffer-hook #'context-coloring-teardown-idle-change-detection nil t)
- (setq context-coloring-maybe-colorize-idle-timer
- (run-with-idle-timer
- (or (plist-get dispatch :delay) context-coloring-default-delay)
- t
- #'context-coloring-maybe-colorize-with-buffer
- (current-buffer)))))
-
-(defun context-coloring-teardown-idle-change-detection ()
- "Teardown idle change detection."
- (dolist (timer (list context-coloring-colorize-idle-timer
- context-coloring-maybe-colorize-idle-timer))
- (context-coloring-cancel-timer timer))
- (remove-hook
- 'kill-buffer-hook #'context-coloring-teardown-idle-change-detection t)
- (remove-hook
- 'after-change-functions #'context-coloring-change-function t))
-
-
-;;; Colorization utilities
-
-(defsubst context-coloring-colorize-region (start end level)
- "Color from START (inclusive) to END (exclusive) with LEVEL."
- (add-text-properties
- start
- end
- `(face ,(context-coloring-bounded-level-face level))))
-
-(defcustom context-coloring-syntactic-comments t
- "If non-nil, also color comments using `font-lock'."
- :type 'boolean
- :group 'context-coloring)
-
-(defcustom context-coloring-syntactic-strings t
- "If non-nil, also color strings using `font-lock'."
- :type 'boolean
- :group 'context-coloring)
-
-(defun context-coloring-font-lock-syntactic-comment-function (state)
- "Color a comment according to STATE."
- (if (nth 3 state) nil font-lock-comment-face))
-
-(defun context-coloring-font-lock-syntactic-string-function (state)
- "Color a string according to STATE."
- (if (nth 3 state) font-lock-string-face nil))
-
-(defsubst context-coloring-colorize-comments-and-strings (&optional min max
keywords-p)
- "Maybe color comments and strings in buffer from MIN to MAX.
-MIN defaults to beginning of buffer. MAX defaults to end. If
-KEYWORDS-P is non-nil, also color keywords from MIN to MAX."
- (when (or context-coloring-syntactic-comments
- context-coloring-syntactic-strings)
- (let ((min (or min (point-min)))
- (max (or max (point-max)))
- (font-lock-syntactic-face-function
- (cond
- ((and context-coloring-syntactic-comments
- (not context-coloring-syntactic-strings))
- #'context-coloring-font-lock-syntactic-comment-function)
- ((and context-coloring-syntactic-strings
- (not context-coloring-syntactic-comments))
- #'context-coloring-font-lock-syntactic-string-function)
- (t
- font-lock-syntactic-face-function))))
- (save-excursion
- (font-lock-fontify-syntactically-region min max)
- (when keywords-p
- (font-lock-fontify-keywords-region min max))))))
-
-(defcustom context-coloring-initial-level 0
- "Scope level at which to start coloring.
-
-If top-level variables and functions do not become global, but
-are scoped to a file (as in Node.js), set this to 1."
- :type 'integer
- :safe #'integerp
- :group 'context-coloring)
-
-
-;;; Dispatch
-
-;;;###autoload
-(defvar context-coloring-dispatch-hash-table (make-hash-table :test #'eq)
- "Map dispatch strategy names to their property lists.
-
-A \"dispatch\" is a property list describing a strategy for
-coloring a buffer.
-
-Its properties must include one of `:modes' or `:predicate', and
-a `:colorizer'.
-
-`:modes' - List of major modes this dispatch is valid for.
-
-`:predicate' - Function that determines if the dispatch is valid
-for any given state.
-
-`:colorizer' - Function that parses and colors the buffer.
-
-`:delay' - Delay between buffer update and colorization, to
-override `context-coloring-default-delay'.
-
-`:setup' - Arbitrary code to set up this dispatch when
-`context-coloring-mode' is enabled.
-
-`:teardown' - Arbitrary code to tear down this dispatch when
-`context-coloring-mode' is disabled.
-
-`:async-p' - Hint that code will be colorized asynchronously.
-Please call `context-coloring-after-colorize' when colorization
-completes.")
-
-(defun context-coloring-find-dispatch (predicate)
- "Find the first dispatch satisfying PREDICATE."
- (let (found)
- (maphash
- (lambda (_ dispatch)
- (when (and (not found)
- (funcall predicate dispatch))
- (setq found dispatch)))
- context-coloring-dispatch-hash-table)
- found))
-
-(defun context-coloring-get-current-dispatch ()
- "Return the first dispatch appropriate for the current state."
- (cond
- ;; Maybe a predicate will be satisfied.
- ((context-coloring-find-dispatch
- (lambda (dispatch)
- (let ((predicate (plist-get dispatch :predicate)))
- (and predicate (funcall predicate))))))
- ;; If not, maybe a major mode (or a derivative) will.
- ((context-coloring-find-dispatch
- (lambda (dispatch)
- (let ((modes (plist-get dispatch :modes))
- match)
- (while (and modes (not match))
- (setq match (eq (pop modes) major-mode)))
- match))))))
-
-(defun context-coloring-before-colorize ()
- "Set up environment for colorization."
- (context-coloring-update-maximum-face))
-
-(defvar context-coloring-after-colorize-hook nil
- "Functions to run after colorizing.")
-
-(defun context-coloring-after-colorize ()
- "Do final business after colorization."
- (run-hooks 'context-coloring-after-colorize-hook))
-
-(defun context-coloring-dispatch ()
- "Determine how to color the current buffer, and color it."
- (let* ((dispatch (context-coloring-get-current-dispatch))
- (colorizer (plist-get dispatch :colorizer))
- (async-p (plist-get dispatch :async-p)))
- (context-coloring-before-colorize)
- (when colorizer
- (catch 'interrupted
- (funcall colorizer)))
- (unless async-p
- (context-coloring-after-colorize))))
-
-
-;;; Colorization
-
-(defvar context-coloring-fontify-keywords-predicates
- (list
- (lambda () (and (boundp 'prettify-symbols-mode) prettify-symbols-mode)))
- "Cases where the whole buffer should have keywords fontified.
-Necessary in cases where a mode relies on fontifications in
-regions where Context Coloring doesn't happen to touch.")
-
-(defun context-coloring-maybe-fontify-keywords ()
- "Determine if the buffer ought to have keywords fontified."
- (when (context-coloring-check-predicates
- context-coloring-fontify-keywords-predicates)
- (with-silent-modifications
- (save-excursion
- (font-lock-fontify-keywords-region (point-min) (point-max))))))
-
-(add-hook 'context-coloring-after-colorize-hook
- #'context-coloring-maybe-fontify-keywords)
-
-(defun context-coloring-colorize ()
- "Color the current buffer by function context."
- (interactive)
- (context-coloring-dispatch))
-
-(defun context-coloring-colorize-with-buffer (buffer)
- "Color BUFFER."
- ;; Don't select deleted buffers.
- (when (get-buffer buffer)
- (with-current-buffer buffer
- (context-coloring-colorize))))
-
-
-;;; Minor mode
-
-(defvar context-coloring-ignore-unavailable-predicates
- (list
- #'minibufferp)
- "Cases when \"unavailable\" messages are silenced.
-Necessary in editing states where coloring is only sometimes
-permissible.")
-
-(defun context-coloring-ignore-unavailable-message-p ()
- "Determine if the unavailable message should be silenced."
- (context-coloring-check-predicates
- context-coloring-ignore-unavailable-predicates))
-
-(defvar context-coloring-interruptable-p t
- "When non-nil, coloring may be interrupted by user input.")
-
-;;;###autoload
-(define-minor-mode context-coloring-mode
- "Toggle contextual code coloring.
-With a prefix argument ARG, enable Context Coloring mode if ARG
-is positive, and disable it otherwise. If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-Context Coloring mode is a buffer-local minor mode. When
-enabled, code is colored by scope. Scopes are colored
-hierarchically. Variables referenced from nested scopes retain
-the color of their defining scopes. Certain syntax, like
-comments and strings, is still colored with `font-lock'.
-
-The entire buffer is colored initially. Changes to the buffer
-trigger recoloring.
-
-Define your own colors by customizing faces like
-`context-coloring-level-N-face', where N is a number starting
-from 0. If no face is found on a custom theme nor the `user'
-theme, the defaults are used.
-
-New language / major mode support can be added with
-`context-coloring-define-dispatch', which see.
-
-Feature inspired by Douglas Crockford."
- nil " Context" nil
- (cond
- (context-coloring-mode
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (cond
- (dispatch
- ;; Font lock is incompatible with this mode; the converse is also true.
- (font-lock-mode 0)
- ;; ...but we do use font-lock functions here.
- (font-lock-set-defaults)
- ;; Safely change the value of this function as necessary.
- (make-local-variable 'font-lock-syntactic-face-function)
- ;; Improve integration with `prettify-symbols-mode'. It relies on Font
- ;; Lock's automatic fontification to apply it's changes on mode change,
- ;; so Context Coloring has to make those changes manually.
- (add-hook 'prettify-symbols-mode-hook
#'context-coloring-maybe-fontify-keywords nil t)
- ;; Furthermore, on Emacs < 25.0, `prettify-symbols-mode' calls
- ;; `font-lock-fontify-buffer-function' which would overwrite context
- ;; coloring, so make it a no-op.
- (set (make-local-variable 'font-lock-fontify-buffer-function) (lambda
()))
- (let ((setup (plist-get dispatch :setup)))
- (when setup
- (funcall setup))
- ;; Colorize once initially.
- (let ((context-coloring-interruptable-p nil))
- (context-coloring-colorize))))
- ((not (context-coloring-ignore-unavailable-message-p))
- (message "Context coloring is unavailable here")))))
- (t
- (let ((dispatch (context-coloring-get-current-dispatch)))
- (when dispatch
- (let ((teardown (plist-get dispatch :teardown)))
- (when teardown
- (funcall teardown)))))
- (remove-hook 'prettify-symbols-mode-hook
#'context-coloring-maybe-fontify-keywords t)
- (turn-on-font-lock-if-desired))))
-
-(provide 'context-coloring)
-
-;;; context-coloring.el ends here
diff --git a/packages/context-coloring/fixtures/.nosearch
b/packages/context-coloring/fixtures/.nosearch
deleted file mode 100644
index e69de29..0000000
diff --git a/packages/context-coloring/fixtures/benchmark/.dir-locals.el
b/packages/context-coloring/fixtures/benchmark/.dir-locals.el
deleted file mode 100644
index f3d5e97..0000000
--- a/packages/context-coloring/fixtures/benchmark/.dir-locals.el
+++ /dev/null
@@ -1 +0,0 @@
-((nil . ((buffer-read-only . t))))
diff --git a/packages/context-coloring/fixtures/benchmark/async-0.9.0.js
b/packages/context-coloring/fixtures/benchmark/async-0.9.0.js
deleted file mode 100644
index 01e8afc..0000000
--- a/packages/context-coloring/fixtures/benchmark/async-0.9.0.js
+++ /dev/null
@@ -1,1123 +0,0 @@
-/*!
- * async
- * https://github.com/caolan/async
- *
- * Copyright 2010-2014 Caolan McMahon
- * Released under the MIT license
- */
-/*jshint onevar: false, indent:4 */
-/*global setImmediate: false, setTimeout: false, console: false */
-(function () {
-
- var async = {};
-
- // global on the server, window in the browser
- var root, previous_async;
-
- root = this;
- if (root != null) {
- previous_async = root.async;
- }
-
- async.noConflict = function () {
- root.async = previous_async;
- return async;
- };
-
- function only_once(fn) {
- var called = false;
- return function() {
- if (called) throw new Error("Callback was already called.");
- called = true;
- fn.apply(root, arguments);
- }
- }
-
- //// cross-browser compatiblity functions ////
-
- var _toString = Object.prototype.toString;
-
- var _isArray = Array.isArray || function (obj) {
- return _toString.call(obj) === '[object Array]';
- };
-
- var _each = function (arr, iterator) {
- if (arr.forEach) {
- return arr.forEach(iterator);
- }
- for (var i = 0; i < arr.length; i += 1) {
- iterator(arr[i], i, arr);
- }
- };
-
- var _map = function (arr, iterator) {
- if (arr.map) {
- return arr.map(iterator);
- }
- var results = [];
- _each(arr, function (x, i, a) {
- results.push(iterator(x, i, a));
- });
- return results;
- };
-
- var _reduce = function (arr, iterator, memo) {
- if (arr.reduce) {
- return arr.reduce(iterator, memo);
- }
- _each(arr, function (x, i, a) {
- memo = iterator(memo, x, i, a);
- });
- return memo;
- };
-
- var _keys = function (obj) {
- if (Object.keys) {
- return Object.keys(obj);
- }
- var keys = [];
- for (var k in obj) {
- if (obj.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- return keys;
- };
-
- //// exported async module functions ////
-
- //// nextTick implementation with browser-compatible fallback ////
- if (typeof process === 'undefined' || !(process.nextTick)) {
- if (typeof setImmediate === 'function') {
- async.nextTick = function (fn) {
- // not a direct alias for IE10 compatibility
- setImmediate(fn);
- };
- async.setImmediate = async.nextTick;
- }
- else {
- async.nextTick = function (fn) {
- setTimeout(fn, 0);
- };
- async.setImmediate = async.nextTick;
- }
- }
- else {
- async.nextTick = process.nextTick;
- if (typeof setImmediate !== 'undefined') {
- async.setImmediate = function (fn) {
- // not a direct alias for IE10 compatibility
- setImmediate(fn);
- };
- }
- else {
- async.setImmediate = async.nextTick;
- }
- }
-
- async.each = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- _each(arr, function (x) {
- iterator(x, only_once(done) );
- });
- function done(err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed >= arr.length) {
- callback();
- }
- }
- }
- };
- async.forEach = async.each;
-
- async.eachSeries = function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length) {
- return callback();
- }
- var completed = 0;
- var iterate = function () {
- iterator(arr[completed], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- if (completed >= arr.length) {
- callback();
- }
- else {
- iterate();
- }
- }
- });
- };
- iterate();
- };
- async.forEachSeries = async.eachSeries;
-
- async.eachLimit = function (arr, limit, iterator, callback) {
- var fn = _eachLimit(limit);
- fn.apply(null, [arr, iterator, callback]);
- };
- async.forEachLimit = async.eachLimit;
-
- var _eachLimit = function (limit) {
-
- return function (arr, iterator, callback) {
- callback = callback || function () {};
- if (!arr.length || limit <= 0) {
- return callback();
- }
- var completed = 0;
- var started = 0;
- var running = 0;
-
- (function replenish () {
- if (completed >= arr.length) {
- return callback();
- }
-
- while (running < limit && started < arr.length) {
- started += 1;
- running += 1;
- iterator(arr[started - 1], function (err) {
- if (err) {
- callback(err);
- callback = function () {};
- }
- else {
- completed += 1;
- running -= 1;
- if (completed >= arr.length) {
- callback();
- }
- else {
- replenish();
- }
- }
- });
- }
- })();
- };
- };
-
-
- var doParallel = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.each].concat(args));
- };
- };
- var doParallelLimit = function(limit, fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [_eachLimit(limit)].concat(args));
- };
- };
- var doSeries = function (fn) {
- return function () {
- var args = Array.prototype.slice.call(arguments);
- return fn.apply(null, [async.eachSeries].concat(args));
- };
- };
-
-
- var _asyncMap = function (eachfn, arr, iterator, callback) {
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- if (!callback) {
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err) {
- callback(err);
- });
- });
- } else {
- var results = [];
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (err, v) {
- results[x.index] = v;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
- async.map = doParallel(_asyncMap);
- async.mapSeries = doSeries(_asyncMap);
- async.mapLimit = function (arr, limit, iterator, callback) {
- return _mapLimit(limit)(arr, iterator, callback);
- };
-
- var _mapLimit = function(limit) {
- return doParallelLimit(limit, _asyncMap);
- };
-
- // reduce only has a series version, as doing reduce in parallel won't
- // work in many situations.
- async.reduce = function (arr, memo, iterator, callback) {
- async.eachSeries(arr, function (x, callback) {
- iterator(memo, x, function (err, v) {
- memo = v;
- callback(err);
- });
- }, function (err) {
- callback(err, memo);
- });
- };
- // inject alias
- async.inject = async.reduce;
- // foldl alias
- async.foldl = async.reduce;
-
- async.reduceRight = function (arr, memo, iterator, callback) {
- var reversed = _map(arr, function (x) {
- return x;
- }).reverse();
- async.reduce(reversed, memo, iterator, callback);
- };
- // foldr alias
- async.foldr = async.reduceRight;
-
- var _filter = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.filter = doParallel(_filter);
- async.filterSeries = doSeries(_filter);
- // select alias
- async.select = async.filter;
- async.selectSeries = async.filterSeries;
-
- var _reject = function (eachfn, arr, iterator, callback) {
- var results = [];
- arr = _map(arr, function (x, i) {
- return {index: i, value: x};
- });
- eachfn(arr, function (x, callback) {
- iterator(x.value, function (v) {
- if (!v) {
- results.push(x);
- }
- callback();
- });
- }, function (err) {
- callback(_map(results.sort(function (a, b) {
- return a.index - b.index;
- }), function (x) {
- return x.value;
- }));
- });
- };
- async.reject = doParallel(_reject);
- async.rejectSeries = doSeries(_reject);
-
- var _detect = function (eachfn, arr, iterator, main_callback) {
- eachfn(arr, function (x, callback) {
- iterator(x, function (result) {
- if (result) {
- main_callback(x);
- main_callback = function () {};
- }
- else {
- callback();
- }
- });
- }, function (err) {
- main_callback();
- });
- };
- async.detect = doParallel(_detect);
- async.detectSeries = doSeries(_detect);
-
- async.some = function (arr, iterator, main_callback) {
- async.each(arr, function (x, callback) {
- iterator(x, function (v) {
- if (v) {
- main_callback(true);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(false);
- });
- };
- // any alias
- async.any = async.some;
-
- async.every = function (arr, iterator, main_callback) {
- async.each(arr, function (x, callback) {
- iterator(x, function (v) {
- if (!v) {
- main_callback(false);
- main_callback = function () {};
- }
- callback();
- });
- }, function (err) {
- main_callback(true);
- });
- };
- // all alias
- async.all = async.every;
-
- async.sortBy = function (arr, iterator, callback) {
- async.map(arr, function (x, callback) {
- iterator(x, function (err, criteria) {
- if (err) {
- callback(err);
- }
- else {
- callback(null, {value: x, criteria: criteria});
- }
- });
- }, function (err, results) {
- if (err) {
- return callback(err);
- }
- else {
- var fn = function (left, right) {
- var a = left.criteria, b = right.criteria;
- return a < b ? -1 : a > b ? 1 : 0;
- };
- callback(null, _map(results.sort(fn), function (x) {
- return x.value;
- }));
- }
- });
- };
-
- async.auto = function (tasks, callback) {
- callback = callback || function () {};
- var keys = _keys(tasks);
- var remainingTasks = keys.length
- if (!remainingTasks) {
- return callback();
- }
-
- var results = {};
-
- var listeners = [];
- var addListener = function (fn) {
- listeners.unshift(fn);
- };
- var removeListener = function (fn) {
- for (var i = 0; i < listeners.length; i += 1) {
- if (listeners[i] === fn) {
- listeners.splice(i, 1);
- return;
- }
- }
- };
- var taskComplete = function () {
- remainingTasks--
- _each(listeners.slice(0), function (fn) {
- fn();
- });
- };
-
- addListener(function () {
- if (!remainingTasks) {
- var theCallback = callback;
- // prevent final callback from calling itself if it errors
- callback = function () {};
-
- theCallback(null, results);
- }
- });
-
- _each(keys, function (k) {
- var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
- var taskCallback = function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- if (err) {
- var safeResults = {};
- _each(_keys(results), function(rkey) {
- safeResults[rkey] = results[rkey];
- });
- safeResults[k] = args;
- callback(err, safeResults);
- // stop subsequent errors hitting callback multiple times
- callback = function () {};
- }
- else {
- results[k] = args;
- async.setImmediate(taskComplete);
- }
- };
- var requires = task.slice(0, Math.abs(task.length - 1)) || [];
- var ready = function () {
- return _reduce(requires, function (a, x) {
- return (a && results.hasOwnProperty(x));
- }, true) && !results.hasOwnProperty(k);
- };
- if (ready()) {
- task[task.length - 1](taskCallback, results);
- }
- else {
- var listener = function () {
- if (ready()) {
- removeListener(listener);
- task[task.length - 1](taskCallback, results);
- }
- };
- addListener(listener);
- }
- });
- };
-
- async.retry = function(times, task, callback) {
- var DEFAULT_TIMES = 5;
- var attempts = [];
- // Use defaults if times not passed
- if (typeof times === 'function') {
- callback = task;
- task = times;
- times = DEFAULT_TIMES;
- }
- // Make sure times is a number
- times = parseInt(times, 10) || DEFAULT_TIMES;
- var wrappedTask = function(wrappedCallback, wrappedResults) {
- var retryAttempt = function(task, finalAttempt) {
- return function(seriesCallback) {
- task(function(err, result){
- seriesCallback(!err || finalAttempt, {err: err,
result: result});
- }, wrappedResults);
- };
- };
- while (times) {
- attempts.push(retryAttempt(task, !(times-=1)));
- }
- async.series(attempts, function(done, data){
- data = data[data.length - 1];
- (wrappedCallback || callback)(data.err, data.result);
- });
- }
- // If a callback is passed, run this as a controll flow
- return callback ? wrappedTask() : wrappedTask
- };
-
- async.waterfall = function (tasks, callback) {
- callback = callback || function () {};
- if (!_isArray(tasks)) {
- var err = new Error('First argument to waterfall must be an array of
functions');
- return callback(err);
- }
- if (!tasks.length) {
- return callback();
- }
- var wrapIterator = function (iterator) {
- return function (err) {
- if (err) {
- callback.apply(null, arguments);
- callback = function () {};
- }
- else {
- var args = Array.prototype.slice.call(arguments, 1);
- var next = iterator.next();
- if (next) {
- args.push(wrapIterator(next));
- }
- else {
- args.push(callback);
- }
- async.setImmediate(function () {
- iterator.apply(null, args);
- });
- }
- };
- };
- wrapIterator(async.iterator(tasks))();
- };
-
- var _parallel = function(eachfn, tasks, callback) {
- callback = callback || function () {};
- if (_isArray(tasks)) {
- eachfn.map(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- eachfn.each(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.parallel = function (tasks, callback) {
- _parallel({ map: async.map, each: async.each }, tasks, callback);
- };
-
- async.parallelLimit = function(tasks, limit, callback) {
- _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks,
callback);
- };
-
- async.series = function (tasks, callback) {
- callback = callback || function () {};
- if (_isArray(tasks)) {
- async.mapSeries(tasks, function (fn, callback) {
- if (fn) {
- fn(function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- callback.call(null, err, args);
- });
- }
- }, callback);
- }
- else {
- var results = {};
- async.eachSeries(_keys(tasks), function (k, callback) {
- tasks[k](function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (args.length <= 1) {
- args = args[0];
- }
- results[k] = args;
- callback(err);
- });
- }, function (err) {
- callback(err, results);
- });
- }
- };
-
- async.iterator = function (tasks) {
- var makeCallback = function (index) {
- var fn = function () {
- if (tasks.length) {
- tasks[index].apply(null, arguments);
- }
- return fn.next();
- };
- fn.next = function () {
- return (index < tasks.length - 1) ? makeCallback(index + 1):
null;
- };
- return fn;
- };
- return makeCallback(0);
- };
-
- async.apply = function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- return function () {
- return fn.apply(
- null, args.concat(Array.prototype.slice.call(arguments))
- );
- };
- };
-
- var _concat = function (eachfn, arr, fn, callback) {
- var r = [];
- eachfn(arr, function (x, cb) {
- fn(x, function (err, y) {
- r = r.concat(y || []);
- cb(err);
- });
- }, function (err) {
- callback(err, r);
- });
- };
- async.concat = doParallel(_concat);
- async.concatSeries = doSeries(_concat);
-
- async.whilst = function (test, iterator, callback) {
- if (test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.whilst(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.doWhilst = function (iterator, test, callback) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- var args = Array.prototype.slice.call(arguments, 1);
- if (test.apply(null, args)) {
- async.doWhilst(iterator, test, callback);
- }
- else {
- callback();
- }
- });
- };
-
- async.until = function (test, iterator, callback) {
- if (!test()) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- async.until(test, iterator, callback);
- });
- }
- else {
- callback();
- }
- };
-
- async.doUntil = function (iterator, test, callback) {
- iterator(function (err) {
- if (err) {
- return callback(err);
- }
- var args = Array.prototype.slice.call(arguments, 1);
- if (!test.apply(null, args)) {
- async.doUntil(iterator, test, callback);
- }
- else {
- callback();
- }
- });
- };
-
- async.queue = function (worker, concurrency) {
- if (concurrency === undefined) {
- concurrency = 1;
- }
- function _insert(q, data, pos, callback) {
- if (!q.started){
- q.started = true;
- }
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length == 0) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- if (q.drain) {
- q.drain();
- }
- });
- }
- _each(data, function(task) {
- var item = {
- data: task,
- callback: typeof callback === 'function' ? callback : null
- };
-
- if (pos) {
- q.tasks.unshift(item);
- } else {
- q.tasks.push(item);
- }
-
- if (q.saturated && q.tasks.length === q.concurrency) {
- q.saturated();
- }
- async.setImmediate(q.process);
- });
- }
-
- var workers = 0;
- var q = {
- tasks: [],
- concurrency: concurrency,
- saturated: null,
- empty: null,
- drain: null,
- started: false,
- paused: false,
- push: function (data, callback) {
- _insert(q, data, false, callback);
- },
- kill: function () {
- q.drain = null;
- q.tasks = [];
- },
- unshift: function (data, callback) {
- _insert(q, data, true, callback);
- },
- process: function () {
- if (!q.paused && workers < q.concurrency && q.tasks.length) {
- var task = q.tasks.shift();
- if (q.empty && q.tasks.length === 0) {
- q.empty();
- }
- workers += 1;
- var next = function () {
- workers -= 1;
- if (task.callback) {
- task.callback.apply(task, arguments);
- }
- if (q.drain && q.tasks.length + workers === 0) {
- q.drain();
- }
- q.process();
- };
- var cb = only_once(next);
- worker(task.data, cb);
- }
- },
- length: function () {
- return q.tasks.length;
- },
- running: function () {
- return workers;
- },
- idle: function() {
- return q.tasks.length + workers === 0;
- },
- pause: function () {
- if (q.paused === true) { return; }
- q.paused = true;
- q.process();
- },
- resume: function () {
- if (q.paused === false) { return; }
- q.paused = false;
- q.process();
- }
- };
- return q;
- };
-
- async.priorityQueue = function (worker, concurrency) {
-
- function _compareTasks(a, b){
- return a.priority - b.priority;
- };
-
- function _binarySearch(sequence, item, compare) {
- var beg = -1,
- end = sequence.length - 1;
- while (beg < end) {
- var mid = beg + ((end - beg + 1) >>> 1);
- if (compare(item, sequence[mid]) >= 0) {
- beg = mid;
- } else {
- end = mid - 1;
- }
- }
- return beg;
- }
-
- function _insert(q, data, priority, callback) {
- if (!q.started){
- q.started = true;
- }
- if (!_isArray(data)) {
- data = [data];
- }
- if(data.length == 0) {
- // call drain immediately if there are no tasks
- return async.setImmediate(function() {
- if (q.drain) {
- q.drain();
- }
- });
- }
- _each(data, function(task) {
- var item = {
- data: task,
- priority: priority,
- callback: typeof callback === 'function' ? callback : null
- };
-
- q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1,
0, item);
-
- if (q.saturated && q.tasks.length === q.concurrency) {
- q.saturated();
- }
- async.setImmediate(q.process);
- });
- }
-
- // Start with a normal queue
- var q = async.queue(worker, concurrency);
-
- // Override push to accept second parameter representing priority
- q.push = function (data, priority, callback) {
- _insert(q, data, priority, callback);
- };
-
- // Remove unshift function
- delete q.unshift;
-
- return q;
- };
-
- async.cargo = function (worker, payload) {
- var working = false,
- tasks = [];
-
- var cargo = {
- tasks: tasks,
- payload: payload,
- saturated: null,
- empty: null,
- drain: null,
- drained: true,
- push: function (data, callback) {
- if (!_isArray(data)) {
- data = [data];
- }
- _each(data, function(task) {
- tasks.push({
- data: task,
- callback: typeof callback === 'function' ? callback :
null
- });
- cargo.drained = false;
- if (cargo.saturated && tasks.length === payload) {
- cargo.saturated();
- }
- });
- async.setImmediate(cargo.process);
- },
- process: function process() {
- if (working) return;
- if (tasks.length === 0) {
- if(cargo.drain && !cargo.drained) cargo.drain();
- cargo.drained = true;
- return;
- }
-
- var ts = typeof payload === 'number'
- ? tasks.splice(0, payload)
- : tasks.splice(0, tasks.length);
-
- var ds = _map(ts, function (task) {
- return task.data;
- });
-
- if(cargo.empty) cargo.empty();
- working = true;
- worker(ds, function () {
- working = false;
-
- var args = arguments;
- _each(ts, function (data) {
- if (data.callback) {
- data.callback.apply(null, args);
- }
- });
-
- process();
- });
- },
- length: function () {
- return tasks.length;
- },
- running: function () {
- return working;
- }
- };
- return cargo;
- };
-
- var _console_fn = function (name) {
- return function (fn) {
- var args = Array.prototype.slice.call(arguments, 1);
- fn.apply(null, args.concat([function (err) {
- var args = Array.prototype.slice.call(arguments, 1);
- if (typeof console !== 'undefined') {
- if (err) {
- if (console.error) {
- console.error(err);
- }
- }
- else if (console[name]) {
- _each(args, function (x) {
- console[name](x);
- });
- }
- }
- }]));
- };
- };
- async.log = _console_fn('log');
- async.dir = _console_fn('dir');
- /*async.info = _console_fn('info');
- async.warn = _console_fn('warn');
- async.error = _console_fn('error');*/
-
- async.memoize = function (fn, hasher) {
- var memo = {};
- var queues = {};
- hasher = hasher || function (x) {
- return x;
- };
- var memoized = function () {
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- var key = hasher.apply(null, args);
- if (key in memo) {
- async.nextTick(function () {
- callback.apply(null, memo[key]);
- });
- }
- else if (key in queues) {
- queues[key].push(callback);
- }
- else {
- queues[key] = [callback];
- fn.apply(null, args.concat([function () {
- memo[key] = arguments;
- var q = queues[key];
- delete queues[key];
- for (var i = 0, l = q.length; i < l; i++) {
- q[i].apply(null, arguments);
- }
- }]));
- }
- };
- memoized.memo = memo;
- memoized.unmemoized = fn;
- return memoized;
- };
-
- async.unmemoize = function (fn) {
- return function () {
- return (fn.unmemoized || fn).apply(null, arguments);
- };
- };
-
- async.times = function (count, iterator, callback) {
- var counter = [];
- for (var i = 0; i < count; i++) {
- counter.push(i);
- }
- return async.map(counter, iterator, callback);
- };
-
- async.timesSeries = function (count, iterator, callback) {
- var counter = [];
- for (var i = 0; i < count; i++) {
- counter.push(i);
- }
- return async.mapSeries(counter, iterator, callback);
- };
-
- async.seq = function (/* functions... */) {
- var fns = arguments;
- return function () {
- var that = this;
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- async.reduce(fns, args, function (newargs, fn, cb) {
- fn.apply(that, newargs.concat([function () {
- var err = arguments[0];
- var nextargs = Array.prototype.slice.call(arguments, 1);
- cb(err, nextargs);
- }]))
- },
- function (err, results) {
- callback.apply(that, [err].concat(results));
- });
- };
- };
-
- async.compose = function (/* functions... */) {
- return async.seq.apply(null, Array.prototype.reverse.call(arguments));
- };
-
- var _applyEach = function (eachfn, fns /*args...*/) {
- var go = function () {
- var that = this;
- var args = Array.prototype.slice.call(arguments);
- var callback = args.pop();
- return eachfn(fns, function (fn, cb) {
- fn.apply(that, args.concat([cb]));
- },
- callback);
- };
- if (arguments.length > 2) {
- var args = Array.prototype.slice.call(arguments, 2);
- return go.apply(this, args);
- }
- else {
- return go;
- }
- };
- async.applyEach = doParallel(_applyEach);
- async.applyEachSeries = doSeries(_applyEach);
-
- async.forever = function (fn, callback) {
- function next(err) {
- if (err) {
- if (callback) {
- return callback(err);
- }
- throw err;
- }
- fn(next);
- }
- next();
- };
-
- // Node.js
- if (typeof module !== 'undefined' && module.exports) {
- module.exports = async;
- }
- // AMD / RequireJS
- else if (typeof define !== 'undefined' && define.amd) {
- define([], function () {
- return async;
- });
- }
- // included directly via <script> tag
- else {
- root.async = async;
- }
-
-}());
diff --git a/packages/context-coloring/fixtures/benchmark/faces.el
b/packages/context-coloring/fixtures/benchmark/faces.el
deleted file mode 100644
index 5176bed..0000000
--- a/packages/context-coloring/fixtures/benchmark/faces.el
+++ /dev/null
@@ -1,2764 +0,0 @@
-;;; faces.el --- Lisp faces
-
-;; Copyright (C) 1992-1996, 1998-2015 Free Software Foundation, Inc.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: internal
-;; Package: emacs
-
-;; 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:
-
-;;; Code:
-
-(defcustom term-file-prefix (purecopy "term/")
- "If non-nil, Emacs startup performs terminal-specific initialization.
-It does this by: (load (concat term-file-prefix (getenv \"TERM\")))
-
-You may set this variable to nil in your init file if you do not wish
-the terminal-initialization file to be loaded."
- :type '(choice (const :tag "No terminal-specific initialization" nil)
- (string :tag "Name of directory with term files"))
- :group 'terminals)
-
-(declare-function xw-defined-colors "term/common-win" (&optional frame))
-
-(defvar help-xref-stack-item)
-
-(defvar face-name-history nil
- "History list for some commands that read face names.
-Maximum length of the history list is determined by the value
-of `history-length', which see.")
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Font selection.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defgroup font-selection nil
- "Influencing face font selection."
- :group 'faces)
-
-
-(defcustom face-font-selection-order
- '(:width :height :weight :slant)
- "A list specifying how face font selection chooses fonts.
-Each of the four symbols `:width', `:height', `:weight', and `:slant'
-must appear once in the list, and the list must not contain any other
-elements. Font selection first tries to find a best matching font
-for those face attributes that appear before in the list. For
-example, if `:slant' appears before `:height', font selection first
-tries to find a font with a suitable slant, even if this results in
-a font height that isn't optimal."
- :tag "Font selection order"
- :type '(list symbol symbol symbol symbol)
- :group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-font-selection-order value)))
-
-
-;; In the absence of Fontconfig support, Monospace and Sans Serif are
-;; unavailable, and we fall back on the courier and helv families,
-;; which are generally available.
-(defcustom face-font-family-alternatives
- (mapcar (lambda (arg) (mapcar 'purecopy arg))
- '(("Monospace" "courier" "fixed")
- ("courier" "CMU Typewriter Text" "fixed")
- ("Sans Serif" "helv" "helvetica" "arial" "fixed")
- ("helv" "helvetica" "arial" "fixed")))
- "Alist of alternative font family names.
-Each element has the form (FAMILY ALTERNATIVE1 ALTERNATIVE2 ...).
-If fonts of family FAMILY can't be loaded, try ALTERNATIVE1, then
-ALTERNATIVE2 etc."
- :tag "Alternative font families to try"
- :type '(repeat (repeat string))
- :group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-alternative-font-family-alist value)))
-
-
-;; This is defined originally in xfaces.c.
-(defcustom face-font-registry-alternatives
- (mapcar (lambda (arg) (mapcar 'purecopy arg))
- (if (featurep 'w32)
- '(("iso8859-1" "ms-oemlatin")
- ("gb2312.1980" "gb2312" "gbk" "gb18030")
- ("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")
- ("ksc5601.1989" "ksx1001.1992" "ksc5601.1987")
- ("muletibetan-2" "muletibetan-0"))
- '(("gb2312.1980" "gb2312.80&gb8565.88" "gbk" "gb18030")
- ("jisx0208.1990" "jisx0208.1983" "jisx0208.1978")
- ("ksc5601.1989" "ksx1001.1992" "ksc5601.1987")
- ("muletibetan-2" "muletibetan-0"))))
- "Alist of alternative font registry names.
-Each element has the form (REGISTRY ALTERNATIVE1 ALTERNATIVE2 ...).
-If fonts of registry REGISTRY can be loaded, font selection
-tries to find a best matching font among all fonts of registry
-REGISTRY, ALTERNATIVE1, ALTERNATIVE2, and etc."
- :tag "Alternative font registries to try"
- :type '(repeat (repeat string))
- :version "21.1"
- :group 'font-selection
- :set #'(lambda (symbol value)
- (set-default symbol value)
- (internal-set-alternative-font-registry-alist value)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Creation, copying.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun face-list ()
- "Return a list of all defined faces."
- (mapcar #'car face-new-frame-defaults))
-
-(defun make-face (face &optional no-init-from-resources)
- "Define a new face with name FACE, a symbol.
-Do not call this directly from Lisp code; use `defface' instead.
-
-If FACE is already known as a face, leave it unmodified. Return FACE.
-
-NO-INIT-FROM-RESOURCES has been deprecated and is no longer used
-and will go away. Handling of conditional X resources application
-has been pushed down to make-x-resource-internal itself."
- (interactive (list (read-from-minibuffer
- "Make face: " nil nil t 'face-name-history)))
- (unless (facep face)
- ;; Make frame-local faces (this also makes the global one).
- (dolist (frame (frame-list))
- (internal-make-lisp-face face frame))
- ;; Add the face to the face menu.
- (when (fboundp 'facemenu-add-new-face)
- (facemenu-add-new-face face))
- ;; Define frame-local faces for all frames from X resources.
- (make-face-x-resource-internal face))
- face)
-
-;; Handling of whether to apply X resources or not, has been pushed down
-;; to make-face-x-resource-internal itself, thus the optional arg is no
-;; longer evaluated at all and going away.
-(set-advertised-calling-convention 'make-face '(face) "24.4")
-
-(defun make-empty-face (face)
- "Define a new, empty face with name FACE.
-Do not call this directly from Lisp code; use `defface' instead."
- (interactive (list (read-from-minibuffer
- "Make empty face: " nil nil t 'face-name-history)))
- (make-face face))
-
-(defun copy-face (old-face new-face &optional frame new-frame)
- "Define a face named NEW-FACE, which is a copy of OLD-FACE.
-This function does not copy face customization data, so NEW-FACE
-will not be made customizable. Most Lisp code should not call
-this function; use `defface' with :inherit instead.
-
-If NEW-FACE already exists as a face, modify it to be like
-OLD-FACE. If NEW-FACE doesn't already exist, create it.
-
-If the optional argument FRAME is a frame, change NEW-FACE on
-FRAME only. If FRAME is t, copy the frame-independent default
-specification for OLD-FACE to NEW-FACE. If FRAME is nil, copy
-the defaults as well as the faces on each existing frame.
-
-If the optional fourth argument NEW-FRAME is given, copy the
-information from face OLD-FACE on frame FRAME to NEW-FACE on
-frame NEW-FRAME. In this case, FRAME must not be nil."
- (let ((inhibit-quit t))
- (if (null frame)
- (progn
- (when new-frame
- (error "Copying face %s from all frames to one frame"
- old-face))
- (make-empty-face new-face)
- (dolist (frame (frame-list))
- (copy-face old-face new-face frame))
- (copy-face old-face new-face t))
- (make-empty-face new-face)
- (internal-copy-lisp-face old-face new-face frame new-frame))
- new-face))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Predicates, type checks.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun facep (face)
- "Return non-nil if FACE is a face name; nil otherwise.
-A face name can be a string or a symbol."
- (internal-lisp-face-p face))
-
-
-(defun check-face (face)
- "Signal an error if FACE doesn't name a face.
-Value is FACE."
- (unless (facep face)
- (error "Not a face: %s" face))
- face)
-
-
-;; The ID returned is not to be confused with the internally used IDs
-;; of realized faces. The ID assigned to Lisp faces is used to
-;; support faces in display table entries.
-
-(defun face-id (face &optional _frame)
- "Return the internal ID of face with name FACE.
-If FACE is a face-alias, return the ID of the target face.
-The optional argument FRAME is ignored, since the internal face ID
-of a face name is the same for all frames."
- (check-face face)
- (or (get face 'face)
- (face-id (get face 'face-alias))))
-
-(defun face-equal (face1 face2 &optional frame)
- "Non-nil if faces FACE1 and FACE2 are equal.
-Faces are considered equal if all their attributes are equal.
-If the optional argument FRAME is given, report on FACE1 and FACE2 in that
frame.
-If FRAME is t, report on the defaults for FACE1 and FACE2 (for new frames).
-If FRAME is omitted or nil, use the selected frame."
- (internal-lisp-face-equal-p face1 face2 frame))
-
-
-(defun face-differs-from-default-p (face &optional frame)
- "Return non-nil if FACE displays differently from the default face.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame."
- (let ((attrs
- (delq :inherit (mapcar 'car face-attribute-name-alist)))
- (differs nil))
- (while (and attrs (not differs))
- (let* ((attr (pop attrs))
- (attr-val (face-attribute face attr frame t)))
- (when (and
- (not (eq attr-val 'unspecified))
- (display-supports-face-attributes-p (list attr attr-val)
- frame))
- (setq differs attr))))
- differs))
-
-
-(defun face-nontrivial-p (face &optional frame)
- "True if face FACE has some non-nil attribute.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame."
- (not (internal-lisp-face-empty-p face frame)))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Setting face attributes from X resources.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defcustom face-x-resources
- (mapcar
- (lambda (arg)
- ;; FIXME; can we purecopy some of the conses too?
- (cons (car arg)
- (cons (purecopy (car (cdr arg))) (purecopy (cdr (cdr arg))))))
- '((:family (".attributeFamily" . "Face.AttributeFamily"))
- (:foundry (".attributeFoundry" . "Face.AttributeFoundry"))
- (:width (".attributeWidth" . "Face.AttributeWidth"))
- (:height (".attributeHeight" . "Face.AttributeHeight"))
- (:weight (".attributeWeight" . "Face.AttributeWeight"))
- (:slant (".attributeSlant" . "Face.AttributeSlant"))
- (:foreground (".attributeForeground" . "Face.AttributeForeground"))
- (:distant-foreground
- (".attributeDistantForeground" . "Face.AttributeDistantForeground"))
- (:background (".attributeBackground" . "Face.AttributeBackground"))
- (:overline (".attributeOverline" . "Face.AttributeOverline"))
- (:strike-through (".attributeStrikeThrough" .
"Face.AttributeStrikeThrough"))
- (:box (".attributeBox" . "Face.AttributeBox"))
- (:underline (".attributeUnderline" . "Face.AttributeUnderline"))
- (:inverse-video (".attributeInverse" . "Face.AttributeInverse"))
- (:stipple
- (".attributeStipple" . "Face.AttributeStipple")
- (".attributeBackgroundPixmap" . "Face.AttributeBackgroundPixmap"))
- (:bold (".attributeBold" . "Face.AttributeBold"))
- (:italic (".attributeItalic" . "Face.AttributeItalic"))
- (:font (".attributeFont" . "Face.AttributeFont"))
- (:inherit (".attributeInherit" . "Face.AttributeInherit"))))
- "List of X resources and classes for face attributes.
-Each element has the form (ATTRIBUTE ENTRY1 ENTRY2...) where ATTRIBUTE is
-the name of a face attribute, and each ENTRY is a cons of the form
-\(RESOURCE . CLASS) with RESOURCE being the resource and CLASS being the
-X resource class for the attribute."
- :type '(repeat (cons symbol (repeat (cons string string))))
- :group 'faces)
-
-
-(declare-function internal-face-x-get-resource "xfaces.c"
- (resource class &optional frame))
-
-(declare-function internal-set-lisp-face-attribute-from-resource "xfaces.c"
- (face attr value &optional frame))
-
-(defun set-face-attribute-from-resource (face attribute resource class frame)
- "Set FACE's ATTRIBUTE from X resource RESOURCE, class CLASS on FRAME.
-Value is the attribute value specified by the resource, or nil
-if not present. This function displays a message if the resource
-specifies an invalid attribute."
- (let* ((face-name (face-name face))
- (value (internal-face-x-get-resource (concat face-name resource)
- class frame)))
- (when value
- (condition-case ()
- (internal-set-lisp-face-attribute-from-resource
- face attribute (downcase value) frame)
- (error
- (message "Face %s, frame %s: invalid attribute %s %s from X resource"
- face-name frame attribute value))))
- value))
-
-
-(defun set-face-attributes-from-resources (face frame)
- "Set attributes of FACE from X resources for FRAME."
- (when (memq (framep frame) '(x w32))
- (dolist (definition face-x-resources)
- (let ((attribute (car definition)))
- (dolist (entry (cdr definition))
- (set-face-attribute-from-resource face attribute (car entry)
- (cdr entry) frame))))))
-
-
-(defun make-face-x-resource-internal (face &optional frame)
- "Fill frame-local FACE on FRAME from X resources.
-FRAME nil or not specified means do it for all frames.
-
-If `inhibit-x-resources' is non-nil, this function does nothing."
- (unless inhibit-x-resources
- (dolist (frame (if (null frame) (frame-list) (list frame)))
- ;; `x-create-frame' already took care of correctly handling
- ;; the reverse video case-- do _not_ touch the default face
- (unless (and (eq face 'default)
- (frame-parameter frame 'reverse))
- (set-face-attributes-from-resources face frame)))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Retrieving face attributes.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun face-name (face)
- "Return the name of face FACE."
- (symbol-name (check-face face)))
-
-
-(defun face-all-attributes (face &optional frame)
- "Return an alist stating the attributes of FACE.
-Each element of the result has the form (ATTR-NAME . ATTR-VALUE).
-If FRAME is omitted or nil the value describes the default attributes,
-but if you specify FRAME, the value describes the attributes
-of FACE on FRAME."
- (mapcar (lambda (pair)
- (let ((attr (car pair)))
- (cons attr (face-attribute face attr (or frame t)))))
- face-attribute-name-alist))
-
-(defun face-attribute (face attribute &optional frame inherit)
- "Return the value of FACE's ATTRIBUTE on FRAME.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-
-If INHERIT is nil, only attributes directly defined by FACE are considered,
- so the return value may be `unspecified', or a relative value.
-If INHERIT is non-nil, FACE's definition of ATTRIBUTE is merged with the
- faces specified by its `:inherit' attribute; however the return value
- may still be `unspecified' or relative.
-If INHERIT is a face or a list of faces, then the result is further merged
- with that face (or faces), until it becomes specified and absolute.
-
-To ensure that the return value is always specified and absolute, use a
-value of `default' for INHERIT; this will resolve any unspecified or
-relative values by merging with the `default' face (which is always
-completely specified)."
- (let ((value (internal-get-lisp-face-attribute face attribute frame)))
- (when (and inherit (face-attribute-relative-p attribute value))
- ;; VALUE is relative, so merge with inherited faces
- (let ((inh-from (face-attribute face :inherit frame)))
- (unless (or (null inh-from) (eq inh-from 'unspecified))
- (condition-case nil
- (setq value
- (face-attribute-merged-with attribute value inh-from
frame))
- ;; The `inherit' attribute may point to non existent faces.
- (error nil)))))
- (when (and inherit
- (not (eq inherit t))
- (face-attribute-relative-p attribute value))
- ;; We should merge with INHERIT as well
- (setq value (face-attribute-merged-with attribute value inherit frame)))
- value))
-
-(defun face-attribute-merged-with (attribute value faces &optional frame)
- "Merges ATTRIBUTE, initially VALUE, with faces from FACES until absolute.
-FACES may be either a single face or a list of faces.
-\[This is an internal function.]"
- (cond ((not (face-attribute-relative-p attribute value))
- value)
- ((null faces)
- value)
- ((consp faces)
- (face-attribute-merged-with
- attribute
- (face-attribute-merged-with attribute value (car faces) frame)
- (cdr faces)
- frame))
- (t
- (merge-face-attribute attribute
- value
- (face-attribute faces attribute frame t)))))
-
-
-(defmacro face-attribute-specified-or (value &rest body)
- "Return VALUE, unless it's `unspecified', in which case evaluate BODY and
return the result."
- (let ((temp (make-symbol "value")))
- `(let ((,temp ,value))
- (if (not (eq ,temp 'unspecified))
- ,temp
- ,@body))))
-
-(defun face-foreground (face &optional frame inherit)
- "Return the foreground color name of FACE, or nil if unspecified.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-
-If INHERIT is nil, only a foreground color directly defined by FACE is
- considered, so the return value may be nil.
-If INHERIT is t, and FACE doesn't define a foreground color, then any
- foreground color that FACE inherits through its `:inherit' attribute
- is considered as well; however the return value may still be nil.
-If INHERIT is a face or a list of faces, then it is used to try to
- resolve an unspecified foreground color.
-
-To ensure that a valid color is always returned, use a value of
-`default' for INHERIT; this will resolve any unspecified values by
-merging with the `default' face (which is always completely specified)."
- (face-attribute-specified-or (face-attribute face :foreground frame inherit)
- nil))
-
-(defun face-background (face &optional frame inherit)
- "Return the background color name of FACE, or nil if unspecified.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-
-If INHERIT is nil, only a background color directly defined by FACE is
- considered, so the return value may be nil.
-If INHERIT is t, and FACE doesn't define a background color, then any
- background color that FACE inherits through its `:inherit' attribute
- is considered as well; however the return value may still be nil.
-If INHERIT is a face or a list of faces, then it is used to try to
- resolve an unspecified background color.
-
-To ensure that a valid color is always returned, use a value of
-`default' for INHERIT; this will resolve any unspecified values by
-merging with the `default' face (which is always completely specified)."
- (face-attribute-specified-or (face-attribute face :background frame inherit)
- nil))
-
-(defun face-stipple (face &optional frame inherit)
- "Return the stipple pixmap name of FACE, or nil if unspecified.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-
-If INHERIT is nil, only a stipple directly defined by FACE is
- considered, so the return value may be nil.
-If INHERIT is t, and FACE doesn't define a stipple, then any stipple
- that FACE inherits through its `:inherit' attribute is considered as
- well; however the return value may still be nil.
-If INHERIT is a face or a list of faces, then it is used to try to
- resolve an unspecified stipple.
-
-To ensure that a valid stipple or nil is always returned, use a value of
-`default' for INHERIT; this will resolve any unspecified values by merging
-with the `default' face (which is always completely specified)."
- (face-attribute-specified-or (face-attribute face :stipple frame inherit)
- nil))
-
-
-(defalias 'face-background-pixmap 'face-stipple)
-
-
-(defun face-underline-p (face &optional frame inherit)
- "Return non-nil if FACE specifies a non-nil underlining.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-Optional argument INHERIT is passed to `face-attribute'."
- (face-attribute-specified-or
- (face-attribute face :underline frame inherit) nil))
-
-
-(defun face-inverse-video-p (face &optional frame inherit)
- "Return non-nil if FACE specifies a non-nil inverse-video.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-Optional argument INHERIT is passed to `face-attribute'."
- (eq (face-attribute face :inverse-video frame inherit) t))
-
-
-(defun face-bold-p (face &optional frame inherit)
- "Return non-nil if the font of FACE is bold on FRAME.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-Optional argument INHERIT is passed to `face-attribute'.
-Use `face-attribute' for finer control."
- (let ((bold (face-attribute face :weight frame inherit)))
- (memq bold '(semi-bold bold extra-bold ultra-bold))))
-
-
-(defun face-italic-p (face &optional frame inherit)
- "Return non-nil if the font of FACE is italic on FRAME.
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame.
-Optional argument INHERIT is passed to `face-attribute'.
-Use `face-attribute' for finer control."
- (let ((italic (face-attribute face :slant frame inherit)))
- (memq italic '(italic oblique))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Face documentation.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun face-documentation (face)
- "Get the documentation string for FACE.
-If FACE is a face-alias, get the documentation for the target face."
- (let ((alias (get face 'face-alias)))
- (if alias
- (let ((doc (get alias 'face-documentation)))
- (format "%s is an alias for the face `%s'.%s" face alias
- (if doc (format "\n%s" doc)
- "")))
- (get face 'face-documentation))))
-
-
-(defun set-face-documentation (face string)
- "Set the documentation string for FACE to STRING."
- ;; Perhaps the text should go in DOC.
- (put face 'face-documentation (purecopy string)))
-
-
-(defalias 'face-doc-string 'face-documentation)
-(defalias 'set-face-doc-string 'set-face-documentation)
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Setting face attributes.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defun set-face-attribute (face frame &rest args)
- "Set attributes of FACE on FRAME from ARGS.
-This function overrides the face attributes specified by FACE's
-face spec. It is mostly intended for internal use only.
-
-If FRAME is nil, set the attributes for all existing frames, as
-well as the default for new frames. If FRAME is t, change the
-default for new frames only.
-
-ARGS must come in pairs ATTRIBUTE VALUE. ATTRIBUTE must be a
-valid face attribute name. All attributes can be set to
-`unspecified'; this fact is not further mentioned below.
-
-The following attributes are recognized:
-
-`:family'
-
-VALUE must be a string specifying the font family
-\(e.g. \"Monospace\") or a fontset.
-
-`:foundry'
-
-VALUE must be a string specifying the font foundry,
-e.g. ``adobe''. If a font foundry is specified, wild-cards `*'
-and `?' are allowed.
-
-`:width'
-
-VALUE specifies the relative proportionate width of the font to use.
-It must be one of the symbols `ultra-condensed', `extra-condensed',
-`condensed', `semi-condensed', `normal', `semi-expanded', `expanded',
-`extra-expanded', or `ultra-expanded'.
-
-`:height'
-
-VALUE specifies the relative or absolute height of the font. An
-absolute height is an integer, and specifies font height in units
-of 1/10 pt. A relative height is either a floating point number,
-which specifies a scaling factor for the underlying face height;
-or a function that takes a single argument (the underlying face
-height) and returns the new height. Note that for the `default'
-face, you must specify an absolute height (since there is nothing
-for it to be relative to).
-
-`:weight'
-
-VALUE specifies the weight of the font to use. It must be one of the
-symbols `ultra-bold', `extra-bold', `bold', `semi-bold', `normal',
-`semi-light', `light', `extra-light', `ultra-light'.
-
-`:slant'
-
-VALUE specifies the slant of the font to use. It must be one of the
-symbols `italic', `oblique', `normal', `reverse-italic', or
-`reverse-oblique'.
-
-`:foreground', `:background'
-
-VALUE must be a color name, a string.
-
-`:underline'
-
-VALUE specifies whether characters in FACE should be underlined.
-If VALUE is t, underline with foreground color of the face.
-If VALUE is a string, underline with that color.
-If VALUE is nil, explicitly don't underline.
-
-Otherwise, VALUE must be a property list of the form:
-
-`(:color COLOR :style STYLE)'.
-
-COLOR can be a either a color name string or `foreground-color'.
-STYLE can be either `line' or `wave'.
-If a keyword/value pair is missing from the property list, a
-default value will be used for the value.
-The default value of COLOR is the foreground color of the face.
-The default value of STYLE is `line'.
-
-`:overline'
-
-VALUE specifies whether characters in FACE should be overlined. If
-VALUE is t, overline with foreground color of the face. If VALUE is a
-string, overline with that color. If VALUE is nil, explicitly don't
-overline.
-
-`:strike-through'
-
-VALUE specifies whether characters in FACE should be drawn with a line
-striking through them. If VALUE is t, use the foreground color of the
-face. If VALUE is a string, strike-through with that color. If VALUE
-is nil, explicitly don't strike through.
-
-`:box'
-
-VALUE specifies whether characters in FACE should have a box drawn
-around them. If VALUE is nil, explicitly don't draw boxes. If
-VALUE is t, draw a box with lines of width 1 in the foreground color
-of the face. If VALUE is a string, the string must be a color name,
-and the box is drawn in that color with a line width of 1. Otherwise,
-VALUE must be a property list of the form `(:line-width WIDTH
-:color COLOR :style STYLE)'. If a keyword/value pair is missing from
-the property list, a default value will be used for the value, as
-specified below. WIDTH specifies the width of the lines to draw; it
-defaults to 1. If WIDTH is negative, the absolute value is the width
-of the lines, and draw top/bottom lines inside the characters area,
-not around it. COLOR is the name of the color to draw in, default is
-the foreground color of the face for simple boxes, and the background
-color of the face for 3D boxes. STYLE specifies whether a 3D box
-should be draw. If STYLE is `released-button', draw a box looking
-like a released 3D button. If STYLE is `pressed-button' draw a box
-that appears like a pressed button. If STYLE is nil, the default if
-the property list doesn't contain a style specification, draw a 2D
-box.
-
-`:inverse-video'
-
-VALUE specifies whether characters in FACE should be displayed in
-inverse video. VALUE must be one of t or nil.
-
-`:stipple'
-
-If VALUE is a string, it must be the name of a file of pixmap data.
-The directories listed in the `x-bitmap-file-path' variable are
-searched. Alternatively, VALUE may be a list of the form (WIDTH
-HEIGHT DATA) where WIDTH and HEIGHT are the size in pixels, and DATA
-is a string containing the raw bits of the bitmap. VALUE nil means
-explicitly don't use a stipple pattern.
-
-For convenience, attributes `:family', `:foundry', `:width',
-`:height', `:weight', and `:slant' may also be set in one step
-from an X font name:
-
-`:font'
-
-Set font-related face attributes from VALUE. VALUE must be a
-valid font name or font object. Setting this attribute will also
-set the `:family', `:foundry', `:width', `:height', `:weight',
-and `:slant' attributes.
-
-`:inherit'
-
-VALUE is the name of a face from which to inherit attributes, or
-a list of face names. Attributes from inherited faces are merged
-into the face like an underlying face would be, with higher
-priority than underlying faces.
-
-For backward compatibility, the keywords `:bold' and `:italic'
-can be used to specify weight and slant respectively. This usage
-is considered obsolete. For these two keywords, the VALUE must
-be either t or nil. A value of t for `:bold' is equivalent to
-setting `:weight' to `bold', and a value of t for `:italic' is
-equivalent to setting `:slant' to `italic'. But if `:weight' is
-specified in the face spec, `:bold' is ignored, and if `:slant'
-is specified, `:italic' is ignored."
- (setq args (purecopy args))
- (let ((where (if (null frame) 0 frame))
- (spec args)
- family foundry)
- ;; If we set the new-frame defaults, this face is modified outside Custom.
- (if (memq where '(0 t))
- (put (or (get face 'face-alias) face) 'face-modified t))
- ;; If family and/or foundry are specified, set it first. Certain
- ;; face attributes, e.g. :weight semi-condensed, are not supported
- ;; in every font. See bug#1127.
- (while spec
- (cond ((eq (car spec) :family)
- (setq family (cadr spec)))
- ((eq (car spec) :foundry)
- (setq foundry (cadr spec))))
- (setq spec (cddr spec)))
- (when (or family foundry)
- (when (and (stringp family)
- (string-match "\\([^-]*\\)-\\([^-]*\\)" family))
- (unless foundry
- (setq foundry (match-string 1 family)))
- (setq family (match-string 2 family)))
- (when (or (stringp family) (eq family 'unspecified))
- (internal-set-lisp-face-attribute face :family (purecopy family)
- where))
- (when (or (stringp foundry) (eq foundry 'unspecified))
- (internal-set-lisp-face-attribute face :foundry (purecopy foundry)
- where)))
- (while args
- (unless (memq (car args) '(:family :foundry))
- (internal-set-lisp-face-attribute face (car args)
- (purecopy (cadr args))
- where))
- (setq args (cddr args)))))
-
-(defun make-face-bold (face &optional frame _noerror)
- "Make the font of FACE be bold, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
-Use `set-face-attribute' for finer control of the font weight."
- (interactive (list (read-face-name "Make which face bold"
- (face-at-point t))))
- (set-face-attribute face frame :weight 'bold))
-
-
-(defun make-face-unbold (face &optional frame _noerror)
- "Make the font of FACE be non-bold, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
- (interactive (list (read-face-name "Make which face non-bold"
- (face-at-point t))))
- (set-face-attribute face frame :weight 'normal))
-
-
-(defun make-face-italic (face &optional frame _noerror)
- "Make the font of FACE be italic, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
-Use `set-face-attribute' for finer control of the font slant."
- (interactive (list (read-face-name "Make which face italic"
- (face-at-point t))))
- (set-face-attribute face frame :slant 'italic))
-
-
-(defun make-face-unitalic (face &optional frame _noerror)
- "Make the font of FACE be non-italic, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility."
- (interactive (list (read-face-name "Make which face non-italic"
- (face-at-point t))))
- (set-face-attribute face frame :slant 'normal))
-
-
-(defun make-face-bold-italic (face &optional frame _noerror)
- "Make the font of FACE be bold and italic, if possible.
-FRAME nil or not specified means change face on all frames.
-Argument NOERROR is ignored and retained for compatibility.
-Use `set-face-attribute' for finer control of font weight and slant."
- (interactive (list (read-face-name "Make which face bold-italic"
- (face-at-point t))))
- (set-face-attribute face frame :weight 'bold :slant 'italic))
-
-
-(defun set-face-font (face font &optional frame)
- "Change font-related attributes of FACE to those of FONT (a string).
-FRAME nil or not specified means change face on all frames.
-This sets the attributes `:family', `:foundry', `:width',
-`:height', `:weight', and `:slant'. When called interactively,
-prompt for the face and font."
- (interactive (read-face-and-attribute :font))
- (set-face-attribute face frame :font font))
-
-
-;; Implementation note: Emulating gray background colors with a
-;; stipple pattern is now part of the face realization process, and is
-;; done in C depending on the frame on which the face is realized.
-
-(defun set-face-background (face color &optional frame)
- "Change the background color of face FACE to COLOR (a string).
-FRAME nil or not specified means change face on all frames.
-COLOR can be a system-defined color name (see `list-colors-display')
-or a hex spec of the form #RRGGBB.
-When called interactively, prompts for the face and color."
- (interactive (read-face-and-attribute :background))
- (set-face-attribute face frame :background (or color 'unspecified)))
-
-
-(defun set-face-foreground (face color &optional frame)
- "Change the foreground color of face FACE to COLOR (a string).
-FRAME nil or not specified means change face on all frames.
-COLOR can be a system-defined color name (see `list-colors-display')
-or a hex spec of the form #RRGGBB.
-When called interactively, prompts for the face and color."
- (interactive (read-face-and-attribute :foreground))
- (set-face-attribute face frame :foreground (or color 'unspecified)))
-
-
-(defun set-face-stipple (face stipple &optional frame)
- "Change the stipple pixmap of face FACE to STIPPLE.
-FRAME nil or not specified means change face on all frames.
-STIPPLE should be a string, the name of a file of pixmap data.
-The directories listed in the `x-bitmap-file-path' variable are searched.
-
-Alternatively, STIPPLE may be a list of the form (WIDTH HEIGHT DATA)
-where WIDTH and HEIGHT are the size in pixels,
-and DATA is a string, containing the raw bits of the bitmap."
- (interactive (read-face-and-attribute :stipple))
- (set-face-attribute face frame :stipple (or stipple 'unspecified)))
-
-
-(defun set-face-underline (face underline &optional frame)
- "Specify whether face FACE is underlined.
-UNDERLINE nil means FACE explicitly doesn't underline.
-UNDERLINE t means FACE underlines with its foreground color.
-If UNDERLINE is a string, underline with that color.
-
-UNDERLINE may also be a list of the form (:color COLOR :style STYLE),
-where COLOR is a string or `foreground-color', and STYLE is either
-`line' or `wave'. :color may be omitted, which means to use the
-foreground color. :style may be omitted, which means to use a line.
-
-FRAME nil or not specified means change face on all frames.
-Use `set-face-attribute' to ``unspecify'' underlining."
- (interactive (read-face-and-attribute :underline))
- (set-face-attribute face frame :underline underline))
-
-(define-obsolete-function-alias 'set-face-underline-p
- 'set-face-underline "24.3")
-
-
-(defun set-face-inverse-video (face inverse-video-p &optional frame)
- "Specify whether face FACE is in inverse video.
-INVERSE-VIDEO-P non-nil means FACE displays explicitly in inverse video.
-INVERSE-VIDEO-P nil means FACE explicitly is not in inverse video.
-FRAME nil or not specified means change face on all frames.
-Use `set-face-attribute' to ``unspecify'' the inverse video attribute."
- (interactive
- (let ((list (read-face-and-attribute :inverse-video)))
- (list (car list) (if (cadr list) t))))
- (set-face-attribute face frame :inverse-video inverse-video-p))
-
-(define-obsolete-function-alias 'set-face-inverse-video-p
- 'set-face-inverse-video "24.4")
-
-(defun set-face-bold (face bold-p &optional frame)
- "Specify whether face FACE is bold.
-BOLD-P non-nil means FACE should explicitly display bold.
-BOLD-P nil means FACE should explicitly display non-bold.
-FRAME nil or not specified means change face on all frames.
-Use `set-face-attribute' or `modify-face' for finer control."
- (if (null bold-p)
- (make-face-unbold face frame)
- (make-face-bold face frame)))
-
-(define-obsolete-function-alias 'set-face-bold-p 'set-face-bold "24.4")
-
-
-(defun set-face-italic (face italic-p &optional frame)
- "Specify whether face FACE is italic.
-ITALIC-P non-nil means FACE should explicitly display italic.
-ITALIC-P nil means FACE should explicitly display non-italic.
-FRAME nil or not specified means change face on all frames.
-Use `set-face-attribute' or `modify-face' for finer control."
- (if (null italic-p)
- (make-face-unitalic face frame)
- (make-face-italic face frame)))
-
-(define-obsolete-function-alias 'set-face-italic-p 'set-face-italic "24.4")
-
-
-(defalias 'set-face-background-pixmap 'set-face-stipple)
-
-
-(defun invert-face (face &optional frame)
- "Swap the foreground and background colors of FACE.
-If FRAME is omitted or nil, it means change face on all frames.
-If FACE specifies neither foreground nor background color,
-set its foreground and background to the background and foreground
-of the default face. Value is FACE."
- (interactive (list (read-face-name "Invert face" (face-at-point t))))
- (let ((fg (face-attribute face :foreground frame))
- (bg (face-attribute face :background frame)))
- (if (not (and (eq fg 'unspecified) (eq bg 'unspecified)))
- (set-face-attribute face frame :foreground bg :background fg)
- (set-face-attribute face frame
- :foreground
- (face-attribute 'default :background frame)
- :background
- (face-attribute 'default :foreground frame))))
- face)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Interactively modifying faces.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar crm-separator) ; from crm.el
-
-(defun read-face-name (prompt &optional default multiple)
- "Read one or more face names, prompting with PROMPT.
-PROMPT should not end in a space or a colon.
-
-Return DEFAULT if the user enters the empty string.
-If DEFAULT is non-nil, it should be a single face or a list of face names
-\(symbols or strings). In the latter case, return the `car' of DEFAULT
-\(if MULTIPLE is nil, see below), or DEFAULT (if MULTIPLE is non-nil).
-
-If MULTIPLE is non-nil, this function uses `completing-read-multiple'
-to read multiple faces with \"[ \\t]*,[ \\t]*\" as the separator regexp
-and it returns a list of face names. Otherwise, it reads and returns
-a single face name."
- (if (and default (not (stringp default)))
- (setq default
- (cond ((symbolp default)
- (symbol-name default))
- (multiple
- (mapconcat (lambda (f) (if (symbolp f) (symbol-name f) f))
- default ", "))
- ;; If we only want one, and the default is more than one,
- ;; discard the unwanted ones.
- (t (symbol-name (car default))))))
- (when (and default (not multiple))
- (require 'crm)
- ;; For compatibility with `completing-read-multiple' use `crm-separator'
- ;; to define DEFAULT if MULTIPLE is nil.
- (setq default (car (split-string default crm-separator t))))
-
- (let ((prompt (if default
- (format "%s (default `%s'): " prompt default)
- (format "%s: " prompt)))
- aliasfaces nonaliasfaces faces)
- ;; Build up the completion tables.
- (mapatoms (lambda (s)
- (if (facep s)
- (if (get s 'face-alias)
- (push (symbol-name s) aliasfaces)
- (push (symbol-name s) nonaliasfaces)))))
- (if multiple
- (progn
- (dolist (face (completing-read-multiple
- prompt
- (completion-table-in-turn nonaliasfaces aliasfaces)
- nil t nil 'face-name-history default))
- ;; Ignore elements that are not faces
- ;; (for example, because DEFAULT was "all faces")
- (if (facep face) (push (intern face) faces)))
- (nreverse faces))
- (let ((face (completing-read
- prompt
- (completion-table-in-turn nonaliasfaces aliasfaces)
- nil t nil 'face-name-history default)))
- (if (facep face) (intern face))))))
-
-;; Not defined without X, but behind window-system test.
-(defvar x-bitmap-file-path)
-
-(defun face-valid-attribute-values (attribute &optional frame)
- "Return valid values for face attribute ATTRIBUTE.
-The optional argument FRAME is used to determine available fonts
-and colors. If it is nil or not specified, the selected frame is used.
-Value is an alist of (NAME . VALUE) if ATTRIBUTE expects a value out
-of a set of discrete values. Value is `integerp' if ATTRIBUTE expects
-an integer value."
- (let ((valid
- (pcase attribute
- (`:family
- (if (window-system frame)
- (mapcar (lambda (x) (cons x x))
- (font-family-list))
- ;; Only one font on TTYs.
- (list (cons "default" "default"))))
- (`:foundry
- (list nil))
- (`:width
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
- font-width-table))
- (`:weight
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
- font-weight-table))
- (`:slant
- (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1)))
- font-slant-table))
- (`:inverse-video
- (mapcar #'(lambda (x) (cons (symbol-name x) x))
- (internal-lisp-face-attribute-values attribute)))
- ((or `:underline `:overline `:strike-through `:box)
- (if (window-system frame)
- (nconc (mapcar #'(lambda (x) (cons (symbol-name x) x))
- (internal-lisp-face-attribute-values attribute))
- (mapcar #'(lambda (c) (cons c c))
- (defined-colors frame)))
- (mapcar #'(lambda (x) (cons (symbol-name x) x))
- (internal-lisp-face-attribute-values attribute))))
- ((or `:foreground `:background)
- (mapcar #'(lambda (c) (cons c c))
- (defined-colors frame)))
- (`:height
- 'integerp)
- (`:stipple
- (and (memq (window-system frame) '(x ns)) ; No stipple on w32
- (mapcar #'list
- (apply #'nconc
- (mapcar (lambda (dir)
- (and (file-readable-p dir)
- (file-directory-p dir)
- (directory-files dir)))
- x-bitmap-file-path)))))
- (`:inherit
- (cons '("none" . nil)
- (mapcar #'(lambda (c) (cons (symbol-name c) c))
- (face-list))))
- (_
- (error "Internal error")))))
- (if (and (listp valid) (not (memq attribute '(:inherit))))
- (nconc (list (cons "unspecified" 'unspecified)) valid)
- valid)))
-
-
-(defconst face-attribute-name-alist
- '((:family . "font family")
- (:foundry . "font foundry")
- (:width . "character set width")
- (:height . "height in 1/10 pt")
- (:weight . "weight")
- (:slant . "slant")
- (:underline . "underline")
- (:overline . "overline")
- (:strike-through . "strike-through")
- (:box . "box")
- (:inverse-video . "inverse-video display")
- (:foreground . "foreground color")
- (:background . "background color")
- (:stipple . "background stipple")
- (:inherit . "inheritance"))
- "An alist of descriptive names for face attributes.
-Each element has the form (ATTRIBUTE-NAME . DESCRIPTION) where
-ATTRIBUTE-NAME is a face attribute name (a keyword symbol), and
-DESCRIPTION is a descriptive name for ATTRIBUTE-NAME.")
-
-
-(defun face-descriptive-attribute-name (attribute)
- "Return a descriptive name for ATTRIBUTE."
- (cdr (assq attribute face-attribute-name-alist)))
-
-
-(defun face-read-string (face default name &optional completion-alist)
- "Interactively read a face attribute string value.
-FACE is the face whose attribute is read. If non-nil, DEFAULT is the
-default string to return if no new value is entered. NAME is a
-descriptive name of the attribute for prompting. COMPLETION-ALIST is an
-alist of valid values, if non-nil.
-
-Entering nothing accepts the default string DEFAULT.
-Value is the new attribute value."
- ;; Capitalize NAME (we don't use `capitalize' because that capitalizes
- ;; each word in a string separately).
- (setq name (concat (upcase (substring name 0 1)) (substring name 1)))
- (let* ((completion-ignore-case t)
- (value (completing-read
- (if default
- (format "%s for face `%s' (default %s): "
- name face default)
- (format "%s for face `%s': " name face))
- completion-alist nil nil nil nil default)))
- (if (equal value "") default value)))
-
-
-(defun face-read-integer (face default name)
- "Interactively read an integer face attribute value.
-FACE is the face whose attribute is read. DEFAULT is the default
-value to return if no new value is entered. NAME is a descriptive
-name of the attribute for prompting. Value is the new attribute value."
- (let ((new-value
- (face-read-string face
- (format "%s" default)
- name
- (list (cons "unspecified" 'unspecified)))))
- (cond ((equal new-value "unspecified")
- 'unspecified)
- ((member new-value '("unspecified-fg" "unspecified-bg"))
- new-value)
- (t
- (string-to-number new-value)))))
-
-
-;; FIXME this does allow you to enter the list forms of :box,
-;; :stipple, or :underline, because face-valid-attribute-values does
-;; not return those forms.
-(defun read-face-attribute (face attribute &optional frame)
- "Interactively read a new value for FACE's ATTRIBUTE.
-Optional argument FRAME nil or unspecified means read an attribute value
-of a global face. Value is the new attribute value."
- (let* ((old-value (face-attribute face attribute frame))
- (attribute-name (face-descriptive-attribute-name attribute))
- (valid (face-valid-attribute-values attribute frame))
- new-value)
- ;; Represent complex attribute values as strings by printing them
- ;; out. Stipple can be a vector; (WIDTH HEIGHT DATA). Box can be
- ;; a list `(:width WIDTH :color COLOR)' or `(:width WIDTH :shadow
- ;; SHADOW)'. Underline can be `(:color COLOR :style STYLE)'.
- (and (memq attribute '(:box :stipple :underline))
- (or (consp old-value)
- (vectorp old-value))
- (setq old-value (prin1-to-string old-value)))
- (cond ((listp valid)
- (let ((default
- (or (car (rassoc old-value valid))
- (format "%s" old-value))))
- (setq new-value
- (face-read-string face default attribute-name valid))
- (if (equal new-value default)
- ;; Nothing changed, so don't bother with all the stuff
- ;; below. In particular, this avoids a non-tty color
- ;; from being canonicalized for a tty when the user
- ;; just uses the default.
- (setq new-value old-value)
- ;; Terminal frames can support colors that don't appear
- ;; explicitly in VALID, using color approximation code
- ;; in tty-colors.el.
- (when (and (memq attribute '(:foreground :background))
- (not (memq (window-system frame) '(x w32 ns)))
- (not (member new-value
- '("unspecified"
- "unspecified-fg" "unspecified-bg"))))
- (setq new-value (car (tty-color-desc new-value frame))))
- (when (assoc new-value valid)
- (setq new-value (cdr (assoc new-value valid)))))))
- ((eq valid 'integerp)
- (setq new-value (face-read-integer face old-value attribute-name)))
- (t (error "Internal error")))
- ;; Convert stipple and box value text we read back to a list or
- ;; vector if it looks like one. This makes the assumption that a
- ;; pixmap file name won't start with an open-paren.
- (and (memq attribute '(:stipple :box :underline))
- (stringp new-value)
- (string-match-p "^[[(]" new-value)
- (setq new-value (read new-value)))
- new-value))
-
-(declare-function fontset-list "fontset.c" ())
-(declare-function x-list-fonts "xfaces.c"
- (pattern &optional face frame maximum width))
-
-(defun read-face-font (face &optional frame)
- "Read the name of a font for FACE on FRAME.
-If optional argument FRAME is nil or omitted, use the selected frame."
- (let ((completion-ignore-case t))
- (completing-read (format "Set font attributes of face `%s' from font: "
face)
- (append (fontset-list) (x-list-fonts "*" nil frame)))))
-
-
-(defun read-all-face-attributes (face &optional frame)
- "Interactively read all attributes for FACE.
-If optional argument FRAME is nil or omitted, use the selected frame.
-Value is a property list of attribute names and new values."
- (let (result)
- (dolist (attribute face-attribute-name-alist result)
- (setq result (cons (car attribute)
- (cons (read-face-attribute face (car attribute) frame)
- result))))))
-
-(defun modify-face (&optional face foreground background stipple
- bold-p italic-p underline inverse-p frame)
- "Modify attributes of faces interactively.
-If optional argument FRAME is nil or omitted, modify the face used
-for newly created frame, i.e. the global face.
-For non-interactive use, `set-face-attribute' is preferred.
-When called from Lisp, if FACE is nil, all arguments but FRAME are ignored
-and the face and its settings are obtained by querying the user."
- (interactive)
- (if face
- (set-face-attribute face frame
- :foreground (or foreground 'unspecified)
- :background (or background 'unspecified)
- :stipple stipple
- :weight (if bold-p 'bold 'normal)
- :slant (if italic-p 'italic 'normal)
- :underline underline
- :inverse-video inverse-p)
- (setq face (read-face-name "Modify face" (face-at-point t)))
- (apply #'set-face-attribute face frame
- (read-all-face-attributes face frame))))
-
-(defun read-face-and-attribute (attribute &optional frame)
- "Read face name and face attribute value.
-ATTRIBUTE is the attribute whose new value is read.
-FRAME nil or unspecified means read attribute value of global face.
-Value is a list (FACE NEW-VALUE) where FACE is the face read
-\(a symbol), and NEW-VALUE is value read."
- (cond ((eq attribute :font)
- (let* ((prompt "Set font-related attributes of face")
- (face (read-face-name prompt (face-at-point t)))
- (font (read-face-font face frame)))
- (list face font)))
- (t
- (let* ((attribute-name (face-descriptive-attribute-name attribute))
- (prompt (format "Set %s of face" attribute-name))
- (face (read-face-name prompt (face-at-point t)))
- (new-value (read-face-attribute face attribute frame)))
- (list face new-value)))))
-
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Listing faces.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defconst list-faces-sample-text
- "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "Text string to display as the sample text for `list-faces-display'.")
-
-
-;; The name list-faces would be more consistent, but let's avoid a
-;; conflict with Lucid, which uses that name differently.
-
-(defvar help-xref-stack)
-(defun list-faces-display (&optional regexp)
- "List all faces, using the same sample text in each.
-The sample text is a string that comes from the variable
-`list-faces-sample-text'.
-
-If REGEXP is non-nil, list only those faces with names matching
-this regular expression. When called interactively with a prefix
-argument, prompt for a regular expression using `read-regexp'."
- (interactive (list (and current-prefix-arg
- (read-regexp "List faces matching regexp"))))
- (let ((all-faces (zerop (length regexp)))
- (frame (selected-frame))
- (max-length 0)
- faces line-format
- disp-frame window face-name)
- ;; We filter and take the max length in one pass
- (setq faces
- (delq nil
- (mapcar (lambda (f)
- (let ((s (symbol-name f)))
- (when (or all-faces (string-match-p regexp s))
- (setq max-length (max (length s) max-length))
- f)))
- (sort (face-list) #'string-lessp))))
- (unless faces
- (error "No faces matching \"%s\"" regexp))
- (setq max-length (1+ max-length)
- line-format (format "%%-%ds" max-length))
- (with-help-window "*Faces*"
- (with-current-buffer standard-output
- (setq truncate-lines t)
- (insert
- (substitute-command-keys
- (concat
- "\\<help-mode-map>Use "
- (if (display-mouse-p) "\\[help-follow-mouse] or ")
- "\\[help-follow] on a face name to customize it\n"
- "or on its sample text for a description of the face.\n\n")))
- (setq help-xref-stack nil)
- (dolist (face faces)
- (setq face-name (symbol-name face))
- (insert (format line-format face-name))
- ;; Hyperlink to a customization buffer for the face. Using
- ;; the help xref mechanism may not be the best way.
- (save-excursion
- (save-match-data
- (search-backward face-name)
- (setq help-xref-stack-item `(list-faces-display ,regexp))
- (help-xref-button 0 'help-customize-face face)))
- (let ((beg (point))
- (line-beg (line-beginning-position)))
- (insert list-faces-sample-text)
- ;; Hyperlink to a help buffer for the face.
- (save-excursion
- (save-match-data
- (search-backward list-faces-sample-text)
- (help-xref-button 0 'help-face face)))
- (insert "\n")
- (put-text-property beg (1- (point)) 'face face)
- ;; Make all face commands default to the proper face
- ;; anywhere in the line.
- (put-text-property line-beg (1- (point)) 'read-face-name face)
- ;; If the sample text has multiple lines, line up all of them.
- (goto-char beg)
- (forward-line 1)
- (while (not (eobp))
- (insert-char ?\s max-length)
- (forward-line 1))))
- (goto-char (point-min))))
- ;; If the *Faces* buffer appears in a different frame,
- ;; copy all the face definitions from FRAME,
- ;; so that the display will reflect the frame that was selected.
- (setq window (get-buffer-window (get-buffer "*Faces*") t))
- (setq disp-frame (if window (window-frame window)
- (car (frame-list))))
- (or (eq frame disp-frame)
- (dolist (face (face-list))
- (copy-face face face frame disp-frame)))))
-
-
-(defun describe-face (face &optional frame)
- "Display the properties of face FACE on FRAME.
-Interactively, FACE defaults to the faces of the character after point
-and FRAME defaults to the selected frame.
-
-If the optional argument FRAME is given, report on face FACE in that frame.
-If FRAME is t, report on the defaults for face FACE (for new frames).
-If FRAME is omitted or nil, use the selected frame."
- (interactive (list (read-face-name "Describe face"
- (or (face-at-point t) 'default)
- t)))
- (let* ((attrs '((:family . "Family")
- (:foundry . "Foundry")
- (:width . "Width")
- (:height . "Height")
- (:weight . "Weight")
- (:slant . "Slant")
- (:foreground . "Foreground")
- (:distant-foreground . "DistantForeground")
- (:background . "Background")
- (:underline . "Underline")
- (:overline . "Overline")
- (:strike-through . "Strike-through")
- (:box . "Box")
- (:inverse-video . "Inverse")
- (:stipple . "Stipple")
- (:font . "Font")
- (:fontset . "Fontset")
- (:inherit . "Inherit")))
- (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x)))
- attrs))))
- (help-setup-xref (list #'describe-face face)
- (called-interactively-p 'interactive))
- (unless face
- (setq face 'default))
- (if (not (listp face))
- (setq face (list face)))
- (with-help-window (help-buffer)
- (with-current-buffer standard-output
- (dolist (f face)
- (if (stringp f) (setq f (intern f)))
- ;; We may get called for anonymous faces (i.e., faces
- ;; expressed using prop-value plists). Those can't be
- ;; usefully customized, so ignore them.
- (when (symbolp f)
- (insert "Face: " (symbol-name f))
- (if (not (facep f))
- (insert " undefined face.\n")
- (let ((customize-label "customize this face")
- file-name)
- (insert (concat " (" (propertize "sample" 'font-lock-face f)
")"))
- (princ (concat " (" customize-label ")\n"))
- ;; FIXME not sure how much of this belongs here, and
- ;; how much in `face-documentation'. The latter is
- ;; not used much, but needs to return nil for
- ;; undocumented faces.
- (let ((alias (get f 'face-alias))
- (face f)
- obsolete)
- (when alias
- (setq face alias)
- (insert
- (format "\n %s is an alias for the face `%s'.\n%s"
- f alias
- (if (setq obsolete (get f 'obsolete-face))
- (format " This face is obsolete%s; use `%s'
instead.\n"
- (if (stringp obsolete)
- (format " since %s" obsolete)
- "")
- alias)
- ""))))
- (insert "\nDocumentation:\n"
- (or (face-documentation face)
- "Not documented as a face.")
- "\n\n"))
- (with-current-buffer standard-output
- (save-excursion
- (re-search-backward
- (concat "\\(" customize-label "\\)") nil t)
- (help-xref-button 1 'help-customize-face f)))
- (setq file-name (find-lisp-object-file-name f 'defface))
- (when file-name
- (princ "Defined in `")
- (princ (file-name-nondirectory file-name))
- (princ "'")
- ;; Make a hyperlink to the library.
- (save-excursion
- (re-search-backward "`\\([^`']+\\)'" nil t)
- (help-xref-button 1 'help-face-def f file-name))
- (princ ".")
- (terpri)
- (terpri))
- (dolist (a attrs)
- (let ((attr (face-attribute f (car a) frame)))
- (insert (make-string (- max-width (length (cdr a))) ?\s)
- (cdr a) ": " (format "%s" attr))
- (if (and (eq (car a) :inherit)
- (not (eq attr 'unspecified)))
- ;; Make a hyperlink to the parent face.
- (save-excursion
- (re-search-backward ": \\([^:]+\\)" nil t)
- (help-xref-button 1 'help-face attr)))
- (insert "\n")))))
- (terpri)))))))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Face specifications (defface).
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; Parameter FRAME Is kept for call compatibility to with previous
-;; face implementation.
-
-(defun face-attr-construct (face &optional _frame)
- "Return a `defface'-style attribute list for FACE.
-Value is a property list of pairs ATTRIBUTE VALUE for all specified
-face attributes of FACE where ATTRIBUTE is the attribute name and
-VALUE is the specified value of that attribute.
-Argument FRAME is ignored and retained for compatibility."
- (let (result)
- (dolist (entry face-attribute-name-alist result)
- (let* ((attribute (car entry))
- (value (face-attribute face attribute)))
- (unless (eq value 'unspecified)
- (setq result (nconc (list attribute value) result)))))))
-
-
-(defun face-spec-set-match-display (display frame)
- "Non-nil if DISPLAY matches FRAME.
-DISPLAY is part of a spec such as can be used in `defface'.
-If FRAME is nil, the current FRAME is used."
- (let* ((conjuncts display)
- conjunct req options
- ;; t means we have succeeded against all the conjuncts in
- ;; DISPLAY that have been tested so far.
- (match t))
- (if (eq conjuncts t)
- (setq conjuncts nil))
- (while (and conjuncts match)
- (setq conjunct (car conjuncts)
- conjuncts (cdr conjuncts)
- req (car conjunct)
- options (cdr conjunct)
- match (cond ((eq req 'type)
- (or (memq (window-system frame) options)
- (and (memq 'graphic options)
- (memq (window-system frame) '(x w32 ns)))
- ;; FIXME: This should be revisited to use
- ;; display-graphic-p, provided that the
- ;; color selection depends on the number
- ;; of supported colors, and all defface's
- ;; are changed to look at number of colors
- ;; instead of (type graphic) etc.
- (if (null (window-system frame))
- (memq 'tty options)
- (or (and (memq 'motif options)
- (featurep 'motif))
- (and (memq 'gtk options)
- (featurep 'gtk))
- (and (memq 'lucid options)
- (featurep 'x-toolkit)
- (not (featurep 'motif))
- (not (featurep 'gtk)))
- (and (memq 'x-toolkit options)
- (featurep 'x-toolkit))))))
- ((eq req 'min-colors)
- (>= (display-color-cells frame) (car options)))
- ((eq req 'class)
- (memq (frame-parameter frame 'display-type) options))
- ((eq req 'background)
- (memq (frame-parameter frame 'background-mode)
- options))
- ((eq req 'supports)
- (display-supports-face-attributes-p options frame))
- (t (error "Unknown req `%S' with options `%S'"
- req options)))))
- match))
-
-
-(defun face-spec-choose (spec &optional frame no-match-retval)
- "Return the proper attributes for FRAME, out of SPEC.
-
-If no match is found or SPEC is nil, return nil, unless NO-MATCH-RETVAL
-is given, in which case return its value instead."
- (unless frame
- (setq frame (selected-frame)))
- (let ((tail spec)
- result defaults match-found)
- (while tail
- (let* ((entry (pop tail))
- (display (car entry))
- (attrs (cdr entry))
- thisval)
- ;; Get the attributes as actually specified by this alternative.
- (setq thisval
- (if (null (cdr attrs)) ;; was (listp (car attrs))
- ;; Old-style entry, the attribute list is the
- ;; first element.
- (car attrs)
- attrs))
-
- ;; If the condition is `default', that sets the default
- ;; for following conditions.
- (if (eq display 'default)
- (setq defaults thisval)
- ;; Otherwise, if it matches, use it.
- (when (face-spec-set-match-display display frame)
- (setq result thisval
- tail nil
- match-found t)))))
- ;; If defaults have been found, it's safe to just append those to the
result
- ;; list (which at this point will be either nil or contain actual specs)
and
- ;; return it to the caller. Since there will most definitely be something
to
- ;; return in this case, there's no need to know/check if a match was found.
- (if defaults
- (append result defaults)
- (if match-found
- result
- no-match-retval))))
-
-
-(defun face-spec-reset-face (face &optional frame)
- "Reset all attributes of FACE on FRAME to unspecified."
- (apply 'set-face-attribute face frame
- (if (eq face 'default)
- ;; For the default face, avoid making any attribute
- ;; unspecified. Instead, set attributes to default values
- ;; (see also realize_default_face in xfaces.c).
- (append
- '(:underline nil :overline nil :strike-through nil
- :box nil :inverse-video nil :stipple nil :inherit nil)
- ;; `display-graphic-p' is unavailable when running
- ;; temacs, prior to loading frame.el.
- (when (fboundp 'display-graphic-p)
- (unless (display-graphic-p frame)
- `(:family "default" :foundry "default" :width normal
- :height 1 :weight normal :slant normal
- :foreground ,(if (frame-parameter nil 'reverse)
- "unspecified-bg"
- "unspecified-fg")
- :background ,(if (frame-parameter nil 'reverse)
- "unspecified-fg"
- "unspecified-bg")))))
- ;; For all other faces, unspecify all attributes.
- (apply 'append
- (mapcar (lambda (x) (list (car x) 'unspecified))
- face-attribute-name-alist)))))
-
-(defun face-spec-set (face spec &optional spec-type)
- "Set the face spec SPEC for FACE.
-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 argument SPEC-TYPE determines which spec to set:
- nil or `face-override-spec' means the override spec (which 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 its other effects."
- (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)))
-
-(defun face-spec-recalc (face frame)
- "Reset the face attributes of FACE on FRAME according to its specs.
-The following sources are applied in this order:
-
- face reset to default values if it's the default face, otherwise set
- to unspecified (through `face-spec-reset-face')
- |
- (theme and user customization)
- or: if none of the above exist, and none match the current frame or
- inherited from the defface spec instead of overwriting it
- entirely, the following is applied instead:
- (defface default spec)
- (X resources (if applicable))
- |
- defface override spec"
- (while (get face 'face-alias)
- (setq face (get face 'face-alias)))
- (face-spec-reset-face face frame)
- ;; If FACE is customized or themed, set the custom spec from
- ;; `theme-face' records.
- (let ((theme-faces (get face 'theme-face))
- (no-match-found 0)
- spec theme-face-applied)
- (if theme-faces
- (dolist (elt (reverse theme-faces))
- (setq spec (face-spec-choose (cadr elt) frame no-match-found))
- (unless (eq spec no-match-found)
- (face-spec-set-2 face frame spec)
- (setq theme-face-applied t))))
- ;; If there was a spec applicable to FRAME, that overrides the
- ;; defface spec entirely (rather than inheriting from it). If
- ;; there was no spec applicable to FRAME, apply the defface spec
- ;; as well as any applicable X resources.
- (unless theme-face-applied
- (setq spec (face-spec-choose (face-default-spec face) frame))
- (face-spec-set-2 face frame spec)
- (make-face-x-resource-internal face frame))
- (setq spec (face-spec-choose (get face 'face-override-spec) frame))
- (face-spec-set-2 face frame spec)))
-
-(defun face-spec-set-2 (face frame spec)
- "Set the face attributes of FACE on FRAME according to SPEC."
- (let (attrs)
- (while spec
- (when (assq (car spec) face-x-resources)
- (push (car spec) attrs)
- (push (cadr spec) attrs))
- (setq spec (cddr spec)))
- (apply 'set-face-attribute face frame (nreverse attrs))))
-
-(defun face-attr-match-p (face attrs &optional frame)
- "Return t if attributes of FACE match values in plist ATTRS.
-Optional parameter FRAME is the frame whose definition of FACE
-is used. If nil or omitted, use the selected frame."
- (unless frame
- (setq frame (selected-frame)))
- (let* ((list face-attribute-name-alist)
- (match t)
- (bold (and (plist-member attrs :bold)
- (not (plist-member attrs :weight))))
- (italic (and (plist-member attrs :italic)
- (not (plist-member attrs :slant))))
- (plist (if (or bold italic)
- (copy-sequence attrs)
- attrs)))
- ;; Handle the Emacs 20 :bold and :italic properties.
- (if bold
- (plist-put plist :weight (if bold 'bold 'normal)))
- (if italic
- (plist-put plist :slant (if italic 'italic 'normal)))
- (while (and match list)
- (let* ((attr (caar list))
- (specified-value
- (if (plist-member plist attr)
- (plist-get plist attr)
- 'unspecified))
- (value-now (face-attribute face attr frame)))
- (setq match (equal specified-value value-now))
- (setq list (cdr list))))
- match))
-
-(defsubst face-spec-match-p (face spec &optional frame)
- "Return t if FACE, on FRAME, matches what SPEC says it should look like."
- (face-attr-match-p face (face-spec-choose spec frame) frame))
-
-(defsubst face-default-spec (face)
- "Return the default face-spec for FACE, ignoring any user customization.
-If there is no default for FACE, return nil."
- (get face 'face-defface-spec))
-
-(defsubst face-user-default-spec (face)
- "Return the user's customized face-spec for FACE, or the default if none.
-If there is neither a user setting nor a default for FACE, return nil."
- (or (get face 'customized-face)
- (get face 'saved-face)
- (face-default-spec face)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Frame-type independent color support.
-;;; We keep the old x-* names as aliases for back-compatibility.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defun defined-colors (&optional frame)
- "Return a list of colors supported for a particular frame.
-The argument FRAME specifies which frame to try.
-The value may be different for frames on different display types.
-If FRAME doesn't support colors, the value is nil.
-If FRAME is nil, that stands for the selected frame."
- (if (memq (framep (or frame (selected-frame))) '(x w32 ns))
- (xw-defined-colors frame)
- (mapcar 'car (tty-color-alist frame))))
-(defalias 'x-defined-colors 'defined-colors)
-
-(declare-function xw-color-defined-p "xfns.c" (color &optional frame))
-
-(defun color-defined-p (color &optional frame)
- "Return non-nil if COLOR is supported on frame FRAME.
-COLOR should be a string naming a color (e.g. \"white\"), or a
-string specifying a color's RGB components (e.g. \"#ff12ec\"), or
-the symbol `unspecified'.
-
-This function returns nil if COLOR is the symbol `unspecified',
-or one of the strings \"unspecified-fg\" or \"unspecified-bg\".
-
-If FRAME is omitted or nil, use the selected frame."
- (unless (member color '(unspecified "unspecified-bg" "unspecified-fg"))
- (if (member (framep (or frame (selected-frame))) '(x w32 ns))
- (xw-color-defined-p color frame)
- (numberp (tty-color-translate color frame)))))
-(defalias 'x-color-defined-p 'color-defined-p)
-
-(declare-function xw-color-values "xfns.c" (color &optional frame))
-
-(defun color-values (color &optional frame)
- "Return a description of the color named COLOR on frame FRAME.
-COLOR should be a string naming a color (e.g. \"white\"), or a
-string specifying a color's RGB components (e.g. \"#ff12ec\").
-
-Return a list of three integers, (RED GREEN BLUE), each between 0
-and either 65280 or 65535 (the maximum depends on the system).
-Use `color-name-to-rgb' if you want RGB floating-point values
-normalized to 1.0.
-
-If FRAME is omitted or nil, use the selected frame.
-If FRAME cannot display COLOR, the value is nil.
-
-COLOR can also be the symbol `unspecified' or one of the strings
-\"unspecified-fg\" or \"unspecified-bg\", in which case the
-return value is nil."
- (cond
- ((member color '(unspecified "unspecified-fg" "unspecified-bg"))
- nil)
- ((memq (framep (or frame (selected-frame))) '(x w32 ns))
- (xw-color-values color frame))
- (t
- (tty-color-values color frame))))
-
-(defalias 'x-color-values 'color-values)
-
-(declare-function xw-display-color-p "xfns.c" (&optional terminal))
-
-(defun display-color-p (&optional display)
- "Return t if DISPLAY supports color.
-The optional argument DISPLAY specifies which display to ask about.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display."
- (if (memq (framep-on-display display) '(x w32 ns))
- (xw-display-color-p display)
- (tty-display-color-p display)))
-(defalias 'x-display-color-p 'display-color-p)
-
-(declare-function x-display-grayscale-p "xfns.c" (&optional terminal))
-
-(defun display-grayscale-p (&optional display)
- "Return non-nil if frames on DISPLAY can display shades of gray.
-DISPLAY should be either a frame or a display name (a string).
-If omitted or nil, that stands for the selected frame's display."
- (let ((frame-type (framep-on-display display)))
- (cond
- ((memq frame-type '(x w32 ns))
- (x-display-grayscale-p display))
- (t
- (> (tty-color-gray-shades display) 2)))))
-
-(defun read-color (&optional prompt convert-to-RGB allow-empty-name msg)
- "Read a color name or RGB triplet.
-Completion is available for color names, but not for RGB triplets.
-
-RGB triplets have the form \"#RRGGBB\". Each of the R, G, and B
-components can have one to four digits, but all three components
-must have the same number of digits. Each digit is a hex value
-between 0 and F; either upper case or lower case for A through F
-are acceptable.
-
-In addition to standard color names and RGB hex values, the
-following are available as color candidates. In each case, the
-corresponding color is used.
-
- * `foreground at point' - foreground under the cursor
- * `background at point' - background under the cursor
-
-Optional arg PROMPT is the prompt; if nil, use a default prompt.
-
-Interactively, or with optional arg CONVERT-TO-RGB-P non-nil,
-convert an input color name to an RGB hex string. Return the RGB
-hex string.
-
-If optional arg ALLOW-EMPTY-NAME is non-nil, the user is allowed
-to enter an empty color name (the empty string).
-
-Interactively, or with optional arg MSG non-nil, print the
-resulting color name in the echo area."
- (interactive "i\np\ni\np") ; Always convert to RGB interactively.
- (let* ((completion-ignore-case t)
- (colors (or facemenu-color-alist
- (append '("foreground at point" "background at point")
- (if allow-empty-name '(""))
- (defined-colors))))
- (color (completing-read
- (or prompt "Color (name or #RGB triplet): ")
- ;; Completing function for reading colors, accepting
- ;; both color names and RGB triplets.
- (lambda (string pred flag)
- (cond
- ((null flag) ; Try completion.
- (or (try-completion string colors pred)
- (if (color-defined-p string)
- string)))
- ((eq flag t) ; List all completions.
- (or (all-completions string colors pred)
- (if (color-defined-p string)
- (list string))))
- ((eq flag 'lambda) ; Test completion.
- (or (member string colors)
- (color-defined-p string)))))
- nil t)))
-
- ;; Process named colors.
- (when (member color colors)
- (cond ((string-equal color "foreground at point")
- (setq color (foreground-color-at-point)))
- ((string-equal color "background at point")
- (setq color (background-color-at-point))))
- (when (and convert-to-RGB
- (not (string-equal color "")))
- (let ((components (x-color-values color)))
- (unless (string-match-p
"^#\\(?:[a-fA-F0-9][a-fA-F0-9][a-fA-F0-9]\\)+$" color)
- (setq color (format "#%04X%04X%04X"
- (logand 65535 (nth 0 components))
- (logand 65535 (nth 1 components))
- (logand 65535 (nth 2 components))))))))
- (when msg (message "Color: `%s'" color))
- color))
-
-(defun face-at-point (&optional thing multiple)
- "Return the face of the character after point.
-If it has more than one face, return the first one.
-If THING is non-nil try first to get a face name from the buffer.
-IF MULTIPLE is non-nil, return a list of all faces.
-Return nil if there is no face."
- (let (faces)
- (if thing
- ;; Try to get a face name from the buffer.
- (let ((face (intern-soft (thing-at-point 'symbol))))
- (if (facep face)
- (push face faces))))
- ;; Add the named faces that the `read-face-name' or `face' property uses.
- (let ((faceprop (or (get-char-property (point) 'read-face-name)
- (get-char-property (point) 'face))))
- (cond ((facep faceprop)
- (push faceprop faces))
- ((and (listp faceprop)
- ;; Don't treat an attribute spec as a list of faces.
- (not (keywordp (car faceprop)))
- (not (memq (car faceprop)
- '(foreground-color background-color))))
- (dolist (face faceprop)
- (if (facep face)
- (push face faces))))))
- (setq faces (delete-dups (nreverse faces)))
- (if multiple faces (car faces))))
-
-(defun foreground-color-at-point ()
- "Return the foreground color of the character after point."
- ;; `face-at-point' alone is not sufficient. It only gets named faces.
- ;; Need also pick up any face properties that are not associated with named
faces.
- (let ((face (or (face-at-point)
- (get-char-property (point) 'read-face-name)
- (get-char-property (point) 'face))))
- (cond ((and face (symbolp face))
- (let ((value (face-foreground face nil 'default)))
- (if (member value '("unspecified-fg" "unspecified-bg"))
- nil
- value)))
- ((consp face)
- (cond ((memq 'foreground-color face) (cdr (memq 'foreground-color
face)))
- ((memq ':foreground face) (cadr (memq ':foreground face)))))
- (t nil)))) ; Invalid face value.
-
-(defun background-color-at-point ()
- "Return the background color of the character after point."
- ;; `face-at-point' alone is not sufficient. It only gets named faces.
- ;; Need also pick up any face properties that are not associated with named
faces.
- (let ((face (or (face-at-point)
- (get-char-property (point) 'read-face-name)
- (get-char-property (point) 'face))))
- (cond ((and face (symbolp face))
- (let ((value (face-background face nil 'default)))
- (if (member value '("unspecified-fg" "unspecified-bg"))
- nil
- value)))
- ((consp face)
- (cond ((memq 'background-color face) (cdr (memq 'background-color
face)))
- ((memq ':background face) (cadr (memq ':background face)))))
- (t nil)))) ; Invalid face value.
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Frame creation.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(declare-function x-display-list "xfns.c" ())
-(declare-function x-open-connection "xfns.c"
- (display &optional xrm-string must-succeed))
-(declare-function x-get-resource "frame.c"
- (attribute class &optional component subclass))
-(declare-function x-parse-geometry "frame.c" (string))
-(defvar x-display-name)
-
-(defun x-handle-named-frame-geometry (parameters)
- "Add geometry parameters for a named frame to parameter list PARAMETERS.
-Value is the new parameter list."
- ;; Note that `x-resource-name' has a global meaning.
- (let ((x-resource-name (cdr (assq 'name parameters))))
- (when x-resource-name
- ;; Before checking X resources, we must have an X connection.
- (or (window-system)
- (x-display-list)
- (x-open-connection (or (cdr (assq 'display parameters))
- x-display-name)))
- (let (res-geometry parsed)
- (and (setq res-geometry (x-get-resource "geometry" "Geometry"))
- (setq parsed (x-parse-geometry res-geometry))
- (setq parameters
- (append parameters parsed
- ;; If the resource specifies a position,
- ;; take note of that.
- (if (or (assq 'top parsed) (assq 'left parsed))
- '((user-position . t) (user-size . t)))))))))
- parameters)
-
-
-(defun x-handle-reverse-video (frame parameters)
- "Handle the reverse-video frame parameter and X resource.
-`x-create-frame' does not handle this one."
- (when (cdr (or (assq 'reverse parameters)
- (let ((resource (x-get-resource "reverseVideo"
- "ReverseVideo")))
- (if resource
- (cons nil (member (downcase resource)
- '("on" "true")))))))
- (let* ((params (frame-parameters frame))
- (bg (cdr (assq 'foreground-color params)))
- (fg (cdr (assq 'background-color params))))
- (modify-frame-parameters frame
- (list (cons 'foreground-color fg)
- (cons 'background-color bg)))
- (if (equal bg (cdr (assq 'border-color params)))
- (modify-frame-parameters frame
- (list (cons 'border-color fg))))
- (if (equal bg (cdr (assq 'mouse-color params)))
- (modify-frame-parameters frame
- (list (cons 'mouse-color fg))))
- (if (equal bg (cdr (assq 'cursor-color params)))
- (modify-frame-parameters frame
- (list (cons 'cursor-color fg)))))))
-
-(declare-function x-create-frame "xfns.c" (parms))
-(declare-function x-setup-function-keys "term/common-win" (frame))
-
-(defun x-create-frame-with-faces (&optional parameters)
- "Create and return a frame with frame parameters PARAMETERS.
-If PARAMETERS specify a frame name, handle X geometry resources
-for that name. If PARAMETERS includes a `reverse' parameter, or
-the X resource ``reverseVideo'' is present, handle that."
- (setq parameters (x-handle-named-frame-geometry parameters))
- (let* ((params (copy-tree parameters))
- (visibility-spec (assq 'visibility parameters))
- (delayed-params '(foreground-color background-color font
- border-color cursor-color mouse-color
- visibility scroll-bar-foreground
- scroll-bar-background))
- frame success)
- (dolist (param delayed-params)
- (setq params (assq-delete-all param params)))
- (setq frame (x-create-frame `((visibility . nil) . ,params)))
- (unwind-protect
- (progn
- (x-setup-function-keys frame)
- (x-handle-reverse-video frame parameters)
- (frame-set-background-mode frame t)
- (face-set-after-frame-default frame parameters)
- (if (null visibility-spec)
- (make-frame-visible frame)
- (modify-frame-parameters frame (list visibility-spec)))
- (setq success t))
- (unless success
- (delete-frame frame)))
- frame))
-
-(defun face-set-after-frame-default (frame &optional parameters)
- "Initialize the frame-local faces of FRAME.
-Calculate the face definitions using the face specs, custom theme
-settings, X resources, and `face-new-frame-defaults'.
-Finally, apply any relevant face attributes found amongst the
-frame parameters in PARAMETERS."
- (let ((window-system-p (memq (window-system frame) '(x w32))))
- ;; The `reverse' is so that `default' goes first.
- (dolist (face (nreverse (face-list)))
- (condition-case ()
- (progn
- ;; Initialize faces from face spec and custom theme.
- (face-spec-recalc face frame)
- ;; Apply attributes specified by face-new-frame-defaults
- (internal-merge-in-global-face face frame))
- ;; Don't let invalid specs prevent frame creation.
- (error nil))))
-
- ;; Apply attributes specified by frame parameters.
- (let ((face-params '((foreground-color default :foreground)
- (background-color default :background)
- (font default :font)
- (border-color border :background)
- (cursor-color cursor :background)
- (scroll-bar-foreground scroll-bar :foreground)
- (scroll-bar-background scroll-bar :background)
- (mouse-color mouse :background))))
- (dolist (param face-params)
- (let* ((param-name (nth 0 param))
- (value (cdr (assq param-name parameters))))
- (if value
- (set-face-attribute (nth 1 param) frame
- (nth 2 param) value))))))
-
-(defun tty-handle-reverse-video (frame parameters)
- "Handle the reverse-video frame parameter for terminal frames."
- (when (cdr (assq 'reverse parameters))
- (let* ((params (frame-parameters frame))
- (bg (cdr (assq 'foreground-color params)))
- (fg (cdr (assq 'background-color params))))
- (modify-frame-parameters frame
- (list (cons 'foreground-color fg)
- (cons 'background-color bg)))
- (if (equal bg (cdr (assq 'mouse-color params)))
- (modify-frame-parameters frame
- (list (cons 'mouse-color fg))))
- (if (equal bg (cdr (assq 'cursor-color params)))
- (modify-frame-parameters frame
- (list (cons 'cursor-color fg)))))))
-
-
-(defun tty-create-frame-with-faces (&optional parameters)
- "Create and return a frame from optional frame parameters PARAMETERS.
-If PARAMETERS contains a `reverse' parameter, handle that."
- (let ((frame (make-terminal-frame parameters))
- success)
- (unwind-protect
- (with-selected-frame frame
- (tty-handle-reverse-video frame (frame-parameters frame))
-
- (unless (terminal-parameter frame 'terminal-initted)
- (set-terminal-parameter frame 'terminal-initted t)
- (set-locale-environment nil frame)
- (tty-run-terminal-initialization frame nil t))
- (frame-set-background-mode frame t)
- (face-set-after-frame-default frame parameters)
- (setq success t))
- (unless success
- (delete-frame frame)))
- frame))
-
-(defun tty-find-type (pred type)
- "Return the longest prefix of TYPE to which PRED returns non-nil.
-TYPE should be a tty type name such as \"xterm-16color\".
-
-The function tries only those prefixes that are followed by a
-dash or underscore in the original type name, like \"xterm\" in
-the above example."
- (let (hyphend)
- (while (and type
- (not (funcall pred type)))
- ;; Strip off last hyphen and what follows, then try again
- (setq type
- (if (setq hyphend (string-match-p "[-_][^-_]+$" type))
- (substring type 0 hyphend)
- nil))))
- type)
-
-(defvar tty-setup-hook nil
- "Hook run after running the initialization function of a new text terminal.
-Specifically, `tty-run-terminal-initialization' runs this.
-This can be used to fine tune the `input-decode-map', for example.")
-
-(defun tty-run-terminal-initialization (frame &optional type run-hook)
- "Run the special initialization code for the terminal type of FRAME.
-The optional TYPE parameter may be used to override the autodetected
-terminal type to a different value.
-
-If optional argument RUN-HOOK is non-nil, then as a final step,
-this runs the hook `tty-setup-hook'.
-
-If you set `term-file-prefix' to nil, this function does nothing."
- (setq type (or type (tty-type frame)))
- ;; Load library for our terminal type.
- ;; User init file can set term-file-prefix to nil to prevent this.
- (with-selected-frame frame
- (unless (null term-file-prefix)
- (let* (term-init-func)
- ;; First, load the terminal initialization file, if it is
- ;; available and it hasn't been loaded already.
- (tty-find-type #'(lambda (type)
- (let ((file (locate-library (concat term-file-prefix
type))))
- (and file
- (or (assoc file load-history)
- (load file t t)))))
- type)
- ;; Next, try to find a matching initialization function, and call it.
- (tty-find-type #'(lambda (type)
- (fboundp (setq term-init-func
- (intern (concat "terminal-init-"
type)))))
- type)
- (when (fboundp term-init-func)
- (funcall term-init-func))
- (set-terminal-parameter frame 'terminal-initted term-init-func)
- (if run-hook (run-hooks 'tty-setup-hook))))))
-
-;; Called from C function init_display to initialize faces of the
-;; dumped terminal frame on startup.
-
-(defun tty-set-up-initial-frame-faces ()
- (let ((frame (selected-frame)))
- (frame-set-background-mode frame t)
- (face-set-after-frame-default frame)))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Standard faces.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defgroup basic-faces nil
- "The standard faces of Emacs."
- :group 'faces)
-
-(defface default
- '((t nil)) ; If this were nil, face-defface-spec would not be set.
- "Basic default face."
- :group 'basic-faces)
-
-(defface bold
- '((t :weight bold))
- "Basic bold face."
- :group 'basic-faces)
-
-(defface italic
- '((((supports :slant italic))
- :slant italic)
- (((supports :underline t))
- :underline t)
- (t
- ;; Default to italic, even if it doesn't appear to be supported,
- ;; because in some cases the display engine will do its own
- ;; workaround (to `dim' on ttys).
- :slant italic))
- "Basic italic face."
- :group 'basic-faces)
-
-(defface bold-italic
- '((t :weight bold :slant italic))
- "Basic bold-italic face."
- :group 'basic-faces)
-
-(defface underline
- '((((supports :underline t))
- :underline t)
- (((supports :weight bold))
- :weight bold)
- (t :underline t))
- "Basic underlined face."
- :group 'basic-faces)
-
-(defface fixed-pitch
- '((t :family "Monospace"))
- "The basic fixed-pitch face."
- :group 'basic-faces)
-
-(defface variable-pitch
- '((t :family "Sans Serif"))
- "The basic variable-pitch face."
- :group 'basic-faces)
-
-(defface shadow
- '((((class color grayscale) (min-colors 88) (background light))
- :foreground "grey50")
- (((class color grayscale) (min-colors 88) (background dark))
- :foreground "grey70")
- (((class color) (min-colors 8) (background light))
- :foreground "green")
- (((class color) (min-colors 8) (background dark))
- :foreground "yellow"))
- "Basic face for shadowed text."
- :group 'basic-faces
- :version "22.1")
-
-(defface link
- '((((class color) (min-colors 88) (background light))
- :foreground "RoyalBlue3" :underline t)
- (((class color) (background light))
- :foreground "blue" :underline t)
- (((class color) (min-colors 88) (background dark))
- :foreground "cyan1" :underline t)
- (((class color) (background dark))
- :foreground "cyan" :underline t)
- (t :inherit underline))
- "Basic face for unvisited links."
- :group 'basic-faces
- :version "22.1")
-
-(defface link-visited
- '((default :inherit link)
- (((class color) (background light)) :foreground "magenta4")
- (((class color) (background dark)) :foreground "violet"))
- "Basic face for visited links."
- :group 'basic-faces
- :version "22.1")
-
-(defface highlight
- '((((class color) (min-colors 88) (background light))
- :background "darkseagreen2")
- (((class color) (min-colors 88) (background dark))
- :background "darkolivegreen")
- (((class color) (min-colors 16) (background light))
- :background "darkseagreen2")
- (((class color) (min-colors 16) (background dark))
- :background "darkolivegreen")
- (((class color) (min-colors 8))
- :background "green" :foreground "black")
- (t :inverse-video t))
- "Basic face for highlighting."
- :group 'basic-faces)
-
-;; Region face: under NS, default to the system-defined selection
-;; color (optimized for the fixed white background of other apps),
-;; if background is light.
-(defface region
- '((((class color) (min-colors 88) (background dark))
- :background "blue3")
- (((class color) (min-colors 88) (background light) (type gtk))
- :distant-foreground "gtk_selection_fg_color"
- :background "gtk_selection_bg_color")
- (((class color) (min-colors 88) (background light) (type ns))
- :distant-foreground "ns_selection_fg_color"
- :background "ns_selection_bg_color")
- (((class color) (min-colors 88) (background light))
- :background "lightgoldenrod2")
- (((class color) (min-colors 16) (background dark))
- :background "blue3")
- (((class color) (min-colors 16) (background light))
- :background "lightgoldenrod2")
- (((class color) (min-colors 8))
- :background "blue" :foreground "white")
- (((type tty) (class mono))
- :inverse-video t)
- (t :background "gray"))
- "Basic face for highlighting the region."
- :version "21.1"
- :group 'basic-faces)
-
-(defface secondary-selection
- '((((class color) (min-colors 88) (background light))
- :background "yellow1")
- (((class color) (min-colors 88) (background dark))
- :background "SkyBlue4")
- (((class color) (min-colors 16) (background light))
- :background "yellow")
- (((class color) (min-colors 16) (background dark))
- :background "SkyBlue4")
- (((class color) (min-colors 8))
- :background "cyan" :foreground "black")
- (t :inverse-video t))
- "Basic face for displaying the secondary selection."
- :group 'basic-faces)
-
-(defface trailing-whitespace
- '((((class color) (background light))
- :background "red1")
- (((class color) (background dark))
- :background "red1")
- (t :inverse-video t))
- "Basic face for highlighting trailing whitespace."
- :version "21.1"
- :group 'basic-faces)
-
-(defface escape-glyph
- '((((background dark)) :foreground "cyan")
- ;; See the comment in minibuffer-prompt for
- ;; the reason not to use blue on MS-DOS.
- (((type pc)) :foreground "magenta")
- ;; red4 is too dark, but some say blue is too loud.
- ;; brown seems to work ok. -- rms.
- (t :foreground "brown"))
- "Face for characters displayed as sequences using `^' or `\\'."
- :group 'basic-faces
- :version "22.1")
-
-(defface nobreak-space
- '((((class color) (min-colors 88)) :inherit escape-glyph :underline t)
- (((class color) (min-colors 8)) :background "magenta")
- (t :inverse-video t))
- "Face for displaying nobreak space."
- :group 'basic-faces
- :version "22.1")
-
-(defgroup mode-line-faces nil
- "Faces used in the mode line."
- :group 'mode-line
- :group 'faces
- :version "22.1")
-
-(defface mode-line
- '((((class color) (min-colors 88))
- :box (:line-width -1 :style released-button)
- :background "grey75" :foreground "black")
- (t
- :inverse-video t))
- "Basic mode line face for selected window."
- :version "21.1"
- :group 'mode-line-faces
- :group 'basic-faces)
-
-(defface mode-line-inactive
- '((default
- :inherit mode-line)
- (((class color) (min-colors 88) (background light))
- :weight light
- :box (:line-width -1 :color "grey75" :style nil)
- :foreground "grey20" :background "grey90")
- (((class color) (min-colors 88) (background dark) )
- :weight light
- :box (:line-width -1 :color "grey40" :style nil)
- :foreground "grey80" :background "grey30"))
- "Basic mode line face for non-selected windows."
- :version "22.1"
- :group 'mode-line-faces
- :group 'basic-faces)
-(define-obsolete-face-alias 'modeline-inactive 'mode-line-inactive "22.1")
-
-(defface mode-line-highlight
- '((((class color) (min-colors 88))
- :box (:line-width 2 :color "grey40" :style released-button))
- (t
- :inherit highlight))
- "Basic mode line face for highlighting."
- :version "22.1"
- :group 'mode-line-faces
- :group 'basic-faces)
-(define-obsolete-face-alias 'modeline-highlight 'mode-line-highlight "22.1")
-
-(defface mode-line-emphasis
- '((t (:weight bold)))
- "Face used to emphasize certain mode line features.
-Use the face `mode-line-highlight' for features that can be selected."
- :version "23.1"
- :group 'mode-line-faces
- :group 'basic-faces)
-
-(defface mode-line-buffer-id
- '((t (:weight bold)))
- "Face used for buffer identification parts of the mode line."
- :version "22.1"
- :group 'mode-line-faces
- :group 'basic-faces)
-(define-obsolete-face-alias 'modeline-buffer-id 'mode-line-buffer-id "22.1")
-
-(defface header-line
- '((default
- :inherit mode-line)
- (((type tty))
- ;; This used to be `:inverse-video t', but that doesn't look very
- ;; good when combined with inverse-video mode-lines and multiple
- ;; windows. Underlining looks better, and is more consistent with
- ;; the window-system face variants, which deemphasize the
- ;; header-line in relation to the mode-line face. If a terminal
- ;; can't underline, then the header-line will end up without any
- ;; highlighting; this may be too confusing in general, although it
- ;; happens to look good with the only current use of header-lines,
- ;; the info browser. XXX
- :inverse-video nil ;Override the value inherited from
mode-line.
- :underline t)
- (((class color grayscale) (background light))
- :background "grey90" :foreground "grey20"
- :box nil)
- (((class color grayscale) (background dark))
- :background "grey20" :foreground "grey90"
- :box nil)
- (((class mono) (background light))
- :background "white" :foreground "black"
- :inverse-video nil
- :box nil
- :underline t)
- (((class mono) (background dark))
- :background "black" :foreground "white"
- :inverse-video nil
- :box nil
- :underline t))
- "Basic header-line face."
- :version "21.1"
- :group 'basic-faces)
-
-(defface vertical-border
- '((((type tty)) :inherit mode-line-inactive))
- "Face used for vertical window dividers on ttys."
- :version "22.1"
- :group 'basic-faces)
-
-(defface window-divider '((t :foreground "gray60"))
- "Basic face for window dividers.
-When a divider is less than 3 pixels wide, it is drawn solidly
-with the foreground of this face. For larger dividers this face
-is used for the inner part while the first pixel line/column is
-drawn with the `window-divider-first-pixel' face and the last
-pixel line/column with the `window-divider-last-pixel' face."
- :version "24.4"
- :group 'frames
- :group 'basic-faces)
-
-(defface window-divider-first-pixel
- '((t :foreground "gray80"))
- "Basic face for first pixel line/column of window dividers.
-When a divider is at least 3 pixels wide, its first pixel
-line/column is drawn with the foreground of this face. If you do
-not want to accentuate the first pixel line/column, set this to
-the same as `window-divider' face."
- :version "24.4"
- :group 'frames
- :group 'basic-faces)
-
-(defface window-divider-last-pixel
- '((t :foreground "gray40"))
- "Basic face for last pixel line/column of window dividers.
-When a divider is at least 3 pixels wide, its last pixel
-line/column is drawn with the foreground of this face. If you do
-not want to accentuate the last pixel line/column, set this to
-the same as `window-divider' face."
- :version "24.4"
- :group 'frames
- :group 'basic-faces)
-
-(defface minibuffer-prompt
- '((((background dark)) :foreground "cyan")
- ;; Don't use blue because many users of the MS-DOS port customize
- ;; their foreground color to be blue.
- (((type pc)) :foreground "magenta")
- (t :foreground "medium blue"))
- "Face for minibuffer prompts.
-By default, Emacs automatically adds this face to the value of
-`minibuffer-prompt-properties', which is a list of text properties
-used to display the prompt text."
- :version "22.1"
- :group 'basic-faces)
-
-(setq minibuffer-prompt-properties
- (append minibuffer-prompt-properties (list 'face 'minibuffer-prompt)))
-
-(defface fringe
- '((((class color) (background light))
- :background "grey95")
- (((class color) (background dark))
- :background "grey10")
- (t
- :background "gray"))
- "Basic face for the fringes to the left and right of windows under X."
- :version "21.1"
- :group 'frames
- :group 'basic-faces)
-
-(defface scroll-bar '((t nil))
- "Basic face for the scroll bar colors under X."
- :version "21.1"
- :group 'frames
- :group 'basic-faces)
-
-(defface border '((t nil))
- "Basic face for the frame border under X."
- :version "21.1"
- :group 'frames
- :group 'basic-faces)
-
-(defface cursor
- '((((background light)) :background "black")
- (((background dark)) :background "white"))
- "Basic face for the cursor color under X.
-Currently, only the `:background' attribute is meaningful; all
-other attributes are ignored. The cursor foreground color is
-taken from the background color of the underlying text.
-
-Note: Other faces cannot inherit from the cursor face."
- :version "21.1"
- :group 'cursor
- :group 'basic-faces)
-
-(put 'cursor 'face-no-inherit t)
-
-(defface mouse '((t nil))
- "Basic face for the mouse color under X."
- :version "21.1"
- :group 'mouse
- :group 'basic-faces)
-
-(defface tool-bar
- '((default
- :box (:line-width 1 :style released-button)
- :foreground "black")
- (((type x w32 ns) (class color))
- :background "grey75")
- (((type x) (class mono))
- :background "grey"))
- "Basic tool-bar face."
- :version "21.1"
- :group 'basic-faces)
-
-(defface menu
- '((((type tty))
- :inverse-video t)
- (((type x-toolkit))
- )
- (t
- :inverse-video t))
- "Basic face for the font and colors of the menu bar and popup menus."
- :version "21.1"
- :group 'menu
- :group 'basic-faces)
-
-(defface help-argument-name '((t :inherit italic))
- "Face to highlight argument names in *Help* buffers."
- :group 'help)
-
-(defface glyphless-char
- '((((type tty)) :inherit underline)
- (((type pc)) :inherit escape-glyph)
- (t :height 0.6))
- "Face for displaying non-graphic characters (e.g. U+202A (LRE)).
-It is used for characters of no fonts too."
- :version "24.1"
- :group 'basic-faces)
-
-(defface error
- '((default :weight bold)
- (((class color) (min-colors 88) (background light)) :foreground "Red1")
- (((class color) (min-colors 88) (background dark)) :foreground "Pink")
- (((class color) (min-colors 16) (background light)) :foreground "Red1")
- (((class color) (min-colors 16) (background dark)) :foreground "Pink")
- (((class color) (min-colors 8)) :foreground "red")
- (t :inverse-video t))
- "Basic face used to highlight errors and to denote failure."
- :version "24.1"
- :group 'basic-faces)
-
-(defface warning
- '((default :weight bold)
- (((class color) (min-colors 16)) :foreground "DarkOrange")
- (((class color)) :foreground "yellow"))
- "Basic face used to highlight warnings."
- :version "24.1"
- :group 'basic-faces)
-
-(defface success
- '((default :weight bold)
- (((class color) (min-colors 16) (background light)) :foreground
"ForestGreen")
- (((class color) (min-colors 88) (background dark)) :foreground "Green1")
- (((class color) (min-colors 16) (background dark)) :foreground "Green")
- (((class color)) :foreground "green"))
- "Basic face used to indicate successful operation."
- :version "24.1"
- :group 'basic-faces)
-
-;; Faces for TTY menus.
-(defface tty-menu-enabled-face
- '((t
- :foreground "yellow" :background "blue" :weight bold))
- "Face for displaying enabled items in TTY menus."
- :group 'basic-faces)
-
-(defface tty-menu-disabled-face
- '((((class color) (min-colors 16))
- :foreground "lightgray" :background "blue")
- (t
- :foreground "white" :background "blue"))
- "Face for displaying disabled items in TTY menus."
- :group 'basic-faces)
-
-(defface tty-menu-selected-face
- '((t :background "red"))
- "Face for displaying the currently selected item in TTY menus."
- :group 'basic-faces)
-
-(defgroup paren-showing-faces nil
- "Faces used to highlight paren matches."
- :group 'paren-showing
- :group 'faces
- :version "22.1")
-
-(defface show-paren-match
- '((((class color) (background light))
- :background "turquoise") ; looks OK on tty (becomes cyan)
- (((class color) (background dark))
- :background "steelblue3") ; looks OK on tty (becomes blue)
- (((background dark))
- :background "grey50")
- (t
- :background "gray"))
- "Face used for a matching paren."
- :group 'paren-showing-faces)
-
-(defface show-paren-mismatch
- '((((class color)) (:foreground "white" :background "purple"))
- (t (:inverse-video t)))
- "Face used for a mismatching paren."
- :group 'paren-showing-faces)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;; Manipulating font names.
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; This is here for compatibility with Emacs 20.2. For example,
-;; international/fontset.el uses x-resolve-font-name. The following
-;; functions are not used in the face implementation itself.
-
-(defvar x-font-regexp nil)
-(defvar x-font-regexp-head nil)
-(defvar x-font-regexp-weight nil)
-(defvar x-font-regexp-slant nil)
-
-(defconst x-font-regexp-weight-subnum 1)
-(defconst x-font-regexp-slant-subnum 2)
-(defconst x-font-regexp-swidth-subnum 3)
-(defconst x-font-regexp-adstyle-subnum 4)
-
-;;; Regexps matching font names in "Host Portable Character Representation."
-;;;
-(let ((- "[-?]")
- (foundry "[^-]+")
- (family "[^-]+")
- (weight "\\(bold\\|demibold\\|medium\\)") ; 1
-; (weight\? "\\(\\*\\|bold\\|demibold\\|medium\\|\\)")
; 1
- (weight\? "\\([^-]*\\)")
; 1
- (slant "\\([ior]\\)") ; 2
-; (slant\? "\\([ior?*]?\\)") ; 2
- (slant\? "\\([^-]?\\)") ; 2
-; (swidth "\\(\\*\\|normal\\|semicondensed\\|\\)") ; 3
- (swidth "\\([^-]*\\)") ; 3
-; (adstyle "\\(\\*\\|sans\\|\\)") ; 4
- (adstyle "\\([^-]*\\)") ; 4
- (pixelsize "[0-9]+")
- (pointsize "[0-9][0-9]+")
- (resx "[0-9][0-9]+")
- (resy "[0-9][0-9]+")
- (spacing "[cmp?*]")
- (avgwidth "[0-9]+")
- (registry "[^-]+")
- (encoding "[^-]+")
- )
- (setq x-font-regexp
- (purecopy (concat "\\`\\*?[-?*]"
- foundry - family - weight\? - slant\? - swidth - adstyle -
- pixelsize - pointsize - resx - resy - spacing - avgwidth -
- registry - encoding "\\*?\\'"
- )))
- (setq x-font-regexp-head
- (purecopy (concat "\\`[-?*]" foundry - family - weight\? - slant\?
- "\\([-*?]\\|\\'\\)")))
- (setq x-font-regexp-slant (purecopy (concat - slant -)))
- (setq x-font-regexp-weight (purecopy (concat - weight -)))
- nil)
-
-
-(defun x-resolve-font-name (pattern &optional face frame)
- "Return a font name matching PATTERN.
-All wildcards in PATTERN are instantiated.
-If PATTERN is nil, return the name of the frame's base font, which never
-contains wildcards.
-Given optional arguments FACE and FRAME, return a font which is
-also the same size as FACE on FRAME, or fail."
- (and (eq frame t)
- (setq frame nil))
- (if pattern
- ;; Note that x-list-fonts has code to handle a face with nil as its font.
- (let ((fonts (x-list-fonts pattern face frame 1)))
- (or fonts
- (if face
- (if (string-match-p "\\*" pattern)
- (if (null (face-font face))
- (error "No matching fonts are the same height as the
frame default font")
- (error "No matching fonts are the same height as face
`%s'" face))
- (if (null (face-font face))
- (error "Height of font `%s' doesn't match the frame
default font"
- pattern)
- (error "Height of font `%s' doesn't match face `%s'"
- pattern face)))
- (error "No fonts match `%s'" pattern)))
- (car fonts))
- (cdr (assq 'font (frame-parameters (selected-frame))))))
-
-(defcustom font-list-limit 100
- "This variable is obsolete and has no effect."
- :type 'integer
- :group 'display)
-(make-obsolete-variable 'font-list-limit nil "24.3")
-
-(provide 'faces)
-
-;;; faces.el ends here
diff --git a/packages/context-coloring/fixtures/benchmark/jquery-2.1.1.js
b/packages/context-coloring/fixtures/benchmark/jquery-2.1.1.js
deleted file mode 100644
index 9f7b3d3..0000000
--- a/packages/context-coloring/fixtures/benchmark/jquery-2.1.1.js
+++ /dev/null
@@ -1,9190 +0,0 @@
-/*!
- * jQuery JavaScript Library v2.1.1
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-05-01T17:11Z
- */
-
-(function( global, factory ) {
-
- if ( typeof module === "object" && typeof module.exports === "object" )
{
- // For CommonJS and CommonJS-like environments where a proper
window is present,
- // execute the factory and get jQuery
- // For environments that do not inherently posses a window with
a document
- // (such as Node.js), expose a jQuery-making factory as
module.exports
- // This accentuates the need for the creation of a real window
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a
window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Can't do this because several apps including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-// Support: Firefox 18+
-//
-
-var arr = [];
-
-var slice = arr.slice;
-
-var concat = arr.concat;
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var support = {};
-
-
-
-var
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- version = "2.1.1",
-
- // Define a local copy of jQuery
- jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor
'enhanced'
- // Need init if jQuery is called (just allow error to be thrown
if not included)
- return new jQuery.fn.init( selector, context );
- },
-
- // Support: Android<4.1
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([\da-z])/gi,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
-jQuery.fn = jQuery.prototype = {
- // The current version of jQuery being used
- jquery: version,
-
- constructor: jQuery,
-
- // Start with an empty selector
- selector: "",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- toArray: function() {
- return slice.call( this );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num != null ?
-
- // Return just the one element from the set
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
- // Return all the elements in a clean array
- slice.call( this );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
-
- // Build a new jQuery matched element set
- var ret = jQuery.merge( this.constructor(), elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ) );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- eq: function( i ) {
- var len = this.length,
- j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
- },
-
- end: function() {
- return this.prevObject || this.constructor(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: arr.sort,
- splice: arr.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
-
- // skip the boolean and the target
- target = arguments[ i ] || {};
- i++;
- }
-
- // Handle case when target is a string or something (possible in deep
copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( i === length ) {
- target = this;
- i--;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or
arrays
- if ( deep && copy && (
jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src &&
jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src &&
jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone
them
- target[ name ] = jQuery.extend( deep,
clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
- // Assume jQuery is ready without the ready module
- isReady: true,
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- noop: function() {},
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray,
-
- isWindow: function( obj ) {
- return obj != null && obj === obj.window;
- },
-
- isNumeric: function( obj ) {
- // parseFloat NaNs numeric-cast false positives
(null|true|false|"")
- // ...but misinterprets leading-number strings, particularly
hex literals ("0x...")
- // subtraction forces infinities to NaN
- return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
- },
-
- isPlainObject: function( obj ) {
- // Not plain objects:
- // - Any object or value whose internal [[Class]] property is
not "[object Object]"
- // - DOM nodes
- // - window
- if ( jQuery.type( obj ) !== "object" || obj.nodeType ||
jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.constructor &&
- !hasOwn.call( obj.constructor.prototype,
"isPrototypeOf" ) ) {
- return false;
- }
-
- // If the function hasn't returned already, we're confident that
- // |obj| is a plain object, created by {} or constructed with
new Object
- return true;
- },
-
- isEmptyObject: function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
-
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
- // Support: Android < 4.0, iOS < 6 (functionish RegExp)
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call(obj) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- globalEval: function( code ) {
- var script,
- indirect = eval;
-
- code = jQuery.trim( code );
-
- if ( code ) {
- // If the code includes a valid, prologue position
- // strict mode pragma, execute code by injecting a
- // script tag into the document.
- if ( code.indexOf("use strict") === 1 ) {
- script = document.createElement("script");
- script.text = code;
- document.head.appendChild( script
).parentNode.removeChild( script );
- } else {
- // Otherwise, avoid the DOM node creation, insertion
- // and removal by using an indirect global eval
- indirect( code );
- }
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha,
fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() ===
name.toLowerCase();
- },
-
- // args is for internal usage only
- each: function( obj, callback, args ) {
- var value,
- i = 0,
- length = obj.length,
- isArray = isArraylike( obj );
-
- if ( args ) {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.apply( obj[ i ], args
);
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.apply( obj[ i ], args
);
-
- if ( value === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.call( obj[ i ], i,
obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.call( obj[ i ], i,
obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- }
- }
-
- return obj;
- },
-
- // Support: Android<4.1
- trim: function( text ) {
- return text == null ?
- "" :
- ( text + "" ).replace( rtrim, "" );
- },
-
- // results is for internal usage only
- makeArray: function( arr, results ) {
- var ret = results || [];
-
- if ( arr != null ) {
- if ( isArraylike( Object(arr) ) ) {
- jQuery.merge( ret,
- typeof arr === "string" ?
- [ arr ] : arr
- );
- } else {
- push.call( ret, arr );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, arr, i ) {
- return arr == null ? -1 : indexOf.call( arr, elem, i );
- },
-
- merge: function( first, second ) {
- var len = +second.length,
- j = 0,
- i = first.length;
-
- for ( ; j < len; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, invert ) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- callbackInverse = !callback( elems[ i ], i );
- if ( callbackInverse !== callbackExpect ) {
- matches.push( elems[ i ] );
- }
- }
-
- return matches;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var value,
- i = 0,
- length = elems.length,
- isArray = isArraylike( elems ),
- ret = [];
-
- // Go through the array, translating each of the items to their
new values
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( i in elems ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
- }
-
- // Flatten any nested arrays
- return concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var tmp, args, proxy;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat(
slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original
handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: Date.now,
-
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object
Error".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-function isArraylike( obj ) {
- var length = obj.length,
- type = jQuery.type( obj );
-
- if ( type === "function" || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.nodeType === 1 && length ) {
- return true;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in
obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v1.10.19
- * http://sizzlejs.com/
- *
- * Copyright 2013 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-04-18
- */
-(function( window ) {
-
-var i,
- support,
- Expr,
- getText,
- isXML,
- tokenize,
- compile,
- select,
- outermostContext,
- sortInput,
- hasDuplicate,
-
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
-
- // Instance-specific data
- expando = "sizzle" + -(new Date()),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- // General-purpose constants
- strundefined = typeof undefined,
- MAX_NEGATIVE = 1 << 31,
-
- // Instance methods
- hasOwn = ({}).hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf if we can't use a native one
- indexOf = arr.indexOf || function( elem ) {
- var i = 0,
- len = this.length;
- for ( ; i < len; i++ ) {
- if ( this[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- booleans =
"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier
http://www.w3.org/TR/css3-selectors/#attribute-selectors
- // Proper syntax:
http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Attribute selectors:
http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" +
whitespace +
- // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace +
- // "Attribute values must be CSS identifiers [capture 5] or
strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" +
identifier + "))|)" + whitespace +
- "*\\]",
-
- pseudos = ":(" + characterEncoding + ")(?:\\((" +
- // To reduce the number of selectors needing tokenize in the
preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
- // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
- // 3. anything else (capture 2)
- ".*" +
- ")\\)|)",
-
- // Leading and non-escaped trailing whitespace, capturing some
non-whitespace characters preceding the latter
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace +
")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" +
whitespace + "*\\]", "g" ),
-
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*"
) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp(
"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace +
"*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace +
"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace +
"*\\)|)(?=[^-]|$)", "i" )
- },
-
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
-
- rnative = /^[^{]+\{\s*\[native \w/,
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
- rsibling = /[+~]/,
- rescape = /'|\\/g,
-
- // CSS escapes
http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" +
whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
- high < 0 ?
- // BMP codepoint
- String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode( high >> 10 | 0xD800, high
& 0x3FF | 0xDC00 );
- };
-
-// Optimize for push.apply( _, NodeList )
-try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
- }
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- var match, elem, m, nodeType,
- // QSA vars
- i, groups, old, nid, newContext, newSelector;
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !==
document ) {
- setDocument( context );
- }
-
- context = context || document;
- results = results || [];
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
- return [];
- }
-
- if ( documentIsHTML && !seed ) {
-
- // Shortcuts
- if ( (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when
Blackberry 4.6 returns
- // nodes that are no longer in the
document (jQuery #6963)
- if ( elem && elem.parentNode ) {
- // Handle the case where IE,
Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem =
context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) &&
elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results,
context.getElementsByTagName( selector ) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) &&
support.getElementsByClassName && context.getElementsByClassName ) {
- push.apply( results,
context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // QSA path
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector ))
) {
- nid = old = expando;
- newContext = context;
- newSelector = nodeType === 9 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on
the root
- // and working up from there (Thanks to Andrew Dupont
for the technique)
- // IE 8 doesn't work on object elements
- if ( nodeType === 1 && context.nodeName.toLowerCase()
!== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + toSelector( groups[i]
);
- }
- newContext = rsibling.test( selector ) &&
testContext( context.parentNode ) || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll(
newSelector )
- );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed
);
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing
it on itself with
- * property name the (space-suffixed) string and (if the cache is larger
than Expr.cacheLength)
- * deleting the oldest entry
- */
-function createCache() {
- var keys = [];
-
- function cache( key, value ) {
- // Use (key + " ") to avoid collision with native prototype
properties (see Issue #157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
- }
- return (cache[ key + " " ] = value);
- }
- return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
- var div = document.createElement("div");
-
- try {
- return !!fn( div );
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if ( div.parentNode ) {
- div.parentNode.removeChild( div );
- }
- // release memory in IE
- div = null;
- }
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
- i = attrs.length;
-
- while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
- }
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a
follows b
- */
-function siblingCheck( a, b ) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
- ( ~a.sourceIndex || MAX_NEGATIVE );
-
- // Use IE sourceIndex if available on both nodes
- if ( diff ) {
- return diff;
- }
-
- // Check if b follows a
- if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
- if ( cur === b ) {
- return -1;
- }
- }
- }
-
- return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type ===
type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a
falsy value
- */
-function testContext( context ) {
- return context && typeof context.getElementsByTagName !== strundefined
&& context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument ||
elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set
the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare,
- doc = node ? node.ownerDocument || node : preferredDoc,
- parent = doc.defaultView;
-
- // If no document and documentElement is available, return
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Set our document
- document = doc;
- docElem = doc.documentElement;
-
- // Support tests
- documentIsHTML = !isXML( doc );
-
- // Support: IE>8
- // If iframe document is assigned to "document" variable and if iframe
has been reloaded,
- // IE will throw "permission denied" error when accessing "document"
variable, see jQuery #13936
- // IE6-8 do not support the defaultView property so parent will be
undefined
- if ( parent && parent !== parent.top ) {
- // IE11 does not have attachEvent, so all must suffer
- if ( parent.addEventListener ) {
- parent.addEventListener( "unload", function() {
- setDocument();
- }, false );
- } else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", function() {
- setDocument();
- });
- }
- }
-
- /* Attributes
- ----------------------------------------------------------------------
*/
-
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not
properties (excepting IE8 booleans)
- support.attributes = assert(function( div ) {
- div.className = "i";
- return !div.getAttribute("className");
- });
-
- /* getElement(s)By*
- ----------------------------------------------------------------------
*/
-
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( div ) {
- div.appendChild( doc.createComment("") );
- return !div.getElementsByTagName("*").length;
- });
-
- // Check if getElementsByClassName can be trusted
- support.getElementsByClassName = rnative.test(
doc.getElementsByClassName ) && assert(function( div ) {
- div.innerHTML = "<div class='a'></div><div class='a i'></div>";
-
- // Support: Safari<4
- // Catch class over-caching
- div.firstChild.className = "i";
- // Support: Opera<10
- // Catch gEBCN failure to find non-leading classes
- return div.getElementsByClassName("i").length === 2;
- });
-
- // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programatically-set
names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function( div ) {
- docElem.appendChild( div ).id = expando;
- return !doc.getElementsByName || !doc.getElementsByName(
expando ).length;
- });
-
- // ID find and filter
- if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== strundefined &&
documentIsHTML ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry
4.6 returns
- // nodes that are no longer in the document
#6963
- return m && m.parentNode ? [ m ] : [];
- }
- };
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute("id") === attrId;
- };
- };
- } else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !==
strundefined && elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- };
- }
-
- // Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !==
strundefined ) {
- return context.getElementsByTagName( tag );
- }
- } :
- function( tag, context ) {
- var elem,
- tmp = [],
- i = 0,
- results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- };
-
- // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function(
className, context ) {
- if ( typeof context.getElementsByClassName !== strundefined &&
documentIsHTML ) {
- return context.getElementsByClassName( className );
- }
- };
-
- /* QSA/matchesSelector
- ----------------------------------------------------------------------
*/
-
- // QSA and matchesSelector support
-
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = [];
-
- // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE
error
- // See http://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
-
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- div.innerHTML = "<select msallowclip=''><option
selected=''></option></select>";
-
- // Support: IE8, Opera 11-12.16
- // Nothing should be selected when empty strings follow
^= or $= or *=
- // The test attribute must be unknown in Opera but
"safe" for WinRT
- //
http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( div.querySelectorAll("[msallowclip^='']").length )
{
- rbuggyQSA.push( "[*^$]=" + whitespace +
"*(?:''|\"\")" );
- }
-
- // Support: IE8
- // Boolean attributes and "value" are not treated
correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace +
"*(?:value|" + booleans + ")" );
- }
-
- // Webkit/Opera - :checked should return selected
option elements
- //
http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
- });
-
- assert(function( div ) {
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during
.innerHTML assignment
- var input = doc.createElement("input");
- input.setAttribute( "type", "hidden" );
- div.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE8
- // Enforce case-sensitivity of name attribute
- if ( div.querySelectorAll("[name=d]").length ) {
- rbuggyQSA.push( "name" + whitespace +
"*[*^$|!~]?=" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements
(hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Opera 10-11 does not throw on post-comma invalid
pseudos
- div.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
-
- if ( (support.matchesSelector = rnative.test( (matches =
docElem.matches ||
- docElem.webkitMatchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
-
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( div, "[s!='']:x" );
- rbuggyMatches.push( "!=", pseudos );
- });
- }
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp(
rbuggyMatches.join("|") );
-
- /* Contains
- ----------------------------------------------------------------------
*/
- hasCompare = rnative.test( docElem.compareDocumentPosition );
-
- // Element contains another
- // Purposefully does not implement inclusive descendent
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test( docElem.contains ) ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && (
- adown.contains ?
- adown.contains( bup ) :
- a.compareDocumentPosition &&
a.compareDocumentPosition( bup ) & 16
- ));
- } :
- function( a, b ) {
- if ( b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- }
- return false;
- };
-
- /* Sorting
- ----------------------------------------------------------------------
*/
-
- // Document order sorting
- sortOrder = hasCompare ?
- function( a, b ) {
-
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- // Sort on method existence if only one input has
compareDocumentPosition
- var compare = !a.compareDocumentPosition -
!b.compareDocumentPosition;
- if ( compare ) {
- return compare;
- }
-
- // Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b )
?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a
) === compare) ) {
-
- // Choose the first element that is related to our
preferred document
- if ( a === doc || a.ownerDocument === preferredDoc &&
contains(preferredDoc, a) ) {
- return -1;
- }
- if ( b === doc || b.ownerDocument === preferredDoc &&
contains(preferredDoc, b) ) {
- return 1;
- }
-
- // Maintain original order
- return sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call(
sortInput, b ) ) :
- 0;
- }
-
- return compare & 4 ? -1 : 1;
- } :
- function( a, b ) {
- // Exit early if the nodes are identical
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [ a ],
- bp = [ b ];
-
- // Parentless nodes are either documents or disconnected
- if ( !aup || !bup ) {
- return a === doc ? -1 :
- b === doc ? 1 :
- aup ? -1 :
- bup ? 1 :
- sortInput ?
- ( indexOf.call( sortInput, a ) - indexOf.call(
sortInput, b ) ) :
- 0;
-
- // If the nodes are siblings, we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
- }
-
- // Otherwise we need full lists of their ancestors for
comparison
- cur = a;
- while ( (cur = cur.parentNode) ) {
- ap.unshift( cur );
- }
- cur = b;
- while ( (cur = cur.parentNode) ) {
- bp.unshift( cur );
- }
-
- // Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
- i++;
- }
-
- return i ?
- // Do a sibling check if the nodes have a common
ancestor
- siblingCheck( ap[i], bp[i] ) :
-
- // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
- 0;
- };
-
- return doc;
-};
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- if ( support.matchesSelector && documentIsHTML &&
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
-
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected
nodes
- if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said
to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType
!== 11 ) {
- return ret;
- }
- } catch(e) {}
- }
-
- return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
- // Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
- setDocument( context );
- }
- return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- var fn = Expr.attrHandle[ name.toLowerCase() ],
- // Don't get fooled by Object.prototype properties (jQuery
#13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
-
- return val !== undefined ?
- val :
- support.attributes || !documentIsHTML ?
- elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
- val.value :
- null;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0;
-
- // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice( 0 );
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
- j = duplicates.push( i );
- }
- }
- while ( j-- ) {
- results.splice( duplicates[ j ], 1 );
- }
- }
-
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
- return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( !nodeType ) {
- // If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery
#11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem =
elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
-
- return ret;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- attrHandle: {},
-
- find: {},
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
-
- // Move the given value to match[3] whether quoted or
unquoted
- match[3] = ( match[3] || match[4] || match[5] || ""
).replace( runescape, funescape );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1].slice( 0, 3 ) === "nth" ) {
- // nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for
Expr.filter.CHILD
- // remember that false/true cast respectively
to 0/1
- match[4] = +( match[4] ? match[5] + (match[6]
|| 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) ||
match[3] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var excess,
- unquoted = !match[6] && match[2];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[3] ) {
- match[2] = match[4] || match[5] || "";
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")",
unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter
method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- "TAG": function( nodeNameSelector ) {
- var nodeName = nodeNameSelector.replace( runescape,
funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() { return true; } :
- function( elem ) {
- return elem.nodeName &&
elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")"
+ className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof
elem.className === "string" && elem.className || typeof elem.getAttribute !==
strundefined && elem.getAttribute("class") || "" );
- });
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check &&
result.indexOf( check ) === 0 :
- operator === "*=" ? check &&
result.indexOf( check ) > -1 :
- operator === "$=" ? check &&
result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result + "
" ).indexOf( check ) > -1 :
- operator === "|=" ? result === check ||
result.slice( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, what, argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, context, xml ) {
- var cache, outerCache, node, diff,
nodeIndex, start,
- dir = simple !== forward ?
"nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType &&
elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType;
-
- if ( parent ) {
-
- //
:(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( (node =
node[ dir ]) ) {
- if (
ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
-
return false;
- }
- }
- // Reverse
direction for :only-* (if we haven't yet done so)
- start = dir =
type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ?
parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...)
stores cache data on `parent`
- if ( forward && useCache ) {
- // Seek `elem` from a
previously-cached index
- outerCache = parent[
expando ] || (parent[ expando ] = {});
- cache = outerCache[
type ] || [];
- nodeIndex = cache[0]
=== dirruns && cache[1];
- diff = cache[0] ===
dirruns && cache[2];
- node = nodeIndex &&
parent.childNodes[ nodeIndex ];
-
- while ( (node =
++nodeIndex && node && node[ dir ] ||
-
- // Fallback to
seeking `elem` from the start
- (diff =
nodeIndex = 0) || start.pop()) ) {
-
- // When found,
cache indexes on `parent` and break
- if (
node.nodeType === 1 && ++diff && node === elem ) {
-
outerCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- // Use previously-cached
element index if available
- } else if ( useCache && (cache
= (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns
) {
- diff = cache[1];
-
- // xml :nth-child(...) or
:nth-last-child(...) or :nth(-last)?-of-type(...)
- } else {
- // Use the same loop as
above to seek `elem` from the start
- while ( (node =
++nodeIndex && node && node[ dir ] ||
- (diff =
nodeIndex = 0) || start.pop()) ) {
-
- if ( ( ofType ?
node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
- //
Cache the index of each encountered element
- if (
useCache ) {
-
(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
- }
-
- if (
node === elem ) {
-
break;
- }
- }
- }
- }
-
- // Incorporate the offset, then
check against cycle size
- diff -= last;
- return diff === first || ( diff
% first === 0 && diff / first >= 0 );
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom
pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[
pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " +
pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty(
pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed,
argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf.call(
seed, matched[i] );
- seed[ idx ] = !(
matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim,
"$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context,
xml ) {
- var elem,
- unmatched = matcher( seed,
null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i]
= elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- return function( elem ) {
- return ( elem.textContent || elem.innerText ||
getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by
"-".
- // The matching of C against the element's language value is
performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction( function( lang ) {
- // lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
- Sizzle.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape
).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( (elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute("xml:lang")
|| elem.getAttribute("lang")) ) {
-
- elemLang =
elemLang.toLowerCase();
- return elemLang === lang ||
elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( (elem = elem.parentNode) &&
elem.nodeType === 1 );
- return false;
- };
- }),
-
- // Miscellaneous
- "target": function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- "root": function( elem ) {
- return elem === docElem;
- },
-
- "focus": function( elem ) {
- return elem === document.activeElement &&
(!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href ||
~elem.tabIndex);
- },
-
- // Boolean properties
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and
selected elements
- //
http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) ||
(nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes
(text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing
instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not
appear as children
- for ( elem = elem.firstChild; elem; elem =
elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- // Element/input types
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" ||
name === "button";
- },
-
- "text": function( elem ) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" &&
- elem.type === "text" &&
-
- // Support: IE<8
- // New HTML5 attribute values (e.g., "search")
appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null ||
attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- "first": createPositionalPseudo(function() {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length )
{
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length,
argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length )
{
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length,
argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length,
argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image:
true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
- }
- groups.push( (tokens = []) );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) &&
(!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[i].value;
- }
- return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they
don't benefit from dir caching
- if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ||
checkNonElements ) {
- if ( matcher( elem, context,
xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 ||
checkNonElements ) {
- outerCache = elem[ expando ] ||
(elem[ expando ] = {});
- if ( (oldCache = outerCache[
dir ]) &&
- oldCache[ 0 ] ===
dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache
so results back-propagate to previous elements
- return (newCache[ 2 ] =
oldCache[ 2 ]);
- } else {
- // Reuse newcache so
results back-propagate to previous elements
- outerCache[ dir ] =
newCache;
-
- // A match means we're
done; a fail means we have to keep checking
- if ( (newCache[ 2 ] =
matcher( elem, context, xml )) ) {
- return true;
- }
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
- }
- return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder,
postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- var temp, i, elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*",
context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for
seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context,
xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed,
or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting
|| postFilter ) ?
-
- // ...intermediate processing is
necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to
matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[
postMap[i] ] = elem);
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
- // Get the final matcherOut by
condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- // Restore matcherIn
since elem is not yet a final match
- temp.push(
(matcherIn[i] = elem) );
- }
- }
- postFinder( null, (matcherOut = []),
temp, xml );
- }
-
- // Move matched elements from seed to results
to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ?
indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
-
- seed[temp] = !(results[temp] =
elem);
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting,
matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable
from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf.call( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- return ( !leadingRelative && ( xml || context !==
outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ),
matcher) ];
- } else {
- matcher = Expr.filter[ tokens[i].type ].apply( null,
tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for
proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
- // If the preceding token was a
descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1
).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
- ).replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens(
tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens =
tokens.slice( j )) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost
) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or
outermost context
- elems = seed || byElement && Expr.find["TAG"](
"*", outermost ),
- // Use integer dirruns iff this is the
outermost matcher
- dirrunsUnique = (dirruns += contextBackup ==
null ? 1 : Math.random() || 0.1),
- len = elems.length;
-
- if ( outermost ) {
- outermostContext = context !== document &&
context;
- }
-
- // Add elements passing elementMatchers directly to
results
- // Keep `i` a string if there are no elements so
`matchedCount` will be "00" below
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari:
<number>) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
- while ( (matcher =
elementMatchers[j++]) ) {
- if ( matcher( elem, context,
xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all
possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every
element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( (matcher = setMatchers[j++]) ) {
- matcher( unmatched, setMatched,
context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to
eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] ||
setMatched[i]) ) {
- setMatched[i] =
pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to
get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple
successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length >
0 &&
- ( matchedCount + setMatchers.length ) >
1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ )
{
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used
to check each element
- if ( !match ) {
- match = tokenize( selector );
- }
- i = match.length;
- while ( i-- ) {
- cached = matcherFromTokens( match[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers(
elementMatchers, setMatchers ) );
-
- // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( (selector = compiled.selector ||
selector) );
-
- results = results || [];
-
- // Try to minimize operations if there is no seed and only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is
an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 &&
documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = ( Expr.find["ID"](
token.matches[0].replace(runescape, funescape), context ) || [] )[0];
- if ( !context ) {
- return results;
-
- // Precompiled matchers will still verify ancestry, so
step up a level
- } else if ( compiled ) {
- context = context.parentNode;
- }
-
- selector = selector.slice( tokens.shift().value.length
);
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 :
tokens.length;
- while ( i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading
sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape,
funescape ),
- rsibling.test( tokens[0].type ) &&
testContext( context.parentNode ) || context
- )) ) {
-
- // If seed is empty or no tokens
remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector(
tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
-
- // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector
above
- ( compiled || compile( selector, match ) )(
- seed,
- context,
- !documentIsHTML,
- results,
- rsibling.test( selector ) && testContext( context.parentNode )
|| context
- );
- return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome<14
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( document.createElement("div") ) &
1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem.getAttribute( name, name.toLowerCase() ===
"type" ? 1 : 2 );
- }
- });
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
- div.innerHTML = "<input/>";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
- addHandle( "value", function( elem, name, isXML ) {
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
- }
- });
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
- return div.getAttribute("disabled") == null;
-}) ) {
- addHandle( booleans, function( elem, name, isXML ) {
- var val;
- if ( !isXML ) {
- return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name ))
&& val.specified ?
- val.value :
- null;
- }
- });
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
- return !!qualifier.call( elem, i, elem ) !== not;
- });
-
- }
-
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- });
-
- }
-
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- qualifier = jQuery.filter( qualifier, elements );
- }
-
- return jQuery.grep( elements, function( elem ) {
- return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
- });
-}
-
-jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem )
{
- return elem.nodeType === 1;
- }));
-};
-
-jQuery.fn.extend({
- find: function( selector ) {
- var i,
- len = this.length,
- ret = [],
- self = this;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector
).filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this )
) {
- return true;
- }
- }
- }) );
- }
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- // Needed because $( selector, context ) becomes $( context
).find( selector )
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
- ret.selector = this.selector ? this.selector + " " + selector :
selector;
- return ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector || [], false) );
- },
- not: function( selector ) {
- return this.pushStack( winnow(this, selector || [], true) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check
membership in the returned set
- // so $("p:first").is("p:last") won't return true for a
doc with two "p".
- typeof selector === "string" && rneedsContext.test(
selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
-});
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
- // A simple way to check for HTML strings
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
- init = jQuery.fn.init = function( selector, context ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector[0] === "<" && selector[ selector.length -
1 ] === ">" && selector.length >= 3 ) {
- // Assume that strings that start and end with
<> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for
#id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ?
context[0] : context;
-
- // scripts is true for back-compat
- // Intentionally let the error be
thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[1],
- context && context.nodeType ?
context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[1] ) &&
jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
- // Properties of
context are called as methods if possible
- if ( jQuery.isFunction(
this[ match ] ) ) {
- this[ match ](
context[ match ] );
-
- // ...and otherwise set
as attributes
- } else {
- this.attr(
match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById(
match[2] );
-
- // Check parentNode to catch when
Blackberry 4.6 returns
- // nodes that are no longer in the
document #6963
- if ( elem && elem.parentNode ) {
- // Inject the element directly
into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector
);
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find(
selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return typeof rootjQuery.ready !== "undefined" ?
- rootjQuery.ready( selector ) :
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- };
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // methods guaranteed to produce a unique set when starting from a
unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.extend({
- dir: function( elem, dir, until ) {
- var matched = [],
- truncate = until !== undefined;
-
- while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
- if ( elem.nodeType === 1 ) {
- if ( truncate && jQuery( elem ).is( until ) ) {
- break;
- }
- matched.push( elem );
- }
- }
- return matched;
- },
-
- sibling: function( n, elem ) {
- var matched = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- matched.push( n );
- }
- }
-
- return matched;
- }
-});
-
-jQuery.fn.extend({
- has: function( target ) {
- var targets = jQuery( target, this ),
- l = targets.length;
-
- return this.filter(function() {
- var i = 0;
- for ( ; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- pos = rneedsContext.test( selectors ) || typeof
selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur =
cur.parentNode ) {
- // Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
-
jQuery.find.matchesSelector(cur, selectors)) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.unique(
matched ) : matched );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[ 0 ] && this[ 0 ].parentNode ) ?
this.first().prevAll().length : -1;
- }
-
- // index in selector
- if ( typeof elem === "string" ) {
- return indexOf.call( jQuery( elem ), this[ 0 ] );
- }
-
- // Locate the position of the desired element
- return indexOf.call( this,
-
- // If it receives a jQuery object, the first element is
used
- elem.jquery ? elem[ 0 ] : elem
- );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.unique(
- jQuery.merge( this.get(), jQuery( selector,
context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter(selector)
- );
- }
-});
-
-function sibling( cur, dir ) {
- while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
- return cur;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild,
elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return elem.contentDocument || jQuery.merge( [],
elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var matched = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- matched = jQuery.filter( selector, matched );
- }
-
- if ( this.length > 1 ) {
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- jQuery.unique( matched );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- matched.reverse();
- }
- }
-
- return this.pushStack( matched );
- };
-});
-var rnotwhite = (/\S+/g);
-
-
-
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in
cache
-function createOptions( options ) {
- var object = optionsCache[ options ] = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- });
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change
how
- * the callback list behaves or a more traditional option
object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired
once (like a Deferred)
- *
- * memory: will keep track of previous values and will
call any callback added
- * after the list has been fired right
away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once
(no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- ( optionsCache[ options ] || createOptions( options ) ) :
- jQuery.extend( {}, options );
-
- var // Last fire value (for non-forgettable lists)
- memory,
- // Flag to know if list was already fired
- fired,
- // Flag to know if list is currently firing
- firing,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if
needed)
- firingIndex,
- // Actual callback list
- list = [],
- // Stack of fire calls for repeatable lists
- stack = !options.once && [],
- // Fire callbacks
- fire = function( data ) {
- memory = options.memory && data;
- fired = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- firing = true;
- for ( ; list && firingIndex < firingLength;
firingIndex++ ) {
- if ( list[ firingIndex ].apply( data[ 0 ],
data[ 1 ] ) === false && options.stopOnFalse ) {
- memory = false; // To prevent further
calls using add
- break;
- }
- }
- firing = false;
- if ( list ) {
- if ( stack ) {
- if ( stack.length ) {
- fire( stack.shift() );
- }
- } else if ( memory ) {
- list = [];
- } else {
- self.disable();
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the
list
- add: function() {
- if ( list ) {
- // First, we save the current length
- var start = list.length;
- (function add( args ) {
- jQuery.each( args, function( _,
arg ) {
- var type = jQuery.type(
arg );
- if ( type ===
"function" ) {
- if (
!options.unique || !self.has( arg ) ) {
-
list.push( arg );
- }
- } else if ( arg &&
arg.length && type !== "string" ) {
- // Inspect
recursively
- add( arg );
- }
- });
- })( arguments );
- // Do we need to add the callbacks to
the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away
- } else if ( memory ) {
- firingStart = start;
- fire( memory );
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function() {
- if ( list ) {
- jQuery.each( arguments, function( _,
arg ) {
- var index;
- while ( ( index =
jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
- // Handle firing indexes
- if ( firing ) {
- if ( index <=
firingLength ) {
-
firingLength--;
- }
- if ( index <=
firingIndex ) {
-
firingIndex--;
- }
- }
- }
- });
- }
- return this;
- },
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list
has callbacks attached.
- has: function( fn ) {
- return fn ? jQuery.inArray( fn, list ) > -1 :
!!( list && list.length );
- },
- // Remove all callbacks from the list
- empty: function() {
- list = [];
- firingLength = 0;
- return this;
- },
- // Have the list do nothing anymore
- disable: function() {
- list = stack = memory = undefined;
- return this;
- },
- // Is it disabled?
- disabled: function() {
- return !list;
- },
- // Lock the list in its current state
- lock: function() {
- stack = undefined;
- if ( !memory ) {
- self.disable();
- }
- return this;
- },
- // Is it locked?
- locked: function() {
- return !stack;
- },
- // Call all callbacks with the given context and
arguments
- fireWith: function( context, args ) {
- if ( list && ( !fired || stack ) ) {
- args = args || [];
- args = [ context, args.slice ?
args.slice() : args ];
- if ( firing ) {
- stack.push( args );
- } else {
- fire( args );
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
- // To know if the callbacks have already been called at
least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-jQuery.extend({
-
- Deferred: function( func ) {
- var tuples = [
- // action, add listener, listener list, final
state
- [ "resolve", "done", jQuery.Callbacks("once
memory"), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks("once
memory"), "rejected" ],
- [ "notify", "progress",
jQuery.Callbacks("memory") ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail(
arguments );
- return this;
- },
- then: function( /* fnDone, fnFail, fnProgress
*/ ) {
- var fns = arguments;
- return jQuery.Deferred(function(
newDefer ) {
- jQuery.each( tuples, function(
i, tuple ) {
- var fn =
jQuery.isFunction( fns[ i ] ) && fns[ i ];
- // deferred[ done |
fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[1]
](function() {
- var returned =
fn && fn.apply( this, arguments );
- if ( returned
&& jQuery.isFunction( returned.promise ) ) {
-
returned.promise()
-
.done( newDefer.resolve )
-
.fail( newDefer.reject )
-
.progress( newDefer.notify );
- } else {
-
newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this,
fn ? [ returned ] : arguments );
- }
- });
- });
- fns = null;
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is
added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend(
obj, promise ) : promise;
- }
- },
- deferred = {};
-
- // Keep pipe for back-compat
- promise.pipe = promise.then;
-
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 3 ];
-
- // promise[ done | fail | progress ] = list.add
- promise[ tuple[1] ] = list.add;
-
- // Handle state
- if ( stateString ) {
- list.add(function() {
- // state = [ resolved | rejected ]
- state = stateString;
-
- // [ reject_list | resolve_list ].disable;
progress_list.lock
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2
].lock );
- }
-
- // deferred[ resolve | reject | notify ]
- deferred[ tuple[0] ] = function() {
- deferred[ tuple[0] + "With" ]( this ===
deferred ? promise : this, arguments );
- return this;
- };
- deferred[ tuple[0] + "With" ] = list.fireWith;
- });
-
- // Make the deferred a promise
- promise.promise( deferred );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( subordinate /* , ..., subordinateN */ ) {
- var i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
-
- // the count of uncompleted subordinates
- remaining = length !== 1 || ( subordinate &&
jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
- // the master Deferred. If resolveValues consist of
only a single Deferred, just use that.
- deferred = remaining === 1 ? subordinate :
jQuery.Deferred(),
-
- // Update function for both resolve and progress values
- updateFunc = function( i, contexts, values ) {
- return function( value ) {
- contexts[ i ] = this;
- values[ i ] = arguments.length > 1 ?
slice.call( arguments ) : value;
- if ( values === progressValues ) {
- deferred.notifyWith( contexts,
values );
- } else if ( !( --remaining ) ) {
- deferred.resolveWith( contexts,
values );
- }
- };
- },
-
- progressValues, progressContexts, resolveContexts;
-
- // add listeners to Deferred subordinates; treat others as
resolved
- if ( length > 1 ) {
- progressValues = new Array( length );
- progressContexts = new Array( length );
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
- if ( resolveValues[ i ] && jQuery.isFunction(
resolveValues[ i ].promise ) ) {
- resolveValues[ i ].promise()
- .done( updateFunc( i,
resolveContexts, resolveValues ) )
- .fail( deferred.reject )
- .progress( updateFunc( i,
progressContexts, progressValues ) );
- } else {
- --remaining;
- }
- }
- }
-
- // if we're not waiting on anything, resolve the master
- if ( !remaining ) {
- deferred.resolveWith( resolveContexts, resolveValues );
- }
-
- return deferred.promise();
- }
-});
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
- // Add the callback
- jQuery.ready.promise().done( fn );
-
- return this;
-};
-
-jQuery.extend({
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
-
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if
need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
- jQuery( document ).off( "ready" );
- }
- }
-});
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
- jQuery.ready();
-}
-
-jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
-
- readyList = jQuery.Deferred();
-
- // Catch cases where $(document).ready() is called after the
browser event has already occurred.
- // we once tried to use readyState "interactive" here, but it
caused issues like the one
- // discovered by ChrisS here:
http://bugs.jquery.com/ticket/12282#comment:15
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the
opportunity to delay ready
- setTimeout( jQuery.ready );
-
- } else {
-
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded",
completed, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed, false );
- }
- }
- return readyList.promise( obj );
-};
-
-// Kick off the DOM ready check even if the user does not
-jQuery.ready.promise();
-
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable,
emptyGet, raw ) {
- var i = 0,
- len = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], true, emptyGet,
raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value
);
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < len; i++ ) {
- fn( elems[i], key, raw ? value : value.call(
elems[i], i, fn( elems[i], key ) ) );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- len ? fn( elems[0], key ) : emptyGet;
-};
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( owner ) {
- // Accepts only:
- // - Node
- // - Node.ELEMENT_NODE
- // - Node.DOCUMENT_NODE
- // - Object
- // - Any
- /* jshint -W018 */
- return owner.nodeType === 1 || owner.nodeType === 9 || !(
+owner.nodeType );
-};
-
-
-function Data() {
- // Support: Android < 4,
- // Old WebKit does not have Object.preventExtensions/freeze method,
- // return new empty object instead with no [[set]] accessor
- Object.defineProperty( this.cache = {}, 0, {
- get: function() {
- return {};
- }
- });
-
- this.expando = jQuery.expando + Math.random();
-}
-
-Data.uid = 1;
-Data.accepts = jQuery.acceptData;
-
-Data.prototype = {
- key: function( owner ) {
- // We can accept data for non-element nodes in modern browsers,
- // but we should not, see #8335.
- // Always return the key for a frozen object.
- if ( !Data.accepts( owner ) ) {
- return 0;
- }
-
- var descriptor = {},
- // Check if the owner object already has a cache key
- unlock = owner[ this.expando ];
-
- // If not, create one
- if ( !unlock ) {
- unlock = Data.uid++;
-
- // Secure it in a non-enumerable, non-writable property
- try {
- descriptor[ this.expando ] = { value: unlock };
- Object.defineProperties( owner, descriptor );
-
- // Support: Android < 4
- // Fallback to a less secure definition
- } catch ( e ) {
- descriptor[ this.expando ] = unlock;
- jQuery.extend( owner, descriptor );
- }
- }
-
- // Ensure the cache object
- if ( !this.cache[ unlock ] ) {
- this.cache[ unlock ] = {};
- }
-
- return unlock;
- },
- set: function( owner, data, value ) {
- var prop,
- // There may be an unlock assigned to this node,
- // if there is no entry for this "owner", create one
inline
- // and set the unlock as though an owner entry had
always existed
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
-
- // Handle: [ owner, key, value ] args
- if ( typeof data === "string" ) {
- cache[ data ] = value;
-
- // Handle: [ owner, { properties } ] args
- } else {
- // Fresh assignments by object are shallow copied
- if ( jQuery.isEmptyObject( cache ) ) {
- jQuery.extend( this.cache[ unlock ], data );
- // Otherwise, copy the properties one-by-one to the
cache object
- } else {
- for ( prop in data ) {
- cache[ prop ] = data[ prop ];
- }
- }
- }
- return cache;
- },
- get: function( owner, key ) {
- // Either a valid cache is found, or will be created.
- // New caches will be created and the unlock returned,
- // allowing direct access to the newly created
- // empty data object. A valid owner object must be provided.
- var cache = this.cache[ this.key( owner ) ];
-
- return key === undefined ?
- cache : cache[ key ];
- },
- access: function( owner, key, value ) {
- var stored;
- // In cases where either:
- //
- // 1. No key was specified
- // 2. A string key was specified, but no value provided
- //
- // Take the "read" path and allow the get method to determine
- // which value to return, respectively either:
- //
- // 1. The entire cache object
- // 2. The data stored at the key
- //
- if ( key === undefined ||
- ((key && typeof key === "string") && value ===
undefined) ) {
-
- stored = this.get( owner, key );
-
- return stored !== undefined ?
- stored : this.get( owner, jQuery.camelCase(key)
);
- }
-
- // [*]When the key is not a string, or both a key and value
- // are specified, set or extend (existing objects) with either:
- //
- // 1. An object of properties
- // 2. A key and value
- //
- this.set( owner, key, value );
-
- // Since the "set" path can have two possible entry points
- // return the expected data based on which path was taken[*]
- return value !== undefined ? value : key;
- },
- remove: function( owner, key ) {
- var i, name, camel,
- unlock = this.key( owner ),
- cache = this.cache[ unlock ];
-
- if ( key === undefined ) {
- this.cache[ unlock ] = {};
-
- } else {
- // Support array or space separated string of keys
- if ( jQuery.isArray( key ) ) {
- // If "name" is an array of keys...
- // When data is initially created, via ("key",
"val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key
was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument
path.
- name = key.concat( key.map( jQuery.camelCase )
);
- } else {
- camel = jQuery.camelCase( key );
- // Try the string as a key before any
manipulation
- if ( key in cache ) {
- name = [ key, camel ];
- } else {
- // If a key with the spaces exists, use
it.
- // Otherwise, create an array by
matching non-whitespace
- name = camel;
- name = name in cache ?
- [ name ] : ( name.match(
rnotwhite ) || [] );
- }
- }
-
- i = name.length;
- while ( i-- ) {
- delete cache[ name[ i ] ];
- }
- }
- },
- hasData: function( owner ) {
- return !jQuery.isEmptyObject(
- this.cache[ owner[ this.expando ] ] || {}
- );
- },
- discard: function( owner ) {
- if ( owner[ this.expando ] ) {
- delete this.cache[ owner[ this.expando ] ];
- }
- }
-};
-var data_priv = new Data();
-
-var data_user = new Data();
-
-
-
-/*
- Implementation Summary
-
- 1. Enforce API surface and semantic compatibility with 1.9.x branch
- 2. Improve the module's maintainability by reducing the storage
- paths to a single mechanism.
- 3. Use the same single mechanism to support "private" and "user" data.
- 4. _Never_ expose "private" data to user code (TODO: Drop _data,
_removeData)
- 5. Avoid exposing implementation details on user objects (eg. expando
properties)
- 6. Provide a clear path for implementation upgrade to WeakMap in 2014
-*/
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /([A-Z])/g;
-
-function dataAttr( elem, key, data ) {
- var name;
-
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
- name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- // Only convert to a number if it
doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON(
data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- data_user.set( elem, key, data );
- } else {
- data = undefined;
- }
- }
- return data;
-}
-
-jQuery.extend({
- hasData: function( elem ) {
- return data_user.hasData( elem ) || data_priv.hasData( elem );
- },
-
- data: function( elem, name, data ) {
- return data_user.access( elem, name, data );
- },
-
- removeData: function( elem, name ) {
- data_user.remove( elem, name );
- },
-
- // TODO: Now that all calls to _data and _removeData have been replaced
- // with direct calls to data_priv methods, these can be deprecated.
- _data: function( elem, name, data ) {
- return data_priv.access( elem, name, data );
- },
-
- _removeData: function( elem, name ) {
- data_priv.remove( elem, name );
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var i, name, data,
- elem = this[ 0 ],
- attrs = elem && elem.attributes;
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = data_user.get( elem );
-
- if ( elem.nodeType === 1 && !data_priv.get(
elem, "hasDataAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
-
- // Support: IE11+
- // The attrs elements can be
null (#14894)
- if ( attrs[ i ] ) {
- name = attrs[ i ].name;
- if ( name.indexOf(
"data-" ) === 0 ) {
- name =
jQuery.camelCase( name.slice(5) );
- dataAttr( elem,
name, data[ name ] );
- }
- }
- }
- data_priv.set( elem, "hasDataAttrs",
true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each(function() {
- data_user.set( this, key );
- });
- }
-
- return access( this, function( value ) {
- var data,
- camelKey = jQuery.camelCase( key );
-
- // The calling jQuery object (element matches) is not
empty
- // (and therefore has an element appears at this[ 0 ])
and the
- // `value` parameter was not undefined. An empty jQuery
object
- // will result in `undefined` for elem = this[ 0 ]
which will
- // throw an exception if an attempt to read a data
cache is made.
- if ( elem && value === undefined ) {
- // Attempt to get data from the cache
- // with the key as-is
- data = data_user.get( elem, key );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to get data from the cache
- // with the key camelized
- data = data_user.get( elem, camelKey );
- if ( data !== undefined ) {
- return data;
- }
-
- // Attempt to "discover" the data in
- // HTML5 custom data-* attrs
- data = dataAttr( elem, camelKey, undefined );
- if ( data !== undefined ) {
- return data;
- }
-
- // We tried really hard, but the data doesn't
exist.
- return;
- }
-
- // Set the data...
- this.each(function() {
- // First, attempt to store a copy or reference
of any
- // data that might've been store with a
camelCased key.
- var data = data_user.get( this, camelKey );
-
- // For HTML5 data-* attribute interop, we have
to
- // store property names with dashes in a
camelCase form.
- // This might not apply to all properties...*
- data_user.set( this, camelKey, value );
-
- // *... In the case of properties that might
_actually_
- // have dashes, we need to also store a copy of
that
- // unchanged property.
- if ( key.indexOf("-") !== -1 && data !==
undefined ) {
- data_user.set( this, key, value );
- }
- });
- }, null, value, arguments.length > 1, null, true );
- },
-
- removeData: function( key ) {
- return this.each(function() {
- data_user.remove( this, key );
- });
- }
-});
-
-
-jQuery.extend({
- queue: function( elem, type, data ) {
- var queue;
-
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = data_priv.get( elem, type );
-
- // Speed up dequeue by getting out quickly if this is
just a lookup
- if ( data ) {
- if ( !queue || jQuery.isArray( data ) ) {
- queue = data_priv.access( elem, type,
jQuery.makeArray(data) );
- } else {
- queue.push( data );
- }
- }
- return queue || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
-
- // If the fx queue is dequeued, always remove the progress
sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
-
- if ( fn ) {
-
- // Add a progress sentinel to prevent the fx queue from
being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- // clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
- }
- },
-
- // not intended for public consumption - generates a queueHooks object,
or returns the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return data_priv.get( elem, key ) || data_priv.access( elem,
key, {
- empty: jQuery.Callbacks("once memory").add(function() {
- data_priv.remove( elem, [ type + "queue", key ]
);
- })
- });
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
- }
-
- return data === undefined ?
- this :
- this.each(function() {
- var queue = jQuery.queue( this, type, data );
-
- // ensure a hooks for this queue
- jQuery._queueHooks( this, type );
-
- if ( type === "fx" && queue[0] !== "inprogress"
) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements
] );
- }
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
-
- while ( i-- ) {
- tmp = data_priv.get( elements[ i ], type + "queueHooks"
);
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
- }
- }
- resolve();
- return defer.promise( obj );
- }
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
- // isHidden might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" ||
!jQuery.contains( elem.ownerDocument, elem );
- };
-
-var rcheckableType = (/^(?:checkbox|radio)$/i);
-
-
-
-(function() {
- var fragment = document.createDocumentFragment(),
- div = fragment.appendChild( document.createElement( "div" ) ),
- input = document.createElement( "input" );
-
- // #11217 - WebKit loses check when the name is after the checked
attribute
- // Support: Windows Web Apps (WWA)
- // `name` and `type` need .setAttribute for WWA
- input.setAttribute( "type", "radio" );
- input.setAttribute( "checked", "checked" );
- input.setAttribute( "name", "t" );
-
- div.appendChild( input );
-
- // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
- // old WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true
).lastChild.checked;
-
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- // Support: IE9-IE11+
- div.innerHTML = "<textarea>x</textarea>";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-})();
-var strundefined = typeof undefined;
-
-
-
-support.focusinBubbles = "onfocusin" in window;
-
-
-var
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
-
-function returnTrue() {
- return true;
-}
-
-function returnFalse() {
- return false;
-}
-
-function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
- global: {},
-
- add: function( elem, types, handler, data, selector ) {
-
- var handleObjIn, eventHandle, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.get( elem );
-
- // Don't attach events to noData or text/comment nodes (but
allow plain objects)
- if ( !elemData ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the
handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to
find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this
is the first
- if ( !(events = elemData.events) ) {
- events = elemData.events = {};
- }
- if ( !(eventHandle = elemData.handle) ) {
- eventHandle = elemData.handle = function( e ) {
- // Discard the second event of a
jQuery.event.trigger() and
- // when an event is called after a page has
unloaded
- return typeof jQuery !== strundefined &&
jQuery.event.triggered !== e.type ?
- jQuery.event.dispatch.apply( elem,
arguments ) : undefined;
- };
- }
-
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only
handlers
- if ( !type ) {
- continue;
- }
-
- // If event changes its type, use the special event
handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api
type, otherwise given type
- type = ( selector ? special.delegateType :
special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector &&
jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener if the special
events handler returns false
- if ( !special.setup || special.setup.call(
elem, data, namespaces, eventHandle ) === false ) {
- if ( elem.addEventListener ) {
- elem.addEventListener( type,
eventHandle, false );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0,
handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for
event optimization
- jQuery.event.global[ type ] = true;
- }
-
- },
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
-
- var j, origCount, tmp,
- events, t, handleObj,
- special, handlers, type, namespaces, origType,
- elemData = data_priv.hasData( elem ) && data_priv.get(
elem );
-
- if ( !elemData || !(events = elemData.events) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // Unbind all events (on this namespace, if provided)
for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type +
types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType :
special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" +
namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
-
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
-
- if ( ( mappedTypes || origType ===
handleObj.origType ) &&
- ( !handler || handler.guid ===
handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace
) ) &&
- ( !selector || selector ===
handleObj.selector || selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
-
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem,
handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something
and no more handlers exist
- // (avoids potential for endless recursion during
removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown ||
special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
- jQuery.removeEvent( elem, type,
elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- delete elemData.handle;
- data_priv.remove( elem, "events" );
- }
- },
-
- trigger: function( event, data, elem, onlyHandlers ) {
-
- var i, cur, tmp, bubbleType, ontype, handle, special,
- eventPath = [ elem || document ],
- type = hasOwn.call( event, "type" ) ? event.type :
event,
- namespaces = hasOwn.call( event, "namespace" ) ?
event.namespace.split(".") : [];
-
- cur = tmp = elem = elem || document;
-
- // Don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // focus/blur morphs to focusin/out; ensure we're not firing
them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf(".") >= 0 ) {
- // Namespaced trigger; create a regexp to match event
type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf(":") < 0 && "on" + type;
-
- // Caller can pass in a jQuery.Event object, Object, or just an
event type string
- event = event[ jQuery.expando ] ?
- event :
- new jQuery.Event( type, typeof event === "object" &&
event );
-
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery
(always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" +
namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
- null;
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the
handler arg list
- data = data == null ?
- [ event ] :
- jQuery.makeArray( data, [ event ] );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( !onlyHandlers && special.trigger && special.trigger.apply(
elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events
spec (#9951)
- // Bubble up to document, then to window; watch for a global
ownerDocument var (#9724)
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow(
elem ) ) {
-
- bubbleType = special.delegateType || type;
- if ( !rfocusMorph.test( bubbleType + type ) ) {
- cur = cur.parentNode;
- }
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push( cur );
- tmp = cur;
- }
-
- // Only add window if we got to document (e.g., not
plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
- eventPath.push( tmp.defaultView ||
tmp.parentWindow || window );
- }
- }
-
- // Fire handlers on the event path
- i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped()
) {
-
- event.type = i > 1 ?
- bubbleType :
- special.bindType || type;
-
- // jQuery handler
- handle = ( data_priv.get( cur, "events" ) || {} )[
event.type ] && data_priv.get( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
-
- // Native handler
- handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur )
) {
- event.result = handle.apply( cur, data );
- if ( event.result === false ) {
- event.preventDefault();
- }
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( (!special._default || special._default.apply(
eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
-
- // Call a native DOM method on the target with
the same name name as the event.
- // Don't do default actions on window, that's
where global variables be (#6170)
- if ( ontype && jQuery.isFunction( elem[ type ]
) && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when
we call its FOO() method
- tmp = elem[ ontype ];
-
- if ( tmp ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same
event, since we already bubbled it above
- jQuery.event.triggered = type;
- elem[ type ]();
- jQuery.event.triggered = undefined;
-
- if ( tmp ) {
- elem[ ontype ] = tmp;
- }
- }
- }
- }
-
- return event.result;
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
-
- var i, j, ret, matched, handleObj,
- handlerQueue = [],
- args = slice.call( arguments ),
- handlers = ( data_priv.get( this, "events" ) || {} )[
event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
-
- // Use the fix-ed jQuery.Event rather than the (read-only)
native event
- args[0] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it
bail if desired
- if ( special.preDispatch && special.preDispatch.call( this,
event ) === false ) {
- return;
- }
-
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event,
handlers );
-
- // Run delegates first; they may want to stop propagation
beneath us
- i = 0;
- while ( (matched = handlerQueue[ i++ ]) &&
!event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
-
- j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) &&
!event.isImmediatePropagationStopped() ) {
-
- // Triggered event must either 1) have no
namespace, or
- // 2) have namespace(s) a subset or equal to
those in the bound event (both can have no namespace).
- if ( !event.namespace_re ||
event.namespace_re.test( handleObj.namespace ) ) {
-
- event.handleObj = handleObj;
- event.data = handleObj.data;
-
- ret = ( (jQuery.event.special[
handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem,
args );
-
- if ( ret !== undefined ) {
- if ( (event.result = ret) ===
false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- handlers: function( event, handlers ) {
- var i, matches, sel, handleObj,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
-
- // Find delegate handlers
- // Black-hole SVG <use> instance trees (#13180)
- // Avoid non-left-click bubbling in Firefox (#3861)
- if ( delegateCount && cur.nodeType && (!event.button ||
event.type !== "click") ) {
-
- for ( ; cur !== this; cur = cur.parentNode || this ) {
-
- // Don't process clicks on disabled elements
(#6911, #8165, #11382, #11764)
- if ( cur.disabled !== true || event.type !==
"click" ) {
- matches = [];
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
-
- // Don't conflict with
Object.prototype properties (#13203)
- sel = handleObj.selector + " ";
-
- if ( matches[ sel ] ===
undefined ) {
- matches[ sel ] =
handleObj.needsContext ?
- jQuery( sel,
this ).index( cur ) >= 0 :
- jQuery.find(
sel, this, null, [ cur ] ).length;
- }
- if ( matches[ sel ] ) {
- matches.push( handleObj
);
- }
- }
- if ( matches.length ) {
- handlerQueue.push({ elem: cur,
handlers: matches });
- }
- }
- }
- }
-
- // Add the remaining (directly-bound) handlers
- if ( delegateCount < handlers.length ) {
- handlerQueue.push({ elem: this, handlers:
handlers.slice( delegateCount ) });
- }
-
- return handlerQueue;
- },
-
- // Includes some event props shared by KeyEvent and MouseEvent
- props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase
metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split(" "),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ?
original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: "button buttons clientX clientY offsetX offsetY pageX
pageY screenX screenY toElement".split(" "),
- filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument ||
document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX + ( doc &&
doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft ||
body && body.clientLeft || 0 );
- event.pageY = original.clientY + ( doc &&
doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop ||
body && body.clientTop || 0 );
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 ===
right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ?
3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize
some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) :
this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: Cordova 2.5 (WebKit) (#13255)
- // All events should have a target; Cordova deviceready doesn't
- if ( !event.target ) {
- event.target = document;
- }
-
- // Support: Safari 6.0+, Chrome < 28
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- return fixHook.filter ? fixHook.filter( event, originalEvent )
: event;
- },
-
- special: {
- load: {
- // Prevent triggered image.load events from bubbling to
window.load
- noBubble: true
- },
- focus: {
- // Fire native event if possible so blur/focus sequence
is correct
- trigger: function() {
- if ( this !== safeActiveElement() && this.focus
) {
- this.focus();
- return false;
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function() {
- if ( this === safeActiveElement() && this.blur
) {
- this.blur();
- return false;
- }
- },
- delegateType: "focusout"
- },
- click: {
- // For checkbox, fire native event so checked state
will be right
- trigger: function() {
- if ( this.type === "checkbox" && this.click &&
jQuery.nodeName( this, "input" ) ) {
- this.click();
- return false;
- }
- },
-
- // For cross-browser consistency, don't fire native
.click() on links
- _default: function( event ) {
- return jQuery.nodeName( event.target, "a" );
- }
- },
-
- beforeunload: {
- postDispatch: function( event ) {
-
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue
field is not set.
- if ( event.result !== undefined &&
event.originalEvent ) {
- event.originalEvent.returnValue =
event.result;
- }
- }
- }
- },
-
- simulate: function( type, elem, event, bubble ) {
- // Piggyback on a donor event to simulate a different one.
- // Fake originalEvent to avoid donor's stopPropagation, but if
the
- // simulated event prevents default then we do the same on the
donor.
- var e = jQuery.extend(
- new jQuery.Event(),
- event,
- {
- type: type,
- isSimulated: true,
- originalEvent: {}
- }
- );
- if ( bubble ) {
- jQuery.event.trigger( e, null, elem );
- } else {
- jQuery.event.dispatch.call( elem, e );
- }
- if ( e.isDefaultPrevented() ) {
- event.preventDefault();
- }
- }
-};
-
-jQuery.removeEvent = function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
-};
-
-jQuery.Event = function( src, props ) {
- // Allow instantiation without the 'new' keyword
- if ( !(this instanceof jQuery.Event) ) {
- return new jQuery.Event( src, props );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as
prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented ||
- src.defaultPrevented === undefined &&
- // Support: Android < 4.0
- src.returnValue === false ?
- returnTrue :
- returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
- }
-
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript
Language Binding
-//
http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
-
- preventDefault: function() {
- var e = this.originalEvent;
-
- this.isDefaultPrevented = returnTrue;
-
- if ( e && e.preventDefault ) {
- e.preventDefault();
- }
- },
- stopPropagation: function() {
- var e = this.originalEvent;
-
- this.isPropagationStopped = returnTrue;
-
- if ( e && e.stopPropagation ) {
- e.stopPropagation();
- }
- },
- stopImmediatePropagation: function() {
- var e = this.originalEvent;
-
- this.isImmediatePropagationStopped = returnTrue;
-
- if ( e && e.stopImmediatePropagation ) {
- e.stopImmediatePropagation();
- }
-
- this.stopPropagation();
- }
-};
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-// Support: Chrome 15+
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
-
- handle: function( event ) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj;
-
- // For mousenter/leave call the handler if related is
outside the target.
- // NB: No relatedTarget if the mouse left/entered the
browser window
- if ( !related || (related !== target &&
!jQuery.contains( target, related )) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments
);
- event.type = fix;
- }
- return ret;
- }
- };
-});
-
-// Create "bubbling" focus and blur events
-// Support: Firefox, Chrome, Safari
-if ( !support.focusinBubbles ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix
) {
-
- // Attach a single capturing handler on the document while
someone wants focusin/focusout
- var handler = function( event ) {
- jQuery.event.simulate( fix, event.target,
jQuery.event.fix( event ), true );
- };
-
- jQuery.event.special[ fix ] = {
- setup: function() {
- var doc = this.ownerDocument || this,
- attaches = data_priv.access( doc, fix );
-
- if ( !attaches ) {
- doc.addEventListener( orig, handler,
true );
- }
- data_priv.access( doc, fix, ( attaches || 0 ) +
1 );
- },
- teardown: function() {
- var doc = this.ownerDocument || this,
- attaches = data_priv.access( doc, fix )
- 1;
-
- if ( !attaches ) {
- doc.removeEventListener( orig, handler,
true );
- data_priv.remove( doc, fix );
-
- } else {
- data_priv.access( doc, fix, attaches );
- }
- }
- };
- });
-}
-
-jQuery.fn.extend({
-
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var origFn, type;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- this.on( type, selector, data, types[ type ],
one );
- }
- return this;
- }
-
- if ( data == null && fn == null ) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return this;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
- // Can use an empty set, since event contains
the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++
);
- }
- return this.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- });
- },
- one: function( types, selector, data, fn ) {
- return this.on( types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- var handleObj, type;
- if ( types && types.preventDefault && types.handleObj ) {
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ? handleObj.origType + "."
+ handleObj.namespace : handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
- }
- if ( typeof types === "object" ) {
- // ( types-object [, selector] )
- for ( type in types ) {
- this.off( type, selector, types[ type ] );
- }
- return this;
- }
- if ( selector === false || typeof selector === "function" ) {
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if ( fn === false ) {
- fn = returnFalse;
- }
- return this.each(function() {
- jQuery.event.remove( this, types, fn, selector );
- });
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
- triggerHandler: function( type, data ) {
- var elem = this[0];
- if ( elem ) {
- return jQuery.event.trigger( type, data, elem, true );
- }
- }
-});
-
-
-var
- rxhtmlTag =
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
- rtagName = /<([\w:]+)/,
- rhtml = /<|&#?\w+;/,
- rnoInnerhtml = /<(?:script|style|link)/i,
- // checked="checked" or checked
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- rscriptType = /^$|\/(?:java|ecma)script/i,
- rscriptTypeMasked = /^true\/(.*)/,
- rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
-
- // We have to close these tags to support XHTML (#13200)
- wrapMap = {
-
- // Support: IE 9
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
-
- thead: [ 1, "<table>", "</table>" ],
- col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
- _default: [ 0, "", "" ]
- };
-
-// Support: IE 9
-wrapMap.optgroup = wrapMap.option;
-
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption =
wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// Support: 1.x compatibility
-// Manipulating tables requires a tbody
-function manipulationTarget( elem, content ) {
- return jQuery.nodeName( elem, "table" ) &&
- jQuery.nodeName( content.nodeType !== 11 ? content :
content.firstChild, "tr" ) ?
-
- elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild(
elem.ownerDocument.createElement("tbody") ) :
- elem;
-}
-
-// Replace/restore the type attribute of script elements for safe DOM
manipulation
-function disableScript( elem ) {
- elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
- return elem;
-}
-function restoreScript( elem ) {
- var match = rscriptTypeMasked.exec( elem.type );
-
- if ( match ) {
- elem.type = match[ 1 ];
- } else {
- elem.removeAttribute("type");
- }
-
- return elem;
-}
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
- var i = 0,
- l = elems.length;
-
- for ( ; i < l; i++ ) {
- data_priv.set(
- elems[ i ], "globalEval", !refElements ||
data_priv.get( refElements[ i ], "globalEval" )
- );
- }
-}
-
-function cloneCopyEvent( src, dest ) {
- var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
-
- if ( dest.nodeType !== 1 ) {
- return;
- }
-
- // 1. Copy private data: events, handlers, etc.
- if ( data_priv.hasData( src ) ) {
- pdataOld = data_priv.access( src );
- pdataCur = data_priv.set( dest, pdataOld );
- events = pdataOld.events;
-
- if ( events ) {
- delete pdataCur.handle;
- pdataCur.events = {};
-
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l;
i++ ) {
- jQuery.event.add( dest, type, events[
type ][ i ] );
- }
- }
- }
- }
-
- // 2. Copy user data
- if ( data_user.hasData( src ) ) {
- udataOld = data_user.access( src );
- udataCur = jQuery.extend( {}, udataOld );
-
- data_user.set( dest, udataCur );
- }
-}
-
-function getAll( context, tag ) {
- var ret = context.getElementsByTagName ? context.getElementsByTagName(
tag || "*" ) :
- context.querySelectorAll ? context.querySelectorAll(
tag || "*" ) :
- [];
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], ret ) :
- ret;
-}
-
-// Support: IE >= 9
-function fixInput( src, dest ) {
- var nodeName = dest.nodeName.toLowerCase();
-
- // Fails to persist the checked state of a cloned checkbox or radio
button.
- if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
- dest.checked = src.checked;
-
- // Fails to return the selected option to the default selected state
when cloning options
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
- }
-}
-
-jQuery.extend({
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var i, l, srcElements, destElements,
- clone = elem.cloneNode( true ),
- inPage = jQuery.contains( elem.ownerDocument, elem );
-
- // Support: IE >= 9
- // Fix Cloning issues
- if ( !support.noCloneChecked && ( elem.nodeType === 1 ||
elem.nodeType === 11 ) &&
- !jQuery.isXMLDoc( elem ) ) {
-
- // We eschew Sizzle here for performance reasons:
http://jsperf.com/getall-vs-sizzle/2
- destElements = getAll( clone );
- srcElements = getAll( elem );
-
- for ( i = 0, l = srcElements.length; i < l; i++ ) {
- fixInput( srcElements[ i ], destElements[ i ] );
- }
- }
-
- // Copy the events from the original to the clone
- if ( dataAndEvents ) {
- if ( deepDataAndEvents ) {
- srcElements = srcElements || getAll( elem );
- destElements = destElements || getAll( clone );
-
- for ( i = 0, l = srcElements.length; i < l; i++
) {
- cloneCopyEvent( srcElements[ i ],
destElements[ i ] );
- }
- } else {
- cloneCopyEvent( elem, clone );
- }
- }
-
- // Preserve script evaluation history
- destElements = getAll( clone, "script" );
- if ( destElements.length > 0 ) {
- setGlobalEval( destElements, !inPage && getAll( elem,
"script" ) );
- }
-
- // Return the cloned set
- return clone;
- },
-
- buildFragment: function( elems, context, scripts, selection ) {
- var elem, tmp, tag, wrap, contains, j,
- fragment = context.createDocumentFragment(),
- nodes = [],
- i = 0,
- l = elems.length;
-
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
-
- if ( elem || elem === 0 ) {
-
- // Add nodes directly
- if ( jQuery.type( elem ) === "object" ) {
- // Support: QtWebKit
- // jQuery.merge because push.apply(_,
arraylike) throws
- jQuery.merge( nodes, elem.nodeType ? [
elem ] : elem );
-
- // Convert non-html into a text node
- } else if ( !rhtml.test( elem ) ) {
- nodes.push( context.createTextNode(
elem ) );
-
- // Convert html into DOM nodes
- } else {
- tmp = tmp || fragment.appendChild(
context.createElement("div") );
-
- // Deserialize a standard representation
- tag = ( rtagName.exec( elem ) || [ "",
"" ] )[ 1 ].toLowerCase();
- wrap = wrapMap[ tag ] ||
wrapMap._default;
- tmp.innerHTML = wrap[ 1 ] +
elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
-
- // Descend through wrappers to the
right content
- j = wrap[ 0 ];
- while ( j-- ) {
- tmp = tmp.lastChild;
- }
-
- // Support: QtWebKit
- // jQuery.merge because push.apply(_,
arraylike) throws
- jQuery.merge( nodes, tmp.childNodes );
-
- // Remember the top-level container
- tmp = fragment.firstChild;
-
- // Fixes #12346
- // Support: Webkit, IE
- tmp.textContent = "";
- }
- }
- }
-
- // Remove wrapper from fragment
- fragment.textContent = "";
-
- i = 0;
- while ( (elem = nodes[ i++ ]) ) {
-
- // #4087 - If origin and destination elements are the
same, and this is
- // that element, do not do anything
- if ( selection && jQuery.inArray( elem, selection ) !==
-1 ) {
- continue;
- }
-
- contains = jQuery.contains( elem.ownerDocument, elem );
-
- // Append to fragment
- tmp = getAll( fragment.appendChild( elem ), "script" );
-
- // Preserve script evaluation history
- if ( contains ) {
- setGlobalEval( tmp );
- }
-
- // Capture executables
- if ( scripts ) {
- j = 0;
- while ( (elem = tmp[ j++ ]) ) {
- if ( rscriptType.test( elem.type || ""
) ) {
- scripts.push( elem );
- }
- }
- }
- }
-
- return fragment;
- },
-
- cleanData: function( elems ) {
- var data, elem, type, key,
- special = jQuery.event.special,
- i = 0;
-
- for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
- if ( jQuery.acceptData( elem ) ) {
- key = elem[ data_priv.expando ];
-
- if ( key && (data = data_priv.cache[ key ]) ) {
- if ( data.events ) {
- for ( type in data.events ) {
- if ( special[ type ] ) {
-
jQuery.event.remove( elem, type );
-
- // This is a shortcut
to avoid jQuery.event.remove's overhead
- } else {
-
jQuery.removeEvent( elem, type, data.handle );
- }
- }
- }
- if ( data_priv.cache[ key ] ) {
- // Discard any remaining
`private` data
- delete data_priv.cache[ key ];
- }
- }
- }
- // Discard any remaining `user` data
- delete data_user.cache[ elem[ data_user.expando ] ];
- }
- }
-});
-
-jQuery.fn.extend({
- text: function( value ) {
- return access( this, function( value ) {
- return value === undefined ?
- jQuery.text( this ) :
- this.empty().each(function() {
- if ( this.nodeType === 1 ||
this.nodeType === 11 || this.nodeType === 9 ) {
- this.textContent = value;
- }
- });
- }, null, value, arguments.length );
- },
-
- append: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 ||
this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.appendChild( elem );
- }
- });
- },
-
- prepend: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 ||
this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.insertBefore( elem, target.firstChild );
- }
- });
- },
-
- before: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this );
- }
- });
- },
-
- after: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem,
this.nextSibling );
- }
- });
- },
-
- remove: function( selector, keepData /* Internal Use Only */ ) {
- var elem,
- elems = selector ? jQuery.filter( selector, this ) :
this,
- i = 0;
-
- for ( ; (elem = elems[i]) != null; i++ ) {
- if ( !keepData && elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem ) );
- }
-
- if ( elem.parentNode ) {
- if ( keepData && jQuery.contains(
elem.ownerDocument, elem ) ) {
- setGlobalEval( getAll( elem, "script" )
);
- }
- elem.parentNode.removeChild( elem );
- }
- }
-
- return this;
- },
-
- empty: function() {
- var elem,
- i = 0;
-
- for ( ; (elem = this[i]) != null; i++ ) {
- if ( elem.nodeType === 1 ) {
-
- // Prevent memory leaks
- jQuery.cleanData( getAll( elem, false ) );
-
- // Remove any remaining nodes
- elem.textContent = "";
- }
- }
-
- return this;
- },
-
- clone: function( dataAndEvents, deepDataAndEvents ) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents :
deepDataAndEvents;
-
- return this.map(function() {
- return jQuery.clone( this, dataAndEvents,
deepDataAndEvents );
- });
- },
-
- html: function( value ) {
- return access( this, function( value ) {
- var elem = this[ 0 ] || {},
- i = 0,
- l = this.length;
-
- if ( value === undefined && elem.nodeType === 1 ) {
- return elem.innerHTML;
- }
-
- // See if we can take a shortcut and just use innerHTML
- if ( typeof value === "string" && !rnoInnerhtml.test(
value ) &&
- !wrapMap[ ( rtagName.exec( value ) || [ "", ""
] )[ 1 ].toLowerCase() ] ) {
-
- value = value.replace( rxhtmlTag, "<$1></$2>" );
-
- try {
- for ( ; i < l; i++ ) {
- elem = this[ i ] || {};
-
- // Remove element nodes and
prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData(
getAll( elem, false ) );
- elem.innerHTML = value;
- }
- }
-
- elem = 0;
-
- // If using innerHTML throws an exception, use
the fallback method
- } catch( e ) {}
- }
-
- if ( elem ) {
- this.empty().append( value );
- }
- }, null, value, arguments.length );
- },
-
- replaceWith: function() {
- var arg = arguments[ 0 ];
-
- // Make the changes, replacing each context element with the
new content
- this.domManip( arguments, function( elem ) {
- arg = this.parentNode;
-
- jQuery.cleanData( getAll( this ) );
-
- if ( arg ) {
- arg.replaceChild( elem, this );
- }
- });
-
- // Force removal if there was no new content (e.g., from empty
arguments)
- return arg && (arg.length || arg.nodeType) ? this :
this.remove();
- },
-
- detach: function( selector ) {
- return this.remove( selector, true );
- },
-
- domManip: function( args, callback ) {
-
- // Flatten any nested arrays
- args = concat.apply( [], args );
-
- var fragment, first, scripts, hasScripts, node, doc,
- i = 0,
- l = this.length,
- set = this,
- iNoClone = l - 1,
- value = args[ 0 ],
- isFunction = jQuery.isFunction( value );
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( isFunction ||
- ( l > 1 && typeof value === "string" &&
- !support.checkClone && rchecked.test(
value ) ) ) {
- return this.each(function( index ) {
- var self = set.eq( index );
- if ( isFunction ) {
- args[ 0 ] = value.call( this, index,
self.html() );
- }
- self.domManip( args, callback );
- });
- }
-
- if ( l ) {
- fragment = jQuery.buildFragment( args, this[ 0
].ownerDocument, false, this );
- first = fragment.firstChild;
-
- if ( fragment.childNodes.length === 1 ) {
- fragment = first;
- }
-
- if ( first ) {
- scripts = jQuery.map( getAll( fragment,
"script" ), disableScript );
- hasScripts = scripts.length;
-
- // Use the original fragment for the last item
instead of the first because it can end up
- // being emptied incorrectly in certain
situations (#8070).
- for ( ; i < l; i++ ) {
- node = fragment;
-
- if ( i !== iNoClone ) {
- node = jQuery.clone( node,
true, true );
-
- // Keep references to cloned
scripts for later restoration
- if ( hasScripts ) {
- // Support: QtWebKit
- // jQuery.merge because
push.apply(_, arraylike) throws
- jQuery.merge( scripts,
getAll( node, "script" ) );
- }
- }
-
- callback.call( this[ i ], node, i );
- }
-
- if ( hasScripts ) {
- doc = scripts[ scripts.length - 1
].ownerDocument;
-
- // Reenable scripts
- jQuery.map( scripts, restoreScript );
-
- // Evaluate executable scripts on first
document insertion
- for ( i = 0; i < hasScripts; i++ ) {
- node = scripts[ i ];
- if ( rscriptType.test(
node.type || "" ) &&
- !data_priv.access(
node, "globalEval" ) && jQuery.contains( doc, node ) ) {
-
- if ( node.src ) {
- // Optional
AJAX dependency, but won't run scripts if not present
- if (
jQuery._evalUrl ) {
-
jQuery._evalUrl( node.src );
- }
- } else {
-
jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
- }
- }
- }
- }
- }
- }
-
- return this;
- }
-});
-
-jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
-}, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var elems,
- ret = [],
- insert = jQuery( selector ),
- last = insert.length - 1,
- i = 0;
-
- for ( ; i <= last; i++ ) {
- elems = i === last ? this : this.clone( true );
- jQuery( insert[ i ] )[ original ]( elems );
-
- // Support: QtWebKit
- // .get() because push.apply(_, arraylike) throws
- push.apply( ret, elems.get() );
- }
-
- return this.pushStack( ret );
- };
-});
-
-
-var iframe,
- elemdisplay = {};
-
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
- var style,
- elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
- // getDefaultComputedStyle might be reliably used only on
attached element
- display = window.getDefaultComputedStyle && ( style =
window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
-
- // Use of this method is a temporary fix (more like
optmization) until something better comes along,
- // since it was removed from specification and
supported only in FF
- style.display : jQuery.css( elem[ 0 ], "display" );
-
- // We don't have any data stored on the element,
- // so use "detach" method as fast way to get rid of the element
- elem.detach();
-
- return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
- var doc = document,
- display = elemdisplay[ nodeName ];
-
- if ( !display ) {
- display = actualDisplay( nodeName, doc );
-
- // If the simple way fails, read from inside an iframe
- if ( display === "none" || !display ) {
-
- // Use the already-created iframe if possible
- iframe = (iframe || jQuery( "<iframe frameborder='0'
width='0' height='0'/>" )).appendTo( doc.documentElement );
-
- // Always write a new HTML skeleton so Webkit and
Firefox don't choke on reuse
- doc = iframe[ 0 ].contentDocument;
-
- // Support: IE
- doc.write();
- doc.close();
-
- display = actualDisplay( nodeName, doc );
- iframe.detach();
- }
-
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
- }
-
- return display;
-}
-var rmargin = (/^margin/);
-
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-var getStyles = function( elem ) {
- return elem.ownerDocument.defaultView.getComputedStyle( elem,
null );
- };
-
-
-
-function curCSS( elem, name, computed ) {
- var width, minWidth, maxWidth, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
-
- // Support: IE9
- // getPropertyValue is only needed for .css('filter') in IE9, see #12537
- if ( computed ) {
- ret = computed.getPropertyValue( name ) || computed[ name ];
- }
-
- if ( computed ) {
-
- if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem )
) {
- ret = jQuery.style( elem, name );
- }
-
- // Support: iOS < 6
- // A tribute to the "awesome hack by Dean Edwards"
- // iOS < 6 (at least) returns percentage for a larger set of
values, but width seems to be reliably pixels
- // this is against the CSSOM draft spec:
http://dev.w3.org/csswg/cssom/#resolved-values
- if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
- // Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth;
-
- // Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width;
-
- // Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
- }
- }
-
- return ret !== undefined ?
- // Support: IE
- // IE returns zIndex value as an integer.
- ret + "" :
- ret;
-}
-
-
-function addGetHookIf( conditionFn, hookFn ) {
- // Define the hook, we'll check on the first run if it's really needed.
- return {
- get: function() {
- if ( conditionFn() ) {
- // Hook not needed (or it's not possible to use
it due to missing dependency),
- // remove it.
- // Since there are no other hooks for
marginRight, remove the whole object.
- delete this.get;
- return;
- }
-
- // Hook needed; redefine it so that the support test is
not executed again.
-
- return (this.get = hookFn).apply( this, arguments );
- }
- };
-}
-
-
-(function() {
- var pixelPositionVal, boxSizingReliableVal,
- docElem = document.documentElement,
- container = document.createElement( "div" ),
- div = document.createElement( "div" );
-
- if ( !div.style ) {
- return;
- }
-
- div.style.backgroundClip = "content-box";
- div.cloneNode( true ).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
- container.style.cssText =
"border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
- "position:absolute";
- container.appendChild( div );
-
- // Executing both pixelPosition & boxSizingReliable tests require only
one layout
- // so they're executed at the same time to save the second computation.
- function computePixelPositionAndBoxSizingReliable() {
- div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
-
"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
-
"box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
- "border:1px;padding:1px;width:4px;position:absolute";
- div.innerHTML = "";
- docElem.appendChild( container );
-
- var divStyle = window.getComputedStyle( div, null );
- pixelPositionVal = divStyle.top !== "1%";
- boxSizingReliableVal = divStyle.width === "4px";
-
- docElem.removeChild( container );
- }
-
- // Support: node.js jsdom
- // Don't assume that getComputedStyle is a property of the global object
- if ( window.getComputedStyle ) {
- jQuery.extend( support, {
- pixelPosition: function() {
- // This test is executed only once but we still
do memoizing
- // since we can use the boxSizingReliable
pre-computing.
- // No need to check if the test was already
performed, though.
- computePixelPositionAndBoxSizingReliable();
- return pixelPositionVal;
- },
- boxSizingReliable: function() {
- if ( boxSizingReliableVal == null ) {
-
computePixelPositionAndBoxSizingReliable();
- }
- return boxSizingReliableVal;
- },
- reliableMarginRight: function() {
- // Support: Android 2.3
- // Check if div with explicit width and no
margin-right incorrectly
- // gets computed margin-right based on width of
container. (#3333)
- // WebKit Bug 13343 - getComputedStyle returns
wrong value for margin-right
- // This support function is only executed once
so no memoizing is needed.
- var ret,
- marginDiv = div.appendChild(
document.createElement( "div" ) );
-
- // Reset CSS: box-sizing; display; margin;
border; padding
- marginDiv.style.cssText = div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
-
"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
-
"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
- marginDiv.style.marginRight =
marginDiv.style.width = "0";
- div.style.width = "1px";
- docElem.appendChild( container );
-
- ret = !parseFloat( window.getComputedStyle(
marginDiv, null ).marginRight );
-
- docElem.removeChild( container );
-
- return ret;
- }
- });
- }
-})();
-
-
-// A method for quickly swapping in/out CSS properties to get correct
calculations.
-jQuery.swap = function( elem, options, callback, args ) {
- var ret, name,
- old = {};
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.apply( elem, args || [] );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
-};
-
-
-var
- // swappable if display is none or starts with table except "table",
"table-cell", or "table-caption"
- // see here for display values:
https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
- rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
- rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
-
- cssShow = { position: "absolute", visibility: "hidden", display:
"block" },
- cssNormalTransform = {
- letterSpacing: "0",
- fontWeight: "400"
- },
-
- cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
-
-// return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( style, name ) {
-
- // shortcut for names that are not vendor prefixed
- if ( name in style ) {
- return name;
- }
-
- // check for vendor prefixed names
- var capName = name[0].toUpperCase() + name.slice(1),
- origName = name,
- i = cssPrefixes.length;
-
- while ( i-- ) {
- name = cssPrefixes[ i ] + capName;
- if ( name in style ) {
- return name;
- }
- }
-
- return origName;
-}
-
-function setPositiveNumber( elem, value, subtract ) {
- var matches = rnumsplit.exec( value );
- return matches ?
- // Guard against undefined "subtract", e.g., when used as in
cssHooks
- Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2
] || "px" ) :
- value;
-}
-
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
- // If we already have the right measurement, avoid augmentation
- 4 :
- // Otherwise initialize for horizontal or vertical properties
- name === "width" ? 1 : 0,
-
- val = 0;
-
- for ( ; i < 4; i += 2 ) {
- // both box models exclude margin, so add it if we want it
- if ( extra === "margin" ) {
- val += jQuery.css( elem, extra + cssExpand[ i ], true,
styles );
- }
-
- if ( isBorderBox ) {
- // border-box includes padding, so remove it if we want
content
- if ( extra === "content" ) {
- val -= jQuery.css( elem, "padding" + cssExpand[
i ], true, styles );
- }
-
- // at this point, extra isn't border nor margin, so
remove border
- if ( extra !== "margin" ) {
- val -= jQuery.css( elem, "border" + cssExpand[
i ] + "Width", true, styles );
- }
- } else {
- // at this point, extra isn't content, so add padding
- val += jQuery.css( elem, "padding" + cssExpand[ i ],
true, styles );
-
- // at this point, extra isn't content nor padding, so
add border
- if ( extra !== "padding" ) {
- val += jQuery.css( elem, "border" + cssExpand[
i ] + "Width", true, styles );
- }
- }
- }
-
- return val;
-}
-
-function getWidthOrHeight( elem, name, extra ) {
-
- // Start with offset property, which is equivalent to the border-box
value
- var valueIsBorderBox = true,
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
- styles = getStyles( elem ),
- isBorderBox = jQuery.css( elem, "boxSizing", false, styles )
=== "border-box";
-
- // some non-html elements return undefined for offsetWidth, so check
for null/undefined
- // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
- // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
- if ( val <= 0 || val == null ) {
- // Fall back to computed then uncomputed css if necessary
- val = curCSS( elem, name, styles );
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
- }
-
- // Computed unit is not pixels. Stop here and return.
- if ( rnumnonpx.test(val) ) {
- return val;
- }
-
- // we need the check for style in case a browser which returns
unreliable values
- // for getComputedStyle silently falls back to the reliable
elem.style
- valueIsBorderBox = isBorderBox &&
- ( support.boxSizingReliable() || val === elem.style[
name ] );
-
- // Normalize "", auto, and prepare for extra
- val = parseFloat( val ) || 0;
- }
-
- // use the active box-sizing model to add/subtract irrelevant styles
- return ( val +
- augmentWidthOrHeight(
- elem,
- name,
- extra || ( isBorderBox ? "border" : "content" ),
- valueIsBorderBox,
- styles
- )
- ) + "px";
-}
-
-function showHide( elements, show ) {
- var display, elem, hidden,
- values = [],
- index = 0,
- length = elements.length;
-
- for ( ; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
-
- values[ index ] = data_priv.get( elem, "olddisplay" );
- display = elem.style.display;
- if ( show ) {
- // Reset the inline display of this element to learn if
it is
- // being hidden by cascaded rules or not
- if ( !values[ index ] && display === "none" ) {
- elem.style.display = "";
- }
-
- // Set elements which have been overridden with
display: none
- // in a stylesheet to whatever the default browser
style is
- // for such an element
- if ( elem.style.display === "" && isHidden( elem ) ) {
- values[ index ] = data_priv.access( elem,
"olddisplay", defaultDisplay(elem.nodeName) );
- }
- } else {
- hidden = isHidden( elem );
-
- if ( display !== "none" || !hidden ) {
- data_priv.set( elem, "olddisplay", hidden ?
display : jQuery.css( elem, "display" ) );
- }
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( index = 0; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
- if ( !show || elem.style.display === "none" ||
elem.style.display === "" ) {
- elem.style.display = show ? values[ index ] || "" :
"none";
- }
- }
-
- return elements;
-}
-
-jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
- // We should always get a number back
from opacity
- var ret = curCSS( elem, "opacity" );
- return ret === "" ? "1" : ret;
- }
- }
- }
- },
-
- // Don't automatically add "px" to these possibly-unitless properties
- cssNumber: {
- "columnCount": true,
- "fillOpacity": true,
- "flexGrow": true,
- "flexShrink": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "order": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- // normalize float css property
- "float": "cssFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ||
!elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, type, hooks,
- origName = jQuery.camelCase( name ),
- style = elem.style;
-
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[
origName ] = vendorPropName( style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- type = typeof value;
-
- // convert relative number strings (+= or -=) to
relative numbers. #7345
- if ( type === "string" && (ret = rrelNum.exec( value ))
) {
- value = ( ret[1] + 1 ) * ret[2] + parseFloat(
jQuery.css( elem, name ) );
- // Fixes bug #9237
- type = "number";
- }
-
- // Make sure that null and NaN values aren't set. See:
#7116
- if ( value == null || value !== value ) {
- return;
- }
-
- // If a number was passed in, add 'px' to the (except
for certain CSS properties)
- if ( type === "number" && !jQuery.cssNumber[ origName ]
) {
- value += "px";
- }
-
- // Fixes #8908, it can be done more correctly by
specifying setters in cssHooks,
- // but it would mean to define eight (for every
problematic property) identical functions
- if ( !support.clearCloneStyle && value === "" &&
name.indexOf( "background" ) === 0 ) {
- style[ name ] = "inherit";
- }
-
- // If a hook was provided, use that value, otherwise
just set the specified value
- if ( !hooks || !("set" in hooks) || (value = hooks.set(
elem, value, extra )) !== undefined ) {
- style[ name ] = value;
- }
-
- } else {
- // If a hook was provided get the non-computed value
from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem,
false, extra )) !== undefined ) {
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra, styles ) {
- var val, num, hooks,
- origName = jQuery.camelCase( name );
-
- // Make sure that we're working with the right name
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[
origName ] = vendorPropName( elem.style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks ) {
- val = hooks.get( elem, true, extra );
- }
-
- // Otherwise, if a way to get the computed value exists, use
that
- if ( val === undefined ) {
- val = curCSS( elem, name, styles );
- }
-
- //convert "normal" to computed value
- if ( val === "normal" && name in cssNormalTransform ) {
- val = cssNormalTransform[ name ];
- }
-
- // Return, converting to number if forced or a qualifier was
provided and val looks numeric
- if ( extra === "" || extra ) {
- num = parseFloat( val );
- return extra === true || jQuery.isNumeric( num ) ? num
|| 0 : val;
- }
- return val;
- }
-});
-
-jQuery.each([ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
- // certain elements can have dimension info if
we invisibly show them
- // however, it must have a current display
style that would benefit from this
- return rdisplayswap.test( jQuery.css( elem,
"display" ) ) && elem.offsetWidth === 0 ?
- jQuery.swap( elem, cssShow, function() {
- return getWidthOrHeight( elem,
name, extra );
- }) :
- getWidthOrHeight( elem, name, extra );
- }
- },
-
- set: function( elem, value, extra ) {
- var styles = extra && getStyles( elem );
- return setPositiveNumber( elem, value, extra ?
- augmentWidthOrHeight(
- elem,
- name,
- extra,
- jQuery.css( elem, "boxSizing", false,
styles ) === "border-box",
- styles
- ) : 0
- );
- }
- };
-});
-
-// Support: Android 2.3
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
- function( elem, computed ) {
- if ( computed ) {
- // WebKit Bug 13343 - getComputedStyle returns wrong
value for margin-right
- // Work around by temporarily setting element display
to inline-block
- return jQuery.swap( elem, { "display": "inline-block" },
- curCSS, [ elem, "marginRight" ] );
- }
- }
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each({
- margin: "",
- padding: "",
- border: "Width"
-}, function( prefix, suffix ) {
- jQuery.cssHooks[ prefix + suffix ] = {
- expand: function( value ) {
- var i = 0,
- expanded = {},
-
- // assumes a single number if not a string
- parts = typeof value === "string" ?
value.split(" ") : [ value ];
-
- for ( ; i < 4; i++ ) {
- expanded[ prefix + cssExpand[ i ] + suffix ] =
- parts[ i ] || parts[ i - 2 ] || parts[
0 ];
- }
-
- return expanded;
- }
- };
-
- if ( !rmargin.test( prefix ) ) {
- jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
- }
-});
-
-jQuery.fn.extend({
- css: function( name, value ) {
- return access( this, function( elem, name, value ) {
- var styles, len,
- map = {},
- i = 0;
-
- if ( jQuery.isArray( name ) ) {
- styles = getStyles( elem );
- len = name.length;
-
- for ( ; i < len; i++ ) {
- map[ name[ i ] ] = jQuery.css( elem,
name[ i ], false, styles );
- }
-
- return map;
- }
-
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- }, name, value, arguments.length > 1 );
- },
- show: function() {
- return showHide( this, true );
- },
- hide: function() {
- return showHide( this );
- },
- toggle: function( state ) {
- if ( typeof state === "boolean" ) {
- return state ? this.show() : this.hide();
- }
-
- return this.each(function() {
- if ( isHidden( this ) ) {
- jQuery( this ).show();
- } else {
- jQuery( this ).hide();
- }
- });
- }
-});
-
-
-function Tween( elem, options, prop, end, easing ) {
- return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
- constructor: Tween,
- init: function( elem, options, prop, end, easing, unit ) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || "swing";
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
- },
- cur: function() {
- var hooks = Tween.propHooks[ this.prop ];
-
- return hooks && hooks.get ?
- hooks.get( this ) :
- Tween.propHooks._default.get( this );
- },
- run: function( percent ) {
- var eased,
- hooks = Tween.propHooks[ this.prop ];
-
- if ( this.options.duration ) {
- this.pos = eased = jQuery.easing[ this.easing ](
- percent, this.options.duration * percent, 0, 1,
this.options.duration
- );
- } else {
- this.pos = eased = percent;
- }
- this.now = ( this.end - this.start ) * eased + this.start;
-
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- if ( hooks && hooks.set ) {
- hooks.set( this );
- } else {
- Tween.propHooks._default.set( this );
- }
- return this;
- }
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
- _default: {
- get: function( tween ) {
- var result;
-
- if ( tween.elem[ tween.prop ] != null &&
- (!tween.elem.style || tween.elem.style[
tween.prop ] == null) ) {
- return tween.elem[ tween.prop ];
- }
-
- // passing an empty string as a 3rd parameter to .css
will automatically
- // attempt a parseFloat and fallback to a string if the
parse fails
- // so, simple values such as "10px" are parsed to Float.
- // complex values such as "rotate(1rad)" are returned
as is.
- result = jQuery.css( tween.elem, tween.prop, "" );
- // Empty strings, null, undefined and "auto" are
converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function( tween ) {
- // use step hook for back compat - use cssHook if its
there - use .style if its
- // available and use plain properties where available
- if ( jQuery.fx.step[ tween.prop ] ) {
- jQuery.fx.step[ tween.prop ]( tween );
- } else if ( tween.elem.style && ( tween.elem.style[
jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
- jQuery.style( tween.elem, tween.prop, tween.now
+ tween.unit );
- } else {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- }
-};
-
-// Support: IE9
-// Panic based approach to setting things on disconnected nodes
-
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function( tween ) {
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
-};
-
-jQuery.easing = {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return 0.5 - Math.cos( p * Math.PI ) / 2;
- }
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
- fxNow, timerId,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
- rrun = /queueHooks$/,
- animationPrefilters = [ defaultPrefilter ],
- tweeners = {
- "*": [ function( prop, value ) {
- var tween = this.createTween( prop, value ),
- target = tween.cur(),
- parts = rfxnum.exec( value ),
- unit = parts && parts[ 3 ] || (
jQuery.cssNumber[ prop ] ? "" : "px" ),
-
- // Starting value computation is required for
potential unit mismatches
- start = ( jQuery.cssNumber[ prop ] || unit !==
"px" && +target ) &&
- rfxnum.exec( jQuery.css( tween.elem,
prop ) ),
- scale = 1,
- maxIterations = 20;
-
- if ( start && start[ 3 ] !== unit ) {
- // Trust units reported by jQuery.css
- unit = unit || start[ 3 ];
-
- // Make sure we update the tween properties
later on
- parts = parts || [];
-
- // Iteratively approximate from a nonzero
starting point
- start = +target || 1;
-
- do {
- // If previous iteration zeroed out,
double until we get *something*
- // Use a string for doubling factor so
we don't accidentally see scale as unchanged below
- scale = scale || ".5";
-
- // Adjust and apply
- start = start / scale;
- jQuery.style( tween.elem, prop, start +
unit );
-
- // Update scale, tolerating zero or NaN from
tween.cur()
- // And breaking the loop if scale is unchanged
or perfect, or if we've just had enough
- } while ( scale !== (scale = tween.cur() /
target) && scale !== 1 && --maxIterations );
- }
-
- // Update tween properties
- if ( parts ) {
- start = tween.start = +start || +target || 0;
- tween.unit = unit;
- // If a +=/-= token was provided, we're doing a
relative animation
- tween.end = parts[ 1 ] ?
- start + ( parts[ 1 ] + 1 ) * parts[ 2 ]
:
- +parts[ 2 ];
- }
-
- return tween;
- } ]
- };
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
- setTimeout(function() {
- fxNow = undefined;
- });
- return ( fxNow = jQuery.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
- var which,
- i = 0,
- attrs = { height: type };
-
- // if we include width, step value is 1 to do all cssExpand values,
- // if we don't include width, step value is 2 to skip over Left and
Right
- includeWidth = includeWidth ? 1 : 0;
- for ( ; i < 4 ; i += 2 - includeWidth ) {
- which = cssExpand[ i ];
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
- }
-
- if ( includeWidth ) {
- attrs.opacity = attrs.width = type;
- }
-
- return attrs;
-}
-
-function createTween( value, prop, animation ) {
- var tween,
- collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ]
),
- index = 0,
- length = collection.length;
- for ( ; index < length; index++ ) {
- if ( (tween = collection[ index ].call( animation, prop, value
)) ) {
-
- // we're done with this property
- return tween;
- }
- }
-}
-
-function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
- var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
- dataShow = data_priv.get( elem, "fxshow" );
-
- // handle queue: false promises
- if ( !opts.queue ) {
- hooks = jQuery._queueHooks( elem, "fx" );
- if ( hooks.unqueued == null ) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function() {
- if ( !hooks.unqueued ) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
-
- anim.always(function() {
- // doing this makes sure that the complete handler will
be called
- // before this completes
- anim.always(function() {
- hooks.unqueued--;
- if ( !jQuery.queue( elem, "fx" ).length ) {
- hooks.empty.fire();
- }
- });
- });
- }
-
- // height/width overflow pass
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) )
{
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE9-10 do not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opts.overflow = [ style.overflow, style.overflowX,
style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height
animated
- display = jQuery.css( elem, "display" );
-
- // Test default display if display is currently "none"
- checkDisplay = display === "none" ?
- data_priv.get( elem, "olddisplay" ) || defaultDisplay(
elem.nodeName ) : display;
-
- if ( checkDisplay === "inline" && jQuery.css( elem, "float" )
=== "none" ) {
- style.display = "inline-block";
- }
- }
-
- if ( opts.overflow ) {
- style.overflow = "hidden";
- anim.always(function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- });
- }
-
- // show/hide pass
- for ( prop in props ) {
- value = props[ prop ];
- if ( rfxtypes.exec( value ) ) {
- delete props[ prop ];
- toggle = toggle || value === "toggle";
- if ( value === ( hidden ? "hide" : "show" ) ) {
-
- // If there is dataShow left over from a
stopped hide or show and we are going to proceed with show, we should pretend
to be hidden
- if ( value === "show" && dataShow && dataShow[
prop ] !== undefined ) {
- hidden = true;
- } else {
- continue;
- }
- }
- orig[ prop ] = dataShow && dataShow[ prop ] ||
jQuery.style( elem, prop );
-
- // Any non-fx value stops us from restoring the original
display value
- } else {
- display = undefined;
- }
- }
-
- if ( !jQuery.isEmptyObject( orig ) ) {
- if ( dataShow ) {
- if ( "hidden" in dataShow ) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = data_priv.access( elem, "fxshow", {} );
- }
-
- // store state if its toggle - enables .stop().toggle() to
"reverse"
- if ( toggle ) {
- dataShow.hidden = !hidden;
- }
- if ( hidden ) {
- jQuery( elem ).show();
- } else {
- anim.done(function() {
- jQuery( elem ).hide();
- });
- }
- anim.done(function() {
- var prop;
-
- data_priv.remove( elem, "fxshow" );
- for ( prop in orig ) {
- jQuery.style( elem, prop, orig[ prop ] );
- }
- });
- for ( prop in orig ) {
- tween = createTween( hidden ? dataShow[ prop ] : 0,
prop, anim );
-
- if ( !( prop in dataShow ) ) {
- dataShow[ prop ] = tween.start;
- if ( hidden ) {
- tween.end = tween.start;
- tween.start = prop === "width" || prop
=== "height" ? 1 : 0;
- }
- }
- }
-
- // If this is a noop like .hide().hide(), restore an overwritten
display value
- } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) :
display) === "inline" ) {
- style.display = display;
- }
-}
-
-function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
-
- // camelCase, specialEasing and expand cssHook pass
- for ( index in props ) {
- name = jQuery.camelCase( index );
- easing = specialEasing[ name ];
- value = props[ index ];
- if ( jQuery.isArray( value ) ) {
- easing = value[ 1 ];
- value = props[ index ] = value[ 0 ];
- }
-
- if ( index !== name ) {
- props[ name ] = value;
- delete props[ index ];
- }
-
- hooks = jQuery.cssHooks[ name ];
- if ( hooks && "expand" in hooks ) {
- value = hooks.expand( value );
- delete props[ name ];
-
- // not quite $.extend, this wont overwrite keys already
present.
- // also - reusing 'index' from above because we have
the correct "name"
- for ( index in value ) {
- if ( !( index in props ) ) {
- props[ index ] = value[ index ];
- specialEasing[ index ] = easing;
- }
- }
- } else {
- specialEasing[ name ] = easing;
- }
- }
-}
-
-function Animation( elem, properties, options ) {
- var result,
- stopped,
- index = 0,
- length = animationPrefilters.length,
- deferred = jQuery.Deferred().always( function() {
- // don't match elem in the :animated selector
- delete tick.elem;
- }),
- tick = function() {
- if ( stopped ) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max( 0, animation.startTime +
animation.duration - currentTime ),
- // archaic crash bug won't allow us to use 1 -
( 0.5 || 0 ) (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
-
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( percent );
- }
-
- deferred.notifyWith( elem, [ animation, percent,
remaining ]);
-
- if ( percent < 1 && length ) {
- return remaining;
- } else {
- deferred.resolveWith( elem, [ animation ] );
- return false;
- }
- },
- animation = deferred.promise({
- elem: elem,
- props: jQuery.extend( {}, properties ),
- opts: jQuery.extend( true, { specialEasing: {} },
options ),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function( prop, end ) {
- var tween = jQuery.Tween( elem, animation.opts,
prop, end,
- animation.opts.specialEasing[
prop ] || animation.opts.easing );
- animation.tweens.push( tween );
- return tween;
- },
- stop: function( gotoEnd ) {
- var index = 0,
- // if we are going to the end, we want
to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ?
animation.tweens.length : 0;
- if ( stopped ) {
- return this;
- }
- stopped = true;
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( 1 );
- }
-
- // resolve when we played the last frame
- // otherwise, reject
- if ( gotoEnd ) {
- deferred.resolveWith( elem, [
animation, gotoEnd ] );
- } else {
- deferred.rejectWith( elem, [ animation,
gotoEnd ] );
- }
- return this;
- }
- }),
- props = animation.props;
-
- propFilter( props, animation.opts.specialEasing );
-
- for ( ; index < length ; index++ ) {
- result = animationPrefilters[ index ].call( animation, elem,
props, animation.opts );
- if ( result ) {
- return result;
- }
- }
-
- jQuery.map( props, createTween, animation );
-
- if ( jQuery.isFunction( animation.opts.start ) ) {
- animation.opts.start.call( elem, animation );
- }
-
- jQuery.fx.timer(
- jQuery.extend( tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- })
- );
-
- // attach callbacks from options
- return animation.progress( animation.opts.progress )
- .done( animation.opts.done, animation.opts.complete )
- .fail( animation.opts.fail )
- .always( animation.opts.always );
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
-
- tweener: function( props, callback ) {
- if ( jQuery.isFunction( props ) ) {
- callback = props;
- props = [ "*" ];
- } else {
- props = props.split(" ");
- }
-
- var prop,
- index = 0,
- length = props.length;
-
- for ( ; index < length ; index++ ) {
- prop = props[ index ];
- tweeners[ prop ] = tweeners[ prop ] || [];
- tweeners[ prop ].unshift( callback );
- }
- },
-
- prefilter: function( callback, prepend ) {
- if ( prepend ) {
- animationPrefilters.unshift( callback );
- } else {
- animationPrefilters.push( callback );
- }
- }
-});
-
-jQuery.speed = function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed
) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing )
&& easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[
opt.duration ] : jQuery.fx.speeds._default;
-
- // normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function() {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- }
- };
-
- return opt;
-};
-
-jQuery.fn.extend({
- fadeTo: function( speed, to, easing, callback ) {
-
- // show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
-
- // animate to the value specified
- .end().animate({ opacity: to }, speed, easing, callback
);
- },
- animate: function( prop, speed, easing, callback ) {
- var empty = jQuery.isEmptyObject( prop ),
- optall = jQuery.speed( speed, easing, callback ),
- doAnimation = function() {
- // Operate on a copy of prop so per-property
easing won't be lost
- var anim = Animation( this, jQuery.extend( {},
prop ), optall );
-
- // Empty animations, or finishing resolves
immediately
- if ( empty || data_priv.get( this, "finish" ) )
{
- anim.stop( true );
- }
- };
- doAnimation.finish = doAnimation;
-
- return empty || optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
- stop: function( type, clearQueue, gotoEnd ) {
- var stopQueue = function( hooks ) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop( gotoEnd );
- };
-
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each(function() {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = data_priv.get( this );
-
- if ( index ) {
- if ( data[ index ] && data[ index ].stop ) {
- stopQueue( data[ index ] );
- }
- } else {
- for ( index in data ) {
- if ( data[ index ] && data[ index
].stop && rrun.test( index ) ) {
- stopQueue( data[ index ] );
- }
- }
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && (type ==
null || timers[ index ].queue === type) ) {
- timers[ index ].anim.stop( gotoEnd );
- dequeue = false;
- timers.splice( index, 1 );
- }
- }
-
- // start the next in the queue if the last step wasn't
forced
- // timers currently will call their complete callbacks,
which will dequeue
- // but only if they were gotoEnd
- if ( dequeue || !gotoEnd ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- finish: function( type ) {
- if ( type !== false ) {
- type = type || "fx";
- }
- return this.each(function() {
- var index,
- data = data_priv.get( this ),
- queue = data[ type + "queue" ],
- hooks = data[ type + "queueHooks" ],
- timers = jQuery.timers,
- length = queue ? queue.length : 0;
-
- // enable finishing flag on private data
- data.finish = true;
-
- // empty the queue first
- jQuery.queue( this, type, [] );
-
- if ( hooks && hooks.stop ) {
- hooks.stop.call( this, true );
- }
-
- // look for any active animations, and finish them
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && timers[
index ].queue === type ) {
- timers[ index ].anim.stop( true );
- timers.splice( index, 1 );
- }
- }
-
- // look for any animations in the old queue and finish
them
- for ( index = 0; index < length; index++ ) {
- if ( queue[ index ] && queue[ index ].finish ) {
- queue[ index ].finish.call( this );
- }
- }
-
- // turn off finishing flag
- delete data.finish;
- });
- }
-});
-
-jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
- var cssFn = jQuery.fn[ name ];
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return speed == null || typeof speed === "boolean" ?
- cssFn.apply( this, arguments ) :
- this.animate( genFx( name, true ), speed, easing,
callback );
- };
-});
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx("show"),
- slideUp: genFx("hide"),
- slideToggle: genFx("toggle"),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
- var timer,
- i = 0,
- timers = jQuery.timers;
-
- fxNow = jQuery.now();
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
- jQuery.timers.push( timer );
- if ( timer() ) {
- jQuery.fx.start();
- } else {
- jQuery.timers.pop();
- }
-};
-
-jQuery.fx.interval = 13;
-
-jQuery.fx.start = function() {
- if ( !timerId ) {
- timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
- }
-};
-
-jQuery.fx.stop = function() {
- clearInterval( timerId );
- timerId = null;
-};
-
-jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
- type = type || "fx";
-
- return this.queue( type, function( next, hooks ) {
- var timeout = setTimeout( next, time );
- hooks.stop = function() {
- clearTimeout( timeout );
- };
- });
-};
-
-
-(function() {
- var input = document.createElement( "input" ),
- select = document.createElement( "select" ),
- opt = select.appendChild( document.createElement( "option" ) );
-
- input.type = "checkbox";
-
- // Support: iOS 5.1, Android 4.x, Android 2.3
- // Check the default checkbox/radio value ("" on old WebKit; "on"
elsewhere)
- support.checkOn = input.value !== "";
-
- // Must access the parent to make an option select properly
- // Support: IE9, IE10
- support.optSelected = opt.selected;
-
- // Make sure that the options inside disabled selects aren't marked as
disabled
- // (WebKit marks them as disabled)
- select.disabled = true;
- support.optDisabled = !opt.disabled;
-
- // Check if an input maintains its value after becoming a radio
- // Support: IE9, IE10
- input = document.createElement( "input" );
- input.value = "t";
- input.type = "radio";
- support.radioValue = input.value === "t";
-})();
-
-
-var nodeHook, boolHook,
- attrHandle = jQuery.expr.attrHandle;
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return access( this, jQuery.attr, name, value, arguments.length
> 1 );
- },
-
- removeAttr: function( name ) {
- return this.each(function() {
- jQuery.removeAttr( this, name );
- });
- }
-});
-
-jQuery.extend({
- attr: function( elem, name, value ) {
- var hooks, ret,
- nType = elem.nodeType;
-
- // don't get/set attributes on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- // Fallback to prop when attributes are not supported
- if ( typeof elem.getAttribute === strundefined ) {
- return jQuery.prop( elem, name, value );
- }
-
- // All attributes are lowercase
- // Grab necessary hook if one is defined
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- name = name.toLowerCase();
- hooks = jQuery.attrHooks[ name ] ||
- ( jQuery.expr.match.bool.test( name ) ?
boolHook : nodeHook );
- }
-
- if ( value !== undefined ) {
-
- if ( value === null ) {
- jQuery.removeAttr( elem, name );
-
- } else if ( hooks && "set" in hooks && (ret =
hooks.set( elem, value, name )) !== undefined ) {
- return ret;
-
- } else {
- elem.setAttribute( name, value + "" );
- return value;
- }
-
- } else if ( hooks && "get" in hooks && (ret = hooks.get( elem,
name )) !== null ) {
- return ret;
-
- } else {
- ret = jQuery.find.attr( elem, name );
-
- // Non-existent attributes return null, we normalize to
undefined
- return ret == null ?
- undefined :
- ret;
- }
- },
-
- removeAttr: function( elem, value ) {
- var name, propName,
- i = 0,
- attrNames = value && value.match( rnotwhite );
-
- if ( attrNames && elem.nodeType === 1 ) {
- while ( (name = attrNames[i++]) ) {
- propName = jQuery.propFix[ name ] || name;
-
- // Boolean attributes get special treatment
(#10870)
- if ( jQuery.expr.match.bool.test( name ) ) {
- // Set corresponding property to false
- elem[ propName ] = false;
- }
-
- elem.removeAttribute( name );
- }
- }
- },
-
- attrHooks: {
- type: {
- set: function( elem, value ) {
- if ( !support.radioValue && value === "radio" &&
- jQuery.nodeName( elem, "input" ) ) {
- // Setting the type on a radio button
after the value resets the value in IE6-9
- // Reset value to default in case type
is set after value during creation
- var val = elem.value;
- elem.setAttribute( "type", value );
- if ( val ) {
- elem.value = val;
- }
- return value;
- }
- }
- }
- }
-});
-
-// Hooks for boolean attributes
-boolHook = {
- set: function( elem, value, name ) {
- if ( value === false ) {
- // Remove boolean attributes when set to false
- jQuery.removeAttr( elem, name );
- } else {
- elem.setAttribute( name, name );
- }
- return name;
- }
-};
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name
) {
- var getter = attrHandle[ name ] || jQuery.find.attr;
-
- attrHandle[ name ] = function( elem, name, isXML ) {
- var ret, handle;
- if ( !isXML ) {
- // Avoid an infinite loop by temporarily removing this
function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
- ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
- null;
- attrHandle[ name ] = handle;
- }
- return ret;
- };
-});
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button)$/i;
-
-jQuery.fn.extend({
- prop: function( name, value ) {
- return access( this, jQuery.prop, name, value, arguments.length
> 1 );
- },
-
- removeProp: function( name ) {
- return this.each(function() {
- delete this[ jQuery.propFix[ name ] || name ];
- });
- }
-});
-
-jQuery.extend({
- propFix: {
- "for": "htmlFor",
- "class": "className"
- },
-
- prop: function( elem, name, value ) {
- var ret, hooks, notxml,
- nType = elem.nodeType;
-
- // don't get/set properties on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
- if ( notxml ) {
- // Fix name and attach hooks
- name = jQuery.propFix[ name ] || name;
- hooks = jQuery.propHooks[ name ];
- }
-
- if ( value !== undefined ) {
- return hooks && "set" in hooks && (ret = hooks.set(
elem, value, name )) !== undefined ?
- ret :
- ( elem[ name ] = value );
-
- } else {
- return hooks && "get" in hooks && (ret = hooks.get(
elem, name )) !== null ?
- ret :
- elem[ name ];
- }
- },
-
- propHooks: {
- tabIndex: {
- get: function( elem ) {
- return elem.hasAttribute( "tabindex" ) ||
rfocusable.test( elem.nodeName ) || elem.href ?
- elem.tabIndex :
- -1;
- }
- }
- }
-});
-
-// Support: IE9+
-// Selectedness for an option in an optgroup can be inaccurate
-if ( !support.optSelected ) {
- jQuery.propHooks.selected = {
- get: function( elem ) {
- var parent = elem.parentNode;
- if ( parent && parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- return null;
- }
- };
-}
-
-jQuery.each([
- "tabIndex",
- "readOnly",
- "maxLength",
- "cellSpacing",
- "cellPadding",
- "rowSpan",
- "colSpan",
- "useMap",
- "frameBorder",
- "contentEditable"
-], function() {
- jQuery.propFix[ this.toLowerCase() ] = this;
-});
-
-
-
-
-var rclass = /[\t\r\n\f]/g;
-
-jQuery.fn.extend({
- addClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- proceed = typeof value === "string" && value,
- i = 0,
- len = this.length;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).addClass( value.call( this, j,
this.className ) );
- });
- }
-
- if ( proceed ) {
- // The disjunction here is for better compressibility
(see removeClass)
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace(
rclass, " " ) :
- " "
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- if ( cur.indexOf( " " + clazz +
" " ) < 0 ) {
- cur += clazz + " ";
- }
- }
-
- // only assign if different to avoid
unneeded rendering.
- finalValue = jQuery.trim( cur );
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- proceed = arguments.length === 0 || typeof value ===
"string" && value,
- i = 0,
- len = this.length;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).removeClass( value.call( this,
j, this.className ) );
- });
- }
- if ( proceed ) {
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- // This expression is here for better
compressibility (see addClass)
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace(
rclass, " " ) :
- ""
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- // Remove *all* instances
- while ( cur.indexOf( " " +
clazz + " " ) >= 0 ) {
- cur = cur.replace( " "
+ clazz + " ", " " );
- }
- }
-
- // only assign if different to avoid
unneeded rendering.
- finalValue = value ? jQuery.trim( cur )
: "";
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value;
-
- if ( typeof stateVal === "boolean" && type === "string" ) {
- return stateVal ? this.addClass( value ) :
this.removeClass( value );
- }
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( i ) {
- jQuery( this ).toggleClass( value.call(this, i,
this.className, stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery( this ),
- classNames = value.match( rnotwhite )
|| [];
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space
separated list
- if ( self.hasClass( className ) ) {
- self.removeClass( className );
- } else {
- self.addClass( className );
- }
- }
-
- // Toggle whole class name
- } else if ( type === strundefined || type === "boolean"
) {
- if ( this.className ) {
- // store className if set
- data_priv.set( this, "__className__",
this.className );
- }
-
- // If the element has a class name or if we're
passed "false",
- // then remove the whole classname (if there
was one, the above saved it).
- // Otherwise bring back whatever was previously
saved (if anything),
- // falling back to the empty string if nothing
was stored.
- this.className = this.className || value ===
false ? "" : data_priv.get( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ",
- i = 0,
- l = this.length;
- for ( ; i < l; i++ ) {
- if ( this[i].nodeType === 1 && (" " + this[i].className
+ " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
- return true;
- }
- }
-
- return false;
- }
-});
-
-
-
-
-var rreturn = /\r/g;
-
-jQuery.fn.extend({
- val: function( value ) {
- var hooks, ret, isFunction,
- elem = this[0];
-
- if ( !arguments.length ) {
- if ( elem ) {
- hooks = jQuery.valHooks[ elem.type ] ||
jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
- if ( hooks && "get" in hooks && (ret =
hooks.get( elem, "value" )) !== undefined ) {
- return ret;
- }
-
- ret = elem.value;
-
- return typeof ret === "string" ?
- // handle most common string cases
- ret.replace(rreturn, "") :
- // handle cases where value is
null/undef or number
- ret == null ? "" : ret;
- }
-
- return;
- }
-
- isFunction = jQuery.isFunction( value );
-
- return this.each(function( i ) {
- var val;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call( this, i, jQuery( this ).val()
);
- } else {
- val = value;
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
-
- } else if ( typeof val === "number" ) {
- val += "";
-
- } else if ( jQuery.isArray( val ) ) {
- val = jQuery.map( val, function( value ) {
- return value == null ? "" : value + "";
- });
- }
-
- hooks = jQuery.valHooks[ this.type ] ||
jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
- // If set returns undefined, fall back to normal setting
- if ( !hooks || !("set" in hooks) || hooks.set( this,
val, "value" ) === undefined ) {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- valHooks: {
- option: {
- get: function( elem ) {
- var val = jQuery.find.attr( elem, "value" );
- return val != null ?
- val :
- // Support: IE10-11+
- // option.text throws exceptions
(#14686, #14858)
- jQuery.trim( jQuery.text( elem ) );
- }
- },
- select: {
- get: function( elem ) {
- var value, option,
- options = elem.options,
- index = elem.selectedIndex,
- one = elem.type === "select-one" ||
index < 0,
- values = one ? null : [],
- max = one ? index + 1 : options.length,
- i = index < 0 ?
- max :
- one ? index : 0;
-
- // Loop through all the selected options
- for ( ; i < max; i++ ) {
- option = options[ i ];
-
- // IE6-9 doesn't update selected after
form reset (#2551)
- if ( ( option.selected || i === index )
&&
- // Don't return options
that are disabled or in a disabled optgroup
- ( support.optDisabled ?
!option.disabled : option.getAttribute( "disabled" ) === null ) &&
- (
!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup"
) ) ) {
-
- // Get the specific value for
the option
- value = jQuery( option ).val();
-
- // We don't need an array for
one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- },
-
- set: function( elem, value ) {
- var optionSet, option,
- options = elem.options,
- values = jQuery.makeArray( value ),
- i = options.length;
-
- while ( i-- ) {
- option = options[ i ];
- if ( (option.selected = jQuery.inArray(
option.value, values ) >= 0) ) {
- optionSet = true;
- }
- }
-
- // force browsers to behave consistently when
non-matching value is set
- if ( !optionSet ) {
- elem.selectedIndex = -1;
- }
- return values;
- }
- }
- }
-});
-
-// Radios and checkboxes getter/setter
-jQuery.each([ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = {
- set: function( elem, value ) {
- if ( jQuery.isArray( value ) ) {
- return ( elem.checked = jQuery.inArray(
jQuery(elem).val(), value ) >= 0 );
- }
- }
- };
- if ( !support.checkOn ) {
- jQuery.valHooks[ this ].get = function( elem ) {
- // Support: Webkit
- // "" is returned instead of "on" if a value isn't
specified
- return elem.getAttribute("value") === null ? "on" :
elem.value;
- };
- }
-});
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click
dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave "
+
- "change select submit keydown keypress keyup error
contextmenu").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- return arguments.length > 0 ?
- this.on( name, null, data, fn ) :
- this.trigger( name );
- };
-});
-
-jQuery.fn.extend({
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- },
-
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length === 1 ? this.off( selector, "**" ) :
this.off( types, selector || "**", fn );
- }
-});
-
-
-var nonce = jQuery.now();
-
-var rquery = (/\?/);
-
-
-
-// Support: Android 2.3
-// Workaround failure to string-cast null input
-jQuery.parseJSON = function( data ) {
- return JSON.parse( data + "" );
-};
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
- var xml, tmp;
- if ( !data || typeof data !== "string" ) {
- return null;
- }
-
- // Support: IE9
- try {
- tmp = new DOMParser();
- xml = tmp.parseFromString( data, "text/xml" );
- } catch ( e ) {
- xml = undefined;
- }
-
- if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
- jQuery.error( "Invalid XML: " + data );
- }
- return xml;
-};
-
-
-var
- // Document location
- ajaxLocParts,
- ajaxLocation,
-
- rhash = /#.*$/,
- rts = /([?&])_=[^&]*/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol =
/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
-
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js
for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData
is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue
down to "*" if needed
- */
- prefilters = {},
-
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*"
if needed
- */
- transports = {},
-
- // Avoid comment-prolog char sequence (#10098); must appease lint and
evade compression
- allTypes = "*/".concat("*");
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
- ajaxLocation = location.href;
-} catch( e ) {
- // Use the href attribute of an A element
- // since IE will modify it given document.location
- ajaxLocation = document.createElement( "a" );
- ajaxLocation.href = "";
- ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
- // dataTypeExpression is optional and defaults to "*"
- return function( dataTypeExpression, func ) {
-
- if ( typeof dataTypeExpression !== "string" ) {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
-
- var dataType,
- i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match(
rnotwhite ) || [];
-
- if ( jQuery.isFunction( func ) ) {
- // For each dataType in the dataTypeExpression
- while ( (dataType = dataTypes[i++]) ) {
- // Prepend if requested
- if ( dataType[0] === "+" ) {
- dataType = dataType.slice( 1 ) || "*";
- (structure[ dataType ] = structure[
dataType ] || []).unshift( func );
-
- // Otherwise append
- } else {
- (structure[ dataType ] = structure[
dataType ] || []).push( func );
- }
- }
- }
- };
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions,
jqXHR ) {
-
- var inspected = {},
- seekingTransport = ( structure === transports );
-
- function inspect( dataType ) {
- var selected;
- inspected[ dataType ] = true;
- jQuery.each( structure[ dataType ] || [], function( _,
prefilterOrFactory ) {
- var dataTypeOrTransport = prefilterOrFactory( options,
originalOptions, jqXHR );
- if ( typeof dataTypeOrTransport === "string" &&
!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
- options.dataTypes.unshift( dataTypeOrTransport
);
- inspect( dataTypeOrTransport );
- return false;
- } else if ( seekingTransport ) {
- return !( selected = dataTypeOrTransport );
- }
- });
- return selected;
- }
-
- return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] &&
inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
- var key, deep,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
- for ( key in src ) {
- if ( src[ key ] !== undefined ) {
- ( flatOptions[ key ] ? target : ( deep || (deep = {}) )
)[ key ] = src[ key ];
- }
- }
- if ( deep ) {
- jQuery.extend( true, target, deep );
- }
-
- return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected
dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-
- var ct, type, finalDataType, firstDataType,
- contents = s.contents,
- dataTypes = s.dataTypes;
-
- // Remove auto dataType and get content-type in the process
- while ( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType ||
jqXHR.getResponseHeader("Content-Type");
- }
- }
-
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
- }
- }
- }
-
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
- } else {
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " +
dataTypes[0] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
- }
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
- converters = {},
- // Work with a copy of dataTypes in case we need to modify it
for conversion
- dataTypes = s.dataTypes.slice();
-
- // Create converters map with lowercased keys
- if ( dataTypes[ 1 ] ) {
- for ( conv in s.converters ) {
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
- }
- }
-
- current = dataTypes.shift();
-
- // Convert to each sequential dataType
- while ( current ) {
-
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
- }
-
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- prev = current;
- current = dataTypes.shift();
-
- if ( current ) {
-
- // There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
-
- current = prev;
-
- // Convert response if prev dataType is non-auto and
differs from current
- } else if ( prev !== "*" && prev !== current ) {
-
- // Seek a direct converter
- conv = converters[ prev + " " + current ] ||
converters[ "* " + current ];
-
- // If none found, seek a pair
- if ( !conv ) {
- for ( conv2 in converters ) {
-
- // If conv2 outputs current
- tmp = conv2.split( " " );
- if ( tmp[ 1 ] === current ) {
-
- // If prev can be
converted to accepted input
- conv = converters[ prev
+ " " + tmp[ 0 ] ] ||
- converters[ "*
" + tmp[ 0 ] ];
- if ( conv ) {
- // Condense
equivalence converters
- if ( conv ===
true ) {
- conv =
converters[ conv2 ];
-
- // Otherwise,
insert the intermediate dataType
- } else if (
converters[ conv2 ] !== true ) {
- current
= tmp[ 0 ];
-
dataTypes.unshift( tmp[ 1 ] );
- }
- break;
- }
- }
- }
- }
-
- // Apply converter (if not an equivalence)
- if ( conv !== true ) {
-
- // Unless errors are allowed to bubble,
catch and return them
- if ( conv && s[ "throws" ] ) {
- response = conv( response );
- } else {
- try {
- response = conv(
response );
- } catch ( e ) {
- return { state:
"parsererror", error: conv ? e : "No conversion from " + prev + " to " +
current };
- }
- }
- }
- }
- }
- }
-
- return { state: "success", data: response };
-}
-
-jQuery.extend({
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
-
- ajaxSettings: {
- url: ajaxLocation,
- type: "GET",
- isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
- global: true,
- processData: true,
- async: true,
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- throws: false,
- traditional: false,
- headers: {},
- */
-
- accepts: {
- "*": allTypes,
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript"
- },
-
- contents: {
- xml: /xml/,
- html: /html/,
- json: /json/
- },
-
- responseFields: {
- xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
- },
-
- // Data converters
- // Keys separate source (or catchall "*") and destination types
with a single space
- converters: {
-
- // Convert anything to text
- "* text": String,
-
- // Text to html (true = no transformation)
- "text html": true,
-
- // Evaluate text as a json expression
- "text json": jQuery.parseJSON,
-
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
-
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- url: true,
- context: true
- }
- },
-
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function( target, settings ) {
- return settings ?
-
- // Building a settings object
- ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ),
settings ) :
-
- // Extending ajaxSettings
- ajaxExtend( jQuery.ajaxSettings, target );
- },
-
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
- ajaxTransport: addToPrefiltersOrTransports( transports ),
-
- // Main method
- ajax: function( url, options ) {
-
- // If url is an object, simulate pre-1.5 signature
- if ( typeof url === "object" ) {
- options = url;
- url = undefined;
- }
-
- // Force options to be an object
- options = options || {};
-
- var transport,
- // URL without anti-cache param
- cacheURL,
- // Response headers
- responseHeadersString,
- responseHeaders,
- // timeout handle
- timeoutTimer,
- // Cross-domain detection vars
- parts,
- // To know if global events are to be dispatched
- fireGlobals,
- // Loop variable
- i,
- // Create the final options object
- s = jQuery.ajaxSetup( {}, options ),
- // Callbacks context
- callbackContext = s.context || s,
- // Context for global events is callbackContext if it
is a DOM node or jQuery collection
- globalEventContext = s.context && (
callbackContext.nodeType || callbackContext.jquery ) ?
- jQuery( callbackContext ) :
- jQuery.event,
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks("once memory"),
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
- // The jqXHR state
- state = 0,
- // Default abort message
- strAbort = "canceled",
- // Fake xhr
- jqXHR = {
- readyState: 0,
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
- var match;
- if ( state === 2 ) {
- if ( !responseHeaders ) {
- responseHeaders = {};
- while ( (match =
rheaders.exec( responseHeadersString )) ) {
-
responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
- }
- }
- match = responseHeaders[
key.toLowerCase() ];
- }
- return match == null ? null : match;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return state === 2 ?
responseHeadersString : null;
- },
-
- // Caches the header
- setRequestHeader: function( name, value ) {
- var lname = name.toLowerCase();
- if ( !state ) {
- name = requestHeadersNames[
lname ] = requestHeadersNames[ lname ] || name;
- requestHeaders[ name ] = value;
- }
- return this;
- },
-
- // Overrides response content-type header
- overrideMimeType: function( type ) {
- if ( !state ) {
- s.mimeType = type;
- }
- return this;
- },
-
- // Status-dependent callbacks
- statusCode: function( map ) {
- var code;
- if ( map ) {
- if ( state < 2 ) {
- for ( code in map ) {
- // Lazy-add the
new callback in a way that preserves old ones
- statusCode[
code ] = [ statusCode[ code ], map[ code ] ];
- }
- } else {
- // Execute the
appropriate callbacks
- jqXHR.always( map[
jqXHR.status ] );
- }
- }
- return this;
- },
-
- // Cancel the request
- abort: function( statusText ) {
- var finalText = statusText || strAbort;
- if ( transport ) {
- transport.abort( finalText );
- }
- done( 0, finalText );
- return this;
- }
- };
-
- // Attach deferreds
- deferred.promise( jqXHR ).complete = completeDeferred.add;
- jqXHR.success = jqXHR.done;
- jqXHR.error = jqXHR.fail;
-
- // Remove hash character (#7531: and string promotion)
- // Add protocol if not provided (prefilters might expect it)
- // Handle falsy url in the settings object (#10093: consistency
with old signature)
- // We also use the url parameter if available
- s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace(
rhash, "" )
- .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
-
- // Alias method option to type as per ticket #12004
- s.type = options.method || options.type || s.method || s.type;
-
- // Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*"
).toLowerCase().match( rnotwhite ) || [ "" ];
-
- // A cross-domain request is in order when we have a
protocol:host:port mismatch
- if ( s.crossDomain == null ) {
- parts = rurl.exec( s.url.toLowerCase() );
- s.crossDomain = !!( parts &&
- ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2
] !== ajaxLocParts[ 2 ] ||
- ( parts[ 3 ] || ( parts[ 1 ] ===
"http:" ? "80" : "443" ) ) !==
- ( ajaxLocParts[ 3 ] || (
ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
- );
- }
-
- // Convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Apply prefilters
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
- // If request was aborted inside a prefilter, stop there
- if ( state === 2 ) {
- return jqXHR;
- }
-
- // We can fire global events as of now if asked to
- fireGlobals = s.global;
-
- // Watch for a new set of requests
- if ( fireGlobals && jQuery.active++ === 0 ) {
- jQuery.event.trigger("ajaxStart");
- }
-
- // Uppercase the type
- s.type = s.type.toUpperCase();
-
- // Determine if request has content
- s.hasContent = !rnoContent.test( s.type );
-
- // Save the URL in case we're toying with the If-Modified-Since
- // and/or If-None-Match header later on
- cacheURL = s.url;
-
- // More options handling for requests with no content
- if ( !s.hasContent ) {
-
- // If data is available, append data to url
- if ( s.data ) {
- cacheURL = ( s.url += ( rquery.test( cacheURL )
? "&" : "?" ) + s.data );
- // #9682: remove data so that it's not used in
an eventual retry
- delete s.data;
- }
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
- s.url = rts.test( cacheURL ) ?
-
- // If there is already a '_' parameter,
set its value
- cacheURL.replace( rts, "$1_=" + nonce++
) :
-
- // Otherwise add one to the end
- cacheURL + ( rquery.test( cacheURL ) ?
"&" : "?" ) + "_=" + nonce++;
- }
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in
ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery.lastModified[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-Modified-Since",
jQuery.lastModified[ cacheURL ] );
- }
- if ( jQuery.etag[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-None-Match",
jQuery.etag[ cacheURL ] );
- }
- }
-
- // Set the correct header, if data is being sent
- if ( s.data && s.hasContent && s.contentType !== false ||
options.contentType ) {
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
- }
-
- // Set the Accepts header for the server, depending on the
dataType
- jqXHR.setRequestHeader(
- "Accept",
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
- s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0
] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
- s.accepts[ "*" ]
- );
-
- // Check for headers option
- for ( i in s.headers ) {
- jqXHR.setRequestHeader( i, s.headers[ i ] );
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend && ( s.beforeSend.call( callbackContext,
jqXHR, s ) === false || state === 2 ) ) {
- // Abort if not done already and return
- return jqXHR.abort();
- }
-
- // aborting is no longer a cancellation
- strAbort = "abort";
-
- // Install callbacks on deferreds
- for ( i in { success: 1, error: 1, complete: 1 } ) {
- jqXHR[ i ]( s[ i ] );
- }
-
- // Get transport
- transport = inspectPrefiltersOrTransports( transports, s,
options, jqXHR );
-
- // If no transport, we auto-abort
- if ( !transport ) {
- done( -1, "No Transport" );
- } else {
- jqXHR.readyState = 1;
-
- // Send global event
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxSend", [
jqXHR, s ] );
- }
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = setTimeout(function() {
- jqXHR.abort("timeout");
- }, s.timeout );
- }
-
- try {
- state = 1;
- transport.send( requestHeaders, done );
- } catch ( e ) {
- // Propagate exception as error if not done
- if ( state < 2 ) {
- done( -1, e );
- // Simply rethrow otherwise
- } else {
- throw e;
- }
- }
- }
-
- // Callback for when everything is done
- function done( status, nativeStatusText, responses, headers ) {
- var isSuccess, success, error, response, modified,
- statusText = nativeStatusText;
-
- // Called once
- if ( state === 2 ) {
- return;
- }
-
- // State is "done" now
- state = 2;
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- clearTimeout( timeoutTimer );
- }
-
- // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0;
-
- // Determine if successful
- isSuccess = status >= 200 && status < 300 || status ===
304;
-
- // Get response data
- if ( responses ) {
- response = ajaxHandleResponses( s, jqXHR,
responses );
- }
-
- // Convert no matter what (that way responseXXX fields
are always set)
- response = ajaxConvert( s, response, jqXHR, isSuccess );
-
- // If successful, handle type chaining
- if ( isSuccess ) {
-
- // Set the If-Modified-Since and/or
If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- modified =
jqXHR.getResponseHeader("Last-Modified");
- if ( modified ) {
- jQuery.lastModified[ cacheURL ]
= modified;
- }
- modified =
jqXHR.getResponseHeader("etag");
- if ( modified ) {
- jQuery.etag[ cacheURL ] =
modified;
- }
- }
-
- // if no content
- if ( status === 204 || s.type === "HEAD" ) {
- statusText = "nocontent";
-
- // if not modified
- } else if ( status === 304 ) {
- statusText = "notmodified";
-
- // If we have data, let's convert it
- } else {
- statusText = response.state;
- success = response.data;
- error = response.error;
- isSuccess = !error;
- }
- } else {
- // We extract error from statusText
- // then normalize statusText and status for
non-aborts
- error = statusText;
- if ( status || !statusText ) {
- statusText = "error";
- if ( status < 0 ) {
- status = 0;
- }
- }
- }
-
- // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = ( nativeStatusText || statusText ) +
"";
-
- // Success/Error
- if ( isSuccess ) {
- deferred.resolveWith( callbackContext, [
success, statusText, jqXHR ] );
- } else {
- deferred.rejectWith( callbackContext, [ jqXHR,
statusText, error ] );
- }
-
- // Status-dependent callbacks
- jqXHR.statusCode( statusCode );
- statusCode = undefined;
-
- if ( fireGlobals ) {
- globalEventContext.trigger( isSuccess ?
"ajaxSuccess" : "ajaxError",
- [ jqXHR, s, isSuccess ? success : error
] );
- }
-
- // Complete
- completeDeferred.fireWith( callbackContext, [ jqXHR,
statusText ] );
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [
jqXHR, s ] );
- // Handle the global AJAX counter
- if ( !( --jQuery.active ) ) {
- jQuery.event.trigger("ajaxStop");
- }
- }
- }
-
- return jqXHR;
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get( url, data, callback, "json" );
- },
-
- getScript: function( url, callback ) {
- return jQuery.get( url, undefined, callback, "script" );
- }
-});
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
- jQuery[ method ] = function( url, data, callback, type ) {
- // shift arguments if data argument was omitted
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = undefined;
- }
-
- return jQuery.ajax({
- url: url,
- type: method,
- dataType: type,
- data: data,
- success: callback
- });
- };
-});
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError",
"ajaxSuccess", "ajaxSend" ], function( i, type ) {
- jQuery.fn[ type ] = function( fn ) {
- return this.on( type, fn );
- };
-});
-
-
-jQuery._evalUrl = function( url ) {
- return jQuery.ajax({
- url: url,
- type: "GET",
- dataType: "script",
- async: false,
- global: false,
- "throws": true
- });
-};
-
-
-jQuery.fn.extend({
- wrapAll: function( html ) {
- var wrap;
-
- if ( jQuery.isFunction( html ) ) {
- return this.each(function( i ) {
- jQuery( this ).wrapAll( html.call(this, i) );
- });
- }
-
- if ( this[ 0 ] ) {
-
- // The elements to wrap the target around
- wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0
).clone( true );
-
- if ( this[ 0 ].parentNode ) {
- wrap.insertBefore( this[ 0 ] );
- }
-
- wrap.map(function() {
- var elem = this;
-
- while ( elem.firstElementChild ) {
- elem = elem.firstElementChild;
- }
-
- return elem;
- }).append( this );
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function( i ) {
- jQuery( this ).wrapInner( html.call(this, i) );
- });
- }
-
- return this.each(function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- });
- },
-
- wrap: function( html ) {
- var isFunction = jQuery.isFunction( html );
-
- return this.each(function( i ) {
- jQuery( this ).wrapAll( isFunction ? html.call(this, i)
: html );
- });
- },
-
- unwrap: function() {
- return this.parent().each(function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- }).end();
- }
-});
-
-
-jQuery.expr.filters.hidden = function( elem ) {
- // Support: Opera <= 12.12
- // Opera reports offsetWidths and offsetHeights less than zero on some
elements
- return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
-};
-jQuery.expr.filters.visible = function( elem ) {
- return !jQuery.expr.filters.hidden( elem );
-};
-
-
-
-
-var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
- var name;
-
- if ( jQuery.isArray( obj ) ) {
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
- // Item is non-scalar (array or object), encode
its numeric index.
- buildParams( prefix + "[" + ( typeof v ===
"object" ? i : "" ) + "]", v, traditional, add );
- }
- });
-
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
- // Serialize object item.
- for ( name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ],
traditional, add );
- }
-
- } else {
- // Serialize scalar item.
- add( prefix, obj );
- }
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
- var prefix,
- s = [],
- add = function( key, value ) {
- // If value is a function, invoke it and return its
value
- value = jQuery.isFunction( value ) ? value() : ( value
== null ? "" : value );
- s[ s.length ] = encodeURIComponent( key ) + "=" +
encodeURIComponent( value );
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings &&
jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form
elements.
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) )
) {
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- });
-
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( prefix in a ) {
- buildParams( prefix, a[ prefix ], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join( "&" ).replace( r20, "+" );
-};
-
-jQuery.fn.extend({
- serialize: function() {
- return jQuery.param( this.serializeArray() );
- },
- serializeArray: function() {
- return this.map(function() {
- // Can add propHook for "elements" to filter or add
form elements
- var elements = jQuery.prop( this, "elements" );
- return elements ? jQuery.makeArray( elements ) : this;
- })
- .filter(function() {
- var type = this.type;
-
- // Use .is( ":disabled" ) so that fieldset[disabled]
works
- return this.name && !jQuery( this ).is( ":disabled" ) &&
- rsubmittable.test( this.nodeName ) &&
!rsubmitterTypes.test( type ) &&
- ( this.checked || !rcheckableType.test( type )
);
- })
- .map(function( i, elem ) {
- var val = jQuery( this ).val();
-
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val ) {
- return { name: elem.name,
value: val.replace( rCRLF, "\r\n" ) };
- }) :
- { name: elem.name, value: val.replace(
rCRLF, "\r\n" ) };
- }).get();
- }
-});
-
-
-jQuery.ajaxSettings.xhr = function() {
- try {
- return new XMLHttpRequest();
- } catch( e ) {}
-};
-
-var xhrId = 0,
- xhrCallbacks = {},
- xhrSuccessStatus = {
- // file protocol always yields status code 0, assume 200
- 0: 200,
- // Support: IE9
- // #1450: sometimes IE returns 1223 when it should be 204
- 1223: 204
- },
- xhrSupported = jQuery.ajaxSettings.xhr();
-
-// Support: IE9
-// Open requests must be manually aborted on unload (#5280)
-if ( window.ActiveXObject ) {
- jQuery( window ).on( "unload", function() {
- for ( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]();
- }
- });
-}
-
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-support.ajax = xhrSupported = !!xhrSupported;
-
-jQuery.ajaxTransport(function( options ) {
- var callback;
-
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( support.cors || xhrSupported && !options.crossDomain ) {
- return {
- send: function( headers, complete ) {
- var i,
- xhr = options.xhr(),
- id = ++xhrId;
-
- xhr.open( options.type, options.url,
options.async, options.username, options.password );
-
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i
];
- }
- }
-
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType )
{
- xhr.overrideMimeType( options.mimeType
);
- }
-
- // X-Requested-With header
- // For cross-domain requests, seeing as
conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set
it to be sure.
- // (it can always be set on a per-request basis
or even using ajaxSetup)
- // For same-domain requests, won't change
header if already provided.
- if ( !options.crossDomain &&
!headers["X-Requested-With"] ) {
- headers["X-Requested-With"] =
"XMLHttpRequest";
- }
-
- // Set headers
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
-
- // Callback
- callback = function( type ) {
- return function() {
- if ( callback ) {
- delete xhrCallbacks[ id
];
- callback = xhr.onload =
xhr.onerror = null;
-
- if ( type === "abort" )
{
- xhr.abort();
- } else if ( type ===
"error" ) {
- complete(
- //
file: protocol always yields status 0; see #8605, #14207
-
xhr.status,
-
xhr.statusText
- );
- } else {
- complete(
-
xhrSuccessStatus[ xhr.status ] || xhr.status,
-
xhr.statusText,
- //
Support: IE9
- //
Accessing binary-data responseText throws an exception
- //
(#11426)
- typeof
xhr.responseText === "string" ? {
-
text: xhr.responseText
- } :
undefined,
-
xhr.getAllResponseHeaders()
- );
- }
- }
- };
- };
-
- // Listen to events
- xhr.onload = callback();
- xhr.onerror = callback("error");
-
- // Create the abort callback
- callback = xhrCallbacks[ id ] =
callback("abort");
-
- try {
- // Do send the request (this may raise
an exception)
- xhr.send( options.hasContent &&
options.data || null );
- } catch ( e ) {
- // #14683: Only rethrow if this hasn't
been notified as an error yet
- if ( callback ) {
- throw e;
- }
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback();
- }
- }
- };
- }
-});
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup({
- accepts: {
- script: "text/javascript, application/javascript,
application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /(?:java|ecma)script/
- },
- converters: {
- "text script": function( text ) {
- jQuery.globalEval( text );
- return text;
- }
- }
-});
-
-// Handle cache's special case and crossDomain
-jQuery.ajaxPrefilter( "script", function( s ) {
- if ( s.cache === undefined ) {
- s.cache = false;
- }
- if ( s.crossDomain ) {
- s.type = "GET";
- }
-});
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function( s ) {
- // This transport only deals with cross domain requests
- if ( s.crossDomain ) {
- var script, callback;
- return {
- send: function( _, complete ) {
- script = jQuery("<script>").prop({
- async: true,
- charset: s.scriptCharset,
- src: s.url
- }).on(
- "load error",
- callback = function( evt ) {
- script.remove();
- callback = null;
- if ( evt ) {
- complete( evt.type ===
"error" ? 404 : 200, evt.type );
- }
- }
- );
- document.head.appendChild( script[ 0 ] );
- },
- abort: function() {
- if ( callback ) {
- callback();
- }
- }
- };
- }
-});
-
-
-
-
-var oldCallbacks = [],
- rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup({
- jsonp: "callback",
- jsonpCallback: function() {
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + (
nonce++ ) );
- this[ callback ] = true;
- return callback;
- }
-});
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
- var callbackName, overwritten, responseContainer,
- jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
- "url" :
- typeof s.data === "string" && !( s.contentType || ""
).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) &&
"data"
- );
-
- // Handle iff the expected data type is "jsonp" or we have a parameter
to set
- if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
- // Get callback name, remembering preexisting value associated
with it
- callbackName = s.jsonpCallback = jQuery.isFunction(
s.jsonpCallback ) ?
- s.jsonpCallback() :
- s.jsonpCallback;
-
- // Insert callback into url or form data
- if ( jsonProp ) {
- s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" +
callbackName );
- } else if ( s.jsonp !== false ) {
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp
+ "=" + callbackName;
- }
-
- // Use data converter to retrieve json after script execution
- s.converters["script json"] = function() {
- if ( !responseContainer ) {
- jQuery.error( callbackName + " was not called"
);
- }
- return responseContainer[ 0 ];
- };
-
- // force json dataType
- s.dataTypes[ 0 ] = "json";
-
- // Install callback
- overwritten = window[ callbackName ];
- window[ callbackName ] = function() {
- responseContainer = arguments;
- };
-
- // Clean-up function (fires after converters)
- jqXHR.always(function() {
- // Restore preexisting value
- window[ callbackName ] = overwritten;
-
- // Save back as free
- if ( s[ callbackName ] ) {
- // make sure that re-using the options doesn't
screw things around
- s.jsonpCallback =
originalSettings.jsonpCallback;
-
- // save the callback name for future use
- oldCallbacks.push( callbackName );
- }
-
- // Call if it was a function and we have a response
- if ( responseContainer && jQuery.isFunction(
overwritten ) ) {
- overwritten( responseContainer[ 0 ] );
- }
-
- responseContainer = overwritten = undefined;
- });
-
- // Delegate to script
- return "script";
- }
-});
-
-
-
-
-// data: string of html
-// context (optional): If specified, the fragment will be created in this
context, defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html
string
-jQuery.parseHTML = function( data, context, keepScripts ) {
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- if ( typeof context === "boolean" ) {
- keepScripts = context;
- context = false;
- }
- context = context || document;
-
- var parsed = rsingleTag.exec( data ),
- scripts = !keepScripts && [];
-
- // Single tag
- if ( parsed ) {
- return [ context.createElement( parsed[1] ) ];
- }
-
- parsed = jQuery.buildFragment( [ data ], context, scripts );
-
- if ( scripts && scripts.length ) {
- jQuery( scripts ).remove();
- }
-
- return jQuery.merge( [], parsed.childNodes );
-};
-
-
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
- }
-
- var selector, type, response,
- self = this,
- off = url.indexOf(" ");
-
- if ( off >= 0 ) {
- selector = jQuery.trim( url.slice( off ) );
- url = url.slice( 0, off );
- }
-
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
-
- // We assume that it's the callback
- callback = params;
- params = undefined;
-
- // Otherwise, build a param string
- } else if ( params && typeof params === "object" ) {
- type = "POST";
- }
-
- // If we have elements to modify, make the request
- if ( self.length > 0 ) {
- jQuery.ajax({
- url: url,
-
- // if "type" variable is undefined, then "GET" method
will be used
- type: type,
- dataType: "html",
- data: params
- }).done(function( responseText ) {
-
- // Save response for use in complete callback
- response = arguments;
-
- self.html( selector ?
-
- // If a selector was specified, locate the
right elements in a dummy div
- // Exclude scripts to avoid IE 'Permission
Denied' errors
- jQuery("<div>").append( jQuery.parseHTML(
responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- }).complete( callback && function( jqXHR, status ) {
- self.each( callback, response || [ jqXHR.responseText,
status, jqXHR ] );
- });
- }
-
- return this;
-};
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
-};
-
-
-
-
-var docElem = window.document.documentElement;
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 &&
elem.defaultView;
-}
-
-jQuery.offset = {
- setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset,
curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
-
- // Set position first, in-case top/left are set even on static
elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position ===
"fixed" ) &&
- ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
-
- // Need to be able to calculate position if either top or left
is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
-
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) +
curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
-
- } else {
- curElem.css( props );
- }
- }
-};
-
-jQuery.fn.extend({
- offset: function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options,
i );
- });
- }
-
- var docElem, win,
- elem = this[ 0 ],
- box = { top: 0, left: 0 },
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- // If we don't have gBCR, just use 0,0 rather than error
- // BlackBerry 5, iOS 3 (original iPhone)
- if ( typeof elem.getBoundingClientRect !== strundefined ) {
- box = elem.getBoundingClientRect();
- }
- win = getWindow( doc );
- return {
- top: box.top + win.pageYOffset - docElem.clientTop,
- left: box.left + win.pageXOffset - docElem.clientLeft
- };
- },
-
- position: function() {
- if ( !this[ 0 ] ) {
- return;
- }
-
- var offsetParent, offset,
- elem = this[ 0 ],
- parentOffset = { top: 0, left: 0 };
-
- // Fixed elements are offset from window (parentOffset =
{top:0, left: 0}, because it is its only offset parent
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
- // We assume that getBoundingClientRect is available
when computed position is fixed
- offset = elem.getBoundingClientRect();
-
- } else {
- // Get *real* offsetParent
- offsetParent = this.offsetParent();
-
- // Get correct offsets
- offset = this.offset();
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
- parentOffset = offsetParent.offset();
- }
-
- // Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ],
"borderTopWidth", true );
- parentOffset.left += jQuery.css( offsetParent[ 0 ],
"borderLeftWidth", true );
- }
-
- // Subtract parent offsets and element margins
- return {
- top: offset.top - parentOffset.top - jQuery.css( elem,
"marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css(
elem, "marginLeft", true )
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || docElem;
-
- while ( offsetParent && ( !jQuery.nodeName(
offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" )
) {
- offsetParent = offsetParent.offsetParent;
- }
-
- return offsetParent || docElem;
- });
- }
-});
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" },
function( method, prop ) {
- var top = "pageYOffset" === prop;
-
- jQuery.fn[ method ] = function( val ) {
- return access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? win[ prop ] : elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : window.pageXOffset,
- top ? val : window.pageYOffset
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length, null );
- };
-});
-
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// getComputedStyle returns percent when specified for top/left/bottom/right
-// rather than make the css module depend on the offset module, we just check
for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
- function( elem, computed ) {
- if ( computed ) {
- computed = curCSS( elem, prop );
- // if curCSS returns percentage, fallback to
offset
- return rnumnonpx.test( computed ) ?
- jQuery( elem ).position()[ prop ] +
"px" :
- computed;
- }
- }
- );
-});
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth
methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" +
name }, function( defaultExtra, funcName ) {
- // margin is only for outerHeight, outerWidth
- jQuery.fn[ funcName ] = function( margin, value ) {
- var chainable = arguments.length && ( defaultExtra ||
typeof margin !== "boolean" ),
- extra = defaultExtra || ( margin === true ||
value === true ? "margin" : "border" );
-
- return access( this, function( elem, type, value ) {
- var doc;
-
- if ( jQuery.isWindow( elem ) ) {
- // As of 5/8/2012 this will yield
incorrect results for Mobile Safari, but there
- // isn't a whole lot we can do. See
pull request at this URL for discussion:
- //
https://github.com/jquery/jquery/pull/764
- return elem.document.documentElement[
"client" + name ];
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- doc = elem.documentElement;
-
- // Either scroll[Width/Height] or
offset[Width/Height] or client[Width/Height],
- // whichever is greatest
- return Math.max(
- elem.body[ "scroll" + name ],
doc[ "scroll" + name ],
- elem.body[ "offset" + name ],
doc[ "offset" + name ],
- doc[ "client" + name ]
- );
- }
-
- return value === undefined ?
- // Get width or height on the element,
requesting but not forcing parseFloat
- jQuery.css( elem, type, extra ) :
-
- // Set width or height on the element
- jQuery.style( elem, type, value, extra
);
- }, type, chainable ? margin : undefined, chainable,
null );
- };
- });
-});
-
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
- return this.length;
-};
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-//
https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function() {
- return jQuery;
- });
-}
-
-
-
-
-var
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$;
-
-jQuery.noConflict = function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in
-// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === strundefined ) {
- window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-
-}));
diff --git a/packages/context-coloring/fixtures/benchmark/lisp.el
b/packages/context-coloring/fixtures/benchmark/lisp.el
deleted file mode 100644
index 7ebd80a..0000000
--- a/packages/context-coloring/fixtures/benchmark/lisp.el
+++ /dev/null
@@ -1,930 +0,0 @@
-;;; lisp.el --- Lisp editing commands for Emacs -*- lexical-binding:t -*-
-
-;; Copyright (C) 1985-1986, 1994, 2000-2015 Free Software Foundation, Inc.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: lisp, languages
-;; Package: emacs
-
-;; 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:
-
-;; Lisp editing commands to go with Lisp major mode. More-or-less
-;; applicable in other modes too.
-
-;;; Code:
-
-;; Note that this variable is used by non-lisp modes too.
-(defcustom defun-prompt-regexp nil
- "If non-nil, a regexp to ignore before a defun.
-This is only necessary if the opening paren or brace is not in column 0.
-See function `beginning-of-defun'."
- :type '(choice (const nil)
- regexp)
- :group 'lisp)
-(make-variable-buffer-local 'defun-prompt-regexp)
-
-(defcustom parens-require-spaces t
- "If non-nil, add whitespace as needed when inserting parentheses.
-This affects `insert-parentheses' and `insert-pair'."
- :type 'boolean
- :group 'lisp)
-
-(defvar forward-sexp-function nil
- ;; FIXME:
- ;; - for some uses, we may want a "sexp-only" version, which only
- ;; jumps over a well-formed sexp, rather than some dwimish thing
- ;; like jumping from an "else" back up to its "if".
- ;; - for up-list, we could use the "sexp-only" behavior as well
- ;; to treat the dwimish halfsexp as a form of "up-list" step.
- "If non-nil, `forward-sexp' delegates to this function.
-Should take the same arguments and behave similarly to `forward-sexp'.")
-
-(defun forward-sexp (&optional arg)
- "Move forward across one balanced expression (sexp).
-With ARG, do it that many times. Negative arg -N means
-move backward across N balanced expressions.
-This command assumes point is not in a string or comment.
-Calls `forward-sexp-function' to do the work, if that is non-nil."
- (interactive "^p")
- (or arg (setq arg 1))
- (if forward-sexp-function
- (funcall forward-sexp-function arg)
- (goto-char (or (scan-sexps (point) arg) (buffer-end arg)))
- (if (< arg 0) (backward-prefix-chars))))
-
-(defun backward-sexp (&optional arg)
- "Move backward across one balanced expression (sexp).
-With ARG, do it that many times. Negative arg -N means
-move forward across N balanced expressions.
-This command assumes point is not in a string or comment.
-Uses `forward-sexp' to do the work."
- (interactive "^p")
- (or arg (setq arg 1))
- (forward-sexp (- arg)))
-
-(defun mark-sexp (&optional arg allow-extend)
- "Set mark ARG sexps from point.
-The place mark goes is the same place \\[forward-sexp] would
-move to with the same argument.
-Interactively, if this command is repeated
-or (in Transient Mark mode) if the mark is active,
-it marks the next ARG sexps after the ones already marked.
-This command assumes point is not in a string or comment."
- (interactive "P\np")
- (cond ((and allow-extend
- (or (and (eq last-command this-command) (mark t))
- (and transient-mark-mode mark-active)))
- (setq arg (if arg (prefix-numeric-value arg)
- (if (< (mark) (point)) -1 1)))
- (set-mark
- (save-excursion
- (goto-char (mark))
- (forward-sexp arg)
- (point))))
- (t
- (push-mark
- (save-excursion
- (forward-sexp (prefix-numeric-value arg))
- (point))
- nil t))))
-
-(defun forward-list (&optional arg)
- "Move forward across one balanced group of parentheses.
-This command will also work on other parentheses-like expressions
-defined by the current language mode.
-With ARG, do it that many times.
-Negative arg -N means move backward across N groups of parentheses.
-This command assumes point is not in a string or comment."
- (interactive "^p")
- (or arg (setq arg 1))
- (goto-char (or (scan-lists (point) arg 0) (buffer-end arg))))
-
-(defun backward-list (&optional arg)
- "Move backward across one balanced group of parentheses.
-This command will also work on other parentheses-like expressions
-defined by the current language mode.
-With ARG, do it that many times.
-Negative arg -N means move forward across N groups of parentheses.
-This command assumes point is not in a string or comment."
- (interactive "^p")
- (or arg (setq arg 1))
- (forward-list (- arg)))
-
-(defun down-list (&optional arg)
- "Move forward down one level of parentheses.
-This command will also work on other parentheses-like expressions
-defined by the current language mode.
-With ARG, do this that many times.
-A negative argument means move backward but still go down a level.
-This command assumes point is not in a string or comment."
- (interactive "^p")
- (or arg (setq arg 1))
- (let ((inc (if (> arg 0) 1 -1)))
- (while (/= arg 0)
- (goto-char (or (scan-lists (point) inc -1) (buffer-end arg)))
- (setq arg (- arg inc)))))
-
-(defun backward-up-list (&optional arg)
- "Move backward out of one level of parentheses.
-This command will also work on other parentheses-like expressions
-defined by the current language mode.
-With ARG, do this that many times.
-A negative argument means move forward but still to a less deep spot.
-This command assumes point is not in a string or comment."
- (interactive "^p")
- (up-list (- (or arg 1))))
-
-(defun up-list (&optional arg)
- "Move forward out of one level of parentheses.
-This command will also work on other parentheses-like expressions
-defined by the current language mode.
-With ARG, do this that many times.
-A negative argument means move backward but still to a less deep spot.
-This command assumes point is not in a string or comment."
- (interactive "^p")
- (or arg (setq arg 1))
- (let ((inc (if (> arg 0) 1 -1))
- pos)
- (while (/= arg 0)
- (if (null forward-sexp-function)
- (goto-char (or (scan-lists (point) inc 1) (buffer-end arg)))
- (condition-case err
- (while (progn (setq pos (point))
- (forward-sexp inc)
- (/= (point) pos)))
- (scan-error (goto-char (nth (if (> arg 0) 3 2) err))))
- (if (= (point) pos)
- (signal 'scan-error
- (list "Unbalanced parentheses" (point) (point)))))
- (setq arg (- arg inc)))))
-
-(defun kill-sexp (&optional arg)
- "Kill the sexp (balanced expression) following point.
-With ARG, kill that many sexps after point.
-Negative arg -N means kill N sexps before point.
-This command assumes point is not in a string or comment."
- (interactive "p")
- (let ((opoint (point)))
- (forward-sexp (or arg 1))
- (kill-region opoint (point))))
-
-(defun backward-kill-sexp (&optional arg)
- "Kill the sexp (balanced expression) preceding point.
-With ARG, kill that many sexps before point.
-Negative arg -N means kill N sexps after point.
-This command assumes point is not in a string or comment."
- (interactive "p")
- (kill-sexp (- (or arg 1))))
-
-;; After Zmacs:
-(defun kill-backward-up-list (&optional arg)
- "Kill the form containing the current sexp, leaving the sexp itself.
-A prefix argument ARG causes the relevant number of surrounding
-forms to be removed.
-This command assumes point is not in a string or comment."
- (interactive "*p")
- (let ((current-sexp (thing-at-point 'sexp)))
- (if current-sexp
- (save-excursion
- (backward-up-list arg)
- (kill-sexp)
- (insert current-sexp))
- (error "Not at a sexp"))))
-
-(defvar beginning-of-defun-function nil
- "If non-nil, function for `beginning-of-defun-raw' to call.
-This is used to find the beginning of the defun instead of using the
-normal recipe (see `beginning-of-defun'). Major modes can define this
-if defining `defun-prompt-regexp' is not sufficient to handle the mode's
-needs.
-
-The function takes the same argument as `beginning-of-defun' and should
-behave similarly, returning non-nil if it found the beginning of a defun.
-Ideally it should move to a point right before an open-paren which encloses
-the body of the defun.")
-
-(defun beginning-of-defun (&optional arg)
- "Move backward to the beginning of a defun.
-With ARG, do it that many times. Negative ARG means move forward
-to the ARGth following beginning of defun.
-
-If search is successful, return t; point ends up at the beginning
-of the line where the search succeeded. Otherwise, return nil.
-
-When `open-paren-in-column-0-is-defun-start' is non-nil, a defun
-is assumed to start where there is a char with open-parenthesis
-syntax at the beginning of a line. If `defun-prompt-regexp' is
-non-nil, then a string which matches that regexp may also precede
-the open-parenthesis. If `defun-prompt-regexp' and
-`open-paren-in-column-0-is-defun-start' are both nil, this
-function instead finds an open-paren at the outermost level.
-
-If the variable `beginning-of-defun-function' is non-nil, its
-value is called as a function, with argument ARG, to find the
-defun's beginning.
-
-Regardless of the values of `defun-prompt-regexp' and
-`beginning-of-defun-function', point always moves to the
-beginning of the line whenever the search is successful."
- (interactive "^p")
- (or (not (eq this-command 'beginning-of-defun))
- (eq last-command 'beginning-of-defun)
- (and transient-mark-mode mark-active)
- (push-mark))
- (and (beginning-of-defun-raw arg)
- (progn (beginning-of-line) t)))
-
-(defun beginning-of-defun-raw (&optional arg)
- "Move point to the character that starts a defun.
-This is identical to function `beginning-of-defun', except that point
-does not move to the beginning of the line when `defun-prompt-regexp'
-is non-nil.
-
-If variable `beginning-of-defun-function' is non-nil, its value
-is called as a function to find the defun's beginning."
- (interactive "^p") ; change this to "P", maybe, if we ever come to pass ARG
- ; to beginning-of-defun-function.
- (unless arg (setq arg 1))
- (cond
- (beginning-of-defun-function
- (condition-case nil
- (funcall beginning-of-defun-function arg)
- ;; We used to define beginning-of-defun-function as taking no argument
- ;; but that makes it impossible to implement correct forward motion:
- ;; we used to use end-of-defun for that, but it's not supposed to do
- ;; the same thing (it moves to the end of a defun not to the beginning
- ;; of the next).
- ;; In case the beginning-of-defun-function uses the old calling
- ;; convention, fallback on the old implementation.
- (wrong-number-of-arguments
- (if (> arg 0)
- (dotimes (_ arg)
- (funcall beginning-of-defun-function))
- (dotimes (_ (- arg))
- (funcall end-of-defun-function))))))
-
- ((or defun-prompt-regexp open-paren-in-column-0-is-defun-start)
- (and (< arg 0) (not (eobp)) (forward-char 1))
- (and (re-search-backward (if defun-prompt-regexp
- (concat (if
open-paren-in-column-0-is-defun-start
- "^\\s(\\|" "")
- "\\(?:" defun-prompt-regexp "\\)\\s(")
- "^\\s(")
- nil 'move arg)
- (progn (goto-char (1- (match-end 0)))
- t)))
-
- ;; If open-paren-in-column-0-is-defun-start and defun-prompt-regexp
- ;; are both nil, column 0 has no significance - so scan forward
- ;; from BOB to see how nested point is, then carry on from there.
- ;;
- ;; It is generally not a good idea to land up here, because the
- ;; call to scan-lists below can be extremely slow. This is because
- ;; back_comment in syntax.c may have to scan from bob to find the
- ;; beginning of each comment. Fixing this is not trivial -- cyd.
-
- ((eq arg 0))
- (t
- (let ((floor (point-min))
- (ceiling (point-max))
- (arg-+ve (> arg 0)))
- (save-restriction
- (widen)
- (let ((ppss (let (syntax-begin-function
- font-lock-beginning-of-syntax-function)
- (syntax-ppss)))
- ;; position of least enclosing paren, or nil.
- encl-pos)
- ;; Back out of any comment/string, so that encl-pos will always
- ;; become nil if we're at top-level.
- (when (nth 8 ppss)
- (goto-char (nth 8 ppss))
- (setq ppss (syntax-ppss))) ; should be fast, due to cache.
- (setq encl-pos (syntax-ppss-toplevel-pos ppss))
- (if encl-pos (goto-char encl-pos))
-
- (and encl-pos arg-+ve (setq arg (1- arg)))
- (and (not encl-pos) (not arg-+ve) (not (looking-at "\\s("))
- (setq arg (1+ arg)))
-
- (condition-case nil ; to catch crazy parens.
- (progn
- (goto-char (scan-lists (point) (- arg) 0))
- (if arg-+ve
- (if (>= (point) floor)
- t
- (goto-char floor)
- nil)
- ;; forward to next (, or trigger the c-c
- (goto-char (1- (scan-lists (point) 1 -1)))
- (if (<= (point) ceiling)
- t
- (goto-char ceiling)
- nil)))
- (error
- (goto-char (if arg-+ve floor ceiling))
- nil))))))))
-
-(defvar end-of-defun-function
- (lambda () (forward-sexp 1))
- "Function for `end-of-defun' to call.
-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 the function can assume that point is at the beginning of the defun body.
-It should move point to the first position after the defun.")
-
-(defun buffer-end (arg)
- "Return the \"far end\" position of the buffer, in direction ARG.
-If ARG is positive, that's the end of the buffer.
-Otherwise, that's the beginning of the buffer."
- (if (> arg 0) (point-max) (point-min)))
-
-(defun end-of-defun (&optional arg)
- "Move forward to next end of defun.
-With argument, do it that many times.
-Negative argument -N means move back to Nth preceding end of defun.
-
-An end of a defun occurs right after the close-parenthesis that
-matches the open-parenthesis that starts a defun; see function
-`beginning-of-defun'.
-
-If variable `end-of-defun-function' is non-nil, its value
-is called as a function to find the defun's end."
- (interactive "^p")
- (or (not (eq this-command 'end-of-defun))
- (eq last-command 'end-of-defun)
- (and transient-mark-mode mark-active)
- (push-mark))
- (if (or (null arg) (= arg 0)) (setq arg 1))
- (let ((pos (point))
- (beg (progn (end-of-line 1) (beginning-of-defun-raw 1) (point)))
- (skip (lambda ()
- ;; When comparing point against pos, we want to consider that if
- ;; point was right after the end of the function, it's still
- ;; considered as "in that function".
- ;; E.g. `eval-defun' from right after the last close-paren.
- (unless (bolp)
- (skip-chars-forward " \t")
- (if (looking-at "\\s<\\|\n")
- (forward-line 1))))))
- (funcall end-of-defun-function)
- (funcall skip)
- (cond
- ((> arg 0)
- ;; Moving forward.
- (if (> (point) pos)
- ;; We already moved forward by one because we started from
- ;; within a function.
- (setq arg (1- arg))
- ;; We started from after the end of the previous function.
- (goto-char pos))
- (unless (zerop arg)
- (beginning-of-defun-raw (- arg))
- (funcall end-of-defun-function)))
- ((< arg 0)
- ;; Moving backward.
- (if (< (point) pos)
- ;; We already moved backward because we started from between
- ;; two functions.
- (setq arg (1+ arg))
- ;; We started from inside a function.
- (goto-char beg))
- (unless (zerop arg)
- (beginning-of-defun-raw (- arg))
- (setq beg (point))
- (funcall end-of-defun-function))))
- (funcall skip)
- (while (and (< arg 0) (>= (point) pos))
- ;; We intended to move backward, but this ended up not doing so:
- ;; Try harder!
- (goto-char beg)
- (beginning-of-defun-raw (- arg))
- (if (>= (point) beg)
- (setq arg 0)
- (setq beg (point))
- (funcall end-of-defun-function)
- (funcall skip)))))
-
-(defun mark-defun (&optional allow-extend)
- "Put mark at end of this defun, point at beginning.
-The defun 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 defun after the ones already marked."
- (interactive "p")
- (cond ((and allow-extend
- (or (and (eq last-command this-command) (mark t))
- (and transient-mark-mode mark-active)))
- (set-mark
- (save-excursion
- (goto-char (mark))
- (end-of-defun)
- (point))))
- (t
- (let ((opoint (point))
- beg end)
- (push-mark opoint)
- ;; Try first in this order for the sake of languages with nested
- ;; functions where several can end at the same place as with
- ;; the offside rule, e.g. Python.
- (beginning-of-defun)
- (setq beg (point))
- (end-of-defun)
- (setq end (point))
- (while (looking-at "^\n")
- (forward-line 1))
- (if (> (point) opoint)
- (progn
- ;; We got the right defun.
- (push-mark beg nil t)
- (goto-char end)
- (exchange-point-and-mark))
- ;; beginning-of-defun moved back one defun
- ;; so we got the wrong one.
- (goto-char opoint)
- (end-of-defun)
- (push-mark (point) nil t)
- (beginning-of-defun))
- (re-search-backward "^\n" (- (point) 1) t)))))
-
-(defun narrow-to-defun (&optional _arg)
- "Make text outside current defun invisible.
-The defun visible is the one that contains point or follows point.
-Optional ARG is ignored."
- (interactive)
- (save-excursion
- (widen)
- (let ((opoint (point))
- beg end)
- ;; Try first in this order for the sake of languages with nested
- ;; functions where several can end at the same place as with
- ;; the offside rule, e.g. Python.
-
- ;; Finding the start of the function is a bit problematic since
- ;; `beginning-of-defun' when we are on the first character of
- ;; the function might go to the previous function.
- ;;
- ;; Therefore we first move one character forward and then call
- ;; `beginning-of-defun'. However now we must check that we did
- ;; not move into the next function.
- (let ((here (point)))
- (unless (eolp)
- (forward-char))
- (beginning-of-defun)
- (when (< (point) here)
- (goto-char here)
- (beginning-of-defun)))
- (setq beg (point))
- (end-of-defun)
- (setq end (point))
- (while (looking-at "^\n")
- (forward-line 1))
- (unless (> (point) opoint)
- ;; beginning-of-defun moved back one defun
- ;; so we got the wrong one.
- (goto-char opoint)
- (end-of-defun)
- (setq end (point))
- (beginning-of-defun)
- (setq beg (point)))
- (goto-char end)
- (re-search-backward "^\n" (- (point) 1) t)
- (narrow-to-region beg end))))
-
-(defvar insert-pair-alist
- '((?\( ?\)) (?\[ ?\]) (?\{ ?\}) (?\< ?\>) (?\" ?\") (?\' ?\') (?\` ?\'))
- "Alist of paired characters inserted by `insert-pair'.
-Each element looks like (OPEN-CHAR CLOSE-CHAR) or (COMMAND-CHAR
-OPEN-CHAR CLOSE-CHAR). The characters OPEN-CHAR and CLOSE-CHAR
-of the pair whose key is equal to the last input character with
-or without modifiers, are inserted by `insert-pair'.")
-
-(defun insert-pair (&optional arg open close)
- "Enclose following ARG sexps in a pair of OPEN and CLOSE characters.
-Leave point after the first character.
-A negative ARG encloses the preceding ARG sexps instead.
-No argument is equivalent to zero: just insert characters
-and leave point between.
-If `parens-require-spaces' is non-nil, this command also inserts a space
-before and after, depending on the surrounding characters.
-If region is active, insert enclosing characters at region boundaries.
-
-If arguments OPEN and CLOSE are nil, the character pair is found
-from the variable `insert-pair-alist' according to the last input
-character with or without modifiers. If no character pair is
-found in the variable `insert-pair-alist', then the last input
-character is inserted ARG times.
-
-This command assumes point is not in a string or comment."
- (interactive "P")
- (if (not (and open close))
- (let ((pair (or (assq last-command-event insert-pair-alist)
- (assq (event-basic-type last-command-event)
- insert-pair-alist))))
- (if pair
- (if (nth 2 pair)
- (setq open (nth 1 pair) close (nth 2 pair))
- (setq open (nth 0 pair) close (nth 1 pair))))))
- (if (and open close)
- (if (and transient-mark-mode mark-active)
- (progn
- (save-excursion (goto-char (region-end)) (insert close))
- (save-excursion (goto-char (region-beginning)) (insert open)))
- (if arg (setq arg (prefix-numeric-value arg))
- (setq arg 0))
- (cond ((> arg 0) (skip-chars-forward " \t"))
- ((< arg 0) (forward-sexp arg) (setq arg (- arg))))
- (and parens-require-spaces
- (not (bobp))
- (memq (char-syntax (preceding-char)) (list ?w ?_ (char-syntax
close)))
- (insert " "))
- (insert open)
- (save-excursion
- (or (eq arg 0) (forward-sexp arg))
- (insert close)
- (and parens-require-spaces
- (not (eobp))
- (memq (char-syntax (following-char)) (list ?w ?_ (char-syntax
open)))
- (insert " "))))
- (insert-char (event-basic-type last-command-event)
- (prefix-numeric-value arg))))
-
-(defun insert-parentheses (&optional arg)
- "Enclose following ARG sexps in parentheses.
-Leave point after open-paren.
-A negative ARG encloses the preceding ARG sexps instead.
-No argument is equivalent to zero: just insert `()' and leave point between.
-If `parens-require-spaces' is non-nil, this command also inserts a space
-before and after, depending on the surrounding characters.
-If region is active, insert enclosing characters at region boundaries.
-
-This command assumes point is not in a string or comment."
- (interactive "P")
- (insert-pair arg ?\( ?\)))
-
-(defun delete-pair ()
- "Delete a pair of characters enclosing the sexp that follows point."
- (interactive)
- (save-excursion (forward-sexp 1) (delete-char -1))
- (delete-char 1))
-
-(defun raise-sexp (&optional arg)
- "Raise ARG sexps higher up the tree."
- (interactive "p")
- (let ((s (if (and transient-mark-mode mark-active)
- (buffer-substring (region-beginning) (region-end))
- (buffer-substring
- (point)
- (save-excursion (forward-sexp arg) (point))))))
- (backward-up-list 1)
- (delete-region (point) (save-excursion (forward-sexp 1) (point)))
- (save-excursion (insert s))))
-
-(defun move-past-close-and-reindent ()
- "Move past next `)', delete indentation before it, then indent after it."
- (interactive)
- (up-list 1)
- (forward-char -1)
- (while (save-excursion ; this is my contribution
- (let ((before-paren (point)))
- (back-to-indentation)
- (and (= (point) before-paren)
- (progn
- ;; Move to end of previous line.
- (beginning-of-line)
- (forward-char -1)
- ;; Verify it doesn't end within a string or comment.
- (let ((end (point))
- state)
- (beginning-of-line)
- ;; Get state at start of line.
- (setq state (list 0 nil nil
- (null (calculate-lisp-indent))
- nil nil nil nil
- nil))
- ;; Parse state across the line to get state at end.
- (setq state (parse-partial-sexp (point) end nil nil
- state))
- ;; Check not in string or comment.
- (and (not (elt state 3)) (not (elt state 4))))))))
- (delete-indentation))
- (forward-char 1)
- (newline-and-indent))
-
-(defun check-parens () ; lame name?
- "Check for unbalanced parentheses in the current buffer.
-More accurately, check the narrowed part of the buffer for unbalanced
-expressions (\"sexps\") in general. This is done according to the
-current syntax table and will find unbalanced brackets or quotes as
-appropriate. (See Info node `(emacs)Parentheses'.) If imbalance is
-found, an error is signaled and point is left at the first unbalanced
-character."
- (interactive)
- (condition-case data
- ;; Buffer can't have more than (point-max) sexps.
- (scan-sexps (point-min) (point-max))
- (scan-error (goto-char (nth 2 data))
- ;; Could print (nth 1 data), which is either
- ;; "Containing expression ends prematurely" or
- ;; "Unbalanced parentheses", but those may not be so
- ;; accurate/helpful, e.g. quotes may actually be
- ;; mismatched.
- (user-error "Unmatched bracket or quote"))))
-
-(defun field-complete (table &optional predicate)
- (declare (obsolete completion-in-region "24.4"))
- (let ((minibuffer-completion-table table)
- (minibuffer-completion-predicate predicate)
- ;; This made sense for lisp-complete-symbol, but for
- ;; field-complete, this is out of place. --Stef
- ;; (completion-annotate-function
- ;; (unless (eq predicate 'fboundp)
- ;; (lambda (str)
- ;; (if (fboundp (intern-soft str)) " <f>"))))
- )
- (call-interactively 'minibuffer-complete)))
-
-(defun lisp-complete-symbol (&optional predicate)
- "Perform completion on Lisp symbol preceding point.
-Compare that symbol against the known Lisp symbols.
-If no characters can be completed, display a list of possible completions.
-Repeating the command at that point scrolls the list.
-
-When called from a program, optional arg PREDICATE is a predicate
-determining which symbols are considered, e.g. `commandp'.
-If PREDICATE is nil, the context determines which symbols are
-considered. If the symbol starts just after an open-parenthesis, only
-symbols with function definitions are considered. Otherwise, all
-symbols with function definitions, values or properties are
-considered."
- (declare (obsolete completion-at-point "24.4"))
- (interactive)
- (let* ((data (lisp-completion-at-point predicate))
- (plist (nthcdr 3 data)))
- (if (null data)
- (minibuffer-message "Nothing to complete")
- (let ((completion-extra-properties plist))
- (completion-in-region (nth 0 data) (nth 1 data) (nth 2 data)
- (plist-get plist :predicate))))))
-
-(defun lisp--local-variables-1 (vars sexp)
- "Return the vars locally bound around the witness, or nil if not found."
- (let (res)
- (while
- (unless
- (setq res
- (pcase sexp
- (`(,(or `let `let*) ,bindings)
- (let ((vars vars))
- (when (eq 'let* (car sexp))
- (dolist (binding (cdr (reverse bindings)))
- (push (or (car-safe binding) binding) vars)))
- (lisp--local-variables-1
- vars (car (cdr-safe (car (last bindings)))))))
- (`(,(or `let `let*) ,bindings . ,body)
- (let ((vars vars))
- (dolist (binding bindings)
- (push (or (car-safe binding) binding) vars))
- (lisp--local-variables-1 vars (car (last body)))))
- (`(lambda ,_) (setq sexp nil))
- (`(lambda ,args . ,body)
- (lisp--local-variables-1
- (append args vars) (car (last body))))
- (`(condition-case ,_ ,e) (lisp--local-variables-1 vars e))
- (`(condition-case ,v ,_ . ,catches)
- (lisp--local-variables-1
- (cons v vars) (cdr (car (last catches)))))
- (`(quote . ,_) (setq sexp nil))
- (`(,_ . ,_)
- (lisp--local-variables-1 vars (car (last sexp))))
- (`lisp--witness--lisp (or vars '(nil)))
- (_ nil)))
- (setq sexp (ignore-errors (butlast sexp)))))
- res))
-
-(defun lisp--local-variables ()
- "Return a list of locally let-bound variables at point."
- (save-excursion
- (skip-syntax-backward "w_")
- (let* ((ppss (syntax-ppss))
- (txt (buffer-substring-no-properties (or (car (nth 9 ppss)) (point))
- (or (nth 8 ppss) (point))))
- (closer ()))
- (dolist (p (nth 9 ppss))
- (push (cdr (syntax-after p)) closer))
- (setq closer (apply #'string closer))
- (let* ((sexp (condition-case nil
- (car (read-from-string
- (concat txt "lisp--witness--lisp" closer)))
- (end-of-file nil)))
- (macroexpand-advice (lambda (expander form &rest args)
- (condition-case nil
- (apply expander form args)
- (error form))))
- (sexp
- (unwind-protect
- (progn
- (advice-add 'macroexpand :around macroexpand-advice)
- (macroexpand-all sexp))
- (advice-remove 'macroexpand macroexpand-advice)))
- (vars (lisp--local-variables-1 nil sexp)))
- (delq nil
- (mapcar (lambda (var)
- (and (symbolp var)
- (not (string-match (symbol-name var) "\\`[&_]"))
- ;; Eliminate uninterned vars.
- (intern-soft var)
- var))
- vars))))))
-
-(defvar lisp--local-variables-completion-table
- ;; Use `defvar' rather than `defconst' since defconst would purecopy this
- ;; value, which would doubly fail: it would fail because purecopy can't
- ;; handle the recursive bytecode object, and it would fail because it would
- ;; move `lastpos' and `lastvars' to pure space where they'd be immutable!
- (let ((lastpos nil) (lastvars nil))
- (letrec ((hookfun (lambda ()
- (setq lastpos nil)
- (remove-hook 'post-command-hook hookfun))))
- (completion-table-dynamic
- (lambda (_string)
- (save-excursion
- (skip-syntax-backward "_w")
- (let ((newpos (cons (point) (current-buffer))))
- (unless (equal lastpos newpos)
- (add-hook 'post-command-hook hookfun)
- (setq lastpos newpos)
- (setq lastvars
- (mapcar #'symbol-name (lisp--local-variables))))))
- lastvars)))))
-
-;; FIXME: Support for Company brings in features which straddle eldoc.
-;; We should consolidate this, so that major modes can provide all that
-;; data all at once:
-;; - a function to extract "the reference at point" (may be more complex
-;; than a mere string, to distinguish various namespaces).
-;; - a function to jump to such a reference.
-;; - a function to show the signature/interface of such a reference.
-;; - a function to build a help-buffer about that reference.
-;; FIXME: Those functions should also be used by the normal completion code in
-;; the *Completions* buffer.
-
-(defun lisp--company-doc-buffer (str)
- (let ((symbol (intern-soft str)))
- ;; FIXME: we really don't want to "display-buffer and then undo it".
- (save-window-excursion
- ;; Make sure we don't display it in another frame, otherwise
- ;; save-window-excursion won't be able to undo it.
- (let ((display-buffer-overriding-action
- '(nil . ((inhibit-switch-frame . t)))))
- (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))))))
-
-(defun lisp--company-doc-string (str)
- (let* ((symbol (intern-soft str))
- (doc (if (fboundp symbol)
- (documentation symbol t)
- (documentation-property symbol 'variable-documentation t))))
- (and (stringp doc)
- (string-match ".*$" doc)
- (match-string 0 doc))))
-
-(declare-function find-library-name "find-func" (library))
-
-(defun lisp--company-location (str)
- (let ((sym (intern-soft str)))
- (cond
- ((fboundp sym) (find-definition-noselect sym nil))
- ((boundp sym) (find-definition-noselect sym 'defvar))
- ((featurep sym)
- (require 'find-func)
- (cons (find-file-noselect (find-library-name
- (symbol-name sym)))
- 0))
- ((facep sym) (find-definition-noselect sym 'defface)))))
-
-(defun lisp-completion-at-point (&optional _predicate)
- "Function used for `completion-at-point-functions' in `emacs-lisp-mode'."
- (with-syntax-table emacs-lisp-mode-syntax-table
- (let* ((pos (point))
- (beg (condition-case nil
- (save-excursion
- (backward-sexp 1)
- (skip-syntax-forward "'")
- (point))
- (scan-error pos)))
- (end
- (unless (or (eq beg (point-max))
- (member (char-syntax (char-after beg))
- '(?\s ?\" ?\( ?\))))
- (condition-case nil
- (save-excursion
- (goto-char beg)
- (forward-sexp 1)
- (when (>= (point) pos)
- (point)))
- (scan-error pos))))
- (funpos (eq (char-before beg) ?\()) ;t if in function position.
- (table-etc
- (if (not funpos)
- ;; FIXME: We could look at the first element of the list and
- ;; use it to provide a more specific completion table in some
- ;; cases. E.g. filter out keywords that are not understood by
- ;; the macro/function being called.
- (list nil (completion-table-merge
- lisp--local-variables-completion-table
- (apply-partially #'completion-table-with-predicate
- obarray
- ;; Don't include all symbols
- ;; (bug#16646).
- (lambda (sym)
- (or (boundp sym)
- (fboundp sym)
- (symbol-plist sym)))
- 'strict))
- :annotation-function
- (lambda (str) (if (fboundp (intern-soft str)) " <f>"))
- :company-doc-buffer #'lisp--company-doc-buffer
- :company-docsig #'lisp--company-doc-string
- :company-location #'lisp--company-location)
- ;; Looks like a funcall position. Let's double check.
- (save-excursion
- (goto-char (1- beg))
- (let ((parent
- (condition-case nil
- (progn (up-list -1) (forward-char 1)
- (let ((c (char-after)))
- (if (eq c ?\() ?\(
- (if (memq (char-syntax c) '(?w ?_))
- (read (current-buffer))))))
- (error nil))))
- (pcase parent
- ;; FIXME: Rather than hardcode special cases here,
- ;; we should use something like a symbol-property.
- (`declare
- (list t (mapcar (lambda (x) (symbol-name (car x)))
- (delete-dups
- ;; FIXME: We should include some
- ;; docstring with each entry.
- (append
- macro-declarations-alist
- defun-declarations-alist)))))
- ((and (or `condition-case `condition-case-unless-debug)
- (guard (save-excursion
- (ignore-errors
- (forward-sexp 2)
- (< (point) beg)))))
- (list t obarray
- :predicate (lambda (sym) (get sym
'error-conditions))))
- ((and ?\(
- (guard (save-excursion
- (goto-char (1- beg))
- (up-list -1)
- (forward-symbol -1)
- (looking-at "\\_<let\\*?\\_>"))))
- (list t obarray
- :predicate #'boundp
- :company-doc-buffer #'lisp--company-doc-buffer
- :company-docsig #'lisp--company-doc-string
- :company-location #'lisp--company-location))
- (_ (list nil obarray
- :predicate #'fboundp
- :company-doc-buffer #'lisp--company-doc-buffer
- :company-docsig #'lisp--company-doc-string
- :company-location #'lisp--company-location
- ))))))))
- (when end
- (let ((tail (if (null (car table-etc))
- (cdr table-etc)
- (cons
- (if (memq (char-syntax (or (char-after end) ?\s))
- '(?\s ?>))
- (cadr table-etc)
- (apply-partially 'completion-table-with-terminator
- " " (cadr table-etc)))
- (cddr table-etc)))))
- `(,beg ,end ,@tail))))))
-
-;;; lisp.el ends here
diff --git a/packages/context-coloring/fixtures/benchmark/lodash-2.4.1.js
b/packages/context-coloring/fixtures/benchmark/lodash-2.4.1.js
deleted file mode 100644
index d653e5a..0000000
--- a/packages/context-coloring/fixtures/benchmark/lodash-2.4.1.js
+++ /dev/null
@@ -1,6785 +0,0 @@
-/**
- * @license
- * Lo-Dash 2.4.1 (Custom Build) <http://lodash.com/>
- * Build: `lodash modern -o ./dist/lodash.js`
- * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
- * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
- * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative
Reporters & Editors
- * Available under MIT license <http://lodash.com/license>
- */
-;(function() {
-
- /** Used as a safe reference for `undefined` in pre ES5 environments */
- var undefined;
-
- /** Used to pool arrays and objects used internally */
- var arrayPool = [],
- objectPool = [];
-
- /** Used to generate unique IDs */
- var idCounter = 0;
-
- /** Used to prefix keys to avoid issues with `__proto__` and properties on
`Object.prototype` */
- var keyPrefix = +new Date + '';
-
- /** Used as the size when optimizations are enabled for large arrays */
- var largeArraySize = 75;
-
- /** Used as the max size of the `arrayPool` and `objectPool` */
- var maxPoolSize = 40;
-
- /** Used to detect and test whitespace */
- var whitespace = (
- // whitespace
- ' \t\x0B\f\xA0\ufeff' +
-
- // line terminators
- '\n\r\u2028\u2029' +
-
- // unicode category "Zs" space separators
-
'\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
- );
-
- /** Used to match empty string literals in compiled template source */
- var reEmptyStringLeading = /\b__p \+= '';/g,
- reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
- reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
-
- /**
- * Used to match ES6 template delimiters
- *
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
- */
- var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
-
- /** Used to match regexp flags from their coerced string values */
- var reFlags = /\w*$/;
-
- /** Used to detected named functions */
- var reFuncName = /^\s*function[ \n\r\t]+\w/;
-
- /** Used to match "interpolate" template delimiters */
- var reInterpolate = /<%=([\s\S]+?)%>/g;
-
- /** Used to match leading whitespace and zeros to be removed */
- var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
-
- /** Used to ensure capturing order of template delimiters */
- var reNoMatch = /($^)/;
-
- /** Used to detect functions containing a `this` reference */
- var reThis = /\bthis\b/;
-
- /** Used to match unescaped characters in compiled string literals */
- var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
-
- /** Used to assign default `context` object properties */
- var contextProps = [
- 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
- 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite',
'isNaN',
- 'parseInt', 'setTimeout'
- ];
-
- /** Used to make template sourceURLs easier to identify */
- var templateCounter = 0;
-
- /** `Object#toString` result shortcuts */
- var argsClass = '[object Arguments]',
- arrayClass = '[object Array]',
- boolClass = '[object Boolean]',
- dateClass = '[object Date]',
- funcClass = '[object Function]',
- numberClass = '[object Number]',
- objectClass = '[object Object]',
- regexpClass = '[object RegExp]',
- stringClass = '[object String]';
-
- /** Used to identify object classifications that `_.clone` supports */
- var cloneableClasses = {};
- cloneableClasses[funcClass] = false;
- cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
- cloneableClasses[boolClass] = cloneableClasses[dateClass] =
- cloneableClasses[numberClass] = cloneableClasses[objectClass] =
- cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
-
- /** Used as an internal `_.debounce` options object */
- var debounceOptions = {
- 'leading': false,
- 'maxWait': 0,
- 'trailing': false
- };
-
- /** Used as the property descriptor for `__bindData__` */
- var descriptor = {
- 'configurable': false,
- 'enumerable': false,
- 'value': null,
- 'writable': false
- };
-
- /** Used to determine if values are of the language type Object */
- var objectTypes = {
- 'boolean': false,
- 'function': true,
- 'object': true,
- 'number': false,
- 'string': false,
- 'undefined': false
- };
-
- /** Used to escape characters for inclusion in compiled string literals */
- var stringEscapes = {
- '\\': '\\',
- "'": "'",
- '\n': 'n',
- '\r': 'r',
- '\t': 't',
- '\u2028': 'u2028',
- '\u2029': 'u2029'
- };
-
- /** Used as a reference to the global object */
- var root = (objectTypes[typeof window] && window) || this;
-
- /** Detect free variable `exports` */
- var freeExports = objectTypes[typeof exports] && exports &&
!exports.nodeType && exports;
-
- /** Detect free variable `module` */
- var freeModule = objectTypes[typeof module] && module && !module.nodeType &&
module;
-
- /** Detect the popular CommonJS extension `module.exports` */
- var moduleExports = freeModule && freeModule.exports === freeExports &&
freeExports;
-
- /** Detect free variable `global` from Node.js or Browserified code and use
it as `root` */
- var freeGlobal = objectTypes[typeof global] && global;
- if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window ===
freeGlobal)) {
- root = freeGlobal;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.indexOf` without support for binary searches
- * or `fromIndex` constraints.
- *
- * @private
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- */
- function baseIndexOf(array, value, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0;
-
- while (++index < length) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * An implementation of `_.contains` for cache objects that mimics the return
- * signature of `_.indexOf` by returning `0` if the value is found, else
`-1`.
- *
- * @private
- * @param {Object} cache The cache object to inspect.
- * @param {*} value The value to search for.
- * @returns {number} Returns `0` if `value` is found, else `-1`.
- */
- function cacheIndexOf(cache, value) {
- var type = typeof value;
- cache = cache.cache;
-
- if (type == 'boolean' || value == null) {
- return cache[value] ? 0 : -1;
- }
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value;
- cache = (cache = cache[type]) && cache[key];
-
- return type == 'object'
- ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
- : (cache ? 0 : -1);
- }
-
- /**
- * Adds a given value to the corresponding cache object.
- *
- * @private
- * @param {*} value The value to add to the cache.
- */
- function cachePush(value) {
- var cache = this.cache,
- type = typeof value;
-
- if (type == 'boolean' || value == null) {
- cache[value] = true;
- } else {
- if (type != 'number' && type != 'string') {
- type = 'object';
- }
- var key = type == 'number' ? value : keyPrefix + value,
- typeCache = cache[type] || (cache[type] = {});
-
- if (type == 'object') {
- (typeCache[key] || (typeCache[key] = [])).push(value);
- } else {
- typeCache[key] = true;
- }
- }
- }
-
- /**
- * Used by `_.max` and `_.min` as the default callback when a given
- * collection is a string value.
- *
- * @private
- * @param {string} value The character to inspect.
- * @returns {number} Returns the code unit of given character.
- */
- function charAtCallback(value) {
- return value.charCodeAt(0);
- }
-
- /**
- * Used by `sortBy` to compare transformed `collection` elements, stable
sorting
- * them in ascending order.
- *
- * @private
- * @param {Object} a The object to compare to `b`.
- * @param {Object} b The object to compare to `a`.
- * @returns {number} Returns the sort order indicator of `1` or `-1`.
- */
- function compareAscending(a, b) {
- var ac = a.criteria,
- bc = b.criteria,
- index = -1,
- length = ac.length;
-
- while (++index < length) {
- var value = ac[index],
- other = bc[index];
-
- if (value !== other) {
- if (value > other || typeof value == 'undefined') {
- return 1;
- }
- if (value < other || typeof other == 'undefined') {
- return -1;
- }
- }
- }
- // Fixes an `Array#sort` bug in the JS engine embedded in Adobe
applications
- // that causes it, under certain circumstances, to return the same value
for
- // `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
- //
- // This also ensures a stable sort in V8 and other engines.
- // See http://code.google.com/p/v8/issues/detail?id=90
- return a.index - b.index;
- }
-
- /**
- * Creates a cache object to optimize linear searches of large arrays.
- *
- * @private
- * @param {Array} [array=[]] The array to search.
- * @returns {null|Object} Returns the cache object or `null` if caching
should not be used.
- */
- function createCache(array) {
- var index = -1,
- length = array.length,
- first = array[0],
- mid = array[(length / 2) | 0],
- last = array[length - 1];
-
- if (first && typeof first == 'object' &&
- mid && typeof mid == 'object' && last && typeof last == 'object') {
- return false;
- }
- var cache = getObject();
- cache['false'] = cache['null'] = cache['true'] = cache['undefined'] =
false;
-
- var result = getObject();
- result.array = array;
- result.cache = cache;
- result.push = cachePush;
-
- while (++index < length) {
- result.push(array[index]);
- }
- return result;
- }
-
- /**
- * Used by `template` to escape characters for inclusion in compiled
- * string literals.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeStringChar(match) {
- return '\\' + stringEscapes[match];
- }
-
- /**
- * Gets an array from the array pool or creates a new one if the pool is
empty.
- *
- * @private
- * @returns {Array} The array from the pool.
- */
- function getArray() {
- return arrayPool.pop() || [];
- }
-
- /**
- * Gets an object from the object pool or creates a new one if the pool is
empty.
- *
- * @private
- * @returns {Object} The object from the pool.
- */
- function getObject() {
- return objectPool.pop() || {
- 'array': null,
- 'cache': null,
- 'criteria': null,
- 'false': false,
- 'index': 0,
- 'null': false,
- 'number': null,
- 'object': null,
- 'push': null,
- 'string': null,
- 'true': false,
- 'undefined': false,
- 'value': null
- };
- }
-
- /**
- * Releases the given array back to the array pool.
- *
- * @private
- * @param {Array} [array] The array to release.
- */
- function releaseArray(array) {
- array.length = 0;
- if (arrayPool.length < maxPoolSize) {
- arrayPool.push(array);
- }
- }
-
- /**
- * Releases the given object back to the object pool.
- *
- * @private
- * @param {Object} [object] The object to release.
- */
- function releaseObject(object) {
- var cache = object.cache;
- if (cache) {
- releaseObject(cache);
- }
- object.array = object.cache = object.criteria = object.object =
object.number = object.string = object.value = null;
- if (objectPool.length < maxPoolSize) {
- objectPool.push(object);
- }
- }
-
- /**
- * Slices the `collection` from the `start` index up to, but not including,
- * the `end` index.
- *
- * Note: This function is used instead of `Array#slice` to support node lists
- * in IE < 9 and to ensure dense arrays are returned.
- *
- * @private
- * @param {Array|Object|string} collection The collection to slice.
- * @param {number} start The start index.
- * @param {number} end The end index.
- * @returns {Array} Returns the new array.
- */
- function slice(array, start, end) {
- start || (start = 0);
- if (typeof end == 'undefined') {
- end = array ? array.length : 0;
- }
- var index = -1,
- length = end - start || 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = array[start + index];
- }
- return result;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Create a new `lodash` function using the given context object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} [context=root] The context object.
- * @returns {Function} Returns the `lodash` function.
- */
- function runInContext(context) {
- // Avoid issues with some ES3 environments that attempt to use values,
named
- // after built-in constructors like `Object`, for the creation of literals.
- // ES5 clears this up by stating that literals must use built-in
constructors.
- // See http://es5.github.io/#x11.1.5.
- context = context ? _.defaults(root.Object(), context, _.pick(root,
contextProps)) : root;
-
- /** Native constructor references */
- var Array = context.Array,
- Boolean = context.Boolean,
- Date = context.Date,
- Function = context.Function,
- Math = context.Math,
- Number = context.Number,
- Object = context.Object,
- RegExp = context.RegExp,
- String = context.String,
- TypeError = context.TypeError;
-
- /**
- * Used for `Array` method references.
- *
- * Normally `Array.prototype` would suffice, however, using an array
literal
- * avoids issues in Narwhal.
- */
- var arrayRef = [];
-
- /** Used for native method references */
- var objectProto = Object.prototype;
-
- /** Used to restore the original `_` reference in `noConflict` */
- var oldDash = context._;
-
- /** Used to resolve the internal [[Class]] of values */
- var toString = objectProto.toString;
-
- /** Used to detect if a method is native */
- var reNative = RegExp('^' +
- String(toString)
- .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
- .replace(/toString| for [^\]]+/g, '.*?') + '$'
- );
-
- /** Native method shortcuts */
- var ceil = Math.ceil,
- clearTimeout = context.clearTimeout,
- floor = Math.floor,
- fnToString = Function.prototype.toString,
- getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) &&
getPrototypeOf,
- hasOwnProperty = objectProto.hasOwnProperty,
- push = arrayRef.push,
- setTimeout = context.setTimeout,
- splice = arrayRef.splice,
- unshift = arrayRef.unshift;
-
- /** Used to set meta data on functions */
- var defineProperty = (function() {
- // IE 8 only accepts DOM elements
- try {
- var o = {},
- func = isNative(func = Object.defineProperty) && func,
- result = func(o, o, o) && func;
- } catch(e) { }
- return result;
- }());
-
- /* Native method shortcuts for methods with the same name as other
`lodash` methods */
- var nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
- nativeIsArray = isNative(nativeIsArray = Array.isArray) &&
nativeIsArray,
- nativeIsFinite = context.isFinite,
- nativeIsNaN = context.isNaN,
- nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
- nativeMax = Math.max,
- nativeMin = Math.min,
- nativeParseInt = context.parseInt,
- nativeRandom = Math.random;
-
- /** Used to lookup a built-in constructor by [[Class]] */
- var ctorByClass = {};
- ctorByClass[arrayClass] = Array;
- ctorByClass[boolClass] = Boolean;
- ctorByClass[dateClass] = Date;
- ctorByClass[funcClass] = Function;
- ctorByClass[objectClass] = Object;
- ctorByClass[numberClass] = Number;
- ctorByClass[regexpClass] = RegExp;
- ctorByClass[stringClass] = String;
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates a `lodash` object which wraps the given value to enable
intuitive
- * method chaining.
- *
- * In addition to Lo-Dash methods, wrappers also have the following
`Array` methods:
- * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`,
`splice`,
- * and `unshift`
- *
- * Chaining is supported in custom builds as long as the `value` method is
- * implicitly or explicitly included in the build.
- *
- * The chainable wrapper functions are:
- * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
- * `compose`, `concat`, `countBy`, `create`, `createCallback`, `curry`,
- * `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`,
`flatten`,
- * `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
`forOwnRight`,
- * `functions`, `groupBy`, `indexBy`, `initial`, `intersection`, `invert`,
- * `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`,
`omit`,
- * `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `pull`,
`push`,
- * `range`, `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`,
`sort`,
- * `sortBy`, `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`,
- * `union`, `uniq`, `unshift`, `unzip`, `values`, `where`, `without`,
`wrap`,
- * and `zip`
- *
- * The non-chainable wrapper functions are:
- * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`,
`findIndex`,
- * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`,
`identity`,
- * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
- * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`,
`isNumber`,
- * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
`join`,
- * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`,
`reduce`,
- * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`,
`runInContext`,
- * `template`, `unescape`, `uniqueId`, and `value`
- *
- * The wrapper functions `first` and `last` return wrapped values when `n`
is
- * provided, otherwise they return unwrapped values.
- *
- * Explicit chaining can be enabled by using the `_.chain` method.
- *
- * @name _
- * @constructor
- * @category Chaining
- * @param {*} value The value to wrap in a `lodash` instance.
- * @returns {Object} Returns a `lodash` instance.
- * @example
- *
- * var wrapped = _([1, 2, 3]);
- *
- * // returns an unwrapped value
- * wrapped.reduce(function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * // returns a wrapped value
- * var squares = wrapped.map(function(num) {
- * return num * num;
- * });
- *
- * _.isArray(squares);
- * // => false
- *
- * _.isArray(squares.value());
- * // => true
- */
- function lodash(value) {
- // don't wrap if already wrapped, even if wrapped by a different
`lodash` constructor
- return (value && typeof value == 'object' && !isArray(value) &&
hasOwnProperty.call(value, '__wrapped__'))
- ? value
- : new lodashWrapper(value);
- }
-
- /**
- * A fast path for creating `lodash` wrapper objects.
- *
- * @private
- * @param {*} value The value to wrap in a `lodash` instance.
- * @param {boolean} chainAll A flag to enable chaining for all methods
- * @returns {Object} Returns a `lodash` instance.
- */
- function lodashWrapper(value, chainAll) {
- this.__chain__ = !!chainAll;
- this.__wrapped__ = value;
- }
- // ensure `new lodashWrapper` is an instance of `lodash`
- lodashWrapper.prototype = lodash.prototype;
-
- /**
- * An object used to flag environments features.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- var support = lodash.support = {};
-
- /**
- * Detect if functions can be decompiled by `Function#toString`
- * (all but PS3 and older Opera mobile browsers & avoided in Windows 8
apps).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcDecomp = !isNative(context.WinRTError) &&
reThis.test(runInContext);
-
- /**
- * Detect if `Function#name` is supported (all but IE).
- *
- * @memberOf _.support
- * @type boolean
- */
- support.funcNames = typeof Function.name == 'string';
-
- /**
- * By default, the template delimiters used by Lo-Dash are similar to
those in
- * embedded Ruby (ERB). Change the following template settings to use
alternative
- * delimiters.
- *
- * @static
- * @memberOf _
- * @type Object
- */
- lodash.templateSettings = {
-
- /**
- * Used to detect `data` property values to be HTML-escaped.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'escape': /<%-([\s\S]+?)%>/g,
-
- /**
- * Used to detect code to be evaluated.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'evaluate': /<%([\s\S]+?)%>/g,
-
- /**
- * Used to detect `data` property values to inject.
- *
- * @memberOf _.templateSettings
- * @type RegExp
- */
- 'interpolate': reInterpolate,
-
- /**
- * Used to reference the data object in the template text.
- *
- * @memberOf _.templateSettings
- * @type string
- */
- 'variable': '',
-
- /**
- * Used to import variables into the compiled template.
- *
- * @memberOf _.templateSettings
- * @type Object
- */
- 'imports': {
-
- /**
- * A reference to the `lodash` function.
- *
- * @memberOf _.templateSettings.imports
- * @type Function
- */
- '_': lodash
- }
- };
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * The base implementation of `_.bind` that creates the bound function and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new bound function.
- */
- function baseBind(bindData) {
- var func = bindData[0],
- partialArgs = bindData[2],
- thisArg = bindData[4];
-
- function bound() {
- // `Function#bind` spec
- // http://es5.github.io/#x15.3.4.5
- if (partialArgs) {
- // avoid `arguments` object deoptimizations by using `slice` instead
- // of `Array.prototype.slice.call` and not assigning `arguments` to a
- // variable as a ternary expression
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- // mimic the constructor's `return` behavior
- // http://es5.github.io/#x13.2.2
- if (this instanceof bound) {
- // ensure `new bound` is an instance of `func`
- var thisBinding = baseCreate(func.prototype),
- result = func.apply(thisBinding, args || arguments);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisArg, args || arguments);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.clone` without argument juggling or
support
- * for `thisArg` binding.
- *
- * @private
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates clones with source counterparts.
- * @returns {*} Returns the cloned value.
- */
- function baseClone(value, isDeep, callback, stackA, stackB) {
- if (callback) {
- var result = callback(value);
- if (typeof result != 'undefined') {
- return result;
- }
- }
- // inspect [[Class]]
- var isObj = isObject(value);
- if (isObj) {
- var className = toString.call(value);
- if (!cloneableClasses[className]) {
- return value;
- }
- var ctor = ctorByClass[className];
- switch (className) {
- case boolClass:
- case dateClass:
- return new ctor(+value);
-
- case numberClass:
- case stringClass:
- return new ctor(value);
-
- case regexpClass:
- result = ctor(value.source, reFlags.exec(value));
- result.lastIndex = value.lastIndex;
- return result;
- }
- } else {
- return value;
- }
- var isArr = isArray(value);
- if (isDeep) {
- // check for circular references and return corresponding clone
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == value) {
- return stackB[length];
- }
- }
- result = isArr ? ctor(value.length) : {};
- }
- else {
- result = isArr ? slice(value) : assign({}, value);
- }
- // add array properties assigned by `RegExp#exec`
- if (isArr) {
- if (hasOwnProperty.call(value, 'index')) {
- result.index = value.index;
- }
- if (hasOwnProperty.call(value, 'input')) {
- result.input = value.input;
- }
- }
- // exit for shallow clone
- if (!isDeep) {
- return result;
- }
- // add the source value to the stack of traversed objects
- // and associate it with its clone
- stackA.push(value);
- stackB.push(result);
-
- // recursively populate clone (susceptible to call stack limits)
- (isArr ? forEach : forOwn)(value, function(objValue, key) {
- result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
- });
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.create` without support for assigning
- * properties to the created object.
- *
- * @private
- * @param {Object} prototype The object to inherit from.
- * @returns {Object} Returns the new object.
- */
- function baseCreate(prototype, properties) {
- return isObject(prototype) ? nativeCreate(prototype) : {};
- }
- // fallback for browsers without `Object.create`
- if (!nativeCreate) {
- baseCreate = (function() {
- function Object() {}
- return function(prototype) {
- if (isObject(prototype)) {
- Object.prototype = prototype;
- var result = new Object;
- Object.prototype = null;
- }
- return result || context.Object();
- };
- }());
- }
-
- /**
- * The base implementation of `_.createCallback` without support for
creating
- * "_.pluck" or "_.where" style callbacks.
- *
- * @private
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- */
- function baseCreateCallback(func, thisArg, argCount) {
- if (typeof func != 'function') {
- return identity;
- }
- // exit early for no `thisArg` or already bound by `Function#bind`
- if (typeof thisArg == 'undefined' || !('prototype' in func)) {
- return func;
- }
- var bindData = func.__bindData__;
- if (typeof bindData == 'undefined') {
- if (support.funcNames) {
- bindData = !func.name;
- }
- bindData = bindData || !support.funcDecomp;
- if (!bindData) {
- var source = fnToString.call(func);
- if (!support.funcNames) {
- bindData = !reFuncName.test(source);
- }
- if (!bindData) {
- // checks if `func` references the `this` keyword and stores the
result
- bindData = reThis.test(source);
- setBindData(func, bindData);
- }
- }
- }
- // exit early if there are no `this` references or `func` is bound
- if (bindData === false || (bindData !== true && bindData[1] & 1)) {
- return func;
- }
- switch (argCount) {
- case 1: return function(value) {
- return func.call(thisArg, value);
- };
- case 2: return function(a, b) {
- return func.call(thisArg, a, b);
- };
- case 3: return function(value, index, collection) {
- return func.call(thisArg, value, index, collection);
- };
- case 4: return function(accumulator, value, index, collection) {
- return func.call(thisArg, accumulator, value, index, collection);
- };
- }
- return bind(func, thisArg);
- }
-
- /**
- * The base implementation of `createWrapper` that creates the wrapper and
- * sets its meta data.
- *
- * @private
- * @param {Array} bindData The bind data array.
- * @returns {Function} Returns the new function.
- */
- function baseCreateWrapper(bindData) {
- var func = bindData[0],
- bitmask = bindData[1],
- partialArgs = bindData[2],
- partialRightArgs = bindData[3],
- thisArg = bindData[4],
- arity = bindData[5];
-
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- key = func;
-
- function bound() {
- var thisBinding = isBind ? thisArg : this;
- if (partialArgs) {
- var args = slice(partialArgs);
- push.apply(args, arguments);
- }
- if (partialRightArgs || isCurry) {
- args || (args = slice(arguments));
- if (partialRightArgs) {
- push.apply(args, partialRightArgs);
- }
- if (isCurry && args.length < arity) {
- bitmask |= 16 & ~32;
- return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask
& ~3), args, null, thisArg, arity]);
- }
- }
- args || (args = arguments);
- if (isBindKey) {
- func = thisBinding[key];
- }
- if (this instanceof bound) {
- thisBinding = baseCreate(func.prototype);
- var result = func.apply(thisBinding, args);
- return isObject(result) ? result : thisBinding;
- }
- return func.apply(thisBinding, args);
- }
- setBindData(bound, bindData);
- return bound;
- }
-
- /**
- * The base implementation of `_.difference` that accepts a single array
- * of values to exclude.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {Array} [values] The array of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- */
- function baseDifference(array, values) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- isLarge = length >= largeArraySize && indexOf === baseIndexOf,
- result = [];
-
- if (isLarge) {
- var cache = createCache(values);
- if (cache) {
- indexOf = cacheIndexOf;
- values = cache;
- } else {
- isLarge = false;
- }
- }
- while (++index < length) {
- var value = array[index];
- if (indexOf(values, value) < 0) {
- result.push(value);
- }
- }
- if (isLarge) {
- releaseObject(values);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.flatten` without support for callback
- * shorthands or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a
single level.
- * @param {boolean} [isStrict=false] A flag to restrict flattening to
arrays and `arguments` objects.
- * @param {number} [fromIndex=0] The index to start from.
- * @returns {Array} Returns a new flattened array.
- */
- function baseFlatten(array, isShallow, isStrict, fromIndex) {
- var index = (fromIndex || 0) - 1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
-
- if (value && typeof value == 'object' && typeof value.length ==
'number'
- && (isArray(value) || isArguments(value))) {
- // recursively flatten arrays (susceptible to call stack limits)
- if (!isShallow) {
- value = baseFlatten(value, isShallow, isStrict);
- }
- var valIndex = -1,
- valLength = value.length,
- resIndex = result.length;
-
- result.length += valLength;
- while (++valIndex < valLength) {
- result[resIndex++] = value[valIndex];
- }
- } else if (!isStrict) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * The base implementation of `_.isEqual`, without support for `thisArg`
binding,
- * that allows partial "_.where" style comparisons.
- *
- * @private
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {Function} [isWhere=false] A flag to indicate performing partial
comparisons.
- * @param {Array} [stackA=[]] Tracks traversed `a` objects.
- * @param {Array} [stackB=[]] Tracks traversed `b` objects.
- * @returns {boolean} Returns `true` if the values are equivalent, else
`false`.
- */
- function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
- // used to indicate that when comparing objects, `a` has at least the
properties of `b`
- if (callback) {
- var result = callback(a, b);
- if (typeof result != 'undefined') {
- return !!result;
- }
- }
- // exit early for identical values
- if (a === b) {
- // treat `+0` vs. `-0` as not equal
- return a !== 0 || (1 / a == 1 / b);
- }
- var type = typeof a,
- otherType = typeof b;
-
- // exit early for unlike primitive values
- if (a === a &&
- !(a && objectTypes[type]) &&
- !(b && objectTypes[otherType])) {
- return false;
- }
- // exit early for `null` and `undefined` avoiding ES3's Function#call
behavior
- // http://es5.github.io/#x15.3.4.4
- if (a == null || b == null) {
- return a === b;
- }
- // compare [[Class]] names
- var className = toString.call(a),
- otherClass = toString.call(b);
-
- if (className == argsClass) {
- className = objectClass;
- }
- if (otherClass == argsClass) {
- otherClass = objectClass;
- }
- if (className != otherClass) {
- return false;
- }
- switch (className) {
- case boolClass:
- case dateClass:
- // coerce dates and booleans to numbers, dates to milliseconds and
booleans
- // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
- return +a == +b;
-
- case numberClass:
- // treat `NaN` vs. `NaN` as equal
- return (a != +a)
- ? b != +b
- // but treat `+0` vs. `-0` as not equal
- : (a == 0 ? (1 / a == 1 / b) : a == +b);
-
- case regexpClass:
- case stringClass:
- // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
- // treat string primitives and their corresponding object instances
as equal
- return a == String(b);
- }
- var isArr = className == arrayClass;
- if (!isArr) {
- // unwrap any `lodash` wrapped values
- var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
- bWrapped = hasOwnProperty.call(b, '__wrapped__');
-
- if (aWrapped || bWrapped) {
- return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ?
b.__wrapped__ : b, callback, isWhere, stackA, stackB);
- }
- // exit for functions and DOM nodes
- if (className != objectClass) {
- return false;
- }
- // in older versions of Opera, `arguments` objects have `Array`
constructors
- var ctorA = a.constructor,
- ctorB = b.constructor;
-
- // non `Object` object instances with different constructors are not
equal
- if (ctorA != ctorB &&
- !(isFunction(ctorA) && ctorA instanceof ctorA &&
isFunction(ctorB) && ctorB instanceof ctorB) &&
- ('constructor' in a && 'constructor' in b)
- ) {
- return false;
- }
- }
- // assume cyclic structures are equal
- // the algorithm for detecting cyclic structures is adapted from ES 5.1
- // section 15.12.3, abstract operation `JO`
(http://es5.github.io/#x15.12.3)
- var initedStack = !stackA;
- stackA || (stackA = getArray());
- stackB || (stackB = getArray());
-
- var length = stackA.length;
- while (length--) {
- if (stackA[length] == a) {
- return stackB[length] == b;
- }
- }
- var size = 0;
- result = true;
-
- // add `a` and `b` to the stack of traversed objects
- stackA.push(a);
- stackB.push(b);
-
- // recursively compare objects and arrays (susceptible to call stack
limits)
- if (isArr) {
- // compare lengths to determine if a deep comparison is necessary
- length = a.length;
- size = b.length;
- result = size == length;
-
- if (result || isWhere) {
- // deep compare the contents, ignoring non-numeric properties
- while (size--) {
- var index = length,
- value = b[size];
-
- if (isWhere) {
- while (index--) {
- if ((result = baseIsEqual(a[index], value, callback, isWhere,
stackA, stackB))) {
- break;
- }
- }
- } else if (!(result = baseIsEqual(a[size], value, callback,
isWhere, stackA, stackB))) {
- break;
- }
- }
- }
- }
- else {
- // deep compare objects using `forIn`, instead of `forOwn`, to avoid
`Object.keys`
- // which, in this case, is more costly
- forIn(b, function(value, key, b) {
- if (hasOwnProperty.call(b, key)) {
- // count the number of properties.
- size++;
- // deep compare each property value.
- return (result = hasOwnProperty.call(a, key) &&
baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
- }
- });
-
- if (result && !isWhere) {
- // ensure both objects have the same number of properties
- forIn(a, function(value, key, a) {
- if (hasOwnProperty.call(a, key)) {
- // `size` will be `-1` if `a` has more properties than `b`
- return (result = --size > -1);
- }
- });
- }
- }
- stackA.pop();
- stackB.pop();
-
- if (initedStack) {
- releaseArray(stackA);
- releaseArray(stackB);
- }
- return result;
- }
-
- /**
- * The base implementation of `_.merge` without argument juggling or
support
- * for `thisArg` binding.
- *
- * @private
- * @param {Object} object The destination object.
- * @param {Object} source The source object.
- * @param {Function} [callback] The function to customize merging
properties.
- * @param {Array} [stackA=[]] Tracks traversed source objects.
- * @param {Array} [stackB=[]] Associates values with source counterparts.
- */
- function baseMerge(object, source, callback, stackA, stackB) {
- (isArray(source) ? forEach : forOwn)(source, function(source, key) {
- var found,
- isArr,
- result = source,
- value = object[key];
-
- if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
- // avoid merging previously merged cyclic sources
- var stackLength = stackA.length;
- while (stackLength--) {
- if ((found = stackA[stackLength] == source)) {
- value = stackB[stackLength];
- break;
- }
- }
- if (!found) {
- var isShallow;
- if (callback) {
- result = callback(value, source);
- if ((isShallow = typeof result != 'undefined')) {
- value = result;
- }
- }
- if (!isShallow) {
- value = isArr
- ? (isArray(value) ? value : [])
- : (isPlainObject(value) ? value : {});
- }
- // add `source` and associated `value` to the stack of traversed
objects
- stackA.push(source);
- stackB.push(value);
-
- // recursively merge objects and arrays (susceptible to call stack
limits)
- if (!isShallow) {
- baseMerge(value, source, callback, stackA, stackB);
- }
- }
- }
- else {
- if (callback) {
- result = callback(value, source);
- if (typeof result == 'undefined') {
- result = source;
- }
- }
- if (typeof result != 'undefined') {
- value = result;
- }
- }
- object[key] = value;
- });
- }
-
- /**
- * The base implementation of `_.random` without argument juggling or
support
- * for returning floating-point numbers.
- *
- * @private
- * @param {number} min The minimum possible value.
- * @param {number} max The maximum possible value.
- * @returns {number} Returns a random number.
- */
- function baseRandom(min, max) {
- return min + floor(nativeRandom() * (max - min + 1));
- }
-
- /**
- * The base implementation of `_.uniq` without support for callback
shorthands
- * or `thisArg` binding.
- *
- * @private
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is
sorted.
- * @param {Function} [callback] The function called per iteration.
- * @returns {Array} Returns a duplicate-value-free array.
- */
- function baseUniq(array, isSorted, callback) {
- var index = -1,
- indexOf = getIndexOf(),
- length = array ? array.length : 0,
- result = [];
-
- var isLarge = !isSorted && length >= largeArraySize && indexOf ===
baseIndexOf,
- seen = (callback || isLarge) ? getArray() : result;
-
- if (isLarge) {
- var cache = createCache(seen);
- indexOf = cacheIndexOf;
- seen = cache;
- }
- while (++index < length) {
- var value = array[index],
- computed = callback ? callback(value, index, array) : value;
-
- if (isSorted
- ? !index || seen[seen.length - 1] !== computed
- : indexOf(seen, computed) < 0
- ) {
- if (callback || isLarge) {
- seen.push(computed);
- }
- result.push(value);
- }
- }
- if (isLarge) {
- releaseArray(seen.array);
- releaseObject(seen);
- } else if (callback) {
- releaseArray(seen);
- }
- return result;
- }
-
- /**
- * Creates a function that aggregates a collection, creating an object
composed
- * of keys generated from the results of running each element of the
collection
- * through a callback. The given `setter` function sets the keys and values
- * of the composed object.
- *
- * @private
- * @param {Function} setter The setter function.
- * @returns {Function} Returns the new aggregator function.
- */
- function createAggregator(setter) {
- return function(collection, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- var index = -1,
- length = collection ? collection.length : 0;
-
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- setter(result, value, callback(value, index, collection),
collection);
- }
- } else {
- forOwn(collection, function(value, key, collection) {
- setter(result, value, callback(value, key, collection),
collection);
- });
- }
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, either curries or invokes `func`
- * with an optional `this` binding and partially applied arguments.
- *
- * @private
- * @param {Function|string} func The function or method name to reference.
- * @param {number} bitmask The bitmask of method flags to compose.
- * The bitmask may be composed of the following flags:
- * 1 - `_.bind`
- * 2 - `_.bindKey`
- * 4 - `_.curry`
- * 8 - `_.curry` (bound)
- * 16 - `_.partial`
- * 32 - `_.partialRight`
- * @param {Array} [partialArgs] An array of arguments to prepend to those
- * provided to the new function.
- * @param {Array} [partialRightArgs] An array of arguments to append to
those
- * provided to the new function.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {number} [arity] The arity of `func`.
- * @returns {Function} Returns the new function.
- */
- function createWrapper(func, bitmask, partialArgs, partialRightArgs,
thisArg, arity) {
- var isBind = bitmask & 1,
- isBindKey = bitmask & 2,
- isCurry = bitmask & 4,
- isCurryBound = bitmask & 8,
- isPartial = bitmask & 16,
- isPartialRight = bitmask & 32;
-
- if (!isBindKey && !isFunction(func)) {
- throw new TypeError;
- }
- if (isPartial && !partialArgs.length) {
- bitmask &= ~16;
- isPartial = partialArgs = false;
- }
- if (isPartialRight && !partialRightArgs.length) {
- bitmask &= ~32;
- isPartialRight = partialRightArgs = false;
- }
- var bindData = func && func.__bindData__;
- if (bindData && bindData !== true) {
- // clone `bindData`
- bindData = slice(bindData);
- if (bindData[2]) {
- bindData[2] = slice(bindData[2]);
- }
- if (bindData[3]) {
- bindData[3] = slice(bindData[3]);
- }
- // set `thisBinding` is not previously bound
- if (isBind && !(bindData[1] & 1)) {
- bindData[4] = thisArg;
- }
- // set if previously bound but not currently (subsequent curried
functions)
- if (!isBind && bindData[1] & 1) {
- bitmask |= 8;
- }
- // set curried arity if not yet set
- if (isCurry && !(bindData[1] & 4)) {
- bindData[5] = arity;
- }
- // append partial left arguments
- if (isPartial) {
- push.apply(bindData[2] || (bindData[2] = []), partialArgs);
- }
- // append partial right arguments
- if (isPartialRight) {
- unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
- }
- // merge flags
- bindData[1] |= bitmask;
- return createWrapper.apply(null, bindData);
- }
- // fast path for `_.bind`
- var creater = (bitmask == 1 || bitmask === 17) ? baseBind :
baseCreateWrapper;
- return creater([func, bitmask, partialArgs, partialRightArgs, thisArg,
arity]);
- }
-
- /**
- * Used by `escape` to convert characters to HTML entities.
- *
- * @private
- * @param {string} match The matched character to escape.
- * @returns {string} Returns the escaped character.
- */
- function escapeHtmlChar(match) {
- return htmlEscapes[match];
- }
-
- /**
- * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
- * customized, this method returns the custom method, otherwise it returns
- * the `baseIndexOf` function.
- *
- * @private
- * @returns {Function} Returns the "indexOf" function.
- */
- function getIndexOf() {
- var result = (result = lodash.indexOf) === indexOf ? baseIndexOf :
result;
- return result;
- }
-
- /**
- * Checks if `value` is a native function.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a native function,
else `false`.
- */
- function isNative(value) {
- return typeof value == 'function' && reNative.test(value);
- }
-
- /**
- * Sets `this` binding data on a given function.
- *
- * @private
- * @param {Function} func The function to set data on.
- * @param {Array} value The data array to set.
- */
- var setBindData = !defineProperty ? noop : function(func, value) {
- descriptor.value = value;
- defineProperty(func, '__bindData__', descriptor);
- };
-
- /**
- * A fallback implementation of `isPlainObject` which checks if a given
value
- * is an object created by the `Object` constructor, assuming objects
created
- * by the `Object` constructor have no inherited enumerable properties and
that
- * there are no `Object.prototype` extensions.
- *
- * @private
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else
`false`.
- */
- function shimIsPlainObject(value) {
- var ctor,
- result;
-
- // avoid non Object objects, `arguments` objects, and DOM elements
- if (!(value && toString.call(value) == objectClass) ||
- (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof
ctor))) {
- return false;
- }
- // In most environments an object's own properties are iterated before
- // its inherited properties. If the last iterated property is an object's
- // own property then there are no inherited enumerable properties.
- forIn(value, function(value, key) {
- result = key;
- });
- return typeof result == 'undefined' || hasOwnProperty.call(value,
result);
- }
-
- /**
- * Used by `unescape` to convert HTML entities to characters.
- *
- * @private
- * @param {string} match The matched character to unescape.
- * @returns {string} Returns the unescaped character.
- */
- function unescapeHtmlChar(match) {
- return htmlUnescapes[match];
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Checks if `value` is an `arguments` object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an `arguments`
object, else `false`.
- * @example
- *
- * (function() { return _.isArguments(arguments); })(1, 2, 3);
- * // => true
- *
- * _.isArguments([1, 2, 3]);
- * // => false
- */
- function isArguments(value) {
- return value && typeof value == 'object' && typeof value.length ==
'number' &&
- toString.call(value) == argsClass || false;
- }
-
- /**
- * Checks if `value` is an array.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an array, else
`false`.
- * @example
- *
- * (function() { return _.isArray(arguments); })();
- * // => false
- *
- * _.isArray([1, 2, 3]);
- * // => true
- */
- var isArray = nativeIsArray || function(value) {
- return value && typeof value == 'object' && typeof value.length ==
'number' &&
- toString.call(value) == arrayClass || false;
- };
-
- /**
- * A fallback implementation of `Object.keys` which produces an array of
the
- * given object's own enumerable property names.
- *
- * @private
- * @type Function
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- */
- var shimKeys = function(object) {
- var index, iterable = object, result = [];
- if (!iterable) return result;
- if (!(objectTypes[typeof object])) return result;
- for (index in iterable) {
- if (hasOwnProperty.call(iterable, index)) {
- result.push(index);
- }
- }
- return result
- };
-
- /**
- * Creates an array composed of the own enumerable property names of an
object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names.
- * @example
- *
- * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
- * // => ['one', 'two', 'three'] (property order is not guaranteed across
environments)
- */
- var keys = !nativeKeys ? shimKeys : function(object) {
- if (!isObject(object)) {
- return [];
- }
- return nativeKeys(object);
- };
-
- /**
- * Used to convert characters to HTML entities:
- *
- * Though the `>` character is escaped for symmetry, characters like `>`
and `/`
- * don't require escaping in HTML and have no special meaning unless
they're part
- * of a tag or an unquoted attribute value.
- * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related
fun fact")
- */
- var htmlEscapes = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": '''
- };
-
- /** Used to convert HTML entities to characters */
- var htmlUnescapes = invert(htmlEscapes);
-
- /** Used to match HTML entities and HTML characters */
- var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
- reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object. Subsequent sources will overwrite property assignments of
previous
- * sources. If a callback is provided it will be executed to produce the
- * assigned values. The callback is bound to `thisArg` and invoked with two
- * arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @type Function
- * @alias extend
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize assigning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
- * // => { 'name': 'fred', 'employer': 'slate' }
- *
- * var defaults = _.partialRight(_.assign, function(a, b) {
- * return typeof a == 'undefined' ? b : a;
- * });
- *
- * var object = { 'name': 'barney' };
- * defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var assign = function(object, source, guard) {
- var index, iterable = object, result = iterable;
- if (!iterable) return result;
- var args = arguments,
- argsIndex = 0,
- argsLength = typeof guard == 'number' ? 2 : args.length;
- if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
- var callback = baseCreateCallback(args[--argsLength - 1],
args[argsLength--], 2);
- } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
- callback = args[--argsLength];
- }
- while (++argsIndex < argsLength) {
- iterable = args[argsIndex];
- if (iterable && objectTypes[typeof iterable]) {
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
-
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- result[index] = callback ? callback(result[index], iterable[index])
: iterable[index];
- }
- }
- }
- return result
- };
-
- /**
- * Creates a clone of `value`. If `isDeep` is `true` nested objects will
also
- * be cloned, otherwise they will be assigned by reference. If a callback
- * is provided it will be executed to produce the cloned values. If the
- * callback returns `undefined` cloning will be handled by the method
instead.
- * The callback is bound to `thisArg` and invoked with one argument;
(value).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to clone.
- * @param {boolean} [isDeep=false] Specify a deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var shallow = _.clone(characters);
- * shallow[0] === characters[0];
- * // => true
- *
- * var deep = _.clone(characters, true);
- * deep[0] === characters[0];
- * // => false
- *
- * _.mixin({
- * 'clone': _.partialRight(_.clone, function(value) {
- * return _.isElement(value) ? value.cloneNode(false) : undefined;
- * })
- * });
- *
- * var clone = _.clone(document.body);
- * clone.childNodes.length;
- * // => 0
- */
- function clone(value, isDeep, callback, thisArg) {
- // allows working with "Collections" methods without using their `index`
- // and `collection` arguments for `isDeep` and `callback`
- if (typeof isDeep != 'boolean' && isDeep != null) {
- thisArg = callback;
- callback = isDeep;
- isDeep = false;
- }
- return baseClone(value, isDeep, typeof callback == 'function' &&
baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates a deep clone of `value`. If a callback is provided it will be
- * executed to produce the cloned values. If the callback returns
`undefined`
- * cloning will be handled by the method instead. The callback is bound to
- * `thisArg` and invoked with one argument; (value).
- *
- * Note: This method is loosely based on the structured clone algorithm.
Functions
- * and DOM nodes are **not** cloned. The enumerable properties of
`arguments` objects and
- * objects created by constructors other than `Object` are cloned to plain
`Object` objects.
- * See
http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to deep clone.
- * @param {Function} [callback] The function to customize cloning values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the deep cloned value.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * var deep = _.cloneDeep(characters);
- * deep[0] === characters[0];
- * // => false
- *
- * var view = {
- * 'label': 'docs',
- * 'node': element
- * };
- *
- * var clone = _.cloneDeep(view, function(value) {
- * return _.isElement(value) ? value.cloneNode(true) : undefined;
- * });
- *
- * clone.node == view.node;
- * // => false
- */
- function cloneDeep(value, callback, thisArg) {
- return baseClone(value, true, typeof callback == 'function' &&
baseCreateCallback(callback, thisArg, 1));
- }
-
- /**
- * Creates an object that inherits from the given `prototype` object. If a
- * `properties` object is provided its own enumerable properties are
assigned
- * to the created object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} prototype The object to inherit from.
- * @param {Object} [properties] The properties to assign to the object.
- * @returns {Object} Returns the new object.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * function Circle() {
- * Shape.call(this);
- * }
- *
- * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
- *
- * var circle = new Circle;
- * circle instanceof Circle;
- * // => true
- *
- * circle instanceof Shape;
- * // => true
- */
- function create(prototype, properties) {
- var result = baseCreate(prototype);
- return properties ? assign(result, properties) : result;
- }
-
- /**
- * Assigns own enumerable properties of source object(s) to the destination
- * object for all destination properties that resolve to `undefined`. Once
a
- * property is set, additional defaults of the same property will be
ignored.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param- {Object} [guard] Allows working with `_.reduce` without using
its
- * `key` and `object` arguments as sources.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var object = { 'name': 'barney' };
- * _.defaults(object, { 'name': 'fred', 'employer': 'slate' });
- * // => { 'name': 'barney', 'employer': 'slate' }
- */
- var defaults = function(object, source, guard) {
- var index, iterable = object, result = iterable;
- if (!iterable) return result;
- var args = arguments,
- argsIndex = 0,
- argsLength = typeof guard == 'number' ? 2 : args.length;
- while (++argsIndex < argsLength) {
- iterable = args[argsIndex];
- if (iterable && objectTypes[typeof iterable]) {
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
-
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- if (typeof result[index] == 'undefined') result[index] =
iterable[index];
- }
- }
- }
- return result
- };
-
- /**
- * This method is like `_.findIndex` except that it returns the key of the
- * first element that passes the callback check, instead of the element
itself.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called
per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else
`undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': false },
- * 'fred': { 'age': 40, 'blocked': true },
- * 'pebbles': { 'age': 1, 'blocked': false }
- * };
- *
- * _.findKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => 'barney' (property order is not guaranteed across environments)
- *
- * // using "_.where" callback shorthand
- * _.findKey(characters, { 'age': 1 });
- * // => 'pebbles'
- *
- * // using "_.pluck" callback shorthand
- * _.findKey(characters, 'blocked');
- * // => 'fred'
- */
- function findKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * This method is like `_.findKey` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to search.
- * @param {Function|Object|string} [callback=identity] The function called
per
- * iteration. If a property name or object is provided it will be used to
- * create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {string|undefined} Returns the key of the found element, else
`undefined`.
- * @example
- *
- * var characters = {
- * 'barney': { 'age': 36, 'blocked': true },
- * 'fred': { 'age': 40, 'blocked': false },
- * 'pebbles': { 'age': 1, 'blocked': true }
- * };
- *
- * _.findLastKey(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => returns `pebbles`, assuming `_.findKey` returns `barney`
- *
- * // using "_.where" callback shorthand
- * _.findLastKey(characters, { 'age': 40 });
- * // => 'fred'
- *
- * // using "_.pluck" callback shorthand
- * _.findLastKey(characters, 'blocked');
- * // => 'pebbles'
- */
- function findLastKey(object, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forOwnRight(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result = key;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over own and inherited enumerable properties of an object,
- * executing the callback for each property. The callback is bound to
`thisArg`
- * and invoked with three arguments; (value, key, object). Callbacks may
exit
- * iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forIn(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'x', 'y', and 'move' (property order is not guaranteed
across environments)
- */
- var forIn = function(collection, callback, thisArg) {
- var index, iterable = collection, result = iterable;
- if (!iterable) return result;
- if (!objectTypes[typeof iterable]) return result;
- callback = callback && typeof thisArg == 'undefined' ? callback :
baseCreateCallback(callback, thisArg, 3);
- for (index in iterable) {
- if (callback(iterable[index], index, collection) === false) return
result;
- }
- return result
- };
-
- /**
- * This method is like `_.forIn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * Shape.prototype.move = function(x, y) {
- * this.x += x;
- * this.y += y;
- * };
- *
- * _.forInRight(new Shape, function(value, key) {
- * console.log(key);
- * });
- * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and
'move'
- */
- function forInRight(object, callback, thisArg) {
- var pairs = [];
-
- forIn(object, function(value, key) {
- pairs.push(key, value);
- });
-
- var length = pairs.length;
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(pairs[length--], pairs[length], object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Iterates over own enumerable properties of an object, executing the
callback
- * for each property. The callback is bound to `thisArg` and invoked with
three
- * arguments; (value, key, object). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
- * console.log(key);
- * });
- * // => logs '0', '1', and 'length' (property order is not guaranteed
across environments)
- */
- var forOwn = function(collection, callback, thisArg) {
- var index, iterable = collection, result = iterable;
- if (!iterable) return result;
- if (!objectTypes[typeof iterable]) return result;
- callback = callback && typeof thisArg == 'undefined' ? callback :
baseCreateCallback(callback, thisArg, 3);
- var ownIndex = -1,
- ownProps = objectTypes[typeof iterable] && keys(iterable),
- length = ownProps ? ownProps.length : 0;
-
- while (++ownIndex < length) {
- index = ownProps[ownIndex];
- if (callback(iterable[index], index, collection) === false) return
result;
- }
- return result
- };
-
- /**
- * This method is like `_.forOwn` except that it iterates over elements
- * of a `collection` in the opposite order.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns `object`.
- * @example
- *
- * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num,
key) {
- * console.log(key);
- * });
- * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1',
and 'length'
- */
- function forOwnRight(object, callback, thisArg) {
- var props = keys(object),
- length = props.length;
-
- callback = baseCreateCallback(callback, thisArg, 3);
- while (length--) {
- var key = props[length];
- if (callback(object[key], key, object) === false) {
- break;
- }
- }
- return object;
- }
-
- /**
- * Creates a sorted array of property names of all enumerable properties,
- * own and inherited, of `object` that have function values.
- *
- * @static
- * @memberOf _
- * @alias methods
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property names that have function
values.
- * @example
- *
- * _.functions(_);
- * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose',
...]
- */
- function functions(object) {
- var result = [];
- forIn(object, function(value, key) {
- if (isFunction(value)) {
- result.push(key);
- }
- });
- return result.sort();
- }
-
- /**
- * Checks if the specified property name exists as a direct property of
`object`,
- * instead of an inherited property.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to check.
- * @returns {boolean} Returns `true` if key is a direct property, else
`false`.
- * @example
- *
- * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
- * // => true
- */
- function has(object, key) {
- return object ? hasOwnProperty.call(object, key) : false;
- }
-
- /**
- * Creates an object composed of the inverted keys and values of the given
object.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to invert.
- * @returns {Object} Returns the created inverted object.
- * @example
- *
- * _.invert({ 'first': 'fred', 'second': 'barney' });
- * // => { 'fred': 'first', 'barney': 'second' }
- */
- function invert(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = {};
-
- while (++index < length) {
- var key = props[index];
- result[object[key]] = key;
- }
- return result;
- }
-
- /**
- * Checks if `value` is a boolean value.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a boolean value,
else `false`.
- * @example
- *
- * _.isBoolean(null);
- * // => false
- */
- function isBoolean(value) {
- return value === true || value === false ||
- value && typeof value == 'object' && toString.call(value) == boolClass
|| false;
- }
-
- /**
- * Checks if `value` is a date.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a date, else
`false`.
- * @example
- *
- * _.isDate(new Date);
- * // => true
- */
- function isDate(value) {
- return value && typeof value == 'object' && toString.call(value) ==
dateClass || false;
- }
-
- /**
- * Checks if `value` is a DOM element.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a DOM element, else
`false`.
- * @example
- *
- * _.isElement(document.body);
- * // => true
- */
- function isElement(value) {
- return value && value.nodeType === 1 || false;
- }
-
- /**
- * Checks if `value` is empty. Arrays, strings, or `arguments` objects
with a
- * length of `0` and objects with no own enumerable properties are
considered
- * "empty".
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object|string} value The value to inspect.
- * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
- * @example
- *
- * _.isEmpty([1, 2, 3]);
- * // => false
- *
- * _.isEmpty({});
- * // => true
- *
- * _.isEmpty('');
- * // => true
- */
- function isEmpty(value) {
- var result = true;
- if (!value) {
- return result;
- }
- var className = toString.call(value),
- length = value.length;
-
- if ((className == arrayClass || className == stringClass || className ==
argsClass ) ||
- (className == objectClass && typeof length == 'number' &&
isFunction(value.splice))) {
- return !length;
- }
- forOwn(value, function() {
- return (result = false);
- });
- return result;
- }
-
- /**
- * Performs a deep comparison between two values to determine if they are
- * equivalent to each other. If a callback is provided it will be executed
- * to compare values. If the callback returns `undefined` comparisons will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (a, b).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} a The value to compare.
- * @param {*} b The other value to compare.
- * @param {Function} [callback] The function to customize comparing values.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if the values are equivalent, else
`false`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var copy = { 'name': 'fred' };
- *
- * object == copy;
- * // => false
- *
- * _.isEqual(object, copy);
- * // => true
- *
- * var words = ['hello', 'goodbye'];
- * var otherWords = ['hi', 'goodbye'];
- *
- * _.isEqual(words, otherWords, function(a, b) {
- * var reGreet = /^(?:hello|hi)$/i,
- * aGreet = _.isString(a) && reGreet.test(a),
- * bGreet = _.isString(b) && reGreet.test(b);
- *
- * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
- * });
- * // => true
- */
- function isEqual(a, b, callback, thisArg) {
- return baseIsEqual(a, b, typeof callback == 'function' &&
baseCreateCallback(callback, thisArg, 2));
- }
-
- /**
- * Checks if `value` is, or can be coerced to, a finite number.
- *
- * Note: This is not the same as native `isFinite` which will return true
for
- * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is finite, else
`false`.
- * @example
- *
- * _.isFinite(-101);
- * // => true
- *
- * _.isFinite('10');
- * // => true
- *
- * _.isFinite(true);
- * // => false
- *
- * _.isFinite('');
- * // => false
- *
- * _.isFinite(Infinity);
- * // => false
- */
- function isFinite(value) {
- return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
- }
-
- /**
- * Checks if `value` is a function.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a function, else
`false`.
- * @example
- *
- * _.isFunction(_);
- * // => true
- */
- function isFunction(value) {
- return typeof value == 'function';
- }
-
- /**
- * Checks if `value` is the language type of Object.
- * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new
String('')`)
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is an object, else
`false`.
- * @example
- *
- * _.isObject({});
- * // => true
- *
- * _.isObject([1, 2, 3]);
- * // => true
- *
- * _.isObject(1);
- * // => false
- */
- function isObject(value) {
- // check if the value is the ECMAScript language type of Object
- // http://es5.github.io/#x8
- // and avoid a V8 bug
- // http://code.google.com/p/v8/issues/detail?id=2291
- return !!(value && objectTypes[typeof value]);
- }
-
- /**
- * Checks if `value` is `NaN`.
- *
- * Note: This is not the same as native `isNaN` which will return `true`
for
- * `undefined` and other non-numeric values. See
http://es5.github.io/#x15.1.2.4.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
- * @example
- *
- * _.isNaN(NaN);
- * // => true
- *
- * _.isNaN(new Number(NaN));
- * // => true
- *
- * isNaN(undefined);
- * // => true
- *
- * _.isNaN(undefined);
- * // => false
- */
- function isNaN(value) {
- // `NaN` as a primitive is the only value that is not equal to itself
- // (perform the [[Class]] check first to avoid errors with some host
objects in IE)
- return isNumber(value) && value != +value;
- }
-
- /**
- * Checks if `value` is `null`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `null`, else
`false`.
- * @example
- *
- * _.isNull(null);
- * // => true
- *
- * _.isNull(undefined);
- * // => false
- */
- function isNull(value) {
- return value === null;
- }
-
- /**
- * Checks if `value` is a number.
- *
- * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a number, else
`false`.
- * @example
- *
- * _.isNumber(8.4 * 5);
- * // => true
- */
- function isNumber(value) {
- return typeof value == 'number' ||
- value && typeof value == 'object' && toString.call(value) ==
numberClass || false;
- }
-
- /**
- * Checks if `value` is an object created by the `Object` constructor.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if `value` is a plain object, else
`false`.
- * @example
- *
- * function Shape() {
- * this.x = 0;
- * this.y = 0;
- * }
- *
- * _.isPlainObject(new Shape);
- * // => false
- *
- * _.isPlainObject([1, 2, 3]);
- * // => false
- *
- * _.isPlainObject({ 'x': 0, 'y': 0 });
- * // => true
- */
- var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
- if (!(value && toString.call(value) == objectClass)) {
- return false;
- }
- var valueOf = value.valueOf,
- objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf))
&& getPrototypeOf(objProto);
-
- return objProto
- ? (value == objProto || getPrototypeOf(value) == objProto)
- : shimIsPlainObject(value);
- };
-
- /**
- * Checks if `value` is a regular expression.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a regular
expression, else `false`.
- * @example
- *
- * _.isRegExp(/fred/);
- * // => true
- */
- function isRegExp(value) {
- return value && typeof value == 'object' && toString.call(value) ==
regexpClass || false;
- }
-
- /**
- * Checks if `value` is a string.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is a string, else
`false`.
- * @example
- *
- * _.isString('fred');
- * // => true
- */
- function isString(value) {
- return typeof value == 'string' ||
- value && typeof value == 'object' && toString.call(value) ==
stringClass || false;
- }
-
- /**
- * Checks if `value` is `undefined`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {*} value The value to check.
- * @returns {boolean} Returns `true` if the `value` is `undefined`, else
`false`.
- * @example
- *
- * _.isUndefined(void 0);
- * // => true
- */
- function isUndefined(value) {
- return typeof value == 'undefined';
- }
-
- /**
- * Creates an object with the same keys as `object` and values generated by
- * running each own enumerable property of `object` through the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, key, object).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new object with values of the results of
each `callback` execution.
- * @example
- *
- * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3;
});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- *
- * var characters = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // using "_.pluck" callback shorthand
- * _.mapValues(characters, 'age');
- * // => { 'fred': 40, 'pebbles': 1 }
- */
- function mapValues(object, callback, thisArg) {
- var result = {};
- callback = lodash.createCallback(callback, thisArg, 3);
-
- forOwn(object, function(value, key, object) {
- result[key] = callback(value, key, object);
- });
- return result;
- }
-
- /**
- * Recursively merges own enumerable properties of the source object(s),
that
- * don't resolve to `undefined` into the destination object. Subsequent
sources
- * will overwrite property assignments of previous sources. If a callback
is
- * provided it will be executed to produce the merged values of the
destination
- * and source properties. If the callback returns `undefined` merging will
- * be handled by the method instead. The callback is bound to `thisArg` and
- * invoked with two arguments; (objectValue, sourceValue).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The destination object.
- * @param {...Object} [source] The source objects.
- * @param {Function} [callback] The function to customize merging
properties.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the destination object.
- * @example
- *
- * var names = {
- * 'characters': [
- * { 'name': 'barney' },
- * { 'name': 'fred' }
- * ]
- * };
- *
- * var ages = {
- * 'characters': [
- * { 'age': 36 },
- * { 'age': 40 }
- * ]
- * };
- *
- * _.merge(names, ages);
- * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name':
'fred', 'age': 40 }] }
- *
- * var food = {
- * 'fruits': ['apple'],
- * 'vegetables': ['beet']
- * };
- *
- * var otherFood = {
- * 'fruits': ['banana'],
- * 'vegetables': ['carrot']
- * };
- *
- * _.merge(food, otherFood, function(a, b) {
- * return _.isArray(a) ? a.concat(b) : undefined;
- * });
- * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
- */
- function merge(object) {
- var args = arguments,
- length = 2;
-
- if (!isObject(object)) {
- return object;
- }
- // allows working with `_.reduce` and `_.reduceRight` without using
- // their `index` and `collection` arguments
- if (typeof args[2] != 'number') {
- length = args.length;
- }
- if (length > 3 && typeof args[length - 2] == 'function') {
- var callback = baseCreateCallback(args[--length - 1], args[length--],
2);
- } else if (length > 2 && typeof args[length - 1] == 'function') {
- callback = args[--length];
- }
- var sources = slice(arguments, 1, length),
- index = -1,
- stackA = getArray(),
- stackB = getArray();
-
- while (++index < length) {
- baseMerge(object, sources[index], callback, stackA, stackB);
- }
- releaseArray(stackA);
- releaseArray(stackB);
- return object;
- }
-
- /**
- * Creates a shallow clone of `object` excluding the specified properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` omitting the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three
arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The properties to omit
or the
- * function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object without the omitted properties.
- * @example
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
- * // => { 'name': 'fred' }
- *
- * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
- * return typeof value == 'number';
- * });
- * // => { 'name': 'fred' }
- */
- function omit(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var props = [];
- forIn(object, function(value, key) {
- props.push(key);
- });
- props = baseDifference(props, baseFlatten(arguments, true, false, 1));
-
- var index = -1,
- length = props.length;
-
- while (++index < length) {
- var key = props[index];
- result[key] = object[key];
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (!callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Creates a two dimensional array of an object's key-value pairs,
- * i.e. `[[key1, value1], [key2, value2]]`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns new array of key-value pairs.
- * @example
- *
- * _.pairs({ 'barney': 36, 'fred': 40 });
- * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed
across environments)
- */
- function pairs(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- var key = props[index];
- result[index] = [key, object[key]];
- }
- return result;
- }
-
- /**
- * Creates a shallow clone of `object` composed of the specified
properties.
- * Property names may be specified as individual arguments or as arrays of
- * property names. If a callback is provided it will be executed for each
- * property of `object` picking the properties the callback returns truey
- * for. The callback is bound to `thisArg` and invoked with three
arguments;
- * (value, key, object).
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The source object.
- * @param {Function|...string|string[]} [callback] The function called per
- * iteration or property names to pick, specified as individual property
- * names or arrays of property names.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns an object composed of the picked properties.
- * @example
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
- * // => { 'name': 'fred' }
- *
- * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
- * return key.charAt(0) != '_';
- * });
- * // => { 'name': 'fred' }
- */
- function pick(object, callback, thisArg) {
- var result = {};
- if (typeof callback != 'function') {
- var index = -1,
- props = baseFlatten(arguments, true, false, 1),
- length = isObject(object) ? props.length : 0;
-
- while (++index < length) {
- var key = props[index];
- if (key in object) {
- result[key] = object[key];
- }
- }
- } else {
- callback = lodash.createCallback(callback, thisArg, 3);
- forIn(object, function(value, key, object) {
- if (callback(value, key, object)) {
- result[key] = value;
- }
- });
- }
- return result;
- }
-
- /**
- * An alternative to `_.reduce` this method transforms `object` to a new
- * `accumulator` object which is the result of running each of its own
- * enumerable properties through a callback, with each callback execution
- * potentially mutating the `accumulator` object. The callback is bound to
- * `thisArg` and invoked with four arguments; (accumulator, value, key,
object).
- * Callbacks may exit iteration early by explicitly returning `false`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Array|Object} object The object to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] The custom accumulator value.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
function(result, num) {
- * num *= num;
- * if (num % 2) {
- * return result.push(num) < 3;
- * }
- * });
- * // => [1, 9, 25]
- *
- * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result,
num, key) {
- * result[key] = num * 3;
- * });
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function transform(object, callback, accumulator, thisArg) {
- var isArr = isArray(object);
- if (accumulator == null) {
- if (isArr) {
- accumulator = [];
- } else {
- var ctor = object && object.constructor,
- proto = ctor && ctor.prototype;
-
- accumulator = baseCreate(proto);
- }
- }
- if (callback) {
- callback = lodash.createCallback(callback, thisArg, 4);
- (isArr ? forEach : forOwn)(object, function(value, index, object) {
- return callback(accumulator, value, index, object);
- });
- }
- return accumulator;
- }
-
- /**
- * Creates an array composed of the own enumerable property values of
`object`.
- *
- * @static
- * @memberOf _
- * @category Objects
- * @param {Object} object The object to inspect.
- * @returns {Array} Returns an array of property values.
- * @example
- *
- * _.values({ 'one': 1, 'two': 2, 'three': 3 });
- * // => [1, 2, 3] (property order is not guaranteed across environments)
- */
- function values(object) {
- var index = -1,
- props = keys(object),
- length = props.length,
- result = Array(length);
-
- while (++index < length) {
- result[index] = object[props[index]];
- }
- return result;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array of elements from the specified indexes, or keys, of the
- * `collection`. Indexes may be specified as individual arguments or as
arrays
- * of indexes.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {...(number|number[]|string|string[])} [index] The indexes of
`collection`
- * to retrieve, specified as individual indexes or arrays of indexes.
- * @returns {Array} Returns a new array of elements corresponding to the
- * provided indexes.
- * @example
- *
- * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
- * // => ['a', 'c', 'e']
- *
- * _.at(['fred', 'barney', 'pebbles'], 0, 2);
- * // => ['fred', 'pebbles']
- */
- function at(collection) {
- var args = arguments,
- index = -1,
- props = baseFlatten(args, true, false, 1),
- length = (args[2] && args[2][args[1]] === collection) ? 1 :
props.length,
- result = Array(length);
-
- while(++index < length) {
- result[index] = collection[props[index]];
- }
- return result;
- }
-
- /**
- * Checks if a given value is present in a collection using strict equality
- * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as
the
- * offset from the end of the collection.
- *
- * @static
- * @memberOf _
- * @alias include
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {*} target The value to check for.
- * @param {number} [fromIndex=0] The index to search from.
- * @returns {boolean} Returns `true` if the `target` element is found,
else `false`.
- * @example
- *
- * _.contains([1, 2, 3], 1);
- * // => true
- *
- * _.contains([1, 2, 3], 1, 2);
- * // => false
- *
- * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
- * // => true
- *
- * _.contains('pebbles', 'eb');
- * // => true
- */
- function contains(collection, target, fromIndex) {
- var index = -1,
- indexOf = getIndexOf(),
- length = collection ? collection.length : 0,
- result = false;
-
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) :
fromIndex) || 0;
- if (isArray(collection)) {
- result = indexOf(collection, target, fromIndex) > -1;
- } else if (typeof length == 'number') {
- result = (isString(collection) ? collection.indexOf(target, fromIndex)
: indexOf(collection, target, fromIndex)) > -1;
- } else {
- forOwn(collection, function(value) {
- if (++index >= fromIndex) {
- return !(result = value === target);
- }
- });
- }
- return result;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of `collection` through the callback. The corresponding
value
- * of each key is the number of times the key was returned by the callback.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); },
Math);
- * // => { '4': 1, '6': 2 }
- *
- * _.countBy(['one', 'two', 'three'], 'length');
- * // => { '3': 2, '5': 1 }
- */
- var countBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
- });
-
- /**
- * Checks if the given callback returns truey value for **all** elements of
- * a collection. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias all
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if all elements passed the callback
check,
- * else `false`.
- * @example
- *
- * _.every([true, 1, null, 'yes']);
- * // => false
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.every(characters, 'age');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.every(characters, { 'age': 36 });
- * // => false
- */
- function every(collection, callback, thisArg) {
- var result = true;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- var index = -1,
- length = collection ? collection.length : 0;
-
- if (typeof length == 'number') {
- while (++index < length) {
- if (!(result = !!callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- return (result = !!callback(value, index, collection));
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning an array of all
elements
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias select
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that passed the
callback check.
- * @example
- *
- * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2
== 0; });
- * // => [2, 4, 6]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.filter(characters, 'blocked');
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- *
- * // using "_.where" callback shorthand
- * _.filter(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- */
- function filter(collection, callback, thisArg) {
- var result = [];
- callback = lodash.createCallback(callback, thisArg, 3);
-
- var index = -1,
- length = collection ? collection.length : 0;
-
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- result.push(value);
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result.push(value);
- }
- });
- }
- return result;
- }
-
- /**
- * Iterates over elements of a collection, returning the first element that
- * the callback returns truey for. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias detect, findWhere
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.find(characters, function(chr) {
- * return chr.age < 40;
- * });
- * // => { 'name': 'barney', 'age': 36, 'blocked': false }
- *
- * // using "_.where" callback shorthand
- * _.find(characters, { 'age': 1 });
- * // => { 'name': 'pebbles', 'age': 1, 'blocked': false }
- *
- * // using "_.pluck" callback shorthand
- * _.find(characters, 'blocked');
- * // => { 'name': 'fred', 'age': 40, 'blocked': true }
- */
- function find(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
-
- var index = -1,
- length = collection ? collection.length : 0;
-
- if (typeof length == 'number') {
- while (++index < length) {
- var value = collection[index];
- if (callback(value, index, collection)) {
- return value;
- }
- }
- } else {
- var result;
- forOwn(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
- }
-
- /**
- * This method is like `_.find` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the found element, else `undefined`.
- * @example
- *
- * _.findLast([1, 2, 3, 4], function(num) {
- * return num % 2 == 1;
- * });
- * // => 3
- */
- function findLast(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
- forEachRight(collection, function(value, index, collection) {
- if (callback(value, index, collection)) {
- result = value;
- return false;
- }
- });
- return result;
- }
-
- /**
- * Iterates over elements of a collection, executing the callback for each
- * element. The callback is bound to `thisArg` and invoked with three
arguments;
- * (value, index|key, collection). Callbacks may exit iteration early by
- * explicitly returning `false`.
- *
- * Note: As with other "Collections" methods, objects with a `length`
property
- * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
- * may be used for object iteration.
- *
- * @static
- * @memberOf _
- * @alias each
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
- * // => logs each number and returns '1,2,3'
- *
- * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) {
console.log(num); });
- * // => logs each number and returns the object (property order is not
guaranteed across environments)
- */
- function forEach(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0;
-
- callback = callback && typeof thisArg == 'undefined' ? callback :
baseCreateCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- while (++index < length) {
- if (callback(collection[index], index, collection) === false) {
- break;
- }
- }
- } else {
- forOwn(collection, callback);
- }
- return collection;
- }
-
- /**
- * This method is like `_.forEach` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias eachRight
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array|Object|string} Returns `collection`.
- * @example
- *
- * _([1, 2, 3]).forEachRight(function(num) { console.log(num);
}).join(',');
- * // => logs each number from right to left and returns '3,2,1'
- */
- function forEachRight(collection, callback, thisArg) {
- var length = collection ? collection.length : 0;
- callback = callback && typeof thisArg == 'undefined' ? callback :
baseCreateCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- while (length--) {
- if (callback(collection[length], length, collection) === false) {
- break;
- }
- }
- } else {
- var props = keys(collection);
- length = props.length;
- forOwn(collection, function(value, key, collection) {
- key = props ? props[--length] : --length;
- return callback(collection[key], key, collection);
- });
- }
- return collection;
- }
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of a collection through the callback. The corresponding
value
- * of each key is an array of the elements responsible for generating the
key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); },
Math);
- * // => { '4': [4.2], '6': [6.1, 6.4] }
- *
- * // using "_.pluck" callback shorthand
- * _.groupBy(['one', 'two', 'three'], 'length');
- * // => { '3': ['one', 'two'], '5': ['three'] }
- */
- var groupBy = createAggregator(function(result, value, key) {
- (hasOwnProperty.call(result, key) ? result[key] : result[key] =
[]).push(value);
- });
-
- /**
- * Creates an object composed of keys generated from the results of running
- * each element of the collection through the given callback. The
corresponding
- * value of each key is the last element responsible for generating the
key.
- * The callback is bound to `thisArg` and invoked with three arguments;
- * (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Object} Returns the composed aggregate object.
- * @example
- *
- * var keys = [
- * { 'dir': 'left', 'code': 97 },
- * { 'dir': 'right', 'code': 100 }
- * ];
- *
- * _.indexBy(keys, 'dir');
- * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir':
'right', 'code': 100 } }
- *
- * _.indexBy(keys, function(key) { return String.fromCharCode(key.code);
});
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right',
'code': 100 } }
- *
- * _.indexBy(characters, function(key) { this.fromCharCode(key.code); },
String);
- * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right',
'code': 100 } }
- */
- var indexBy = createAggregator(function(result, value, key) {
- result[key] = value;
- });
-
- /**
- * Invokes the method named by `methodName` on each element in the
`collection`
- * returning an array of the results of each invoked method. Additional
arguments
- * will be provided to each invoked method. If `methodName` is a function
it
- * will be invoked for, and `this` bound to, each element in the
`collection`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|string} methodName The name of the method to invoke or
- * the function invoked per iteration.
- * @param {...*} [arg] Arguments to invoke the method with.
- * @returns {Array} Returns a new array of the results of each invoked
method.
- * @example
- *
- * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
- * // => [[1, 5, 7], [1, 2, 3]]
- *
- * _.invoke([123, 456], String.prototype.split, '');
- * // => [['1', '2', '3'], ['4', '5', '6']]
- */
- function invoke(collection, methodName) {
- var args = slice(arguments, 2),
- index = -1,
- isFunc = typeof methodName == 'function',
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- result[++index] = (isFunc ? methodName :
value[methodName]).apply(value, args);
- });
- return result;
- }
-
- /**
- * Creates an array of values by running each element in the collection
- * through the callback. The callback is bound to `thisArg` and invoked
with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias collect
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of the results of each `callback`
execution.
- * @example
- *
- * _.map([1, 2, 3], function(num) { return num * 3; });
- * // => [3, 6, 9]
- *
- * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num *
3; });
- * // => [3, 6, 9] (property order is not guaranteed across environments)
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(characters, 'name');
- * // => ['barney', 'fred']
- */
- function map(collection, callback, thisArg) {
- var index = -1,
- length = collection ? collection.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- if (typeof length == 'number') {
- var result = Array(length);
- while (++index < length) {
- result[index] = callback(collection[index], index, collection);
- }
- } else {
- result = [];
- forOwn(collection, function(value, key, collection) {
- result[++index] = callback(value, key, collection);
- });
- }
- return result;
- }
-
- /**
- * Retrieves the maximum value of a collection. If the collection is empty
or
- * falsey `-Infinity` is returned. If a callback is provided it will be
executed
- * for each value in the collection to generate the criterion by which the
value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the maximum value.
- * @example
- *
- * _.max([4, 2, 8, 6]);
- * // => 8
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.max(characters, function(chr) { return chr.age; });
- * // => { 'name': 'fred', 'age': 40 };
- *
- * // using "_.pluck" callback shorthand
- * _.max(characters, 'age');
- * // => { 'name': 'fred', 'age': 40 };
- */
- function max(collection, callback, thisArg) {
- var computed = -Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] ===
collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value > result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- forEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current > computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the minimum value of a collection. If the collection is empty
or
- * falsey `Infinity` is returned. If a callback is provided it will be
executed
- * for each value in the collection to generate the criterion by which the
value
- * is ranked. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the minimum value.
- * @example
- *
- * _.min([4, 2, 8, 6]);
- * // => 2
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.min(characters, function(chr) { return chr.age; });
- * // => { 'name': 'barney', 'age': 36 };
- *
- * // using "_.pluck" callback shorthand
- * _.min(characters, 'age');
- * // => { 'name': 'barney', 'age': 36 };
- */
- function min(collection, callback, thisArg) {
- var computed = Infinity,
- result = computed;
-
- // allows working with functions like `_.map` without using
- // their `index` argument as a callback
- if (typeof callback != 'function' && thisArg && thisArg[callback] ===
collection) {
- callback = null;
- }
- if (callback == null && isArray(collection)) {
- var index = -1,
- length = collection.length;
-
- while (++index < length) {
- var value = collection[index];
- if (value < result) {
- result = value;
- }
- }
- } else {
- callback = (callback == null && isString(collection))
- ? charAtCallback
- : lodash.createCallback(callback, thisArg, 3);
-
- forEach(collection, function(value, index, collection) {
- var current = callback(value, index, collection);
- if (current < computed) {
- computed = current;
- result = value;
- }
- });
- }
- return result;
- }
-
- /**
- * Retrieves the value of a specified property from all elements in the
collection.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {string} property The name of the property to pluck.
- * @returns {Array} Returns a new array of property values.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * _.pluck(characters, 'name');
- * // => ['barney', 'fred']
- */
- var pluck = map;
-
- /**
- * Reduces a collection to a value which is the accumulated result of
running
- * each element in the collection through the callback, where each
successive
- * callback execution consumes the return value of the previous execution.
If
- * `accumulator` is not provided the first element of the collection will
be
- * used as the initial `accumulator` value. The callback is bound to
`thisArg`
- * and invoked with four arguments; (accumulator, value, index|key,
collection).
- *
- * @static
- * @memberOf _
- * @alias foldl, inject
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var sum = _.reduce([1, 2, 3], function(sum, num) {
- * return sum + num;
- * });
- * // => 6
- *
- * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num,
key) {
- * result[key] = num * 3;
- * return result;
- * }, {});
- * // => { 'a': 3, 'b': 6, 'c': 9 }
- */
- function reduce(collection, callback, accumulator, thisArg) {
- if (!collection) return accumulator;
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
-
- var index = -1,
- length = collection.length;
-
- if (typeof length == 'number') {
- if (noaccum) {
- accumulator = collection[++index];
- }
- while (++index < length) {
- accumulator = callback(accumulator, collection[index], index,
collection);
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection)
- });
- }
- return accumulator;
- }
-
- /**
- * This method is like `_.reduce` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * @static
- * @memberOf _
- * @alias foldr
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function} [callback=identity] The function called per iteration.
- * @param {*} [accumulator] Initial value of the accumulator.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the accumulated value.
- * @example
- *
- * var list = [[0, 1], [2, 3], [4, 5]];
- * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); },
[]);
- * // => [4, 5, 2, 3, 0, 1]
- */
- function reduceRight(collection, callback, accumulator, thisArg) {
- var noaccum = arguments.length < 3;
- callback = lodash.createCallback(callback, thisArg, 4);
- forEachRight(collection, function(value, index, collection) {
- accumulator = noaccum
- ? (noaccum = false, value)
- : callback(accumulator, value, index, collection);
- });
- return accumulator;
- }
-
- /**
- * The opposite of `_.filter` this method returns the elements of a
- * collection that the callback does **not** return truey for.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of elements that failed the
callback check.
- * @example
- *
- * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2
== 0; });
- * // => [1, 3, 5]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.reject(characters, 'blocked');
- * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }]
- *
- * // using "_.where" callback shorthand
- * _.reject(characters, { 'age': 36 });
- * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
- */
- function reject(collection, callback, thisArg) {
- callback = lodash.createCallback(callback, thisArg, 3);
- return filter(collection, function(value, index, collection) {
- return !callback(value, index, collection);
- });
- }
-
- /**
- * Retrieves a random element or `n` random elements from a collection.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to sample.
- * @param {number} [n] The number of elements to sample.
- * @param- {Object} [guard] Allows working with functions like `_.map`
- * without using their `index` arguments as `n`.
- * @returns {Array} Returns the random sample(s) of `collection`.
- * @example
- *
- * _.sample([1, 2, 3, 4]);
- * // => 2
- *
- * _.sample([1, 2, 3, 4], 2);
- * // => [3, 1]
- */
- function sample(collection, n, guard) {
- if (collection && typeof collection.length != 'number') {
- collection = values(collection);
- }
- if (n == null || guard) {
- return collection ? collection[baseRandom(0, collection.length - 1)] :
undefined;
- }
- var result = shuffle(collection);
- result.length = nativeMin(nativeMax(0, n), result.length);
- return result;
- }
-
- /**
- * Creates an array of shuffled values, using a version of the Fisher-Yates
- * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to shuffle.
- * @returns {Array} Returns a new shuffled collection.
- * @example
- *
- * _.shuffle([1, 2, 3, 4, 5, 6]);
- * // => [4, 1, 6, 3, 5, 2]
- */
- function shuffle(collection) {
- var index = -1,
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- forEach(collection, function(value) {
- var rand = baseRandom(0, ++index);
- result[index] = result[rand];
- result[rand] = value;
- });
- return result;
- }
-
- /**
- * Gets the size of the `collection` by returning `collection.length` for
arrays
- * and array-like objects or the number of own enumerable properties for
objects.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to inspect.
- * @returns {number} Returns `collection.length` or number of own
enumerable properties.
- * @example
- *
- * _.size([1, 2]);
- * // => 2
- *
- * _.size({ 'one': 1, 'two': 2, 'three': 3 });
- * // => 3
- *
- * _.size('pebbles');
- * // => 7
- */
- function size(collection) {
- var length = collection ? collection.length : 0;
- return typeof length == 'number' ? length : keys(collection).length;
- }
-
- /**
- * Checks if the callback returns a truey value for **any** element of a
- * collection. The function returns as soon as it finds a passing value and
- * does not iterate over the entire collection. The callback is bound to
- * `thisArg` and invoked with three arguments; (value, index|key,
collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias any
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {boolean} Returns `true` if any element passed the callback
check,
- * else `false`.
- * @example
- *
- * _.some([null, 0, 'yes', false], Boolean);
- * // => true
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.some(characters, 'blocked');
- * // => true
- *
- * // using "_.where" callback shorthand
- * _.some(characters, { 'age': 1 });
- * // => false
- */
- function some(collection, callback, thisArg) {
- var result;
- callback = lodash.createCallback(callback, thisArg, 3);
-
- var index = -1,
- length = collection ? collection.length : 0;
-
- if (typeof length == 'number') {
- while (++index < length) {
- if ((result = callback(collection[index], index, collection))) {
- break;
- }
- }
- } else {
- forOwn(collection, function(value, index, collection) {
- return !(result = callback(value, index, collection));
- });
- }
- return !!result;
- }
-
- /**
- * Creates an array of elements, sorted in ascending order by the results
of
- * running each element in a collection through the callback. This method
- * performs a stable sort, that is, it will preserve the original sort
order
- * of equal elements. The callback is bound to `thisArg` and invoked with
- * three arguments; (value, index|key, collection).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an array of property names is provided for `callback` the collection
- * will be sorted by each property value.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Array|Function|Object|string} [callback=identity] The function
called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of sorted elements.
- * @example
- *
- * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
- * // => [3, 1, 2]
- *
- * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
- * // => [3, 1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 26 },
- * { 'name': 'fred', 'age': 30 }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.map(_.sortBy(characters, 'age'), _.values);
- * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
- *
- * // sorting by multiple properties
- * _.map(_.sortBy(characters, ['name', 'age']), _.values);
- * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
- */
- function sortBy(collection, callback, thisArg) {
- var index = -1,
- isArr = isArray(callback),
- length = collection ? collection.length : 0,
- result = Array(typeof length == 'number' ? length : 0);
-
- if (!isArr) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- forEach(collection, function(value, key, collection) {
- var object = result[++index] = getObject();
- if (isArr) {
- object.criteria = map(callback, function(key) { return value[key];
});
- } else {
- (object.criteria = getArray())[0] = callback(value, key, collection);
- }
- object.index = index;
- object.value = value;
- });
-
- length = result.length;
- result.sort(compareAscending);
- while (length--) {
- var object = result[length];
- result[length] = object.value;
- if (!isArr) {
- releaseArray(object.criteria);
- }
- releaseObject(object);
- }
- return result;
- }
-
- /**
- * Converts the `collection` to an array.
- *
- * @static
- * @memberOf _
- * @category Collections
- * @param {Array|Object|string} collection The collection to convert.
- * @returns {Array} Returns the new converted array.
- * @example
- *
- * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
- * // => [2, 3, 4]
- */
- function toArray(collection) {
- if (collection && typeof collection.length == 'number') {
- return slice(collection);
- }
- return values(collection);
- }
-
- /**
- * Performs a deep comparison of each element in a `collection` to the
given
- * `properties` object, returning an array of all elements that have
equivalent
- * property values.
- *
- * @static
- * @memberOf _
- * @type Function
- * @category Collections
- * @param {Array|Object|string} collection The collection to iterate over.
- * @param {Object} props The object of property values to filter by.
- * @returns {Array} Returns a new array of elements that have the given
properties.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * _.where(characters, { 'age': 36 });
- * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
- *
- * _.where(characters, { 'pets': ['dino'] });
- * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
- */
- var where = filter;
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates an array with all falsey values removed. The values `false`,
`null`,
- * `0`, `""`, `undefined`, and `NaN` are all falsey.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to compact.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.compact([0, 1, false, 2, '', 3]);
- * // => [1, 2, 3]
- */
- function compact(array) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- while (++index < length) {
- var value = array[index];
- if (value) {
- result.push(value);
- }
- }
- return result;
- }
-
- /**
- * Creates an array excluding all values of the provided arrays using
strict
- * equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {...Array} [values] The arrays of values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
- * // => [1, 3, 4]
- */
- function difference(array) {
- return baseDifference(array, baseFlatten(arguments, true, true, 1));
- }
-
- /**
- * This method is like `_.find` except that it returns the index of the
first
- * element that passes the callback check, instead of the element itself.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': false },
- * { 'name': 'fred', 'age': 40, 'blocked': true },
- * { 'name': 'pebbles', 'age': 1, 'blocked': false }
- * ];
- *
- * _.findIndex(characters, function(chr) {
- * return chr.age < 20;
- * });
- * // => 2
- *
- * // using "_.where" callback shorthand
- * _.findIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findIndex(characters, 'blocked');
- * // => 1
- */
- function findIndex(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- if (callback(array[index], index, array)) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * This method is like `_.findIndex` except that it iterates over elements
- * of a `collection` from right to left.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index of the found element, else `-1`.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36, 'blocked': true },
- * { 'name': 'fred', 'age': 40, 'blocked': false },
- * { 'name': 'pebbles', 'age': 1, 'blocked': true }
- * ];
- *
- * _.findLastIndex(characters, function(chr) {
- * return chr.age > 30;
- * });
- * // => 1
- *
- * // using "_.where" callback shorthand
- * _.findLastIndex(characters, { 'age': 36 });
- * // => 0
- *
- * // using "_.pluck" callback shorthand
- * _.findLastIndex(characters, 'blocked');
- * // => 2
- */
- function findLastIndex(array, callback, thisArg) {
- var length = array ? array.length : 0;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (length--) {
- if (callback(array[length], length, array)) {
- return length;
- }
- }
- return -1;
- }
-
- /**
- * Gets the first element or first `n` elements of an array. If a callback
- * is provided elements at the beginning of the array are returned as long
- * as the callback returns truey. The callback is bound to `thisArg` and
- * invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias head, take
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the first element(s) of `array`.
- * @example
- *
- * _.first([1, 2, 3]);
- * // => 1
- *
- * _.first([1, 2, 3], 2);
- * // => [1, 2]
- *
- * _.first([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [1, 2]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.first(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
- * // => ['barney', 'fred']
- */
- function first(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = -1;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[0] : undefined;
- }
- }
- return slice(array, 0, nativeMin(nativeMax(0, n), length));
- }
-
- /**
- * Flattens a nested array (the nesting can be to any depth). If
`isShallow`
- * is truey, the array will only be flattened a single level. If a callback
- * is provided each element of the array is passed through the callback
before
- * flattening. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to flatten.
- * @param {boolean} [isShallow=false] A flag to restrict flattening to a
single level.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new flattened array.
- * @example
- *
- * _.flatten([1, [2], [3, [[4]]]]);
- * // => [1, 2, 3, 4];
- *
- * _.flatten([1, [2], [3, [[4]]]], true);
- * // => [1, 2, 3, [[4]]];
- *
- * var characters = [
- * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
- * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.flatten(characters, 'pets');
- * // => ['hoppy', 'baby puss', 'dino']
- */
- function flatten(array, isShallow, callback, thisArg) {
- // juggle arguments
- if (typeof isShallow != 'boolean' && isShallow != null) {
- thisArg = callback;
- callback = (typeof isShallow != 'function' && thisArg &&
thisArg[isShallow] === array) ? null : isShallow;
- isShallow = false;
- }
- if (callback != null) {
- array = map(array, callback, thisArg);
- }
- return baseFlatten(array, isShallow);
- }
-
- /**
- * Gets the index at which the first occurrence of `value` is found using
- * strict equality for comparisons, i.e. `===`. If the array is already
sorted
- * providing `true` for `fromIndex` will run a faster binary search.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {boolean|number} [fromIndex=0] The index to search from or `true`
- * to perform a binary search on a sorted array.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 1
- *
- * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 4
- *
- * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
- * // => 2
- */
- function indexOf(array, value, fromIndex) {
- if (typeof fromIndex == 'number') {
- var length = array ? array.length : 0;
- fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) :
fromIndex || 0);
- } else if (fromIndex) {
- var index = sortedIndex(array, value);
- return array[index] === value ? index : -1;
- }
- return baseIndexOf(array, value, fromIndex);
- }
-
- /**
- * Gets all but the last element or last `n` elements of an array. If a
- * callback is provided elements at the end of the array are excluded from
- * the result as long as the callback returns truey. The callback is bound
- * to `thisArg` and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.initial([1, 2, 3]);
- * // => [1, 2]
- *
- * _.initial([1, 2, 3], 2);
- * // => [1]
- *
- * _.initial([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [1]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.initial(characters, 'blocked');
- * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
- *
- * // using "_.where" callback shorthand
- * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
- * // => ['barney', 'fred']
- */
- function initial(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : callback || n;
- }
- return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
- }
-
- /**
- * Creates an array of unique values present in all provided arrays using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of shared values.
- * @example
- *
- * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2]
- */
- function intersection() {
- var args = [],
- argsIndex = -1,
- argsLength = arguments.length,
- caches = getArray(),
- indexOf = getIndexOf(),
- trustIndexOf = indexOf === baseIndexOf,
- seen = getArray();
-
- while (++argsIndex < argsLength) {
- var value = arguments[argsIndex];
- if (isArray(value) || isArguments(value)) {
- args.push(value);
- caches.push(trustIndexOf && value.length >= largeArraySize &&
- createCache(argsIndex ? args[argsIndex] : seen));
- }
- }
- var array = args[0],
- index = -1,
- length = array ? array.length : 0,
- result = [];
-
- outer:
- while (++index < length) {
- var cache = caches[0];
- value = array[index];
-
- if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
- argsIndex = argsLength;
- (cache || seen).push(value);
- while (--argsIndex) {
- cache = caches[argsIndex];
- if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex],
value)) < 0) {
- continue outer;
- }
- }
- result.push(value);
- }
- }
- while (argsLength--) {
- cache = caches[argsLength];
- if (cache) {
- releaseObject(cache);
- }
- }
- releaseArray(caches);
- releaseArray(seen);
- return result;
- }
-
- /**
- * Gets the last element or last `n` elements of an array. If a callback is
- * provided elements at the end of the array are returned as long as the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback] The function called
- * per element or the number of elements to return. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {*} Returns the last element(s) of `array`.
- * @example
- *
- * _.last([1, 2, 3]);
- * // => 3
- *
- * _.last([1, 2, 3], 2);
- * // => [2, 3]
- *
- * _.last([1, 2, 3], function(num) {
- * return num > 1;
- * });
- * // => [2, 3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.last(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.last(characters, { 'employer': 'na' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function last(array, callback, thisArg) {
- var n = 0,
- length = array ? array.length : 0;
-
- if (typeof callback != 'number' && callback != null) {
- var index = length;
- callback = lodash.createCallback(callback, thisArg, 3);
- while (index-- && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = callback;
- if (n == null || thisArg) {
- return array ? array[length - 1] : undefined;
- }
- }
- return slice(array, nativeMax(0, length - n));
- }
-
- /**
- * Gets the index at which the last occurrence of `value` is found using
strict
- * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is
used
- * as the offset from the end of the collection.
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to search.
- * @param {*} value The value to search for.
- * @param {number} [fromIndex=array.length-1] The index to search from.
- * @returns {number} Returns the index of the matched value or `-1`.
- * @example
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
- * // => 4
- *
- * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
- * // => 1
- */
- function lastIndexOf(array, value, fromIndex) {
- var index = array ? array.length : 0;
- if (typeof fromIndex == 'number') {
- index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) :
nativeMin(fromIndex, index - 1)) + 1;
- }
- while (index--) {
- if (array[index] === value) {
- return index;
- }
- }
- return -1;
- }
-
- /**
- * Removes all provided values from the given array using strict equality
for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {...*} [value] The values to remove.
- * @returns {Array} Returns `array`.
- * @example
- *
- * var array = [1, 2, 3, 1, 2, 3];
- * _.pull(array, 2, 3);
- * console.log(array);
- * // => [1, 1]
- */
- function pull(array) {
- var args = arguments,
- argsIndex = 0,
- argsLength = args.length,
- length = array ? array.length : 0;
-
- while (++argsIndex < argsLength) {
- var index = -1,
- value = args[argsIndex];
- while (++index < length) {
- if (array[index] === value) {
- splice.call(array, index--, 1);
- length--;
- }
- }
- }
- return array;
- }
-
- /**
- * Creates an array of numbers (positive and/or negative) progressing from
- * `start` up to but not including `end`. If `start` is less than `stop` a
- * zero-length range is created unless a negative `step` is specified.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {number} [start=0] The start of the range.
- * @param {number} end The end of the range.
- * @param {number} [step=1] The value to increment or decrement by.
- * @returns {Array} Returns a new range array.
- * @example
- *
- * _.range(4);
- * // => [0, 1, 2, 3]
- *
- * _.range(1, 5);
- * // => [1, 2, 3, 4]
- *
- * _.range(0, 20, 5);
- * // => [0, 5, 10, 15]
- *
- * _.range(0, -4, -1);
- * // => [0, -1, -2, -3]
- *
- * _.range(1, 4, 0);
- * // => [1, 1, 1]
- *
- * _.range(0);
- * // => []
- */
- function range(start, end, step) {
- start = +start || 0;
- step = typeof step == 'number' ? step : (+step || 1);
-
- if (end == null) {
- end = start;
- start = 0;
- }
- // use `Array(length)` so engines like Chakra and V8 avoid slower modes
- // http://youtu.be/XAqIpGU8ZZk#t=17m25s
- var index = -1,
- length = nativeMax(0, ceil((end - start) / (step || 1))),
- result = Array(length);
-
- while (++index < length) {
- result[index] = start;
- start += step;
- }
- return result;
- }
-
- /**
- * Removes all elements from an array that the callback returns truey for
- * and returns an array of removed elements. The callback is bound to
`thisArg`
- * and invoked with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to modify.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a new array of removed elements.
- * @example
- *
- * var array = [1, 2, 3, 4, 5, 6];
- * var evens = _.remove(array, function(num) { return num % 2 == 0; });
- *
- * console.log(array);
- * // => [1, 3, 5]
- *
- * console.log(evens);
- * // => [2, 4, 6]
- */
- function remove(array, callback, thisArg) {
- var index = -1,
- length = array ? array.length : 0,
- result = [];
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length) {
- var value = array[index];
- if (callback(value, index, array)) {
- result.push(value);
- splice.call(array, index--, 1);
- length--;
- }
- }
- return result;
- }
-
- /**
- * The opposite of `_.initial` this method gets all but the first element
or
- * first `n` elements of an array. If a callback function is provided
elements
- * at the beginning of the array are excluded from the result as long as
the
- * callback returns truey. The callback is bound to `thisArg` and invoked
- * with three arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias drop, tail
- * @category Arrays
- * @param {Array} array The array to query.
- * @param {Function|Object|number|string} [callback=1] The function called
- * per element or the number of elements to exclude. If a property name or
- * object is provided it will be used to create a "_.pluck" or "_.where"
- * style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a slice of `array`.
- * @example
- *
- * _.rest([1, 2, 3]);
- * // => [2, 3]
- *
- * _.rest([1, 2, 3], 2);
- * // => [3]
- *
- * _.rest([1, 2, 3], function(num) {
- * return num < 3;
- * });
- * // => [3]
- *
- * var characters = [
- * { 'name': 'barney', 'blocked': true, 'employer': 'slate' },
- * { 'name': 'fred', 'blocked': false, 'employer': 'slate' },
- * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' }
- * ];
- *
- * // using "_.pluck" callback shorthand
- * _.pluck(_.rest(characters, 'blocked'), 'name');
- * // => ['fred', 'pebbles']
- *
- * // using "_.where" callback shorthand
- * _.rest(characters, { 'employer': 'slate' });
- * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }]
- */
- function rest(array, callback, thisArg) {
- if (typeof callback != 'number' && callback != null) {
- var n = 0,
- index = -1,
- length = array ? array.length : 0;
-
- callback = lodash.createCallback(callback, thisArg, 3);
- while (++index < length && callback(array[index], index, array)) {
- n++;
- }
- } else {
- n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
- }
- return slice(array, n);
- }
-
- /**
- * Uses a binary search to determine the smallest index at which a value
- * should be inserted into a given sorted array in order to maintain the
sort
- * order of the array. If a callback is provided it will be executed for
- * `value` and each element of `array` to compute their sort ranking. The
- * callback is bound to `thisArg` and invoked with one argument; (value).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to inspect.
- * @param {*} value The value to evaluate.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {number} Returns the index at which `value` should be inserted
- * into `array`.
- * @example
- *
- * _.sortedIndex([20, 30, 50], 40);
- * // => 2
- *
- * // using "_.pluck" callback shorthand
- * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 },
'x');
- * // => 2
- *
- * var dict = {
- * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty':
50 }
- * };
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return dict.wordToNumber[word];
- * });
- * // => 2
- *
- * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
- * return this.wordToNumber[word];
- * }, dict);
- * // => 2
- */
- function sortedIndex(array, value, callback, thisArg) {
- var low = 0,
- high = array ? array.length : low;
-
- // explicitly reference `identity` for better inlining in Firefox
- callback = callback ? lodash.createCallback(callback, thisArg, 1) :
identity;
- value = callback(value);
-
- while (low < high) {
- var mid = (low + high) >>> 1;
- (callback(array[mid]) < value)
- ? low = mid + 1
- : high = mid;
- }
- return low;
- }
-
- /**
- * Creates an array of unique values, in order, of the provided arrays
using
- * strict equality for comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of combined values.
- * @example
- *
- * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
- * // => [1, 2, 3, 5, 4]
- */
- function union() {
- return baseUniq(baseFlatten(arguments, true, true));
- }
-
- /**
- * Creates a duplicate-value-free version of an array using strict equality
- * for comparisons, i.e. `===`. If the array is sorted, providing
- * `true` for `isSorted` will use a faster algorithm. If a callback is
provided
- * each element of `array` is passed through the callback before uniqueness
- * is computed. The callback is bound to `thisArg` and invoked with three
- * arguments; (value, index, array).
- *
- * If a property name is provided for `callback` the created "_.pluck"
style
- * callback will return the property value of the given element.
- *
- * If an object is provided for `callback` the created "_.where" style
callback
- * will return `true` for elements that have the properties of the given
object,
- * else `false`.
- *
- * @static
- * @memberOf _
- * @alias unique
- * @category Arrays
- * @param {Array} array The array to process.
- * @param {boolean} [isSorted=false] A flag to indicate that `array` is
sorted.
- * @param {Function|Object|string} [callback=identity] The function called
- * per iteration. If a property name or object is provided it will be used
- * to create a "_.pluck" or "_.where" style callback, respectively.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns a duplicate-value-free array.
- * @example
- *
- * _.uniq([1, 2, 1, 3, 1]);
- * // => [1, 2, 3]
- *
- * _.uniq([1, 1, 2, 2, 3], true);
- * // => [1, 2, 3]
- *
- * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return
letter.toLowerCase(); });
- * // => ['A', 'b', 'C']
- *
- * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return
this.floor(num); }, Math);
- * // => [1, 2.5, 3]
- *
- * // using "_.pluck" callback shorthand
- * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
- * // => [{ 'x': 1 }, { 'x': 2 }]
- */
- function uniq(array, isSorted, callback, thisArg) {
- // juggle arguments
- if (typeof isSorted != 'boolean' && isSorted != null) {
- thisArg = callback;
- callback = (typeof isSorted != 'function' && thisArg &&
thisArg[isSorted] === array) ? null : isSorted;
- isSorted = false;
- }
- if (callback != null) {
- callback = lodash.createCallback(callback, thisArg, 3);
- }
- return baseUniq(array, isSorted, callback);
- }
-
- /**
- * Creates an array excluding all provided values using strict equality for
- * comparisons, i.e. `===`.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {Array} array The array to filter.
- * @param {...*} [value] The values to exclude.
- * @returns {Array} Returns a new array of filtered values.
- * @example
- *
- * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
- * // => [2, 3, 4]
- */
- function without(array) {
- return baseDifference(array, slice(arguments, 1));
- }
-
- /**
- * Creates an array that is the symmetric difference of the provided
arrays.
- * See http://en.wikipedia.org/wiki/Symmetric_difference.
- *
- * @static
- * @memberOf _
- * @category Arrays
- * @param {...Array} [array] The arrays to inspect.
- * @returns {Array} Returns an array of values.
- * @example
- *
- * _.xor([1, 2, 3], [5, 2, 1, 4]);
- * // => [3, 5, 4]
- *
- * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
- * // => [1, 4, 5]
- */
- function xor() {
- var index = -1,
- length = arguments.length;
-
- while (++index < length) {
- var array = arguments[index];
- if (isArray(array) || isArguments(array)) {
- var result = result
- ? baseUniq(baseDifference(result,
array).concat(baseDifference(array, result)))
- : array;
- }
- }
- return result || [];
- }
-
- /**
- * Creates an array of grouped elements, the first of which contains the
first
- * elements of the given arrays, the second of which contains the second
- * elements of the given arrays, and so on.
- *
- * @static
- * @memberOf _
- * @alias unzip
- * @category Arrays
- * @param {...Array} [array] Arrays to process.
- * @returns {Array} Returns a new array of grouped elements.
- * @example
- *
- * _.zip(['fred', 'barney'], [30, 40], [true, false]);
- * // => [['fred', 30, true], ['barney', 40, false]]
- */
- function zip() {
- var array = arguments.length > 1 ? arguments : arguments[0],
- index = -1,
- length = array ? max(pluck(array, 'length')) : 0,
- result = Array(length < 0 ? 0 : length);
-
- while (++index < length) {
- result[index] = pluck(array, index);
- }
- return result;
- }
-
- /**
- * Creates an object composed from arrays of `keys` and `values`. Provide
- * either a single two dimensional array, i.e. `[[key1, value1], [key2,
value2]]`
- * or two arrays, one of `keys` and one of corresponding `values`.
- *
- * @static
- * @memberOf _
- * @alias object
- * @category Arrays
- * @param {Array} keys The array of keys.
- * @param {Array} [values=[]] The array of values.
- * @returns {Object} Returns an object composed of the given keys and
- * corresponding values.
- * @example
- *
- * _.zipObject(['fred', 'barney'], [30, 40]);
- * // => { 'fred': 30, 'barney': 40 }
- */
- function zipObject(keys, values) {
- var index = -1,
- length = keys ? keys.length : 0,
- result = {};
-
- if (!values && length && !isArray(keys[0])) {
- values = [];
- }
- while (++index < length) {
- var key = keys[index];
- if (values) {
- result[key] = values[index];
- } else if (key) {
- result[key[0]] = key[1];
- }
- }
- return result;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that executes `func`, with the `this` binding and
- * arguments of the created function, only after being called `n` times.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {number} n The number of times the function must be called before
- * `func` is executed.
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var saves = ['profile', 'settings'];
- *
- * var done = _.after(saves.length, function() {
- * console.log('Done saving!');
- * });
- *
- * _.forEach(saves, function(type) {
- * asyncSave({ 'type': type, 'complete': done });
- * });
- * // => logs 'Done saving!', after all saves have completed
- */
- function after(n, func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (--n < 1) {
- return func.apply(this, arguments);
- }
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with the `this`
- * binding of `thisArg` and prepends any additional `bind` arguments to
those
- * provided to the bound function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to bind.
- * @param {*} [thisArg] The `this` binding of `func`.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var func = function(greeting) {
- * return greeting + ' ' + this.name;
- * };
- *
- * func = _.bind(func, { 'name': 'fred' }, 'hi');
- * func();
- * // => 'hi fred'
- */
- function bind(func, thisArg) {
- return arguments.length > 2
- ? createWrapper(func, 17, slice(arguments, 2), null, thisArg)
- : createWrapper(func, 1, null, null, thisArg);
- }
-
- /**
- * Binds methods of an object to the object itself, overwriting the
existing
- * method. Method names may be specified as individual arguments or as
arrays
- * of method names. If no method names are provided all the function
properties
- * of `object` will be bound.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object to bind and assign the bound methods
to.
- * @param {...string} [methodName] The object method names to
- * bind, specified as individual method names or arrays of method names.
- * @returns {Object} Returns `object`.
- * @example
- *
- * var view = {
- * 'label': 'docs',
- * 'onClick': function() { console.log('clicked ' + this.label); }
- * };
- *
- * _.bindAll(view);
- * jQuery('#docs').on('click', view.onClick);
- * // => logs 'clicked docs', when the button is clicked
- */
- function bindAll(object) {
- var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false,
1) : functions(object),
- index = -1,
- length = funcs.length;
-
- while (++index < length) {
- var key = funcs[index];
- object[key] = createWrapper(object[key], 1, null, null, object);
- }
- return object;
- }
-
- /**
- * Creates a function that, when called, invokes the method at
`object[key]`
- * and prepends any additional `bindKey` arguments to those provided to
the bound
- * function. This method differs from `_.bind` by allowing bound functions
to
- * reference methods that will be redefined or don't yet exist.
- * See http://michaux.ca/articles/lazy-function-definition-pattern.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Object} object The object the method belongs to.
- * @param {string} key The key of the method.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new bound function.
- * @example
- *
- * var object = {
- * 'name': 'fred',
- * 'greet': function(greeting) {
- * return greeting + ' ' + this.name;
- * }
- * };
- *
- * var func = _.bindKey(object, 'greet', 'hi');
- * func();
- * // => 'hi fred'
- *
- * object.greet = function(greeting) {
- * return greeting + 'ya ' + this.name + '!';
- * };
- *
- * func();
- * // => 'hiya fred!'
- */
- function bindKey(object, key) {
- return arguments.length > 2
- ? createWrapper(key, 19, slice(arguments, 2), null, object)
- : createWrapper(key, 3, null, null, object);
- }
-
- /**
- * Creates a function that is the composition of the provided functions,
- * where each function consumes the return value of the function that
follows.
- * For example, composing the functions `f()`, `g()`, and `h()` produces
`f(g(h()))`.
- * Each function is executed with the `this` binding of the composed
function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {...Function} [func] Functions to compose.
- * @returns {Function} Returns the new composed function.
- * @example
- *
- * var realNameMap = {
- * 'pebbles': 'penelope'
- * };
- *
- * var format = function(name) {
- * name = realNameMap[name.toLowerCase()] || name;
- * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
- * };
- *
- * var greet = function(formatted) {
- * return 'Hiya ' + formatted + '!';
- * };
- *
- * var welcome = _.compose(greet, format);
- * welcome('pebbles');
- * // => 'Hiya Penelope!'
- */
- function compose() {
- var funcs = arguments,
- length = funcs.length;
-
- while (length--) {
- if (!isFunction(funcs[length])) {
- throw new TypeError;
- }
- }
- return function() {
- var args = arguments,
- length = funcs.length;
-
- while (length--) {
- args = [funcs[length].apply(this, args)];
- }
- return args[0];
- };
- }
-
- /**
- * Creates a function which accepts one or more arguments of `func` that
when
- * invoked either executes `func` returning its result, if all `func`
arguments
- * have been provided, or returns a function that accepts one or more of
the
- * remaining `func` arguments, and so on. The arity of `func` can be
specified
- * if `func.length` is not sufficient.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to curry.
- * @param {number} [arity=func.length] The arity of `func`.
- * @returns {Function} Returns the new curried function.
- * @example
- *
- * var curried = _.curry(function(a, b, c) {
- * console.log(a + b + c);
- * });
- *
- * curried(1)(2)(3);
- * // => 6
- *
- * curried(1, 2)(3);
- * // => 6
- *
- * curried(1, 2, 3);
- * // => 6
- */
- function curry(func, arity) {
- arity = typeof arity == 'number' ? arity : (+arity || func.length);
- return createWrapper(func, 4, null, null, null, arity);
- }
-
- /**
- * Creates a function that will delay the execution of `func` until after
- * `wait` milliseconds have elapsed since the last time it was invoked.
- * Provide an options object to indicate that `func` should be invoked on
- * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
- * to the debounced function will return the result of the last `func`
call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be
called
- * on the trailing edge of the timeout only if the the debounced function
is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to debounce.
- * @param {number} wait The number of milliseconds to delay.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=false] Specify execution on the
leading edge of the timeout.
- * @param {number} [options.maxWait] The maximum time `func` is allowed to
be delayed before it's called.
- * @param {boolean} [options.trailing=true] Specify execution on the
trailing edge of the timeout.
- * @returns {Function} Returns the new debounced function.
- * @example
- *
- * // avoid costly calculations while the window size is in flux
- * var lazyLayout = _.debounce(calculateLayout, 150);
- * jQuery(window).on('resize', lazyLayout);
- *
- * // execute `sendMail` when the click event is fired, debouncing
subsequent calls
- * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
- * 'leading': true,
- * 'trailing': false
- * });
- *
- * // ensure `batchLog` is executed once after 1 second of debounced calls
- * var source = new EventSource('/stream');
- * source.addEventListener('message', _.debounce(batchLog, 250, {
- * 'maxWait': 1000
- * }, false);
- */
- function debounce(func, wait, options) {
- var args,
- maxTimeoutId,
- result,
- stamp,
- thisArg,
- timeoutId,
- trailingCall,
- lastCalled = 0,
- maxWait = false,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- wait = nativeMax(0, wait) || 0;
- if (options === true) {
- var leading = true;
- trailing = false;
- } else if (isObject(options)) {
- leading = options.leading;
- maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) ||
0);
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- var delayed = function() {
- var remaining = wait - (now() - stamp);
- if (remaining <= 0) {
- if (maxTimeoutId) {
- clearTimeout(maxTimeoutId);
- }
- var isCalled = trailingCall;
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (isCalled) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- } else {
- timeoutId = setTimeout(delayed, remaining);
- }
- };
-
- var maxDelayed = function() {
- if (timeoutId) {
- clearTimeout(timeoutId);
- }
- maxTimeoutId = timeoutId = trailingCall = undefined;
- if (trailing || (maxWait !== wait)) {
- lastCalled = now();
- result = func.apply(thisArg, args);
- if (!timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- }
- };
-
- return function() {
- args = arguments;
- stamp = now();
- thisArg = this;
- trailingCall = trailing && (timeoutId || !leading);
-
- if (maxWait === false) {
- var leadingCall = leading && !timeoutId;
- } else {
- if (!maxTimeoutId && !leading) {
- lastCalled = stamp;
- }
- var remaining = maxWait - (stamp - lastCalled),
- isCalled = remaining <= 0;
-
- if (isCalled) {
- if (maxTimeoutId) {
- maxTimeoutId = clearTimeout(maxTimeoutId);
- }
- lastCalled = stamp;
- result = func.apply(thisArg, args);
- }
- else if (!maxTimeoutId) {
- maxTimeoutId = setTimeout(maxDelayed, remaining);
- }
- }
- if (isCalled && timeoutId) {
- timeoutId = clearTimeout(timeoutId);
- }
- else if (!timeoutId && wait !== maxWait) {
- timeoutId = setTimeout(delayed, wait);
- }
- if (leadingCall) {
- isCalled = true;
- result = func.apply(thisArg, args);
- }
- if (isCalled && !timeoutId && !maxTimeoutId) {
- args = thisArg = null;
- }
- return result;
- };
- }
-
- /**
- * Defers executing the `func` function until the current call stack has
cleared.
- * Additional arguments will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to defer.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.defer(function(text) { console.log(text); }, 'deferred');
- * // logs 'deferred' after one or more milliseconds
- */
- function defer(func) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 1);
- return setTimeout(function() { func.apply(undefined, args); }, 1);
- }
-
- /**
- * Executes the `func` function after `wait` milliseconds. Additional
arguments
- * will be provided to `func` when it is invoked.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to delay.
- * @param {number} wait The number of milliseconds to delay execution.
- * @param {...*} [arg] Arguments to invoke the function with.
- * @returns {number} Returns the timer id.
- * @example
- *
- * _.delay(function(text) { console.log(text); }, 1000, 'later');
- * // => logs 'later' after one second
- */
- function delay(func, wait) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var args = slice(arguments, 2);
- return setTimeout(function() { func.apply(undefined, args); }, wait);
- }
-
- /**
- * Creates a function that memoizes the result of `func`. If `resolver` is
- * provided it will be used to determine the cache key for storing the
result
- * based on the arguments provided to the memoized function. By default,
the
- * first argument provided to the memoized function is used as the cache
key.
- * The `func` is executed with the `this` binding of the memoized function.
- * The result cache is exposed as the `cache` property on the memoized
function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to have its output memoized.
- * @param {Function} [resolver] A function used to resolve the cache key.
- * @returns {Function} Returns the new memoizing function.
- * @example
- *
- * var fibonacci = _.memoize(function(n) {
- * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
- * });
- *
- * fibonacci(9)
- * // => 34
- *
- * var data = {
- * 'fred': { 'name': 'fred', 'age': 40 },
- * 'pebbles': { 'name': 'pebbles', 'age': 1 }
- * };
- *
- * // modifying the result cache
- * var get = _.memoize(function(name) { return data[name]; }, _.identity);
- * get('pebbles');
- * // => { 'name': 'pebbles', 'age': 1 }
- *
- * get.cache.pebbles.name = 'penelope';
- * get('pebbles');
- * // => { 'name': 'penelope', 'age': 1 }
- */
- function memoize(func, resolver) {
- if (!isFunction(func)) {
- throw new TypeError;
- }
- var memoized = function() {
- var cache = memoized.cache,
- key = resolver ? resolver.apply(this, arguments) : keyPrefix +
arguments[0];
-
- return hasOwnProperty.call(cache, key)
- ? cache[key]
- : (cache[key] = func.apply(this, arguments));
- }
- memoized.cache = {};
- return memoized;
- }
-
- /**
- * Creates a function that is restricted to execute `func` once. Repeat
calls to
- * the function will return the value of the first call. The `func` is
executed
- * with the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to restrict.
- * @returns {Function} Returns the new restricted function.
- * @example
- *
- * var initialize = _.once(createApplication);
- * initialize();
- * initialize();
- * // `initialize` executes `createApplication` once
- */
- function once(func) {
- var ran,
- result;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- return function() {
- if (ran) {
- return result;
- }
- ran = true;
- result = func.apply(this, arguments);
-
- // clear the `func` variable so the function may be garbage collected
- func = null;
- return result;
- };
- }
-
- /**
- * Creates a function that, when called, invokes `func` with any additional
- * `partial` arguments prepended to those provided to the new function.
This
- * method is similar to `_.bind` except it does **not** alter the `this`
binding.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var greet = function(greeting, name) { return greeting + ' ' + name; };
- * var hi = _.partial(greet, 'hi');
- * hi('fred');
- * // => 'hi fred'
- */
- function partial(func) {
- return createWrapper(func, 16, slice(arguments, 1));
- }
-
- /**
- * This method is like `_.partial` except that `partial` arguments are
- * appended to those provided to the new function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to partially apply arguments to.
- * @param {...*} [arg] Arguments to be partially applied.
- * @returns {Function} Returns the new partially applied function.
- * @example
- *
- * var defaultsDeep = _.partialRight(_.merge, _.defaults);
- *
- * var options = {
- * 'variable': 'data',
- * 'imports': { 'jq': $ }
- * };
- *
- * defaultsDeep(options, _.templateSettings);
- *
- * options.variable
- * // => 'data'
- *
- * options.imports
- * // => { '_': _, 'jq': $ }
- */
- function partialRight(func) {
- return createWrapper(func, 32, null, slice(arguments, 1));
- }
-
- /**
- * Creates a function that, when executed, will only call the `func`
function
- * at most once per every `wait` milliseconds. Provide an options object to
- * indicate that `func` should be invoked on the leading and/or trailing
edge
- * of the `wait` timeout. Subsequent calls to the throttled function will
- * return the result of the last `func` call.
- *
- * Note: If `leading` and `trailing` options are `true` `func` will be
called
- * on the trailing edge of the timeout only if the the throttled function
is
- * invoked more than once during the `wait` timeout.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {Function} func The function to throttle.
- * @param {number} wait The number of milliseconds to throttle executions
to.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.leading=true] Specify execution on the
leading edge of the timeout.
- * @param {boolean} [options.trailing=true] Specify execution on the
trailing edge of the timeout.
- * @returns {Function} Returns the new throttled function.
- * @example
- *
- * // avoid excessively updating the position while scrolling
- * var throttled = _.throttle(updatePosition, 100);
- * jQuery(window).on('scroll', throttled);
- *
- * // execute `renewToken` when the click event is fired, but not more
than once every 5 minutes
- * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
- * 'trailing': false
- * }));
- */
- function throttle(func, wait, options) {
- var leading = true,
- trailing = true;
-
- if (!isFunction(func)) {
- throw new TypeError;
- }
- if (options === false) {
- leading = false;
- } else if (isObject(options)) {
- leading = 'leading' in options ? options.leading : leading;
- trailing = 'trailing' in options ? options.trailing : trailing;
- }
- debounceOptions.leading = leading;
- debounceOptions.maxWait = wait;
- debounceOptions.trailing = trailing;
-
- return debounce(func, wait, debounceOptions);
- }
-
- /**
- * Creates a function that provides `value` to the wrapper function as its
- * first argument. Additional arguments provided to the function are
appended
- * to those provided to the wrapper function. The wrapper is executed with
- * the `this` binding of the created function.
- *
- * @static
- * @memberOf _
- * @category Functions
- * @param {*} value The value to wrap.
- * @param {Function} wrapper The wrapper function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var p = _.wrap(_.escape, function(func, text) {
- * return '<p>' + func(text) + '</p>';
- * });
- *
- * p('Fred, Wilma, & Pebbles');
- * // => '<p>Fred, Wilma, & Pebbles</p>'
- */
- function wrap(value, wrapper) {
- return createWrapper(wrapper, 16, [value]);
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates a function that returns `value`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value The value to return from the new function.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var object = { 'name': 'fred' };
- * var getter = _.constant(object);
- * getter() === object;
- * // => true
- */
- function constant(value) {
- return function() {
- return value;
- };
- }
-
- /**
- * Produces a callback bound to an optional `thisArg`. If `func` is a
property
- * name the created callback will return the property value for a given
element.
- * If `func` is an object the created callback will return `true` for
elements
- * that contain the equivalent object properties, otherwise it will return
`false`.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} [func=identity] The value to convert to a callback.
- * @param {*} [thisArg] The `this` binding of the created callback.
- * @param {number} [argCount] The number of arguments the callback accepts.
- * @returns {Function} Returns a callback function.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // wrap to create custom callback shorthands
- * _.createCallback = _.wrap(_.createCallback, function(func, callback,
thisArg) {
- * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
- * return !match ? func(callback, thisArg) : function(object) {
- * return match[2] == 'gt' ? object[match[1]] > match[3] :
object[match[1]] < match[3];
- * };
- * });
- *
- * _.filter(characters, 'age__gt38');
- * // => [{ 'name': 'fred', 'age': 40 }]
- */
- function createCallback(func, thisArg, argCount) {
- var type = typeof func;
- if (func == null || type == 'function') {
- return baseCreateCallback(func, thisArg, argCount);
- }
- // handle "_.pluck" style callback shorthands
- if (type != 'object') {
- return property(func);
- }
- var props = keys(func),
- key = props[0],
- a = func[key];
-
- // handle "_.where" style callback shorthands
- if (props.length == 1 && a === a && !isObject(a)) {
- // fast path the common case of providing an object with a single
- // property containing a primitive value
- return function(object) {
- var b = object[key];
- return a === b && (a !== 0 || (1 / a == 1 / b));
- };
- }
- return function(object) {
- var length = props.length,
- result = false;
-
- while (length--) {
- if (!(result = baseIsEqual(object[props[length]],
func[props[length]], null, true))) {
- break;
- }
- }
- return result;
- };
- }
-
- /**
- * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding HTML entities.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to escape.
- * @returns {string} Returns the escaped string.
- * @example
- *
- * _.escape('Fred, Wilma, & Pebbles');
- * // => 'Fred, Wilma, & Pebbles'
- */
- function escape(string) {
- return string == null ? '' : String(string).replace(reUnescapedHtml,
escapeHtmlChar);
- }
-
- /**
- * This method returns the first argument provided to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {*} value Any value.
- * @returns {*} Returns `value`.
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.identity(object) === object;
- * // => true
- */
- function identity(value) {
- return value;
- }
-
- /**
- * Adds function properties of a source object to the destination object.
- * If `object` is a function methods will be added to its prototype as
well.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Function|Object} [object=lodash] object The destination object.
- * @param {Object} source The object of functions to add.
- * @param {Object} [options] The options object.
- * @param {boolean} [options.chain=true] Specify whether the functions
added are chainable.
- * @example
- *
- * function capitalize(string) {
- * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
- * }
- *
- * _.mixin({ 'capitalize': capitalize });
- * _.capitalize('fred');
- * // => 'Fred'
- *
- * _('fred').capitalize().value();
- * // => 'Fred'
- *
- * _.mixin({ 'capitalize': capitalize }, { 'chain': false });
- * _('fred').capitalize();
- * // => 'Fred'
- */
- function mixin(object, source, options) {
- var chain = true,
- methodNames = source && functions(source);
-
- if (!source || (!options && !methodNames.length)) {
- if (options == null) {
- options = source;
- }
- ctor = lodashWrapper;
- source = object;
- object = lodash;
- methodNames = functions(source);
- }
- if (options === false) {
- chain = false;
- } else if (isObject(options) && 'chain' in options) {
- chain = options.chain;
- }
- var ctor = object,
- isFunc = isFunction(ctor);
-
- forEach(methodNames, function(methodName) {
- var func = object[methodName] = source[methodName];
- if (isFunc) {
- ctor.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- value = this.__wrapped__,
- args = [value];
-
- push.apply(args, arguments);
- var result = func.apply(object, args);
- if (chain || chainAll) {
- if (value === result && isObject(result)) {
- return this;
- }
- result = new ctor(result);
- result.__chain__ = chainAll;
- }
- return result;
- };
- }
- });
- }
-
- /**
- * Reverts the '_' variable to its previous value and returns a reference
to
- * the `lodash` function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @returns {Function} Returns the `lodash` function.
- * @example
- *
- * var lodash = _.noConflict();
- */
- function noConflict() {
- context._ = oldDash;
- return this;
- }
-
- /**
- * A no-operation function.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var object = { 'name': 'fred' };
- * _.noop(object) === undefined;
- * // => true
- */
- function noop() {
- // no operation performed
- }
-
- /**
- * Gets the number of milliseconds that have elapsed since the Unix epoch
- * (1 January 1970 00:00:00 UTC).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @example
- *
- * var stamp = _.now();
- * _.defer(function() { console.log(_.now() - stamp); });
- * // => logs the number of milliseconds it took for the deferred function
to be called
- */
- var now = isNative(now = Date.now) && now || function() {
- return new Date().getTime();
- };
-
- /**
- * Converts the given value into an integer of the specified radix.
- * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
- * `value` is a hexadecimal, in which case a `radix` of `16` is used.
- *
- * Note: This method avoids differences in native ES3 and ES5 `parseInt`
- * implementations. See http://es5.github.io/#E.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} value The value to parse.
- * @param {number} [radix] The radix used to interpret the value to parse.
- * @returns {number} Returns the new integer value.
- * @example
- *
- * _.parseInt('08');
- * // => 8
- */
- var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt :
function(value, radix) {
- // Firefox < 21 and Opera < 15 follow the ES3 specified implementation
of `parseInt`
- return nativeParseInt(isString(value) ?
value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
- };
-
- /**
- * Creates a "_.pluck" style function, which returns the `key` value of a
- * given object.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} key The name of the property to retrieve.
- * @returns {Function} Returns the new function.
- * @example
- *
- * var characters = [
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'barney', 'age': 36 }
- * ];
- *
- * var getName = _.property('name');
- *
- * _.map(characters, getName);
- * // => ['barney', 'fred']
- *
- * _.sortBy(characters, getName);
- * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
- */
- function property(key) {
- return function(object) {
- return object[key];
- };
- }
-
- /**
- * Produces a random number between `min` and `max` (inclusive). If only
one
- * argument is provided a number between `0` and the given number will be
- * returned. If `floating` is truey or either `min` or `max` are floats a
- * floating-point number will be returned instead of an integer.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} [min=0] The minimum possible value.
- * @param {number} [max=1] The maximum possible value.
- * @param {boolean} [floating=false] Specify returning a floating-point
number.
- * @returns {number} Returns a random number.
- * @example
- *
- * _.random(0, 5);
- * // => an integer between 0 and 5
- *
- * _.random(5);
- * // => also an integer between 0 and 5
- *
- * _.random(5, true);
- * // => a floating-point number between 0 and 5
- *
- * _.random(1.2, 5.2);
- * // => a floating-point number between 1.2 and 5.2
- */
- function random(min, max, floating) {
- var noMin = min == null,
- noMax = max == null;
-
- if (floating == null) {
- if (typeof min == 'boolean' && noMax) {
- floating = min;
- min = 1;
- }
- else if (!noMax && typeof max == 'boolean') {
- floating = max;
- noMax = true;
- }
- }
- if (noMin && noMax) {
- max = 1;
- }
- min = +min || 0;
- if (noMax) {
- max = min;
- min = 0;
- } else {
- max = +max || 0;
- }
- if (floating || min % 1 || max % 1) {
- var rand = nativeRandom();
- return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand
+'').length - 1)))), max);
- }
- return baseRandom(min, max);
- }
-
- /**
- * Resolves the value of property `key` on `object`. If `key` is a function
- * it will be invoked with the `this` binding of `object` and its result
returned,
- * else the property value is returned. If `object` is falsey then
`undefined`
- * is returned.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {Object} object The object to inspect.
- * @param {string} key The name of the property to resolve.
- * @returns {*} Returns the resolved value.
- * @example
- *
- * var object = {
- * 'cheese': 'crumpets',
- * 'stuff': function() {
- * return 'nonsense';
- * }
- * };
- *
- * _.result(object, 'cheese');
- * // => 'crumpets'
- *
- * _.result(object, 'stuff');
- * // => 'nonsense'
- */
- function result(object, key) {
- if (object) {
- var value = object[key];
- return isFunction(value) ? object[key]() : value;
- }
- }
-
- /**
- * A micro-templating method that handles arbitrary delimiters, preserves
- * whitespace, and correctly escapes quotes within interpolated code.
- *
- * Note: In the development build, `_.template` utilizes sourceURLs for
easier
- * debugging. See
http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- *
- * For more information on precompiling templates see:
- * http://lodash.com/custom-builds
- *
- * For more information on Chrome extension sandboxes see:
- * http://developer.chrome.com/stable/extensions/sandboxingEval.html
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} text The template text.
- * @param {Object} data The data object used to populate the text.
- * @param {Object} [options] The options object.
- * @param {RegExp} [options.escape] The "escape" delimiter.
- * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
- * @param {Object} [options.imports] An object to import into the template
as local variables.
- * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
- * @param {string} [sourceURL] The sourceURL of the template's compiled
source.
- * @param {string} [variable] The data object variable name.
- * @returns {Function|string} Returns a compiled function when no `data`
object
- * is given, else it returns the interpolated text.
- * @example
- *
- * // using the "interpolate" delimiter to create a compiled template
- * var compiled = _.template('hello <%= name %>');
- * compiled({ 'name': 'fred' });
- * // => 'hello fred'
- *
- * // using the "escape" delimiter to escape HTML in data property values
- * _.template('<b><%- value %></b>', { 'value': '<script>' });
- * // => '<b><script></b>'
- *
- * // using the "evaluate" delimiter to generate HTML
- * var list = '<% _.forEach(people, function(name) { %><li><%- name
%></li><% }); %>';
- * _.template(list, { 'people': ['fred', 'barney'] });
- * // => '<li>fred</li><li>barney</li>'
- *
- * // using the ES6 delimiter as an alternative to the default
"interpolate" delimiter
- * _.template('hello ${ name }', { 'name': 'pebbles' });
- * // => 'hello pebbles'
- *
- * // using the internal `print` function in "evaluate" delimiters
- * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
- * // => 'hello barney!'
- *
- * // using a custom template delimiters
- * _.templateSettings = {
- * 'interpolate': /{{([\s\S]+?)}}/g
- * };
- *
- * _.template('hello {{ name }}!', { 'name': 'mustache' });
- * // => 'hello mustache!'
- *
- * // using the `imports` option to import jQuery
- * var list = '<% jq.each(people, function(name) { %><li><%- name
%></li><% }); %>';
- * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq':
jQuery } });
- * // => '<li>fred</li><li>barney</li>'
- *
- * // using the `sourceURL` option to specify a custom sourceURL for the
template
- * var compiled = _.template('hello <%= name %>', null, { 'sourceURL':
'/basic/greeting.jst' });
- * compiled(data);
- * // => find the source of "greeting.jst" under the Sources tab or
Resources panel of the web inspector
- *
- * // using the `variable` option to ensure a with-statement isn't used in
the compiled template
- * var compiled = _.template('hi <%= data.name %>!', null, { 'variable':
'data' });
- * compiled.source;
- * // => function(data) {
- * var __t, __p = '', __e = _.escape;
- * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
- * return __p;
- * }
- *
- * // using the `source` property to inline compiled templates for
meaningful
- * // line numbers in error messages and a stack trace
- * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
- * var JST = {\
- * "main": ' + _.template(mainText).source + '\
- * };\
- * ');
- */
- function template(text, data, options) {
- // based on John Resig's `tmpl` implementation
- // http://ejohn.org/blog/javascript-micro-templating/
- // and Laura Doktorova's doT.js
- // https://github.com/olado/doT
- var settings = lodash.templateSettings;
- text = String(text || '');
-
- // avoid missing dependencies when `iteratorTemplate` is not defined
- options = defaults({}, options, settings);
-
- var imports = defaults({}, options.imports, settings.imports),
- importsKeys = keys(imports),
- importsValues = values(imports);
-
- var isEvaluating,
- index = 0,
- interpolate = options.interpolate || reNoMatch,
- source = "__p += '";
-
- // compile the regexp to match each delimiter
- var reDelimiters = RegExp(
- (options.escape || reNoMatch).source + '|' +
- interpolate.source + '|' +
- (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source +
'|' +
- (options.evaluate || reNoMatch).source + '|$'
- , 'g');
-
- text.replace(reDelimiters, function(match, escapeValue,
interpolateValue, esTemplateValue, evaluateValue, offset) {
- interpolateValue || (interpolateValue = esTemplateValue);
-
- // escape characters that cannot be included in string literals
- source += text.slice(index, offset).replace(reUnescapedString,
escapeStringChar);
-
- // replace delimiters with snippets
- if (escapeValue) {
- source += "' +\n__e(" + escapeValue + ") +\n'";
- }
- if (evaluateValue) {
- isEvaluating = true;
- source += "';\n" + evaluateValue + ";\n__p += '";
- }
- if (interpolateValue) {
- source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' :
__t) +\n'";
- }
- index = offset + match.length;
-
- // the JS engine embedded in Adobe products requires returning the
`match`
- // string in order to produce the correct `offset` value
- return match;
- });
-
- source += "';\n";
-
- // if `variable` is not specified, wrap a with-statement around the
generated
- // code to add the data object to the top of the scope chain
- var variable = options.variable,
- hasVariable = variable;
-
- if (!hasVariable) {
- variable = 'obj';
- source = 'with (' + variable + ') {\n' + source + '\n}\n';
- }
- // cleanup code by stripping empty strings
- source = (isEvaluating ? source.replace(reEmptyStringLeading, '') :
source)
- .replace(reEmptyStringMiddle, '$1')
- .replace(reEmptyStringTrailing, '$1;');
-
- // frame code as the function body
- source = 'function(' + variable + ') {\n' +
- (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
- "var __t, __p = '', __e = _.escape" +
- (isEvaluating
- ? ', __j = Array.prototype.join;\n' +
- "function print() { __p += __j.call(arguments, '') }\n"
- : ';\n'
- ) +
- source +
- 'return __p\n}';
-
- // Use a sourceURL for easier debugging.
- //
http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
- var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL ||
'/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
-
- try {
- var result = Function(importsKeys, 'return ' + source +
sourceURL).apply(undefined, importsValues);
- } catch(e) {
- e.source = source;
- throw e;
- }
- if (data) {
- return result(data);
- }
- // provide the compiled function's source by its `toString` method, in
- // supported environments, or the `source` property as a convenience for
- // inlining compiled templates during the build process
- result.source = source;
- return result;
- }
-
- /**
- * Executes the callback `n` times, returning an array of the results
- * of each callback execution. The callback is bound to `thisArg` and
invoked
- * with one argument; (index).
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {number} n The number of times to execute the callback.
- * @param {Function} callback The function called per iteration.
- * @param {*} [thisArg] The `this` binding of `callback`.
- * @returns {Array} Returns an array of the results of each `callback`
execution.
- * @example
- *
- * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
- * // => [3, 6, 4]
- *
- * _.times(3, function(n) { mage.castSpell(n); });
- * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`,
and `2` respectively
- *
- * _.times(3, function(n) { this.cast(n); }, mage);
- * // => also calls `mage.castSpell(n)` three times
- */
- function times(n, callback, thisArg) {
- n = (n = +n) > -1 ? n : 0;
- var index = -1,
- result = Array(n);
-
- callback = baseCreateCallback(callback, thisArg, 1);
- while (++index < n) {
- result[index] = callback(index);
- }
- return result;
- }
-
- /**
- * The inverse of `_.escape` this method converts the HTML entities
- * `&`, `<`, `>`, `"`, and `'` in `string` to their
- * corresponding characters.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} string The string to unescape.
- * @returns {string} Returns the unescaped string.
- * @example
- *
- * _.unescape('Fred, Barney & Pebbles');
- * // => 'Fred, Barney & Pebbles'
- */
- function unescape(string) {
- return string == null ? '' : String(string).replace(reEscapedHtml,
unescapeHtmlChar);
- }
-
- /**
- * Generates a unique ID. If `prefix` is provided the ID will be appended
to it.
- *
- * @static
- * @memberOf _
- * @category Utilities
- * @param {string} [prefix] The value to prefix the ID with.
- * @returns {string} Returns the unique ID.
- * @example
- *
- * _.uniqueId('contact_');
- * // => 'contact_104'
- *
- * _.uniqueId();
- * // => '105'
- */
- function uniqueId(prefix) {
- var id = ++idCounter;
- return String(prefix == null ? '' : prefix) + id;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * Creates a `lodash` object that wraps the given value with explicit
- * method chaining enabled.
- *
- * @static
- * @memberOf _
- * @category Chaining
- * @param {*} value The value to wrap.
- * @returns {Object} Returns the wrapper object.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 },
- * { 'name': 'pebbles', 'age': 1 }
- * ];
- *
- * var youngest = _.chain(characters)
- * .sortBy('age')
- * .map(function(chr) { return chr.name + ' is ' + chr.age; })
- * .first()
- * .value();
- * // => 'pebbles is 1'
- */
- function chain(value) {
- value = new lodashWrapper(value);
- value.__chain__ = true;
- return value;
- }
-
- /**
- * Invokes `interceptor` with the `value` as the first argument and then
- * returns `value`. The purpose of this method is to "tap into" a method
- * chain in order to perform operations on intermediate results within
- * the chain.
- *
- * @static
- * @memberOf _
- * @category Chaining
- * @param {*} value The value to provide to `interceptor`.
- * @param {Function} interceptor The function to invoke.
- * @returns {*} Returns `value`.
- * @example
- *
- * _([1, 2, 3, 4])
- * .tap(function(array) { array.pop(); })
- * .reverse()
- * .value();
- * // => [3, 2, 1]
- */
- function tap(value, interceptor) {
- interceptor(value);
- return value;
- }
-
- /**
- * Enables explicit method chaining on the wrapper object.
- *
- * @name chain
- * @memberOf _
- * @category Chaining
- * @returns {*} Returns the wrapper object.
- * @example
- *
- * var characters = [
- * { 'name': 'barney', 'age': 36 },
- * { 'name': 'fred', 'age': 40 }
- * ];
- *
- * // without explicit chaining
- * _(characters).first();
- * // => { 'name': 'barney', 'age': 36 }
- *
- * // with explicit chaining
- * _(characters).chain()
- * .first()
- * .pick('age')
- * .value();
- * // => { 'age': 36 }
- */
- function wrapperChain() {
- this.__chain__ = true;
- return this;
- }
-
- /**
- * Produces the `toString` result of the wrapped value.
- *
- * @name toString
- * @memberOf _
- * @category Chaining
- * @returns {string} Returns the string result.
- * @example
- *
- * _([1, 2, 3]).toString();
- * // => '1,2,3'
- */
- function wrapperToString() {
- return String(this.__wrapped__);
- }
-
- /**
- * Extracts the wrapped value.
- *
- * @name valueOf
- * @memberOf _
- * @alias value
- * @category Chaining
- * @returns {*} Returns the wrapped value.
- * @example
- *
- * _([1, 2, 3]).valueOf();
- * // => [1, 2, 3]
- */
- function wrapperValueOf() {
- return this.__wrapped__;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- // add functions that return wrapped values when chaining
- lodash.after = after;
- lodash.assign = assign;
- lodash.at = at;
- lodash.bind = bind;
- lodash.bindAll = bindAll;
- lodash.bindKey = bindKey;
- lodash.chain = chain;
- lodash.compact = compact;
- lodash.compose = compose;
- lodash.constant = constant;
- lodash.countBy = countBy;
- lodash.create = create;
- lodash.createCallback = createCallback;
- lodash.curry = curry;
- lodash.debounce = debounce;
- lodash.defaults = defaults;
- lodash.defer = defer;
- lodash.delay = delay;
- lodash.difference = difference;
- lodash.filter = filter;
- lodash.flatten = flatten;
- lodash.forEach = forEach;
- lodash.forEachRight = forEachRight;
- lodash.forIn = forIn;
- lodash.forInRight = forInRight;
- lodash.forOwn = forOwn;
- lodash.forOwnRight = forOwnRight;
- lodash.functions = functions;
- lodash.groupBy = groupBy;
- lodash.indexBy = indexBy;
- lodash.initial = initial;
- lodash.intersection = intersection;
- lodash.invert = invert;
- lodash.invoke = invoke;
- lodash.keys = keys;
- lodash.map = map;
- lodash.mapValues = mapValues;
- lodash.max = max;
- lodash.memoize = memoize;
- lodash.merge = merge;
- lodash.min = min;
- lodash.omit = omit;
- lodash.once = once;
- lodash.pairs = pairs;
- lodash.partial = partial;
- lodash.partialRight = partialRight;
- lodash.pick = pick;
- lodash.pluck = pluck;
- lodash.property = property;
- lodash.pull = pull;
- lodash.range = range;
- lodash.reject = reject;
- lodash.remove = remove;
- lodash.rest = rest;
- lodash.shuffle = shuffle;
- lodash.sortBy = sortBy;
- lodash.tap = tap;
- lodash.throttle = throttle;
- lodash.times = times;
- lodash.toArray = toArray;
- lodash.transform = transform;
- lodash.union = union;
- lodash.uniq = uniq;
- lodash.values = values;
- lodash.where = where;
- lodash.without = without;
- lodash.wrap = wrap;
- lodash.xor = xor;
- lodash.zip = zip;
- lodash.zipObject = zipObject;
-
- // add aliases
- lodash.collect = map;
- lodash.drop = rest;
- lodash.each = forEach;
- lodash.eachRight = forEachRight;
- lodash.extend = assign;
- lodash.methods = functions;
- lodash.object = zipObject;
- lodash.select = filter;
- lodash.tail = rest;
- lodash.unique = uniq;
- lodash.unzip = zip;
-
- // add functions to `lodash.prototype`
- mixin(lodash);
-
-
/*--------------------------------------------------------------------------*/
-
- // add functions that return unwrapped values when chaining
- lodash.clone = clone;
- lodash.cloneDeep = cloneDeep;
- lodash.contains = contains;
- lodash.escape = escape;
- lodash.every = every;
- lodash.find = find;
- lodash.findIndex = findIndex;
- lodash.findKey = findKey;
- lodash.findLast = findLast;
- lodash.findLastIndex = findLastIndex;
- lodash.findLastKey = findLastKey;
- lodash.has = has;
- lodash.identity = identity;
- lodash.indexOf = indexOf;
- lodash.isArguments = isArguments;
- lodash.isArray = isArray;
- lodash.isBoolean = isBoolean;
- lodash.isDate = isDate;
- lodash.isElement = isElement;
- lodash.isEmpty = isEmpty;
- lodash.isEqual = isEqual;
- lodash.isFinite = isFinite;
- lodash.isFunction = isFunction;
- lodash.isNaN = isNaN;
- lodash.isNull = isNull;
- lodash.isNumber = isNumber;
- lodash.isObject = isObject;
- lodash.isPlainObject = isPlainObject;
- lodash.isRegExp = isRegExp;
- lodash.isString = isString;
- lodash.isUndefined = isUndefined;
- lodash.lastIndexOf = lastIndexOf;
- lodash.mixin = mixin;
- lodash.noConflict = noConflict;
- lodash.noop = noop;
- lodash.now = now;
- lodash.parseInt = parseInt;
- lodash.random = random;
- lodash.reduce = reduce;
- lodash.reduceRight = reduceRight;
- lodash.result = result;
- lodash.runInContext = runInContext;
- lodash.size = size;
- lodash.some = some;
- lodash.sortedIndex = sortedIndex;
- lodash.template = template;
- lodash.unescape = unescape;
- lodash.uniqueId = uniqueId;
-
- // add aliases
- lodash.all = every;
- lodash.any = some;
- lodash.detect = find;
- lodash.findWhere = find;
- lodash.foldl = reduce;
- lodash.foldr = reduceRight;
- lodash.include = contains;
- lodash.inject = reduce;
-
- mixin(function() {
- var source = {}
- forOwn(lodash, function(func, methodName) {
- if (!lodash.prototype[methodName]) {
- source[methodName] = func;
- }
- });
- return source;
- }(), false);
-
-
/*--------------------------------------------------------------------------*/
-
- // add functions capable of returning wrapped and unwrapped values when
chaining
- lodash.first = first;
- lodash.last = last;
- lodash.sample = sample;
-
- // add aliases
- lodash.take = first;
- lodash.head = first;
-
- forOwn(lodash, function(func, methodName) {
- var callbackable = methodName !== 'sample';
- if (!lodash.prototype[methodName]) {
- lodash.prototype[methodName]= function(n, guard) {
- var chainAll = this.__chain__,
- result = func(this.__wrapped__, n, guard);
-
- return !chainAll && (n == null || (guard && !(callbackable && typeof
n == 'function')))
- ? result
- : new lodashWrapper(result, chainAll);
- };
- }
- });
-
-
/*--------------------------------------------------------------------------*/
-
- /**
- * The semantic version number.
- *
- * @static
- * @memberOf _
- * @type string
- */
- lodash.VERSION = '2.4.1';
-
- // add "Chaining" functions to the wrapper
- lodash.prototype.chain = wrapperChain;
- lodash.prototype.toString = wrapperToString;
- lodash.prototype.value = wrapperValueOf;
- lodash.prototype.valueOf = wrapperValueOf;
-
- // add `Array` functions that return unwrapped values
- forEach(['join', 'pop', 'shift'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- var chainAll = this.__chain__,
- result = func.apply(this.__wrapped__, arguments);
-
- return chainAll
- ? new lodashWrapper(result, chainAll)
- : result;
- };
- });
-
- // add `Array` functions that return the existing wrapped value
- forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- func.apply(this.__wrapped__, arguments);
- return this;
- };
- });
-
- // add `Array` functions that return new wrapped values
- forEach(['concat', 'slice', 'splice'], function(methodName) {
- var func = arrayRef[methodName];
- lodash.prototype[methodName] = function() {
- return new lodashWrapper(func.apply(this.__wrapped__, arguments),
this.__chain__);
- };
- });
-
- return lodash;
- }
-
-
/*--------------------------------------------------------------------------*/
-
- // expose Lo-Dash
- var _ = runInContext();
-
- // some AMD build optimizers like r.js check for condition patterns like the
following:
- if (typeof define == 'function' && typeof define.amd == 'object' &&
define.amd) {
- // Expose Lo-Dash to the global object even when an AMD loader is present
in
- // case Lo-Dash is loaded with a RequireJS shim config.
- // See http://requirejs.org/docs/api.html#config-shim
- root._ = _;
-
- // define as an anonymous module so, through path mapping, it can be
- // referenced as the "underscore" module
- define(function() {
- return _;
- });
- }
- // check for `exports` after `define` in case a build optimizer adds an
`exports` object
- else if (freeExports && freeModule) {
- // in Node.js or RingoJS
- if (moduleExports) {
- (freeModule.exports = _)._ = _;
- }
- // in Narwhal or Rhino -require
- else {
- freeExports._ = _;
- }
- }
- else {
- // in a browser or Rhino
- root._ = _;
- }
-}.call(this));
diff --git a/packages/context-coloring/fixtures/benchmark/mkdirp-0.5.0.js
b/packages/context-coloring/fixtures/benchmark/mkdirp-0.5.0.js
deleted file mode 100644
index a1742b2..0000000
--- a/packages/context-coloring/fixtures/benchmark/mkdirp-0.5.0.js
+++ /dev/null
@@ -1,97 +0,0 @@
-var path = require('path');
-var fs = require('fs');
-
-module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
-
-function mkdirP (p, opts, f, made) {
- if (typeof opts === 'function') {
- f = opts;
- opts = {};
- }
- else if (!opts || typeof opts !== 'object') {
- opts = { mode: opts };
- }
-
- var mode = opts.mode;
- var xfs = opts.fs || fs;
-
- if (mode === undefined) {
- mode = 0777 & (~process.umask());
- }
- if (!made) made = null;
-
- var cb = f || function () {};
- p = path.resolve(p);
-
- xfs.mkdir(p, mode, function (er) {
- if (!er) {
- made = made || p;
- return cb(null, made);
- }
- switch (er.code) {
- case 'ENOENT':
- mkdirP(path.dirname(p), opts, function (er, made) {
- if (er) cb(er, made);
- else mkdirP(p, opts, cb, made);
- });
- break;
-
- // In the case of any other error, just see if there's a dir
- // there already. If so, then hooray! If not, then something
- // is borked.
- default:
- xfs.stat(p, function (er2, stat) {
- // if the stat fails, then that's super weird.
- // let the original error be the failure reason.
- if (er2 || !stat.isDirectory()) cb(er, made)
- else cb(null, made);
- });
- break;
- }
- });
-}
-
-mkdirP.sync = function sync (p, opts, made) {
- if (!opts || typeof opts !== 'object') {
- opts = { mode: opts };
- }
-
- var mode = opts.mode;
- var xfs = opts.fs || fs;
-
- if (mode === undefined) {
- mode = 0777 & (~process.umask());
- }
- if (!made) made = null;
-
- p = path.resolve(p);
-
- try {
- xfs.mkdirSync(p, mode);
- made = made || p;
- }
- catch (err0) {
- switch (err0.code) {
- case 'ENOENT' :
- made = sync(path.dirname(p), opts, made);
- sync(p, opts, made);
- break;
-
- // In the case of any other error, just see if there's a dir
- // there already. If so, then hooray! If not, then something
- // is borked.
- default:
- var stat;
- try {
- stat = xfs.statSync(p);
- }
- catch (err1) {
- throw err0;
- }
- if (!stat.isDirectory()) throw err0;
- break;
- }
- }
-
- return made;
-};
diff --git a/packages/context-coloring/fixtures/benchmark/simple.el
b/packages/context-coloring/fixtures/benchmark/simple.el
deleted file mode 100644
index 5e5cd87..0000000
--- a/packages/context-coloring/fixtures/benchmark/simple.el
+++ /dev/null
@@ -1,7901 +0,0 @@
-;;; simple.el --- basic editing commands for Emacs -*- lexical-binding: t -*-
-
-;; Copyright (C) 1985-1987, 1993-2015 Free Software Foundation, Inc.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: internal
-;; Package: emacs
-
-;; 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:
-
-;; A grab-bag of basic Emacs commands not specifically related to some
-;; major mode or to file-handling.
-
-;;; Code:
-
-(eval-when-compile (require 'cl-lib))
-
-(declare-function widget-convert "wid-edit" (type &rest args))
-(declare-function shell-mode "shell" ())
-
-;;; From compile.el
-(defvar compilation-current-error)
-(defvar compilation-context-lines)
-
-(defcustom idle-update-delay 0.5
- "Idle time delay before updating various things on the screen.
-Various Emacs features that update auxiliary information when point moves
-wait this many seconds after Emacs becomes idle before doing an update."
- :type 'number
- :group 'display
- :version "22.1")
-
-(defgroup killing nil
- "Killing and yanking commands."
- :group 'editing)
-
-(defgroup paren-matching nil
- "Highlight (un)matching of parens and expressions."
- :group 'matching)
-
-;;; next-error support framework
-
-(defgroup next-error nil
- "`next-error' support framework."
- :group 'compilation
- :version "22.1")
-
-(defface next-error
- '((t (:inherit region)))
- "Face used to highlight next error locus."
- :group 'next-error
- :version "22.1")
-
-(defcustom next-error-highlight 0.5
- "Highlighting of locations in selected source buffers.
-If a number, highlight the locus in `next-error' face for the given time
-in seconds, or until the next command is executed.
-If t, highlight the locus until the next command is executed, or until
-some other locus replaces it.
-If nil, don't highlight the locus in the source buffer.
-If `fringe-arrow', indicate the locus by the fringe arrow
-indefinitely until some other locus replaces it."
- :type '(choice (number :tag "Highlight for specified time")
- (const :tag "Semipermanent highlighting" t)
- (const :tag "No highlighting" nil)
- (const :tag "Fringe arrow" fringe-arrow))
- :group 'next-error
- :version "22.1")
-
-(defcustom next-error-highlight-no-select 0.5
- "Highlighting of locations in `next-error-no-select'.
-If number, highlight the locus in `next-error' face for given time in seconds.
-If t, highlight the locus indefinitely until some other locus replaces it.
-If nil, don't highlight the locus in the source buffer.
-If `fringe-arrow', indicate the locus by the fringe arrow
-indefinitely until some other locus replaces it."
- :type '(choice (number :tag "Highlight for specified time")
- (const :tag "Semipermanent highlighting" t)
- (const :tag "No highlighting" nil)
- (const :tag "Fringe arrow" fringe-arrow))
- :group 'next-error
- :version "22.1")
-
-(defcustom next-error-recenter nil
- "Display the line in the visited source file recentered as specified.
-If non-nil, the value is passed directly to `recenter'."
- :type '(choice (integer :tag "Line to recenter to")
- (const :tag "Center of window" (4))
- (const :tag "No recentering" nil))
- :group 'next-error
- :version "23.1")
-
-(defcustom next-error-hook nil
- "List of hook functions run by `next-error' after visiting source file."
- :type 'hook
- :group 'next-error)
-
-(defvar next-error-highlight-timer nil)
-
-(defvar next-error-overlay-arrow-position nil)
-(put 'next-error-overlay-arrow-position 'overlay-arrow-string (purecopy "=>"))
-(add-to-list 'overlay-arrow-variable-list 'next-error-overlay-arrow-position)
-
-(defvar next-error-last-buffer nil
- "The most recent `next-error' buffer.
-A buffer becomes most recent when its compilation, grep, or
-similar mode is started, or when it is used with \\[next-error]
-or \\[compile-goto-error].")
-
-(defvar next-error-function nil
- "Function to use to find the next error in the current buffer.
-The function is called with 2 parameters:
-ARG is an integer specifying by how many errors to move.
-RESET is a boolean which, if non-nil, says to go back to the beginning
-of the errors before moving.
-Major modes providing compile-like functionality should set this variable
-to indicate to `next-error' that this is a candidate buffer and how
-to navigate in it.")
-(make-variable-buffer-local 'next-error-function)
-
-(defvar next-error-move-function nil
- "Function to use to move to an error locus.
-It takes two arguments, a buffer position in the error buffer
-and a buffer position in the error locus buffer.
-The buffer for the error locus should already be current.
-nil means use goto-char using the second argument position.")
-(make-variable-buffer-local 'next-error-move-function)
-
-(defsubst next-error-buffer-p (buffer
- &optional avoid-current
- extra-test-inclusive
- extra-test-exclusive)
- "Test if BUFFER is a `next-error' capable buffer.
-
-If AVOID-CURRENT is non-nil, treat the current buffer
-as an absolute last resort only.
-
-The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
-that normally would not qualify. If it returns t, the buffer
-in question is treated as usable.
-
-The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
-that would normally be considered usable. If it returns nil,
-that buffer is rejected."
- (and (buffer-name buffer) ;First make sure it's live.
- (not (and avoid-current (eq buffer (current-buffer))))
- (with-current-buffer buffer
- (if next-error-function ; This is the normal test.
- ;; Optionally reject some buffers.
- (if extra-test-exclusive
- (funcall extra-test-exclusive)
- t)
- ;; Optionally accept some other buffers.
- (and extra-test-inclusive
- (funcall extra-test-inclusive))))))
-
-(defun next-error-find-buffer (&optional avoid-current
- extra-test-inclusive
- extra-test-exclusive)
- "Return a `next-error' capable buffer.
-
-If AVOID-CURRENT is non-nil, treat the current buffer
-as an absolute last resort only.
-
-The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
-that normally would not qualify. If it returns t, the buffer
-in question is treated as usable.
-
-The function EXTRA-TEST-EXCLUSIVE, if non-nil, is called in each buffer
-that would normally be considered usable. If it returns nil,
-that buffer is rejected."
- (or
- ;; 1. If one window on the selected frame displays such buffer, return it.
- (let ((window-buffers
- (delete-dups
- (delq nil (mapcar (lambda (w)
- (if (next-error-buffer-p
- (window-buffer w)
- avoid-current
- extra-test-inclusive extra-test-exclusive)
- (window-buffer w)))
- (window-list))))))
- (if (eq (length window-buffers) 1)
- (car window-buffers)))
- ;; 2. If next-error-last-buffer is an acceptable buffer, use that.
- (if (and next-error-last-buffer
- (next-error-buffer-p next-error-last-buffer avoid-current
- extra-test-inclusive extra-test-exclusive))
- next-error-last-buffer)
- ;; 3. If the current buffer is acceptable, choose it.
- (if (next-error-buffer-p (current-buffer) avoid-current
- extra-test-inclusive extra-test-exclusive)
- (current-buffer))
- ;; 4. Look for any acceptable buffer.
- (let ((buffers (buffer-list)))
- (while (and buffers
- (not (next-error-buffer-p
- (car buffers) avoid-current
- extra-test-inclusive extra-test-exclusive)))
- (setq buffers (cdr buffers)))
- (car buffers))
- ;; 5. Use the current buffer as a last resort if it qualifies,
- ;; even despite AVOID-CURRENT.
- (and avoid-current
- (next-error-buffer-p (current-buffer) nil
- extra-test-inclusive extra-test-exclusive)
- (progn
- (message "This is the only buffer with error message locations")
- (current-buffer)))
- ;; 6. Give up.
- (error "No buffers contain error message locations")))
-
-(defun next-error (&optional arg reset)
- "Visit next `next-error' message and corresponding source code.
-
-If all the error messages parsed so far have been processed already,
-the message buffer is checked for new ones.
-
-A prefix ARG specifies how many error messages to move;
-negative means move back to previous error messages.
-Just \\[universal-argument] as a prefix means reparse the error message buffer
-and start at the first error.
-
-The RESET argument specifies that we should restart from the beginning.
-
-\\[next-error] normally uses the most recently started
-compilation, grep, or occur buffer. It can also operate on any
-buffer with output from the \\[compile], \\[grep] commands, or,
-more generally, on any buffer in Compilation mode or with
-Compilation Minor mode enabled, or any buffer in which
-`next-error-function' is bound to an appropriate function.
-To specify use of a particular buffer for error messages, type
-\\[next-error] in that buffer when it is the only one displayed
-in the current frame.
-
-Once \\[next-error] has chosen the buffer for error messages, it
-runs `next-error-hook' with `run-hooks', and stays with that buffer
-until you use it in some other buffer which uses Compilation mode
-or Compilation Minor mode.
-
-To control which errors are matched, customize the variable
-`compilation-error-regexp-alist'."
- (interactive "P")
- (if (consp arg) (setq reset t arg nil))
- (when (setq next-error-last-buffer (next-error-find-buffer))
- ;; we know here that next-error-function is a valid symbol we can funcall
- (with-current-buffer next-error-last-buffer
- (funcall next-error-function (prefix-numeric-value arg) reset)
- (when next-error-recenter
- (recenter next-error-recenter))
- (run-hooks 'next-error-hook))))
-
-(defun next-error-internal ()
- "Visit the source code corresponding to the `next-error' message at point."
- (setq next-error-last-buffer (current-buffer))
- ;; we know here that next-error-function is a valid symbol we can funcall
- (with-current-buffer next-error-last-buffer
- (funcall next-error-function 0 nil)
- (when next-error-recenter
- (recenter next-error-recenter))
- (run-hooks 'next-error-hook)))
-
-(defalias 'goto-next-locus 'next-error)
-(defalias 'next-match 'next-error)
-
-(defun previous-error (&optional n)
- "Visit previous `next-error' message and corresponding source code.
-
-Prefix arg N says how many error messages to move backwards (or
-forwards, if negative).
-
-This operates on the output from the \\[compile] and \\[grep] commands."
- (interactive "p")
- (next-error (- (or n 1))))
-
-(defun first-error (&optional n)
- "Restart at the first error.
-Visit corresponding source code.
-With prefix arg N, visit the source code of the Nth error.
-This operates on the output from the \\[compile] command, for instance."
- (interactive "p")
- (next-error n t))
-
-(defun next-error-no-select (&optional n)
- "Move point to the next error in the `next-error' buffer and highlight match.
-Prefix arg N says how many error messages to move forwards (or
-backwards, if negative).
-Finds and highlights the source line like \\[next-error], but does not
-select the source buffer."
- (interactive "p")
- (let ((next-error-highlight next-error-highlight-no-select))
- (next-error n))
- (pop-to-buffer next-error-last-buffer))
-
-(defun previous-error-no-select (&optional n)
- "Move point to the previous error in the `next-error' buffer and highlight
match.
-Prefix arg N says how many error messages to move backwards (or
-forwards, if negative).
-Finds and highlights the source line like \\[previous-error], but does not
-select the source buffer."
- (interactive "p")
- (next-error-no-select (- (or n 1))))
-
-;; Internal variable for `next-error-follow-mode-post-command-hook'.
-(defvar next-error-follow-last-line nil)
-
-(define-minor-mode next-error-follow-minor-mode
- "Minor mode for compilation, occur and diff modes.
-With a prefix argument ARG, enable mode if ARG is positive, and
-disable it otherwise. If called from Lisp, enable mode if ARG is
-omitted or nil.
-When turned on, cursor motion in the compilation, grep, occur or diff
-buffer causes automatic display of the corresponding source code location."
- :group 'next-error :init-value nil :lighter " Fol"
- (if (not next-error-follow-minor-mode)
- (remove-hook 'post-command-hook
'next-error-follow-mode-post-command-hook t)
- (add-hook 'post-command-hook 'next-error-follow-mode-post-command-hook nil
t)
- (make-local-variable 'next-error-follow-last-line)))
-
-;; Used as a `post-command-hook' by `next-error-follow-mode'
-;; for the *Compilation* *grep* and *Occur* buffers.
-(defun next-error-follow-mode-post-command-hook ()
- (unless (equal next-error-follow-last-line (line-number-at-pos))
- (setq next-error-follow-last-line (line-number-at-pos))
- (condition-case nil
- (let ((compilation-context-lines nil))
- (setq compilation-current-error (point))
- (next-error-no-select 0))
- (error t))))
-
-
-;;;
-
-(defun fundamental-mode ()
- "Major mode not specialized for anything in particular.
-Other major modes are defined by comparison with this one."
- (interactive)
- (kill-all-local-variables)
- (run-mode-hooks))
-
-;; Special major modes to view specially formatted data rather than files.
-
-(defvar special-mode-map
- (let ((map (make-sparse-keymap)))
- (suppress-keymap map)
- (define-key map "q" 'quit-window)
- (define-key map " " 'scroll-up-command)
- (define-key map [?\S-\ ] 'scroll-down-command)
- (define-key map "\C-?" 'scroll-down-command)
- (define-key map "?" 'describe-mode)
- (define-key map "h" 'describe-mode)
- (define-key map ">" 'end-of-buffer)
- (define-key map "<" 'beginning-of-buffer)
- (define-key map "g" 'revert-buffer)
- map))
-
-(put 'special-mode 'mode-class 'special)
-(define-derived-mode special-mode nil "Special"
- "Parent major mode from which special major modes should inherit."
- (setq buffer-read-only t))
-
-;; Making and deleting lines.
-
-(defvar self-insert-uses-region-functions nil
- "Special hook to tell if `self-insert-command' will use the region.
-It must be called via `run-hook-with-args-until-success' with no arguments.
-Any `post-self-insert-command' which consumes the region should
-register a function on this hook so that things like `delete-selection-mode'
-can refrain from consuming the region.")
-
-(defvar hard-newline (propertize "\n" 'hard t 'rear-nonsticky '(hard))
- "Propertized string representing a hard newline character.")
-
-(defun newline (&optional arg interactive)
- "Insert a newline, and move to left margin of the new line if it's blank.
-If option `use-hard-newlines' is non-nil, the newline is marked with the
-text-property `hard'.
-With ARG, insert that many newlines.
-
-If `electric-indent-mode' is enabled, this indents the final new line
-that it adds, and reindents the preceding line. To just insert
-a newline, use \\[electric-indent-just-newline].
-
-Calls `auto-fill-function' if the current column number is greater
-than the value of `fill-column' and ARG is nil.
-A non-nil INTERACTIVE argument means to run the `post-self-insert-hook'."
- (interactive "*P\np")
- (barf-if-buffer-read-only)
- ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
- ;; Set last-command-event to tell self-insert what to insert.
- (let* ((was-page-start (and (bolp) (looking-at page-delimiter)))
- (beforepos (point))
- (last-command-event ?\n)
- ;; Don't auto-fill if we have a numeric argument.
- (auto-fill-function (if arg nil auto-fill-function))
- (postproc
- ;; Do the rest in post-self-insert-hook, because we want to do it
- ;; *before* other functions on that hook.
- (lambda ()
- (cl-assert (eq ?\n (char-before)))
- ;; Mark the newline(s) `hard'.
- (if use-hard-newlines
- (set-hard-newline-properties
- (- (point) (prefix-numeric-value arg)) (point)))
- ;; If the newline leaves the previous line blank, and we
- ;; have a left margin, delete that from the blank line.
- (save-excursion
- (goto-char beforepos)
- (beginning-of-line)
- (and (looking-at "[ \t]$")
- (> (current-left-margin) 0)
- (delete-region (point)
- (line-end-position))))
- ;; Indent the line after the newline, except in one case:
- ;; when we added the newline at the beginning of a line which
- ;; starts a page.
- (or was-page-start
- (move-to-left-margin nil t)))))
- (unwind-protect
- (if (not interactive)
- ;; FIXME: For non-interactive uses, many calls actually just want
- ;; (insert "\n"), so maybe we should do just that, so as to avoid
- ;; the risk of filling or running abbrevs unexpectedly.
- (let ((post-self-insert-hook (list postproc)))
- (self-insert-command (prefix-numeric-value arg)))
- (unwind-protect
- (progn
- (add-hook 'post-self-insert-hook postproc nil t)
- (self-insert-command (prefix-numeric-value arg)))
- ;; We first used let-binding to protect the hook, but that was naive
- ;; since add-hook affects the symbol-default value of the variable,
- ;; whereas the let-binding might only protect the buffer-local value.
- (remove-hook 'post-self-insert-hook postproc t)))
- (cl-assert (not (member postproc post-self-insert-hook)))
- (cl-assert (not (member postproc (default-value
'post-self-insert-hook))))))
- nil)
-
-(defun set-hard-newline-properties (from to)
- (let ((sticky (get-text-property from 'rear-nonsticky)))
- (put-text-property from to 'hard 't)
- ;; If rear-nonsticky is not "t", add 'hard to rear-nonsticky list
- (if (and (listp sticky) (not (memq 'hard sticky)))
- (put-text-property from (point) 'rear-nonsticky
- (cons 'hard sticky)))))
-
-(defun open-line (n)
- "Insert a newline and leave point before it.
-If there is a fill prefix and/or a `left-margin', insert them
-on the new line if the line would have been blank.
-With arg N, insert N newlines."
- (interactive "*p")
- (let* ((do-fill-prefix (and fill-prefix (bolp)))
- (do-left-margin (and (bolp) (> (current-left-margin) 0)))
- (loc (point-marker))
- ;; Don't expand an abbrev before point.
- (abbrev-mode nil))
- (newline n)
- (goto-char loc)
- (while (> n 0)
- (cond ((bolp)
- (if do-left-margin (indent-to (current-left-margin)))
- (if do-fill-prefix (insert-and-inherit fill-prefix))))
- (forward-line 1)
- (setq n (1- n)))
- (goto-char loc)
- (end-of-line)))
-
-(defun split-line (&optional arg)
- "Split current line, moving portion beyond point vertically down.
-If the current line starts with `fill-prefix', insert it on the new
-line as well. With prefix ARG, don't insert `fill-prefix' on new line.
-
-When called from Lisp code, ARG may be a prefix string to copy."
- (interactive "*P")
- (skip-chars-forward " \t")
- (let* ((col (current-column))
- (pos (point))
- ;; What prefix should we check for (nil means don't).
- (prefix (cond ((stringp arg) arg)
- (arg nil)
- (t fill-prefix)))
- ;; Does this line start with it?
- (have-prfx (and prefix
- (save-excursion
- (beginning-of-line)
- (looking-at (regexp-quote prefix))))))
- (newline 1)
- (if have-prfx (insert-and-inherit prefix))
- (indent-to col 0)
- (goto-char pos)))
-
-(defun delete-indentation (&optional arg)
- "Join this line to previous and fix up whitespace at join.
-If there is a fill prefix, delete it from the beginning of this line.
-With argument, join this line to following line."
- (interactive "*P")
- (beginning-of-line)
- (if arg (forward-line 1))
- (if (eq (preceding-char) ?\n)
- (progn
- (delete-region (point) (1- (point)))
- ;; If the second line started with the fill prefix,
- ;; delete the prefix.
- (if (and fill-prefix
- (<= (+ (point) (length fill-prefix)) (point-max))
- (string= fill-prefix
- (buffer-substring (point)
- (+ (point) (length fill-prefix)))))
- (delete-region (point) (+ (point) (length fill-prefix))))
- (fixup-whitespace))))
-
-(defalias 'join-line #'delete-indentation) ; easier to find
-
-(defun delete-blank-lines ()
- "On blank line, delete all surrounding blank lines, leaving just one.
-On isolated blank line, delete that one.
-On nonblank line, delete any immediately following blank lines."
- (interactive "*")
- (let (thisblank singleblank)
- (save-excursion
- (beginning-of-line)
- (setq thisblank (looking-at "[ \t]*$"))
- ;; Set singleblank if there is just one blank line here.
- (setq singleblank
- (and thisblank
- (not (looking-at "[ \t]*\n[ \t]*$"))
- (or (bobp)
- (progn (forward-line -1)
- (not (looking-at "[ \t]*$")))))))
- ;; Delete preceding blank lines, and this one too if it's the only one.
- (if thisblank
- (progn
- (beginning-of-line)
- (if singleblank (forward-line 1))
- (delete-region (point)
- (if (re-search-backward "[^ \t\n]" nil t)
- (progn (forward-line 1) (point))
- (point-min)))))
- ;; Delete following blank lines, unless the current line is blank
- ;; and there are no following blank lines.
- (if (not (and thisblank singleblank))
- (save-excursion
- (end-of-line)
- (forward-line 1)
- (delete-region (point)
- (if (re-search-forward "[^ \t\n]" nil t)
- (progn (beginning-of-line) (point))
- (point-max)))))
- ;; Handle the special case where point is followed by newline and eob.
- ;; Delete the line, leaving point at eob.
- (if (looking-at "^[ \t]*\n\\'")
- (delete-region (point) (point-max)))))
-
-(defcustom delete-trailing-lines t
- "If non-nil, \\[delete-trailing-whitespace] deletes trailing lines.
-Trailing lines are deleted only if `delete-trailing-whitespace'
-is called on the entire buffer (rather than an active region)."
- :type 'boolean
- :group 'editing
- :version "24.3")
-
-(defun delete-trailing-whitespace (&optional start end)
- "Delete trailing whitespace between START and END.
-If called interactively, START and END are the start/end of the
-region if the mark is active, or of the buffer's accessible
-portion if the mark is inactive.
-
-This command deletes whitespace characters after the last
-non-whitespace character in each line between START and END. It
-does not consider formfeed characters to be whitespace.
-
-If this command acts on the entire buffer (i.e. if called
-interactively with the mark inactive, or called from Lisp with
-END nil), it also deletes all trailing lines at the end of the
-buffer if the variable `delete-trailing-lines' is non-nil."
- (interactive (progn
- (barf-if-buffer-read-only)
- (if (use-region-p)
- (list (region-beginning) (region-end))
- (list nil nil))))
- (save-match-data
- (save-excursion
- (let ((end-marker (copy-marker (or end (point-max))))
- (start (or start (point-min))))
- (goto-char start)
- (while (re-search-forward "\\s-$" end-marker t)
- (skip-syntax-backward "-" (line-beginning-position))
- ;; Don't delete formfeeds, even if they are considered whitespace.
- (if (looking-at-p ".*\f")
- (goto-char (match-end 0)))
- (delete-region (point) (match-end 0)))
- ;; Delete trailing empty lines.
- (goto-char end-marker)
- (when (and (not end)
- delete-trailing-lines
- ;; Really the end of buffer.
- (= (point-max) (1+ (buffer-size)))
- (<= (skip-chars-backward "\n") -2))
- (delete-region (1+ (point)) end-marker))
- (set-marker end-marker nil))))
- ;; Return nil for the benefit of `write-file-functions'.
- nil)
-
-(defun newline-and-indent ()
- "Insert a newline, then indent according to major mode.
-Indentation is done using the value of `indent-line-function'.
-In programming language modes, this is the same as TAB.
-In some text modes, where TAB inserts a tab, this command indents to the
-column specified by the function `current-left-margin'."
- (interactive "*")
- (delete-horizontal-space t)
- (newline nil t)
- (indent-according-to-mode))
-
-(defun reindent-then-newline-and-indent ()
- "Reindent current line, insert newline, then indent the new line.
-Indentation of both lines is done according to the current major mode,
-which means calling the current value of `indent-line-function'.
-In programming language modes, this is the same as TAB.
-In some text modes, where TAB inserts a tab, this indents to the
-column specified by the function `current-left-margin'."
- (interactive "*")
- (let ((pos (point)))
- ;; Be careful to insert the newline before indenting the line.
- ;; Otherwise, the indentation might be wrong.
- (newline)
- (save-excursion
- (goto-char pos)
- ;; We are at EOL before the call to indent-according-to-mode, and
- ;; after it we usually are as well, but not always. We tried to
- ;; address it with `save-excursion' but that uses a normal marker
- ;; whereas we need `move after insertion', so we do the save/restore
- ;; by hand.
- (setq pos (copy-marker pos t))
- (indent-according-to-mode)
- (goto-char pos)
- ;; Remove the trailing white-space after indentation because
- ;; indentation may introduce the whitespace.
- (delete-horizontal-space t))
- (indent-according-to-mode)))
-
-(defcustom read-quoted-char-radix 8
- "Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
-Legitimate radix values are 8, 10 and 16."
- :type '(choice (const 8) (const 10) (const 16))
- :group 'editing-basics)
-
-(defun read-quoted-char (&optional prompt)
- "Like `read-char', but do not allow quitting.
-Also, if the first character read is an octal digit,
-we read any number of octal digits and return the
-specified character code. Any nondigit terminates the sequence.
-If the terminator is RET, it is discarded;
-any other terminator is used itself as input.
-
-The optional argument PROMPT specifies a string to use to prompt the user.
-The variable `read-quoted-char-radix' controls which radix to use
-for numeric input."
- (let ((message-log-max nil)
- (help-events (delq nil (mapcar (lambda (c) (unless (characterp c) c))
- help-event-list)))
- done (first t) (code 0) translated)
- (while (not done)
- (let ((inhibit-quit first)
- ;; Don't let C-h or other help chars get the help
- ;; message--only help function keys. See bug#16617.
- (help-char nil)
- (help-event-list help-events)
- (help-form
- "Type the special character you want to use,
-or the octal character code.
-RET terminates the character code and is discarded;
-any other non-digit terminates the character code and is then used as input."))
- (setq translated (read-key (and prompt (format "%s-" prompt))))
- (if inhibit-quit (setq quit-flag nil)))
- (if (integerp translated)
- (setq translated (char-resolve-modifiers translated)))
- (cond ((null translated))
- ((not (integerp translated))
- (setq unread-command-events
- (listify-key-sequence (this-single-command-raw-keys))
- done t))
- ((/= (logand translated ?\M-\^@) 0)
- ;; Turn a meta-character into a character with the 0200 bit set.
- (setq code (logior (logand translated (lognot ?\M-\^@)) 128)
- done t))
- ((and (<= ?0 translated)
- (< translated (+ ?0 (min 10 read-quoted-char-radix))))
- (setq code (+ (* code read-quoted-char-radix) (- translated ?0)))
- (and prompt (setq prompt (message "%s %c" prompt translated))))
- ((and (<= ?a (downcase translated))
- (< (downcase translated)
- (+ ?a -10 (min 36 read-quoted-char-radix))))
- (setq code (+ (* code read-quoted-char-radix)
- (+ 10 (- (downcase translated) ?a))))
- (and prompt (setq prompt (message "%s %c" prompt translated))))
- ((and (not first) (eq translated ?\C-m))
- (setq done t))
- ((not first)
- (setq unread-command-events
- (listify-key-sequence (this-single-command-raw-keys))
- done t))
- (t (setq code translated
- done t)))
- (setq first nil))
- code))
-
-(defun quoted-insert (arg)
- "Read next input character and insert it.
-This is useful for inserting control characters.
-With argument, insert ARG copies of the character.
-
-If the first character you type after this command is an octal digit,
-you should type a sequence of octal digits which specify a character code.
-Any nondigit terminates the sequence. If the terminator is a RET,
-it is discarded; any other terminator is used itself as input.
-The variable `read-quoted-char-radix' specifies the radix for this feature;
-set it to 10 or 16 to use decimal or hex instead of octal.
-
-In overwrite mode, this function inserts the character anyway, and
-does not handle octal digits specially. This means that if you use
-overwrite as your normal editing mode, you can use this function to
-insert characters when necessary.
-
-In binary overwrite mode, this function does overwrite, and octal
-digits are interpreted as a character code. This is intended to be
-useful for editing binary files."
- (interactive "*p")
- (let* ((char
- ;; Avoid "obsolete" warnings for translation-table-for-input.
- (with-no-warnings
- (let (translation-table-for-input input-method-function)
- (if (or (not overwrite-mode)
- (eq overwrite-mode 'overwrite-mode-binary))
- (read-quoted-char)
- (read-char))))))
- ;; This used to assume character codes 0240 - 0377 stand for
- ;; characters in some single-byte character set, and converted them
- ;; to Emacs characters. But in 23.1 this feature is deprecated
- ;; in favor of inserting the corresponding Unicode characters.
- ;; (if (and enable-multibyte-characters
- ;; (>= char ?\240)
- ;; (<= char ?\377))
- ;; (setq char (unibyte-char-to-multibyte char)))
- (unless (characterp char)
- (user-error "%s is not a valid character"
- (key-description (vector char))))
- (if (> arg 0)
- (if (eq overwrite-mode 'overwrite-mode-binary)
- (delete-char arg)))
- (while (> arg 0)
- (insert-and-inherit char)
- (setq arg (1- arg)))))
-
-(defun forward-to-indentation (&optional arg)
- "Move forward ARG lines and position at first nonblank character."
- (interactive "^p")
- (forward-line (or arg 1))
- (skip-chars-forward " \t"))
-
-(defun backward-to-indentation (&optional arg)
- "Move backward ARG lines and position at first nonblank character."
- (interactive "^p")
- (forward-line (- (or arg 1)))
- (skip-chars-forward " \t"))
-
-(defun back-to-indentation ()
- "Move point to the first non-whitespace character on this line."
- (interactive "^")
- (beginning-of-line 1)
- (skip-syntax-forward " " (line-end-position))
- ;; Move back over chars that have whitespace syntax but have the p flag.
- (backward-prefix-chars))
-
-(defun fixup-whitespace ()
- "Fixup white space between objects around point.
-Leave one space or none, according to the context."
- (interactive "*")
- (save-excursion
- (delete-horizontal-space)
- (if (or (looking-at "^\\|\\s)")
- (save-excursion (forward-char -1)
- (looking-at "$\\|\\s(\\|\\s'")))
- nil
- (insert ?\s))))
-
-(defun delete-horizontal-space (&optional backward-only)
- "Delete all spaces and tabs around point.
-If BACKWARD-ONLY is non-nil, only delete them before point."
- (interactive "*P")
- (let ((orig-pos (point)))
- (delete-region
- (if backward-only
- orig-pos
- (progn
- (skip-chars-forward " \t")
- (constrain-to-field nil orig-pos t)))
- (progn
- (skip-chars-backward " \t")
- (constrain-to-field nil orig-pos)))))
-
-(defun just-one-space (&optional n)
- "Delete all spaces and tabs around point, leaving one space (or N spaces).
-If N is negative, delete newlines as well, leaving -N spaces.
-See also `cycle-spacing'."
- (interactive "*p")
- (cycle-spacing n nil t))
-
-(defvar cycle-spacing--context nil
- "Store context used in consecutive calls to `cycle-spacing' command.
-The first time this function is run, it saves the original point
-position and original spacing around the point in this
-variable.")
-
-(defun cycle-spacing (&optional n preserve-nl-back single-shot)
- "Manipulate whitespace around point in a smart way.
-In interactive use, this function behaves differently in successive
-consecutive calls.
-
-The first call in a sequence acts like `just-one-space'.
-It deletes all spaces and tabs around point, leaving one space
-\(or N spaces). N is the prefix argument. If N is negative,
-it deletes newlines as well, leaving -N spaces.
-\(If PRESERVE-NL-BACK is non-nil, it does not delete newlines before point.)
-
-The second call in a sequence (or the first call if the above does
-not result in any changes) deletes all spaces.
-
-The third call in a sequence restores the original whitespace (and point).
-
-If SINGLE-SHOT is non-nil, it only performs the first step in the sequence."
- (interactive "*p")
- (let ((orig-pos (point))
- (skip-characters (if (and n (< n 0)) " \t\n\r" " \t"))
- (n (abs (or n 1))))
- (skip-chars-backward (if preserve-nl-back " \t" skip-characters))
- (constrain-to-field nil orig-pos)
- (cond
- ;; Command run for the first time or single-shot is non-nil.
- ((or single-shot
- (not (equal last-command this-command))
- (not cycle-spacing--context))
- (let* ((start (point))
- (n (- n (skip-chars-forward " " (+ n (point)))))
- (mid (point))
- (end (progn
- (skip-chars-forward skip-characters)
- (constrain-to-field nil orig-pos t))))
- (setq cycle-spacing--context ;; Save for later.
- ;; Special handling for case where there was no space at all.
- (unless (= start end)
- (cons orig-pos (buffer-substring start (point)))))
- ;; If this run causes no change in buffer content, delete all spaces,
- ;; otherwise delete all excess spaces.
- (delete-region (if (and (not single-shot) (zerop n) (= mid end))
- start mid) end)
- (insert (make-string n ?\s))))
-
- ;; Command run for the second time.
- ((not (equal orig-pos (point)))
- (delete-region (point) orig-pos))
-
- ;; Command run for the third time.
- (t
- (insert (cdr cycle-spacing--context))
- (goto-char (car cycle-spacing--context))
- (setq cycle-spacing--context nil)))))
-
-(defun beginning-of-buffer (&optional arg)
- "Move point to the beginning of the buffer.
-With numeric arg N, put point N/10 of the way from the beginning.
-If the buffer is narrowed, this command uses the beginning of the
-accessible part of the buffer.
-
-If Transient Mark mode is disabled, leave mark at previous
-position, unless a \\[universal-argument] prefix is supplied.
-
-Don't use this command in Lisp programs!
-\(goto-char (point-min)) is faster."
- (interactive "^P")
- (or (consp arg)
- (region-active-p)
- (push-mark))
- (let ((size (- (point-max) (point-min))))
- (goto-char (if (and arg (not (consp arg)))
- (+ (point-min)
- (if (> size 10000)
- ;; Avoid overflow for large buffer sizes!
- (* (prefix-numeric-value arg)
- (/ size 10))
- (/ (+ 10 (* size (prefix-numeric-value arg))) 10)))
- (point-min))))
- (if (and arg (not (consp arg))) (forward-line 1)))
-(put 'beginning-of-buffer 'interactive-only
- "use `(goto-char (point-min))' instead.")
-
-(defun end-of-buffer (&optional arg)
- "Move point to the end of the buffer.
-With numeric arg N, put point N/10 of the way from the end.
-If the buffer is narrowed, this command uses the end of the
-accessible part of the buffer.
-
-If Transient Mark mode is disabled, leave mark at previous
-position, unless a \\[universal-argument] prefix is supplied.
-
-Don't use this command in Lisp programs!
-\(goto-char (point-max)) is faster."
- (interactive "^P")
- (or (consp arg) (region-active-p) (push-mark))
- (let ((size (- (point-max) (point-min))))
- (goto-char (if (and arg (not (consp arg)))
- (- (point-max)
- (if (> size 10000)
- ;; Avoid overflow for large buffer sizes!
- (* (prefix-numeric-value arg)
- (/ size 10))
- (/ (* size (prefix-numeric-value arg)) 10)))
- (point-max))))
- ;; If we went to a place in the middle of the buffer,
- ;; adjust it to the beginning of a line.
- (cond ((and arg (not (consp arg))) (forward-line 1))
- ((and (eq (current-buffer) (window-buffer))
- (> (point) (window-end nil t)))
- ;; If the end of the buffer is not already on the screen,
- ;; then scroll specially to put it near, but not at, the bottom.
- (overlay-recenter (point))
- (recenter -3))))
-(put 'end-of-buffer 'interactive-only "use `(goto-char (point-max))' instead.")
-
-(defcustom delete-active-region t
- "Whether single-char deletion commands delete an active region.
-This has an effect only if Transient Mark mode is enabled, and
-affects `delete-forward-char' and `delete-backward-char', though
-not `delete-char'.
-
-If the value is the symbol `kill', the active region is killed
-instead of deleted."
- :type '(choice (const :tag "Delete active region" t)
- (const :tag "Kill active region" kill)
- (const :tag "Do ordinary deletion" nil))
- :group 'killing
- :version "24.1")
-
-(defvar region-extract-function
- (lambda (delete)
- (when (region-beginning)
- (if (eq delete 'delete-only)
- (delete-region (region-beginning) (region-end))
- (filter-buffer-substring (region-beginning) (region-end) delete))))
- "Function to get the region's content.
-Called with one argument DELETE.
-If DELETE is `delete-only', then only delete the region and the return value
-is undefined. If DELETE is nil, just return the content as a string.
-If anything else, delete the region and return its content as a string.")
-
-(defun delete-backward-char (n &optional killflag)
- "Delete the previous N characters (following if N is negative).
-If Transient Mark mode is enabled, the mark is active, and N is 1,
-delete the text in the region and deactivate the mark instead.
-To disable this, set option `delete-active-region' to nil.
-
-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.
-
-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."
- (interactive "p\nP")
- (unless (integerp n)
- (signal 'wrong-type-argument (list 'integerp n)))
- (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) 'region)
- (funcall region-extract-function 'delete-only)))
- ;; 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))))
- ;; Otherwise, do simple deletion.
- (t (delete-char (- n) killflag))))
-(put 'delete-backward-char 'interactive-only 'delete-char)
-
-(defun delete-forward-char (n &optional killflag)
- "Delete the following N characters (previous if N is negative).
-If Transient Mark mode is enabled, the mark is active, and N is 1,
-delete the text in the region and deactivate the mark instead.
-To disable this, set variable `delete-active-region' to nil.
-
-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)))
- (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) 'region)
- (funcall region-extract-function 'delete-only)))
-
- ;; Otherwise, do simple deletion.
- (t (delete-char n killflag))))
-(put 'delete-forward-char 'interactive-only 'delete-char)
-
-(defun mark-whole-buffer ()
- "Put point at beginning and mark at end of buffer.
-If narrowing is in effect, only uses the accessible part of the buffer.
-You probably should not use this function in Lisp programs;
-it is usually a mistake for a Lisp function to use any subroutine
-that uses or sets the mark."
- (interactive)
- (push-mark (point))
- (push-mark (point-max) nil t)
- (goto-char (point-min)))
-
-
-;; Counting lines, one way or another.
-
-(defun goto-line (line &optional buffer)
- "Go to LINE, counting from line 1 at beginning of buffer.
-If called interactively, a numeric prefix argument specifies
-LINE; without a numeric prefix argument, read LINE from the
-minibuffer.
-
-If optional argument BUFFER is non-nil, switch to that buffer and
-move to line LINE there. If called interactively with \\[universal-argument]
-as argument, BUFFER is the most recently selected other buffer.
-
-Prior to moving point, this function sets the mark (without
-activating it), unless Transient Mark mode is enabled and the
-mark is already active.
-
-This function is usually the wrong thing to use in a Lisp program.
-What you probably want instead is something like:
- (goto-char (point-min))
- (forward-line (1- N))
-If at all possible, an even better solution is to use char counts
-rather than line counts."
- (interactive
- (if (and current-prefix-arg (not (consp current-prefix-arg)))
- (list (prefix-numeric-value current-prefix-arg))
- ;; Look for a default, a number in the buffer at point.
- (let* ((default
- (save-excursion
- (skip-chars-backward "0-9")
- (if (looking-at "[0-9]")
- (string-to-number
- (buffer-substring-no-properties
- (point)
- (progn (skip-chars-forward "0-9")
- (point)))))))
- ;; Decide if we're switching buffers.
- (buffer
- (if (consp current-prefix-arg)
- (other-buffer (current-buffer) t)))
- (buffer-prompt
- (if buffer
- (concat " in " (buffer-name buffer))
- "")))
- ;; Read the argument, offering that number (if any) as default.
- (list (read-number (format "Goto line%s: " buffer-prompt)
- (list default (line-number-at-pos)))
- buffer))))
- ;; Switch to the desired buffer, one way or another.
- (if buffer
- (let ((window (get-buffer-window buffer)))
- (if window (select-window window)
- (switch-to-buffer-other-window buffer))))
- ;; Leave mark at previous position
- (or (region-active-p) (push-mark))
- ;; Move to the specified line number in that buffer.
- (save-restriction
- (widen)
- (goto-char (point-min))
- (if (eq selective-display t)
- (re-search-forward "[\n\C-m]" nil 'end (1- line))
- (forward-line (1- line)))))
-(put 'goto-line 'interactive-only 'forward-line)
-
-(defun count-words-region (start end &optional arg)
- "Count the number of words in the region.
-If called interactively, print a message reporting the number of
-lines, words, and characters in the region (whether or not the
-region is active); with prefix ARG, report for the entire buffer
-rather than the region.
-
-If called from Lisp, return the number of words between positions
-START and END."
- (interactive (if current-prefix-arg
- (list nil nil current-prefix-arg)
- (list (region-beginning) (region-end) nil)))
- (cond ((not (called-interactively-p 'any))
- (count-words start end))
- (arg
- (count-words--buffer-message))
- (t
- (count-words--message "Region" start end))))
-
-(defun count-words (start end)
- "Count words between START and END.
-If called interactively, START and END are normally the start and
-end of the buffer; but if the region is active, START and END are
-the start and end of the region. Print a message reporting the
-number of lines, words, and chars.
-
-If called from Lisp, return the number of words between START and
-END, without printing any message."
- (interactive (list nil nil))
- (cond ((not (called-interactively-p 'any))
- (let ((words 0))
- (save-excursion
- (save-restriction
- (narrow-to-region start end)
- (goto-char (point-min))
- (while (forward-word 1)
- (setq words (1+ words)))))
- words))
- ((use-region-p)
- (call-interactively 'count-words-region))
- (t
- (count-words--buffer-message))))
-
-(defun count-words--buffer-message ()
- (count-words--message
- (if (buffer-narrowed-p) "Narrowed part of buffer" "Buffer")
- (point-min) (point-max)))
-
-(defun count-words--message (str start end)
- (let ((lines (count-lines start end))
- (words (count-words start end))
- (chars (- end start)))
- (message "%s has %d line%s, %d word%s, and %d character%s."
- str
- lines (if (= lines 1) "" "s")
- words (if (= words 1) "" "s")
- chars (if (= chars 1) "" "s"))))
-
-(define-obsolete-function-alias 'count-lines-region 'count-words-region "24.1")
-
-(defun what-line ()
- "Print the current buffer line number and narrowed line number of point."
- (interactive)
- (let ((start (point-min))
- (n (line-number-at-pos)))
- (if (= start 1)
- (message "Line %d" n)
- (save-excursion
- (save-restriction
- (widen)
- (message "line %d (narrowed line %d)"
- (+ n (line-number-at-pos start) -1) n))))))
-
-(defun count-lines (start end)
- "Return number of lines between START and END.
-This is usually the number of newlines between them,
-but can be one more if START is not equal to END
-and the greater of them is not at the start of a line."
- (save-excursion
- (save-restriction
- (narrow-to-region start end)
- (goto-char (point-min))
- (if (eq selective-display t)
- (save-match-data
- (let ((done 0))
- (while (re-search-forward "[\n\C-m]" nil t 40)
- (setq done (+ 40 done)))
- (while (re-search-forward "[\n\C-m]" nil t 1)
- (setq done (+ 1 done)))
- (goto-char (point-max))
- (if (and (/= start end)
- (not (bolp)))
- (1+ done)
- done)))
- (- (buffer-size) (forward-line (buffer-size)))))))
-
-(defun line-number-at-pos (&optional pos)
- "Return (narrowed) buffer line number at position POS.
-If POS is nil, use current buffer location.
-Counting starts at (point-min), so the value refers
-to the contents of the accessible portion of the buffer."
- (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 what-cursor-position (&optional detail)
- "Print info on cursor position (on screen and within buffer).
-Also describe the character after point, and give its character code
-in octal, decimal and hex.
-
-For a non-ASCII multibyte character, also give its encoding in the
-buffer's selected coding system if the coding system encodes the
-character safely. If the character is encoded into one byte, that
-code is shown in hex. If the character is encoded into more than one
-byte, just \"...\" is shown.
-
-In addition, with prefix argument, show details about that character
-in *Help* buffer. See also the command `describe-char'."
- (interactive "P")
- (let* ((char (following-char))
- (bidi-fixer
- (cond ((memq char '(?\x202a ?\x202b ?\x202d ?\x202e))
- ;; If the character is one of LRE, LRO, RLE, RLO, it
- ;; will start a directional embedding, which could
- ;; completely disrupt the rest of the line (e.g., RLO
- ;; will display the rest of the line right-to-left).
- ;; So we put an invisible PDF character after these
- ;; characters, to end the embedding, which eliminates
- ;; any effects on the rest of the line.
- (propertize (string ?\x202c) 'invisible t))
- ;; Strong right-to-left characters cause reordering of
- ;; the following numerical characters which show the
- ;; codepoint, so append LRM to countermand that.
- ((memq (get-char-code-property char 'bidi-class) '(R AL))
- (propertize (string ?\x200e) 'invisible t))
- (t
- "")))
- (beg (point-min))
- (end (point-max))
- (pos (point))
- (total (buffer-size))
- (percent (if (> total 50000)
- ;; Avoid overflow from multiplying by 100!
- (/ (+ (/ total 200) (1- pos)) (max (/ total 100) 1))
- (/ (+ (/ total 2) (* 100 (1- pos))) (max total 1))))
- (hscroll (if (= (window-hscroll) 0)
- ""
- (format " Hscroll=%d" (window-hscroll))))
- (col (current-column)))
- (if (= pos end)
- (if (or (/= beg 1) (/= end (1+ total)))
- (message "point=%d of %d (%d%%) <%d-%d> column=%d%s"
- pos total percent beg end col hscroll)
- (message "point=%d of %d (EOB) column=%d%s"
- pos total col hscroll))
- (let ((coding buffer-file-coding-system)
- encoded encoding-msg display-prop under-display)
- (if (or (not coding)
- (eq (coding-system-type coding) t))
- (setq coding (default-value 'buffer-file-coding-system)))
- (if (eq (char-charset char) 'eight-bit)
- (setq encoding-msg
- (format "(%d, #o%o, #x%x, raw-byte)" char char char))
- ;; Check if the character is displayed with some `display'
- ;; text property. In that case, set under-display to the
- ;; buffer substring covered by that property.
- (setq display-prop (get-char-property pos 'display))
- (if display-prop
- (let ((to (or (next-single-char-property-change pos 'display)
- (point-max))))
- (if (< to (+ pos 4))
- (setq under-display "")
- (setq under-display "..."
- to (+ pos 4)))
- (setq under-display
- (concat (buffer-substring-no-properties pos to)
- under-display)))
- (setq encoded (and (>= char 128) (encode-coding-char char coding))))
- (setq encoding-msg
- (if display-prop
- (if (not (stringp display-prop))
- (format "(%d, #o%o, #x%x, part of display \"%s\")"
- char char char under-display)
- (format "(%d, #o%o, #x%x, part of display \"%s\"->\"%s\")"
- char char char under-display display-prop))
- (if encoded
- (format "(%d, #o%o, #x%x, file %s)"
- char char char
- (if (> (length encoded) 1)
- "..."
- (encoded-string-description encoded coding)))
- (format "(%d, #o%o, #x%x)" char char char)))))
- (if detail
- ;; We show the detailed information about CHAR.
- (describe-char (point)))
- (if (or (/= beg 1) (/= end (1+ total)))
- (message "Char: %s%s %s point=%d of %d (%d%%) <%d-%d> column=%d%s"
- (if (< char 256)
- (single-key-description char)
- (buffer-substring-no-properties (point) (1+ (point))))
- bidi-fixer
- encoding-msg pos total percent beg end col hscroll)
- (message "Char: %s%s %s point=%d of %d (%d%%) column=%d%s"
- (if enable-multibyte-characters
- (if (< char 128)
- (single-key-description char)
- (buffer-substring-no-properties (point) (1+ (point))))
- (single-key-description char))
- bidi-fixer encoding-msg pos total percent col hscroll))))))
-
-;; Initialize read-expression-map. It is defined at C level.
-(defvar read-expression-map
- (let ((m (make-sparse-keymap)))
- (define-key m "\M-\t" 'completion-at-point)
- ;; Might as well bind TAB to completion, since inserting a TAB char is
- ;; much too rarely useful.
- (define-key m "\t" 'completion-at-point)
- (set-keymap-parent m minibuffer-local-map)
- m))
-
-(defun read-minibuffer (prompt &optional initial-contents)
- "Return a Lisp object read using the minibuffer, unevaluated.
-Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
-is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer.
-Such arguments are used as in `read-from-minibuffer'.)"
- ;; Used for interactive spec `x'.
- (read-from-minibuffer prompt initial-contents minibuffer-local-map
- t 'minibuffer-history))
-
-(defun eval-minibuffer (prompt &optional initial-contents)
- "Return value of Lisp expression read using the minibuffer.
-Prompt with PROMPT. If non-nil, optional second arg INITIAL-CONTENTS
-is a string to insert in the minibuffer before reading.
-\(INITIAL-CONTENTS can also be a cons of a string and an integer.
-Such arguments are used as in `read-from-minibuffer'.)"
- ;; Used for interactive spec `X'.
- (eval (read--expression prompt initial-contents)))
-
-(defvar minibuffer-completing-symbol nil
- "Non-nil means completing a Lisp symbol in the minibuffer.")
-(make-obsolete-variable 'minibuffer-completing-symbol nil "24.1" 'get)
-
-(defvar minibuffer-default nil
- "The current default value or list of default values in the minibuffer.
-The functions `read-from-minibuffer' and `completing-read' bind
-this variable locally.")
-
-(defcustom eval-expression-print-level 4
- "Value for `print-level' while printing value in `eval-expression'.
-A value of nil means no limit."
- :group 'lisp
- :type '(choice (const :tag "No Limit" nil) integer)
- :version "21.1")
-
-(defcustom eval-expression-print-length 12
- "Value for `print-length' while printing value in `eval-expression'.
-A value of nil means no limit."
- :group 'lisp
- :type '(choice (const :tag "No Limit" nil) integer)
- :version "21.1")
-
-(defcustom eval-expression-debug-on-error t
- "If non-nil set `debug-on-error' to t in `eval-expression'.
-If nil, don't change the value of `debug-on-error'."
- :group 'lisp
- :type 'boolean
- :version "21.1")
-
-(defun eval-expression-print-format (value)
- "Format VALUE as a result of evaluated expression.
-Return a formatted string which is displayed in the echo area
-in addition to the value printed by prin1 in functions which
-display the result of expression evaluation."
- (if (and (integerp value)
- (or (eq standard-output t)
- (zerop (prefix-numeric-value current-prefix-arg))))
- (let ((char-string
- (if (and (characterp value)
- (char-displayable-p value))
- (prin1-char value))))
- (if char-string
- (format " (#o%o, #x%x, %s)" value value char-string)
- (format " (#o%o, #x%x)" value value)))))
-
-(defvar eval-expression-minibuffer-setup-hook nil
- "Hook run by `eval-expression' when entering the minibuffer.")
-
-(defun read--expression (prompt &optional initial-contents)
- (let ((minibuffer-completing-symbol t))
- (minibuffer-with-setup-hook
- (lambda ()
- (add-hook 'completion-at-point-functions
- #'lisp-completion-at-point nil t)
- (run-hooks 'eval-expression-minibuffer-setup-hook))
- (read-from-minibuffer prompt initial-contents
- read-expression-map t
- 'read-expression-history))))
-
-;; We define this, rather than making `eval' interactive,
-;; for the sake of completion of names like eval-region, eval-buffer.
-(defun eval-expression (exp &optional insert-value)
- "Evaluate EXP and print value in the echo area.
-When called interactively, read an Emacs Lisp expression and evaluate it.
-Value is also consed on to front of the variable `values'.
-Optional argument INSERT-VALUE non-nil (interactively, with prefix
-argument) means insert the result into the current buffer instead of
-printing it in the echo area.
-
-Normally, this function truncates long output according to the value
-of the variables `eval-expression-print-length' and
-`eval-expression-print-level'. With a prefix argument of zero,
-however, there is no such truncation. Such a prefix argument
-also causes integers to be printed in several additional formats
-\(octal, hexadecimal, and character).
-
-Runs the hook `eval-expression-minibuffer-setup-hook' on entering the
-minibuffer.
-
-If `eval-expression-debug-on-error' is non-nil, which is the default,
-this command arranges for all errors to enter the debugger."
- (interactive
- (list (read--expression "Eval: ")
- current-prefix-arg))
-
- (if (null eval-expression-debug-on-error)
- (push (eval exp lexical-binding) values)
- (let ((old-value (make-symbol "t")) new-value)
- ;; Bind debug-on-error to something unique so that we can
- ;; detect when evalled code changes it.
- (let ((debug-on-error old-value))
- (push (eval exp lexical-binding) values)
- (setq new-value debug-on-error))
- ;; If evalled code has changed the value of debug-on-error,
- ;; propagate that change to the global binding.
- (unless (eq old-value new-value)
- (setq debug-on-error new-value))))
-
- (let ((print-length (and (not (zerop (prefix-numeric-value insert-value)))
- eval-expression-print-length))
- (print-level (and (not (zerop (prefix-numeric-value insert-value)))
- eval-expression-print-level))
- (deactivate-mark))
- (if insert-value
- (with-no-warnings
- (let ((standard-output (current-buffer)))
- (prog1
- (prin1 (car values))
- (when (zerop (prefix-numeric-value insert-value))
- (let ((str (eval-expression-print-format (car values))))
- (if str (princ str)))))))
- (prog1
- (prin1 (car values) t)
- (let ((str (eval-expression-print-format (car values))))
- (if str (princ str t)))))))
-
-(defun edit-and-eval-command (prompt command)
- "Prompting with PROMPT, let user edit COMMAND and eval result.
-COMMAND is a Lisp expression. Let user edit that expression in
-the minibuffer, then read and evaluate the result."
- (let ((command
- (let ((print-level nil)
- (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
- (unwind-protect
- (read-from-minibuffer prompt
- (prin1-to-string command)
- read-expression-map t
- 'command-history)
- ;; If command was added to command-history as a string,
- ;; get rid of that. We want only evaluable expressions there.
- (if (stringp (car command-history))
- (setq command-history (cdr command-history)))))))
-
- ;; If command to be redone does not match front of history,
- ;; add it to the history.
- (or (equal command (car command-history))
- (setq command-history (cons command command-history)))
- (eval command)))
-
-(defun repeat-complex-command (arg)
- "Edit and re-evaluate last complex command, or ARGth from last.
-A complex command is one which used the minibuffer.
-The command is placed in the minibuffer as a Lisp form for editing.
-The result is executed, repeating the command as changed.
-If the command has been changed or is not the most recent previous
-command it is added to the front of the command history.
-You can use the minibuffer history commands \
-\\<minibuffer-local-map>\\[next-history-element] and
\\[previous-history-element]
-to get different commands to edit and resubmit."
- (interactive "p")
- (let ((elt (nth (1- arg) command-history))
- newcmd)
- (if elt
- (progn
- (setq newcmd
- (let ((print-level nil)
- (minibuffer-history-position arg)
- (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
- (unwind-protect
- (read-from-minibuffer
- "Redo: " (prin1-to-string elt) read-expression-map t
- (cons 'command-history arg))
-
- ;; If command was added to command-history as a
- ;; string, get rid of that. We want only
- ;; evaluable expressions there.
- (if (stringp (car command-history))
- (setq command-history (cdr command-history))))))
-
- ;; If command to be redone does not match front of history,
- ;; add it to the history.
- (or (equal newcmd (car command-history))
- (setq command-history (cons newcmd command-history)))
- (unwind-protect
- (progn
- ;; Trick called-interactively-p into thinking that `newcmd' is
- ;; an interactive call (bug#14136).
- (add-hook 'called-interactively-p-functions
- #'repeat-complex-command--called-interactively-skip)
- (eval newcmd))
- (remove-hook 'called-interactively-p-functions
- #'repeat-complex-command--called-interactively-skip)))
- (if command-history
- (error "Argument %d is beyond length of command history" arg)
- (error "There are no previous complex commands to repeat")))))
-
-(defun repeat-complex-command--called-interactively-skip (i _frame1 frame2)
- (and (eq 'eval (cadr frame2))
- (eq 'repeat-complex-command
- (cadr (backtrace-frame i #'called-interactively-p)))
- 1))
-
-(defvar extended-command-history nil)
-
-(defun read-extended-command ()
- "Read command name to invoke in `execute-extended-command'."
- (minibuffer-with-setup-hook
- (lambda ()
- (set (make-local-variable 'minibuffer-default-add-function)
- (lambda ()
- ;; Get a command name at point in the original buffer
- ;; to propose it after M-n.
- (with-current-buffer (window-buffer (minibuffer-selected-window))
- (and (commandp (function-called-at-point))
- (format "%S" (function-called-at-point)))))))
- ;; Read a string, completing from and restricting to the set of
- ;; all defined commands. Don't provide any initial input.
- ;; Save the command read on the extended-command history list.
- (completing-read
- (concat (cond
- ((eq current-prefix-arg '-) "- ")
- ((and (consp current-prefix-arg)
- (eq (car current-prefix-arg) 4)) "C-u ")
- ((and (consp current-prefix-arg)
- (integerp (car current-prefix-arg)))
- (format "%d " (car current-prefix-arg)))
- ((integerp current-prefix-arg)
- (format "%d " current-prefix-arg)))
- ;; This isn't strictly correct if `execute-extended-command'
- ;; is bound to anything else (e.g. [menu]).
- ;; It could use (key-description (this-single-command-keys)),
- ;; but actually a prompt other than "M-x" would be confusing,
- ;; because "M-x" is a well-known prompt to read a command
- ;; and it serves as a shorthand for "Extended command: ".
- "M-x ")
- obarray 'commandp t nil 'extended-command-history)))
-
-(defcustom suggest-key-bindings t
- "Non-nil means show the equivalent key-binding when M-x command has one.
-The value can be a length of time to show the message for.
-If the value is non-nil and not a number, we wait 2 seconds."
- :group 'keyboard
- :type '(choice (const :tag "off" nil)
- (integer :tag "time" 2)
- (other :tag "on")))
-
-(defun execute-extended-command (prefixarg &optional command-name)
- ;; Based on Fexecute_extended_command in keyboard.c of Emacs.
- ;; Aaron S. Hawley <aaron.s.hawley(at)gmail.com> 2009-08-24
- "Read a command name, then read the arguments and call the command.
-Interactively, to pass a prefix argument to the command you are
-invoking, give a prefix argument to `execute-extended-command'.
-Noninteractively, the argument PREFIXARG is the prefix argument to
-give to the command you invoke."
- (interactive (list current-prefix-arg (read-extended-command)))
- ;; Emacs<24 calling-convention was with a single `prefixarg' argument.
- (if (null command-name)
- (setq command-name (let ((current-prefix-arg prefixarg)) ; for prompt
- (read-extended-command))))
- (let* ((function (and (stringp command-name) (intern-soft command-name)))
- (binding (and suggest-key-bindings
- (not executing-kbd-macro)
- (where-is-internal function overriding-local-map t))))
- (unless (commandp function)
- (error "`%s' is not a valid command name" command-name))
- (setq this-command function)
- ;; Normally `real-this-command' should never be changed, but here we really
- ;; want to pretend that M-x <cmd> RET is nothing more than a "key
- ;; binding" for <cmd>, so the command the user really wanted to run is
- ;; `function' and not `execute-extended-command'. The difference is
- ;; visible in cases such as M-x <cmd> RET and then C-x z (bug#11506).
- (setq real-this-command function)
- (let ((prefix-arg prefixarg))
- (command-execute function 'record))
- ;; If enabled, show which key runs this command.
- (when binding
- ;; But first wait, and skip the message if there is input.
- (let* ((waited
- ;; If this command displayed something in the echo area;
- ;; wait a few seconds, then display our suggestion message.
- (sit-for (cond
- ((zerop (length (current-message))) 0)
- ((numberp suggest-key-bindings) suggest-key-bindings)
- (t 2)))))
- (when (and waited (not (consp unread-command-events)))
- (with-temp-message
- (format "You can run the command `%s' with %s"
- function (key-description binding))
- (sit-for (if (numberp suggest-key-bindings)
- suggest-key-bindings
- 2))))))))
-
-(defun command-execute (cmd &optional record-flag keys special)
- ;; BEWARE: Called directly from the C code.
- "Execute CMD as an editor command.
-CMD must be a symbol that satisfies the `commandp' predicate.
-Optional second arg RECORD-FLAG non-nil
-means unconditionally put this command in the variable `command-history'.
-Otherwise, that is done only if an arg is read using the minibuffer.
-The argument KEYS specifies the value to use instead of (this-command-keys)
-when reading the arguments; if it is nil, (this-command-keys) is used.
-The argument SPECIAL, if non-nil, means that this command is executing
-a special event, so ignore the prefix argument and don't clear it."
- (setq debug-on-next-call nil)
- (let ((prefixarg (unless special
- (prog1 prefix-arg
- (setq current-prefix-arg prefix-arg)
- (setq prefix-arg nil)))))
- (if (and (symbolp cmd)
- (get cmd 'disabled)
- disabled-command-function)
- ;; FIXME: Weird calling convention!
- (run-hooks 'disabled-command-function)
- (let ((final cmd))
- (while
- (progn
- (setq final (indirect-function final))
- (if (autoloadp final)
- (setq final (autoload-do-load final cmd)))))
- (cond
- ((arrayp final)
- ;; If requested, place the macro in the command history. For
- ;; other sorts of commands, call-interactively takes care of this.
- (when record-flag
- (push `(execute-kbd-macro ,final ,prefixarg) command-history)
- ;; Don't keep command history around forever.
- (when (and (numberp history-length) (> history-length 0))
- (let ((cell (nthcdr history-length command-history)))
- (if (consp cell) (setcdr cell nil)))))
- (execute-kbd-macro final prefixarg))
- (t
- ;; Pass `cmd' rather than `final', for the backtrace's sake.
- (prog1 (call-interactively cmd record-flag keys)
- (when (and (symbolp cmd)
- (get cmd 'byte-obsolete-info)
- (not (get cmd 'command-execute-obsolete-warned)))
- (put cmd 'command-execute-obsolete-warned t)
- (message "%s" (macroexp--obsolete-warning
- cmd (get cmd 'byte-obsolete-info)
"command"))))))))))
-
-(defvar minibuffer-history nil
- "Default minibuffer history list.
-This is used for all minibuffer input
-except when an alternate history list is specified.
-
-Maximum length of the history list is determined by the value
-of `history-length', which see.")
-(defvar minibuffer-history-sexp-flag nil
- "Control whether history list elements are expressions or strings.
-If the value of this variable equals current minibuffer depth,
-they are expressions; otherwise they are strings.
-\(That convention is designed to do the right thing for
-recursive uses of the minibuffer.)")
-(setq minibuffer-history-variable 'minibuffer-history)
-(setq minibuffer-history-position nil) ;; Defvar is in C code.
-(defvar minibuffer-history-search-history nil)
-
-(defvar minibuffer-text-before-history nil
- "Text that was in this minibuffer before any history commands.
-This is nil if there have not yet been any history commands
-in this use of the minibuffer.")
-
-(add-hook 'minibuffer-setup-hook 'minibuffer-history-initialize)
-
-(defun minibuffer-history-initialize ()
- (setq minibuffer-text-before-history nil))
-
-(defun minibuffer-avoid-prompt (_new _old)
- "A point-motion hook for the minibuffer, that moves point out of the prompt."
- (constrain-to-field nil (point-max)))
-
-(defcustom minibuffer-history-case-insensitive-variables nil
- "Minibuffer history variables for which matching should ignore case.
-If a history variable is a member of this list, then the
-\\[previous-matching-history-element] and \\[next-matching-history-element]\
- commands ignore case when searching it, regardless of `case-fold-search'."
- :type '(repeat variable)
- :group 'minibuffer)
-
-(defun previous-matching-history-element (regexp n)
- "Find the previous history element that matches REGEXP.
-\(Previous history elements refer to earlier actions.)
-With prefix argument N, search for Nth previous match.
-If N is negative, find the next or Nth next match.
-Normally, history elements are matched case-insensitively if
-`case-fold-search' is non-nil, but an uppercase letter in REGEXP
-makes the search case-sensitive.
-See also `minibuffer-history-case-insensitive-variables'."
- (interactive
- (let* ((enable-recursive-minibuffers t)
- (regexp (read-from-minibuffer "Previous element matching (regexp): "
- nil
- minibuffer-local-map
- nil
- 'minibuffer-history-search-history
- (car
minibuffer-history-search-history))))
- ;; Use the last regexp specified, by default, if input is empty.
- (list (if (string= regexp "")
- (if minibuffer-history-search-history
- (car minibuffer-history-search-history)
- (user-error "No previous history search regexp"))
- regexp)
- (prefix-numeric-value current-prefix-arg))))
- (unless (zerop n)
- (if (and (zerop minibuffer-history-position)
- (null minibuffer-text-before-history))
- (setq minibuffer-text-before-history
- (minibuffer-contents-no-properties)))
- (let ((history (symbol-value minibuffer-history-variable))
- (case-fold-search
- (if (isearch-no-upper-case-p regexp t) ; assume isearch.el is dumped
- ;; On some systems, ignore case for file names.
- (if (memq minibuffer-history-variable
- minibuffer-history-case-insensitive-variables)
- t
- ;; Respect the user's setting for case-fold-search:
- case-fold-search)
- nil))
- prevpos
- match-string
- match-offset
- (pos minibuffer-history-position))
- (while (/= n 0)
- (setq prevpos pos)
- (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
- (when (= pos prevpos)
- (user-error (if (= pos 1)
- "No later matching history item"
- "No earlier matching history item")))
- (setq match-string
- (if (eq minibuffer-history-sexp-flag (minibuffer-depth))
- (let ((print-level nil))
- (prin1-to-string (nth (1- pos) history)))
- (nth (1- pos) history)))
- (setq match-offset
- (if (< n 0)
- (and (string-match regexp match-string)
- (match-end 0))
- (and (string-match (concat ".*\\(" regexp "\\)") match-string)
- (match-beginning 1))))
- (when match-offset
- (setq n (+ n (if (< n 0) 1 -1)))))
- (setq minibuffer-history-position pos)
- (goto-char (point-max))
- (delete-minibuffer-contents)
- (insert match-string)
- (goto-char (+ (minibuffer-prompt-end) match-offset))))
- (if (memq (car (car command-history)) '(previous-matching-history-element
- next-matching-history-element))
- (setq command-history (cdr command-history))))
-
-(defun next-matching-history-element (regexp n)
- "Find the next history element that matches REGEXP.
-\(The next history element refers to a more recent action.)
-With prefix argument N, search for Nth next match.
-If N is negative, find the previous or Nth previous match.
-Normally, history elements are matched case-insensitively if
-`case-fold-search' is non-nil, but an uppercase letter in REGEXP
-makes the search case-sensitive."
- (interactive
- (let* ((enable-recursive-minibuffers t)
- (regexp (read-from-minibuffer "Next element matching (regexp): "
- nil
- minibuffer-local-map
- nil
- 'minibuffer-history-search-history
- (car
minibuffer-history-search-history))))
- ;; Use the last regexp specified, by default, if input is empty.
- (list (if (string= regexp "")
- (if minibuffer-history-search-history
- (car minibuffer-history-search-history)
- (user-error "No previous history search regexp"))
- regexp)
- (prefix-numeric-value current-prefix-arg))))
- (previous-matching-history-element regexp (- n)))
-
-(defvar minibuffer-temporary-goal-position nil)
-
-(defvar minibuffer-default-add-function 'minibuffer-default-add-completions
- "Function run by `goto-history-element' before consuming default values.
-This is useful to dynamically add more elements to the list of default values
-when `goto-history-element' reaches the end of this list.
-Before calling this function `goto-history-element' sets the variable
-`minibuffer-default-add-done' to t, so it will call this function only
-once. In special cases, when this function needs to be called more
-than once, it can set `minibuffer-default-add-done' to nil explicitly,
-overriding the setting of this variable to t in `goto-history-element'.")
-
-(defvar minibuffer-default-add-done nil
- "When nil, add more elements to the end of the list of default values.
-The value nil causes `goto-history-element' to add more elements to
-the list of defaults when it reaches the end of this list. It does
-this by calling a function defined by `minibuffer-default-add-function'.")
-
-(make-variable-buffer-local 'minibuffer-default-add-done)
-
-(defun minibuffer-default-add-completions ()
- "Return a list of all completions without the default value.
-This function is used to add all elements of the completion table to
-the end of the list of defaults just after the default value."
- (let ((def minibuffer-default)
- (all (all-completions ""
- minibuffer-completion-table
- minibuffer-completion-predicate)))
- (if (listp def)
- (append def all)
- (cons def (delete def all)))))
-
-(defun goto-history-element (nabs)
- "Puts element of the minibuffer history in the minibuffer.
-The argument NABS specifies the absolute history position."
- (interactive "p")
- (when (and (not minibuffer-default-add-done)
- (functionp minibuffer-default-add-function)
- (< nabs (- (if (listp minibuffer-default)
- (length minibuffer-default)
- 1))))
- (setq minibuffer-default-add-done t
- minibuffer-default (funcall minibuffer-default-add-function)))
- (let ((minimum (if minibuffer-default
- (- (if (listp minibuffer-default)
- (length minibuffer-default)
- 1))
- 0))
- elt minibuffer-returned-to-present)
- (if (and (zerop minibuffer-history-position)
- (null minibuffer-text-before-history))
- (setq minibuffer-text-before-history
- (minibuffer-contents-no-properties)))
- (if (< nabs minimum)
- (user-error (if minibuffer-default
- "End of defaults; no next item"
- "End of history; no default available")))
- (if (> nabs (length (symbol-value minibuffer-history-variable)))
- (user-error "Beginning of history; no preceding item"))
- (unless (memq last-command '(next-history-element
- previous-history-element))
- (let ((prompt-end (minibuffer-prompt-end)))
- (set (make-local-variable 'minibuffer-temporary-goal-position)
- (cond ((<= (point) prompt-end) prompt-end)
- ((eobp) nil)
- (t (point))))))
- (goto-char (point-max))
- (delete-minibuffer-contents)
- (setq minibuffer-history-position nabs)
- (cond ((< nabs 0)
- (setq elt (if (listp minibuffer-default)
- (nth (1- (abs nabs)) minibuffer-default)
- minibuffer-default)))
- ((= nabs 0)
- (setq elt (or minibuffer-text-before-history ""))
- (setq minibuffer-returned-to-present t)
- (setq minibuffer-text-before-history nil))
- (t (setq elt (nth (1- minibuffer-history-position)
- (symbol-value minibuffer-history-variable)))))
- (insert
- (if (and (eq minibuffer-history-sexp-flag (minibuffer-depth))
- (not minibuffer-returned-to-present))
- (let ((print-level nil))
- (prin1-to-string elt))
- elt))
- (goto-char (or minibuffer-temporary-goal-position (point-max)))))
-
-(defun next-history-element (n)
- "Puts next element of the minibuffer history in the minibuffer.
-With argument N, it uses the Nth following element."
- (interactive "p")
- (or (zerop n)
- (goto-history-element (- minibuffer-history-position n))))
-
-(defun previous-history-element (n)
- "Puts previous element of the minibuffer history in the minibuffer.
-With argument N, it uses the Nth previous element."
- (interactive "p")
- (or (zerop n)
- (goto-history-element (+ minibuffer-history-position n))))
-
-(defun next-complete-history-element (n)
- "Get next history element which completes the minibuffer before the point.
-The contents of the minibuffer after the point are deleted, and replaced
-by the new completion."
- (interactive "p")
- (let ((point-at-start (point)))
- (next-matching-history-element
- (concat
- "^" (regexp-quote (buffer-substring (minibuffer-prompt-end) (point))))
- n)
- ;; next-matching-history-element always puts us at (point-min).
- ;; Move to the position we were at before changing the buffer contents.
- ;; This is still sensible, because the text before point has not changed.
- (goto-char point-at-start)))
-
-(defun previous-complete-history-element (n)
- "\
-Get previous history element which completes the minibuffer before the point.
-The contents of the minibuffer after the point are deleted, and replaced
-by the new completion."
- (interactive "p")
- (next-complete-history-element (- n)))
-
-;; For compatibility with the old subr of the same name.
-(defun minibuffer-prompt-width ()
- "Return the display width of the minibuffer prompt.
-Return 0 if current buffer is not a minibuffer."
- ;; Return the width of everything before the field at the end of
- ;; the buffer; this should be 0 for normal buffers.
- (1- (minibuffer-prompt-end)))
-
-;; isearch minibuffer history
-(add-hook 'minibuffer-setup-hook 'minibuffer-history-isearch-setup)
-
-(defvar minibuffer-history-isearch-message-overlay)
-(make-variable-buffer-local 'minibuffer-history-isearch-message-overlay)
-
-(defun minibuffer-history-isearch-setup ()
- "Set up a minibuffer for using isearch to search the minibuffer history.
-Intended to be added to `minibuffer-setup-hook'."
- (set (make-local-variable 'isearch-search-fun-function)
- 'minibuffer-history-isearch-search)
- (set (make-local-variable 'isearch-message-function)
- 'minibuffer-history-isearch-message)
- (set (make-local-variable 'isearch-wrap-function)
- 'minibuffer-history-isearch-wrap)
- (set (make-local-variable 'isearch-push-state-function)
- 'minibuffer-history-isearch-push-state)
- (add-hook 'isearch-mode-end-hook 'minibuffer-history-isearch-end nil t))
-
-(defun minibuffer-history-isearch-end ()
- "Clean up the minibuffer after terminating isearch in the minibuffer."
- (if minibuffer-history-isearch-message-overlay
- (delete-overlay minibuffer-history-isearch-message-overlay)))
-
-(defun minibuffer-history-isearch-search ()
- "Return the proper search function, for isearch in minibuffer history."
- (lambda (string bound noerror)
- (let ((search-fun
- ;; Use standard functions to search within minibuffer text
- (isearch-search-fun-default))
- found)
- ;; Avoid lazy-highlighting matches in the minibuffer prompt when
- ;; searching forward. Lazy-highlight calls this lambda with the
- ;; bound arg, so skip the minibuffer prompt.
- (if (and bound isearch-forward (< (point) (minibuffer-prompt-end)))
- (goto-char (minibuffer-prompt-end)))
- (or
- ;; 1. First try searching in the initial minibuffer text
- (funcall search-fun string
- (if isearch-forward bound (minibuffer-prompt-end))
- noerror)
- ;; 2. If the above search fails, start putting next/prev history
- ;; elements in the minibuffer successively, and search the string
- ;; in them. Do this only when bound is nil (i.e. not while
- ;; lazy-highlighting search strings in the current minibuffer text).
- (unless bound
- (condition-case nil
- (progn
- (while (not found)
- (cond (isearch-forward
- (next-history-element 1)
- (goto-char (minibuffer-prompt-end)))
- (t
- (previous-history-element 1)
- (goto-char (point-max))))
- (setq isearch-barrier (point) isearch-opoint (point))
- ;; After putting the next/prev history element, search
- ;; the string in them again, until next-history-element
- ;; or previous-history-element raises an error at the
- ;; beginning/end of history.
- (setq found (funcall search-fun string
- (unless isearch-forward
- ;; For backward search, don't search
- ;; in the minibuffer prompt
- (minibuffer-prompt-end))
- noerror)))
- ;; Return point of the new search result
- (point))
- ;; Return nil when next(prev)-history-element fails
- (error nil)))))))
-
-(defun minibuffer-history-isearch-message (&optional c-q-hack ellipsis)
- "Display the minibuffer history search prompt.
-If there are no search errors, this function displays an overlay with
-the isearch prompt which replaces the original minibuffer prompt.
-Otherwise, it displays the standard isearch message returned from
-the function `isearch-message'."
- (if (not (and (minibufferp) isearch-success (not isearch-error)))
- ;; Use standard function `isearch-message' when not in the minibuffer,
- ;; or search fails, or has an error (like incomplete regexp).
- ;; This function overwrites minibuffer text with isearch message,
- ;; so it's possible to see what is wrong in the search string.
- (isearch-message c-q-hack ellipsis)
- ;; Otherwise, put the overlay with the standard isearch prompt over
- ;; the initial minibuffer prompt.
- (if (overlayp minibuffer-history-isearch-message-overlay)
- (move-overlay minibuffer-history-isearch-message-overlay
- (point-min) (minibuffer-prompt-end))
- (setq minibuffer-history-isearch-message-overlay
- (make-overlay (point-min) (minibuffer-prompt-end)))
- (overlay-put minibuffer-history-isearch-message-overlay 'evaporate t))
- (overlay-put minibuffer-history-isearch-message-overlay
- 'display (isearch-message-prefix c-q-hack ellipsis))
- ;; And clear any previous isearch message.
- (message "")))
-
-(defun minibuffer-history-isearch-wrap ()
- "Wrap the minibuffer history search when search fails.
-Move point to the first history element for a forward search,
-or to the last history element for a backward search."
- ;; When `minibuffer-history-isearch-search' fails on reaching the
- ;; beginning/end of the history, wrap the search to the first/last
- ;; minibuffer history element.
- (if isearch-forward
- (goto-history-element (length (symbol-value
minibuffer-history-variable)))
- (goto-history-element 0))
- (setq isearch-success t)
- (goto-char (if isearch-forward (minibuffer-prompt-end) (point-max))))
-
-(defun minibuffer-history-isearch-push-state ()
- "Save a function restoring the state of minibuffer history search.
-Save `minibuffer-history-position' to the additional state parameter
-in the search status stack."
- (let ((pos minibuffer-history-position))
- (lambda (cmd)
- (minibuffer-history-isearch-pop-state cmd pos))))
-
-(defun minibuffer-history-isearch-pop-state (_cmd hist-pos)
- "Restore the minibuffer history search state.
-Go to the history element by the absolute history position HIST-POS."
- (goto-history-element hist-pos))
-
-
-;Put this on C-x u, so we can force that rather than C-_ into startup msg
-(define-obsolete-function-alias 'advertised-undo 'undo "23.2")
-
-(defconst undo-equiv-table (make-hash-table :test 'eq :weakness t)
- "Table mapping redo records to the corresponding undo one.
-A redo record for undo-in-region maps to t.
-A redo record for ordinary undo maps to the following (earlier) undo.")
-
-(defvar undo-in-region nil
- "Non-nil if `pending-undo-list' is not just a tail of `buffer-undo-list'.")
-
-(defvar undo-no-redo nil
- "If t, `undo' doesn't go through redo entries.")
-
-(defvar pending-undo-list nil
- "Within a run of consecutive undo commands, list remaining to be undone.
-If t, we undid all the way to the end of it.")
-
-(defun undo (&optional arg)
- "Undo some previous changes.
-Repeat this command to undo more changes.
-A numeric ARG serves as a repeat count.
-
-In Transient Mark mode when the mark is active, only undo changes within
-the current region. Similarly, when not in Transient Mark mode, just
\\[universal-argument]
-as an argument limits undo to changes within the current region."
- (interactive "*P")
- ;; Make last-command indicate for the next command that this was an undo.
- ;; That way, another undo will undo more.
- ;; If we get to the end of the undo history and get an error,
- ;; another undo command will find the undo history empty
- ;; and will get another error. To begin undoing the undos,
- ;; you must type some other command.
- (let* ((modified (buffer-modified-p))
- ;; For an indirect buffer, look in the base buffer for the
- ;; auto-save data.
- (base-buffer (or (buffer-base-buffer) (current-buffer)))
- (recent-save (with-current-buffer base-buffer
- (recent-auto-save-p)))
- message)
- ;; If we get an error in undo-start,
- ;; the next command should not be a "consecutive undo".
- ;; So set `this-command' to something other than `undo'.
- (setq this-command 'undo-start)
-
- (unless (and (eq last-command 'undo)
- (or (eq pending-undo-list t)
- ;; If something (a timer or filter?) changed the buffer
- ;; since the previous command, don't continue the undo seq.
- (let ((list buffer-undo-list))
- (while (eq (car list) nil)
- (setq list (cdr list)))
- ;; If the last undo record made was made by undo
- ;; it shows nothing else happened in between.
- (gethash list undo-equiv-table))))
- (setq undo-in-region
- (or (region-active-p) (and arg (not (numberp arg)))))
- (if undo-in-region
- (undo-start (region-beginning) (region-end))
- (undo-start))
- ;; get rid of initial undo boundary
- (undo-more 1))
- ;; If we got this far, the next command should be a consecutive undo.
- (setq this-command 'undo)
- ;; Check to see whether we're hitting a redo record, and if
- ;; so, ask the user whether she wants to skip the redo/undo pair.
- (let ((equiv (gethash pending-undo-list undo-equiv-table)))
- (or (eq (selected-window) (minibuffer-window))
- (setq message (format "%s%s!"
- (if (or undo-no-redo (not equiv))
- "Undo" "Redo")
- (if undo-in-region " in region" ""))))
- (when (and (consp equiv) undo-no-redo)
- ;; The equiv entry might point to another redo record if we have done
- ;; undo-redo-undo-redo-... so skip to the very last equiv.
- (while (let ((next (gethash equiv undo-equiv-table)))
- (if next (setq equiv next))))
- (setq pending-undo-list equiv)))
- (undo-more
- (if (numberp arg)
- (prefix-numeric-value arg)
- 1))
- ;; Record the fact that the just-generated undo records come from an
- ;; undo operation--that is, they are redo records.
- ;; In the ordinary case (not within a region), map the redo
- ;; record to the following undos.
- ;; I don't know how to do that in the undo-in-region case.
- (let ((list buffer-undo-list))
- ;; Strip any leading undo boundaries there might be, like we do
- ;; above when checking.
- (while (eq (car list) nil)
- (setq list (cdr list)))
- (puthash list
- ;; Prevent identity mapping. This can happen if
- ;; consecutive nils are erroneously in undo list.
- (if (or undo-in-region (eq list pending-undo-list))
- t
- pending-undo-list)
- undo-equiv-table))
- ;; Don't specify a position in the undo record for the undo command.
- ;; Instead, undoing this should move point to where the change is.
- (let ((tail buffer-undo-list)
- (prev nil))
- (while (car tail)
- (when (integerp (car tail))
- (let ((pos (car tail)))
- (if prev
- (setcdr prev (cdr tail))
- (setq buffer-undo-list (cdr tail)))
- (setq tail (cdr tail))
- (while (car tail)
- (if (eq pos (car tail))
- (if prev
- (setcdr prev (cdr tail))
- (setq buffer-undo-list (cdr tail)))
- (setq prev tail))
- (setq tail (cdr tail)))
- (setq tail nil)))
- (setq prev tail tail (cdr tail))))
- ;; Record what the current undo list says,
- ;; so the next command can tell if the buffer was modified in between.
- (and modified (not (buffer-modified-p))
- (with-current-buffer base-buffer
- (delete-auto-save-file-if-necessary recent-save)))
- ;; Display a message announcing success.
- (if message
- (message "%s" message))))
-
-(defun buffer-disable-undo (&optional buffer)
- "Make BUFFER stop keeping undo information.
-No argument or nil as argument means do this for the current buffer."
- (interactive)
- (with-current-buffer (if buffer (get-buffer buffer) (current-buffer))
- (setq buffer-undo-list t)))
-
-(defun undo-only (&optional arg)
- "Undo some previous changes.
-Repeat this command to undo more changes.
-A numeric ARG serves as a repeat count.
-Contrary to `undo', this will not redo a previous undo."
- (interactive "*p")
- (let ((undo-no-redo t)) (undo arg)))
-
-(defvar undo-in-progress nil
- "Non-nil while performing an undo.
-Some change-hooks test this variable to do something different.")
-
-(defun undo-more (n)
- "Undo back N undo-boundaries beyond what was already undone recently.
-Call `undo-start' to get ready to undo recent changes,
-then call `undo-more' one or more times to undo them."
- (or (listp pending-undo-list)
- (user-error (concat "No further undo information"
- (and undo-in-region " for region"))))
- (let ((undo-in-progress t))
- ;; Note: The following, while pulling elements off
- ;; `pending-undo-list' will call primitive change functions which
- ;; will push more elements onto `buffer-undo-list'.
- (setq pending-undo-list (primitive-undo n pending-undo-list))
- (if (null pending-undo-list)
- (setq pending-undo-list t))))
-
-(defun primitive-undo (n list)
- "Undo N records from the front of the list LIST.
-Return what remains of the list."
-
- ;; This is a good feature, but would make undo-start
- ;; unable to do what is expected.
- ;;(when (null (car (list)))
- ;; ;; If the head of the list is a boundary, it is the boundary
- ;; ;; preceding this command. Get rid of it and don't count it.
- ;; (setq list (cdr list))))
-
- (let ((arg n)
- ;; In a writable buffer, enable undoing read-only text that is
- ;; so because of text properties.
- (inhibit-read-only t)
- ;; Don't let `intangible' properties interfere with undo.
- (inhibit-point-motion-hooks t)
- ;; We use oldlist only to check for EQ. ++kfs
- (oldlist buffer-undo-list)
- (did-apply nil)
- (next nil))
- (while (> arg 0)
- (while (setq next (pop list)) ;Exit inner loop at undo boundary.
- ;; Handle an integer by setting point to that value.
- (pcase next
- ((pred integerp) (goto-char next))
- ;; Element (t . TIME) records previous modtime.
- ;; Preserve any flag of NONEXISTENT_MODTIME_NSECS or
- ;; UNKNOWN_MODTIME_NSECS.
- (`(t . ,time)
- ;; If this records an obsolete save
- ;; (not matching the actual disk file)
- ;; then don't mark unmodified.
- (when (or (equal time (visited-file-modtime))
- (and (consp time)
- (equal (list (car time) (cdr time))
- (visited-file-modtime))))
- (when (fboundp 'unlock-buffer)
- (unlock-buffer))
- (set-buffer-modified-p nil)))
- ;; Element (nil PROP VAL BEG . END) is property change.
- (`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare))
- (when (or (> (point-min) beg) (< (point-max) end))
- (error "Changes to be undone are outside visible portion of
buffer"))
- (put-text-property beg end prop val))
- ;; Element (BEG . END) means range was inserted.
- (`(,(and beg (pred integerp)) . ,(and end (pred integerp)))
- ;; (and `(,beg . ,end) `(,(pred integerp) . ,(pred integerp)))
- ;; Ideally: `(,(pred integerp beg) . ,(pred integerp end))
- (when (or (> (point-min) beg) (< (point-max) end))
- (error "Changes to be undone are outside visible portion of
buffer"))
- ;; Set point first thing, so that undoing this undo
- ;; does not send point back to where it is now.
- (goto-char beg)
- (delete-region beg end))
- ;; Element (apply FUN . ARGS) means call FUN to undo.
- (`(apply . ,fun-args)
- (let ((currbuff (current-buffer)))
- (if (integerp (car fun-args))
- ;; Long format: (apply DELTA START END FUN . ARGS).
- (pcase-let* ((`(,delta ,start ,end ,fun . ,args) fun-args)
- (start-mark (copy-marker start nil))
- (end-mark (copy-marker end t)))
- (when (or (> (point-min) start) (< (point-max) end))
- (error "Changes to be undone are outside visible portion
of buffer"))
- (apply fun args) ;; Use `save-current-buffer'?
- ;; Check that the function did what the entry
- ;; said it would do.
- (unless (and (= start start-mark)
- (= (+ delta end) end-mark))
- (error "Changes to be undone by function different than
announced"))
- (set-marker start-mark nil)
- (set-marker end-mark nil))
- (apply fun-args))
- (unless (eq currbuff (current-buffer))
- (error "Undo function switched buffer"))
- (setq did-apply t)))
- ;; Element (STRING . POS) means STRING was deleted.
- (`(,(and string (pred stringp)) . ,(and pos (pred integerp)))
- (when (let ((apos (abs pos)))
- (or (< apos (point-min)) (> apos (point-max))))
- (error "Changes to be undone are outside visible portion of
buffer"))
- (let (valid-marker-adjustments)
- ;; Check that marker adjustments which were recorded
- ;; with the (STRING . POS) record are still valid, ie
- ;; the markers haven't moved. We check their validity
- ;; before reinserting the string so as we don't need to
- ;; mind marker insertion-type.
- (while (and (markerp (car-safe (car list)))
- (integerp (cdr-safe (car list))))
- (let* ((marker-adj (pop list))
- (m (car marker-adj)))
- (and (eq (marker-buffer m) (current-buffer))
- (= pos m)
- (push marker-adj valid-marker-adjustments))))
- ;; Insert string and adjust point
- (if (< pos 0)
- (progn
- (goto-char (- pos))
- (insert string))
- (goto-char pos)
- (insert string)
- (goto-char pos))
- ;; Adjust the valid marker adjustments
- (dolist (adj valid-marker-adjustments)
- (set-marker (car adj)
- (- (car adj) (cdr adj))))))
- ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.
- (`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))
- (warn "Encountered %S entry in undo list with no matching (TEXT .
POS) entry"
- next)
- ;; Even though these elements are not expected in the undo
- ;; list, adjust them to be conservative for the 24.4
- ;; release. (Bug#16818)
- (when (marker-buffer marker)
- (set-marker marker
- (- marker offset)
- (marker-buffer marker))))
- (_ (error "Unrecognized entry in undo list %S" next))))
- (setq arg (1- arg)))
- ;; Make sure an apply entry produces at least one undo entry,
- ;; so the test in `undo' for continuing an undo series
- ;; will work right.
- (if (and did-apply
- (eq oldlist buffer-undo-list))
- (setq buffer-undo-list
- (cons (list 'apply 'cdr nil) buffer-undo-list))))
- list)
-
-;; Deep copy of a list
-(defun undo-copy-list (list)
- "Make a copy of undo list LIST."
- (mapcar 'undo-copy-list-1 list))
-
-(defun undo-copy-list-1 (elt)
- (if (consp elt)
- (cons (car elt) (undo-copy-list-1 (cdr elt)))
- elt))
-
-(defun undo-start (&optional beg end)
- "Set `pending-undo-list' to the front of the undo list.
-The next call to `undo-more' will undo the most recently made change.
-If BEG and END are specified, then only undo elements
-that apply to text between BEG and END are used; other undo elements
-are ignored. If BEG and END are nil, all undo elements are used."
- (if (eq buffer-undo-list t)
- (user-error "No undo information in this buffer"))
- (setq pending-undo-list
- (if (and beg end (not (= beg end)))
- (undo-make-selective-list (min beg end) (max beg end))
- buffer-undo-list)))
-
-(defun undo-make-selective-list (start end)
- "Return a list of undo elements for the region START to END.
-The elements come from `buffer-undo-list', but we keep only
-the elements inside this region, and discard those outside this region.
-If we find an element that crosses an edge of this region,
-we stop and ignore all further elements."
- (let ((undo-list-copy (undo-copy-list buffer-undo-list))
- (undo-list (list nil))
- some-rejected
- undo-elt temp-undo-list delta)
- (while undo-list-copy
- (setq undo-elt (car undo-list-copy))
- (let ((keep-this
- (cond ((and (consp undo-elt) (eq (car undo-elt) t))
- ;; This is a "was unmodified" element.
- ;; Keep it if we have kept everything thus far.
- (not some-rejected))
- ;; Skip over marker adjustments, instead relying on
- ;; finding them after (TEXT . POS) elements
- ((markerp (car-safe undo-elt))
- nil)
- (t
- (undo-elt-in-region undo-elt start end)))))
- (if keep-this
- (progn
- (setq end (+ end (cdr (undo-delta undo-elt))))
- ;; Don't put two nils together in the list
- (when (not (and (eq (car undo-list) nil)
- (eq undo-elt nil)))
- (setq undo-list (cons undo-elt undo-list))
- ;; If (TEXT . POS), "keep" its subsequent (MARKER
- ;; . ADJUSTMENT) whose markers haven't moved.
- (when (and (stringp (car-safe undo-elt))
- (integerp (cdr-safe undo-elt)))
- (let ((list-i (cdr undo-list-copy)))
- (while (markerp (car-safe (car list-i)))
- (let* ((adj-elt (pop list-i))
- (m (car adj-elt)))
- (and (eq (marker-buffer m) (current-buffer))
- (= (cdr undo-elt) m)
- (push adj-elt undo-list))))))))
- (if (undo-elt-crosses-region undo-elt start end)
- (setq undo-list-copy nil)
- (setq some-rejected t)
- (setq temp-undo-list (cdr undo-list-copy))
- (setq delta (undo-delta undo-elt))
-
- (when (/= (cdr delta) 0)
- (let ((position (car delta))
- (offset (cdr delta)))
-
- ;; Loop down the earlier events adjusting their buffer
- ;; positions to reflect the fact that a change to the buffer
- ;; isn't being undone. We only need to process those element
- ;; types which undo-elt-in-region will return as being in
- ;; the region since only those types can ever get into the
- ;; output
-
- (while temp-undo-list
- (setq undo-elt (car temp-undo-list))
- (cond ((integerp undo-elt)
- (if (>= undo-elt position)
- (setcar temp-undo-list (- undo-elt offset))))
- ((atom undo-elt) nil)
- ((stringp (car undo-elt))
- ;; (TEXT . POSITION)
- (let ((text-pos (abs (cdr undo-elt)))
- (point-at-end (< (cdr undo-elt) 0 )))
- (if (>= text-pos position)
- (setcdr undo-elt (* (if point-at-end -1 1)
- (- text-pos offset))))))
- ((integerp (car undo-elt))
- ;; (BEGIN . END)
- (when (>= (car undo-elt) position)
- (setcar undo-elt (- (car undo-elt) offset))
- (setcdr undo-elt (- (cdr undo-elt) offset))))
- ((null (car undo-elt))
- ;; (nil PROPERTY VALUE BEG . END)
- (let ((tail (nthcdr 3 undo-elt)))
- (when (>= (car tail) position)
- (setcar tail (- (car tail) offset))
- (setcdr tail (- (cdr tail) offset))))))
- (setq temp-undo-list (cdr temp-undo-list))))))))
- (setq undo-list-copy (cdr undo-list-copy)))
- (nreverse undo-list)))
-
-(defun undo-elt-in-region (undo-elt start end)
- "Determine whether UNDO-ELT falls inside the region START ... END.
-If it crosses the edge, we return nil.
-
-Generally this function is not useful for determining
-whether (MARKER . ADJUSTMENT) undo elements are in the region,
-because markers can be arbitrarily relocated. Instead, pass the
-marker adjustment's corresponding (TEXT . POS) element."
- (cond ((integerp undo-elt)
- (and (>= undo-elt start)
- (<= undo-elt end)))
- ((eq undo-elt nil)
- t)
- ((atom undo-elt)
- nil)
- ((stringp (car undo-elt))
- ;; (TEXT . POSITION)
- (and (>= (abs (cdr undo-elt)) start)
- (<= (abs (cdr undo-elt)) end)))
- ((and (consp undo-elt) (markerp (car undo-elt)))
- ;; (MARKER . ADJUSTMENT)
- (<= start (car undo-elt) end))
- ((null (car undo-elt))
- ;; (nil PROPERTY VALUE BEG . END)
- (let ((tail (nthcdr 3 undo-elt)))
- (and (>= (car tail) start)
- (<= (cdr tail) end))))
- ((integerp (car undo-elt))
- ;; (BEGIN . END)
- (and (>= (car undo-elt) start)
- (<= (cdr undo-elt) end)))))
-
-(defun undo-elt-crosses-region (undo-elt start end)
- "Test whether UNDO-ELT crosses one edge of that region START ... END.
-This assumes we have already decided that UNDO-ELT
-is not *inside* the region START...END."
- (cond ((atom undo-elt) nil)
- ((null (car undo-elt))
- ;; (nil PROPERTY VALUE BEG . END)
- (let ((tail (nthcdr 3 undo-elt)))
- (and (< (car tail) end)
- (> (cdr tail) start))))
- ((integerp (car undo-elt))
- ;; (BEGIN . END)
- (and (< (car undo-elt) end)
- (> (cdr undo-elt) start)))))
-
-;; Return the first affected buffer position and the delta for an undo element
-;; delta is defined as the change in subsequent buffer positions if we *did*
-;; the undo.
-(defun undo-delta (undo-elt)
- (if (consp undo-elt)
- (cond ((stringp (car undo-elt))
- ;; (TEXT . POSITION)
- (cons (abs (cdr undo-elt)) (length (car undo-elt))))
- ((integerp (car undo-elt))
- ;; (BEGIN . END)
- (cons (car undo-elt) (- (car undo-elt) (cdr undo-elt))))
- (t
- '(0 . 0)))
- '(0 . 0)))
-
-(defcustom undo-ask-before-discard nil
- "If non-nil ask about discarding undo info for the current command.
-Normally, Emacs discards the undo info for the current command if
-it exceeds `undo-outer-limit'. But if you set this option
-non-nil, it asks in the echo area whether to discard the info.
-If you answer no, there is a slight risk that Emacs might crash, so
-only do it if you really want to undo the command.
-
-This option is mainly intended for debugging. You have to be
-careful if you use it for other purposes. Garbage collection is
-inhibited while the question is asked, meaning that Emacs might
-leak memory. So you should make sure that you do not wait
-excessively long before answering the question."
- :type 'boolean
- :group 'undo
- :version "22.1")
-
-(defvar undo-extra-outer-limit nil
- "If non-nil, an extra level of size that's ok in an undo item.
-We don't ask the user about truncating the undo list until the
-current item gets bigger than this amount.
-
-This variable only matters if `undo-ask-before-discard' is non-nil.")
-(make-variable-buffer-local 'undo-extra-outer-limit)
-
-;; When the first undo batch in an undo list is longer than
-;; undo-outer-limit, this function gets called to warn the user that
-;; the undo info for the current command was discarded. Garbage
-;; collection is inhibited around the call, so it had better not do a
-;; lot of consing.
-(setq undo-outer-limit-function 'undo-outer-limit-truncate)
-(defun undo-outer-limit-truncate (size)
- (if undo-ask-before-discard
- (when (or (null undo-extra-outer-limit)
- (> size undo-extra-outer-limit))
- ;; Don't ask the question again unless it gets even bigger.
- ;; This applies, in particular, if the user quits from the question.
- ;; Such a quit quits out of GC, but something else will call GC
- ;; again momentarily. It will call this function again,
- ;; but we don't want to ask the question again.
- (setq undo-extra-outer-limit (+ size 50000))
- (if (let (use-dialog-box track-mouse executing-kbd-macro )
- (yes-or-no-p (format "Buffer `%s' undo info is %d bytes long;
discard it? "
- (buffer-name) size)))
- (progn (setq buffer-undo-list nil)
- (setq undo-extra-outer-limit nil)
- t)
- nil))
- (display-warning '(undo discard-info)
- (concat
- (format "Buffer `%s' undo info was %d bytes long.\n"
- (buffer-name) size)
- "The undo info was discarded because it exceeded \
-`undo-outer-limit'.
-
-This is normal if you executed a command that made a huge change
-to the buffer. In that case, to prevent similar problems in the
-future, set `undo-outer-limit' to a value that is large enough to
-cover the maximum size of normal changes you expect a single
-command to make, but not so large that it might exceed the
-maximum memory allotted to Emacs.
-
-If you did not execute any such command, the situation is
-probably due to a bug and you should report it.
-
-You can disable the popping up of this buffer by adding the entry
-\(undo discard-info) to the user option `warning-suppress-types',
-which is defined in the `warnings' library.\n")
- :warning)
- (setq buffer-undo-list nil)
- t))
-
-(defcustom password-word-equivalents
- '("password" "passcode" "passphrase" "pass phrase"
- ; These are sorted according to the GNU en_US locale.
- "암호" ; ko
- "パスワード" ; ja
- "ପ୍ରବେଶ ସଙ୍କେତ" ; or
- "ពាក្យសម្ងាត់" ; km
- "adgangskode" ; da
- "contraseña" ; es
- "contrasenya" ; ca
- "geslo" ; sl
- "hasło" ; pl
- "heslo" ; cs, sk
- "iphasiwedi" ; zu
- "jelszó" ; hu
- "lösenord" ; sv
- "lozinka" ; hr, sr
- "mật khẩu" ; vi
- "mot de passe" ; fr
- "parola" ; tr
- "pasahitza" ; eu
- "passord" ; nb
- "passwort" ; de
- "pasvorto" ; eo
- "salasana" ; fi
- "senha" ; pt
- "slaptažodis" ; lt
- "wachtwoord" ; nl
- "كلمة السر" ; ar
- "ססמה" ; he
- "лозинка" ; sr
- "пароль" ; kk, ru, uk
- "गुप्तशब्द" ; mr
- "शब्दकूट" ; hi
- "પાસવર્ડ" ; gu
- "సంకేతపదము" ; te
- "ਪਾਸਵਰਡ" ; pa
- "ಗುಪ್ತಪದ" ; kn
- "கடவுச்சொல்" ; ta
- "അടയാളവാക്ക്" ; ml
- "গুপ্তশব্দ" ; as
- "পাসওয়ার্ড" ; bn_IN
- "රහස්පදය" ; si
- "密码" ; zh_CN
- "密碼" ; zh_TW
- )
- "List of words equivalent to \"password\".
-This is used by Shell mode and other parts of Emacs to recognize
-password prompts, including prompts in languages other than
-English. Different case choices should not be assumed to be
-included; callers should bind `case-fold-search' to t."
- :type '(repeat string)
- :version "24.4"
- :group 'processes)
-
-(defvar shell-command-history nil
- "History list for some commands that read shell commands.
-
-Maximum length of the history list is determined by the value
-of `history-length', which see.")
-
-(defvar shell-command-switch (purecopy "-c")
- "Switch used to have the shell execute its command line argument.")
-
-(defvar shell-command-default-error-buffer nil
- "Buffer name for `shell-command' and `shell-command-on-region' error output.
-This buffer is used when `shell-command' or `shell-command-on-region'
-is run interactively. A value of nil means that output to stderr and
-stdout will be intermixed in the output stream.")
-
-(declare-function mailcap-file-default-commands "mailcap" (files))
-(declare-function dired-get-filename "dired" (&optional localp
no-error-if-not-filep))
-
-(defun minibuffer-default-add-shell-commands ()
- "Return a list of all commands associated with the current file.
-This function is used to add all related commands retrieved by `mailcap'
-to the end of the list of defaults just after the default value."
- (interactive)
- (let* ((filename (if (listp minibuffer-default)
- (car minibuffer-default)
- minibuffer-default))
- (commands (and filename (require 'mailcap nil t)
- (mailcap-file-default-commands (list filename)))))
- (setq commands (mapcar (lambda (command)
- (concat command " " filename))
- commands))
- (if (listp minibuffer-default)
- (append minibuffer-default commands)
- (cons minibuffer-default commands))))
-
-(declare-function shell-completion-vars "shell" ())
-
-(defvar minibuffer-local-shell-command-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (define-key map "\t" 'completion-at-point)
- map)
- "Keymap used for completing shell commands in minibuffer.")
-
-(defun read-shell-command (prompt &optional initial-contents hist &rest args)
- "Read a shell command from the minibuffer.
-The arguments are the same as the ones of `read-from-minibuffer',
-except READ and KEYMAP are missing and HIST defaults
-to `shell-command-history'."
- (require 'shell)
- (minibuffer-with-setup-hook
- (lambda ()
- (shell-completion-vars)
- (set (make-local-variable 'minibuffer-default-add-function)
- 'minibuffer-default-add-shell-commands))
- (apply 'read-from-minibuffer prompt initial-contents
- minibuffer-local-shell-command-map
- nil
- (or hist 'shell-command-history)
- args)))
-
-(defcustom async-shell-command-buffer 'confirm-new-buffer
- "What to do when the output buffer is used by another shell command.
-This option specifies how to resolve the conflict where a new command
-wants to direct its output to the buffer `*Async Shell Command*',
-but this buffer is already taken by another running shell command.
-
-The value `confirm-kill-process' is used to ask for confirmation before
-killing the already running process and running a new process
-in the same buffer, `confirm-new-buffer' for confirmation before running
-the command in a new buffer with a name other than the default buffer name,
-`new-buffer' for doing the same without confirmation,
-`confirm-rename-buffer' for confirmation before renaming the existing
-output buffer and running a new command in the default buffer,
-`rename-buffer' for doing the same without confirmation."
- :type '(choice (const :tag "Confirm killing of running command"
- confirm-kill-process)
- (const :tag "Confirm creation of a new buffer"
- confirm-new-buffer)
- (const :tag "Create a new buffer"
- new-buffer)
- (const :tag "Confirm renaming of existing buffer"
- confirm-rename-buffer)
- (const :tag "Rename the existing buffer"
- rename-buffer))
- :group 'shell
- :version "24.3")
-
-(defun async-shell-command (command &optional output-buffer error-buffer)
- "Execute string COMMAND asynchronously in background.
-
-Like `shell-command', but adds `&' at the end of COMMAND
-to execute it asynchronously.
-
-The output appears in the buffer `*Async Shell Command*'.
-That buffer is in shell mode.
-
-You can configure `async-shell-command-buffer' to specify what to do in
-case when `*Async Shell Command*' buffer is already taken by another
-running shell command. To run COMMAND without displaying the output
-in a window you can configure `display-buffer-alist' to use the action
-`display-buffer-no-window' for the buffer `*Async Shell Command*'.
-
-In Elisp, you will often be better served by calling `start-process'
-directly, since it offers more control and does not impose the use of a
-shell (with its need to quote arguments)."
- (interactive
- (list
- (read-shell-command "Async shell command: " nil nil
- (let ((filename
- (cond
- (buffer-file-name)
- ((eq major-mode 'dired-mode)
- (dired-get-filename nil t)))))
- (and filename (file-relative-name filename))))
- current-prefix-arg
- shell-command-default-error-buffer))
- (unless (string-match "&[ \t]*\\'" command)
- (setq command (concat command " &")))
- (shell-command command output-buffer error-buffer))
-
-(defun shell-command (command &optional output-buffer error-buffer)
- "Execute string COMMAND in inferior shell; display output, if any.
-With prefix argument, insert the COMMAND's output at point.
-
-If COMMAND ends in `&', execute it asynchronously.
-The output appears in the buffer `*Async Shell Command*'.
-That buffer is in shell mode. You can also use
-`async-shell-command' that automatically adds `&'.
-
-Otherwise, COMMAND is executed synchronously. The output appears in
-the buffer `*Shell Command Output*'. If the output is short enough to
-display in the echo area (which is determined by the variables
-`resize-mini-windows' and `max-mini-window-height'), it is shown
-there, but it is nonetheless available in buffer `*Shell Command
-Output*' even though that buffer is not automatically displayed.
-
-To specify a coding system for converting non-ASCII characters
-in the shell command output, use \\[universal-coding-system-argument] \
-before this command.
-
-Noninteractive callers can specify coding systems by binding
-`coding-system-for-read' and `coding-system-for-write'.
-
-The optional second argument OUTPUT-BUFFER, if non-nil,
-says to put the output in some other buffer.
-If OUTPUT-BUFFER is a buffer or buffer name, put the output there.
-If OUTPUT-BUFFER is not a buffer and not nil,
-insert output in current buffer. (This cannot be done asynchronously.)
-In either case, the buffer is first erased, and the output is
-inserted after point (leaving mark after it).
-
-If the command terminates without error, but generates output,
-and you did not specify \"insert it in the current buffer\",
-the output can be displayed in the echo area or in its buffer.
-If the output is short enough to display in the echo area
-\(determined by the variable `max-mini-window-height' if
-`resize-mini-windows' is non-nil), it is shown there.
-Otherwise,the buffer containing the output is displayed.
-
-If there is output and an error, and you did not specify \"insert it
-in the current buffer\", a message about the error goes at the end
-of the output.
-
-If there is no output, or if output is inserted in the current buffer,
-then `*Shell Command Output*' is deleted.
-
-If the optional third argument ERROR-BUFFER is non-nil, it is a buffer
-or buffer name to which to direct the command's standard error output.
-If it is nil, error output is mingled with regular output.
-In an interactive call, the variable `shell-command-default-error-buffer'
-specifies the value of ERROR-BUFFER.
-
-In Elisp, you will often be better served by calling `call-process' or
-`start-process' directly, since it offers more control and does not impose
-the use of a shell (with its need to quote arguments)."
-
- (interactive
- (list
- (read-shell-command "Shell command: " nil nil
- (let ((filename
- (cond
- (buffer-file-name)
- ((eq major-mode 'dired-mode)
- (dired-get-filename nil t)))))
- (and filename (file-relative-name filename))))
- current-prefix-arg
- shell-command-default-error-buffer))
- ;; Look for a handler in case default-directory is a remote file name.
- (let ((handler
- (find-file-name-handler (directory-file-name default-directory)
- 'shell-command)))
- (if handler
- (funcall handler 'shell-command command output-buffer error-buffer)
- (if (and output-buffer
- (not (or (bufferp output-buffer) (stringp output-buffer))))
- ;; Output goes in current buffer.
- (let ((error-file
- (if error-buffer
- (make-temp-file
- (expand-file-name "scor"
- (or small-temporary-file-directory
- temporary-file-directory)))
- nil)))
- (barf-if-buffer-read-only)
- (push-mark nil t)
- ;; We do not use -f for csh; we will not support broken use of
- ;; .cshrcs. Even the BSD csh manual says to use
- ;; "if ($?prompt) exit" before things which are not useful
- ;; non-interactively. Besides, if someone wants their other
- ;; aliases for shell commands then they can still have them.
- (call-process shell-file-name nil
- (if error-file
- (list t error-file)
- t)
- nil shell-command-switch command)
- (when (and error-file (file-exists-p error-file))
- (if (< 0 (nth 7 (file-attributes error-file)))
- (with-current-buffer (get-buffer-create error-buffer)
- (let ((pos-from-end (- (point-max) (point))))
- (or (bobp)
- (insert "\f\n"))
- ;; Do no formatting while reading error file,
- ;; because that can run a shell command, and we
- ;; don't want that to cause an infinite recursion.
- (format-insert-file error-file nil)
- ;; Put point after the inserted errors.
- (goto-char (- (point-max) pos-from-end)))
- (display-buffer (current-buffer))))
- (delete-file error-file))
- ;; This is like exchange-point-and-mark, but doesn't
- ;; activate the mark. It is cleaner to avoid activation,
- ;; even though the command loop would deactivate the mark
- ;; because we inserted text.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker) (point)
- (current-buffer)))))
- ;; Output goes in a separate buffer.
- ;; Preserve the match data in case called from a program.
- (save-match-data
- (if (string-match "[ \t]*&[ \t]*\\'" command)
- ;; Command ending with ampersand means asynchronous.
- (let ((buffer (get-buffer-create
- (or output-buffer "*Async Shell Command*")))
- (directory default-directory)
- proc)
- ;; Remove the ampersand.
- (setq command (substring command 0 (match-beginning 0)))
- ;; Ask the user what to do with already running process.
- (setq proc (get-buffer-process buffer))
- (when proc
- (cond
- ((eq async-shell-command-buffer 'confirm-kill-process)
- ;; If will kill a process, query first.
- (if (yes-or-no-p "A command is running in the default
buffer. Kill it? ")
- (kill-process proc)
- (error "Shell command in progress")))
- ((eq async-shell-command-buffer 'confirm-new-buffer)
- ;; If will create a new buffer, query first.
- (if (yes-or-no-p "A command is running in the default
buffer. Use a new buffer? ")
- (setq buffer (generate-new-buffer
- (or output-buffer "*Async Shell
Command*")))
- (error "Shell command in progress")))
- ((eq async-shell-command-buffer 'new-buffer)
- ;; It will create a new buffer.
- (setq buffer (generate-new-buffer
- (or output-buffer "*Async Shell Command*"))))
- ((eq async-shell-command-buffer 'confirm-rename-buffer)
- ;; If will rename the buffer, query first.
- (if (yes-or-no-p "A command is running in the default
buffer. Rename it? ")
- (progn
- (with-current-buffer buffer
- (rename-uniquely))
- (setq buffer (get-buffer-create
- (or output-buffer "*Async Shell
Command*"))))
- (error "Shell command in progress")))
- ((eq async-shell-command-buffer 'rename-buffer)
- ;; It will rename the buffer.
- (with-current-buffer buffer
- (rename-uniquely))
- (setq buffer (get-buffer-create
- (or output-buffer "*Async Shell
Command*"))))))
- (with-current-buffer buffer
- (setq buffer-read-only nil)
- ;; Setting buffer-read-only to nil doesn't suffice
- ;; if some text has a non-nil read-only property,
- ;; which comint sometimes adds for prompts.
- (let ((inhibit-read-only t))
- (erase-buffer))
- (display-buffer buffer '(nil (allow-no-window . t)))
- (setq default-directory directory)
- (setq proc (start-process "Shell" buffer shell-file-name
- shell-command-switch command))
- (setq mode-line-process '(":%s"))
- (require 'shell) (shell-mode)
- (set-process-sentinel proc 'shell-command-sentinel)
- ;; Use the comint filter for proper handling of carriage
motion
- ;; (see `comint-inhibit-carriage-motion'),.
- (set-process-filter proc 'comint-output-filter)
- ))
- ;; Otherwise, command is executed synchronously.
- (shell-command-on-region (point) (point) command
- output-buffer nil error-buffer)))))))
-
-(defun display-message-or-buffer (message
- &optional buffer-name not-this-window frame)
- "Display MESSAGE in the echo area if possible, otherwise in a pop-up buffer.
-MESSAGE may be either a string or a buffer.
-
-A buffer is displayed using `display-buffer' if MESSAGE is too long for
-the maximum height of the echo area, as defined by `max-mini-window-height'
-if `resize-mini-windows' is non-nil.
-
-Returns either the string shown in the echo area, or when a pop-up
-buffer is used, the window used to display it.
-
-If MESSAGE is a string, then the optional argument BUFFER-NAME is the
-name of the buffer used to display it in the case where a pop-up buffer
-is used, defaulting to `*Message*'. In the case where MESSAGE is a
-string and it is displayed in the echo area, it is not specified whether
-the contents are inserted into the buffer anyway.
-
-Optional arguments NOT-THIS-WINDOW and FRAME are as for `display-buffer',
-and only used if a buffer is displayed."
- (cond ((and (stringp message) (not (string-match "\n" message)))
- ;; Trivial case where we can use the echo area
- (message "%s" message))
- ((and (stringp message)
- (= (string-match "\n" message) (1- (length message))))
- ;; Trivial case where we can just remove single trailing newline
- (message "%s" (substring message 0 (1- (length message)))))
- (t
- ;; General case
- (with-current-buffer
- (if (bufferp message)
- message
- (get-buffer-create (or buffer-name "*Message*")))
-
- (unless (bufferp message)
- (erase-buffer)
- (insert message))
-
- (let ((lines
- (if (= (buffer-size) 0)
- 0
- (count-screen-lines nil nil nil (minibuffer-window)))))
- (cond ((= lines 0))
- ((and (or (<= lines 1)
- (<= lines
- (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)))
- ;; Don't use the echo area if the output buffer is
- ;; already displayed in the selected frame.
- (not (get-buffer-window (current-buffer))))
- ;; Echo area
- (goto-char (point-max))
- (when (bolp)
- (backward-char 1))
- (message "%s" (buffer-substring (point-min) (point))))
- (t
- ;; Buffer
- (goto-char (point-min))
- (display-buffer (current-buffer)
- not-this-window frame))))))))
-
-
-;; We have a sentinel to prevent insertion of a termination message
-;; in the buffer itself.
-(defun shell-command-sentinel (process signal)
- (if (memq (process-status process) '(exit signal))
- (message "%s: %s."
- (car (cdr (cdr (process-command process))))
- (substring signal 0 -1))))
-
-(defun shell-command-on-region (start end command
- &optional output-buffer replace
- error-buffer display-error-buffer)
- "Execute string COMMAND in inferior shell with region as input.
-Normally display output (if any) in temp buffer `*Shell Command Output*';
-Prefix arg means replace the region with it. Return the exit code of
-COMMAND.
-
-To specify a coding system for converting non-ASCII characters
-in the input and output to the shell command, use
\\[universal-coding-system-argument]
-before this command. By default, the input (from the current buffer)
-is encoded using coding-system specified by `process-coding-system-alist',
-falling back to `default-process-coding-system' if no match for COMMAND
-is found in `process-coding-system-alist'.
-
-Noninteractive callers can specify coding systems by binding
-`coding-system-for-read' and `coding-system-for-write'.
-
-If the command generates output, the output may be displayed
-in the echo area or in a buffer.
-If the output is short enough to display in the echo area
-\(determined by the variable `max-mini-window-height' if
-`resize-mini-windows' is non-nil), it is shown there.
-Otherwise it is displayed in the buffer `*Shell Command Output*'.
-The output is available in that buffer in both cases.
-
-If there is output and an error, a message about the error
-appears at the end of the output. If there is no output, or if
-output is inserted in the current buffer, the buffer `*Shell
-Command Output*' is deleted.
-
-Optional fourth arg OUTPUT-BUFFER specifies where to put the
-command's output. If the value is a buffer or buffer name,
-put the output there. If the value is nil, use the buffer
-`*Shell Command Output*'. Any other value, excluding nil,
-means to insert the output in the current buffer. In either case,
-the output is inserted after point (leaving mark after it).
-
-Optional fifth arg REPLACE, if non-nil, means to insert the
-output in place of text from START to END, putting point and mark
-around it.
-
-Optional sixth arg ERROR-BUFFER, if non-nil, specifies a buffer
-or buffer name to which to direct the command's standard error
-output. If nil, error output is mingled with regular output.
-When called interactively, `shell-command-default-error-buffer'
-is used for ERROR-BUFFER.
-
-Optional seventh arg DISPLAY-ERROR-BUFFER, if non-nil, means to
-display the error buffer if there were any errors. When called
-interactively, this is t."
- (interactive (let (string)
- (unless (mark)
- (error "The mark is not set now, so there is no region"))
- ;; Do this before calling region-beginning
- ;; and region-end, in case subprocess output
- ;; relocates them while we are in the minibuffer.
- (setq string (read-shell-command "Shell command on region: "))
- ;; call-interactively recognizes region-beginning and
- ;; region-end specially, leaving them in the history.
- (list (region-beginning) (region-end)
- string
- current-prefix-arg
- current-prefix-arg
- shell-command-default-error-buffer
- t)))
- (let ((error-file
- (if error-buffer
- (make-temp-file
- (expand-file-name "scor"
- (or small-temporary-file-directory
- temporary-file-directory)))
- nil))
- exit-status)
- (if (or replace
- (and output-buffer
- (not (or (bufferp output-buffer) (stringp output-buffer)))))
- ;; Replace specified region with output from command.
- (let ((swap (and replace (< start end))))
- ;; Don't muck with mark unless REPLACE says we should.
- (goto-char start)
- (and replace (push-mark (point) 'nomsg))
- (setq exit-status
- (call-process-region start end shell-file-name replace
- (if error-file
- (list t error-file)
- t)
- nil shell-command-switch command))
- ;; It is rude to delete a buffer which the command is not using.
- ;; (let ((shell-buffer (get-buffer "*Shell Command Output*")))
- ;; (and shell-buffer (not (eq shell-buffer (current-buffer)))
- ;; (kill-buffer shell-buffer)))
- ;; Don't muck with mark unless REPLACE says we should.
- (and replace swap (exchange-point-and-mark)))
- ;; No prefix argument: put the output in a temp buffer,
- ;; replacing its entire contents.
- (let ((buffer (get-buffer-create
- (or output-buffer "*Shell Command Output*"))))
- (unwind-protect
- (if (eq buffer (current-buffer))
- ;; If the input is the same buffer as the output,
- ;; delete everything but the specified region,
- ;; then replace that region with the output.
- (progn (setq buffer-read-only nil)
- (delete-region (max start end) (point-max))
- (delete-region (point-min) (min start end))
- (setq exit-status
- (call-process-region (point-min) (point-max)
- shell-file-name t
- (if error-file
- (list t error-file)
- t)
- nil shell-command-switch
- command)))
- ;; Clear the output buffer, then run the command with
- ;; output there.
- (let ((directory default-directory))
- (with-current-buffer buffer
- (setq buffer-read-only nil)
- (if (not output-buffer)
- (setq default-directory directory))
- (erase-buffer)))
- (setq exit-status
- (call-process-region start end shell-file-name nil
- (if error-file
- (list buffer error-file)
- buffer)
- nil shell-command-switch command)))
- ;; Report the output.
- (with-current-buffer buffer
- (setq mode-line-process
- (cond ((null exit-status)
- " - Error")
- ((stringp exit-status)
- (format " - Signal [%s]" exit-status))
- ((not (equal 0 exit-status))
- (format " - Exit [%d]" exit-status)))))
- (if (with-current-buffer buffer (> (point-max) (point-min)))
- ;; There's some output, display it
- (display-message-or-buffer buffer)
- ;; No output; error?
- (let ((output
- (if (and error-file
- (< 0 (nth 7 (file-attributes error-file))))
- (format "some error output%s"
- (if shell-command-default-error-buffer
- (format " to the \"%s\" buffer"
- shell-command-default-error-buffer)
- ""))
- "no output")))
- (cond ((null exit-status)
- (message "(Shell command failed with error)"))
- ((equal 0 exit-status)
- (message "(Shell command succeeded with %s)"
- output))
- ((stringp exit-status)
- (message "(Shell command killed by signal %s)"
- exit-status))
- (t
- (message "(Shell command failed with code %d and %s)"
- exit-status output))))
- ;; Don't kill: there might be useful info in the undo-log.
- ;; (kill-buffer buffer)
- ))))
-
- (when (and error-file (file-exists-p error-file))
- (if (< 0 (nth 7 (file-attributes error-file)))
- (with-current-buffer (get-buffer-create error-buffer)
- (let ((pos-from-end (- (point-max) (point))))
- (or (bobp)
- (insert "\f\n"))
- ;; Do no formatting while reading error file,
- ;; because that can run a shell command, and we
- ;; don't want that to cause an infinite recursion.
- (format-insert-file error-file nil)
- ;; Put point after the inserted errors.
- (goto-char (- (point-max) pos-from-end)))
- (and display-error-buffer
- (display-buffer (current-buffer)))))
- (delete-file error-file))
- exit-status))
-
-(defun shell-command-to-string (command)
- "Execute shell command COMMAND and return its output as a string."
- (with-output-to-string
- (with-current-buffer
- standard-output
- (process-file shell-file-name nil t nil shell-command-switch command))))
-
-(defun process-file (program &optional infile buffer display &rest args)
- "Process files synchronously in a separate process.
-Similar to `call-process', but may invoke a file handler based on
-`default-directory'. The current working directory of the
-subprocess is `default-directory'.
-
-File names in INFILE and BUFFER are handled normally, but file
-names in ARGS should be relative to `default-directory', as they
-are passed to the process verbatim. (This is a difference to
-`call-process' which does not support file handlers for INFILE
-and BUFFER.)
-
-Some file handlers might not support all variants, for example
-they might behave as if DISPLAY was nil, regardless of the actual
-value passed."
- (let ((fh (find-file-name-handler default-directory 'process-file))
- lc stderr-file)
- (unwind-protect
- (if fh (apply fh 'process-file program infile buffer display args)
- (when infile (setq lc (file-local-copy infile)))
- (setq stderr-file (when (and (consp buffer) (stringp (cadr buffer)))
- (make-temp-file "emacs")))
- (prog1
- (apply 'call-process program
- (or lc infile)
- (if stderr-file (list (car buffer) stderr-file) buffer)
- display args)
- (when stderr-file (copy-file stderr-file (cadr buffer) t))))
- (when stderr-file (delete-file stderr-file))
- (when lc (delete-file lc)))))
-
-(defvar process-file-side-effects t
- "Whether a call of `process-file' changes remote files.
-
-By default, this variable is always set to `t', meaning that a
-call of `process-file' could potentially change any file on a
-remote host. When set to `nil', a file handler could optimize
-its behavior with respect to remote file attribute caching.
-
-You should only ever change this variable with a let-binding;
-never with `setq'.")
-
-(defun start-file-process (name buffer program &rest program-args)
- "Start a program in a subprocess. Return the process object for it.
-
-Similar to `start-process', but may invoke a file handler based on
-`default-directory'. See Info node `(elisp)Magic File Names'.
-
-This handler ought to run PROGRAM, perhaps on the local host,
-perhaps on a remote host that corresponds to `default-directory'.
-In the latter case, the local part of `default-directory' becomes
-the working directory of the process.
-
-PROGRAM and PROGRAM-ARGS might be file names. They are not
-objects of file handler invocation. File handlers might not
-support pty association, if PROGRAM is nil."
- (let ((fh (find-file-name-handler default-directory 'start-file-process)))
- (if fh (apply fh 'start-file-process name buffer program program-args)
- (apply 'start-process name buffer program program-args))))
-
-;;;; Process menu
-
-(defvar tabulated-list-format)
-(defvar tabulated-list-entries)
-(defvar tabulated-list-sort-key)
-(declare-function tabulated-list-init-header "tabulated-list" ())
-(declare-function tabulated-list-print "tabulated-list"
- (&optional remember-pos))
-
-(defvar process-menu-query-only nil)
-
-(define-derived-mode process-menu-mode tabulated-list-mode "Process Menu"
- "Major mode for listing the processes called by Emacs."
- (setq tabulated-list-format [("Process" 15 t)
- ("Status" 7 t)
- ("Buffer" 15 t)
- ("TTY" 12 t)
- ("Command" 0 t)])
- (make-local-variable 'process-menu-query-only)
- (setq tabulated-list-sort-key (cons "Process" nil))
- (add-hook 'tabulated-list-revert-hook 'list-processes--refresh nil t)
- (tabulated-list-init-header))
-
-(defun list-processes--refresh ()
- "Recompute the list of processes for the Process List buffer.
-Also, delete any process that is exited or signaled."
- (setq tabulated-list-entries nil)
- (dolist (p (process-list))
- (cond ((memq (process-status p) '(exit signal closed))
- (delete-process p))
- ((or (not process-menu-query-only)
- (process-query-on-exit-flag p))
- (let* ((buf (process-buffer p))
- (type (process-type p))
- (name (process-name p))
- (status (symbol-name (process-status p)))
- (buf-label (if (buffer-live-p buf)
- `(,(buffer-name buf)
- face link
- help-echo ,(concat "Visit buffer `"
- (buffer-name buf) "'")
- follow-link t
- process-buffer ,buf
- action process-menu-visit-buffer)
- "--"))
- (tty (or (process-tty-name p) "--"))
- (cmd
- (if (memq type '(network serial))
- (let ((contact (process-contact p t)))
- (if (eq type 'network)
- (format "(%s %s)"
- (if (plist-get contact :type)
- "datagram"
- "network")
- (if (plist-get contact :server)
- (format "server on %s"
- (or
- (plist-get contact :host)
- (plist-get contact :local)))
- (format "connection to %s"
- (plist-get contact :host))))
- (format "(serial port %s%s)"
- (or (plist-get contact :port) "?")
- (let ((speed (plist-get contact :speed)))
- (if speed
- (format " at %s b/s" speed)
- "")))))
- (mapconcat 'identity (process-command p) " "))))
- (push (list p (vector name status buf-label tty cmd))
- tabulated-list-entries))))))
-
-(defun process-menu-visit-buffer (button)
- (display-buffer (button-get button 'process-buffer)))
-
-(defun list-processes (&optional query-only buffer)
- "Display a list of all processes that are Emacs sub-processes.
-If optional argument QUERY-ONLY is non-nil, only processes with
-the query-on-exit flag set are listed.
-Any process listed as exited or signaled is actually eliminated
-after the listing is made.
-Optional argument BUFFER specifies a buffer to use, instead of
-\"*Process List*\".
-The return value is always nil.
-
-This function lists only processes that were launched by Emacs. To
-see other processes running on the system, use `list-system-processes'."
- (interactive)
- (or (fboundp 'process-list)
- (error "Asynchronous subprocesses are not supported on this system"))
- (unless (bufferp buffer)
- (setq buffer (get-buffer-create "*Process List*")))
- (with-current-buffer buffer
- (process-menu-mode)
- (setq process-menu-query-only query-only)
- (list-processes--refresh)
- (tabulated-list-print))
- (display-buffer buffer)
- nil)
-
-(defvar universal-argument-map
- (let ((map (make-sparse-keymap))
- (universal-argument-minus
- ;; For backward compatibility, minus with no modifiers is an ordinary
- ;; command if digits have already been entered.
- `(menu-item "" negative-argument
- :filter ,(lambda (cmd)
- (if (integerp prefix-arg) nil cmd)))))
- (define-key map [switch-frame]
- (lambda (e) (interactive "e")
- (handle-switch-frame e) (universal-argument--mode)))
- (define-key map [?\C-u] 'universal-argument-more)
- (define-key map [?-] universal-argument-minus)
- (define-key map [?0] 'digit-argument)
- (define-key map [?1] 'digit-argument)
- (define-key map [?2] 'digit-argument)
- (define-key map [?3] 'digit-argument)
- (define-key map [?4] 'digit-argument)
- (define-key map [?5] 'digit-argument)
- (define-key map [?6] 'digit-argument)
- (define-key map [?7] 'digit-argument)
- (define-key map [?8] 'digit-argument)
- (define-key map [?9] 'digit-argument)
- (define-key map [kp-0] 'digit-argument)
- (define-key map [kp-1] 'digit-argument)
- (define-key map [kp-2] 'digit-argument)
- (define-key map [kp-3] 'digit-argument)
- (define-key map [kp-4] 'digit-argument)
- (define-key map [kp-5] 'digit-argument)
- (define-key map [kp-6] 'digit-argument)
- (define-key map [kp-7] 'digit-argument)
- (define-key map [kp-8] 'digit-argument)
- (define-key map [kp-9] 'digit-argument)
- (define-key map [kp-subtract] universal-argument-minus)
- map)
- "Keymap used while processing \\[universal-argument].")
-
-(defun universal-argument--mode ()
- (set-transient-map universal-argument-map))
-
-(defun universal-argument ()
- "Begin a numeric argument for the following command.
-Digits or minus sign following \\[universal-argument] make up the numeric
argument.
-\\[universal-argument] following the digits or minus sign ends the argument.
-\\[universal-argument] without digits or minus sign provides 4 as argument.
-Repeating \\[universal-argument] without digits or minus sign
- multiplies the argument by 4 each time.
-For some commands, just \\[universal-argument] by itself serves as a flag
-which is different in effect from any particular numeric argument.
-These commands include \\[set-mark-command] and \\[start-kbd-macro]."
- (interactive)
- (setq prefix-arg (list 4))
- (universal-argument--mode))
-
-(defun universal-argument-more (arg)
- ;; A subsequent C-u means to multiply the factor by 4 if we've typed
- ;; nothing but C-u's; otherwise it means to terminate the prefix arg.
- (interactive "P")
- (setq prefix-arg (if (consp arg)
- (list (* 4 (car arg)))
- (if (eq arg '-)
- (list -4)
- arg)))
- (when (consp prefix-arg) (universal-argument--mode)))
-
-(defun negative-argument (arg)
- "Begin a negative numeric argument for the next command.
-\\[universal-argument] following digits or minus sign ends the argument."
- (interactive "P")
- (setq prefix-arg (cond ((integerp arg) (- arg))
- ((eq arg '-) nil)
- (t '-)))
- (universal-argument--mode))
-
-(defun digit-argument (arg)
- "Part of the numeric argument for the next command.
-\\[universal-argument] following digits or minus sign ends the argument."
- (interactive "P")
- (let* ((char (if (integerp last-command-event)
- last-command-event
- (get last-command-event 'ascii-character)))
- (digit (- (logand char ?\177) ?0)))
- (setq prefix-arg (cond ((integerp arg)
- (+ (* arg 10)
- (if (< arg 0) (- digit) digit)))
- ((eq arg '-)
- ;; Treat -0 as just -, so that -01 will work.
- (if (zerop digit) '- (- digit)))
- (t
- digit))))
- (universal-argument--mode))
-
-
-(defvar filter-buffer-substring-functions nil
- "This variable is a wrapper hook around `buffer-substring--filter'.")
-(make-obsolete-variable 'filter-buffer-substring-functions
- 'filter-buffer-substring-function "24.4")
-
-(defvar filter-buffer-substring-function #'buffer-substring--filter
- "Function to perform the filtering in `filter-buffer-substring'.
-The function is called with the same 3 arguments (BEG END DELETE)
-that `filter-buffer-substring' received. It should return the
-buffer substring between BEG and END, after filtering. If DELETE is
-non-nil, it should delete the text between BEG and END from the buffer.")
-
-(defvar buffer-substring-filters nil
- "List of filter functions for `buffer-substring--filter'.
-Each function must accept a single argument, a string, and return a string.
-The buffer substring is passed to the first function in the list,
-and the return value of each function is passed to the next.
-As a special convention, point is set to the start of the buffer text
-being operated on (i.e., the first argument of `buffer-substring--filter')
-before these functions are called.")
-(make-obsolete-variable 'buffer-substring-filters
- 'filter-buffer-substring-function "24.1")
-
-(defun filter-buffer-substring (beg end &optional delete)
- "Return the buffer substring between BEG and END, after filtering.
-If DELETE is non-nil, delete the text between BEG and END from the buffer.
-
-This calls the function that `filter-buffer-substring-function' specifies
-\(passing the same three arguments that it received) to do the work,
-and returns whatever it does. The default function does no filtering,
-unless a hook has been set.
-
-Use `filter-buffer-substring' instead of `buffer-substring',
-`buffer-substring-no-properties', or `delete-and-extract-region' when
-you want to allow filtering to take place. For example, major or minor
-modes can use `filter-buffer-substring-function' to extract characters
-that are special to a buffer, and should not be copied into other buffers."
- (funcall filter-buffer-substring-function beg end delete))
-
-(defun buffer-substring--filter (beg end &optional delete)
- "Default function to use for `filter-buffer-substring-function'.
-Its arguments and return value are as specified for `filter-buffer-substring'.
-This respects the wrapper hook `filter-buffer-substring-functions',
-and the abnormal hook `buffer-substring-filters'.
-No filtering is done unless a hook says to."
- (with-wrapper-hook filter-buffer-substring-functions (beg end delete)
- (cond
- ((or delete buffer-substring-filters)
- (save-excursion
- (goto-char beg)
- (let ((string (if delete (delete-and-extract-region beg end)
- (buffer-substring beg end))))
- (dolist (filter buffer-substring-filters)
- (setq string (funcall filter string)))
- string)))
- (t
- (buffer-substring beg end)))))
-
-
-;;;; Window system cut and paste hooks.
-
-(defvar interprogram-cut-function nil
- "Function to call to make a killed region available to other programs.
-Most window systems provide a facility for cutting and pasting
-text between different programs, such as the clipboard on X and
-MS-Windows, or the pasteboard on Nextstep/Mac OS.
-
-This variable holds a function that Emacs calls whenever text is
-put in the kill ring, to make the new kill available to other
-programs. The function takes one argument, TEXT, which is a
-string containing the text which should be made available.")
-
-(defvar interprogram-paste-function nil
- "Function to call to get text cut from other programs.
-Most window systems provide a facility for cutting and pasting
-text between different programs, such as the clipboard on X and
-MS-Windows, or the pasteboard on Nextstep/Mac OS.
-
-This variable holds a function that Emacs calls to obtain text
-that other programs have provided for pasting. The function is
-called with no arguments. If no other program has provided text
-to paste, the function should return nil (in which case the
-caller, usually `current-kill', should use the top of the Emacs
-kill ring). If another program has provided text to paste, the
-function should return that text as a string (in which case the
-caller should put this string in the kill ring as the latest
-kill).
-
-The function may also return a list of strings if the window
-system supports multiple selections. The first string will be
-used as the pasted text, but the other will be placed in the kill
-ring for easy access via `yank-pop'.
-
-Note that the function should return a string only if a program
-other than Emacs has provided a string for pasting; if Emacs
-provided the most recent string, the function should return nil.
-If it is difficult to tell whether Emacs or some other program
-provided the current string, it is probably good enough to return
-nil if the string is equal (according to `string=') to the last
-text Emacs provided.")
-
-
-
-;;;; The kill ring data structure.
-
-(defvar kill-ring nil
- "List of killed text sequences.
-Since the kill ring is supposed to interact nicely with cut-and-paste
-facilities offered by window systems, use of this variable should
-interact nicely with `interprogram-cut-function' and
-`interprogram-paste-function'. The functions `kill-new',
-`kill-append', and `current-kill' are supposed to implement this
-interaction; you may want to use them instead of manipulating the kill
-ring directly.")
-
-(defcustom kill-ring-max 60
- "Maximum length of kill ring before oldest elements are thrown away."
- :type 'integer
- :group 'killing)
-
-(defvar kill-ring-yank-pointer nil
- "The tail of the kill ring whose car is the last thing yanked.")
-
-(defcustom save-interprogram-paste-before-kill nil
- "Save clipboard strings into kill ring before replacing them.
-When one selects something in another program to paste it into Emacs,
-but kills something in Emacs before actually pasting it,
-this selection is gone unless this variable is non-nil,
-in which case the other program's selection is saved in the `kill-ring'
-before the Emacs kill and one can still paste it using \\[yank] \\[yank-pop]."
- :type 'boolean
- :group 'killing
- :version "23.2")
-
-(defcustom kill-do-not-save-duplicates nil
- "Do not add a new string to `kill-ring' if it duplicates the last one.
-The comparison is done using `equal-including-properties'."
- :type 'boolean
- :group 'killing
- :version "23.2")
-
-(defun kill-new (string &optional replace)
- "Make STRING the latest kill in the kill ring.
-Set `kill-ring-yank-pointer' to point to it.
-If `interprogram-cut-function' is non-nil, apply it to STRING.
-Optional second argument REPLACE non-nil means that STRING will replace
-the front of the kill ring, rather than being added to the list.
-
-When `save-interprogram-paste-before-kill' and `interprogram-paste-function'
-are non-nil, saves the interprogram paste string(s) into `kill-ring' before
-STRING.
-
-When the yank handler has a non-nil PARAM element, the original STRING
-argument is not used by `insert-for-yank'. However, since Lisp code
-may access and use elements from the kill ring directly, the STRING
-argument should still be a \"useful\" string for such uses."
- (unless (and kill-do-not-save-duplicates
- ;; Due to text properties such as 'yank-handler that
- ;; can alter the contents to yank, comparison using
- ;; `equal' is unsafe.
- (equal-including-properties string (car kill-ring)))
- (if (fboundp 'menu-bar-update-yank-menu)
- (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
- (when save-interprogram-paste-before-kill
- (let ((interprogram-paste (and interprogram-paste-function
- (funcall interprogram-paste-function))))
- (when interprogram-paste
- (dolist (s (if (listp interprogram-paste)
- (nreverse interprogram-paste)
- (list interprogram-paste)))
- (unless (and kill-do-not-save-duplicates
- (equal-including-properties s (car kill-ring)))
- (push s kill-ring))))))
- (unless (and kill-do-not-save-duplicates
- (equal-including-properties string (car kill-ring)))
- (if (and replace kill-ring)
- (setcar kill-ring string)
- (push string kill-ring)
- (if (> (length kill-ring) kill-ring-max)
- (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))))
- (setq kill-ring-yank-pointer kill-ring)
- (if interprogram-cut-function
- (funcall interprogram-cut-function string)))
-
-(defun kill-append (string before-p)
- "Append STRING to the end of the latest kill in the kill ring.
-If BEFORE-P is non-nil, prepend STRING to the kill.
-If `interprogram-cut-function' is set, pass the resulting kill to it."
- (let* ((cur (car kill-ring)))
- (kill-new (if before-p (concat string cur) (concat cur string))
- (or (= (length cur) 0)
- (equal nil (get-text-property 0 'yank-handler cur))))))
-
-(defcustom yank-pop-change-selection nil
- "Whether rotating the kill ring changes the window system selection.
-If non-nil, whenever the kill ring is rotated (usually via the
-`yank-pop' command), Emacs also calls `interprogram-cut-function'
-to copy the new kill to the window system selection."
- :type 'boolean
- :group 'killing
- :version "23.1")
-
-(defun current-kill (n &optional do-not-move)
- "Rotate the yanking point by N places, and then return that kill.
-If N is zero and `interprogram-paste-function' is set to a
-function that returns a string or a list of strings, and if that
-function doesn't return nil, then that string (or list) is added
-to the front of the kill ring and the string (or first string in
-the list) is returned as the latest kill.
-
-If N is not zero, and if `yank-pop-change-selection' is
-non-nil, use `interprogram-cut-function' to transfer the
-kill at the new yank point into the window system selection.
-
-If optional arg DO-NOT-MOVE is non-nil, then don't actually
-move the yanking point; just return the Nth kill forward."
-
- (let ((interprogram-paste (and (= n 0)
- interprogram-paste-function
- (funcall interprogram-paste-function))))
- (if interprogram-paste
- (progn
- ;; Disable the interprogram cut function when we add the new
- ;; text to the kill ring, so Emacs doesn't try to own the
- ;; selection, with identical text.
- (let ((interprogram-cut-function nil))
- (if (listp interprogram-paste)
- (mapc 'kill-new (nreverse interprogram-paste))
- (kill-new interprogram-paste)))
- (car kill-ring))
- (or kill-ring (error "Kill ring is empty"))
- (let ((ARGth-kill-element
- (nthcdr (mod (- n (length kill-ring-yank-pointer))
- (length kill-ring))
- kill-ring)))
- (unless do-not-move
- (setq kill-ring-yank-pointer ARGth-kill-element)
- (when (and yank-pop-change-selection
- (> n 0)
- interprogram-cut-function)
- (funcall interprogram-cut-function (car ARGth-kill-element))))
- (car ARGth-kill-element)))))
-
-
-
-;;;; Commands for manipulating the kill ring.
-
-(defcustom kill-read-only-ok nil
- "Non-nil means don't signal an error for killing read-only text."
- :type 'boolean
- :group 'killing)
-
-(defun kill-region (beg end &optional region)
- "Kill (\"cut\") text between point and mark.
-This deletes the text from the buffer and saves it in the kill ring.
-The command \\[yank] can retrieve it from there.
-\(If you want to save the region without killing it, use \\[kill-ring-save].)
-
-If you want to append the killed region to the last killed text,
-use \\[append-next-kill] before \\[kill-region].
-
-If the buffer is read-only, Emacs will beep and refrain from deleting
-the text, but put the text in the kill ring anyway. This means that
-you can use the killing commands to copy text from a read-only buffer.
-
-Lisp programs should use this function for killing text.
- (To delete text, use `delete-region'.)
-Supply two arguments, character positions indicating the stretch of text
- to be killed.
-Any command that calls this function is a \"kill command\".
-If the previous command was also a kill command,
-the text killed this time appends to the text killed last time
-to make one entry in the kill ring.
-
-The optional argument REGION if non-nil, indicates that we're not just killing
-some text between BEG and END, but we're killing the region."
- ;; Pass mark first, then point, because the order matters when
- ;; calling `kill-append'.
- (interactive (list (mark) (point) 'region))
- (unless (and beg end)
- (error "The mark is not set now, so there is no region"))
- (condition-case nil
- (let ((string (if region
- (funcall region-extract-function 'delete)
- (filter-buffer-substring beg end 'delete))))
- (when string ;STRING is nil if BEG = END
- ;; Add that string to the kill ring, one way or another.
- (if (eq last-command 'kill-region)
- (kill-append string (< end beg))
- (kill-new string nil)))
- (when (or string (eq last-command 'kill-region))
- (setq this-command 'kill-region))
- (setq deactivate-mark t)
- nil)
- ((buffer-read-only text-read-only)
- ;; The code above failed because the buffer, or some of the characters
- ;; in the region, are read-only.
- ;; We should beep, in case the user just isn't aware of this.
- ;; However, there's no harm in putting
- ;; the region's text in the kill ring, anyway.
- (copy-region-as-kill beg end region)
- ;; Set this-command now, so it will be set even if we get an error.
- (setq this-command 'kill-region)
- ;; This should barf, if appropriate, and give us the correct error.
- (if kill-read-only-ok
- (progn (message "Read only text copied to kill ring") nil)
- ;; Signal an error if the buffer is read-only.
- (barf-if-buffer-read-only)
- ;; If the buffer isn't read-only, the text is.
- (signal 'text-read-only (list (current-buffer)))))))
-
-;; copy-region-as-kill no longer sets this-command, because it's confusing
-;; to get two copies of the text when the user accidentally types M-w and
-;; then corrects it with the intended C-w.
-(defun copy-region-as-kill (beg end &optional region)
- "Save the region as if killed, but don't kill it.
-In Transient Mark mode, deactivate the mark.
-If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste.
-
-The optional argument REGION if non-nil, indicates that we're not just copying
-some text between BEG and END, but we're copying the region.
-
-This command's old key binding has been given to `kill-ring-save'."
- ;; Pass mark first, then point, because the order matters when
- ;; calling `kill-append'.
- (interactive (list (mark) (point)
- (prefix-numeric-value current-prefix-arg)))
- (let ((str (if region
- (funcall region-extract-function nil)
- (filter-buffer-substring beg end))))
- (if (eq last-command 'kill-region)
- (kill-append str (< end beg))
- (kill-new str)))
- (setq deactivate-mark t)
- nil)
-
-(defun kill-ring-save (beg end &optional region)
- "Save the region as if killed, but don't kill it.
-In Transient Mark mode, deactivate the mark.
-If `interprogram-cut-function' is non-nil, also save the text for a window
-system cut and paste.
-
-If you want to append the killed line to the last killed text,
-use \\[append-next-kill] before \\[kill-ring-save].
-
-The optional argument REGION if non-nil, indicates that we're not just copying
-some text between BEG and END, but we're copying the region.
-
-This command is similar to `copy-region-as-kill', except that it gives
-visual feedback indicating the extent of the region being copied."
- ;; Pass mark first, then point, because the order matters when
- ;; calling `kill-append'.
- (interactive (list (mark) (point)
- (prefix-numeric-value current-prefix-arg)))
- (copy-region-as-kill beg end region)
- ;; This use of called-interactively-p is correct because the code it
- ;; controls just gives the user visual feedback.
- (if (called-interactively-p 'interactive)
- (indicate-copied-region)))
-
-(defun indicate-copied-region (&optional message-len)
- "Indicate that the region text has been copied interactively.
-If the mark is visible in the selected window, blink the cursor
-between point and mark if there is currently no active region
-highlighting.
-
-If the mark lies outside the selected window, display an
-informative message containing a sample of the copied text. The
-optional argument MESSAGE-LEN, if non-nil, specifies the length
-of this sample text; it defaults to 40."
- (let ((mark (mark t))
- (point (point))
- ;; Inhibit quitting so we can make a quit here
- ;; look like a C-g typed as a command.
- (inhibit-quit t))
- (if (pos-visible-in-window-p mark (selected-window))
- ;; Swap point-and-mark quickly so as to show the region that
- ;; was selected. Don't do it if the region is highlighted.
- (unless (and (region-active-p)
- (face-background 'region))
- ;; Swap point and mark.
- (set-marker (mark-marker) (point) (current-buffer))
- (goto-char mark)
- (sit-for blink-matching-delay)
- ;; Swap back.
- (set-marker (mark-marker) mark (current-buffer))
- (goto-char point)
- ;; If user quit, deactivate the mark
- ;; as C-g would as a command.
- (and quit-flag mark-active
- (deactivate-mark)))
- (let ((len (min (abs (- mark point))
- (or message-len 40))))
- (if (< point mark)
- ;; Don't say "killed"; that is misleading.
- (message "Saved text until \"%s\""
- (buffer-substring-no-properties (- mark len) mark))
- (message "Saved text from \"%s\""
- (buffer-substring-no-properties mark (+ mark len))))))))
-
-(defun append-next-kill (&optional interactive)
- "Cause following command, if it kills, to add to previous kill.
-If the next command kills forward from point, the kill is
-appended to the previous killed text. If the command kills
-backward, the kill is prepended. Kill commands that act on the
-region, such as `kill-region', are regarded as killing forward if
-point is after mark, and killing backward if point is before
-mark.
-
-If the next command is not a kill command, `append-next-kill' has
-no effect.
-
-The argument is used for internal purposes; do not supply one."
- (interactive "p")
- ;; We don't use (interactive-p), since that breaks kbd macros.
- (if interactive
- (progn
- (setq this-command 'kill-region)
- (message "If the next command is a kill, it will append"))
- (setq last-command 'kill-region)))
-
-;; Yanking.
-
-(defcustom yank-handled-properties
- '((font-lock-face . yank-handle-font-lock-face-property)
- (category . yank-handle-category-property))
- "List of special text property handling conditions for yanking.
-Each element should have the form (PROP . FUN), where PROP is a
-property symbol and FUN is a function. When the `yank' command
-inserts text into the buffer, it scans the inserted text for
-stretches of text that have `eq' values of the text property
-PROP; for each such stretch of text, FUN is called with three
-arguments: the property's value in that text, and the start and
-end positions of the text.
-
-This is done prior to removing the properties specified by
-`yank-excluded-properties'."
- :group 'killing
- :type '(repeat (cons (symbol :tag "property symbol")
- function))
- :version "24.3")
-
-;; This is actually used in subr.el but defcustom does not work there.
-(defcustom yank-excluded-properties
- '(category field follow-link fontified font-lock-face help-echo
- intangible invisible keymap local-map mouse-face read-only
- yank-handler)
- "Text properties to discard when yanking.
-The value should be a list of text properties to discard or t,
-which means to discard all text properties.
-
-See also `yank-handled-properties'."
- :type '(choice (const :tag "All" t) (repeat symbol))
- :group 'killing
- :version "24.3")
-
-(defvar yank-window-start nil)
-(defvar yank-undo-function nil
- "If non-nil, function used by `yank-pop' to delete last stretch of yanked
text.
-Function is called with two parameters, START and END corresponding to
-the value of the mark and point; it is guaranteed that START <= END.
-Normally set from the UNDO element of a yank-handler; see `insert-for-yank'.")
-
-(defun yank-pop (&optional arg)
- "Replace just-yanked stretch of killed text with a different stretch.
-This command is allowed only immediately after a `yank' or a `yank-pop'.
-At such a time, the region contains a stretch of reinserted
-previously-killed text. `yank-pop' deletes that text and inserts in its
-place a different stretch of killed text.
-
-With no argument, the previous kill is inserted.
-With argument N, insert the Nth previous kill.
-If N is negative, this is a more recent kill.
-
-The sequence of kills wraps around, so that after the oldest one
-comes the newest one.
-
-When this command inserts killed text into the buffer, it honors
-`yank-excluded-properties' and `yank-handler' as described in the
-doc string for `insert-for-yank-1', which see."
- (interactive "*p")
- (if (not (eq last-command 'yank))
- (error "Previous command was not a yank"))
- (setq this-command 'yank)
- (unless arg (setq arg 1))
- (let ((inhibit-read-only t)
- (before (< (point) (mark t))))
- (if before
- (funcall (or yank-undo-function 'delete-region) (point) (mark t))
- (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
- (setq yank-undo-function nil)
- (set-marker (mark-marker) (point) (current-buffer))
- (insert-for-yank (current-kill arg))
- ;; Set the window start back where it was in the yank command,
- ;; if possible.
- (set-window-start (selected-window) yank-window-start t)
- (if before
- ;; This is like exchange-point-and-mark, but doesn't activate the mark.
- ;; It is cleaner to avoid activation, even though the command
- ;; loop would deactivate the mark because we inserted text.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker) (point) (current-buffer))))))
- nil)
-
-(defun yank (&optional arg)
- "Reinsert (\"paste\") the last stretch of killed text.
-More precisely, reinsert the most recent kill, which is the
-stretch of killed text most recently killed OR yanked. Put point
-at the end, and set mark at the beginning without activating it.
-With just \\[universal-argument] as argument, put point at beginning, and mark
at end.
-With argument N, reinsert the Nth most recent kill.
-
-When this command inserts text into the buffer, it honors the
-`yank-handled-properties' and `yank-excluded-properties'
-variables, and the `yank-handler' text property. See
-`insert-for-yank-1' for details.
-
-See also the command `yank-pop' (\\[yank-pop])."
- (interactive "*P")
- (setq yank-window-start (window-start))
- ;; If we don't get all the way thru, make last-command indicate that
- ;; for the following command.
- (setq this-command t)
- (push-mark (point))
- (insert-for-yank (current-kill (cond
- ((listp arg) 0)
- ((eq arg '-) -2)
- (t (1- arg)))))
- (if (consp arg)
- ;; This is like exchange-point-and-mark, but doesn't activate the mark.
- ;; It is cleaner to avoid activation, even though the command
- ;; loop would deactivate the mark because we inserted text.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker) (point) (current-buffer)))))
- ;; If we do get all the way thru, make this-command indicate that.
- (if (eq this-command t)
- (setq this-command 'yank))
- nil)
-
-(defun rotate-yank-pointer (arg)
- "Rotate the yanking point in the kill ring.
-With ARG, rotate that many kills forward (or backward, if negative)."
- (interactive "p")
- (current-kill arg))
-
-;; Some kill commands.
-
-;; Internal subroutine of delete-char
-(defun kill-forward-chars (arg)
- (if (listp arg) (setq arg (car arg)))
- (if (eq arg '-) (setq arg -1))
- (kill-region (point) (+ (point) arg)))
-
-;; Internal subroutine of backward-delete-char
-(defun kill-backward-chars (arg)
- (if (listp arg) (setq arg (car arg)))
- (if (eq arg '-) (setq arg -1))
- (kill-region (point) (- (point) arg)))
-
-(defcustom backward-delete-char-untabify-method 'untabify
- "The method for untabifying when deleting backward.
-Can be `untabify' -- turn a tab to many spaces, then delete one space;
- `hungry' -- delete all whitespace, both tabs and spaces;
- `all' -- delete all whitespace, including tabs, spaces and newlines;
- nil -- just delete one character."
- :type '(choice (const untabify) (const hungry) (const all) (const nil))
- :version "20.3"
- :group 'killing)
-
-(defun backward-delete-char-untabify (arg &optional killp)
- "Delete characters backward, changing tabs into spaces.
-The exact behavior depends on `backward-delete-char-untabify-method'.
-Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
-Interactively, ARG is the prefix arg (default 1)
-and KILLP is t if a prefix arg was specified."
- (interactive "*p\nP")
- (when (eq backward-delete-char-untabify-method 'untabify)
- (let ((count arg))
- (save-excursion
- (while (and (> count 0) (not (bobp)))
- (if (= (preceding-char) ?\t)
- (let ((col (current-column)))
- (forward-char -1)
- (setq col (- col (current-column)))
- (insert-char ?\s col)
- (delete-char 1)))
- (forward-char -1)
- (setq count (1- count))))))
- (let* ((skip (cond ((eq backward-delete-char-untabify-method 'hungry) " \t")
- ((eq backward-delete-char-untabify-method 'all)
- " \t\n\r")))
- (n (if skip
- (let* ((oldpt (point))
- (wh (- oldpt (save-excursion
- (skip-chars-backward skip)
- (constrain-to-field nil oldpt)))))
- (+ arg (if (zerop wh) 0 (1- wh))))
- arg)))
- ;; Avoid warning about delete-backward-char
- (with-no-warnings (delete-backward-char n killp))))
-
-(defun zap-to-char (arg char)
- "Kill up to and including ARGth occurrence of CHAR.
-Case is ignored if `case-fold-search' is non-nil in the current buffer.
-Goes backward if ARG is negative; error if CHAR not found."
- (interactive (list (prefix-numeric-value current-prefix-arg)
- (read-char "Zap to char: " t)))
- ;; Avoid "obsolete" warnings for translation-table-for-input.
- (with-no-warnings
- (if (char-table-p translation-table-for-input)
- (setq char (or (aref translation-table-for-input char) char))))
- (kill-region (point) (progn
- (search-forward (char-to-string char) nil nil arg)
- (point))))
-
-;; kill-line and its subroutines.
-
-(defcustom kill-whole-line nil
- "If non-nil, `kill-line' with no arg at start of line kills the whole line."
- :type 'boolean
- :group 'killing)
-
-(defun kill-line (&optional arg)
- "Kill the rest of the current line; if no nonblanks there, kill thru newline.
-With prefix argument ARG, kill that many lines from point.
-Negative arguments kill lines backward.
-With zero argument, kills the text before point on the current line.
-
-When calling from a program, nil means \"no arg\",
-a number counts as a prefix arg.
-
-To kill a whole line, when point is not at the beginning, type \
-\\[move-beginning-of-line] \\[kill-line] \\[kill-line].
-
-If `show-trailing-whitespace' is non-nil, this command will just
-kill the rest of the current line, even if there are only
-nonblanks there.
-
-If option `kill-whole-line' is non-nil, then this command kills the whole line
-including its terminating newline, when used at the beginning of a line
-with no argument. As a consequence, you can always kill a whole line
-by typing \\[move-beginning-of-line] \\[kill-line].
-
-If you want to append the killed line to the last killed text,
-use \\[append-next-kill] before \\[kill-line].
-
-If the buffer is read-only, Emacs will beep and refrain from deleting
-the line, but put the line in the kill ring anyway. This means that
-you can use this command to copy text from a read-only buffer.
-\(If the variable `kill-read-only-ok' is non-nil, then this won't
-even beep.)"
- (interactive "P")
- (kill-region (point)
- ;; It is better to move point to the other end of the kill
- ;; before killing. That way, in a read-only buffer, point
- ;; moves across the text that is copied to the kill ring.
- ;; The choice has no effect on undo now that undo records
- ;; the value of point from before the command was run.
- (progn
- (if arg
- (forward-visible-line (prefix-numeric-value arg))
- (if (eobp)
- (signal 'end-of-buffer nil))
- (let ((end
- (save-excursion
- (end-of-visible-line) (point))))
- (if (or (save-excursion
- ;; If trailing whitespace is visible,
- ;; don't treat it as nothing.
- (unless show-trailing-whitespace
- (skip-chars-forward " \t" end))
- (= (point) end))
- (and kill-whole-line (bolp)))
- (forward-visible-line 1)
- (goto-char end))))
- (point))))
-
-(defun kill-whole-line (&optional arg)
- "Kill current line.
-With prefix ARG, kill that many lines starting from the current line.
-If ARG is negative, kill backward. Also kill the preceding newline.
-\(This is meant to make \\[repeat] work well with negative arguments.)
-If ARG is zero, kill current line but exclude the trailing newline."
- (interactive "p")
- (or arg (setq arg 1))
- (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))
- (signal 'end-of-buffer nil))
- (if (and (< arg 0) (bobp) (save-excursion (end-of-visible-line) (bobp)))
- (signal 'beginning-of-buffer nil))
- (unless (eq last-command 'kill-region)
- (kill-new "")
- (setq last-command 'kill-region))
- (cond ((zerop arg)
- ;; We need to kill in two steps, because the previous command
- ;; could have been a kill command, in which case the text
- ;; before point needs to be prepended to the current kill
- ;; ring entry and the text after point appended. Also, we
- ;; need to use save-excursion to avoid copying the same text
- ;; twice to the kill ring in read-only buffers.
- (save-excursion
- (kill-region (point) (progn (forward-visible-line 0) (point))))
- (kill-region (point) (progn (end-of-visible-line) (point))))
- ((< arg 0)
- (save-excursion
- (kill-region (point) (progn (end-of-visible-line) (point))))
- (kill-region (point)
- (progn (forward-visible-line (1+ arg))
- (unless (bobp) (backward-char))
- (point))))
- (t
- (save-excursion
- (kill-region (point) (progn (forward-visible-line 0) (point))))
- (kill-region (point)
- (progn (forward-visible-line arg) (point))))))
-
-(defun forward-visible-line (arg)
- "Move forward by ARG lines, ignoring currently invisible newlines only.
-If ARG is negative, move backward -ARG lines.
-If ARG is zero, move to the beginning of the current line."
- (condition-case nil
- (if (> arg 0)
- (progn
- (while (> arg 0)
- (or (zerop (forward-line 1))
- (signal 'end-of-buffer nil))
- ;; If the newline we just skipped is invisible,
- ;; don't count it.
- (let ((prop
- (get-char-property (1- (point)) 'invisible)))
- (if (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec)))
- (setq arg (1+ arg))))
- (setq arg (1- arg)))
- ;; If invisible text follows, and it is a number of complete lines,
- ;; skip it.
- (let ((opoint (point)))
- (while (and (not (eobp))
- (let ((prop
- (get-char-property (point) 'invisible)))
- (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec)))))
- (goto-char
- (if (get-text-property (point) 'invisible)
- (or (next-single-property-change (point) 'invisible)
- (point-max))
- (next-overlay-change (point)))))
- (unless (bolp)
- (goto-char opoint))))
- (let ((first t))
- (while (or first (<= arg 0))
- (if first
- (beginning-of-line)
- (or (zerop (forward-line -1))
- (signal 'beginning-of-buffer nil)))
- ;; If the newline we just moved to is invisible,
- ;; don't count it.
- (unless (bobp)
- (let ((prop
- (get-char-property (1- (point)) 'invisible)))
- (unless (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec)))
- (setq arg (1+ arg)))))
- (setq first nil))
- ;; If invisible text follows, and it is a number of complete lines,
- ;; skip it.
- (let ((opoint (point)))
- (while (and (not (bobp))
- (let ((prop
- (get-char-property (1- (point)) 'invisible)))
- (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec)))))
- (goto-char
- (if (get-text-property (1- (point)) 'invisible)
- (or (previous-single-property-change (point) 'invisible)
- (point-min))
- (previous-overlay-change (point)))))
- (unless (bolp)
- (goto-char opoint)))))
- ((beginning-of-buffer end-of-buffer)
- nil)))
-
-(defun end-of-visible-line ()
- "Move to end of current visible line."
- (end-of-line)
- ;; If the following character is currently invisible,
- ;; skip all characters with that same `invisible' property value,
- ;; then find the next newline.
- (while (and (not (eobp))
- (save-excursion
- (skip-chars-forward "^\n")
- (let ((prop
- (get-char-property (point) 'invisible)))
- (if (eq buffer-invisibility-spec t)
- prop
- (or (memq prop buffer-invisibility-spec)
- (assq prop buffer-invisibility-spec))))))
- (skip-chars-forward "^\n")
- (if (get-text-property (point) 'invisible)
- (goto-char (or (next-single-property-change (point) 'invisible)
- (point-max)))
- (goto-char (next-overlay-change (point))))
- (end-of-line)))
-
-(defun insert-buffer (buffer)
- "Insert after point the contents of BUFFER.
-Puts mark after the inserted text.
-BUFFER may be a buffer or a buffer name.
-
-This function is meant for the user to run interactively.
-Don't call it from programs: use `insert-buffer-substring' instead!"
- (interactive
- (list
- (progn
- (barf-if-buffer-read-only)
- (read-buffer "Insert buffer: "
- (if (eq (selected-window) (next-window))
- (other-buffer (current-buffer))
- (window-buffer (next-window)))
- t))))
- (push-mark
- (save-excursion
- (insert-buffer-substring (get-buffer buffer))
- (point)))
- nil)
-(put 'insert-buffer 'interactive-only 'insert-buffer-substring)
-
-(defun append-to-buffer (buffer start end)
- "Append to specified buffer the text of the region.
-It is inserted into that buffer before its point.
-
-When calling from a program, give three arguments:
-BUFFER (or buffer name), START and END.
-START and END specify the portion of the current buffer to be copied."
- (interactive
- (list (read-buffer "Append to buffer: " (other-buffer (current-buffer) t))
- (region-beginning) (region-end)))
- (let* ((oldbuf (current-buffer))
- (append-to (get-buffer-create buffer))
- (windows (get-buffer-window-list append-to t t))
- point)
- (save-excursion
- (with-current-buffer append-to
- (setq point (point))
- (barf-if-buffer-read-only)
- (insert-buffer-substring oldbuf start end)
- (dolist (window windows)
- (when (= (window-point window) point)
- (set-window-point window (point))))))))
-
-(defun prepend-to-buffer (buffer start end)
- "Prepend to specified buffer the text of the region.
-It is inserted into that buffer after its point.
-
-When calling from a program, give three arguments:
-BUFFER (or buffer name), START and END.
-START and END specify the portion of the current buffer to be copied."
- (interactive "BPrepend to buffer: \nr")
- (let ((oldbuf (current-buffer)))
- (with-current-buffer (get-buffer-create buffer)
- (barf-if-buffer-read-only)
- (save-excursion
- (insert-buffer-substring oldbuf start end)))))
-
-(defun copy-to-buffer (buffer start end)
- "Copy to specified buffer the text of the region.
-It is inserted into that buffer, replacing existing text there.
-
-When calling from a program, give three arguments:
-BUFFER (or buffer name), START and END.
-START and END specify the portion of the current buffer to be copied."
- (interactive "BCopy to buffer: \nr")
- (let ((oldbuf (current-buffer)))
- (with-current-buffer (get-buffer-create buffer)
- (barf-if-buffer-read-only)
- (erase-buffer)
- (save-excursion
- (insert-buffer-substring oldbuf start end)))))
-
-(define-error 'mark-inactive (purecopy "The mark is not active now"))
-
-(defvar activate-mark-hook nil
- "Hook run when the mark becomes active.
-It is also run at the end of a command, if the mark is active and
-it is possible that the region may have changed.")
-
-(defvar deactivate-mark-hook nil
- "Hook run when the mark becomes inactive.")
-
-(defun mark (&optional force)
- "Return this buffer's mark value as integer, or nil if never set.
-
-In Transient Mark mode, this function signals an error if
-the mark is not active. However, if `mark-even-if-inactive' is non-nil,
-or the argument FORCE is non-nil, it disregards whether the mark
-is active, and returns an integer or nil in the usual way.
-
-If you are using this in an editing command, you are most likely making
-a mistake; see the documentation of `set-mark'."
- (if (or force (not transient-mark-mode) mark-active mark-even-if-inactive)
- (marker-position (mark-marker))
- (signal 'mark-inactive nil)))
-
-;; Behind display-selections-p.
-(declare-function x-selection-owner-p "xselect.c"
- (&optional selection terminal))
-(declare-function x-selection-exists-p "xselect.c"
- (&optional selection terminal))
-
-(defun deactivate-mark (&optional force)
- "Deactivate the mark.
-If Transient Mark mode is disabled, this function normally does
-nothing; but if FORCE is non-nil, it deactivates the mark anyway.
-
-Deactivating the mark sets `mark-active' to nil, updates the
-primary selection according to `select-active-regions', and runs
-`deactivate-mark-hook'.
-
-If Transient Mark mode was temporarily enabled, reset the value
-of the variable `transient-mark-mode'; if this causes Transient
-Mark mode to be disabled, don't change `mark-active' to nil or
-run `deactivate-mark-hook'."
- (when (or transient-mark-mode force)
- (when (and (if (eq select-active-regions 'only)
- (eq (car-safe transient-mark-mode) 'only)
- select-active-regions)
- (region-active-p)
- (display-selections-p))
- ;; The var `saved-region-selection', if non-nil, is the text in
- ;; the region prior to the last command modifying the buffer.
- ;; Set the selection to that, or to the current region.
- (cond (saved-region-selection
- (if (x-selection-owner-p 'PRIMARY)
- (x-set-selection 'PRIMARY saved-region-selection))
- (setq saved-region-selection nil))
- ;; If another program has acquired the selection, region
- ;; deactivation should not clobber it (Bug#11772).
- ((and (/= (region-beginning) (region-end))
- (or (x-selection-owner-p 'PRIMARY)
- (null (x-selection-exists-p 'PRIMARY))))
- (x-set-selection 'PRIMARY
- (funcall region-extract-function nil)))))
- (when mark-active (force-mode-line-update)) ;Refresh toolbar (bug#16382).
- (cond
- ((eq (car-safe transient-mark-mode) 'only)
- (setq transient-mark-mode (cdr transient-mark-mode)))
- ((eq transient-mark-mode 'lambda)
- (setq transient-mark-mode nil)))
- (setq mark-active nil)
- (run-hooks 'deactivate-mark-hook)
- (redisplay--update-region-highlight (selected-window))))
-
-(defun activate-mark (&optional no-tmm)
- "Activate the mark.
-If NO-TMM is non-nil, leave `transient-mark-mode' alone."
- (when (mark t)
- (unless (region-active-p)
- (force-mode-line-update) ;Refresh toolbar (bug#16382).
- (setq mark-active t)
- (unless (or transient-mark-mode no-tmm)
- (setq transient-mark-mode 'lambda))
- (run-hooks 'activate-mark-hook))))
-
-(defun set-mark (pos)
- "Set this buffer's mark to POS. Don't use this function!
-That is to say, don't use this function unless you want
-the user to see that the mark has moved, and you want the previous
-mark position to be lost.
-
-Normally, when a new mark is set, the old one should go on the stack.
-This is why most applications should use `push-mark', not `set-mark'.
-
-Novice Emacs Lisp programmers often try to use the mark for the wrong
-purposes. The mark saves a location for the user's convenience.
-Most editing commands should not alter the mark.
-To remember a location for internal use in the Lisp program,
-store it in a Lisp variable. Example:
-
- (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
- (if pos
- (progn
- (set-marker (mark-marker) pos (current-buffer))
- (activate-mark 'no-tmm))
- ;; Normally we never clear mark-active except in Transient Mark mode.
- ;; But when we actually clear out the mark value too, we must
- ;; clear mark-active in any mode.
- (deactivate-mark t)
- ;; `deactivate-mark' sometimes leaves mark-active non-nil, but
- ;; it should never be nil if the mark is nil.
- (setq mark-active nil)
- (set-marker (mark-marker) nil)))
-
-(defcustom use-empty-active-region nil
- "Whether \"region-aware\" commands should act on empty regions.
-If nil, region-aware commands treat empty regions as inactive.
-If non-nil, region-aware commands treat the region as active as
-long as the mark is active, even if the region is empty.
-
-Region-aware commands are those that act on the region if it is
-active and Transient Mark mode is enabled, and on the text near
-point otherwise."
- :type 'boolean
- :version "23.1"
- :group 'editing-basics)
-
-(defun use-region-p ()
- "Return t if the region is active and it is appropriate to act on it.
-This is used by commands that act specially on the region under
-Transient Mark mode.
-
-The return value is t if Transient Mark mode is enabled and the
-mark is active; furthermore, if `use-empty-active-region' is nil,
-the region must not be empty. Otherwise, the return value is nil.
-
-For some commands, it may be appropriate to ignore the value of
-`use-empty-active-region'; in that case, use `region-active-p'."
- (and (region-active-p)
- (or use-empty-active-region (> (region-end) (region-beginning)))))
-
-(defun region-active-p ()
- "Return t if Transient Mark mode is enabled and the mark is active.
-
-Some commands act specially on the region when Transient Mark
-mode is enabled. Usually, such commands should use
-`use-region-p' instead of this function, because `use-region-p'
-also checks the value of `use-empty-active-region'."
- (and transient-mark-mode mark-active
- ;; FIXME: Somehow we sometimes end up with mark-active non-nil but
- ;; without the mark being set (e.g. bug#17324). We really should fix
- ;; that problem, but in the mean time, let's make sure we don't say the
- ;; region is active when there's no mark.
- (mark)))
-
-
-(defvar redisplay-unhighlight-region-function
- (lambda (rol) (when (overlayp rol) (delete-overlay rol))))
-
-(defvar redisplay-highlight-region-function
- (lambda (start end window rol)
- (if (not (overlayp rol))
- (let ((nrol (make-overlay start end)))
- (funcall redisplay-unhighlight-region-function rol)
- (overlay-put nrol 'window window)
- (overlay-put nrol 'face 'region)
- ;; Normal priority so that a large region doesn't hide all the
- ;; overlays within it, but high secondary priority so that if it
- ;; ends/starts in the middle of a small overlay, that small overlay
- ;; won't hide the region's boundaries.
- (overlay-put nrol 'priority '(nil . 100))
- nrol)
- (unless (and (eq (overlay-buffer rol) (current-buffer))
- (eq (overlay-start rol) start)
- (eq (overlay-end rol) end))
- (move-overlay rol start end (current-buffer)))
- rol)))
-
-(defun redisplay--update-region-highlight (window)
- (with-current-buffer (window-buffer window)
- (let ((rol (window-parameter window 'internal-region-overlay)))
- (if (not (region-active-p))
- (funcall redisplay-unhighlight-region-function rol)
- (let* ((pt (window-point window))
- (mark (mark))
- (start (min pt mark))
- (end (max pt mark))
- (new
- (funcall redisplay-highlight-region-function
- start end window rol)))
- (unless (equal new rol)
- (set-window-parameter window 'internal-region-overlay
- new)))))))
-
-(defun redisplay--update-region-highlights (windows)
- (with-demoted-errors "redisplay--update-region-highlights: %S"
- (if (null windows)
- (redisplay--update-region-highlight (selected-window))
- (unless (listp windows) (setq windows (window-list-1 nil nil t)))
- (if highlight-nonselected-windows
- (mapc #'redisplay--update-region-highlight windows)
- (let ((msw (and (window-minibuffer-p) (minibuffer-selected-window))))
- (dolist (w windows)
- (if (or (eq w (selected-window)) (eq w msw))
- (redisplay--update-region-highlight w)
- (funcall redisplay-unhighlight-region-function
- (window-parameter w 'internal-region-overlay)))))))))
-
-(add-function :before pre-redisplay-function
- #'redisplay--update-region-highlights)
-
-
-(defvar-local mark-ring nil
- "The list of former marks of the current buffer, most recent first.")
-(put 'mark-ring 'permanent-local t)
-
-(defcustom mark-ring-max 16
- "Maximum size of mark ring. Start discarding off end if gets this big."
- :type 'integer
- :group 'editing-basics)
-
-(defvar global-mark-ring nil
- "The list of saved global marks, most recent first.")
-
-(defcustom global-mark-ring-max 16
- "Maximum size of global mark ring. \
-Start discarding off end if gets this big."
- :type 'integer
- :group 'editing-basics)
-
-(defun pop-to-mark-command ()
- "Jump to mark, and pop a new position for mark off the ring.
-\(Does not affect global mark ring)."
- (interactive)
- (if (null (mark t))
- (error "No mark set in this buffer")
- (if (= (point) (mark t))
- (message "Mark popped"))
- (goto-char (mark t))
- (pop-mark)))
-
-(defun push-mark-command (arg &optional nomsg)
- "Set mark at where point is.
-If no prefix ARG and mark is already set there, just activate it.
-Display `Mark set' unless the optional second arg NOMSG is non-nil."
- (interactive "P")
- (let ((mark (mark t)))
- (if (or arg (null mark) (/= mark (point)))
- (push-mark nil nomsg t)
- (activate-mark 'no-tmm)
- (unless nomsg
- (message "Mark activated")))))
-
-(defcustom set-mark-command-repeat-pop nil
- "Non-nil means repeating \\[set-mark-command] after popping mark pops it
again.
-That means that C-u \\[set-mark-command] \\[set-mark-command]
-will pop the mark twice, and
-C-u \\[set-mark-command] \\[set-mark-command] \\[set-mark-command]
-will pop the mark three times.
-
-A value of nil means \\[set-mark-command]'s behavior does not change
-after C-u \\[set-mark-command]."
- :type 'boolean
- :group 'editing-basics)
-
-(defun set-mark-command (arg)
- "Set the mark where point is, or jump to the mark.
-Setting the mark also alters the region, which is the text
-between point and mark; this is the closest equivalent in
-Emacs to what some editors call the \"selection\".
-
-With no prefix argument, set the mark at point, and push the
-old mark position on local mark ring. Also push the old mark on
-global mark ring, if the previous mark was set in another buffer.
-
-When Transient Mark Mode is off, immediately repeating this
-command activates `transient-mark-mode' temporarily.
-
-With prefix argument (e.g., \\[universal-argument] \\[set-mark-command]), \
-jump to the mark, and set the mark from
-position popped off the local mark ring (this does not affect the global
-mark ring). Use \\[pop-global-mark] to jump to a mark popped off the global
-mark ring (see `pop-global-mark').
-
-If `set-mark-command-repeat-pop' is non-nil, repeating
-the \\[set-mark-command] command with no prefix argument pops the next position
-off the local (or global) mark ring and jumps there.
-
-With \\[universal-argument] \\[universal-argument] as prefix
-argument, unconditionally set mark where point is, even if
-`set-mark-command-repeat-pop' is non-nil.
-
-Novice Emacs Lisp programmers often try to use the mark for the wrong
-purposes. See the documentation of `set-mark' for more information."
- (interactive "P")
- (cond ((eq transient-mark-mode 'lambda)
- (setq transient-mark-mode nil))
- ((eq (car-safe transient-mark-mode) 'only)
- (deactivate-mark)))
- (cond
- ((and (consp arg) (> (prefix-numeric-value arg) 4))
- (push-mark-command nil))
- ((not (eq this-command 'set-mark-command))
- (if arg
- (pop-to-mark-command)
- (push-mark-command t)))
- ((and set-mark-command-repeat-pop
- (eq last-command 'pop-to-mark-command))
- (setq this-command 'pop-to-mark-command)
- (pop-to-mark-command))
- ((and set-mark-command-repeat-pop
- (eq last-command 'pop-global-mark)
- (not arg))
- (setq this-command 'pop-global-mark)
- (pop-global-mark))
- (arg
- (setq this-command 'pop-to-mark-command)
- (pop-to-mark-command))
- ((eq last-command 'set-mark-command)
- (if (region-active-p)
- (progn
- (deactivate-mark)
- (message "Mark deactivated"))
- (activate-mark)
- (message "Mark activated")))
- (t
- (push-mark-command nil))))
-
-(defun push-mark (&optional location nomsg activate)
- "Set mark at LOCATION (point, by default) and push old mark on mark ring.
-If the last global mark pushed was not in the current buffer,
-also push LOCATION on the global mark ring.
-Display `Mark set' unless the optional second arg NOMSG is non-nil.
-
-Novice Emacs Lisp programmers often try to use the mark for the wrong
-purposes. See the documentation of `set-mark' for more information.
-
-In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil."
- (unless (null (mark t))
- (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
- (when (> (length mark-ring) mark-ring-max)
- (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
- (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))
- (set-marker (mark-marker) (or location (point)) (current-buffer))
- ;; Now push the mark on the global mark ring.
- (if (and global-mark-ring
- (eq (marker-buffer (car global-mark-ring)) (current-buffer)))
- ;; The last global mark pushed was in this same buffer.
- ;; Don't push another one.
- nil
- (setq global-mark-ring (cons (copy-marker (mark-marker)) global-mark-ring))
- (when (> (length global-mark-ring) global-mark-ring-max)
- (move-marker (car (nthcdr global-mark-ring-max global-mark-ring)) nil)
- (setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil)))
- (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
- (message "Mark set"))
- (if (or activate (not transient-mark-mode))
- (set-mark (mark t)))
- nil)
-
-(defun pop-mark ()
- "Pop off mark ring into the buffer's actual mark.
-Does not set point. Does nothing if mark ring is empty."
- (when mark-ring
- (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
- (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
- (move-marker (car mark-ring) nil)
- (if (null (mark t)) (ding))
- (setq mark-ring (cdr mark-ring)))
- (deactivate-mark))
-
-(define-obsolete-function-alias
- 'exchange-dot-and-mark 'exchange-point-and-mark "23.3")
-(defun exchange-point-and-mark (&optional arg)
- "Put the mark where point is now, and point where the mark is now.
-This command works even when the mark is not active,
-and it reactivates the mark.
-
-If Transient Mark mode is on, a prefix ARG deactivates the mark
-if it is active, and otherwise avoids reactivating it. If
-Transient Mark mode is off, a prefix ARG enables Transient Mark
-mode temporarily."
- (interactive "P")
- (let ((omark (mark t))
- (temp-highlight (eq (car-safe transient-mark-mode) 'only)))
- (if (null omark)
- (error "No mark set in this buffer"))
- (set-mark (point))
- (goto-char omark)
- (cond (temp-highlight
- (setq transient-mark-mode (cons 'only transient-mark-mode)))
- ((or (and arg (region-active-p)) ; (xor arg (not (region-active-p)))
- (not (or arg (region-active-p))))
- (deactivate-mark))
- (t (activate-mark)))
- nil))
-
-(defcustom shift-select-mode t
- "When non-nil, shifted motion keys activate the mark momentarily.
-
-While the mark is activated in this way, any shift-translated point
-motion key extends the region, and if Transient Mark mode was off, it
-is temporarily turned on. Furthermore, the mark will be deactivated
-by any subsequent point motion key that was not shift-translated, or
-by any action that normally deactivates the mark in Transient Mark mode.
-
-See `this-command-keys-shift-translated' for the meaning of
-shift-translation."
- :type 'boolean
- :group 'editing-basics)
-
-(defun handle-shift-selection ()
- "Activate/deactivate mark depending on invocation thru shift translation.
-This function is called by `call-interactively' when a command
-with a `^' character in its `interactive' spec is invoked, before
-running the command itself.
-
-If `shift-select-mode' is enabled and the command was invoked
-through shift translation, set the mark and activate the region
-temporarily, unless it was already set in this way. See
-`this-command-keys-shift-translated' for the meaning of shift
-translation.
-
-Otherwise, if the region has been activated temporarily,
-deactivate it, and restore the variable `transient-mark-mode' to
-its earlier value."
- (cond ((and shift-select-mode this-command-keys-shift-translated)
- (unless (and mark-active
- (eq (car-safe transient-mark-mode) 'only))
- (setq transient-mark-mode
- (cons 'only
- (unless (eq transient-mark-mode 'lambda)
- transient-mark-mode)))
- (push-mark nil nil t)))
- ((eq (car-safe transient-mark-mode) 'only)
- (setq transient-mark-mode (cdr transient-mark-mode))
- (deactivate-mark))))
-
-(define-minor-mode transient-mark-mode
- "Toggle Transient Mark mode.
-With a prefix argument ARG, enable Transient Mark mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-Transient Mark mode if ARG is omitted or nil.
-
-Transient Mark mode is a global minor mode. When enabled, the
-region is highlighted with the `region' face whenever the mark
-is active. The mark is \"deactivated\" by changing the buffer,
-and after certain other operations that set the mark but whose
-main purpose is something else--for example, incremental search,
-\\[beginning-of-buffer], and \\[end-of-buffer].
-
-You can also deactivate the mark by typing \\[keyboard-quit] or
-\\[keyboard-escape-quit].
-
-Many commands change their behavior when Transient Mark mode is
-in effect and the mark is active, by acting on the region instead
-of their usual default part of the buffer's text. Examples of
-such commands include \\[comment-dwim], \\[flush-lines], \\[keep-lines],
-\\[query-replace], \\[query-replace-regexp], \\[ispell], and \\[undo].
-To see the documentation of commands which are sensitive to the
-Transient Mark mode, invoke \\[apropos-documentation] and type \"transient\"
-or \"mark.*active\" at the prompt."
- :global t
- ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again.
- :variable transient-mark-mode)
-
-(defvar widen-automatically t
- "Non-nil means it is ok for commands to call `widen' when they want to.
-Some commands will do this in order to go to positions outside
-the current accessible part of the buffer.
-
-If `widen-automatically' is nil, these commands will do something else
-as a fallback, and won't change the buffer bounds.")
-
-(defvar non-essential nil
- "Whether the currently executing code is performing an essential task.
-This variable should be non-nil only when running code which should not
-disturb the user. E.g. it can be used to prevent Tramp from prompting the
-user for a password when we are simply scanning a set of files in the
-background or displaying possible completions before the user even asked
-for it.")
-
-(defun pop-global-mark ()
- "Pop off global mark ring and jump to the top location."
- (interactive)
- ;; Pop entries which refer to non-existent buffers.
- (while (and global-mark-ring (not (marker-buffer (car global-mark-ring))))
- (setq global-mark-ring (cdr global-mark-ring)))
- (or global-mark-ring
- (error "No global mark set"))
- (let* ((marker (car global-mark-ring))
- (buffer (marker-buffer marker))
- (position (marker-position marker)))
- (setq global-mark-ring (nconc (cdr global-mark-ring)
- (list (car global-mark-ring))))
- (set-buffer buffer)
- (or (and (>= position (point-min))
- (<= position (point-max)))
- (if widen-automatically
- (widen)
- (error "Global mark position is outside accessible part of buffer")))
- (goto-char position)
- (switch-to-buffer buffer)))
-
-(defcustom next-line-add-newlines nil
- "If non-nil, `next-line' inserts newline to avoid `end of buffer' error."
- :type 'boolean
- :version "21.1"
- :group 'editing-basics)
-
-(defun next-line (&optional arg try-vscroll)
- "Move cursor vertically down ARG lines.
-Interactively, vscroll tall lines if `auto-window-vscroll' is enabled.
-Non-interactively, use TRY-VSCROLL to control whether to vscroll tall
-lines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this
-function will not vscroll.
-
-ARG defaults to 1.
-
-If there is no character in the target line exactly under the current column,
-the cursor is positioned after the character in that line which spans this
-column, or at the end of the line if it is not long enough.
-If there is no line in the buffer after this one, behavior depends on the
-value of `next-line-add-newlines'. If non-nil, it inserts a newline character
-to create a line, and moves the cursor to that line. Otherwise it moves the
-cursor to the end of the buffer.
-
-If the variable `line-move-visual' is non-nil, this command moves
-by display lines. Otherwise, it moves by buffer lines, without
-taking variable-width characters or continued lines into account.
-
-The command \\[set-goal-column] can be used to create
-a semipermanent goal column for this command.
-Then instead of trying to move exactly vertically (or as close as possible),
-this command moves to the specified goal column (or as close as possible).
-The goal column is stored in the variable `goal-column', which is nil
-when there is no goal column. Note that setting `goal-column'
-overrides `line-move-visual' and causes this command to move by buffer
-lines rather than by display lines.
-
-If you are thinking of using this in a Lisp program, consider
-using `forward-line' instead. It is usually easier to use
-and more reliable (no dependence on goal column, etc.)."
- (interactive "^p\np")
- (or arg (setq arg 1))
- (if (and next-line-add-newlines (= arg 1))
- (if (save-excursion (end-of-line) (eobp))
- ;; When adding a newline, don't expand an abbrev.
- (let ((abbrev-mode nil))
- (end-of-line)
- (insert (if use-hard-newlines hard-newline "\n")))
- (line-move arg nil nil try-vscroll))
- (if (called-interactively-p 'interactive)
- (condition-case err
- (line-move arg nil nil try-vscroll)
- ((beginning-of-buffer end-of-buffer)
- (signal (car err) (cdr err))))
- (line-move arg nil nil try-vscroll)))
- nil)
-(put 'next-line 'interactive-only 'forward-line)
-
-(defun previous-line (&optional arg try-vscroll)
- "Move cursor vertically up ARG lines.
-Interactively, vscroll tall lines if `auto-window-vscroll' is enabled.
-Non-interactively, use TRY-VSCROLL to control whether to vscroll tall
-lines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this
-function will not vscroll.
-
-ARG defaults to 1.
-
-If there is no character in the target line exactly over the current column,
-the cursor is positioned after the character in that line which spans this
-column, or at the end of the line if it is not long enough.
-
-If the variable `line-move-visual' is non-nil, this command moves
-by display lines. Otherwise, it moves by buffer lines, without
-taking variable-width characters or continued lines into account.
-
-The command \\[set-goal-column] can be used to create
-a semipermanent goal column for this command.
-Then instead of trying to move exactly vertically (or as close as possible),
-this command moves to the specified goal column (or as close as possible).
-The goal column is stored in the variable `goal-column', which is nil
-when there is no goal column. Note that setting `goal-column'
-overrides `line-move-visual' and causes this command to move by buffer
-lines rather than by display lines.
-
-If you are thinking of using this in a Lisp program, consider using
-`forward-line' with a negative argument instead. It is usually easier
-to use and more reliable (no dependence on goal column, etc.)."
- (interactive "^p\np")
- (or arg (setq arg 1))
- (if (called-interactively-p 'interactive)
- (condition-case err
- (line-move (- arg) nil nil try-vscroll)
- ((beginning-of-buffer end-of-buffer)
- (signal (car err) (cdr err))))
- (line-move (- arg) nil nil try-vscroll))
- nil)
-(put 'previous-line 'interactive-only
- "use `forward-line' with negative argument instead.")
-
-(defcustom track-eol nil
- "Non-nil means vertical motion starting at end of line keeps to ends of
lines.
-This means moving to the end of each line moved onto.
-The beginning of a blank line does not count as the end of a line.
-This has no effect when the variable `line-move-visual' is non-nil."
- :type 'boolean
- :group 'editing-basics)
-
-(defcustom goal-column nil
- "Semipermanent goal column for vertical motion, as set by
\\[set-goal-column], or nil.
-A non-nil setting overrides the variable `line-move-visual', which see."
- :type '(choice integer
- (const :tag "None" nil))
- :group 'editing-basics)
-(make-variable-buffer-local 'goal-column)
-
-(defvar temporary-goal-column 0
- "Current goal column for vertical motion.
-It is the column where point was at the start of the current run
-of vertical motion commands.
-
-When moving by visual lines via the function `line-move-visual', it is a cons
-cell (COL . HSCROLL), where COL is the x-position, in pixels,
-divided by the default column width, and HSCROLL is the number of
-columns by which window is scrolled from left margin.
-
-When the `track-eol' feature is doing its job, the value is
-`most-positive-fixnum'.")
-
-(defcustom line-move-ignore-invisible t
- "Non-nil means commands that move by lines ignore invisible newlines.
-When this option is non-nil, \\[next-line], \\[previous-line],
\\[move-end-of-line], and \\[move-beginning-of-line] behave
-as if newlines that are invisible didn't exist, and count
-only visible newlines. Thus, moving across across 2 newlines
-one of which is invisible will be counted as a one-line move.
-Also, a non-nil value causes invisible text to be ignored when
-counting columns for the purposes of keeping point in the same
-column by \\[next-line] and \\[previous-line].
-
-Outline mode sets this."
- :type 'boolean
- :group 'editing-basics)
-
-(defcustom line-move-visual t
- "When non-nil, `line-move' moves point by visual lines.
-This movement is based on where the cursor is displayed on the
-screen, instead of relying on buffer contents alone. It takes
-into account variable-width characters and line continuation.
-If nil, `line-move' moves point by logical lines.
-A non-nil setting of `goal-column' overrides the value of this variable
-and forces movement by logical lines.
-A window that is horizontally scrolled also forces movement by logical
-lines."
- :type 'boolean
- :group 'editing-basics
- :version "23.1")
-
-;; Only used if display-graphic-p.
-(declare-function font-info "font.c" (name &optional frame))
-
-(defun default-font-height ()
- "Return the height in pixels of the current buffer's default face font."
- (let ((default-font (face-font 'default)))
- (cond
- ((and (display-multi-font-p)
- ;; Avoid calling font-info if the frame's default font was
- ;; not changed since the frame was created. That's because
- ;; font-info is expensive for some fonts, see bug #14838.
- (not (string= (frame-parameter nil 'font) default-font)))
- (aref (font-info default-font) 3))
- (t (frame-char-height)))))
-
-(defun default-line-height ()
- "Return the pixel height of current buffer's default-face text line.
-
-The value includes `line-spacing', if any, defined for the buffer
-or the frame."
- (let ((dfh (default-font-height))
- (lsp (if (display-graphic-p)
- (or line-spacing
- (default-value 'line-spacing)
- (frame-parameter nil 'line-spacing)
- 0)
- 0)))
- (if (floatp lsp)
- (setq lsp (truncate (* (frame-char-height) lsp))))
- (+ dfh lsp)))
-
-(defun window-screen-lines ()
- "Return the number of screen lines in the text area of the selected window.
-
-This is different from `window-text-height' in that this function counts
-lines in units of the height of the font used by the default face displayed
-in the window, not in units of the frame's default font, and also accounts
-for `line-spacing', if any, defined for the window's buffer or frame.
-
-The value is a floating-point number."
- (let ((edges (window-inside-pixel-edges))
- (dlh (default-line-height)))
- (/ (float (- (nth 3 edges) (nth 1 edges))) dlh)))
-
-;; Returns non-nil if partial move was done.
-(defun line-move-partial (arg noerror to-end)
- (if (< arg 0)
- ;; Move backward (up).
- ;; If already vscrolled, reduce vscroll
- (let ((vs (window-vscroll nil t))
- (dlh (default-line-height)))
- (when (> vs dlh)
- (set-window-vscroll nil (- vs dlh) t)))
-
- ;; Move forward (down).
- (let* ((lh (window-line-height -1))
- (rowh (car lh))
- (vpos (nth 1 lh))
- (ypos (nth 2 lh))
- (rbot (nth 3 lh))
- (this-lh (window-line-height))
- (this-height (car this-lh))
- (this-ypos (nth 2 this-lh))
- (dlh (default-line-height))
- (wslines (window-screen-lines))
- (edges (window-inside-pixel-edges))
- (winh (- (nth 3 edges) (nth 1 edges) 1))
- py vs last-line)
- (if (> (mod wslines 1.0) 0.0)
- (setq wslines (round (+ wslines 0.5))))
- (when (or (null lh)
- (>= rbot dlh)
- (<= ypos (- dlh))
- (null this-lh)
- (<= this-ypos (- dlh)))
- (unless lh
- (let ((wend (pos-visible-in-window-p t nil t)))
- (setq rbot (nth 3 wend)
- rowh (nth 4 wend)
- vpos (nth 5 wend))))
- (unless this-lh
- (let ((wstart (pos-visible-in-window-p nil nil t)))
- (setq this-ypos (nth 2 wstart)
- this-height (nth 4 wstart))))
- (setq py
- (or (nth 1 this-lh)
- (let ((ppos (posn-at-point))
- col-row)
- (setq col-row (posn-actual-col-row ppos))
- (if col-row
- (- (cdr col-row) (window-vscroll))
- (cdr (posn-col-row ppos))))))
- ;; VPOS > 0 means the last line is only partially visible.
- ;; But if the part that is visible is at least as tall as the
- ;; default font, that means the line is actually fully
- ;; readable, and something like line-spacing is hidden. So in
- ;; that case we accept the last line in the window as still
- ;; visible, and consider the margin as starting one line
- ;; later.
- (if (and vpos (> vpos 0))
- (if (and rowh
- (>= rowh (default-font-height))
- (< rowh dlh))
- (setq last-line (min (- wslines scroll-margin) vpos))
- (setq last-line (min (- wslines scroll-margin 1) (1- vpos)))))
- (cond
- ;; If last line of window is fully visible, and vscrolling
- ;; more would make this line invisible, move forward.
- ((and (or (< (setq vs (window-vscroll nil t)) dlh)
- (null this-height)
- (<= this-height dlh))
- (or (null rbot) (= rbot 0)))
- nil)
- ;; If cursor is not in the bottom scroll margin, and the
- ;; current line is is not too tall, move forward.
- ((and (or (null this-height) (<= this-height winh))
- vpos
- (> vpos 0)
- (< py last-line))
- nil)
- ;; When already vscrolled, we vscroll some more if we can,
- ;; or clear vscroll and move forward at end of tall image.
- ((> vs 0)
- (when (or (and rbot (> rbot 0))
- (and this-height (> this-height dlh)))
- (set-window-vscroll nil (+ vs dlh) t)))
- ;; If cursor just entered the bottom scroll margin, move forward,
- ;; but also optionally vscroll one line so redisplay won't recenter.
- ((and vpos
- (> vpos 0)
- (= py last-line))
- ;; Don't vscroll if the partially-visible line at window
- ;; bottom is not too tall (a.k.a. "just one more text
- ;; line"): in that case, we do want redisplay to behave
- ;; normally, i.e. recenter or whatever.
- ;;
- ;; Note: ROWH + RBOT from the value returned by
- ;; pos-visible-in-window-p give the total height of the
- ;; partially-visible glyph row at the end of the window. As
- ;; we are dealing with floats, we disregard sub-pixel
- ;; discrepancies between that and DLH.
- (if (and rowh rbot (>= (- (+ rowh rbot) winh) 1))
- (set-window-vscroll nil dlh t))
- (line-move-1 arg noerror to-end)
- t)
- ;; If there are lines above the last line, scroll-up one line.
- ((and vpos (> vpos 0))
- (scroll-up 1)
- t)
- ;; Finally, start vscroll.
- (t
- (set-window-vscroll nil dlh t)))))))
-
-
-;; This is like line-move-1 except that it also performs
-;; vertical scrolling of tall images if appropriate.
-;; That is not really a clean thing to do, since it mixes
-;; scrolling with cursor motion. But so far we don't have
-;; a cleaner solution to the problem of making C-n do something
-;; useful given a tall image.
-(defun line-move (arg &optional noerror to-end try-vscroll)
- "Move forward ARG lines.
-If NOERROR, don't signal an error if we can't move ARG lines.
-TO-END is unused.
-TRY-VSCROLL controls whether to vscroll tall lines: if either
-`auto-window-vscroll' or TRY-VSCROLL is nil, this function will
-not vscroll."
- (if noninteractive
- (line-move-1 arg noerror to-end)
- (unless (and auto-window-vscroll try-vscroll
- ;; Only vscroll for single line moves
- (= (abs arg) 1)
- ;; Under scroll-conservatively, the display engine
- ;; does this better.
- (zerop scroll-conservatively)
- ;; But don't vscroll in a keyboard macro.
- (not defining-kbd-macro)
- (not executing-kbd-macro)
- (line-move-partial arg noerror to-end))
- (set-window-vscroll nil 0 t)
- (if (and line-move-visual
- ;; Display-based column are incompatible with goal-column.
- (not goal-column)
- ;; When the text in the window is scrolled to the left,
- ;; display-based motion doesn't make sense (because each
- ;; logical line occupies exactly one screen line).
- (not (> (window-hscroll) 0))
- ;; Likewise when the text _was_ scrolled to the left
- ;; when the current run of vertical motion commands
- ;; started.
- (not (and (memq last-command
- `(next-line previous-line ,this-command))
- auto-hscroll-mode
- (numberp temporary-goal-column)
- (>= temporary-goal-column
- (- (window-width) hscroll-margin)))))
- (prog1 (line-move-visual arg noerror)
- ;; If we moved into a tall line, set vscroll to make
- ;; scrolling through tall images more smooth.
- (let ((lh (line-pixel-height))
- (edges (window-inside-pixel-edges))
- (dlh (default-line-height))
- winh)
- (setq winh (- (nth 3 edges) (nth 1 edges) 1))
- (if (and (< arg 0)
- (< (point) (window-start))
- (> lh winh))
- (set-window-vscroll
- nil
- (- lh dlh) t))))
- (line-move-1 arg noerror to-end)))))
-
-;; Display-based alternative to line-move-1.
-;; Arg says how many lines to move. The value is t if we can move the
-;; specified number of lines.
-(defun line-move-visual (arg &optional noerror)
- "Move ARG lines forward.
-If NOERROR, don't signal an error if we can't move that many lines."
- (let ((opoint (point))
- (hscroll (window-hscroll))
- target-hscroll)
- ;; Check if the previous command was a line-motion command, or if
- ;; we were called from some other command.
- (if (and (consp temporary-goal-column)
- (memq last-command `(next-line previous-line ,this-command)))
- ;; If so, there's no need to reset `temporary-goal-column',
- ;; but we may need to hscroll.
- (if (or (/= (cdr temporary-goal-column) hscroll)
- (> (cdr temporary-goal-column) 0))
- (setq target-hscroll (cdr temporary-goal-column)))
- ;; Otherwise, we should reset `temporary-goal-column'.
- (let ((posn (posn-at-point))
- x-pos)
- (cond
- ;; Handle the `overflow-newline-into-fringe' case:
- ((eq (nth 1 posn) 'right-fringe)
- (setq temporary-goal-column (cons (- (window-width) 1) hscroll)))
- ((car (posn-x-y posn))
- (setq x-pos (car (posn-x-y posn)))
- ;; In R2L lines, the X pixel coordinate is measured from the
- ;; left edge of the window, but columns are still counted
- ;; from the logical-order beginning of the line, i.e. from
- ;; the right edge in this case. We need to adjust for that.
- (if (eq (current-bidi-paragraph-direction) 'right-to-left)
- (setq x-pos (- (window-body-width nil t) 1 x-pos)))
- (setq temporary-goal-column
- (cons (/ (float x-pos)
- (frame-char-width))
- hscroll))))))
- (if target-hscroll
- (set-window-hscroll (selected-window) target-hscroll))
- ;; vertical-motion can move more than it was asked to if it moves
- ;; across display strings with newlines. We don't want to ring
- ;; the bell and announce beginning/end of buffer in that case.
- (or (and (or (and (>= arg 0)
- (>= (vertical-motion
- (cons (or goal-column
- (if (consp temporary-goal-column)
- (car temporary-goal-column)
- temporary-goal-column))
- arg))
- arg))
- (and (< arg 0)
- (<= (vertical-motion
- (cons (or goal-column
- (if (consp temporary-goal-column)
- (car temporary-goal-column)
- temporary-goal-column))
- arg))
- arg)))
- (or (>= arg 0)
- (/= (point) opoint)
- ;; If the goal column lies on a display string,
- ;; `vertical-motion' advances the cursor to the end
- ;; of the string. For arg < 0, this can cause the
- ;; cursor to get stuck. (Bug#3020).
- (= (vertical-motion arg) arg)))
- (unless noerror
- (signal (if (< arg 0) 'beginning-of-buffer 'end-of-buffer)
- nil)))))
-
-;; This is the guts of next-line and previous-line.
-;; Arg says how many lines to move.
-;; The value is t if we can move the specified number of lines.
-(defun line-move-1 (arg &optional noerror _to-end)
- ;; Don't run any point-motion hooks, and disregard intangibility,
- ;; for intermediate positions.
- (let ((inhibit-point-motion-hooks t)
- (opoint (point))
- (orig-arg arg))
- (if (consp temporary-goal-column)
- (setq temporary-goal-column (+ (car temporary-goal-column)
- (cdr temporary-goal-column))))
- (unwind-protect
- (progn
- (if (not (memq last-command '(next-line previous-line)))
- (setq temporary-goal-column
- (if (and track-eol (eolp)
- ;; Don't count beg of empty line as end of line
- ;; unless we just did explicit end-of-line.
- (or (not (bolp)) (eq last-command
'move-end-of-line)))
- most-positive-fixnum
- (current-column))))
-
- (if (not (or (integerp selective-display)
- line-move-ignore-invisible))
- ;; Use just newline characters.
- ;; Set ARG to 0 if we move as many lines as requested.
- (or (if (> arg 0)
- (progn (if (> arg 1) (forward-line (1- arg)))
- ;; This way of moving forward ARG lines
- ;; verifies that we have a newline after the last
one.
- ;; It doesn't get confused by intangible text.
- (end-of-line)
- (if (zerop (forward-line 1))
- (setq arg 0)))
- (and (zerop (forward-line arg))
- (bolp)
- (setq arg 0)))
- (unless noerror
- (signal (if (< arg 0)
- 'beginning-of-buffer
- 'end-of-buffer)
- nil)))
- ;; Move by arg lines, but ignore invisible ones.
- (let (done)
- (while (and (> arg 0) (not done))
- ;; If the following character is currently invisible,
- ;; skip all characters with that same `invisible' property
value.
- (while (and (not (eobp)) (invisible-p (point)))
- (goto-char (next-char-property-change (point))))
- ;; Move a line.
- ;; We don't use `end-of-line', since we want to escape
- ;; from field boundaries occurring exactly at point.
- (goto-char (constrain-to-field
- (let ((inhibit-field-text-motion t))
- (line-end-position))
- (point) t t
- 'inhibit-line-move-field-capture))
- ;; If there's no invisibility here, move over the newline.
- (cond
- ((eobp)
- (if (not noerror)
- (signal 'end-of-buffer nil)
- (setq done t)))
- ((and (> arg 1) ;; Use vertical-motion for last move
- (not (integerp selective-display))
- (not (invisible-p (point))))
- ;; We avoid vertical-motion when possible
- ;; because that has to fontify.
- (forward-line 1))
- ;; Otherwise move a more sophisticated way.
- ((zerop (vertical-motion 1))
- (if (not noerror)
- (signal 'end-of-buffer nil)
- (setq done t))))
- (unless done
- (setq arg (1- arg))))
- ;; The logic of this is the same as the loop above,
- ;; it just goes in the other direction.
- (while (and (< arg 0) (not done))
- ;; For completely consistency with the forward-motion
- ;; case, we should call beginning-of-line here.
- ;; However, if point is inside a field and on a
- ;; continued line, the call to (vertical-motion -1)
- ;; below won't move us back far enough; then we return
- ;; to the same column in line-move-finish, and point
- ;; gets stuck -- cyd
- (forward-line 0)
- (cond
- ((bobp)
- (if (not noerror)
- (signal 'beginning-of-buffer nil)
- (setq done t)))
- ((and (< arg -1) ;; Use vertical-motion for last move
- (not (integerp selective-display))
- (not (invisible-p (1- (point)))))
- (forward-line -1))
- ((zerop (vertical-motion -1))
- (if (not noerror)
- (signal 'beginning-of-buffer nil)
- (setq done t))))
- (unless done
- (setq arg (1+ arg))
- (while (and ;; Don't move over previous invis lines
- ;; if our target is the middle of this line.
- (or (zerop (or goal-column temporary-goal-column))
- (< arg 0))
- (not (bobp)) (invisible-p (1- (point))))
- (goto-char (previous-char-property-change (point))))))))
- ;; This is the value the function returns.
- (= arg 0))
-
- (cond ((> arg 0)
- ;; If we did not move down as far as desired, at least go
- ;; to end of line. Be sure to call point-entered and
- ;; point-left-hooks.
- (let* ((npoint (prog1 (line-end-position)
- (goto-char opoint)))
- (inhibit-point-motion-hooks nil))
- (goto-char npoint)))
- ((< arg 0)
- ;; If we did not move up as far as desired,
- ;; at least go to beginning of line.
- (let* ((npoint (prog1 (line-beginning-position)
- (goto-char opoint)))
- (inhibit-point-motion-hooks nil))
- (goto-char npoint)))
- (t
- (line-move-finish (or goal-column temporary-goal-column)
- opoint (> orig-arg 0)))))))
-
-(defun line-move-finish (column opoint forward)
- (let ((repeat t))
- (while repeat
- ;; Set REPEAT to t to repeat the whole thing.
- (setq repeat nil)
-
- (let (new
- (old (point))
- (line-beg (line-beginning-position))
- (line-end
- ;; Compute the end of the line
- ;; ignoring effectively invisible newlines.
- (save-excursion
- ;; Like end-of-line but ignores fields.
- (skip-chars-forward "^\n")
- (while (and (not (eobp)) (invisible-p (point)))
- (goto-char (next-char-property-change (point)))
- (skip-chars-forward "^\n"))
- (point))))
-
- ;; Move to the desired column.
- (line-move-to-column (truncate column))
-
- ;; Corner case: suppose we start out in a field boundary in
- ;; the middle of a continued line. When we get to
- ;; line-move-finish, point is at the start of a new *screen*
- ;; line but the same text line; then line-move-to-column would
- ;; move us backwards. Test using C-n with point on the "x" in
- ;; (insert "a" (propertize "x" 'field t) (make-string 89 ?y))
- (and forward
- (< (point) old)
- (goto-char old))
-
- (setq new (point))
-
- ;; Process intangibility within a line.
- ;; With inhibit-point-motion-hooks bound to nil, a call to
- ;; goto-char moves point past intangible text.
-
- ;; However, inhibit-point-motion-hooks controls both the
- ;; intangibility and the point-entered/point-left hooks. The
- ;; following hack avoids calling the point-* hooks
- ;; unnecessarily. Note that we move *forward* past intangible
- ;; text when the initial and final points are the same.
- (goto-char new)
- (let ((inhibit-point-motion-hooks nil))
- (goto-char new)
-
- ;; If intangibility moves us to a different (later) place
- ;; in the same line, use that as the destination.
- (if (<= (point) line-end)
- (setq new (point))
- ;; If that position is "too late",
- ;; try the previous allowable position.
- ;; See if it is ok.
- (backward-char)
- (if (if forward
- ;; If going forward, don't accept the previous
- ;; allowable position if it is before the target line.
- (< line-beg (point))
- ;; If going backward, don't accept the previous
- ;; allowable position if it is still after the target line.
- (<= (point) line-end))
- (setq new (point))
- ;; As a last resort, use the end of the line.
- (setq new line-end))))
-
- ;; Now move to the updated destination, processing fields
- ;; as well as intangibility.
- (goto-char opoint)
- (let ((inhibit-point-motion-hooks nil))
- (goto-char
- ;; Ignore field boundaries if the initial and final
- ;; positions have the same `field' property, even if the
- ;; fields are non-contiguous. This seems to be "nicer"
- ;; behavior in many situations.
- (if (eq (get-char-property new 'field)
- (get-char-property opoint 'field))
- new
- (constrain-to-field new opoint t t
- 'inhibit-line-move-field-capture))))
-
- ;; If all this moved us to a different line,
- ;; retry everything within that new line.
- (when (or (< (point) line-beg) (> (point) line-end))
- ;; Repeat the intangibility and field processing.
- (setq repeat t))))))
-
-(defun line-move-to-column (col)
- "Try to find column COL, considering invisibility.
-This function works only in certain cases,
-because what we really need is for `move-to-column'
-and `current-column' to be able to ignore invisible text."
- (if (zerop col)
- (beginning-of-line)
- (move-to-column col))
-
- (when (and line-move-ignore-invisible
- (not (bolp)) (invisible-p (1- (point))))
- (let ((normal-location (point))
- (normal-column (current-column)))
- ;; If the following character is currently invisible,
- ;; skip all characters with that same `invisible' property value.
- (while (and (not (eobp))
- (invisible-p (point)))
- (goto-char (next-char-property-change (point))))
- ;; Have we advanced to a larger column position?
- (if (> (current-column) normal-column)
- ;; We have made some progress towards the desired column.
- ;; See if we can make any further progress.
- (line-move-to-column (+ (current-column) (- col normal-column)))
- ;; Otherwise, go to the place we originally found
- ;; and move back over invisible text.
- ;; that will get us to the same place on the screen
- ;; but with a more reasonable buffer position.
- (goto-char normal-location)
- (let ((line-beg (line-beginning-position)))
- (while (and (not (bolp)) (invisible-p (1- (point))))
- (goto-char (previous-char-property-change (point) line-beg))))))))
-
-(defun move-end-of-line (arg)
- "Move point to end of current line as displayed.
-With argument ARG not nil or 1, move forward ARG - 1 lines first.
-If point reaches the beginning or end of buffer, it stops there.
-
-To ignore the effects of the `intangible' text or overlay
-property, bind `inhibit-point-motion-hooks' to t.
-If there is an image in the current line, this function
-disregards newlines that are part of the text on which the image
-rests."
- (interactive "^p")
- (or arg (setq arg 1))
- (let (done)
- (while (not done)
- (let ((newpos
- (save-excursion
- (let ((goal-column 0)
- (line-move-visual nil))
- (and (line-move arg t)
- ;; With bidi reordering, we may not be at bol,
- ;; so make sure we are.
- (skip-chars-backward "^\n")
- (not (bobp))
- (progn
- (while (and (not (bobp)) (invisible-p (1- (point))))
- (goto-char (previous-single-char-property-change
- (point) 'invisible)))
- (backward-char 1)))
- (point)))))
- (goto-char newpos)
- (if (and (> (point) newpos)
- (eq (preceding-char) ?\n))
- (backward-char 1)
- (if (and (> (point) newpos) (not (eobp))
- (not (eq (following-char) ?\n)))
- ;; If we skipped something intangible and now we're not
- ;; really at eol, keep going.
- (setq arg 1)
- (setq done t)))))))
-
-(defun move-beginning-of-line (arg)
- "Move point to beginning of current line as displayed.
-\(If there's an image in the line, this disregards newlines
-which are part of the text that the image rests on.)
-
-With argument ARG not nil or 1, move forward ARG - 1 lines first.
-If point reaches the beginning or end of buffer, it stops there.
-To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
- (interactive "^p")
- (or arg (setq arg 1))
-
- (let ((orig (point))
- first-vis first-vis-field-value)
-
- ;; Move by lines, if ARG is not 1 (the default).
- (if (/= arg 1)
- (let ((line-move-visual nil))
- (line-move (1- arg) t)))
-
- ;; Move to beginning-of-line, ignoring fields and invisible text.
- (skip-chars-backward "^\n")
- (while (and (not (bobp)) (invisible-p (1- (point))))
- (goto-char (previous-char-property-change (point)))
- (skip-chars-backward "^\n"))
-
- ;; Now find first visible char in the line.
- (while (and (< (point) orig) (invisible-p (point)))
- (goto-char (next-char-property-change (point) orig)))
- (setq first-vis (point))
-
- ;; See if fields would stop us from reaching FIRST-VIS.
- (setq first-vis-field-value
- (constrain-to-field first-vis orig (/= arg 1) t nil))
-
- (goto-char (if (/= first-vis-field-value first-vis)
- ;; If yes, obey them.
- first-vis-field-value
- ;; Otherwise, move to START with attention to fields.
- ;; (It is possible that fields never matter in this case.)
- (constrain-to-field (point) orig
- (/= arg 1) t nil)))))
-
-
-;; Many people have said they rarely use this feature, and often type
-;; it by accident. Maybe it shouldn't even be on a key.
-(put 'set-goal-column 'disabled t)
-
-(defun set-goal-column (arg)
- "Set the current horizontal position as a goal for \\[next-line] and
\\[previous-line].
-Those commands will move to this position in the line moved to
-rather than trying to keep the same horizontal position.
-With a non-nil argument ARG, clears out the goal column
-so that \\[next-line] and \\[previous-line] resume vertical motion.
-The goal column is stored in the variable `goal-column'."
- (interactive "P")
- (if arg
- (progn
- (setq goal-column nil)
- (message "No goal column"))
- (setq goal-column (current-column))
- ;; The older method below can be erroneous if `set-goal-column' is bound
- ;; to a sequence containing %
- ;;(message (substitute-command-keys
- ;;"Goal column %d (use \\[set-goal-column] with an arg to unset it)")
- ;;goal-column)
- (message "%s"
- (concat
- (format "Goal column %d " goal-column)
- (substitute-command-keys
- "(use \\[set-goal-column] with an arg to unset it)")))
-
- )
- nil)
-
-;;; Editing based on visual lines, as opposed to logical lines.
-
-(defun end-of-visual-line (&optional n)
- "Move point to end of current visual line.
-With argument N not nil or 1, move forward N - 1 visual lines first.
-If point reaches the beginning or end of buffer, it stops there.
-To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
- (interactive "^p")
- (or n (setq n 1))
- (if (/= n 1)
- (let ((line-move-visual t))
- (line-move (1- n) t)))
- ;; Unlike `move-beginning-of-line', `move-end-of-line' doesn't
- ;; constrain to field boundaries, so we don't either.
- (vertical-motion (cons (window-width) 0)))
-
-(defun beginning-of-visual-line (&optional n)
- "Move point to beginning of current visual line.
-With argument N not nil or 1, move forward N - 1 visual lines first.
-If point reaches the beginning or end of buffer, it stops there.
-To ignore intangibility, bind `inhibit-point-motion-hooks' to t."
- (interactive "^p")
- (or n (setq n 1))
- (let ((opoint (point)))
- (if (/= n 1)
- (let ((line-move-visual t))
- (line-move (1- n) t)))
- (vertical-motion 0)
- ;; Constrain to field boundaries, like `move-beginning-of-line'.
- (goto-char (constrain-to-field (point) opoint (/= n 1)))))
-
-(defun kill-visual-line (&optional arg)
- "Kill the rest of the visual line.
-With prefix argument ARG, kill that many visual lines from point.
-If ARG is negative, kill visual lines backward.
-If ARG is zero, kill the text before point on the current visual
-line.
-
-If you want to append the killed line to the last killed text,
-use \\[append-next-kill] before \\[kill-line].
-
-If the buffer is read-only, Emacs will beep and refrain from deleting
-the line, but put the line in the kill ring anyway. This means that
-you can use this command to copy text from a read-only buffer.
-\(If the variable `kill-read-only-ok' is non-nil, then this won't
-even beep.)"
- (interactive "P")
- ;; Like in `kill-line', it's better to move point to the other end
- ;; of the kill before killing.
- (let ((opoint (point))
- (kill-whole-line (and kill-whole-line (bolp))))
- (if arg
- (vertical-motion (prefix-numeric-value arg))
- (end-of-visual-line 1)
- (if (= (point) opoint)
- (vertical-motion 1)
- ;; Skip any trailing whitespace at the end of the visual line.
- ;; We used to do this only if `show-trailing-whitespace' is
- ;; nil, but that's wrong; the correct thing would be to check
- ;; whether the trailing whitespace is highlighted. But, it's
- ;; OK to just do this unconditionally.
- (skip-chars-forward " \t")))
- (kill-region opoint (if (and kill-whole-line (looking-at "\n"))
- (1+ (point))
- (point)))))
-
-(defun next-logical-line (&optional arg try-vscroll)
- "Move cursor vertically down ARG lines.
-This is identical to `next-line', except that it always moves
-by logical lines instead of visual lines, ignoring the value of
-the variable `line-move-visual'."
- (interactive "^p\np")
- (let ((line-move-visual nil))
- (with-no-warnings
- (next-line arg try-vscroll))))
-
-(defun previous-logical-line (&optional arg try-vscroll)
- "Move cursor vertically up ARG lines.
-This is identical to `previous-line', except that it always moves
-by logical lines instead of visual lines, ignoring the value of
-the variable `line-move-visual'."
- (interactive "^p\np")
- (let ((line-move-visual nil))
- (with-no-warnings
- (previous-line arg try-vscroll))))
-
-(defgroup visual-line nil
- "Editing based on visual lines."
- :group 'convenience
- :version "23.1")
-
-(defvar visual-line-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [remap kill-line] 'kill-visual-line)
- (define-key map [remap move-beginning-of-line] 'beginning-of-visual-line)
- (define-key map [remap move-end-of-line] 'end-of-visual-line)
- ;; These keybindings interfere with xterm function keys. Are
- ;; there any other suitable bindings?
- ;; (define-key map "\M-[" 'previous-logical-line)
- ;; (define-key map "\M-]" 'next-logical-line)
- map))
-
-(defcustom visual-line-fringe-indicators '(nil nil)
- "How fringe indicators are shown for wrapped lines in `visual-line-mode'.
-The value should be a list of the form (LEFT RIGHT), where LEFT
-and RIGHT are symbols representing the bitmaps to display, to
-indicate wrapped lines, in the left and right fringes respectively.
-See also `fringe-indicator-alist'.
-The default is not to display fringe indicators for wrapped lines.
-This variable does not affect fringe indicators displayed for
-other purposes."
- :type '(list (choice (const :tag "Hide left indicator" nil)
- (const :tag "Left curly arrow" left-curly-arrow)
- (symbol :tag "Other bitmap"))
- (choice (const :tag "Hide right indicator" nil)
- (const :tag "Right curly arrow" right-curly-arrow)
- (symbol :tag "Other bitmap")))
- :set (lambda (symbol value)
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (when (and (boundp 'visual-line-mode)
- (symbol-value 'visual-line-mode))
- (setq fringe-indicator-alist
- (cons (cons 'continuation value)
- (assq-delete-all
- 'continuation
- (copy-tree fringe-indicator-alist)))))))
- (set-default symbol value)))
-
-(defvar visual-line--saved-state nil)
-
-(define-minor-mode visual-line-mode
- "Toggle visual line based editing (Visual Line mode).
-With a prefix argument ARG, enable Visual Line mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-When Visual Line mode is enabled, `word-wrap' is turned on in
-this buffer, and simple editing commands are redefined to act on
-visual lines, not logical lines. See Info node `Visual Line
-Mode' for details."
- :keymap visual-line-mode-map
- :group 'visual-line
- :lighter " Wrap"
- (if visual-line-mode
- (progn
- (set (make-local-variable 'visual-line--saved-state) nil)
- ;; Save the local values of some variables, to be restored if
- ;; visual-line-mode is turned off.
- (dolist (var '(line-move-visual truncate-lines
- truncate-partial-width-windows
- word-wrap fringe-indicator-alist))
- (if (local-variable-p var)
- (push (cons var (symbol-value var))
- visual-line--saved-state)))
- (set (make-local-variable 'line-move-visual) t)
- (set (make-local-variable 'truncate-partial-width-windows) nil)
- (setq truncate-lines nil
- word-wrap t
- fringe-indicator-alist
- (cons (cons 'continuation visual-line-fringe-indicators)
- fringe-indicator-alist)))
- (kill-local-variable 'line-move-visual)
- (kill-local-variable 'word-wrap)
- (kill-local-variable 'truncate-lines)
- (kill-local-variable 'truncate-partial-width-windows)
- (kill-local-variable 'fringe-indicator-alist)
- (dolist (saved visual-line--saved-state)
- (set (make-local-variable (car saved)) (cdr saved)))
- (kill-local-variable 'visual-line--saved-state)))
-
-(defun turn-on-visual-line-mode ()
- (visual-line-mode 1))
-
-(define-globalized-minor-mode global-visual-line-mode
- visual-line-mode turn-on-visual-line-mode)
-
-
-(defun transpose-chars (arg)
- "Interchange characters around point, moving forward one character.
-With prefix arg ARG, effect is to take character before point
-and drag it forward past ARG other characters (backward if ARG negative).
-If no argument and at end of line, the previous two chars are exchanged."
- (interactive "*P")
- (and (null arg) (eolp) (forward-char -1))
- (transpose-subr 'forward-char (prefix-numeric-value arg)))
-
-(defun transpose-words (arg)
- "Interchange words around point, leaving point at end of them.
-With prefix arg ARG, effect is to take word before or around point
-and drag it forward past ARG other words (backward if ARG negative).
-If ARG is zero, the words around or after point and around or after mark
-are interchanged."
- ;; FIXME: `foo a!nd bar' should transpose into `bar and foo'.
- (interactive "*p")
- (transpose-subr 'forward-word arg))
-
-(defun transpose-sexps (arg)
- "Like \\[transpose-words] but applies to sexps.
-Does not work on a sexp that point is in the middle of
-if it is a list or string."
- (interactive "*p")
- (transpose-subr
- (lambda (arg)
- ;; Here we should try to simulate the behavior of
- ;; (cons (progn (forward-sexp x) (point))
- ;; (progn (forward-sexp (- x)) (point)))
- ;; Except that we don't want to rely on the second forward-sexp
- ;; putting us back to where we want to be, since forward-sexp-function
- ;; might do funny things like infix-precedence.
- (if (if (> arg 0)
- (looking-at "\\sw\\|\\s_")
- (and (not (bobp))
- (save-excursion (forward-char -1) (looking-at "\\sw\\|\\s_"))))
- ;; Jumping over a symbol. We might be inside it, mind you.
- (progn (funcall (if (> arg 0)
- 'skip-syntax-backward 'skip-syntax-forward)
- "w_")
- (cons (save-excursion (forward-sexp arg) (point)) (point)))
- ;; Otherwise, we're between sexps. Take a step back before jumping
- ;; to make sure we'll obey the same precedence no matter which direction
- ;; we're going.
- (funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) " .")
- (cons (save-excursion (forward-sexp arg) (point))
- (progn (while (or (forward-comment (if (> arg 0) 1 -1))
- (not (zerop (funcall (if (> arg 0)
- 'skip-syntax-forward
- 'skip-syntax-backward)
- ".")))))
- (point)))))
- arg 'special))
-
-(defun transpose-lines (arg)
- "Exchange current line and previous line, leaving point after both.
-With argument ARG, takes previous line and moves it past ARG lines.
-With argument 0, interchanges line point is in with line mark is in."
- (interactive "*p")
- (transpose-subr (function
- (lambda (arg)
- (if (> arg 0)
- (progn
- ;; Move forward over ARG lines,
- ;; but create newlines if necessary.
- (setq arg (forward-line arg))
- (if (/= (preceding-char) ?\n)
- (setq arg (1+ arg)))
- (if (> arg 0)
- (newline arg)))
- (forward-line arg))))
- arg))
-
-;; FIXME seems to leave point BEFORE the current object when ARG = 0,
-;; which seems inconsistent with the ARG /= 0 case.
-;; FIXME document SPECIAL.
-(defun transpose-subr (mover arg &optional special)
- "Subroutine to do the work of transposing objects.
-Works for lines, sentences, paragraphs, etc. MOVER is a function that
-moves forward by units of the given object (e.g. forward-sentence,
-forward-paragraph). If ARG is zero, exchanges the current object
-with the one containing mark. If ARG is an integer, moves the
-current object past ARG following (if ARG is positive) or
-preceding (if ARG is negative) objects, leaving point after the
-current object."
- (let ((aux (if special mover
- (lambda (x)
- (cons (progn (funcall mover x) (point))
- (progn (funcall mover (- x)) (point))))))
- pos1 pos2)
- (cond
- ((= arg 0)
- (save-excursion
- (setq pos1 (funcall aux 1))
- (goto-char (or (mark) (error "No mark set in this buffer")))
- (setq pos2 (funcall aux 1))
- (transpose-subr-1 pos1 pos2))
- (exchange-point-and-mark))
- ((> arg 0)
- (setq pos1 (funcall aux -1))
- (setq pos2 (funcall aux arg))
- (transpose-subr-1 pos1 pos2)
- (goto-char (car pos2)))
- (t
- (setq pos1 (funcall aux -1))
- (goto-char (car pos1))
- (setq pos2 (funcall aux arg))
- (transpose-subr-1 pos1 pos2)))))
-
-(defun transpose-subr-1 (pos1 pos2)
- (when (> (car pos1) (cdr pos1)) (setq pos1 (cons (cdr pos1) (car pos1))))
- (when (> (car pos2) (cdr pos2)) (setq pos2 (cons (cdr pos2) (car pos2))))
- (when (> (car pos1) (car pos2))
- (let ((swap pos1))
- (setq pos1 pos2 pos2 swap)))
- (if (> (cdr pos1) (car pos2)) (error "Don't have two things to transpose"))
- (atomic-change-group
- ;; This sequence of insertions attempts to preserve marker
- ;; positions at the start and end of the transposed objects.
- (let* ((word (buffer-substring (car pos2) (cdr pos2)))
- (len1 (- (cdr pos1) (car pos1)))
- (len2 (length word))
- (boundary (make-marker)))
- (set-marker boundary (car pos2))
- (goto-char (cdr pos1))
- (insert-before-markers word)
- (setq word (delete-and-extract-region (car pos1) (+ (car pos1) len1)))
- (goto-char boundary)
- (insert word)
- (goto-char (+ boundary len1))
- (delete-region (point) (+ (point) len2))
- (set-marker boundary nil))))
-
-(defun backward-word (&optional arg)
- "Move backward until encountering the beginning of a word.
-With argument ARG, do this that many times.
-If ARG is omitted or nil, move point backward one word."
- (interactive "^p")
- (forward-word (- (or arg 1))))
-
-(defun mark-word (&optional arg allow-extend)
- "Set mark ARG words away from point.
-The place mark goes is the same place \\[forward-word] would
-move to with the same argument.
-Interactively, if this command is repeated
-or (in Transient Mark mode) if the mark is active,
-it marks the next ARG words after the ones already marked."
- (interactive "P\np")
- (cond ((and allow-extend
- (or (and (eq last-command this-command) (mark t))
- (region-active-p)))
- (setq arg (if arg (prefix-numeric-value arg)
- (if (< (mark) (point)) -1 1)))
- (set-mark
- (save-excursion
- (goto-char (mark))
- (forward-word arg)
- (point))))
- (t
- (push-mark
- (save-excursion
- (forward-word (prefix-numeric-value arg))
- (point))
- nil t))))
-
-(defun kill-word (arg)
- "Kill characters forward until encountering the end of a word.
-With argument ARG, do this that many times."
- (interactive "p")
- (kill-region (point) (progn (forward-word arg) (point))))
-
-(defun backward-kill-word (arg)
- "Kill characters backward until encountering the beginning of a word.
-With argument ARG, do this that many times."
- (interactive "p")
- (kill-word (- arg)))
-
-(defun current-word (&optional strict really-word)
- "Return the symbol or word that point is on (or a nearby one) as a string.
-The return value includes no text properties.
-If optional arg STRICT is non-nil, return nil unless point is within
-or adjacent to a symbol or word. In all cases the value can be nil
-if there is no word nearby.
-The function, belying its name, normally finds a symbol.
-If optional arg REALLY-WORD is non-nil, it finds just a word."
- (save-excursion
- (let* ((oldpoint (point)) (start (point)) (end (point))
- (syntaxes (if really-word "w" "w_"))
- (not-syntaxes (concat "^" syntaxes)))
- (skip-syntax-backward syntaxes) (setq start (point))
- (goto-char oldpoint)
- (skip-syntax-forward syntaxes) (setq end (point))
- (when (and (eq start oldpoint) (eq end oldpoint)
- ;; Point is neither within nor adjacent to a word.
- (not strict))
- ;; Look for preceding word in same line.
- (skip-syntax-backward not-syntaxes (line-beginning-position))
- (if (bolp)
- ;; No preceding word in same line.
- ;; Look for following word in same line.
- (progn
- (skip-syntax-forward not-syntaxes (line-end-position))
- (setq start (point))
- (skip-syntax-forward syntaxes)
- (setq end (point)))
- (setq end (point))
- (skip-syntax-backward syntaxes)
- (setq start (point))))
- ;; If we found something nonempty, return it as a string.
- (unless (= start end)
- (buffer-substring-no-properties start end)))))
-
-(defcustom fill-prefix nil
- "String for filling to insert at front of new line, or nil for none."
- :type '(choice (const :tag "None" nil)
- string)
- :group 'fill)
-(make-variable-buffer-local 'fill-prefix)
-(put 'fill-prefix 'safe-local-variable 'string-or-null-p)
-
-(defcustom auto-fill-inhibit-regexp nil
- "Regexp to match lines which should not be auto-filled."
- :type '(choice (const :tag "None" nil)
- regexp)
- :group 'fill)
-
-(defun do-auto-fill ()
- "The default value for `normal-auto-fill-function'.
-This is the default auto-fill function, some major modes use a different one.
-Returns t if it really did any work."
- (let (fc justify give-up
- (fill-prefix fill-prefix))
- (if (or (not (setq justify (current-justification)))
- (null (setq fc (current-fill-column)))
- (and (eq justify 'left)
- (<= (current-column) fc))
- (and auto-fill-inhibit-regexp
- (save-excursion (beginning-of-line)
- (looking-at auto-fill-inhibit-regexp))))
- nil ;; Auto-filling not required
- (if (memq justify '(full center right))
- (save-excursion (unjustify-current-line)))
-
- ;; Choose a fill-prefix automatically.
- (when (and adaptive-fill-mode
- (or (null fill-prefix) (string= fill-prefix "")))
- (let ((prefix
- (fill-context-prefix
- (save-excursion (fill-forward-paragraph -1) (point))
- (save-excursion (fill-forward-paragraph 1) (point)))))
- (and prefix (not (equal prefix ""))
- ;; Use auto-indentation rather than a guessed empty prefix.
- (not (and fill-indent-according-to-mode
- (string-match "\\`[ \t]*\\'" prefix)))
- (setq fill-prefix prefix))))
-
- (while (and (not give-up) (> (current-column) fc))
- ;; Determine where to split the line.
- (let* (after-prefix
- (fill-point
- (save-excursion
- (beginning-of-line)
- (setq after-prefix (point))
- (and fill-prefix
- (looking-at (regexp-quote fill-prefix))
- (setq after-prefix (match-end 0)))
- (move-to-column (1+ fc))
- (fill-move-to-break-point after-prefix)
- (point))))
-
- ;; See whether the place we found is any good.
- (if (save-excursion
- (goto-char fill-point)
- (or (bolp)
- ;; There is no use breaking at end of line.
- (save-excursion (skip-chars-forward " ") (eolp))
- ;; It is futile to split at the end of the prefix
- ;; since we would just insert the prefix again.
- (and after-prefix (<= (point) after-prefix))
- ;; Don't split right after a comment starter
- ;; since we would just make another comment starter.
- (and comment-start-skip
- (let ((limit (point)))
- (beginning-of-line)
- (and (re-search-forward comment-start-skip
- limit t)
- (eq (point) limit))))))
- ;; No good place to break => stop trying.
- (setq give-up t)
- ;; Ok, we have a useful place to break the line. Do it.
- (let ((prev-column (current-column)))
- ;; If point is at the fill-point, do not `save-excursion'.
- ;; Otherwise, if a comment prefix or fill-prefix is inserted,
- ;; point will end up before it rather than after it.
- (if (save-excursion
- (skip-chars-backward " \t")
- (= (point) fill-point))
- (default-indent-new-line t)
- (save-excursion
- (goto-char fill-point)
- (default-indent-new-line t)))
- ;; Now do justification, if required
- (if (not (eq justify 'left))
- (save-excursion
- (end-of-line 0)
- (justify-current-line justify nil t)))
- ;; If making the new line didn't reduce the hpos of
- ;; the end of the line, then give up now;
- ;; trying again will not help.
- (if (>= (current-column) prev-column)
- (setq give-up t))))))
- ;; Justify last line.
- (justify-current-line justify t t)
- t)))
-
-(defvar comment-line-break-function 'comment-indent-new-line
- "Mode-specific function which line breaks and continues a comment.
-This function is called during auto-filling when a comment syntax
-is defined.
-The function should take a single optional argument, which is a flag
-indicating whether it should use soft newlines.")
-
-(defun default-indent-new-line (&optional soft)
- "Break line at point and indent.
-If a comment syntax is defined, call `comment-indent-new-line'.
-
-The inserted newline is marked hard if variable `use-hard-newlines' is true,
-unless optional argument SOFT is non-nil."
- (interactive)
- (if comment-start
- (funcall comment-line-break-function soft)
- ;; Insert the newline before removing empty space so that markers
- ;; get preserved better.
- (if soft (insert-and-inherit ?\n) (newline 1))
- (save-excursion (forward-char -1) (delete-horizontal-space))
- (delete-horizontal-space)
-
- (if (and fill-prefix (not adaptive-fill-mode))
- ;; Blindly trust a non-adaptive fill-prefix.
- (progn
- (indent-to-left-margin)
- (insert-before-markers-and-inherit fill-prefix))
-
- (cond
- ;; If there's an adaptive prefix, use it unless we're inside
- ;; a comment and the prefix is not a comment starter.
- (fill-prefix
- (indent-to-left-margin)
- (insert-and-inherit fill-prefix))
- ;; If we're not inside a comment, just try to indent.
- (t (indent-according-to-mode))))))
-
-(defvar normal-auto-fill-function 'do-auto-fill
- "The function to use for `auto-fill-function' if Auto Fill mode is turned on.
-Some major modes set this.")
-
-(put 'auto-fill-function :minor-mode-function 'auto-fill-mode)
-;; `functions' and `hooks' are usually unsafe to set, but setting
-;; auto-fill-function to nil in a file-local setting is safe and
-;; can be useful to prevent auto-filling.
-(put 'auto-fill-function 'safe-local-variable 'null)
-
-(define-minor-mode auto-fill-mode
- "Toggle automatic line breaking (Auto Fill mode).
-With a prefix argument ARG, enable Auto Fill mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-When Auto Fill mode is enabled, inserting a space at a column
-beyond `current-fill-column' automatically breaks the line at a
-previous space.
-
-When `auto-fill-mode' is on, the `auto-fill-function' variable is
-non-`nil'.
-
-The value of `normal-auto-fill-function' specifies the function to use
-for `auto-fill-function' when turning Auto Fill mode on."
- :variable (auto-fill-function
- . (lambda (v) (setq auto-fill-function
- (if v normal-auto-fill-function)))))
-
-;; This holds a document string used to document auto-fill-mode.
-(defun auto-fill-function ()
- "Automatically break line at a previous space, in insertion of text."
- nil)
-
-(defun turn-on-auto-fill ()
- "Unconditionally turn on Auto Fill mode."
- (auto-fill-mode 1))
-
-(defun turn-off-auto-fill ()
- "Unconditionally turn off Auto Fill mode."
- (auto-fill-mode -1))
-
-(custom-add-option 'text-mode-hook 'turn-on-auto-fill)
-
-(defun set-fill-column (arg)
- "Set `fill-column' to specified argument.
-Use \\[universal-argument] followed by a number to specify a column.
-Just \\[universal-argument] as argument means to use the current column."
- (interactive
- (list (or current-prefix-arg
- ;; We used to use current-column silently, but C-x f is too easily
- ;; typed as a typo for C-x C-f, so we turned it into an error and
- ;; now an interactive prompt.
- (read-number "Set fill-column to: " (current-column)))))
- (if (consp arg)
- (setq arg (current-column)))
- (if (not (integerp arg))
- ;; Disallow missing argument; it's probably a typo for C-x C-f.
- (error "set-fill-column requires an explicit argument")
- (message "Fill column set to %d (was %d)" arg fill-column)
- (setq fill-column arg)))
-
-(defun set-selective-display (arg)
- "Set `selective-display' to ARG; clear it if no arg.
-When the value of `selective-display' is a number > 0,
-lines whose indentation is >= that value are not displayed.
-The variable `selective-display' has a separate value for each buffer."
- (interactive "P")
- (if (eq selective-display t)
- (error "selective-display already in use for marked lines"))
- (let ((current-vpos
- (save-restriction
- (narrow-to-region (point-min) (point))
- (goto-char (window-start))
- (vertical-motion (window-height)))))
- (setq selective-display
- (and arg (prefix-numeric-value arg)))
- (recenter current-vpos))
- (set-window-start (selected-window) (window-start))
- (princ "selective-display set to " t)
- (prin1 selective-display t)
- (princ "." t))
-
-(defvaralias 'indicate-unused-lines 'indicate-empty-lines)
-
-(defun toggle-truncate-lines (&optional arg)
- "Toggle truncating of long lines for the current buffer.
-When truncating is off, long lines are folded.
-With prefix argument ARG, truncate long lines if ARG is positive,
-otherwise fold them. Note that in side-by-side windows, this
-command has no effect if `truncate-partial-width-windows' is
-non-nil."
- (interactive "P")
- (setq truncate-lines
- (if (null arg)
- (not truncate-lines)
- (> (prefix-numeric-value arg) 0)))
- (force-mode-line-update)
- (unless truncate-lines
- (let ((buffer (current-buffer)))
- (walk-windows (lambda (window)
- (if (eq buffer (window-buffer window))
- (set-window-hscroll window 0)))
- nil t)))
- (message "Truncate long lines %s"
- (if truncate-lines "enabled" "disabled")))
-
-(defun toggle-word-wrap (&optional arg)
- "Toggle whether to use word-wrapping for continuation lines.
-With prefix argument ARG, wrap continuation lines at word boundaries
-if ARG is positive, otherwise wrap them at the right screen edge.
-This command toggles the value of `word-wrap'. It has no effect
-if long lines are truncated."
- (interactive "P")
- (setq word-wrap
- (if (null arg)
- (not word-wrap)
- (> (prefix-numeric-value arg) 0)))
- (force-mode-line-update)
- (message "Word wrapping %s"
- (if word-wrap "enabled" "disabled")))
-
-(defvar overwrite-mode-textual (purecopy " Ovwrt")
- "The string displayed in the mode line when in overwrite mode.")
-(defvar overwrite-mode-binary (purecopy " Bin Ovwrt")
- "The string displayed in the mode line when in binary overwrite mode.")
-
-(define-minor-mode overwrite-mode
- "Toggle Overwrite mode.
-With a prefix argument ARG, enable Overwrite mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-When Overwrite mode is enabled, printing characters typed in
-replace existing text on a one-for-one basis, rather than pushing
-it to the right. At the end of a line, such characters extend
-the line. Before a tab, such characters insert until the tab is
-filled in. \\[quoted-insert] still inserts characters in
-overwrite mode; this is supposed to make it easier to insert
-characters when necessary."
- :variable (overwrite-mode
- . (lambda (v) (setq overwrite-mode (if v
'overwrite-mode-textual)))))
-
-(define-minor-mode binary-overwrite-mode
- "Toggle Binary Overwrite mode.
-With a prefix argument ARG, enable Binary Overwrite mode if ARG
-is positive, and disable it otherwise. If called from Lisp,
-enable the mode if ARG is omitted or nil.
-
-When Binary Overwrite mode is enabled, printing characters typed
-in replace existing text. Newlines are not treated specially, so
-typing at the end of a line joins the line to the next, with the
-typed character between them. Typing before a tab character
-simply replaces the tab with the character typed.
-\\[quoted-insert] replaces the text at the cursor, just as
-ordinary typing characters do.
-
-Note that Binary Overwrite mode is not its own minor mode; it is
-a specialization of overwrite mode, entered by setting the
-`overwrite-mode' variable to `overwrite-mode-binary'."
- :variable (overwrite-mode
- . (lambda (v) (setq overwrite-mode (if v
'overwrite-mode-binary)))))
-
-(define-minor-mode line-number-mode
- "Toggle line number display in the mode line (Line Number mode).
-With a prefix argument ARG, enable Line Number mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-Line numbers do not appear for very large buffers and buffers
-with very long lines; see variables `line-number-display-limit'
-and `line-number-display-limit-width'."
- :init-value t :global t :group 'mode-line)
-
-(define-minor-mode column-number-mode
- "Toggle column number display in the mode line (Column Number mode).
-With a prefix argument ARG, enable Column Number mode if ARG is
-positive, and disable it otherwise.
-
-If called from Lisp, enable the mode if ARG is omitted or nil."
- :global t :group 'mode-line)
-
-(define-minor-mode size-indication-mode
- "Toggle buffer size display in the mode line (Size Indication mode).
-With a prefix argument ARG, enable Size Indication mode if ARG is
-positive, and disable it otherwise.
-
-If called from Lisp, enable the mode if ARG is omitted or nil."
- :global t :group 'mode-line)
-
-(define-minor-mode auto-save-mode
- "Toggle auto-saving in the current buffer (Auto Save mode).
-With a prefix argument ARG, enable Auto Save mode if ARG is
-positive, and disable it otherwise.
-
-If called from Lisp, enable the mode if ARG is omitted or nil."
- :variable ((and buffer-auto-save-file-name
- ;; If auto-save is off because buffer has shrunk,
- ;; then toggling should turn it on.
- (>= buffer-saved-size 0))
- . (lambda (val)
- (setq buffer-auto-save-file-name
- (cond
- ((null val) nil)
- ((and buffer-file-name auto-save-visited-file-name
- (not buffer-read-only))
- buffer-file-name)
- (t (make-auto-save-file-name))))))
- ;; If -1 was stored here, to temporarily turn off saving,
- ;; turn it back on.
- (and (< buffer-saved-size 0)
- (setq buffer-saved-size 0)))
-
-(defgroup paren-blinking nil
- "Blinking matching of parens and expressions."
- :prefix "blink-matching-"
- :group 'paren-matching)
-
-(defcustom blink-matching-paren t
- "Non-nil means show matching open-paren when close-paren is inserted.
-If t, highlight the paren. If `jump', move cursor to its position."
- :type '(choice
- (const :tag "Disable" nil)
- (const :tag "Highlight" t)
- (const :tag "Move cursor" jump))
- :group 'paren-blinking)
-
-(defcustom blink-matching-paren-on-screen t
- "Non-nil means show matching open-paren when it is on screen.
-If nil, don't show it (but the open-paren can still be shown
-when it is off screen).
-
-This variable has no effect if `blink-matching-paren' is nil.
-\(In that case, the open-paren is never shown.)
-It is also ignored if `show-paren-mode' is enabled."
- :type 'boolean
- :group 'paren-blinking)
-
-(defcustom blink-matching-paren-distance (* 100 1024)
- "If non-nil, maximum distance to search backwards for matching open-paren.
-If nil, search stops at the beginning of the accessible portion of the buffer."
- :version "23.2" ; 25->100k
- :type '(choice (const nil) integer)
- :group 'paren-blinking)
-
-(defcustom blink-matching-delay 1
- "Time in seconds to delay after showing a matching paren."
- :type 'number
- :group 'paren-blinking)
-
-(defcustom blink-matching-paren-dont-ignore-comments nil
- "If nil, `blink-matching-paren' ignores comments.
-More precisely, when looking for the matching parenthesis,
-it skips the contents of comments that end before point."
- :type 'boolean
- :group 'paren-blinking)
-
-(defun blink-matching-check-mismatch (start end)
- "Return whether or not START...END are matching parens.
-END is the current point and START is the blink position.
-START might be nil if no matching starter was found.
-Returns non-nil if we find there is a mismatch."
- (let* ((end-syntax (syntax-after (1- end)))
- (matching-paren (and (consp end-syntax)
- (eq (syntax-class end-syntax) 5)
- (cdr end-syntax))))
- ;; For self-matched chars like " and $, we can't know when they're
- ;; mismatched or unmatched, so we can only do it for parens.
- (when matching-paren
- (not (and start
- (or
- (eq (char-after start) matching-paren)
- ;; The cdr might hold a new paren-class info rather than
- ;; a matching-char info, in which case the two CDRs
- ;; should match.
- (eq matching-paren (cdr-safe (syntax-after start)))))))))
-
-(defvar blink-matching-check-function #'blink-matching-check-mismatch
- "Function to check parentheses mismatches.
-The function takes two arguments (START and END) where START is the
-position just before the opening token and END is the position right after.
-START can be nil, if it was not found.
-The function should return non-nil if the two tokens do not match.")
-
-(defvar blink-matching--overlay
- (let ((ol (make-overlay (point) (point) nil t)))
- (overlay-put ol 'face 'show-paren-match)
- (delete-overlay ol)
- ol)
- "Overlay used to highlight the matching paren.")
-
-(defun blink-matching-open ()
- "Momentarily highlight the beginning of the sexp before point."
- (interactive)
- (when (and (not (bobp))
- blink-matching-paren)
- (let* ((oldpos (point))
- (message-log-max nil) ; Don't log messages about paren matching.
- (blinkpos
- (save-excursion
- (save-restriction
- (if blink-matching-paren-distance
- (narrow-to-region
- (max (minibuffer-prompt-end) ;(point-min) unless minibuf.
- (- (point) blink-matching-paren-distance))
- oldpos))
- (let ((parse-sexp-ignore-comments
- (and parse-sexp-ignore-comments
- (not blink-matching-paren-dont-ignore-comments))))
- (condition-case ()
- (progn
- (forward-sexp -1)
- ;; backward-sexp skips backward over prefix chars,
- ;; so move back to the matching paren.
- (while (and (< (point) (1- oldpos))
- (let ((code (syntax-after (point))))
- (or (eq (syntax-class code) 6)
- (eq (logand 1048576 (car code))
- 1048576))))
- (forward-char 1))
- (point))
- (error nil))))))
- (mismatch (funcall blink-matching-check-function blinkpos oldpos)))
- (cond
- (mismatch
- (if blinkpos
- (if (minibufferp)
- (minibuffer-message "Mismatched parentheses")
- (message "Mismatched parentheses"))
- (if (minibufferp)
- (minibuffer-message "No matching parenthesis found")
- (message "No matching parenthesis found"))))
- ((not blinkpos) nil)
- ((pos-visible-in-window-p blinkpos)
- ;; Matching open within window, temporarily move to or highlight
- ;; char after blinkpos but only if `blink-matching-paren-on-screen'
- ;; is non-nil.
- (and blink-matching-paren-on-screen
- (not show-paren-mode)
- (if (eq blink-matching-paren 'jump)
- (save-excursion
- (goto-char blinkpos)
- (sit-for blink-matching-delay))
- (unwind-protect
- (progn
- (move-overlay blink-matching--overlay blinkpos (1+
blinkpos)
- (current-buffer))
- (sit-for blink-matching-delay))
- (delete-overlay blink-matching--overlay)))))
- (t
- (save-excursion
- (goto-char blinkpos)
- (let ((open-paren-line-string
- ;; Show what precedes the open in its line, if anything.
- (cond
- ((save-excursion (skip-chars-backward " \t") (not (bolp)))
- (buffer-substring (line-beginning-position)
- (1+ blinkpos)))
- ;; Show what follows the open in its line, if anything.
- ((save-excursion
- (forward-char 1)
- (skip-chars-forward " \t")
- (not (eolp)))
- (buffer-substring blinkpos
- (line-end-position)))
- ;; Otherwise show the previous nonblank line,
- ;; if there is one.
- ((save-excursion (skip-chars-backward "\n \t") (not (bobp)))
- (concat
- (buffer-substring (progn
- (skip-chars-backward "\n \t")
- (line-beginning-position))
- (progn (end-of-line)
- (skip-chars-backward " \t")
- (point)))
- ;; Replace the newline and other whitespace with `...'.
- "..."
- (buffer-substring blinkpos (1+ blinkpos))))
- ;; There is nothing to show except the char itself.
- (t (buffer-substring blinkpos (1+ blinkpos))))))
- (message "Matches %s"
- (substring-no-properties open-paren-line-string)))))))))
-
-(defvar blink-paren-function 'blink-matching-open
- "Function called, if non-nil, whenever a close parenthesis is inserted.
-More precisely, a char with closeparen syntax is self-inserted.")
-
-(defun blink-paren-post-self-insert-function ()
- (when (and (eq (char-before) last-command-event) ; Sanity check.
- (memq (char-syntax last-command-event) '(?\) ?\$))
- blink-paren-function
- (not executing-kbd-macro)
- (not noninteractive)
- ;; Verify an even number of quoting characters precede the close.
- (= 1 (logand 1 (- (point)
- (save-excursion
- (forward-char -1)
- (skip-syntax-backward "/\\")
- (point))))))
- (funcall blink-paren-function)))
-
-(put 'blink-paren-post-self-insert-function 'priority 100)
-
-(add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function
- ;; Most likely, this hook is nil, so this arg doesn't matter,
- ;; but I use it as a reminder that this function usually
- ;; likes to be run after others since it does
- ;; `sit-for'. That's also the reason it get a `priority' prop
- ;; of 100.
- 'append)
-
-;; This executes C-g typed while Emacs is waiting for a command.
-;; Quitting out of a program does not go through here;
-;; that happens in the QUIT macro at the C code level.
-(defun keyboard-quit ()
- "Signal a `quit' condition.
-During execution of Lisp code, this character causes a quit directly.
-At top-level, as an editor command, this simply beeps."
- (interactive)
- ;; Avoid adding the region to the window selection.
- (setq saved-region-selection nil)
- (let (select-active-regions)
- (deactivate-mark))
- (if (fboundp 'kmacro-keyboard-quit)
- (kmacro-keyboard-quit))
- ;; Force the next redisplay cycle to remove the "Def" indicator from
- ;; all the mode lines.
- (if defining-kbd-macro
- (force-mode-line-update t))
- (setq defining-kbd-macro nil)
- (let ((debug-on-quit nil))
- (signal 'quit nil)))
-
-(defvar buffer-quit-function nil
- "Function to call to \"quit\" the current buffer, or nil if none.
-\\[keyboard-escape-quit] calls this function when its more local actions
-\(such as canceling a prefix argument, minibuffer or region) do not apply.")
-
-(defun keyboard-escape-quit ()
- "Exit the current \"mode\" (in a generalized sense of the word).
-This command can exit an interactive command such as `query-replace',
-can clear out a prefix argument or a region,
-can get out of the minibuffer or other recursive edit,
-cancel the use of the current buffer (for special-purpose buffers),
-or go back to just one window (by deleting all but the selected window)."
- (interactive)
- (cond ((eq last-command 'mode-exited) nil)
- ((region-active-p)
- (deactivate-mark))
- ((> (minibuffer-depth) 0)
- (abort-recursive-edit))
- (current-prefix-arg
- nil)
- ((> (recursion-depth) 0)
- (exit-recursive-edit))
- (buffer-quit-function
- (funcall buffer-quit-function))
- ((not (one-window-p t))
- (delete-other-windows))
- ((string-match "^ \\*" (buffer-name (current-buffer)))
- (bury-buffer))))
-
-(defun play-sound-file (file &optional volume device)
- "Play sound stored in FILE.
-VOLUME and DEVICE correspond to the keywords of the sound
-specification for `play-sound'."
- (interactive "fPlay sound file: ")
- (let ((sound (list :file file)))
- (if volume
- (plist-put sound :volume volume))
- (if device
- (plist-put sound :device device))
- (push 'sound sound)
- (play-sound sound)))
-
-
-(defcustom read-mail-command 'rmail
- "Your preference for a mail reading package.
-This is used by some keybindings which support reading mail.
-See also `mail-user-agent' concerning sending mail."
- :type '(radio (function-item :tag "Rmail" :format "%t\n" rmail)
- (function-item :tag "Gnus" :format "%t\n" gnus)
- (function-item :tag "Emacs interface to MH"
- :format "%t\n" mh-rmail)
- (function :tag "Other"))
- :version "21.1"
- :group 'mail)
-
-(defcustom mail-user-agent 'message-user-agent
- "Your preference for a mail composition package.
-Various Emacs Lisp packages (e.g. Reporter) require you to compose an
-outgoing email message. This variable lets you specify which
-mail-sending package you prefer.
-
-Valid values include:
-
- `message-user-agent' -- use the Message package.
- See Info node `(message)'.
- `sendmail-user-agent' -- use the Mail package.
- See Info node `(emacs)Sending Mail'.
- `mh-e-user-agent' -- use the Emacs interface to the MH mail system.
- See Info node `(mh-e)'.
- `gnus-user-agent' -- like `message-user-agent', but with Gnus
- paraphernalia if Gnus is running, particularly
- the Gcc: header for archiving.
-
-Additional valid symbols may be available; check with the author of
-your package for details. The function should return non-nil if it
-succeeds.
-
-See also `read-mail-command' concerning reading mail."
- :type '(radio (function-item :tag "Message package"
- :format "%t\n"
- message-user-agent)
- (function-item :tag "Mail package"
- :format "%t\n"
- sendmail-user-agent)
- (function-item :tag "Emacs interface to MH"
- :format "%t\n"
- mh-e-user-agent)
- (function-item :tag "Message with full Gnus features"
- :format "%t\n"
- gnus-user-agent)
- (function :tag "Other"))
- :version "23.2" ; sendmail->message
- :group 'mail)
-
-(defcustom compose-mail-user-agent-warnings t
- "If non-nil, `compose-mail' warns about changes in `mail-user-agent'.
-If the value of `mail-user-agent' is the default, and the user
-appears to have customizations applying to the old default,
-`compose-mail' issues a warning."
- :type 'boolean
- :version "23.2"
- :group 'mail)
-
-(defun rfc822-goto-eoh ()
- "If the buffer starts with a mail header, move point to the header's end.
-Otherwise, moves to `point-min'.
-The end of the header is the start of the next line, if there is one,
-else the end of the last line. This function obeys RFC822."
- (goto-char (point-min))
- (when (re-search-forward
- "^\\([:\n]\\|[^: \t\n]+[ \t\n]\\)" nil 'move)
- (goto-char (match-beginning 0))))
-
-;; Used by Rmail (e.g., rmail-forward).
-(defvar mail-encode-mml nil
- "If non-nil, mail-user-agent's `sendfunc' command should mml-encode
-the outgoing message before sending it.")
-
-(defun compose-mail (&optional to subject other-headers continue
- switch-function yank-action send-actions
- return-action)
- "Start composing a mail message to send.
-This uses the user's chosen mail composition package
-as selected with the variable `mail-user-agent'.
-The optional arguments TO and SUBJECT specify recipients
-and the initial Subject field, respectively.
-
-OTHER-HEADERS is an alist specifying additional
-header fields. Elements look like (HEADER . VALUE) where both
-HEADER and VALUE are strings.
-
-CONTINUE, if non-nil, says to continue editing a message already
-being composed. Interactively, CONTINUE is the prefix argument.
-
-SWITCH-FUNCTION, if non-nil, is a function to use to
-switch to and display the buffer used for mail composition.
-
-YANK-ACTION, if non-nil, is an action to perform, if and when necessary,
-to insert the raw text of the message being replied to.
-It has the form (FUNCTION . ARGS). The user agent will apply
-FUNCTION to ARGS, to insert the raw text of the original message.
-\(The user agent will also run `mail-citation-hook', *after* the
-original text has been inserted in this way.)
-
-SEND-ACTIONS is a list of actions to call when the message is sent.
-Each action has the form (FUNCTION . ARGS).
-
-RETURN-ACTION, if non-nil, is an action for returning to the
-caller. It has the form (FUNCTION . ARGS). The function is
-called after the mail has been sent or put aside, and the mail
-buffer buried."
- (interactive
- (list nil nil nil current-prefix-arg))
-
- ;; In Emacs 23.2, the default value of `mail-user-agent' changed
- ;; from sendmail-user-agent to message-user-agent. Some users may
- ;; encounter incompatibilities. This hack tries to detect problems
- ;; and warn about them.
- (and compose-mail-user-agent-warnings
- (eq mail-user-agent 'message-user-agent)
- (let (warn-vars)
- (dolist (var '(mail-mode-hook mail-send-hook mail-setup-hook
- mail-yank-hooks mail-archive-file-name
- mail-default-reply-to mail-mailing-lists
- mail-self-blind))
- (and (boundp var)
- (symbol-value var)
- (push var warn-vars)))
- (when warn-vars
- (display-warning 'mail
- (format "\
-The default mail mode is now Message mode.
-You have the following Mail mode variable%s customized:
-\n %s\n\nTo use Mail mode, set `mail-user-agent' to sendmail-user-agent.
-To disable this warning, set `compose-mail-user-agent-warnings' to nil."
- (if (> (length warn-vars) 1) "s" "")
- (mapconcat 'symbol-name
- warn-vars " "))))))
-
- (let ((function (get mail-user-agent 'composefunc)))
- (funcall function to subject other-headers continue switch-function
- yank-action send-actions return-action)))
-
-(defun compose-mail-other-window (&optional to subject other-headers continue
- yank-action send-actions
- return-action)
- "Like \\[compose-mail], but edit the outgoing message in another window."
- (interactive (list nil nil nil current-prefix-arg))
- (compose-mail to subject other-headers continue
- 'switch-to-buffer-other-window yank-action send-actions
- return-action))
-
-(defun compose-mail-other-frame (&optional to subject other-headers continue
- yank-action send-actions
- return-action)
- "Like \\[compose-mail], but edit the outgoing message in another frame."
- (interactive (list nil nil nil current-prefix-arg))
- (compose-mail to subject other-headers continue
- 'switch-to-buffer-other-frame yank-action send-actions
- return-action))
-
-
-(defvar set-variable-value-history nil
- "History of values entered with `set-variable'.
-
-Maximum length of the history list is determined by the value
-of `history-length', which see.")
-
-(defun set-variable (variable value &optional make-local)
- "Set VARIABLE to VALUE. VALUE is a Lisp object.
-VARIABLE should be a user option variable name, a Lisp variable
-meant to be customized by users. You should enter VALUE in Lisp syntax,
-so if you want VALUE to be a string, you must surround it with doublequotes.
-VALUE is used literally, not evaluated.
-
-If VARIABLE has a `variable-interactive' property, that is used as if
-it were the arg to `interactive' (which see) to interactively read VALUE.
-
-If VARIABLE has been defined with `defcustom', then the type information
-in the definition is used to check that VALUE is valid.
-
-With a prefix argument, set VARIABLE to VALUE buffer-locally."
- (interactive
- (let* ((default-var (variable-at-point))
- (var (if (custom-variable-p default-var)
- (read-variable (format "Set variable (default %s): "
default-var)
- default-var)
- (read-variable "Set variable: ")))
- (minibuffer-help-form '(describe-variable var))
- (prop (get var 'variable-interactive))
- (obsolete (car (get var 'byte-obsolete-variable)))
- (prompt (format "Set %s %s to value: " var
- (cond ((local-variable-p var)
- "(buffer-local)")
- ((or current-prefix-arg
- (local-variable-if-set-p var))
- "buffer-locally")
- (t "globally"))))
- (val (progn
- (when obsolete
- (message (concat "`%S' is obsolete; "
- (if (symbolp obsolete) "use `%S' instead"
"%s"))
- var obsolete)
- (sit-for 3))
- (if prop
- ;; Use VAR's `variable-interactive' property
- ;; as an interactive spec for prompting.
- (call-interactively `(lambda (arg)
- (interactive ,prop)
- arg))
- (read-from-minibuffer prompt nil
- read-expression-map t
- 'set-variable-value-history
- (format "%S" (symbol-value var)))))))
- (list var val current-prefix-arg)))
-
- (and (custom-variable-p variable)
- (not (get variable 'custom-type))
- (custom-load-symbol variable))
- (let ((type (get variable 'custom-type)))
- (when type
- ;; Match with custom type.
- (require 'cus-edit)
- (setq type (widget-convert type))
- (unless (widget-apply type :match value)
- (error "Value `%S' does not match type %S of %S"
- value (car type) variable))))
-
- (if make-local
- (make-local-variable variable))
-
- (set variable value)
-
- ;; Force a thorough redisplay for the case that the variable
- ;; has an effect on the display, like `tab-width' has.
- (force-mode-line-update))
-
-;; Define the major mode for lists of completions.
-
-(defvar completion-list-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [mouse-2] 'choose-completion)
- (define-key map [follow-link] 'mouse-face)
- (define-key map [down-mouse-2] nil)
- (define-key map "\C-m" 'choose-completion)
- (define-key map "\e\e\e" 'delete-completion-window)
- (define-key map [left] 'previous-completion)
- (define-key map [right] 'next-completion)
- (define-key map "q" 'quit-window)
- (define-key map "z" 'kill-this-buffer)
- map)
- "Local map for completion list buffers.")
-
-;; Completion mode is suitable only for specially formatted data.
-(put 'completion-list-mode 'mode-class 'special)
-
-(defvar completion-reference-buffer nil
- "Record the buffer that was current when the completion list was requested.
-This is a local variable in the completion list buffer.
-Initial value is nil to avoid some compiler warnings.")
-
-(defvar completion-no-auto-exit nil
- "Non-nil means `choose-completion-string' should never exit the minibuffer.
-This also applies to other functions such as `choose-completion'.")
-
-(defvar completion-base-position nil
- "Position of the base of the text corresponding to the shown completions.
-This variable is used in the *Completions* buffers.
-Its value is a list of the form (START END) where START is the place
-where the completion should be inserted and END (if non-nil) is the end
-of the text to replace. If END is nil, point is used instead.")
-
-(defvar completion-list-insert-choice-function #'completion--replace
- "Function to use to insert the text chosen in *Completions*.
-Called with three arguments (BEG END TEXT), it should replace the text
-between BEG and END with TEXT. Expected to be set buffer-locally
-in the *Completions* buffer.")
-
-(defvar completion-base-size nil
- "Number of chars before point not involved in completion.
-This is a local variable in the completion list buffer.
-It refers to the chars in the minibuffer if completing in the
-minibuffer, or in `completion-reference-buffer' otherwise.
-Only characters in the field at point are included.
-
-If nil, Emacs determines which part of the tail end of the
-buffer's text is involved in completion by comparing the text
-directly.")
-(make-obsolete-variable 'completion-base-size 'completion-base-position "23.2")
-
-(defun delete-completion-window ()
- "Delete the completion list window.
-Go to the window from which completion was requested."
- (interactive)
- (let ((buf completion-reference-buffer))
- (if (one-window-p t)
- (if (window-dedicated-p) (delete-frame))
- (delete-window (selected-window))
- (if (get-buffer-window buf)
- (select-window (get-buffer-window buf))))))
-
-(defun previous-completion (n)
- "Move to the previous item in the completion list."
- (interactive "p")
- (next-completion (- n)))
-
-(defun next-completion (n)
- "Move to the next item in the completion list.
-With prefix argument N, move N items (negative N means move backward)."
- (interactive "p")
- (let ((beg (point-min)) (end (point-max)))
- (while (and (> n 0) (not (eobp)))
- ;; If in a completion, move to the end of it.
- (when (get-text-property (point) 'mouse-face)
- (goto-char (next-single-property-change (point) 'mouse-face nil end)))
- ;; Move to start of next one.
- (unless (get-text-property (point) 'mouse-face)
- (goto-char (next-single-property-change (point) 'mouse-face nil end)))
- (setq n (1- n)))
- (while (and (< n 0) (not (bobp)))
- (let ((prop (get-text-property (1- (point)) 'mouse-face)))
- ;; If in a completion, move to the start of it.
- (when (and prop (eq prop (get-text-property (point) 'mouse-face)))
- (goto-char (previous-single-property-change
- (point) 'mouse-face nil beg)))
- ;; Move to end of the previous completion.
- (unless (or (bobp) (get-text-property (1- (point)) 'mouse-face))
- (goto-char (previous-single-property-change
- (point) 'mouse-face nil beg)))
- ;; Move to the start of that one.
- (goto-char (previous-single-property-change
- (point) 'mouse-face nil beg))
- (setq n (1+ n))))))
-
-(defun choose-completion (&optional event)
- "Choose the completion at point.
-If EVENT, use EVENT's position to determine the starting position."
- (interactive (list last-nonmenu-event))
- ;; In case this is run via the mouse, give temporary modes such as
- ;; isearch a chance to turn off.
- (run-hooks 'mouse-leave-buffer-hook)
- (with-current-buffer (window-buffer (posn-window (event-start event)))
- (let ((buffer completion-reference-buffer)
- (base-size completion-base-size)
- (base-position completion-base-position)
- (insert-function completion-list-insert-choice-function)
- (choice
- (save-excursion
- (goto-char (posn-point (event-start event)))
- (let (beg end)
- (cond
- ((and (not (eobp)) (get-text-property (point) 'mouse-face))
- (setq end (point) beg (1+ (point))))
- ((and (not (bobp))
- (get-text-property (1- (point)) 'mouse-face))
- (setq end (1- (point)) beg (point)))
- (t (error "No completion here")))
- (setq beg (previous-single-property-change beg 'mouse-face))
- (setq end (or (next-single-property-change end 'mouse-face)
- (point-max)))
- (buffer-substring-no-properties beg end)))))
-
- (unless (buffer-live-p buffer)
- (error "Destination buffer is dead"))
- (quit-window nil (posn-window (event-start event)))
-
- (with-current-buffer buffer
- (choose-completion-string
- choice buffer
- (or base-position
- (when base-size
- ;; Someone's using old completion code that doesn't know
- ;; about base-position yet.
- (list (+ base-size (field-beginning))))
- ;; If all else fails, just guess.
- (list (choose-completion-guess-base-position choice)))
- insert-function)))))
-
-;; Delete the longest partial match for STRING
-;; that can be found before POINT.
-(defun choose-completion-guess-base-position (string)
- (save-excursion
- (let ((opoint (point))
- len)
- ;; Try moving back by the length of the string.
- (goto-char (max (- (point) (length string))
- (minibuffer-prompt-end)))
- ;; See how far back we were actually able to move. That is the
- ;; upper bound on how much we can match and delete.
- (setq len (- opoint (point)))
- (if completion-ignore-case
- (setq string (downcase string)))
- (while (and (> len 0)
- (let ((tail (buffer-substring (point) opoint)))
- (if completion-ignore-case
- (setq tail (downcase tail)))
- (not (string= tail (substring string 0 len)))))
- (setq len (1- len))
- (forward-char 1))
- (point))))
-
-(defun choose-completion-delete-max-match (string)
- (declare (obsolete choose-completion-guess-base-position "23.2"))
- (delete-region (choose-completion-guess-base-position string) (point)))
-
-(defvar choose-completion-string-functions nil
- "Functions that may override the normal insertion of a completion choice.
-These functions are called in order with three arguments:
-CHOICE - the string to insert in the buffer,
-BUFFER - the buffer in which the choice should be inserted,
-BASE-POSITION - where to insert the completion.
-
-If a function in the list returns non-nil, that function is supposed
-to have inserted the CHOICE in the BUFFER, and possibly exited
-the minibuffer; no further functions will be called.
-
-If all functions in the list return nil, that means to use
-the default method of inserting the completion in BUFFER.")
-
-(defun choose-completion-string (choice &optional
- buffer base-position insert-function)
- "Switch to BUFFER and insert the completion choice CHOICE.
-BASE-POSITION says where to insert the completion.
-INSERT-FUNCTION says how to insert the completion and falls
-back on `completion-list-insert-choice-function' when nil."
-
- ;; If BUFFER is the minibuffer, exit the minibuffer
- ;; unless it is reading a file name and CHOICE is a directory,
- ;; or completion-no-auto-exit is non-nil.
-
- ;; Some older code may call us passing `base-size' instead of
- ;; `base-position'. It's difficult to make any use of `base-size',
- ;; so we just ignore it.
- (unless (consp base-position)
- (message "Obsolete `base-size' passed to choose-completion-string")
- (setq base-position nil))
-
- (let* ((buffer (or buffer completion-reference-buffer))
- (mini-p (minibufferp buffer)))
- ;; If BUFFER is a minibuffer, barf unless it's the currently
- ;; active minibuffer.
- (if (and mini-p
- (not (and (active-minibuffer-window)
- (equal buffer
- (window-buffer (active-minibuffer-window))))))
- (error "Minibuffer is not active for completion")
- ;; Set buffer so buffer-local choose-completion-string-functions works.
- (set-buffer buffer)
- (unless (run-hook-with-args-until-success
- 'choose-completion-string-functions
- ;; The fourth arg used to be `mini-p' but was useless
- ;; (since minibufferp can be used on the `buffer' arg)
- ;; and indeed unused. The last used to be `base-size', so we
- ;; keep it to try and avoid breaking old code.
- choice buffer base-position nil)
- ;; This remove-text-properties should be unnecessary since `choice'
- ;; comes from buffer-substring-no-properties.
- ;;(remove-text-properties 0 (length choice) '(mouse-face nil) choice)
- ;; Insert the completion into the buffer where it was requested.
- (funcall (or insert-function completion-list-insert-choice-function)
- (or (car base-position) (point))
- (or (cadr base-position) (point))
- choice)
- ;; Update point in the window that BUFFER is showing in.
- (let ((window (get-buffer-window buffer t)))
- (set-window-point window (point)))
- ;; If completing for the minibuffer, exit it with this choice.
- (and (not completion-no-auto-exit)
- (minibufferp buffer)
- minibuffer-completion-table
- ;; If this is reading a file name, and the file name chosen
- ;; is a directory, don't exit the minibuffer.
- (let* ((result (buffer-substring (field-beginning) (point)))
- (bounds
- (completion-boundaries result minibuffer-completion-table
- minibuffer-completion-predicate
- "")))
- (if (eq (car bounds) (length result))
- ;; The completion chosen leads to a new set of completions
- ;; (e.g. it's a directory): don't exit the minibuffer yet.
- (let ((mini (active-minibuffer-window)))
- (select-window mini)
- (when minibuffer-auto-raise
- (raise-frame (window-frame mini))))
- (exit-minibuffer))))))))
-
-(define-derived-mode completion-list-mode nil "Completion List"
- "Major mode for buffers showing lists of possible completions.
-Type \\<completion-list-mode-map>\\[choose-completion] in the completion list\
- to select the completion near point.
-Or click to select one with the mouse.
-
-\\{completion-list-mode-map}"
- (set (make-local-variable 'completion-base-size) nil))
-
-(defun completion-list-mode-finish ()
- "Finish setup of the completions buffer.
-Called from `temp-buffer-show-hook'."
- (when (eq major-mode 'completion-list-mode)
- (setq buffer-read-only t)))
-
-(add-hook 'temp-buffer-show-hook 'completion-list-mode-finish)
-
-
-;; Variables and faces used in `completion-setup-function'.
-
-(defcustom completion-show-help t
- "Non-nil means show help message in *Completions* buffer."
- :type 'boolean
- :version "22.1"
- :group 'completion)
-
-;; This function goes in completion-setup-hook, so that it is called
-;; after the text of the completion list buffer is written.
-(defun completion-setup-function ()
- (let* ((mainbuf (current-buffer))
- (base-dir
- ;; FIXME: This is a bad hack. We try to set the default-directory
- ;; in the *Completions* buffer so that the relative file names
- ;; displayed there can be treated as valid file names, independently
- ;; from the completion context. But this suffers from many problems:
- ;; - It's not clear when the completions are file names. With some
- ;; completion tables (e.g. bzr revision specs), the listed
- ;; completions can mix file names and other things.
- ;; - It doesn't pay attention to possible quoting.
- ;; - With fancy completion styles, the code below will not always
- ;; find the right base directory.
- (if minibuffer-completing-file-name
- (file-name-as-directory
- (expand-file-name
- (buffer-substring (minibuffer-prompt-end)
- (- (point) (or completion-base-size 0))))))))
- (with-current-buffer standard-output
- (let ((base-size completion-base-size) ;Read before killing localvars.
- (base-position completion-base-position)
- (insert-fun completion-list-insert-choice-function))
- (completion-list-mode)
- (set (make-local-variable 'completion-base-size) base-size)
- (set (make-local-variable 'completion-base-position) base-position)
- (set (make-local-variable 'completion-list-insert-choice-function)
- insert-fun))
- (set (make-local-variable 'completion-reference-buffer) mainbuf)
- (if base-dir (setq default-directory base-dir))
- ;; Maybe insert help string.
- (when completion-show-help
- (goto-char (point-min))
- (if (display-mouse-p)
- (insert (substitute-command-keys
- "Click on a completion to select it.\n")))
- (insert (substitute-command-keys
- "In this buffer, type \\[choose-completion] to \
-select the completion near point.\n\n"))))))
-
-(add-hook 'completion-setup-hook 'completion-setup-function)
-
-(define-key minibuffer-local-completion-map [prior] 'switch-to-completions)
-(define-key minibuffer-local-completion-map "\M-v" 'switch-to-completions)
-
-(defun switch-to-completions ()
- "Select the completion list window."
- (interactive)
- (let ((window (or (get-buffer-window "*Completions*" 0)
- ;; Make sure we have a completions window.
- (progn (minibuffer-completion-help)
- (get-buffer-window "*Completions*" 0)))))
- (when window
- (select-window window)
- ;; In the new buffer, go to the first completion.
- ;; FIXME: Perhaps this should be done in `minibuffer-completion-help'.
- (when (bobp)
- (next-completion 1)))))
-
-;;; Support keyboard commands to turn on various modifiers.
-
-;; These functions -- which are not commands -- each add one modifier
-;; to the following event.
-
-(defun event-apply-alt-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Alt modifier to the following event.
-For example, type \\[event-apply-alt-modifier] & to enter Alt-&."
- (vector (event-apply-modifier (read-event) 'alt 22 "A-")))
-(defun event-apply-super-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Super modifier to the following event.
-For example, type \\[event-apply-super-modifier] & to enter Super-&."
- (vector (event-apply-modifier (read-event) 'super 23 "s-")))
-(defun event-apply-hyper-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Hyper modifier to the following event.
-For example, type \\[event-apply-hyper-modifier] & to enter Hyper-&."
- (vector (event-apply-modifier (read-event) 'hyper 24 "H-")))
-(defun event-apply-shift-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Shift modifier to the following event.
-For example, type \\[event-apply-shift-modifier] & to enter Shift-&."
- (vector (event-apply-modifier (read-event) 'shift 25 "S-")))
-(defun event-apply-control-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Ctrl modifier to the following event.
-For example, type \\[event-apply-control-modifier] & to enter Ctrl-&."
- (vector (event-apply-modifier (read-event) 'control 26 "C-")))
-(defun event-apply-meta-modifier (_ignore-prompt)
- "\\<function-key-map>Add the Meta modifier to the following event.
-For example, type \\[event-apply-meta-modifier] & to enter Meta-&."
- (vector (event-apply-modifier (read-event) 'meta 27 "M-")))
-
-(defun event-apply-modifier (event symbol lshiftby prefix)
- "Apply a modifier flag to event EVENT.
-SYMBOL is the name of this modifier, as a symbol.
-LSHIFTBY is the numeric value of this modifier, in keyboard events.
-PREFIX is the string that represents this modifier in an event type symbol."
- (if (numberp event)
- (cond ((eq symbol 'control)
- (if (and (<= (downcase event) ?z)
- (>= (downcase event) ?a))
- (- (downcase event) ?a -1)
- (if (and (<= (downcase event) ?Z)
- (>= (downcase event) ?A))
- (- (downcase event) ?A -1)
- (logior (lsh 1 lshiftby) event))))
- ((eq symbol 'shift)
- (if (and (<= (downcase event) ?z)
- (>= (downcase event) ?a))
- (upcase event)
- (logior (lsh 1 lshiftby) event)))
- (t
- (logior (lsh 1 lshiftby) event)))
- (if (memq symbol (event-modifiers event))
- event
- (let ((event-type (if (symbolp event) event (car event))))
- (setq event-type (intern (concat prefix (symbol-name event-type))))
- (if (symbolp event)
- event-type
- (cons event-type (cdr event)))))))
-
-(define-key function-key-map [?\C-x ?@ ?h] 'event-apply-hyper-modifier)
-(define-key function-key-map [?\C-x ?@ ?s] 'event-apply-super-modifier)
-(define-key function-key-map [?\C-x ?@ ?m] 'event-apply-meta-modifier)
-(define-key function-key-map [?\C-x ?@ ?a] 'event-apply-alt-modifier)
-(define-key function-key-map [?\C-x ?@ ?S] 'event-apply-shift-modifier)
-(define-key function-key-map [?\C-x ?@ ?c] 'event-apply-control-modifier)
-
-;;;; Keypad support.
-
-;; Make the keypad keys act like ordinary typing keys. If people add
-;; bindings for the function key symbols, then those bindings will
-;; override these, so this shouldn't interfere with any existing
-;; bindings.
-
-;; Also tell read-char how to handle these keys.
-(mapc
- (lambda (keypad-normal)
- (let ((keypad (nth 0 keypad-normal))
- (normal (nth 1 keypad-normal)))
- (put keypad 'ascii-character normal)
- (define-key function-key-map (vector keypad) (vector normal))))
- ;; See also kp-keys bound in bindings.el.
- '((kp-space ?\s)
- (kp-tab ?\t)
- (kp-enter ?\r)
- (kp-separator ?,)
- (kp-equal ?=)
- ;; Do the same for various keys that are represented as symbols under
- ;; GUIs but naturally correspond to characters.
- (backspace 127)
- (delete 127)
- (tab ?\t)
- (linefeed ?\n)
- (clear ?\C-l)
- (return ?\C-m)
- (escape ?\e)
- ))
-
-;;;;
-;;;; forking a twin copy of a buffer.
-;;;;
-
-(defvar clone-buffer-hook nil
- "Normal hook to run in the new buffer at the end of `clone-buffer'.")
-
-(defvar clone-indirect-buffer-hook nil
- "Normal hook to run in the new buffer at the end of
`clone-indirect-buffer'.")
-
-(defun clone-process (process &optional newname)
- "Create a twin copy of PROCESS.
-If NEWNAME is nil, it defaults to PROCESS' name;
-NEWNAME is modified by adding or incrementing <N> at the end as necessary.
-If PROCESS is associated with a buffer, the new process will be associated
- with the current buffer instead.
-Returns nil if PROCESS has already terminated."
- (setq newname (or newname (process-name process)))
- (if (string-match "<[0-9]+>\\'" newname)
- (setq newname (substring newname 0 (match-beginning 0))))
- (when (memq (process-status process) '(run stop open))
- (let* ((process-connection-type (process-tty-name process))
- (new-process
- (if (memq (process-status process) '(open))
- (let ((args (process-contact process t)))
- (setq args (plist-put args :name newname))
- (setq args (plist-put args :buffer
- (if (process-buffer process)
- (current-buffer))))
- (apply 'make-network-process args))
- (apply 'start-process newname
- (if (process-buffer process) (current-buffer))
- (process-command process)))))
- (set-process-query-on-exit-flag
- new-process (process-query-on-exit-flag process))
- (set-process-inherit-coding-system-flag
- new-process (process-inherit-coding-system-flag process))
- (set-process-filter new-process (process-filter process))
- (set-process-sentinel new-process (process-sentinel process))
- (set-process-plist new-process (copy-sequence (process-plist process)))
- new-process)))
-
-;; things to maybe add (currently partly covered by `funcall mode'):
-;; - syntax-table
-;; - overlays
-(defun clone-buffer (&optional newname display-flag)
- "Create and return a twin copy of the current buffer.
-Unlike an indirect buffer, the new buffer can be edited
-independently of the old one (if it is not read-only).
-NEWNAME is the name of the new buffer. It may be modified by
-adding or incrementing <N> at the end as necessary to create a
-unique buffer name. If nil, it defaults to the name of the
-current buffer, with the proper suffix. If DISPLAY-FLAG is
-non-nil, the new buffer is shown with `pop-to-buffer'. Trying to
-clone a file-visiting buffer, or a buffer whose major mode symbol
-has a non-nil `no-clone' property, results in an error.
-
-Interactively, DISPLAY-FLAG is t and NEWNAME is the name of the
-current buffer with appropriate suffix. However, if a prefix
-argument is given, then the command prompts for NEWNAME in the
-minibuffer.
-
-This runs the normal hook `clone-buffer-hook' in the new buffer
-after it has been set up properly in other respects."
- (interactive
- (progn
- (if buffer-file-name
- (error "Cannot clone a file-visiting buffer"))
- (if (get major-mode 'no-clone)
- (error "Cannot clone a buffer in %s mode" mode-name))
- (list (if current-prefix-arg
- (read-buffer "Name of new cloned buffer: " (current-buffer)))
- t)))
- (if buffer-file-name
- (error "Cannot clone a file-visiting buffer"))
- (if (get major-mode 'no-clone)
- (error "Cannot clone a buffer in %s mode" mode-name))
- (setq newname (or newname (buffer-name)))
- (if (string-match "<[0-9]+>\\'" newname)
- (setq newname (substring newname 0 (match-beginning 0))))
- (let ((buf (current-buffer))
- (ptmin (point-min))
- (ptmax (point-max))
- (pt (point))
- (mk (if mark-active (mark t)))
- (modified (buffer-modified-p))
- (mode major-mode)
- (lvars (buffer-local-variables))
- (process (get-buffer-process (current-buffer)))
- (new (generate-new-buffer (or newname (buffer-name)))))
- (save-restriction
- (widen)
- (with-current-buffer new
- (insert-buffer-substring buf)))
- (with-current-buffer new
- (narrow-to-region ptmin ptmax)
- (goto-char pt)
- (if mk (set-mark mk))
- (set-buffer-modified-p modified)
-
- ;; Clone the old buffer's process, if any.
- (when process (clone-process process))
-
- ;; Now set up the major mode.
- (funcall mode)
-
- ;; Set up other local variables.
- (mapc (lambda (v)
- (condition-case () ;in case var is read-only
- (if (symbolp v)
- (makunbound v)
- (set (make-local-variable (car v)) (cdr v)))
- (error nil)))
- lvars)
-
- ;; Run any hooks (typically set up by the major mode
- ;; for cloning to work properly).
- (run-hooks 'clone-buffer-hook))
- (if display-flag
- ;; Presumably the current buffer is shown in the selected frame, so
- ;; we want to display the clone elsewhere.
- (let ((same-window-regexps nil)
- (same-window-buffer-names))
- (pop-to-buffer new)))
- new))
-
-
-(defun clone-indirect-buffer (newname display-flag &optional norecord)
- "Create an indirect buffer that is a twin copy of the current buffer.
-
-Give the indirect buffer name NEWNAME. Interactively, read NEWNAME
-from the minibuffer when invoked with a prefix arg. If NEWNAME is nil
-or if not called with a prefix arg, NEWNAME defaults to the current
-buffer's name. The name is modified by adding a `<N>' suffix to it
-or by incrementing the N in an existing suffix. Trying to clone a
-buffer whose major mode symbol has a non-nil `no-clone-indirect'
-property results in an error.
-
-DISPLAY-FLAG non-nil means show the new buffer with `pop-to-buffer'.
-This is always done when called interactively.
-
-Optional third arg NORECORD non-nil means do not put this buffer at the
-front of the list of recently selected ones."
- (interactive
- (progn
- (if (get major-mode 'no-clone-indirect)
- (error "Cannot indirectly clone a buffer in %s mode" mode-name))
- (list (if current-prefix-arg
- (read-buffer "Name of indirect buffer: " (current-buffer)))
- t)))
- (if (get major-mode 'no-clone-indirect)
- (error "Cannot indirectly clone a buffer in %s mode" mode-name))
- (setq newname (or newname (buffer-name)))
- (if (string-match "<[0-9]+>\\'" newname)
- (setq newname (substring newname 0 (match-beginning 0))))
- (let* ((name (generate-new-buffer-name newname))
- (buffer (make-indirect-buffer (current-buffer) name t)))
- (with-current-buffer buffer
- (run-hooks 'clone-indirect-buffer-hook))
- (when display-flag
- (pop-to-buffer buffer norecord))
- buffer))
-
-
-(defun clone-indirect-buffer-other-window (newname display-flag &optional
norecord)
- "Like `clone-indirect-buffer' but display in another window."
- (interactive
- (progn
- (if (get major-mode 'no-clone-indirect)
- (error "Cannot indirectly clone a buffer in %s mode" mode-name))
- (list (if current-prefix-arg
- (read-buffer "Name of indirect buffer: " (current-buffer)))
- t)))
- (let ((pop-up-windows t))
- (clone-indirect-buffer newname display-flag norecord)))
-
-
-;;; Handling of Backspace and Delete keys.
-
-(defcustom normal-erase-is-backspace 'maybe
- "Set the default behavior of the Delete and Backspace keys.
-
-If set to t, Delete key deletes forward and Backspace key deletes
-backward.
-
-If set to nil, both Delete and Backspace keys delete backward.
-
-If set to 'maybe (which is the default), Emacs automatically
-selects a behavior. On window systems, the behavior depends on
-the keyboard used. If the keyboard has both a Backspace key and
-a Delete key, and both are mapped to their usual meanings, the
-option's default value is set to t, so that Backspace can be used
-to delete backward, and Delete can be used to delete forward.
-
-If not running under a window system, customizing this option
-accomplishes a similar effect by mapping C-h, which is usually
-generated by the Backspace key, to DEL, and by mapping DEL to C-d
-via `keyboard-translate'. The former functionality of C-h is
-available on the F1 key. You should probably not use this
-setting if you don't have both Backspace, Delete and F1 keys.
-
-Setting this variable with setq doesn't take effect. Programmatically,
-call `normal-erase-is-backspace-mode' (which see) instead."
- :type '(choice (const :tag "Off" nil)
- (const :tag "Maybe" maybe)
- (other :tag "On" t))
- :group 'editing-basics
- :version "21.1"
- :set (lambda (symbol value)
- ;; The fboundp is because of a problem with :set when
- ;; dumping Emacs. It doesn't really matter.
- (if (fboundp 'normal-erase-is-backspace-mode)
- (normal-erase-is-backspace-mode (or value 0))
- (set-default symbol value))))
-
-(defun normal-erase-is-backspace-setup-frame (&optional frame)
- "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
- (unless frame (setq frame (selected-frame)))
- (with-selected-frame frame
- (unless (terminal-parameter nil 'normal-erase-is-backspace)
- (normal-erase-is-backspace-mode
- (if (if (eq normal-erase-is-backspace 'maybe)
- (and (not noninteractive)
- (or (memq system-type '(ms-dos windows-nt))
- (memq window-system '(w32 ns))
- (and (memq window-system '(x))
- (fboundp 'x-backspace-delete-keys-p)
- (x-backspace-delete-keys-p))
- ;; If the terminal Emacs is running on has erase char
- ;; set to ^H, use the Backspace key for deleting
- ;; backward, and the Delete key for deleting forward.
- (and (null window-system)
- (eq tty-erase-char ?\^H))))
- normal-erase-is-backspace)
- 1 0)))))
-
-(define-minor-mode normal-erase-is-backspace-mode
- "Toggle the Erase and Delete mode of the Backspace and Delete keys.
-With a prefix argument ARG, enable this feature if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-On window systems, when this mode is on, Delete is mapped to C-d
-and Backspace is mapped to DEL; when this mode is off, both
-Delete and Backspace are mapped to DEL. (The remapping goes via
-`local-function-key-map', so binding Delete or Backspace in the
-global or local keymap will override that.)
-
-In addition, on window systems, the bindings of C-Delete, M-Delete,
-C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
-the global keymap in accordance with the functionality of Delete and
-Backspace. For example, if Delete is remapped to C-d, which deletes
-forward, C-Delete is bound to `kill-word', but if Delete is remapped
-to DEL, which deletes backward, C-Delete is bound to
-`backward-kill-word'.
-
-If not running on a window system, a similar effect is accomplished by
-remapping C-h (normally produced by the Backspace key) and DEL via
-`keyboard-translate': if this mode is on, C-h is mapped to DEL and DEL
-to C-d; if it's off, the keys are not remapped.
-
-When not running on a window system, and this mode is turned on, the
-former functionality of C-h is available on the F1 key. You should
-probably not turn on this mode on a text-only terminal if you don't
-have both Backspace, Delete and F1 keys.
-
-See also `normal-erase-is-backspace'."
- :variable ((eq (terminal-parameter nil 'normal-erase-is-backspace) 1)
- . (lambda (v)
- (setf (terminal-parameter nil 'normal-erase-is-backspace)
- (if v 1 0))))
- (let ((enabled (eq 1 (terminal-parameter
- nil 'normal-erase-is-backspace))))
-
- (cond ((or (memq window-system '(x w32 ns pc))
- (memq system-type '(ms-dos windows-nt)))
- (let ((bindings
- `(([M-delete] [M-backspace])
- ([C-M-delete] [C-M-backspace])
- ([?\e C-delete] [?\e C-backspace]))))
-
- (if enabled
- (progn
- (define-key local-function-key-map [delete] [deletechar])
- (define-key local-function-key-map [kp-delete] [deletechar])
- (define-key local-function-key-map [backspace] [?\C-?])
- (dolist (b bindings)
- ;; Not sure if input-decode-map is really right, but
- ;; keyboard-translate-table (used below) only works
- ;; for integer events, and key-translation-table is
- ;; global (like the global-map, used earlier).
- (define-key input-decode-map (car b) nil)
- (define-key input-decode-map (cadr b) nil)))
- (define-key local-function-key-map [delete] [?\C-?])
- (define-key local-function-key-map [kp-delete] [?\C-?])
- (define-key local-function-key-map [backspace] [?\C-?])
- (dolist (b bindings)
- (define-key input-decode-map (car b) (cadr b))
- (define-key input-decode-map (cadr b) (car b))))))
- (t
- (if enabled
- (progn
- (keyboard-translate ?\C-h ?\C-?)
- (keyboard-translate ?\C-? ?\C-d))
- (keyboard-translate ?\C-h ?\C-h)
- (keyboard-translate ?\C-? ?\C-?))))
-
- (if (called-interactively-p 'interactive)
- (message "Delete key deletes %s"
- (if (eq 1 (terminal-parameter nil 'normal-erase-is-backspace))
- "forward" "backward")))))
-
-(defvar vis-mode-saved-buffer-invisibility-spec nil
- "Saved value of `buffer-invisibility-spec' when Visible mode is on.")
-
-(define-minor-mode read-only-mode
- "Change whether the current buffer is read-only.
-With prefix argument ARG, make the buffer read-only if ARG is
-positive, otherwise make it writable. If buffer is read-only
-and `view-read-only' is non-nil, enter view mode.
-
-Do not call this from a Lisp program unless you really intend to
-do the same thing as the \\[read-only-mode] command, including
-possibly enabling or disabling View mode. Also, note that this
-command works by setting the variable `buffer-read-only', which
-does not affect read-only regions caused by text properties. To
-ignore read-only status in a Lisp program (whether due to text
-properties or buffer state), bind `inhibit-read-only' temporarily
-to a non-nil value."
- :variable buffer-read-only
- (cond
- ((and (not buffer-read-only) view-mode)
- (View-exit-and-edit)
- (make-local-variable 'view-read-only)
- (setq view-read-only t)) ; Must leave view mode.
- ((and buffer-read-only view-read-only
- ;; If view-mode is already active, `view-mode-enter' is a nop.
- (not view-mode)
- (not (eq (get major-mode 'mode-class) 'special)))
- (view-mode-enter))))
-
-(define-minor-mode visible-mode
- "Toggle making all invisible text temporarily visible (Visible mode).
-With a prefix argument ARG, enable Visible mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-This mode works by saving the value of `buffer-invisibility-spec'
-and setting it to nil."
- :lighter " Vis"
- :group 'editing-basics
- (when (local-variable-p 'vis-mode-saved-buffer-invisibility-spec)
- (setq buffer-invisibility-spec vis-mode-saved-buffer-invisibility-spec)
- (kill-local-variable 'vis-mode-saved-buffer-invisibility-spec))
- (when visible-mode
- (set (make-local-variable 'vis-mode-saved-buffer-invisibility-spec)
- buffer-invisibility-spec)
- (setq buffer-invisibility-spec nil)))
-
-(defvar messages-buffer-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map special-mode-map)
- (define-key map "g" nil) ; nothing to revert
- map))
-
-(define-derived-mode messages-buffer-mode special-mode "Messages"
- "Major mode used in the \"*Messages*\" buffer.")
-
-(defun messages-buffer ()
- "Return the \"*Messages*\" buffer.
-If it does not exist, create and it switch it to `messages-buffer-mode'."
- (or (get-buffer "*Messages*")
- (with-current-buffer (get-buffer-create "*Messages*")
- (messages-buffer-mode)
- (current-buffer))))
-
-
-;; Minibuffer prompt stuff.
-
-;;(defun minibuffer-prompt-modification (start end)
-;; (error "You cannot modify the prompt"))
-;;
-;;
-;;(defun minibuffer-prompt-insertion (start end)
-;; (let ((inhibit-modification-hooks t))
-;; (delete-region start end)
-;; ;; Discard undo information for the text insertion itself
-;; ;; and for the text deletion.above.
-;; (when (consp buffer-undo-list)
-;; (setq buffer-undo-list (cddr buffer-undo-list)))
-;; (message "You cannot modify the prompt")))
-;;
-;;
-;;(setq minibuffer-prompt-properties
-;; (list 'modification-hooks '(minibuffer-prompt-modification)
-;; 'insert-in-front-hooks '(minibuffer-prompt-insertion)))
-
-
-;;;; Problematic external packages.
-
-;; rms says this should be done by specifying symbols that define
-;; versions together with bad values. This is therefore not as
-;; flexible as it could be. See the thread:
-;; http://lists.gnu.org/archive/html/emacs-devel/2007-08/msg00300.html
-(defconst bad-packages-alist
- ;; Not sure exactly which semantic versions have problems.
- ;; Definitely 2.0pre3, probably all 2.0pre's before this.
- '((semantic semantic-version "\\`2\\.0pre[1-3]\\'"
- "The version of `semantic' loaded does not work in Emacs 22.
-It can cause constant high CPU load.
-Upgrade to at least Semantic 2.0pre4 (distributed with CEDET 1.0pre4).")
- ;; CUA-mode does not work with GNU Emacs version 22.1 and newer.
- ;; Except for version 1.2, all of the 1.x and 2.x version of cua-mode
- ;; provided the `CUA-mode' feature. Since this is no longer true,
- ;; we can warn the user if the `CUA-mode' feature is ever provided.
- (CUA-mode t nil
-"CUA-mode is now part of the standard GNU Emacs distribution,
-so you can now enable CUA via the Options menu or by customizing `cua-mode'.
-
-You have loaded an older version of CUA-mode which does not work
-correctly with this version of Emacs. You should remove the old
-version and use the one distributed with Emacs."))
- "Alist of packages known to cause problems in this version of Emacs.
-Each element has the form (PACKAGE SYMBOL REGEXP STRING).
-PACKAGE is either a regular expression to match file names, or a
-symbol (a feature name), like for `with-eval-after-load'.
-SYMBOL is either the name of a string variable, or `t'. Upon
-loading PACKAGE, if SYMBOL is t or matches REGEXP, display a
-warning using STRING as the message.")
-
-(defun bad-package-check (package)
- "Run a check using the element from `bad-packages-alist' matching PACKAGE."
- (condition-case nil
- (let* ((list (assoc package bad-packages-alist))
- (symbol (nth 1 list)))
- (and list
- (boundp symbol)
- (or (eq symbol t)
- (and (stringp (setq symbol (eval symbol)))
- (string-match-p (nth 2 list) symbol)))
- (display-warning package (nth 3 list) :warning)))
- (error nil)))
-
-(dolist (elem bad-packages-alist)
- (let ((pkg (car elem)))
- (with-eval-after-load pkg
- (bad-package-check pkg))))
-
-
-;;; Generic dispatcher commands
-
-;; Macro `define-alternatives' is used to create generic commands.
-;; Generic commands are these (like web, mail, news, encrypt, irc, etc.)
-;; that can have different alternative implementations where choosing
-;; among them is exclusively a matter of user preference.
-
-;; (define-alternatives COMMAND) creates a new interactive command
-;; M-x COMMAND and a customizable variable COMMAND-alternatives.
-;; Typically, the user will not need to customize this variable; packages
-;; wanting to add alternative implementations should use
-;;
-;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives
-
-(defmacro define-alternatives (command &rest customizations)
- "Define the new command `COMMAND'.
-
-The argument `COMMAND' should be a symbol.
-
-Running `M-x COMMAND RET' for the first time prompts for which
-alternative to use and records the selected command as a custom
-variable.
-
-Running `C-u M-x COMMAND RET' prompts again for an alternative
-and overwrites the previous choice.
-
-The variable `COMMAND-alternatives' contains an alist with
-alternative implementations of COMMAND. `define-alternatives'
-does not have any effect until this variable is set.
-
-CUSTOMIZATIONS, if non-nil, should be composed of alternating
-`defcustom' keywords and values to add to the declaration of
-`COMMAND-alternatives' (typically :group and :version)."
- (let* ((command-name (symbol-name command))
- (varalt-name (concat command-name "-alternatives"))
- (varalt-sym (intern varalt-name))
- (varimp-sym (intern (concat command-name "--implementation"))))
- `(progn
-
- (defcustom ,varalt-sym nil
- ,(format "Alist of alternative implementations for the `%s' command.
-
-Each entry must be a pair (ALTNAME . ALTFUN), where:
-ALTNAME - The name shown at user to describe the alternative implementation.
-ALTFUN - The function called to implement this alternative."
- command-name)
- :type '(alist :key-type string :value-type function)
- ,@customizations)
-
- (put ',varalt-sym 'definition-name ',command)
- (defvar ,varimp-sym nil "Internal use only.")
-
- (defun ,command (&optional arg)
- ,(format "Run generic command `%s'.
-If used for the first time, or with interactive ARG, ask the user which
-implementation to use for `%s'. The variable `%s'
-contains the list of implementations currently supported for this command."
- command-name command-name varalt-name)
- (interactive "P")
- (when (or arg (null ,varimp-sym))
- (let ((val (completing-read
- ,(format "Select implementation for command `%s': "
- command-name)
- ,varalt-sym nil t)))
- (unless (string-equal val "")
- (when (null ,varimp-sym)
- (message
- "Use `C-u M-x %s RET' to select another implementation"
- ,command-name)
- (sit-for 3))
- (customize-save-variable ',varimp-sym
- (cdr (assoc-string val ,varalt-sym))))))
- (if ,varimp-sym
- (call-interactively ,varimp-sym)
- (message ,(format "No implementation selected for command `%s'"
- command-name)))))))
-
-
-;; This is here because files in obsolete/ are not scanned for autoloads.
-
-(defvar iswitchb-mode nil "\
-Non-nil if Iswitchb mode is enabled.
-See the command `iswitchb-mode' 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 `iswitchb-mode'.")
-
-(custom-autoload 'iswitchb-mode "iswitchb" nil)
-
-(autoload 'iswitchb-mode "iswitchb" "\
-Toggle Iswitchb mode.
-With a prefix argument ARG, enable Iswitchb mode if ARG is
-positive, and disable it otherwise. If called from Lisp, enable
-the mode if ARG is omitted or nil.
-
-Iswitchb mode is a global minor mode that enables switching
-between buffers using substrings. See `iswitchb' for details.
-
-\(fn &optional ARG)" t nil)
-
-(make-obsolete 'iswitchb-mode
- "use `icomplete-mode' or `ido-mode' instead." "24.4")
-
-
-(provide 'simple)
-
-;;; simple.el ends here
diff --git a/packages/context-coloring/fixtures/benchmark/subr.el
b/packages/context-coloring/fixtures/benchmark/subr.el
deleted file mode 100644
index d4da916..0000000
--- a/packages/context-coloring/fixtures/benchmark/subr.el
+++ /dev/null
@@ -1,4800 +0,0 @@
-;;; subr.el --- basic lisp subroutines for Emacs -*- coding: utf-8;
lexical-binding:t -*-
-
-;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2015 Free Software
Foundation, Inc.
-
-;; Maintainer: emacs-devel@gnu.org
-;; Keywords: internal
-;; Package: emacs
-
-;; 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:
-
-;;; Code:
-
-;; Beware: while this file has tag `utf-8', before it's compiled, it gets
-;; loaded as "raw-text", so non-ASCII chars won't work right during bootstrap.
-
-(defmacro declare-function (_fn _file &optional _arglist _fileonly)
- "Tell the byte-compiler that function FN is defined, in FILE.
-Optional ARGLIST is the argument list used by the function.
-The FILE argument is not used by the byte-compiler, but by the
-`check-declare' package, which checks that FILE contains a
-definition for FN. ARGLIST is used by both the byte-compiler
-and `check-declare' to check for consistency.
-
-FILE can be either a Lisp file (in which case the \".el\"
-extension is optional), or a C file. C files are expanded
-relative to the Emacs \"src/\" directory. Lisp files are
-searched for using `locate-library', and if that fails they are
-expanded relative to the location of the file containing the
-declaration. A FILE with an \"ext:\" prefix is an external file.
-`check-declare' will check such files if they are found, and skip
-them without error if they are not.
-
-FILEONLY non-nil means that `check-declare' will only check that
-FILE exists, not that it defines FN. This is intended for
-function-definitions that `check-declare' does not recognize, e.g.
-`defstruct'.
-
-To specify a value for FILEONLY without passing an argument list,
-set ARGLIST to t. This is necessary because nil means an
-empty argument list, rather than an unspecified one.
-
-Note that for the purposes of `check-declare', this statement
-must be the first non-whitespace on a line.
-
-For more information, see Info node `(elisp)Declaring Functions'."
- ;; Does nothing - byte-compile-declare-function does the work.
- nil)
-
-
-;;;; Basic Lisp macros.
-
-(defalias 'not 'null)
-
-(defmacro noreturn (form)
- "Evaluate FORM, expecting it not to return.
-If FORM does return, signal an error."
- (declare (debug t))
- `(prog1 ,form
- (error "Form marked with `noreturn' did return")))
-
-(defmacro 1value (form)
- "Evaluate FORM, expecting a constant return value.
-This is the global do-nothing version. There is also `testcover-1value'
-that complains if FORM ever does return differing values."
- (declare (debug t))
- form)
-
-(defmacro def-edebug-spec (symbol spec)
- "Set the `edebug-form-spec' property of SYMBOL according to SPEC.
-Both SYMBOL and SPEC are unevaluated. The SPEC can be:
-0 (instrument no arguments); t (instrument all arguments);
-a symbol (naming a function with an Edebug specification); or a list.
-The elements of the list describe the argument types; see
-Info node `(elisp)Specification List' for details."
- `(put (quote ,symbol) 'edebug-form-spec (quote ,spec)))
-
-(defmacro lambda (&rest cdr)
- "Return a lambda expression.
-A call of the form (lambda ARGS DOCSTRING INTERACTIVE BODY) is
-self-quoting; the result of evaluating the lambda expression is the
-expression itself. The lambda expression may then be treated as a
-function, i.e., stored as the function value of a symbol, passed to
-`funcall' or `mapcar', etc.
-
-ARGS should take the same form as an argument list for a `defun'.
-DOCSTRING is an optional documentation string.
- If present, it should describe how to call the function.
- But documentation strings are usually not useful in nameless functions.
-INTERACTIVE should be a call to the function `interactive', which see.
-It may also be omitted.
-BODY should be a list of Lisp expressions.
-
-\(fn ARGS [DOCSTRING] [INTERACTIVE] BODY)"
- (declare (doc-string 2) (indent defun)
- (debug (&define lambda-list
- [&optional stringp]
- [&optional ("interactive" interactive)]
- def-body)))
- ;; Note that this definition should not use backquotes; subr.el should not
- ;; depend on backquote.el.
- (list 'function (cons 'lambda cdr)))
-
-(defmacro setq-local (var val)
- "Set variable VAR to value VAL in current buffer."
- ;; Can't use backquote here, it's too early in the bootstrap.
- (list 'set (list 'make-local-variable (list 'quote var)) val))
-
-(defmacro defvar-local (var val &optional docstring)
- "Define VAR as a buffer-local variable with default value VAL.
-Like `defvar' but additionally marks the variable as being automatically
-buffer-local wherever it is set."
- (declare (debug defvar) (doc-string 3))
- ;; Can't use backquote here, it's too early in the bootstrap.
- (list 'progn (list 'defvar var val docstring)
- (list 'make-variable-buffer-local (list 'quote var))))
-
-(defun apply-partially (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."
- `(closure (t) (&rest args)
- (apply ',fun ,@(mapcar (lambda (arg) `',arg) args) args)))
-
-(defmacro push (newelt place)
- "Add NEWELT to the list stored in the generalized variable PLACE.
-This is morally equivalent to (setf PLACE (cons NEWELT PLACE)),
-except that PLACE is only evaluated once (after NEWELT)."
- (declare (debug (form gv-place)))
- (if (symbolp place)
- ;; Important special case, to avoid triggering GV too early in
- ;; the bootstrap.
- (list 'setq place
- (list 'cons newelt place))
- (require 'macroexp)
- (macroexp-let2 macroexp-copyable-p v newelt
- (gv-letplace (getter setter) place
- (funcall setter `(cons ,v ,getter))))))
-
-(defmacro pop (place)
- "Return the first element of PLACE's value, and remove it from the list.
-PLACE must be a generalized variable whose value is a list.
-If the value is nil, `pop' returns nil but does not actually
-change the list."
- (declare (debug (gv-place)))
- ;; We use `car-safe' here instead of `car' because the behavior is the same
- ;; (if it's not a cons cell, the `cdr' would have signaled an error already),
- ;; but `car-safe' is total, so the byte-compiler can safely remove it if the
- ;; result is not used.
- `(car-safe
- ,(if (symbolp place)
- ;; So we can use `pop' in the bootstrap before `gv' can be used.
- (list 'prog1 place (list 'setq place (list 'cdr place)))
- (gv-letplace (getter setter) place
- `(prog1 ,getter ,(funcall setter `(cdr ,getter)))))))
-
-(defmacro when (cond &rest body)
- "If COND yields non-nil, do BODY, else return nil.
-When COND yields non-nil, eval BODY forms sequentially and return
-value of last one, or nil if there are none.
-
-\(fn COND BODY...)"
- (declare (indent 1) (debug t))
- (list 'if cond (cons 'progn body)))
-
-(defmacro unless (cond &rest body)
- "If COND yields nil, do BODY, else return nil.
-When COND yields nil, eval BODY forms sequentially and return
-value of last one, or nil if there are none.
-
-\(fn COND BODY...)"
- (declare (indent 1) (debug t))
- (cons 'if (cons cond (cons nil body))))
-
-(defmacro dolist (spec &rest body)
- "Loop over a list.
-Evaluate BODY with VAR bound to each car from LIST, in turn.
-Then evaluate RESULT to get return value, default nil.
-
-\(fn (VAR LIST [RESULT]) BODY...)"
- (declare (indent 1) (debug ((symbolp form &optional form) body)))
- ;; It would be cleaner to create an uninterned symbol,
- ;; but that uses a lot more space when many functions in many files
- ;; use dolist.
- ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
- (let ((temp '--dolist-tail--))
- ;; This is not a reliable test, but it does not matter because both
- ;; semantics are acceptable, tho one is slightly faster with dynamic
- ;; scoping and the other is slightly faster (and has cleaner semantics)
- ;; with lexical scoping.
- (if lexical-binding
- `(let ((,temp ,(nth 1 spec)))
- (while ,temp
- (let ((,(car spec) (car ,temp)))
- ,@body
- (setq ,temp (cdr ,temp))))
- ,@(cdr (cdr spec)))
- `(let ((,temp ,(nth 1 spec))
- ,(car spec))
- (while ,temp
- (setq ,(car spec) (car ,temp))
- ,@body
- (setq ,temp (cdr ,temp)))
- ,@(if (cdr (cdr spec))
- `((setq ,(car spec) nil) ,@(cdr (cdr spec))))))))
-
-(defmacro dotimes (spec &rest body)
- "Loop a certain number of times.
-Evaluate BODY with VAR bound to successive integers running from 0,
-inclusive, to COUNT, exclusive. Then evaluate RESULT to get
-the return value (nil if RESULT is omitted).
-
-\(fn (VAR COUNT [RESULT]) BODY...)"
- (declare (indent 1) (debug dolist))
- ;; It would be cleaner to create an uninterned symbol,
- ;; but that uses a lot more space when many functions in many files
- ;; use dotimes.
- ;; FIXME: This cost disappears in byte-compiled lexical-binding files.
- (let ((temp '--dotimes-limit--)
- (start 0)
- (end (nth 1 spec)))
- ;; This is not a reliable test, but it does not matter because both
- ;; semantics are acceptable, tho one is slightly faster with dynamic
- ;; scoping and the other has cleaner semantics.
- (if lexical-binding
- (let ((counter '--dotimes-counter--))
- `(let ((,temp ,end)
- (,counter ,start))
- (while (< ,counter ,temp)
- (let ((,(car spec) ,counter))
- ,@body)
- (setq ,counter (1+ ,counter)))
- ,@(if (cddr spec)
- ;; FIXME: This let often leads to "unused var" warnings.
- `((let ((,(car spec) ,counter)) ,@(cddr spec))))))
- `(let ((,temp ,end)
- (,(car spec) ,start))
- (while (< ,(car spec) ,temp)
- ,@body
- (setq ,(car spec) (1+ ,(car spec))))
- ,@(cdr (cdr spec))))))
-
-(defmacro declare (&rest _specs)
- "Do not evaluate any arguments, and return nil.
-If a `declare' form appears as the first form in the body of a
-`defun' or `defmacro' form, SPECS specifies various additional
-information about the function or macro; these go into effect
-during the evaluation of the `defun' or `defmacro' form.
-
-The possible values of SPECS are specified by
-`defun-declarations-alist' and `macro-declarations-alist'."
- ;; FIXME: edebug spec should pay attention to defun-declarations-alist.
- nil)
-
-(defmacro ignore-errors (&rest body)
- "Execute BODY; if an error occurs, return nil.
-Otherwise, return result of last form in BODY.
-See also `with-demoted-errors' that does something similar
-without silencing all errors."
- (declare (debug t) (indent 0))
- `(condition-case nil (progn ,@body) (error nil)))
-
-;;;; Basic Lisp functions.
-
-(defun ignore (&rest _ignore)
- "Do nothing and return nil.
-This function accepts any number of arguments, but ignores them."
- (interactive)
- nil)
-
-;; Signal a compile-error if the first arg is missing.
-(defun error (&rest args)
- "Signal an error, making error message by passing all args to `format'.
-In Emacs, the convention is that error messages start with a capital
-letter but *do not* end with a period. Please follow this convention
-for the sake of consistency."
- (declare (advertised-calling-convention (string &rest args) "23.1"))
- (signal 'error (list (apply 'format args))))
-
-(defun user-error (format &rest args)
- "Signal a pilot error, making error message by passing all args to `format'.
-In Emacs, the convention is that error messages start with a capital
-letter but *do not* end with a period. Please follow this convention
-for the sake of consistency.
-This is just like `error' except that `user-error's are expected to be the
-result of an incorrect manipulation on the part of the user, rather than the
-result of an actual problem."
- (signal 'user-error (list (apply #'format format args))))
-
-(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 #'nconc
- (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))))
-
-;; We put this here instead of in frame.el so that it's defined even on
-;; systems where frame.el isn't loaded.
-(defun frame-configuration-p (object)
- "Return non-nil if OBJECT seems to be a frame configuration.
-Any list whose car is `frame-configuration' is assumed to be a frame
-configuration."
- (and (consp object)
- (eq (car object) 'frame-configuration)))
-
-;;;; List functions.
-
-(defsubst caar (x)
- "Return the car of the car of X."
- (car (car x)))
-
-(defsubst cadr (x)
- "Return the car of the cdr of X."
- (car (cdr x)))
-
-(defsubst cdar (x)
- "Return the cdr of the car of X."
- (cdr (car x)))
-
-(defsubst cddr (x)
- "Return the cdr of the cdr of X."
- (cdr (cdr x)))
-
-(defun last (list &optional n)
- "Return the last link of LIST. Its car is the last element.
-If LIST is nil, return nil.
-If N is non-nil, return the Nth-to-last link of LIST.
-If N is bigger than the length of LIST, return LIST."
- (if n
- (and (>= n 0)
- (let ((m (safe-length list)))
- (if (< n m) (nthcdr (- m n) list) list)))
- (and list
- (nthcdr (1- (safe-length list)) list))))
-
-(defun butlast (list &optional n)
- "Return a copy of LIST with the last N elements removed.
-If N is omitted or nil, the last element is removed from the
-copy."
- (if (and n (<= n 0)) list
- (nbutlast (copy-sequence list) n)))
-
-(defun nbutlast (list &optional n)
- "Modifies LIST to remove the last N elements.
-If N is omitted or nil, remove the last element."
- (let ((m (length list)))
- (or n (setq n 1))
- (and (< n m)
- (progn
- (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil))
- list))))
-
-(defun delete-dups (list)
- "Destructively remove `equal' duplicates from LIST.
-Store the result in LIST and return it. LIST must be a proper list.
-Of several `equal' occurrences of an element in LIST, the first
-one is kept."
- (let ((tail list))
- (while tail
- (setcdr tail (delete (car tail) (cdr tail)))
- (setq tail (cdr tail))))
- list)
-
-;; See http://lists.gnu.org/archive/html/emacs-devel/2013-05/msg00204.html
-(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."
- (let ((tail list) last)
- (while (consp tail)
- (if (equal (car tail) (cadr tail))
- (setcdr tail (cddr tail))
- (setq last (car tail)
- tail (cdr tail))))
- (if (and circular
- (cdr list)
- (equal last (car list)))
- (nbutlast list)
- list)))
-
-(defun number-sequence (from &optional to inc)
- "Return a sequence of numbers from FROM to TO (both inclusive) as a list.
-INC is the increment used between numbers in the sequence and defaults to 1.
-So, the Nth element of the list is (+ FROM (* N INC)) where N counts from
-zero. TO is only included if there is an N for which TO = FROM + N * INC.
-If TO is nil or numerically equal to FROM, return (FROM).
-If INC is positive and TO is less than FROM, or INC is negative
-and TO is larger than FROM, return nil.
-If INC is zero and TO is neither nil nor numerically equal to
-FROM, signal an error.
-
-This function is primarily designed for integer arguments.
-Nevertheless, FROM, TO and INC can be integer or float. However,
-floating point arithmetic is inexact. For instance, depending on
-the machine, it may quite well happen that
-\(number-sequence 0.4 0.6 0.2) returns the one element list (0.4),
-whereas (number-sequence 0.4 0.8 0.2) returns a list with three
-elements. Thus, if some of the arguments are floats and one wants
-to make sure that TO is included, one may have to explicitly write
-TO as (+ FROM (* N INC)) or use a variable whose value was
-computed with this exact expression. Alternatively, you can,
-of course, also replace TO with a slightly larger value
-\(or a slightly more negative value if INC is negative)."
- (if (or (not to) (= from to))
- (list from)
- (or inc (setq inc 1))
- (when (zerop inc) (error "The increment can not be zero"))
- (let (seq (n 0) (next from))
- (if (> inc 0)
- (while (<= next to)
- (setq seq (cons next seq)
- n (1+ n)
- next (+ from (* n inc))))
- (while (>= next to)
- (setq seq (cons next seq)
- n (1+ n)
- next (+ from (* n inc)))))
- (nreverse seq))))
-
-(defun copy-tree (tree &optional vecp)
- "Make a copy of TREE.
-If TREE is a cons cell, this recursively copies both its car and its cdr.
-Contrast to `copy-sequence', which copies only along the cdrs. With second
-argument VECP, this copies vectors as well as conses."
- (if (consp tree)
- (let (result)
- (while (consp tree)
- (let ((newcar (car tree)))
- (if (or (consp (car tree)) (and vecp (vectorp (car tree))))
- (setq newcar (copy-tree (car tree) vecp)))
- (push newcar result))
- (setq tree (cdr tree)))
- (nconc (nreverse result) tree))
- (if (and vecp (vectorp tree))
- (let ((i (length (setq tree (copy-sequence tree)))))
- (while (>= (setq i (1- i)) 0)
- (aset tree i (copy-tree (aref tree i) vecp)))
- tree)
- tree)))
-
-;;;; Various list-search functions.
-
-(defun assoc-default (key alist &optional test default)
- "Find object KEY in a pseudo-alist ALIST.
-ALIST is a list of conses or objects. Each element
- (or the element's car, if it is a cons) is compared with KEY by
- calling TEST, with two arguments: (i) the element or its car,
- and (ii) KEY.
-If that is non-nil, the element matches; then `assoc-default'
- returns the element's cdr, if it is a cons, or DEFAULT if the
- element is not a cons.
-
-If no element matches, the value is nil.
-If TEST is omitted or nil, `equal' is used."
- (let (found (tail alist) value)
- (while (and tail (not found))
- (let ((elt (car tail)))
- (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key)
- (setq found t value (if (consp elt) (cdr elt) default))))
- (setq tail (cdr tail)))
- value))
-
-(defun assoc-ignore-case (key alist)
- "Like `assoc', but ignores differences in case and text representation.
-KEY must be a string. Upper-case and lower-case letters are treated as equal.
-Unibyte strings are converted to multibyte for comparison."
- (declare (obsolete assoc-string "22.1"))
- (assoc-string key alist t))
-
-(defun assoc-ignore-representation (key alist)
- "Like `assoc', but ignores differences in text representation.
-KEY must be a string.
-Unibyte strings are converted to multibyte for comparison."
- (declare (obsolete assoc-string "22.1"))
- (assoc-string key alist nil))
-
-(defun member-ignore-case (elt list)
- "Like `member', but ignore differences in case and text representation.
-ELT must be a string. Upper-case and lower-case letters are treated as equal.
-Unibyte strings are converted to multibyte for comparison.
-Non-strings in LIST are ignored."
- (while (and list
- (not (and (stringp (car list))
- (eq t (compare-strings elt 0 nil (car list) 0 nil t)))))
- (setq list (cdr list)))
- list)
-
-(defun assq-delete-all (key alist)
- "Delete from ALIST all elements whose car is `eq' to KEY.
-Return the modified alist.
-Elements of ALIST that are not conses are ignored."
- (while (and (consp (car alist))
- (eq (car (car alist)) key))
- (setq alist (cdr alist)))
- (let ((tail alist) tail-cdr)
- (while (setq tail-cdr (cdr tail))
- (if (and (consp (car tail-cdr))
- (eq (car (car tail-cdr)) key))
- (setcdr tail (cdr tail-cdr))
- (setq tail tail-cdr))))
- alist)
-
-(defun rassq-delete-all (value alist)
- "Delete from ALIST all elements whose cdr is `eq' to VALUE.
-Return the modified alist.
-Elements of ALIST that are not conses are ignored."
- (while (and (consp (car alist))
- (eq (cdr (car alist)) value))
- (setq alist (cdr alist)))
- (let ((tail alist) tail-cdr)
- (while (setq tail-cdr (cdr tail))
- (if (and (consp (car tail-cdr))
- (eq (cdr (car tail-cdr)) value))
- (setcdr tail (cdr tail-cdr))
- (setq tail tail-cdr))))
- alist)
-
-(defun remove (elt seq)
- "Return a copy of SEQ with all occurrences of ELT removed.
-SEQ must be a list, vector, or string. The comparison is done with `equal'."
- (if (nlistp seq)
- ;; If SEQ isn't a list, there's no need to copy SEQ because
- ;; `delete' will return a new object.
- (delete elt seq)
- (delete elt (copy-sequence seq))))
-
-(defun remq (elt list)
- "Return LIST with all occurrences of ELT removed.
-The comparison is done with `eq'. Contrary to `delq', this does not use
-side-effects, and the argument LIST is not modified."
- (while (and (eq elt (car list)) (setq list (cdr list))))
- (if (memq elt list)
- (delq elt (copy-sequence list))
- list))
-
-;;;; Keymap support.
-
-(defun kbd (keys)
- "Convert KEYS to the internal Emacs key representation.
-KEYS should be a string constant in the format used for
-saving keyboard macros (see `edmacro-mode')."
- ;; Don't use a defalias, since the `pure' property is only true for
- ;; the calling convention of `kbd'.
- (read-kbd-macro keys))
-(put 'kbd 'pure t)
-
-(defun undefined ()
- "Beep to tell the user this binding is undefined."
- (interactive)
- (ding)
- (message "%s is undefined" (key-description (this-single-command-keys)))
- (setq defining-kbd-macro nil)
- (force-mode-line-update)
- ;; If this is a down-mouse event, don't reset prefix-arg;
- ;; pass it to the command run by the up event.
- (setq prefix-arg
- (when (memq 'down (event-modifiers last-command-event))
- current-prefix-arg)))
-
-;; Prevent the \{...} documentation construct
-;; from mentioning keys that run this command.
-(put 'undefined 'suppress-keymap t)
-
-(defun suppress-keymap (map &optional nodigits)
- "Make MAP override all normally self-inserting keys to be undefined.
-Normally, as an exception, digits and minus-sign are set to make prefix args,
-but optional second arg NODIGITS non-nil treats them like other chars."
- (define-key map [remap self-insert-command] 'undefined)
- (or nodigits
- (let (loop)
- (define-key map "-" 'negative-argument)
- ;; Make plain numbers do numeric args.
- (setq loop ?0)
- (while (<= loop ?9)
- (define-key map (char-to-string loop) 'digit-argument)
- (setq loop (1+ loop))))))
-
-(defun make-composed-keymap (maps &optional parent)
- "Construct a new keymap composed of MAPS and inheriting from PARENT.
-When looking up a key in the returned map, the key is looked in each
-keymap of MAPS in turn until a binding is found.
-If no binding is found in MAPS, the lookup continues in PARENT, if non-nil.
-As always with keymap inheritance, a nil binding in MAPS overrides
-any corresponding binding in PARENT, but it does not override corresponding
-bindings in other keymaps of MAPS.
-MAPS can be a list of keymaps or a single keymap.
-PARENT if non-nil should be a keymap."
- `(keymap
- ,@(if (keymapp maps) (list maps) maps)
- ,@parent))
-
-(defun define-key-after (keymap key definition &optional after)
- "Add binding in KEYMAP for KEY => DEFINITION, right after AFTER's binding.
-This is like `define-key' except that the binding for KEY is placed
-just after the binding for the event AFTER, instead of at the beginning
-of the map. Note that AFTER must be an event type (like KEY), NOT a command
-\(like DEFINITION).
-
-If AFTER is t or omitted, the new binding goes at the end of the keymap.
-AFTER should be a single event type--a symbol or a character, not a sequence.
-
-Bindings are always added before any inherited map.
-
-The order of bindings in a keymap only matters when it is used as
-a menu, so this function is not useful for non-menu keymaps."
- (unless after (setq after t))
- (or (keymapp keymap)
- (signal 'wrong-type-argument (list 'keymapp keymap)))
- (setq key
- (if (<= (length key) 1) (aref key 0)
- (setq keymap (lookup-key keymap
- (apply 'vector
- (butlast (mapcar 'identity key)))))
- (aref key (1- (length key)))))
- (let ((tail keymap) done inserted)
- (while (and (not done) tail)
- ;; Delete any earlier bindings for the same key.
- (if (eq (car-safe (car (cdr tail))) key)
- (setcdr tail (cdr (cdr tail))))
- ;; If we hit an included map, go down that one.
- (if (keymapp (car tail)) (setq tail (car tail)))
- ;; When we reach AFTER's binding, insert the new binding after.
- ;; If we reach an inherited keymap, insert just before that.
- ;; If we reach the end of this keymap, insert at the end.
- (if (or (and (eq (car-safe (car tail)) after)
- (not (eq after t)))
- (eq (car (cdr tail)) 'keymap)
- (null (cdr tail)))
- (progn
- ;; Stop the scan only if we find a parent keymap.
- ;; Keep going past the inserted element
- ;; so we can delete any duplications that come later.
- (if (eq (car (cdr tail)) 'keymap)
- (setq done t))
- ;; Don't insert more than once.
- (or inserted
- (setcdr tail (cons (cons key definition) (cdr tail))))
- (setq inserted t)))
- (setq tail (cdr tail)))))
-
-(defun map-keymap-sorted (function keymap)
- "Implement `map-keymap' with sorting.
-Don't call this function; it is for internal use only."
- (let (list)
- (map-keymap (lambda (a b) (push (cons a b) list))
- keymap)
- (setq list (sort list
- (lambda (a b)
- (setq a (car a) b (car b))
- (if (integerp a)
- (if (integerp b) (< a b)
- t)
- (if (integerp b) t
- ;; string< also accepts symbols.
- (string< a b))))))
- (dolist (p list)
- (funcall function (car p) (cdr p)))))
-
-(defun keymap--menu-item-binding (val)
- "Return the binding part of a menu-item."
- (cond
- ((not (consp val)) val) ;Not a menu-item.
- ((eq 'menu-item (car val))
- (let* ((binding (nth 2 val))
- (plist (nthcdr 3 val))
- (filter (plist-get plist :filter)))
- (if filter (funcall filter binding)
- binding)))
- ((and (consp (cdr val)) (stringp (cadr val)))
- (cddr val))
- ((stringp (car val))
- (cdr val))
- (t val))) ;Not a menu-item either.
-
-(defun keymap--menu-item-with-binding (item binding)
- "Build a menu-item like ITEM but with its binding changed to BINDING."
- (cond
- ((not (consp item)) binding) ;Not a menu-item.
- ((eq 'menu-item (car item))
- (setq item (copy-sequence item))
- (let ((tail (nthcdr 2 item)))
- (setcar tail binding)
- ;; Remove any potential filter.
- (if (plist-get (cdr tail) :filter)
- (setcdr tail (plist-put (cdr tail) :filter nil))))
- item)
- ((and (consp (cdr item)) (stringp (cadr item)))
- (cons (car item) (cons (cadr item) binding)))
- (t (cons (car item) binding))))
-
-(defun keymap--merge-bindings (val1 val2)
- "Merge bindings VAL1 and VAL2."
- (let ((map1 (keymap--menu-item-binding val1))
- (map2 (keymap--menu-item-binding val2)))
- (if (not (and (keymapp map1) (keymapp map2)))
- ;; There's nothing to merge: val1 takes precedence.
- val1
- (let ((map (list 'keymap map1 map2))
- (item (if (keymapp val1) (if (keymapp val2) nil val2) val1)))
- (keymap--menu-item-with-binding item map)))))
-
-(defun keymap-canonicalize (map)
- "Return a simpler equivalent keymap.
-This resolves inheritance and redefinitions. The returned keymap
-should behave identically to a copy of KEYMAP w.r.t `lookup-key'
-and use in active keymaps and menus.
-Subkeymaps may be modified but are not canonicalized."
- ;; FIXME: Problem with the difference between a nil binding
- ;; that hides a binding in an inherited map and a nil binding that's ignored
- ;; to let some further binding visible. Currently a nil binding hides all.
- ;; FIXME: we may want to carefully (re)order elements in case they're
- ;; menu-entries.
- (let ((bindings ())
- (ranges ())
- (prompt (keymap-prompt map)))
- (while (keymapp map)
- (setq map (map-keymap ;; -internal
- (lambda (key item)
- (if (consp key)
- ;; Treat char-ranges specially.
- (push (cons key item) ranges)
- (push (cons key item) bindings)))
- map)))
- ;; Create the new map.
- (setq map (funcall (if ranges 'make-keymap 'make-sparse-keymap) prompt))
- (dolist (binding ranges)
- ;; Treat char-ranges specially. FIXME: need to merge as well.
- (define-key map (vector (car binding)) (cdr binding)))
- ;; Process the bindings starting from the end.
- (dolist (binding (prog1 bindings (setq bindings ())))
- (let* ((key (car binding))
- (oldbind (assq key bindings)))
- (push (if (not oldbind)
- ;; The normal case: no duplicate bindings.
- binding
- ;; This is the second binding for this key.
- (setq bindings (delq oldbind bindings))
- (cons key (keymap--merge-bindings (cdr binding)
- (cdr oldbind))))
- bindings)))
- (nconc map bindings)))
-
-(put 'keyboard-translate-table 'char-table-extra-slots 0)
-
-(defun keyboard-translate (from to)
- "Translate character FROM to TO on the current terminal.
-This function creates a `keyboard-translate-table' if necessary
-and then modifies one entry in it."
- (or (char-table-p keyboard-translate-table)
- (setq keyboard-translate-table
- (make-char-table 'keyboard-translate-table nil)))
- (aset keyboard-translate-table from to))
-
-;;;; Key binding commands.
-
-(defun global-set-key (key command)
- "Give KEY a global binding as COMMAND.
-COMMAND is the command definition to use; usually it is
-a symbol naming an interactively-callable function.
-KEY is a key sequence; noninteractively, it is a string or vector
-of characters or event types, and non-ASCII characters with codes
-above 127 (such as ISO Latin-1) can be included if you use a vector.
-
-Note that if KEY has a local binding in the current buffer,
-that local binding will continue to shadow any global binding
-that you make with this function."
- (interactive "KSet key globally: \nCSet key %s to command: ")
- (or (vectorp key) (stringp key)
- (signal 'wrong-type-argument (list 'arrayp key)))
- (define-key (current-global-map) key command))
-
-(defun local-set-key (key command)
- "Give KEY a local binding as COMMAND.
-COMMAND is the command definition to use; usually it is
-a symbol naming an interactively-callable function.
-KEY is a key sequence; noninteractively, it is a string or vector
-of characters or event types, and non-ASCII characters with codes
-above 127 (such as ISO Latin-1) can be included if you use a vector.
-
-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 "KSet key locally: \nCSet key %s locally to command: ")
- (let ((map (current-local-map)))
- (or map
- (use-local-map (setq map (make-sparse-keymap))))
- (or (vectorp key) (stringp key)
- (signal 'wrong-type-argument (list 'arrayp key)))
- (define-key map key command)))
-
-(defun global-unset-key (key)
- "Remove global binding of KEY.
-KEY is a string or vector representing a sequence of keystrokes."
- (interactive "kUnset key globally: ")
- (global-set-key key nil))
-
-(defun local-unset-key (key)
- "Remove local binding of KEY.
-KEY is a string or vector representing a sequence of keystrokes."
- (interactive "kUnset key locally: ")
- (if (current-local-map)
- (local-set-key key nil))
- nil)
-
-;;;; substitute-key-definition and its subroutines.
-
-(defvar key-substitution-in-progress nil
- "Used internally by `substitute-key-definition'.")
-
-(defun substitute-key-definition (olddef newdef keymap &optional oldmap prefix)
- "Replace OLDDEF with NEWDEF for any keys in KEYMAP now defined as OLDDEF.
-In other words, OLDDEF is replaced with NEWDEF where ever it appears.
-Alternatively, if optional fourth argument OLDMAP is specified, we redefine
-in KEYMAP as NEWDEF those keys which are defined as OLDDEF in OLDMAP.
-
-If you don't specify OLDMAP, you can usually get the same results
-in a cleaner way with command remapping, like this:
- (define-key KEYMAP [remap OLDDEF] NEWDEF)
-\n(fn OLDDEF NEWDEF KEYMAP &optional OLDMAP)"
- ;; Don't document PREFIX in the doc string because we don't want to
- ;; advertise it. It's meant for recursive calls only. Here's its
- ;; meaning
-
- ;; If optional argument PREFIX is specified, it should be a key
- ;; prefix, a string. Redefined bindings will then be bound to the
- ;; original key, with PREFIX added at the front.
- (or prefix (setq prefix ""))
- (let* ((scan (or oldmap keymap))
- (prefix1 (vconcat prefix [nil]))
- (key-substitution-in-progress
- (cons scan key-substitution-in-progress)))
- ;; Scan OLDMAP, finding each char or event-symbol that
- ;; has any definition, and act on it with hack-key.
- (map-keymap
- (lambda (char defn)
- (aset prefix1 (length prefix) char)
- (substitute-key-definition-key defn olddef newdef prefix1 keymap))
- scan)))
-
-(defun substitute-key-definition-key (defn olddef newdef prefix keymap)
- (let (inner-def skipped menu-item)
- ;; Find the actual command name within the binding.
- (if (eq (car-safe defn) 'menu-item)
- (setq menu-item defn defn (nth 2 defn))
- ;; Skip past menu-prompt.
- (while (stringp (car-safe defn))
- (push (pop defn) skipped))
- ;; Skip past cached key-equivalence data for menu items.
- (if (consp (car-safe defn))
- (setq defn (cdr defn))))
- (if (or (eq defn olddef)
- ;; Compare with equal if definition is a key sequence.
- ;; That is useful for operating on function-key-map.
- (and (or (stringp defn) (vectorp defn))
- (equal defn olddef)))
- (define-key keymap prefix
- (if menu-item
- (let ((copy (copy-sequence menu-item)))
- (setcar (nthcdr 2 copy) newdef)
- copy)
- (nconc (nreverse skipped) newdef)))
- ;; Look past a symbol that names a keymap.
- (setq inner-def
- (or (indirect-function defn t) defn))
- ;; For nested keymaps, we use `inner-def' rather than `defn' so as to
- ;; avoid autoloading a keymap. This is mostly done to preserve the
- ;; original non-autoloading behavior of pre-map-keymap times.
- (if (and (keymapp inner-def)
- ;; Avoid recursively scanning
- ;; where KEYMAP does not have a submap.
- (let ((elt (lookup-key keymap prefix)))
- (or (null elt) (natnump elt) (keymapp elt)))
- ;; Avoid recursively rescanning keymap being scanned.
- (not (memq inner-def key-substitution-in-progress)))
- ;; If this one isn't being scanned already, scan it now.
- (substitute-key-definition olddef newdef keymap inner-def prefix)))))
-
-
-;;;; The global keymap tree.
-
-;; global-map, esc-map, and ctl-x-map have their values set up in
-;; keymap.c; we just give them docstrings here.
-
-(defvar global-map nil
- "Default global keymap mapping Emacs keyboard input into commands.
-The value is a keymap which is usually (but not necessarily) Emacs's
-global map.")
-
-(defvar esc-map nil
- "Default keymap for ESC (meta) commands.
-The normal global definition of the character ESC indirects to this keymap.")
-
-(defvar ctl-x-map nil
- "Default keymap for C-x commands.
-The normal global definition of the character C-x indirects to this keymap.")
-
-(defvar ctl-x-4-map (make-sparse-keymap)
- "Keymap for subcommands of C-x 4.")
-(defalias 'ctl-x-4-prefix ctl-x-4-map)
-(define-key ctl-x-map "4" 'ctl-x-4-prefix)
-
-(defvar ctl-x-5-map (make-sparse-keymap)
- "Keymap for frame commands.")
-(defalias 'ctl-x-5-prefix ctl-x-5-map)
-(define-key ctl-x-map "5" 'ctl-x-5-prefix)
-
-
-;;;; Event manipulation functions.
-
-(defconst listify-key-sequence-1 (logior 128 ?\M-\C-@))
-
-(defun listify-key-sequence (key)
- "Convert a key sequence to a list of events."
- (if (vectorp key)
- (append key nil)
- (mapcar (function (lambda (c)
- (if (> c 127)
- (logxor c listify-key-sequence-1)
- c)))
- key)))
-
-(defun eventp (obj)
- "True if the argument is an event object."
- (when obj
- (or (integerp obj)
- (and (symbolp obj) obj (not (keywordp obj)))
- (and (consp obj) (symbolp (car obj))))))
-
-(defun event-modifiers (event)
- "Return a list of symbols representing the modifier keys in event EVENT.
-The elements of the list may include `meta', `control',
-`shift', `hyper', `super', `alt', `click', `double', `triple', `drag',
-and `down'.
-EVENT may be an event or an event type. If EVENT is a symbol
-that has never been used in an event that has been read as input
-in the current Emacs session, then this function may fail to include
-the `click' modifier."
- (let ((type event))
- (if (listp type)
- (setq type (car type)))
- (if (symbolp type)
- ;; Don't read event-symbol-elements directly since we're not
- ;; sure the symbol has already been parsed.
- (cdr (internal-event-symbol-parse-modifiers type))
- (let ((list nil)
- (char (logand type (lognot (logior ?\M-\^@ ?\C-\^@ ?\S-\^@
- ?\H-\^@ ?\s-\^@ ?\A-\^@)))))
- (if (not (zerop (logand type ?\M-\^@)))
- (push 'meta list))
- (if (or (not (zerop (logand type ?\C-\^@)))
- (< char 32))
- (push 'control list))
- (if (or (not (zerop (logand type ?\S-\^@)))
- (/= char (downcase char)))
- (push 'shift list))
- (or (zerop (logand type ?\H-\^@))
- (push 'hyper list))
- (or (zerop (logand type ?\s-\^@))
- (push 'super list))
- (or (zerop (logand type ?\A-\^@))
- (push 'alt list))
- list))))
-
-(defun event-basic-type (event)
- "Return the basic type of the given event (all modifiers removed).
-The value is a printing character (not upper case) or a symbol.
-EVENT may be an event or an event type. If EVENT is a symbol
-that has never been used in an event that has been read as input
-in the current Emacs session, then this function may return nil."
- (if (consp event)
- (setq event (car event)))
- (if (symbolp event)
- (car (get event 'event-symbol-elements))
- (let* ((base (logand event (1- ?\A-\^@)))
- (uncontrolled (if (< base 32) (logior base 64) base)))
- ;; There are some numbers that are invalid characters and
- ;; cause `downcase' to get an error.
- (condition-case ()
- (downcase uncontrolled)
- (error uncontrolled)))))
-
-(defsubst mouse-movement-p (object)
- "Return non-nil if OBJECT is a mouse movement event."
- (eq (car-safe object) 'mouse-movement))
-
-(defun mouse-event-p (object)
- "Return non-nil if OBJECT is a mouse click event."
- ;; is this really correct? maybe remove mouse-movement?
- (memq (event-basic-type object) '(mouse-1 mouse-2 mouse-3 mouse-movement)))
-
-(defun event-start (event)
- "Return the starting position of EVENT.
-EVENT should be a mouse click, drag, or key press event. If
-EVENT is nil, the value of `posn-at-point' is used instead.
-
-The following accessor functions are used to access the elements
-of the position:
-
-`posn-window': The window the event is in.
-`posn-area': A symbol identifying the area the event occurred in,
-or nil if the event occurred in the text area.
-`posn-point': The buffer position of the event.
-`posn-x-y': The pixel-based coordinates of the event.
-`posn-col-row': The estimated column and row corresponding to the
-position of the event.
-`posn-actual-col-row': The actual column and row corresponding to the
-position of the event.
-`posn-string': The string object of the event, which is either
-nil or (STRING . POSITION)'.
-`posn-image': The image object of the event, if any.
-`posn-object': The image or string object of the event, if any.
-`posn-timestamp': The time the event occurred, in milliseconds.
-
-For more information, see Info node `(elisp)Click Events'."
- (if (consp event) (nth 1 event)
- (or (posn-at-point)
- (list (selected-window) (point) '(0 . 0) 0))))
-
-(defun event-end (event)
- "Return the ending position of EVENT.
-EVENT should be a click, drag, or key press event.
-
-See `event-start' for a description of the value returned."
- (if (consp event) (nth (if (consp (nth 2 event)) 2 1) event)
- (or (posn-at-point)
- (list (selected-window) (point) '(0 . 0) 0))))
-
-(defsubst event-click-count (event)
- "Return the multi-click count of EVENT, a click or drag event.
-The return value is a positive integer."
- (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1))
-
-;;;; Extracting fields of the positions in an event.
-
-(defun posnp (obj)
- "Return non-nil if OBJ appears to be a valid `posn' object specifying a
window.
-If OBJ is a valid `posn' object, but specifies a frame rather
-than a window, return nil."
- ;; FIXME: Correct the behavior of this function so that all valid
- ;; `posn' objects are recognized, after updating other code that
- ;; depends on its present behavior.
- (and (windowp (car-safe obj))
- (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS.
- (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET.
- (integerp (car-safe (cdr obj))))) ;TIMESTAMP.
-
-(defsubst posn-window (position)
- "Return the window in POSITION.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (nth 0 position))
-
-(defsubst posn-area (position)
- "Return the window area recorded in POSITION, or nil for the text area.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (let ((area (if (consp (nth 1 position))
- (car (nth 1 position))
- (nth 1 position))))
- (and (symbolp area) area)))
-
-(defun posn-point (position)
- "Return the buffer location in POSITION.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions.
-Returns nil if POSITION does not correspond to any buffer location (e.g.
-a click on a scroll bar)."
- (or (nth 5 position)
- (let ((pt (nth 1 position)))
- (or (car-safe pt)
- ;; Apparently this can also be `vertical-scroll-bar' (bug#13979).
- (if (integerp pt) pt)))))
-
-(defun posn-set-point (position)
- "Move point to POSITION.
-Select the corresponding window as well."
- (if (not (windowp (posn-window position)))
- (error "Position not in text area of window"))
- (select-window (posn-window position))
- (if (numberp (posn-point position))
- (goto-char (posn-point position))))
-
-(defsubst posn-x-y (position)
- "Return the x and y coordinates in POSITION.
-The return value has the form (X . Y), where X and Y are given in
-pixels. POSITION should be a list of the form returned by
-`event-start' and `event-end'."
- (nth 2 position))
-
-(declare-function scroll-bar-scale "scroll-bar" (num-denom whole))
-
-(defun posn-col-row (position)
- "Return the nominal column and row in POSITION, measured in characters.
-The column and row values are approximations calculated from the x
-and y coordinates in POSITION and the frame's default character width
-and default line height, including spacing.
-For a scroll-bar event, the result column is 0, and the row
-corresponds to the vertical position of the click in the scroll bar.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (let* ((pair (posn-x-y position))
- (frame-or-window (posn-window position))
- (frame (if (framep frame-or-window)
- frame-or-window
- (window-frame frame-or-window)))
- (window (when (windowp frame-or-window) frame-or-window))
- (area (posn-area position)))
- (cond
- ((null frame-or-window)
- '(0 . 0))
- ((eq area 'vertical-scroll-bar)
- (cons 0 (scroll-bar-scale pair (1- (window-height window)))))
- ((eq area 'horizontal-scroll-bar)
- (cons (scroll-bar-scale pair (window-width window)) 0))
- (t
- ;; FIXME: This should take line-spacing properties on
- ;; newlines into account.
- (let* ((spacing (when (display-graphic-p frame)
- (or (with-current-buffer
- (window-buffer (frame-selected-window frame))
- line-spacing)
- (frame-parameter frame 'line-spacing)))))
- (cond ((floatp spacing)
- (setq spacing (truncate (* spacing
- (frame-char-height frame)))))
- ((null spacing)
- (setq spacing 0)))
- (cons (/ (car pair) (frame-char-width frame))
- (/ (cdr pair) (+ (frame-char-height frame) spacing))))))))
-
-(defun posn-actual-col-row (position)
- "Return the window row number in POSITION and character number in that row.
-
-Return nil if POSITION does not contain the actual position; in that case
-\`posn-col-row' can be used to get approximate values.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions.
-
-This function does not account for the width on display, like the
-number of visual columns taken by a TAB or image. If you need
-the coordinates of POSITION in character units, you should use
-\`posn-col-row', not this function."
- (nth 6 position))
-
-(defsubst posn-timestamp (position)
- "Return the timestamp of POSITION.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (nth 3 position))
-
-(defun posn-string (position)
- "Return the string object of POSITION.
-Value is a cons (STRING . STRING-POS), or nil if not a string.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (let ((x (nth 4 position)))
- ;; Apparently this can also be `handle' or `below-handle' (bug#13979).
- (when (consp x) x)))
-
-(defsubst posn-image (position)
- "Return the image object of POSITION.
-Value is a list (image ...), or nil if not an image.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (nth 7 position))
-
-(defsubst posn-object (position)
- "Return the object (image or string) of POSITION.
-Value is a list (image ...) for an image object, a cons cell
-\(STRING . STRING-POS) for a string object, and nil for a buffer position.
-POSITION should be a list of the form returned by the `event-start'
-and `event-end' functions."
- (or (posn-image position) (posn-string position)))
-
-(defsubst posn-object-x-y (position)
- "Return the x and y coordinates relative to the object of POSITION.
-The return value has the form (DX . DY), where DX and DY are
-given in pixels. POSITION should be a list of the form returned
-by `event-start' and `event-end'."
- (nth 8 position))
-
-(defsubst posn-object-width-height (position)
- "Return the pixel width and height of the object of POSITION.
-The return value has the form (WIDTH . HEIGHT). POSITION should
-be a list of the form returned by `event-start' and `event-end'."
- (nth 9 position))
-
-
-;;;; Obsolescent names for functions.
-
-(define-obsolete-function-alias 'window-dot 'window-point "22.1")
-(define-obsolete-function-alias 'set-window-dot 'set-window-point "22.1")
-(define-obsolete-function-alias 'read-input 'read-string "22.1")
-(define-obsolete-function-alias 'show-buffer 'set-window-buffer "22.1")
-(define-obsolete-function-alias 'eval-current-buffer 'eval-buffer "22.1")
-(define-obsolete-function-alias 'string-to-int 'string-to-number "22.1")
-
-(make-obsolete 'forward-point "use (+ (point) N) instead." "23.1")
-(make-obsolete 'buffer-has-markers-at nil "24.3")
-
-(defun insert-string (&rest args)
- "Mocklisp-compatibility insert function.
-Like the function `insert' except that any argument that is a number
-is converted into a string by expressing it in decimal."
- (declare (obsolete insert "22.1"))
- (dolist (el args)
- (insert (if (integerp el) (number-to-string el) el))))
-
-(defun makehash (&optional test)
- (declare (obsolete make-hash-table "22.1"))
- (make-hash-table :test (or test 'eql)))
-
-(defun log10 (x)
- "Return (log X 10), the log base 10 of X."
- (declare (obsolete log "24.4"))
- (log x 10))
-
-;; These are used by VM and some old programs
-(defalias 'focus-frame 'ignore "")
-(make-obsolete 'focus-frame "it does nothing." "22.1")
-(defalias 'unfocus-frame 'ignore "")
-(make-obsolete 'unfocus-frame "it does nothing." "22.1")
-(make-obsolete 'make-variable-frame-local
- "explicitly check for a frame-parameter instead." "22.2")
-(set-advertised-calling-convention
- 'all-completions '(string collection &optional predicate) "23.1")
-(set-advertised-calling-convention 'unintern '(name obarray) "23.3")
-(set-advertised-calling-convention 'redirect-frame-focus '(frame focus-frame)
"24.3")
-(set-advertised-calling-convention 'decode-char '(ch charset) "21.4")
-(set-advertised-calling-convention 'encode-char '(ch charset) "21.4")
-
-;;;; Obsolescence declarations for variables, and aliases.
-
-;; Special "default-FOO" variables which contain the default value of
-;; the "FOO" variable are nasty. Their implementation is brittle, and
-;; slows down several unrelated variable operations; furthermore, they
-;; can lead to really odd behavior if you decide to make them
-;; buffer-local.
-
-;; Not used at all in Emacs, last time I checked:
-(make-obsolete-variable 'default-mode-line-format 'mode-line-format "23.2")
-(make-obsolete-variable 'default-header-line-format 'header-line-format "23.2")
-(make-obsolete-variable 'default-line-spacing 'line-spacing "23.2")
-(make-obsolete-variable 'default-abbrev-mode 'abbrev-mode "23.2")
-(make-obsolete-variable 'default-ctl-arrow 'ctl-arrow "23.2")
-(make-obsolete-variable 'default-truncate-lines 'truncate-lines "23.2")
-(make-obsolete-variable 'default-left-margin 'left-margin "23.2")
-(make-obsolete-variable 'default-tab-width 'tab-width "23.2")
-(make-obsolete-variable 'default-case-fold-search 'case-fold-search "23.2")
-(make-obsolete-variable 'default-left-margin-width 'left-margin-width "23.2")
-(make-obsolete-variable 'default-right-margin-width 'right-margin-width "23.2")
-(make-obsolete-variable 'default-left-fringe-width 'left-fringe-width "23.2")
-(make-obsolete-variable 'default-right-fringe-width 'right-fringe-width "23.2")
-(make-obsolete-variable 'default-fringes-outside-margins
'fringes-outside-margins "23.2")
-(make-obsolete-variable 'default-scroll-bar-width 'scroll-bar-width "23.2")
-(make-obsolete-variable 'default-vertical-scroll-bar 'vertical-scroll-bar
"23.2")
-(make-obsolete-variable 'default-indicate-empty-lines 'indicate-empty-lines
"23.2")
-(make-obsolete-variable 'default-indicate-buffer-boundaries
'indicate-buffer-boundaries "23.2")
-(make-obsolete-variable 'default-fringe-indicator-alist
'fringe-indicator-alist "23.2")
-(make-obsolete-variable 'default-fringe-cursor-alist 'fringe-cursor-alist
"23.2")
-(make-obsolete-variable 'default-scroll-up-aggressively
'scroll-up-aggressively "23.2")
-(make-obsolete-variable 'default-scroll-down-aggressively
'scroll-down-aggressively "23.2")
-(make-obsolete-variable 'default-fill-column 'fill-column "23.2")
-(make-obsolete-variable 'default-cursor-type 'cursor-type "23.2")
-(make-obsolete-variable 'default-cursor-in-non-selected-windows
'cursor-in-non-selected-windows "23.2")
-(make-obsolete-variable 'default-buffer-file-coding-system
'buffer-file-coding-system "23.2")
-(make-obsolete-variable 'default-major-mode 'major-mode "23.2")
-(make-obsolete-variable 'default-enable-multibyte-characters
- "use enable-multibyte-characters or set-buffer-multibyte instead" "23.2")
-
-(make-obsolete-variable 'define-key-rebound-commands nil "23.2")
-(make-obsolete-variable 'redisplay-end-trigger-functions 'jit-lock-register
"23.1")
-(make-obsolete-variable 'deferred-action-list 'post-command-hook "24.1")
-(make-obsolete-variable 'deferred-action-function 'post-command-hook "24.1")
-(make-obsolete-variable 'redisplay-dont-pause nil "24.5")
-(make-obsolete 'window-redisplay-end-trigger nil "23.1")
-(make-obsolete 'set-window-redisplay-end-trigger nil "23.1")
-
-(make-obsolete 'process-filter-multibyte-p nil "23.1")
-(make-obsolete 'set-process-filter-multibyte nil "23.1")
-
-;; Lisp manual only updated in 22.1.
-(define-obsolete-variable-alias 'executing-macro 'executing-kbd-macro
- "before 19.34")
-
-(define-obsolete-variable-alias 'x-lost-selection-hooks
- 'x-lost-selection-functions "22.1")
-(define-obsolete-variable-alias 'x-sent-selection-hooks
- 'x-sent-selection-functions "22.1")
-
-;; This was introduced in 21.4 for pre-unicode unification. That
-;; usage was rendered obsolete in 23.1 which uses Unicode internally.
-;; Other uses are possible, so this variable is not _really_ obsolete,
-;; but Stefan insists to mark it so.
-(make-obsolete-variable 'translation-table-for-input nil "23.1")
-
-(defvaralias 'messages-buffer-max-lines 'message-log-max)
-
-;;;; Alternate names for functions - these are not being phased out.
-
-(defalias 'send-string 'process-send-string)
-(defalias 'send-region 'process-send-region)
-(defalias 'string= 'string-equal)
-(defalias 'string< 'string-lessp)
-(defalias 'move-marker 'set-marker)
-(defalias 'rplaca 'setcar)
-(defalias 'rplacd 'setcdr)
-(defalias 'beep 'ding) ;preserve lingual purity
-(defalias 'indent-to-column 'indent-to)
-(defalias 'backward-delete-char 'delete-backward-char)
-(defalias 'search-forward-regexp (symbol-function 're-search-forward))
-(defalias 'search-backward-regexp (symbol-function 're-search-backward))
-(defalias 'int-to-string 'number-to-string)
-(defalias 'store-match-data 'set-match-data)
-(defalias 'chmod 'set-file-modes)
-(defalias 'mkdir 'make-directory)
-;; These are the XEmacs names:
-(defalias 'point-at-eol 'line-end-position)
-(defalias 'point-at-bol 'line-beginning-position)
-
-(defalias 'user-original-login-name 'user-login-name)
-
-
-;;;; Hook manipulation functions.
-
-(defun add-hook (hook function &optional append local)
- "Add to the value of HOOK the function FUNCTION.
-FUNCTION is not added if already present.
-FUNCTION is added (if necessary) at the beginning of the hook list
-unless the optional argument APPEND is non-nil, in which case
-FUNCTION is added at the end.
-
-The optional fourth argument, LOCAL, if non-nil, says to modify
-the hook's buffer-local value rather than its global value.
-This makes the hook buffer-local, and it makes t a member of the
-buffer-local value. That acts as a flag to run the hook
-functions of the global value as well as in the local value.
-
-HOOK should be a symbol, and FUNCTION may be any valid function. If
-HOOK is void, it is first set to nil. If HOOK's value is a single
-function, it is changed to a list of functions."
- (or (boundp hook) (set hook nil))
- (or (default-boundp hook) (set-default hook nil))
- (if local (unless (local-variable-if-set-p hook)
- (set (make-local-variable hook) (list t)))
- ;; Detect the case where make-local-variable was used on a hook
- ;; and do what we used to do.
- (unless (and (consp (symbol-value hook)) (memq t (symbol-value hook)))
- (setq local t)))
- (let ((hook-value (if local (symbol-value hook) (default-value hook))))
- ;; If the hook value is a single function, turn it into a list.
- (when (or (not (listp hook-value)) (functionp hook-value))
- (setq hook-value (list hook-value)))
- ;; Do the actual addition if necessary
- (unless (member function hook-value)
- (when (stringp function)
- (setq function (purecopy function)))
- (setq hook-value
- (if append
- (append hook-value (list function))
- (cons function hook-value))))
- ;; Set the actual variable
- (if local
- (progn
- ;; If HOOK isn't a permanent local,
- ;; but FUNCTION wants to survive a change of modes,
- ;; mark HOOK as partially permanent.
- (and (symbolp function)
- (get function 'permanent-local-hook)
- (not (get hook 'permanent-local))
- (put hook 'permanent-local 'permanent-local-hook))
- (set hook hook-value))
- (set-default hook hook-value))))
-
-(defun remove-hook (hook function &optional local)
- "Remove from the value of HOOK the function FUNCTION.
-HOOK should be a symbol, and FUNCTION may be any valid function. If
-FUNCTION isn't the value of HOOK, or, if FUNCTION doesn't appear in the
-list of hooks to run in HOOK, then nothing is done. See `add-hook'.
-
-The optional third argument, LOCAL, if non-nil, says to modify
-the hook's buffer-local value rather than its default value."
- (or (boundp hook) (set hook nil))
- (or (default-boundp hook) (set-default hook nil))
- ;; Do nothing if LOCAL is t but this hook has no local binding.
- (unless (and local (not (local-variable-p hook)))
- ;; Detect the case where make-local-variable was used on a hook
- ;; and do what we used to do.
- (when (and (local-variable-p hook)
- (not (and (consp (symbol-value hook))
- (memq t (symbol-value hook)))))
- (setq local t))
- (let ((hook-value (if local (symbol-value hook) (default-value hook))))
- ;; Remove the function, for both the list and the non-list cases.
- (if (or (not (listp hook-value)) (eq (car hook-value) 'lambda))
- (if (equal hook-value function) (setq hook-value nil))
- (setq hook-value (delete function (copy-sequence hook-value))))
- ;; If the function is on the global hook, we need to shadow it locally
- ;;(when (and local (member function (default-value hook))
- ;; (not (member (cons 'not function) hook-value)))
- ;; (push (cons 'not function) hook-value))
- ;; Set the actual variable
- (if (not local)
- (set-default hook hook-value)
- (if (equal hook-value '(t))
- (kill-local-variable hook)
- (set hook hook-value))))))
-
-(defmacro letrec (binders &rest body)
- "Bind variables according to BINDERS then eval BODY.
-The value of the last form in BODY is returned.
-Each element of BINDERS is a list (SYMBOL VALUEFORM) which binds
-SYMBOL to the value of VALUEFORM.
-All symbols are bound before the VALUEFORMs are evalled."
- ;; Only useful in lexical-binding mode.
- ;; As a special-form, we could implement it more efficiently (and cleanly,
- ;; making the vars actually unbound during evaluation of the binders).
- (declare (debug let) (indent 1))
- `(let ,(mapcar #'car binders)
- ,@(mapcar (lambda (binder) `(setq ,@binder)) binders)
- ,@body))
-
-(defmacro with-wrapper-hook (hook args &rest body)
- "Run BODY, using wrapper functions from HOOK with additional ARGS.
-HOOK is an abnormal hook. Each hook function in HOOK \"wraps\"
-around the preceding ones, like a set of nested `around' advices.
-
-Each hook function should accept an argument list consisting of a
-function FUN, followed by the additional arguments in ARGS.
-
-The first hook function in HOOK is passed a FUN that, if it is called
-with arguments ARGS, performs BODY (i.e., the default operation).
-The FUN passed to each successive hook function is defined based
-on the preceding hook functions; if called with arguments ARGS,
-it does what the `with-wrapper-hook' call would do if the
-preceding hook functions were the only ones present in HOOK.
-
-Each hook function may call its FUN argument as many times as it wishes,
-including never. In that case, such a hook function acts to replace
-the default definition altogether, and any preceding hook functions.
-Of course, a subsequent hook function may do the same thing.
-
-Each hook function definition is used to construct the FUN passed
-to the next hook function, if any. The last (or \"outermost\")
-FUN is then called once."
- (declare (indent 2) (debug (form sexp body))
- (obsolete "use a <foo>-function variable modified by
`add-function'."
- "24.4"))
- ;; We need those two gensyms because CL's lexical scoping is not available
- ;; for function arguments :-(
- (let ((funs (make-symbol "funs"))
- (global (make-symbol "global"))
- (argssym (make-symbol "args"))
- (runrestofhook (make-symbol "runrestofhook")))
- ;; Since the hook is a wrapper, the loop has to be done via
- ;; recursion: a given hook function will call its parameter in order to
- ;; continue looping.
- `(letrec ((,runrestofhook
- (lambda (,funs ,global ,argssym)
- ;; `funs' holds the functions left on the hook and `global'
- ;; holds the functions left on the global part of the hook
- ;; (in case the hook is local).
- (if (consp ,funs)
- (if (eq t (car ,funs))
- (funcall ,runrestofhook
- (append ,global (cdr ,funs)) nil ,argssym)
- (apply (car ,funs)
- (apply-partially
- (lambda (,funs ,global &rest ,argssym)
- (funcall ,runrestofhook ,funs ,global
,argssym))
- (cdr ,funs) ,global)
- ,argssym))
- ;; Once there are no more functions on the hook, run
- ;; the original body.
- (apply (lambda ,args ,@body) ,argssym)))))
- (funcall ,runrestofhook ,hook
- ;; The global part of the hook, if any.
- ,(if (symbolp hook)
- `(if (local-variable-p ',hook)
- (default-value ',hook)))
- (list ,@args)))))
-
-(defun add-to-list (list-var element &optional append compare-fn)
- "Add ELEMENT to the value of LIST-VAR if it isn't there yet.
-The test for presence of ELEMENT is done with `equal', or with
-COMPARE-FN if that's non-nil.
-If ELEMENT is added, it is added at the beginning of the list,
-unless the optional argument APPEND is non-nil, in which case
-ELEMENT is added at the end.
-
-The return value is the new value of LIST-VAR.
-
-This is handy to add some elements to configuration variables,
-but please do not abuse it in Elisp code, where you are usually
-better off using `push' or `cl-pushnew'.
-
-If you want to use `add-to-list' on a variable that is not
-defined until a certain package is loaded, you should put the
-call to `add-to-list' into a hook function that will be run only
-after loading the package. `eval-after-load' provides one way to
-do this. In some cases other hooks, such as major mode hooks,
-can do the job."
- (declare
- (compiler-macro
- (lambda (exp)
- ;; FIXME: Something like this could be used for `set' as well.
- (if (or (not (eq 'quote (car-safe list-var)))
- (special-variable-p (cadr list-var))
- (not (macroexp-const-p append)))
- exp
- (let* ((sym (cadr list-var))
- (append (eval append))
- (msg (format "`add-to-list' can't use lexical var `%s'; use
`push' or `cl-pushnew'"
- sym))
- ;; Big ugly hack so we only output a warning during
- ;; byte-compilation, and so we can use
- ;; byte-compile-not-lexical-var-p to silence the warning
- ;; when a defvar has been seen but not yet executed.
- (warnfun (lambda ()
- ;; FIXME: We should also emit a warning for let-bound
- ;; variables with dynamic binding.
- (when (assq sym byte-compile--lexical-environment)
- (byte-compile-log-warning msg t :error))))
- (code
- (macroexp-let2 macroexp-copyable-p x element
- `(if ,(if compare-fn
- (progn
- (require 'cl-lib)
- `(cl-member ,x ,sym :test ,compare-fn))
- ;; For bootstrapping reasons, don't rely on
- ;; cl--compiler-macro-member for the base case.
- `(member ,x ,sym))
- ,sym
- ,(if append
- `(setq ,sym (append ,sym (list ,x)))
- `(push ,x ,sym))))))
- (if (not (macroexp--compiling-p))
- code
- `(progn
- (macroexp--funcall-if-compiled ',warnfun)
- ,code)))))))
- (if (cond
- ((null compare-fn)
- (member element (symbol-value list-var)))
- ((eq compare-fn 'eq)
- (memq element (symbol-value list-var)))
- ((eq compare-fn 'eql)
- (memql element (symbol-value list-var)))
- (t
- (let ((lst (symbol-value list-var)))
- (while (and lst
- (not (funcall compare-fn element (car lst))))
- (setq lst (cdr lst)))
- lst)))
- (symbol-value list-var)
- (set list-var
- (if append
- (append (symbol-value list-var) (list element))
- (cons element (symbol-value list-var))))))
-
-
-(defun add-to-ordered-list (list-var element &optional order)
- "Add ELEMENT to the value of LIST-VAR if it isn't there yet.
-The test for presence of ELEMENT is done with `eq'.
-
-The resulting list is reordered so that the elements are in the
-order given by each element's numeric list order. Elements
-without a numeric list order are placed at the end of the list.
-
-If the third optional argument ORDER is a number (integer or
-float), set the element's list order to the given value. If
-ORDER is nil or omitted, do not change the numeric order of
-ELEMENT. If ORDER has any other value, remove the numeric order
-of ELEMENT if it has one.
-
-The list order for each element is stored in LIST-VAR's
-`list-order' property.
-
-The return value is the new value of LIST-VAR."
- (let ((ordering (get list-var 'list-order)))
- (unless ordering
- (put list-var 'list-order
- (setq ordering (make-hash-table :weakness 'key :test 'eq))))
- (when order
- (puthash element (and (numberp order) order) ordering))
- (unless (memq element (symbol-value list-var))
- (set list-var (cons element (symbol-value list-var))))
- (set list-var (sort (symbol-value list-var)
- (lambda (a b)
- (let ((oa (gethash a ordering))
- (ob (gethash b ordering)))
- (if (and oa ob)
- (< oa ob)
- oa)))))))
-
-(defun add-to-history (history-var newelt &optional maxelt keep-all)
- "Add NEWELT to the history list stored in the variable HISTORY-VAR.
-Return the new history list.
-If MAXELT is non-nil, it specifies the maximum length of the history.
-Otherwise, the maximum history length is the value of the `history-length'
-property on symbol HISTORY-VAR, if set, or the value of the `history-length'
-variable.
-Remove duplicates of NEWELT if `history-delete-duplicates' is non-nil.
-If optional fourth arg KEEP-ALL is non-nil, add NEWELT to history even
-if it is empty or a duplicate."
- (unless maxelt
- (setq maxelt (or (get history-var 'history-length)
- history-length)))
- (let ((history (symbol-value history-var))
- tail)
- (when (and (listp history)
- (or keep-all
- (not (stringp newelt))
- (> (length newelt) 0))
- (or keep-all
- (not (equal (car history) newelt))))
- (if history-delete-duplicates
- (setq history (delete newelt history)))
- (setq history (cons newelt history))
- (when (integerp maxelt)
- (if (= 0 maxelt)
- (setq history nil)
- (setq tail (nthcdr (1- maxelt) history))
- (when (consp tail)
- (setcdr tail nil)))))
- (set history-var history)))
-
-
-;;;; Mode hooks.
-
-(defvar delay-mode-hooks nil
- "If non-nil, `run-mode-hooks' should delay running the hooks.")
-(defvar delayed-mode-hooks nil
- "List of delayed mode hooks waiting to be run.")
-(make-variable-buffer-local 'delayed-mode-hooks)
-(put 'delay-mode-hooks 'permanent-local t)
-
-(defvar change-major-mode-after-body-hook nil
- "Normal hook run in major mode functions, before the mode hooks.")
-
-(defvar after-change-major-mode-hook nil
- "Normal hook run at the very end of major mode functions.")
-
-(defun run-mode-hooks (&rest hooks)
- "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
-If the variable `delay-mode-hooks' is non-nil, does not run any hooks,
-just adds the HOOKS to the list `delayed-mode-hooks'.
-Otherwise, runs hooks in the sequence: `change-major-mode-after-body-hook',
-`delayed-mode-hooks' (in reverse order), HOOKS, and finally
-`after-change-major-mode-hook'. Major mode functions should use
-this instead of `run-hooks' when running their FOO-mode-hook."
- (if delay-mode-hooks
- ;; Delaying case.
- (dolist (hook hooks)
- (push hook delayed-mode-hooks))
- ;; Normal case, just run the hook as before plus any delayed hooks.
- (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
- (setq delayed-mode-hooks nil)
- (apply 'run-hooks (cons 'change-major-mode-after-body-hook hooks))
- (run-hooks 'after-change-major-mode-hook)))
-
-(defmacro delay-mode-hooks (&rest body)
- "Execute BODY, but delay any `run-mode-hooks'.
-These hooks will be executed by the first following call to
-`run-mode-hooks' that occurs outside any `delayed-mode-hooks' form.
-Only affects hooks run in the current buffer."
- (declare (debug t) (indent 0))
- `(progn
- (make-local-variable 'delay-mode-hooks)
- (let ((delay-mode-hooks t))
- ,@body)))
-
-;; PUBLIC: find if the current mode derives from another.
-
-(defun derived-mode-p (&rest modes)
- "Non-nil if the current major mode is derived from one of MODES.
-Uses the `derived-mode-parent' property of the symbol to trace backwards."
- (let ((parent major-mode))
- (while (and (not (memq parent modes))
- (setq parent (get parent 'derived-mode-parent))))
- parent))
-
-;;;; Minor modes.
-
-;; If a minor mode is not defined with define-minor-mode,
-;; add it here explicitly.
-;; isearch-mode is deliberately excluded, since you should
-;; not call it yourself.
-(defvar minor-mode-list '(auto-save-mode auto-fill-mode abbrev-mode
- overwrite-mode view-mode
- hs-minor-mode)
- "List of all minor mode functions.")
-
-(defun add-minor-mode (toggle name &optional keymap after toggle-fun)
- "Register a new minor mode.
-
-This is an XEmacs-compatibility function. Use `define-minor-mode' instead.
-
-TOGGLE is a symbol which is the name of a buffer-local variable that
-is toggled on or off to say whether the minor mode is active or not.
-
-NAME specifies what will appear in the mode line when the minor mode
-is active. NAME should be either a string starting with a space, or a
-symbol whose value is such a string.
-
-Optional KEYMAP is the keymap for the minor mode that will be added
-to `minor-mode-map-alist'.
-
-Optional AFTER specifies that TOGGLE should be added after AFTER
-in `minor-mode-alist'.
-
-Optional TOGGLE-FUN is an interactive function to toggle the mode.
-It defaults to (and should by convention be) TOGGLE.
-
-If TOGGLE has a non-nil `:included' property, an entry for the mode is
-included in the mode-line minor mode menu.
-If TOGGLE has a `:menu-tag', that is used for the menu item's label."
- (unless (memq toggle minor-mode-list)
- (push toggle minor-mode-list))
-
- (unless toggle-fun (setq toggle-fun toggle))
- (unless (eq toggle-fun toggle)
- (put toggle :minor-mode-function toggle-fun))
- ;; Add the name to the minor-mode-alist.
- (when name
- (let ((existing (assq toggle minor-mode-alist)))
- (if existing
- (setcdr existing (list name))
- (let ((tail minor-mode-alist) found)
- (while (and tail (not found))
- (if (eq after (caar tail))
- (setq found tail)
- (setq tail (cdr tail))))
- (if found
- (let ((rest (cdr found)))
- (setcdr found nil)
- (nconc found (list (list toggle name)) rest))
- (push (list toggle name) minor-mode-alist))))))
- ;; Add the toggle to the minor-modes menu if requested.
- (when (get toggle :included)
- (define-key mode-line-mode-menu
- (vector toggle)
- (list 'menu-item
- (concat
- (or (get toggle :menu-tag)
- (if (stringp name) name (symbol-name toggle)))
- (let ((mode-name (if (symbolp name) (symbol-value name))))
- (if (and (stringp mode-name) (string-match "[^ ]+" mode-name))
- (concat " (" (match-string 0 mode-name) ")"))))
- toggle-fun
- :button (cons :toggle toggle))))
-
- ;; Add the map to the minor-mode-map-alist.
- (when keymap
- (let ((existing (assq toggle minor-mode-map-alist)))
- (if existing
- (setcdr existing keymap)
- (let ((tail minor-mode-map-alist) found)
- (while (and tail (not found))
- (if (eq after (caar tail))
- (setq found tail)
- (setq tail (cdr tail))))
- (if found
- (let ((rest (cdr found)))
- (setcdr found nil)
- (nconc found (list (cons toggle keymap)) rest))
- (push (cons toggle keymap) minor-mode-map-alist)))))))
-
-;;;; Load history
-
-(defsubst autoloadp (object)
- "Non-nil if OBJECT is an autoload."
- (eq 'autoload (car-safe object)))
-
-;; (defun autoload-type (object)
-;; "Returns the type of OBJECT or `function' or `command' if the type is nil.
-;; OBJECT should be an autoload object."
-;; (when (autoloadp object)
-;; (let ((type (nth 3 object)))
-;; (cond ((null type) (if (nth 2 object) 'command 'function))
-;; ((eq 'keymap t) 'macro)
-;; (type)))))
-
-;; (defalias 'autoload-file #'cadr
-;; "Return the name of the file from which AUTOLOAD will be loaded.
-;; \n\(fn AUTOLOAD)")
-
-(defun symbol-file (symbol &optional type)
- "Return the name of the file that defined SYMBOL.
-The value is normally an absolute file name. It can also be nil,
-if the definition is not associated with any file. If SYMBOL
-specifies an autoloaded function, the value can be a relative
-file name without extension.
-
-If TYPE is nil, then any kind of definition is acceptable. If
-TYPE is `defun', `defvar', or `defface', that specifies function
-definition, variable definition, or face definition only."
- (if (and (or (null type) (eq type 'defun))
- (symbolp symbol)
- (autoloadp (symbol-function symbol)))
- (nth 1 (symbol-function symbol))
- (let ((files load-history)
- file)
- (while files
- (if (if type
- (if (eq type 'defvar)
- ;; Variables are present just as their names.
- (member symbol (cdr (car files)))
- ;; Other types are represented as (TYPE . NAME).
- (member (cons type symbol) (cdr (car files))))
- ;; We accept all types, so look for variable def
- ;; and then for any other kind.
- (or (member symbol (cdr (car files)))
- (rassq symbol (cdr (car files)))))
- (setq file (car (car files)) files nil))
- (setq files (cdr files)))
- file)))
-
-(defun locate-library (library &optional nosuffix path interactive-call)
- "Show the precise file name of Emacs library LIBRARY.
-LIBRARY should be a relative file name of the library, a string.
-It can omit the suffix (a.k.a. file-name extension) if NOSUFFIX is
-nil (which is the default, see below).
-This command searches the directories in `load-path' like `\\[load-library]'
-to find the file that `\\[load-library] RET LIBRARY RET' would load.
-Optional second arg NOSUFFIX non-nil means don't add suffixes `load-suffixes'
-to the specified name LIBRARY.
-
-If the optional third arg PATH is specified, that list of directories
-is used instead of `load-path'.
-
-When called from a program, the file name is normally returned as a
-string. When run interactively, the argument INTERACTIVE-CALL is t,
-and the file name is displayed in the echo area."
- (interactive (list (completing-read "Locate library: "
- (apply-partially
- 'locate-file-completion-table
- load-path (get-load-suffixes)))
- nil nil
- t))
- (let ((file (locate-file library
- (or path load-path)
- (append (unless nosuffix (get-load-suffixes))
- load-file-rep-suffixes))))
- (if interactive-call
- (if file
- (message "Library is file %s" (abbreviate-file-name file))
- (message "No library %s in search path" library)))
- file))
-
-
-;;;; Process stuff.
-
-(defun process-lines (program &rest args)
- "Execute PROGRAM with ARGS, returning its output as a list of lines.
-Signal an error if the program returns with a non-zero exit status."
- (with-temp-buffer
- (let ((status (apply 'call-process program nil (current-buffer) nil args)))
- (unless (eq status 0)
- (error "%s exited with status %s" program status))
- (goto-char (point-min))
- (let (lines)
- (while (not (eobp))
- (setq lines (cons (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))
- lines))
- (forward-line 1))
- (nreverse lines)))))
-
-(defun process-live-p (process)
- "Returns non-nil if PROCESS is alive.
-A process is considered alive if its status is `run', `open',
-`listen', `connect' or `stop'. Value is nil if PROCESS is not a
-process."
- (and (processp process)
- (memq (process-status process)
- '(run open listen connect stop))))
-
-;; compatibility
-
-(make-obsolete
- 'process-kill-without-query
- "use `process-query-on-exit-flag' or `set-process-query-on-exit-flag'."
- "22.1")
-(defun process-kill-without-query (process &optional _flag)
- "Say no query needed if PROCESS is running when Emacs is exited.
-Optional second argument if non-nil says to require a query.
-Value is t if a query was formerly required."
- (let ((old (process-query-on-exit-flag process)))
- (set-process-query-on-exit-flag process nil)
- old))
-
-(defun process-kill-buffer-query-function ()
- "Ask before killing a buffer that has a running process."
- (let ((process (get-buffer-process (current-buffer))))
- (or (not process)
- (not (memq (process-status process) '(run stop open listen)))
- (not (process-query-on-exit-flag process))
- (yes-or-no-p
- (format "Buffer %S has a running process; kill it? "
- (buffer-name (current-buffer)))))))
-
-(add-hook 'kill-buffer-query-functions 'process-kill-buffer-query-function)
-
-;; process plist management
-
-(defun process-get (process propname)
- "Return the value of PROCESS' PROPNAME property.
-This is the last value stored with `(process-put PROCESS PROPNAME VALUE)'."
- (plist-get (process-plist process) propname))
-
-(defun process-put (process propname value)
- "Change PROCESS' PROPNAME property to VALUE.
-It can be retrieved with `(process-get PROCESS PROPNAME)'."
- (set-process-plist process
- (plist-put (process-plist process) propname value)))
-
-
-;;;; Input and display facilities.
-
-(defconst read-key-empty-map (make-sparse-keymap))
-
-(defvar read-key-delay 0.01) ;Fast enough for 100Hz repeat rate, hopefully.
-
-(defun read-key (&optional prompt)
- "Read a key from the keyboard.
-Contrary to `read-event' this will not return a raw event but instead will
-obey the input decoding and translations usually done by `read-key-sequence'.
-So escape sequences and keyboard encoding are taken into account.
-When there's an ambiguity because the key looks like the prefix of
-some sort of escape sequence, the ambiguity is resolved via `read-key-delay'."
- ;; This overriding-terminal-local-map binding also happens to
- ;; disable quail's input methods, so although read-key-sequence
- ;; always inherits the input method, in practice read-key does not
- ;; inherit the input method (at least not if it's based on quail).
- (let ((overriding-terminal-local-map nil)
- (overriding-local-map read-key-empty-map)
- (echo-keystrokes 0)
- (old-global-map (current-global-map))
- (timer (run-with-idle-timer
- ;; Wait long enough that Emacs has the time to receive and
- ;; process all the raw events associated with the single-key.
- ;; But don't wait too long, or the user may find the delay
- ;; annoying (or keep hitting more keys which may then get
- ;; lost or misinterpreted).
- ;; This is only relevant for keys which Emacs perceives as
- ;; "prefixes", such as C-x (because of the C-x 8 map in
- ;; key-translate-table and the C-x @ map in function-key-map)
- ;; or ESC (because of terminal escape sequences in
- ;; input-decode-map).
- read-key-delay t
- (lambda ()
- (let ((keys (this-command-keys-vector)))
- (unless (zerop (length keys))
- ;; `keys' is non-empty, so the user has hit at least
- ;; one key; there's no point waiting any longer, even
- ;; though read-key-sequence thinks we should wait
- ;; for more input to decide how to interpret the
- ;; current input.
- (throw 'read-key keys)))))))
- (unwind-protect
- (progn
- (use-global-map
- (let ((map (make-sparse-keymap)))
- ;; Don't hide the menu-bar and tool-bar entries.
- (define-key map [menu-bar] (lookup-key global-map [menu-bar]))
- (define-key map [tool-bar]
- ;; This hack avoids evaluating the :filter (Bug#9922).
- (or (cdr (assq 'tool-bar global-map))
- (lookup-key global-map [tool-bar])))
- map))
- (aref (catch 'read-key (read-key-sequence-vector prompt nil t)) 0))
- (cancel-timer timer)
- (use-global-map old-global-map))))
-
-(defvar read-passwd-map
- ;; BEWARE: `defconst' would purecopy it, breaking the sharing with
- ;; minibuffer-local-map along the way!
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map minibuffer-local-map)
- (define-key map "\C-u" #'delete-minibuffer-contents) ;bug#12570
- map)
- "Keymap used while reading passwords.")
-
-(defun read-passwd (prompt &optional confirm default)
- "Read a password, prompting with PROMPT, and return it.
-If optional CONFIRM is non-nil, read the password twice to make sure.
-Optional DEFAULT is a default password to use instead of empty input.
-
-This function echoes `.' for each character that the user types.
-Note that in batch mode, the input is not hidden!
-
-Once the caller uses the password, it can erase the password
-by doing (clear-string STRING)."
- (if confirm
- (let (success)
- (while (not success)
- (let ((first (read-passwd prompt nil default))
- (second (read-passwd "Confirm password: " nil default)))
- (if (equal first second)
- (progn
- (and (arrayp second) (clear-string second))
- (setq success first))
- (and (arrayp first) (clear-string first))
- (and (arrayp second) (clear-string second))
- (message "Password not repeated accurately; please start over")
- (sit-for 1))))
- success)
- (let ((hide-chars-fun
- (lambda (beg end _len)
- (clear-this-command-keys)
- (setq beg (min end (max (minibuffer-prompt-end)
- beg)))
- (dotimes (i (- end beg))
- (put-text-property (+ i beg) (+ 1 i beg)
- 'display (string ?.)))))
- minibuf)
- (minibuffer-with-setup-hook
- (lambda ()
- (setq minibuf (current-buffer))
- ;; Turn off electricity.
- (setq-local post-self-insert-hook nil)
- (setq-local buffer-undo-list t)
- (setq-local select-active-regions nil)
- (use-local-map read-passwd-map)
- (setq-local inhibit-modification-hooks nil) ;bug#15501.
- (setq-local show-paren-mode nil) ;bug#16091.
- (add-hook 'after-change-functions hide-chars-fun nil 'local))
- (unwind-protect
- (let ((enable-recursive-minibuffers t))
- (read-string
- (if noninteractive
- (format "%s[INPUT WILL NOT BE HIDDEN!] " prompt) ; bug#17839
- prompt)
- nil t default)) ; t = "no history"
- (when (buffer-live-p minibuf)
- (with-current-buffer minibuf
- ;; Not sure why but it seems that there might be cases where the
- ;; minibuffer is not always properly reset later on, so undo
- ;; whatever we've done here (bug#11392).
- (remove-hook 'after-change-functions hide-chars-fun 'local)
- (kill-local-variable 'post-self-insert-hook)
- ;; And of course, don't keep the sensitive data around.
- (erase-buffer))))))))
-
-(defun read-number (prompt &optional default)
- "Read a numeric value in the minibuffer, prompting with PROMPT.
-DEFAULT specifies a default value to return if the user just types RET.
-The value of DEFAULT is inserted into PROMPT.
-This function is used by the `interactive' code letter `n'."
- (let ((n nil)
- (default1 (if (consp default) (car default) default)))
- (when default1
- (setq prompt
- (if (string-match "\\(\\):[ \t]*\\'" prompt)
- (replace-match (format " (default %s)" default1) t t prompt 1)
- (replace-regexp-in-string "[ \t]*\\'"
- (format " (default %s) " default1)
- prompt t t))))
- (while
- (progn
- (let ((str (read-from-minibuffer
- prompt nil nil nil nil
- (when default
- (if (consp default)
- (mapcar 'number-to-string (delq nil default))
- (number-to-string default))))))
- (condition-case nil
- (setq n (cond
- ((zerop (length str)) default1)
- ((stringp str) (read str))))
- (error nil)))
- (unless (numberp n)
- (message "Please enter a number.")
- (sit-for 1)
- t)))
- n))
-
-(defun read-char-choice (prompt chars &optional inhibit-keyboard-quit)
- "Read and return one of CHARS, prompting for PROMPT.
-Any input that is not one of CHARS is ignored.
-
-If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
-keyboard-quit events while waiting for a valid input."
- (unless (consp chars)
- (error "Called `read-char-choice' without valid char choices"))
- (let (char done show-help (helpbuf " *Char Help*"))
- (let ((cursor-in-echo-area t)
- (executing-kbd-macro executing-kbd-macro)
- (esc-flag nil))
- (save-window-excursion ; in case we call help-form-show
- (while (not done)
- (unless (get-text-property 0 'face prompt)
- (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
- (setq char (let ((inhibit-quit inhibit-keyboard-quit))
- (read-key prompt)))
- (and show-help (buffer-live-p (get-buffer helpbuf))
- (kill-buffer helpbuf))
- (cond
- ((not (numberp char)))
- ;; If caller has set help-form, that's enough.
- ;; They don't explicitly have to add help-char to chars.
- ((and help-form
- (eq char help-char)
- (setq show-help t)
- (help-form-show)))
- ((memq char chars)
- (setq done t))
- ((and executing-kbd-macro (= char -1))
- ;; read-event returns -1 if we are in a kbd macro and
- ;; there are no more events in the macro. Attempt to
- ;; get an event interactively.
- (setq executing-kbd-macro nil))
- ((not inhibit-keyboard-quit)
- (cond
- ((and (null esc-flag) (eq char ?\e))
- (setq esc-flag t))
- ((memq char '(?\C-g ?\e))
- (keyboard-quit))))))))
- ;; Display the question with the answer. But without cursor-in-echo-area.
- (message "%s%s" prompt (char-to-string char))
- char))
-
-(defun sit-for (seconds &optional nodisp obsolete)
- "Redisplay, then wait for SECONDS seconds. Stop when input is available.
-SECONDS may be a floating-point value.
-\(On operating systems that do not support waiting for fractions of a
-second, floating-point values are rounded down to the nearest integer.)
-
-If optional arg NODISP is t, don't redisplay, just wait for input.
-Redisplay does not happen if input is available before it starts.
-
-Value is t if waited the full time with no input arriving, and nil otherwise.
-
-An obsolete, but still supported form is
-\(sit-for SECONDS &optional MILLISECONDS NODISP)
-where the optional arg MILLISECONDS specifies an additional wait period,
-in milliseconds; this was useful when Emacs was built without
-floating point support."
- (declare (advertised-calling-convention (seconds &optional nodisp) "22.1"))
- ;; This used to be implemented in C until the following discussion:
- ;; http://lists.gnu.org/archive/html/emacs-devel/2006-07/msg00401.html
- ;; Then it was moved here using an implementation based on an idle timer,
- ;; which was then replaced by the use of read-event.
- (if (numberp nodisp)
- (setq seconds (+ seconds (* 1e-3 nodisp))
- nodisp obsolete)
- (if obsolete (setq nodisp obsolete)))
- (cond
- (noninteractive
- (sleep-for seconds)
- t)
- ((input-pending-p t)
- nil)
- ((<= seconds 0)
- (or nodisp (redisplay)))
- (t
- (or nodisp (redisplay))
- ;; FIXME: we should not read-event here at all, because it's much too
- ;; difficult to reliably "undo" a read-event by pushing it onto
- ;; unread-command-events.
- ;; For bug#14782, we need read-event to do the keyboard-coding-system
- ;; decoding (hence non-nil as second arg under POSIX ttys).
- ;; For bug#15614, we need read-event not to inherit-input-method.
- ;; So we temporarily suspend input-method-function.
- (let ((read (let ((input-method-function nil))
- (read-event nil t seconds))))
- (or (null read)
- (progn
- ;; If last command was a prefix arg, e.g. C-u, push this event onto
- ;; unread-command-events as (t . EVENT) so it will be added to
- ;; this-command-keys by read-key-sequence.
- (if (eq overriding-terminal-local-map universal-argument-map)
- (setq read (cons t read)))
- (push read unread-command-events)
- nil))))))
-
-;; Behind display-popup-menus-p test.
-(declare-function x-popup-dialog "menu.c" (position contents &optional header))
-
-(defun y-or-n-p (prompt)
- "Ask user a \"y or n\" question. Return t if answer is \"y\".
-PROMPT is the string to display to ask the question. It should
-end in a space; `y-or-n-p' adds \"(y or n) \" to it.
-
-No confirmation of the answer is requested; a single character is
-enough. SPC also means yes, and DEL means no.
-
-To be precise, this function translates user input into responses
-by consulting the bindings in `query-replace-map'; see the
-documentation of that variable for more information. In this
-case, the useful bindings are `act', `skip', `recenter',
-`scroll-up', `scroll-down', and `quit'.
-An `act' response means yes, and a `skip' response means no.
-A `quit' response means to invoke `keyboard-quit'.
-If the user enters `recenter', `scroll-up', or `scroll-down'
-responses, perform the requested window recentering or scrolling
-and ask again.
-
-Under a windowing system a dialog box will be used if `last-nonmenu-event'
-is nil and `use-dialog-box' is non-nil."
- ;; ¡Beware! when I tried to edebug this code, Emacs got into a weird state
- ;; where all the keys were unbound (i.e. it somehow got triggered
- ;; within read-key, apparently). I had to kill it.
- (let ((answer 'recenter)
- (padded (lambda (prompt &optional dialog)
- (let ((l (length prompt)))
- (concat prompt
- (if (or (zerop l) (eq ?\s (aref prompt (1- l))))
- "" " ")
- (if dialog "" "(y or n) "))))))
- (cond
- (noninteractive
- (setq prompt (funcall padded prompt))
- (let ((temp-prompt prompt))
- (while (not (memq answer '(act skip)))
- (let ((str (read-string temp-prompt)))
- (cond ((member str '("y" "Y")) (setq answer 'act))
- ((member str '("n" "N")) (setq answer 'skip))
- (t (setq temp-prompt (concat "Please answer y or n. "
- prompt))))))))
- ((and (display-popup-menus-p)
- (listp last-nonmenu-event)
- use-dialog-box)
- (setq prompt (funcall padded prompt t)
- answer (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip)))))
- (t
- (setq prompt (funcall padded prompt))
- (while
- (let* ((scroll-actions '(recenter scroll-up scroll-down
- scroll-other-window
scroll-other-window-down))
- (key
- (let ((cursor-in-echo-area t))
- (when minibuffer-auto-raise
- (raise-frame (window-frame (minibuffer-window))))
- (read-key (propertize (if (memq answer scroll-actions)
- prompt
- (concat "Please answer y or n. "
- prompt))
- 'face 'minibuffer-prompt)))))
- (setq answer (lookup-key query-replace-map (vector key) t))
- (cond
- ((memq answer '(skip act)) nil)
- ((eq answer 'recenter)
- (recenter) t)
- ((eq answer 'scroll-up)
- (ignore-errors (scroll-up-command)) t)
- ((eq answer 'scroll-down)
- (ignore-errors (scroll-down-command)) t)
- ((eq answer 'scroll-other-window)
- (ignore-errors (scroll-other-window)) t)
- ((eq answer 'scroll-other-window-down)
- (ignore-errors (scroll-other-window-down)) t)
- ((or (memq answer '(exit-prefix quit)) (eq key ?\e))
- (signal 'quit nil) t)
- (t t)))
- (ding)
- (discard-input))))
- (let ((ret (eq answer 'act)))
- (unless noninteractive
- (message "%s%c" prompt (if ret ?y ?n)))
- ret)))
-
-
-;;; Atomic change groups.
-
-(defmacro atomic-change-group (&rest body)
- "Perform BODY as an atomic change group.
-This means that if BODY exits abnormally,
-all of its changes to the current buffer are undone.
-This works regardless of whether undo is enabled in the buffer.
-
-This mechanism is transparent to ordinary use of undo;
-if undo is enabled in the buffer and BODY succeeds, the
-user can undo the change normally."
- (declare (indent 0) (debug t))
- (let ((handle (make-symbol "--change-group-handle--"))
- (success (make-symbol "--change-group-success--")))
- `(let ((,handle (prepare-change-group))
- ;; Don't truncate any undo data in the middle of this.
- (undo-outer-limit nil)
- (undo-limit most-positive-fixnum)
- (undo-strong-limit most-positive-fixnum)
- (,success nil))
- (unwind-protect
- (progn
- ;; This is inside the unwind-protect because
- ;; it enables undo if that was disabled; we need
- ;; to make sure that it gets disabled again.
- (activate-change-group ,handle)
- ,@body
- (setq ,success t))
- ;; Either of these functions will disable undo
- ;; if it was disabled before.
- (if ,success
- (accept-change-group ,handle)
- (cancel-change-group ,handle))))))
-
-(defun prepare-change-group (&optional buffer)
- "Return a handle for the current buffer's state, for a change group.
-If you specify BUFFER, make a handle for BUFFER's state instead.
-
-Pass the handle to `activate-change-group' afterward to initiate
-the actual changes of the change group.
-
-To finish the change group, call either `accept-change-group' or
-`cancel-change-group' passing the same handle as argument. Call
-`accept-change-group' to accept the changes in the group as final;
-call `cancel-change-group' to undo them all. You should use
-`unwind-protect' to make sure the group is always finished. The call
-to `activate-change-group' should be inside the `unwind-protect'.
-Once you finish the group, don't use the handle again--don't try to
-finish the same group twice. For a simple example of correct use, see
-the source code of `atomic-change-group'.
-
-The handle records only the specified buffer. To make a multibuffer
-change group, call this function once for each buffer you want to
-cover, then use `nconc' to combine the returned values, like this:
-
- (nconc (prepare-change-group buffer-1)
- (prepare-change-group buffer-2))
-
-You can then activate that multibuffer change group with a single
-call to `activate-change-group' and finish it with a single call
-to `accept-change-group' or `cancel-change-group'."
-
- (if buffer
- (list (cons buffer (with-current-buffer buffer buffer-undo-list)))
- (list (cons (current-buffer) buffer-undo-list))))
-
-(defun activate-change-group (handle)
- "Activate a change group made with `prepare-change-group' (which see)."
- (dolist (elt handle)
- (with-current-buffer (car elt)
- (if (eq buffer-undo-list t)
- (setq buffer-undo-list nil)))))
-
-(defun accept-change-group (handle)
- "Finish a change group made with `prepare-change-group' (which see).
-This finishes the change group by accepting its changes as final."
- (dolist (elt handle)
- (with-current-buffer (car elt)
- (if (eq (cdr elt) t)
- (setq buffer-undo-list t)))))
-
-(defun cancel-change-group (handle)
- "Finish a change group made with `prepare-change-group' (which see).
-This finishes the change group by reverting all of its changes."
- (dolist (elt handle)
- (with-current-buffer (car elt)
- (setq elt (cdr elt))
- (save-restriction
- ;; Widen buffer temporarily so if the buffer was narrowed within
- ;; the body of `atomic-change-group' all changes can be undone.
- (widen)
- (let ((old-car
- (if (consp elt) (car elt)))
- (old-cdr
- (if (consp elt) (cdr elt))))
- ;; Temporarily truncate the undo log at ELT.
- (when (consp elt)
- (setcar elt nil) (setcdr elt nil))
- (unless (eq last-command 'undo) (undo-start))
- ;; Make sure there's no confusion.
- (when (and (consp elt) (not (eq elt (last pending-undo-list))))
- (error "Undoing to some unrelated state"))
- ;; Undo it all.
- (save-excursion
- (while (listp pending-undo-list) (undo-more 1)))
- ;; Reset the modified cons cell ELT to its original content.
- (when (consp elt)
- (setcar elt old-car)
- (setcdr elt old-cdr))
- ;; Revert the undo info to what it was when we grabbed the state.
- (setq buffer-undo-list elt))))))
-
-;;;; Display-related functions.
-
-;; For compatibility.
-(define-obsolete-function-alias 'redraw-modeline
- 'force-mode-line-update "24.3")
-
-(defun momentary-string-display (string pos &optional exit-char message)
- "Momentarily display STRING in the buffer at POS.
-Display remains until next event is input.
-If POS is a marker, only its position is used; its buffer is ignored.
-Optional third arg EXIT-CHAR can be a character, event or event
-description list. EXIT-CHAR defaults to SPC. If the input is
-EXIT-CHAR it is swallowed; otherwise it is then available as
-input (as a command if nothing else).
-Display MESSAGE (optional fourth arg) in the echo area.
-If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there."
- (or exit-char (setq exit-char ?\s))
- (let ((ol (make-overlay pos pos))
- (str (copy-sequence string)))
- (unwind-protect
- (progn
- (save-excursion
- (overlay-put ol 'after-string str)
- (goto-char pos)
- ;; To avoid trouble with out-of-bounds position
- (setq pos (point))
- ;; If the string end is off screen, recenter now.
- (if (<= (window-end nil t) pos)
- (recenter (/ (window-height) 2))))
- (message (or message "Type %s to continue editing.")
- (single-key-description exit-char))
- (let ((event (read-key)))
- ;; `exit-char' can be an event, or an event description list.
- (or (eq event exit-char)
- (eq event (event-convert-list exit-char))
- (setq unread-command-events
- (append (this-single-command-raw-keys))))))
- (delete-overlay ol))))
-
-
-;;;; Overlay operations
-
-(defun copy-overlay (o)
- "Return a copy of overlay O."
- (let ((o1 (if (overlay-buffer o)
- (make-overlay (overlay-start o) (overlay-end o)
- ;; FIXME: there's no easy way to find the
- ;; insertion-type of the two markers.
- (overlay-buffer o))
- (let ((o1 (make-overlay (point-min) (point-min))))
- (delete-overlay o1)
- o1)))
- (props (overlay-properties o)))
- (while props
- (overlay-put o1 (pop props) (pop props)))
- o1))
-
-(defun remove-overlays (&optional beg end name val)
- "Clear BEG and END of overlays whose property NAME has value VAL.
-Overlays might be moved and/or split.
-BEG and END default respectively to the beginning and end of buffer."
- ;; This speeds up the loops over overlays.
- (unless beg (setq beg (point-min)))
- (unless end (setq end (point-max)))
- (overlay-recenter end)
- (if (< end beg)
- (setq beg (prog1 end (setq end beg))))
- (save-excursion
- (dolist (o (overlays-in beg end))
- (when (eq (overlay-get o name) val)
- ;; Either push this overlay outside beg...end
- ;; or split it to exclude beg...end
- ;; or delete it entirely (if it is contained in beg...end).
- (if (< (overlay-start o) beg)
- (if (> (overlay-end o) end)
- (progn
- (move-overlay (copy-overlay o)
- (overlay-start o) beg)
- (move-overlay o end (overlay-end o)))
- (move-overlay o (overlay-start o) beg))
- (if (> (overlay-end o) end)
- (move-overlay o end (overlay-end o))
- (delete-overlay o)))))))
-
-;;;; Miscellanea.
-
-(defvar suspend-hook nil
- "Normal hook run by `suspend-emacs', before suspending.")
-
-(defvar suspend-resume-hook nil
- "Normal hook run by `suspend-emacs', after Emacs is continued.")
-
-(defvar temp-buffer-show-hook nil
- "Normal hook run by `with-output-to-temp-buffer' after displaying the buffer.
-When the hook runs, the temporary buffer is current, and the window it
-was displayed in is selected.")
-
-(defvar temp-buffer-setup-hook nil
- "Normal hook run by `with-output-to-temp-buffer' at the start.
-When the hook runs, the temporary buffer is current.
-This hook is normally set up with a function to put the buffer in Help
-mode.")
-
-(defconst user-emacs-directory
- (if (eq system-type 'ms-dos)
- ;; MS-DOS cannot have initial dot.
- "~/_emacs.d/"
- "~/.emacs.d/")
- "Directory beneath which additional per-user Emacs-specific files are placed.
-Various programs in Emacs store information in this directory.
-Note that this should end with a directory separator.
-See also `locate-user-emacs-file'.")
-
-;;;; Misc. useful functions.
-
-(defsubst buffer-narrowed-p ()
- "Return non-nil if the current buffer is narrowed."
- (/= (- (point-max) (point-min)) (buffer-size)))
-
-(defun find-tag-default-bounds ()
- "Determine the boundaries of the default tag, based on text at point.
-Return a cons cell with the beginning and end of the found tag.
-If there is no plausible default, return nil."
- (let (from to bound)
- (when (or (progn
- ;; Look at text around `point'.
- (save-excursion
- (skip-syntax-backward "w_") (setq from (point)))
- (save-excursion
- (skip-syntax-forward "w_") (setq to (point)))
- (> to from))
- ;; Look between `line-beginning-position' and `point'.
- (save-excursion
- (and (setq bound (line-beginning-position))
- (skip-syntax-backward "^w_" bound)
- (> (setq to (point)) bound)
- (skip-syntax-backward "w_")
- (setq from (point))))
- ;; Look between `point' and `line-end-position'.
- (save-excursion
- (and (setq bound (line-end-position))
- (skip-syntax-forward "^w_" bound)
- (< (setq from (point)) bound)
- (skip-syntax-forward "w_")
- (setq to (point)))))
- (cons from to))))
-
-(defun find-tag-default ()
- "Determine default tag to search for, based on text at point.
-If there is no plausible default, return nil."
- (let ((bounds (find-tag-default-bounds)))
- (when bounds
- (buffer-substring-no-properties (car bounds) (cdr bounds)))))
-
-(defun find-tag-default-as-regexp ()
- "Return regexp that matches the default tag at point.
-If there is no tag at point, return nil.
-
-When in a major mode that does not provide its own
-`find-tag-default-function', return a regexp that matches the
-symbol at point exactly."
- (let ((tag (funcall (or find-tag-default-function
- (get major-mode 'find-tag-default-function)
- 'find-tag-default))))
- (if tag (regexp-quote tag))))
-
-(defun find-tag-default-as-symbol-regexp ()
- "Return regexp that matches the default tag at point as symbol.
-If there is no tag at point, return nil.
-
-When in a major mode that does not provide its own
-`find-tag-default-function', return a regexp that matches the
-symbol at point exactly."
- (let ((tag-regexp (find-tag-default-as-regexp)))
- (if (and tag-regexp
- (eq (or find-tag-default-function
- (get major-mode 'find-tag-default-function)
- 'find-tag-default)
- 'find-tag-default))
- (format "\\_<%s\\_>" tag-regexp)
- tag-regexp)))
-
-(defun play-sound (sound)
- "SOUND is a list of the form `(sound KEYWORD VALUE...)'.
-The following keywords are recognized:
-
- :file FILE - read sound data from FILE. If FILE isn't an
-absolute file name, it is searched in `data-directory'.
-
- :data DATA - read sound data from string DATA.
-
-Exactly one of :file or :data must be present.
-
- :volume VOL - set volume to VOL. VOL must an integer in the
-range 0..100 or a float in the range 0..1.0. If not specified,
-don't change the volume setting of the sound device.
-
- :device DEVICE - play sound on DEVICE. If not specified,
-a system-dependent default device name is used.
-
-Note: :data and :device are currently not supported on Windows."
- (if (fboundp 'play-sound-internal)
- (play-sound-internal sound)
- (error "This Emacs binary lacks sound support")))
-
-(declare-function w32-shell-dos-semantics "w32-fns" nil)
-
-(defun shell-quote-argument (argument)
- "Quote ARGUMENT for passing as argument to an inferior shell."
- (cond
- ((eq system-type 'ms-dos)
- ;; Quote using double quotes, but escape any existing quotes in
- ;; the argument with backslashes.
- (let ((result "")
- (start 0)
- end)
- (if (or (null (string-match "[^\"]" argument))
- (< (match-end 0) (length argument)))
- (while (string-match "[\"]" argument start)
- (setq end (match-beginning 0)
- result (concat result (substring argument start end)
- "\\" (substring argument end (1+ end)))
- start (1+ end))))
- (concat "\"" result (substring argument start) "\"")))
-
- ((and (eq system-type 'windows-nt) (w32-shell-dos-semantics))
-
- ;; First, quote argument so that CommandLineToArgvW will
- ;; understand it. See
- ;; http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
- ;; After we perform that level of quoting, escape shell
- ;; metacharacters so that cmd won't mangle our argument. If the
- ;; argument contains no double quote characters, we can just
- ;; surround it with double quotes. Otherwise, we need to prefix
- ;; each shell metacharacter with a caret.
-
- (setq argument
- ;; escape backslashes at end of string
- (replace-regexp-in-string
- "\\(\\\\*\\)$"
- "\\1\\1"
- ;; escape backslashes and quotes in string body
- (replace-regexp-in-string
- "\\(\\\\*\\)\""
- "\\1\\1\\\\\""
- argument)))
-
- (if (string-match "[%!\"]" argument)
- (concat
- "^\""
- (replace-regexp-in-string
- "\\([%!()\"<>&|^]\\)"
- "^\\1"
- argument)
- "^\"")
- (concat "\"" argument "\"")))
-
- (t
- (if (equal argument "")
- "''"
- ;; Quote everything except POSIX filename characters.
- ;; This should be safe enough even for really weird shells.
- (replace-regexp-in-string
- "\n" "'\n'"
- (replace-regexp-in-string "[^-0-9a-zA-Z_./\n]" "\\\\\\&" argument))))
- ))
-
-(defun string-or-null-p (object)
- "Return t if OBJECT is a string or nil.
-Otherwise, return nil."
- (or (stringp object) (null object)))
-
-(defun booleanp (object)
- "Return t if OBJECT is one of the two canonical boolean values: t or nil.
-Otherwise, return nil."
- (and (memq object '(nil t)) t))
-
-(defun special-form-p (object)
- "Non-nil if and only if OBJECT is a special form."
- (if (and (symbolp object) (fboundp object))
- (setq object (indirect-function object t)))
- (and (subrp object) (eq (cdr (subr-arity object)) 'unevalled)))
-
-(defun macrop (object)
- "Non-nil if and only if OBJECT is a macro."
- (let ((def (indirect-function object t)))
- (when (consp def)
- (or (eq 'macro (car def))
- (and (autoloadp def) (memq (nth 4 def) '(macro t)))))))
-
-(defun field-at-pos (pos)
- "Return the field at position POS, taking stickiness etc into account."
- (let ((raw-field (get-char-property (field-beginning pos) 'field)))
- (if (eq raw-field 'boundary)
- (get-char-property (1- (field-end pos)) 'field)
- raw-field)))
-
-(defun sha1 (object &optional start end binary)
- "Return the SHA1 (Secure Hash Algorithm) of an OBJECT.
-OBJECT is either a string or a buffer. Optional arguments START and
-END are character positions specifying which portion of OBJECT for
-computing the hash. If BINARY is non-nil, return a string in binary
-form."
- (secure-hash 'sha1 object start end binary))
-
-(defalias 'function-put #'put
- ;; This is only really used in Emacs>24.4, but we add it to 24.4 already, so
- ;; as to ease the pain when people use future autoload files that contain
- ;; function-put.
- "Set function F's property PROP to VALUE.
-The namespace for PROP is shared with symbols.
-So far, F can only be a symbol, not a lambda expression.")
-
-(defun function-get (f prop &optional autoload)
- "Return the value of property PROP of function F.
-If AUTOLOAD is non-nil and F is autoloaded, try to autoload it
-in the hope that it will set PROP. If AUTOLOAD is `macro', only do it
-if it's an autoloaded macro."
- (let ((val nil))
- (while (and (symbolp f)
- (null (setq val (get f prop)))
- (fboundp f))
- (let ((fundef (symbol-function f)))
- (if (and autoload (autoloadp fundef)
- (not (equal fundef
- (autoload-do-load fundef f
- (if (eq autoload 'macro)
- 'macro)))))
- nil ;Re-try `get' on the same `f'.
- (setq f fundef))))
- val))
-
-;;;; Support for yanking and text properties.
-;; Why here in subr.el rather than in simple.el? --Stef
-
-(defvar yank-handled-properties)
-(defvar yank-excluded-properties)
-
-(defun remove-yank-excluded-properties (start end)
- "Process text properties between START and END, inserted for a `yank'.
-Perform the handling specified by `yank-handled-properties', then
-remove properties specified by `yank-excluded-properties'."
- (let ((inhibit-read-only t))
- (dolist (handler yank-handled-properties)
- (let ((prop (car handler))
- (fun (cdr handler))
- (run-start start))
- (while (< run-start end)
- (let ((value (get-text-property run-start prop))
- (run-end (next-single-property-change
- run-start prop nil end)))
- (funcall fun value run-start run-end)
- (setq run-start run-end)))))
- (if (eq yank-excluded-properties t)
- (set-text-properties start end nil)
- (remove-list-of-text-properties start end yank-excluded-properties))))
-
-(defvar yank-undo-function)
-
-(defun insert-for-yank (string)
- "Call `insert-for-yank-1' repetitively for each `yank-handler' segment.
-
-See `insert-for-yank-1' for more details."
- (let (to)
- (while (setq to (next-single-property-change 0 'yank-handler string))
- (insert-for-yank-1 (substring string 0 to))
- (setq string (substring string to))))
- (insert-for-yank-1 string))
-
-(defun insert-for-yank-1 (string)
- "Insert STRING at point for the `yank' command.
-This function is like `insert', except it honors the variables
-`yank-handled-properties' and `yank-excluded-properties', and the
-`yank-handler' text property.
-
-Properties listed in `yank-handled-properties' are processed,
-then those listed in `yank-excluded-properties' are discarded.
-
-If STRING has a non-nil `yank-handler' property on its first
-character, the normal insert behavior is altered. The value of
-the `yank-handler' property must be a list of one to four
-elements, of the form (FUNCTION PARAM NOEXCLUDE UNDO).
-FUNCTION, if non-nil, should be a function of one argument, an
- object to insert; it is called instead of `insert'.
-PARAM, if present and non-nil, replaces STRING as the argument to
- FUNCTION or `insert'; e.g. if FUNCTION is `yank-rectangle', PARAM
- may be a list of strings to insert as a rectangle.
-If NOEXCLUDE is present and non-nil, the normal removal of
- `yank-excluded-properties' is not performed; instead FUNCTION is
- responsible for the removal. This may be necessary if FUNCTION
- adjusts point before or after inserting the object.
-UNDO, if present and non-nil, should be a function to be called
- by `yank-pop' to undo the insertion of the current object. It is
- given two arguments, the start and end of the region. FUNCTION
- may set `yank-undo-function' to override UNDO."
- (let* ((handler (and (stringp string)
- (get-text-property 0 'yank-handler string)))
- (param (or (nth 1 handler) string))
- (opoint (point))
- (inhibit-read-only inhibit-read-only)
- end)
-
- (setq yank-undo-function t)
- (if (nth 0 handler) ; FUNCTION
- (funcall (car handler) param)
- (insert param))
- (setq end (point))
-
- ;; Prevent read-only properties from interfering with the
- ;; following text property changes.
- (setq inhibit-read-only t)
-
- (unless (nth 2 handler) ; NOEXCLUDE
- (remove-yank-excluded-properties opoint end))
-
- ;; If last inserted char has properties, mark them as rear-nonsticky.
- (if (and (> end opoint)
- (text-properties-at (1- end)))
- (put-text-property (1- end) end 'rear-nonsticky t))
-
- (if (eq yank-undo-function t) ; not set by FUNCTION
- (setq yank-undo-function (nth 3 handler))) ; UNDO
- (if (nth 4 handler) ; COMMAND
- (setq this-command (nth 4 handler)))))
-
-(defun insert-buffer-substring-no-properties (buffer &optional start end)
- "Insert before point a substring of BUFFER, without text properties.
-BUFFER may be a buffer or a buffer name.
-Arguments START and END are character positions specifying the substring.
-They default to the values of (point-min) and (point-max) in BUFFER."
- (let ((opoint (point)))
- (insert-buffer-substring buffer start end)
- (let ((inhibit-read-only t))
- (set-text-properties opoint (point) nil))))
-
-(defun insert-buffer-substring-as-yank (buffer &optional start end)
- "Insert before point a part of BUFFER, stripping some text properties.
-BUFFER may be a buffer or a buffer name.
-Arguments START and END are character positions specifying the substring.
-They default to the values of (point-min) and (point-max) in BUFFER.
-Before insertion, process text properties according to
-`yank-handled-properties' and `yank-excluded-properties'."
- ;; Since the buffer text should not normally have yank-handler properties,
- ;; there is no need to handle them here.
- (let ((opoint (point)))
- (insert-buffer-substring buffer start end)
- (remove-yank-excluded-properties opoint (point))))
-
-(defun yank-handle-font-lock-face-property (face start end)
- "If `font-lock-defaults' is nil, apply FACE as a `face' property.
-START and END denote the start and end of the text to act on.
-Do nothing if FACE is nil."
- (and face
- (null font-lock-defaults)
- (put-text-property start end 'face face)))
-
-;; This removes `mouse-face' properties in *Help* buffer buttons:
-;; http://lists.gnu.org/archive/html/emacs-devel/2002-04/msg00648.html
-(defun yank-handle-category-property (category start end)
- "Apply property category CATEGORY's properties between START and END."
- (when category
- (let ((start2 start))
- (while (< start2 end)
- (let ((end2 (next-property-change start2 nil end))
- (original (text-properties-at start2)))
- (set-text-properties start2 end2 (symbol-plist category))
- (add-text-properties start2 end2 original)
- (setq start2 end2))))))
-
-
-;;;; Synchronous shell commands.
-
-(defun start-process-shell-command (name buffer &rest args)
- "Start a program in a subprocess. Return the process object for it.
-NAME is name for process. It is modified if necessary to make it unique.
-BUFFER is the buffer (or buffer name) to associate with the process.
- Process output goes at end of that buffer, unless you specify
- an output stream or filter function to handle the output.
- BUFFER may be also nil, meaning that this process is not associated
- with any buffer
-COMMAND is the shell command to run.
-
-An old calling convention accepted any number of arguments after COMMAND,
-which were just concatenated to COMMAND. This is still supported but strongly
-discouraged."
- (declare (advertised-calling-convention (name buffer command) "23.1"))
- ;; We used to use `exec' to replace the shell with the command,
- ;; but that failed to handle (...) and semicolon, etc.
- (start-process name buffer shell-file-name shell-command-switch
- (mapconcat 'identity args " ")))
-
-(defun start-file-process-shell-command (name buffer &rest args)
- "Start a program in a subprocess. Return the process object for it.
-Similar to `start-process-shell-command', but calls `start-file-process'."
- (declare (advertised-calling-convention (name buffer command) "23.1"))
- (start-file-process
- name buffer
- (if (file-remote-p default-directory) "/bin/sh" shell-file-name)
- (if (file-remote-p default-directory) "-c" shell-command-switch)
- (mapconcat 'identity args " ")))
-
-(defun call-process-shell-command (command &optional infile buffer display
- &rest args)
- "Execute the shell command COMMAND synchronously in separate process.
-The remaining arguments are optional.
-The program's input comes from file INFILE (nil means `/dev/null').
-Insert output in BUFFER before point; t means current buffer;
- nil for BUFFER means discard it; 0 means discard and don't wait.
-BUFFER can also have the form (REAL-BUFFER STDERR-FILE); in that case,
-REAL-BUFFER says what to do with standard output, as above,
-while STDERR-FILE says what to do with standard error in the child.
-STDERR-FILE may be nil (discard standard error output),
-t (mix it with ordinary output), or a file name string.
-
-Fourth arg DISPLAY non-nil means redisplay buffer as output is inserted.
-Wildcards and redirection are handled as usual in the shell.
-
-If BUFFER is 0, `call-process-shell-command' returns immediately with value
nil.
-Otherwise it waits for COMMAND to terminate and returns a numeric exit
-status or a signal description string.
-If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
-
-An old calling convention accepted any number of arguments after DISPLAY,
-which were just concatenated to COMMAND. This is still supported but strongly
-discouraged."
- (declare (advertised-calling-convention
- (command &optional infile buffer display) "24.5"))
- ;; We used to use `exec' to replace the shell with the command,
- ;; but that failed to handle (...) and semicolon, etc.
- (call-process shell-file-name
- infile buffer display
- shell-command-switch
- (mapconcat 'identity (cons command args) " ")))
-
-(defun process-file-shell-command (command &optional infile buffer display
- &rest args)
- "Process files synchronously in a separate process.
-Similar to `call-process-shell-command', but calls `process-file'."
- (declare (advertised-calling-convention
- (command &optional infile buffer display) "24.5"))
- (process-file
- (if (file-remote-p default-directory) "/bin/sh" shell-file-name)
- infile buffer display
- (if (file-remote-p default-directory) "-c" shell-command-switch)
- (mapconcat 'identity (cons command args) " ")))
-
-;;;; Lisp macros to do various things temporarily.
-
-(defmacro with-current-buffer (buffer-or-name &rest body)
- "Execute the forms in BODY with BUFFER-OR-NAME temporarily current.
-BUFFER-OR-NAME must be a buffer or the name of an existing buffer.
-The value returned is the value of the last form in BODY. See
-also `with-temp-buffer'."
- (declare (indent 1) (debug t))
- `(save-current-buffer
- (set-buffer ,buffer-or-name)
- ,@body))
-
-(defun internal--before-with-selected-window (window)
- (let ((other-frame (window-frame window)))
- (list window (selected-window)
- ;; Selecting a window on another frame also changes that
- ;; frame's frame-selected-window. We must save&restore it.
- (unless (eq (selected-frame) other-frame)
- (frame-selected-window other-frame))
- ;; Also remember the top-frame if on ttys.
- (unless (eq (selected-frame) other-frame)
- (tty-top-frame other-frame)))))
-
-(defun internal--after-with-selected-window (state)
- ;; First reset frame-selected-window.
- (when (window-live-p (nth 2 state))
- ;; We don't use set-frame-selected-window because it does not
- ;; pass the `norecord' argument to Fselect_window.
- (select-window (nth 2 state) 'norecord)
- (and (frame-live-p (nth 3 state))
- (not (eq (tty-top-frame) (nth 3 state)))
- (select-frame (nth 3 state) 'norecord)))
- ;; Then reset the actual selected-window.
- (when (window-live-p (nth 1 state))
- (select-window (nth 1 state) 'norecord)))
-
-(defmacro with-selected-window (window &rest body)
- "Execute the forms in BODY with WINDOW as the selected window.
-The value returned is the value of the last form in BODY.
-
-This macro saves and restores the selected window, as well as the
-selected window of each frame. It does not change the order of
-recently selected windows. If the previously selected window of
-some frame is no longer live at the end of BODY, that frame's
-selected window is left alone. If the selected window is no
-longer live, then whatever window is selected at the end of BODY
-remains selected.
-
-This macro uses `save-current-buffer' to save and restore the
-current buffer, since otherwise its normal operation could
-potentially make a different buffer current. It does not alter
-the buffer list ordering."
- (declare (indent 1) (debug t))
- `(let ((save-selected-window--state
- (internal--before-with-selected-window ,window)))
- (save-current-buffer
- (unwind-protect
- (progn (select-window (car save-selected-window--state) 'norecord)
- ,@body)
- (internal--after-with-selected-window save-selected-window--state)))))
-
-(defmacro with-selected-frame (frame &rest body)
- "Execute the forms in BODY with FRAME as the selected frame.
-The value returned is the value of the last form in BODY.
-
-This macro saves and restores the selected frame, and changes the
-order of neither the recently selected windows nor the buffers in
-the buffer list."
- (declare (indent 1) (debug t))
- (let ((old-frame (make-symbol "old-frame"))
- (old-buffer (make-symbol "old-buffer")))
- `(let ((,old-frame (selected-frame))
- (,old-buffer (current-buffer)))
- (unwind-protect
- (progn (select-frame ,frame 'norecord)
- ,@body)
- (when (frame-live-p ,old-frame)
- (select-frame ,old-frame 'norecord))
- (when (buffer-live-p ,old-buffer)
- (set-buffer ,old-buffer))))))
-
-(defmacro save-window-excursion (&rest body)
- "Execute BODY, then restore previous window configuration.
-This macro saves the window configuration on the selected frame,
-executes BODY, then calls `set-window-configuration' to restore
-the saved window configuration. The return value is the last
-form in BODY. The window configuration is also restored if BODY
-exits nonlocally.
-
-BEWARE: Most uses of this macro introduce bugs.
-E.g. it should not be used to try and prevent some code from opening
-a new window, since that window may sometimes appear in another frame,
-in which case `save-window-excursion' cannot help."
- (declare (indent 0) (debug t))
- (let ((c (make-symbol "wconfig")))
- `(let ((,c (current-window-configuration)))
- (unwind-protect (progn ,@body)
- (set-window-configuration ,c)))))
-
-(defun internal-temp-output-buffer-show (buffer)
- "Internal function for `with-output-to-temp-buffer'."
- (with-current-buffer buffer
- (set-buffer-modified-p nil)
- (goto-char (point-min)))
-
- (if temp-buffer-show-function
- (funcall temp-buffer-show-function buffer)
- (with-current-buffer buffer
- (let* ((window
- (let ((window-combination-limit
- ;; When `window-combination-limit' equals
- ;; `temp-buffer' or `temp-buffer-resize' and
- ;; `temp-buffer-resize-mode' is enabled in this
- ;; buffer bind it to t so resizing steals space
- ;; preferably from the window that was split.
- (if (or (eq window-combination-limit 'temp-buffer)
- (and (eq window-combination-limit
- 'temp-buffer-resize)
- temp-buffer-resize-mode))
- t
- window-combination-limit)))
- (display-buffer buffer)))
- (frame (and window (window-frame window))))
- (when window
- (unless (eq frame (selected-frame))
- (make-frame-visible frame))
- (setq minibuffer-scroll-window window)
- (set-window-hscroll window 0)
- ;; Don't try this with NOFORCE non-nil!
- (set-window-start window (point-min) t)
- ;; This should not be necessary.
- (set-window-point window (point-min))
- ;; Run `temp-buffer-show-hook', with the chosen window selected.
- (with-selected-window window
- (run-hooks 'temp-buffer-show-hook))))))
- ;; Return nil.
- nil)
-
-;; Doc is very similar to with-temp-buffer-window.
-(defmacro with-output-to-temp-buffer (bufname &rest body)
- "Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer.
-
-This construct makes buffer BUFNAME empty before running BODY.
-It does not make the buffer current for BODY.
-Instead it binds `standard-output' to that buffer, so that output
-generated with `prin1' and similar functions in BODY goes into
-the buffer.
-
-At the end of BODY, this marks buffer BUFNAME unmodified and displays
-it in a window, but does not select it. The normal way to do this is
-by calling `display-buffer', then running `temp-buffer-show-hook'.
-However, if `temp-buffer-show-function' is non-nil, it calls that
-function instead (and does not run `temp-buffer-show-hook'). The
-function gets one argument, the buffer to display.
-
-The return value of `with-output-to-temp-buffer' is the value of the
-last form in BODY. If BODY does not finish normally, the buffer
-BUFNAME is not displayed.
-
-This runs the hook `temp-buffer-setup-hook' before BODY,
-with the buffer BUFNAME temporarily current. It runs the hook
-`temp-buffer-show-hook' after displaying buffer BUFNAME, with that
-buffer temporarily current, and the window that was used to display it
-temporarily selected. But it doesn't run `temp-buffer-show-hook'
-if it uses `temp-buffer-show-function'.
-
-By default, the setup hook puts the buffer into Help mode before running BODY.
-If BODY does not change the major mode, the show hook makes the buffer
-read-only, and scans it for function and variable names to make them into
-clickable cross-references.
-
-See the related form `with-temp-buffer-window'."
- (declare (debug t))
- (let ((old-dir (make-symbol "old-dir"))
- (buf (make-symbol "buf")))
- `(let* ((,old-dir default-directory)
- (,buf
- (with-current-buffer (get-buffer-create ,bufname)
- (prog1 (current-buffer)
- (kill-all-local-variables)
- ;; FIXME: delete_all_overlays
- (setq default-directory ,old-dir)
- (setq buffer-read-only nil)
- (setq buffer-file-name nil)
- (setq buffer-undo-list t)
- (let ((inhibit-read-only t)
- (inhibit-modification-hooks t))
- (erase-buffer)
- (run-hooks 'temp-buffer-setup-hook)))))
- (standard-output ,buf))
- (prog1 (progn ,@body)
- (internal-temp-output-buffer-show ,buf)))))
-
-(defmacro with-temp-file (file &rest body)
- "Create a new buffer, evaluate BODY there, and write the buffer to FILE.
-The value returned is the value of the last form in BODY.
-See also `with-temp-buffer'."
- (declare (indent 1) (debug t))
- (let ((temp-file (make-symbol "temp-file"))
- (temp-buffer (make-symbol "temp-buffer")))
- `(let ((,temp-file ,file)
- (,temp-buffer
- (get-buffer-create (generate-new-buffer-name " *temp file*"))))
- (unwind-protect
- (prog1
- (with-current-buffer ,temp-buffer
- ,@body)
- (with-current-buffer ,temp-buffer
- (write-region nil nil ,temp-file nil 0)))
- (and (buffer-name ,temp-buffer)
- (kill-buffer ,temp-buffer))))))
-
-(defmacro with-temp-message (message &rest body)
- "Display MESSAGE temporarily if non-nil while BODY is evaluated.
-The original message is restored to the echo area after BODY has finished.
-The value returned is the value of the last form in BODY.
-MESSAGE is written to the message log buffer if `message-log-max' is non-nil.
-If MESSAGE is nil, the echo area and message log buffer are unchanged.
-Use a MESSAGE of \"\" to temporarily clear the echo area."
- (declare (debug t) (indent 1))
- (let ((current-message (make-symbol "current-message"))
- (temp-message (make-symbol "with-temp-message")))
- `(let ((,temp-message ,message)
- (,current-message))
- (unwind-protect
- (progn
- (when ,temp-message
- (setq ,current-message (current-message))
- (message "%s" ,temp-message))
- ,@body)
- (and ,temp-message
- (if ,current-message
- (message "%s" ,current-message)
- (message nil)))))))
-
-(defmacro with-temp-buffer (&rest body)
- "Create a temporary buffer, and evaluate BODY there like `progn'.
-See also `with-temp-file' and `with-output-to-string'."
- (declare (indent 0) (debug t))
- (let ((temp-buffer (make-symbol "temp-buffer")))
- `(let ((,temp-buffer (generate-new-buffer " *temp*")))
- ;; FIXME: kill-buffer can change current-buffer in some odd cases.
- (with-current-buffer ,temp-buffer
- (unwind-protect
- (progn ,@body)
- (and (buffer-name ,temp-buffer)
- (kill-buffer ,temp-buffer)))))))
-
-(defmacro with-silent-modifications (&rest body)
- "Execute BODY, pretending it does not modify the buffer.
-If BODY performs real modifications to the buffer's text, other
-than cosmetic ones, undo data may become corrupted.
-
-This macro will run BODY normally, but doesn't count its buffer
-modifications as being buffer modifications. This affects things
-like `buffer-modified-p', checking whether the file is locked by
-someone else, running buffer modification hooks, and other things
-of that nature.
-
-Typically used around modifications of text-properties which do
-not really affect the buffer's content."
- (declare (debug t) (indent 0))
- (let ((modified (make-symbol "modified")))
- `(let* ((,modified (buffer-modified-p))
- (buffer-undo-list t)
- (inhibit-read-only t)
- (inhibit-modification-hooks t)
- deactivate-mark
- ;; Avoid setting and removing file locks and checking
- ;; buffer's uptodate-ness w.r.t the underlying file.
- buffer-file-name
- buffer-file-truename)
- (unwind-protect
- (progn
- ,@body)
- (unless ,modified
- (restore-buffer-modified-p nil))))))
-
-(defmacro with-output-to-string (&rest body)
- "Execute BODY, return the text it sent to `standard-output', as a string."
- (declare (indent 0) (debug t))
- `(let ((standard-output
- (get-buffer-create (generate-new-buffer-name " *string-output*"))))
- (unwind-protect
- (progn
- (let ((standard-output standard-output))
- ,@body)
- (with-current-buffer standard-output
- (buffer-string)))
- (kill-buffer standard-output))))
-
-(defmacro with-local-quit (&rest body)
- "Execute BODY, allowing quits to terminate BODY but not escape further.
-When a quit terminates BODY, `with-local-quit' returns nil but
-requests another quit. That quit will be processed as soon as quitting
-is allowed once again. (Immediately, if `inhibit-quit' is nil.)"
- (declare (debug t) (indent 0))
- `(condition-case nil
- (let ((inhibit-quit nil))
- ,@body)
- (quit (setq quit-flag t)
- ;; This call is to give a chance to handle quit-flag
- ;; in case inhibit-quit is nil.
- ;; Without this, it will not be handled until the next function
- ;; call, and that might allow it to exit thru a condition-case
- ;; that intends to handle the quit signal next time.
- (eval '(ignore nil)))))
-
-(defmacro while-no-input (&rest body)
- "Execute BODY only as long as there's no pending input.
-If input arrives, that ends the execution of BODY,
-and `while-no-input' returns t. Quitting makes it return nil.
-If BODY finishes, `while-no-input' returns whatever value BODY produced."
- (declare (debug t) (indent 0))
- (let ((catch-sym (make-symbol "input")))
- `(with-local-quit
- (catch ',catch-sym
- (let ((throw-on-input ',catch-sym))
- (or (input-pending-p)
- (progn ,@body)))))))
-
-(defmacro condition-case-unless-debug (var bodyform &rest handlers)
- "Like `condition-case' except that it does not prevent debugging.
-More specifically if `debug-on-error' is set then the debugger will be invoked
-even if this catches the signal."
- (declare (debug condition-case) (indent 2))
- `(condition-case ,var
- ,bodyform
- ,@(mapcar (lambda (handler)
- `((debug ,@(if (listp (car handler)) (car handler)
- (list (car handler))))
- ,@(cdr handler)))
- handlers)))
-
-(define-obsolete-function-alias 'condition-case-no-debug
- 'condition-case-unless-debug "24.1")
-
-(defmacro with-demoted-errors (format &rest body)
- "Run BODY and demote any errors to simple messages.
-FORMAT is a string passed to `message' to format any error message.
-It should contain a single %-sequence; e.g., \"Error: %S\".
-
-If `debug-on-error' is non-nil, run BODY without catching its errors.
-This is to be used around code which is not expected to signal an error
-but which should be robust in the unexpected case that an error is signaled.
-
-For backward compatibility, if FORMAT is not a constant string, it
-is assumed to be part of BODY, in which case the message format
-used is \"Error: %S\"."
- (declare (debug t) (indent 1))
- (let ((err (make-symbol "err"))
- (format (if (and (stringp format) body) format
- (prog1 "Error: %S"
- (if format (push format body))))))
- `(condition-case-unless-debug ,err
- ,(macroexp-progn body)
- (error (message ,format ,err) nil))))
-
-(defmacro combine-after-change-calls (&rest body)
- "Execute BODY, but don't call the after-change functions till the end.
-If BODY makes changes in the buffer, they are recorded
-and the functions on `after-change-functions' are called several times
-when BODY is finished.
-The return value is the value of the last form in BODY.
-
-If `before-change-functions' is non-nil, then calls to the after-change
-functions can't be deferred, so in that case this macro has no effect.
-
-Do not alter `after-change-functions' or `before-change-functions'
-in BODY."
- (declare (indent 0) (debug t))
- `(unwind-protect
- (let ((combine-after-change-calls t))
- . ,body)
- (combine-after-change-execute)))
-
-(defmacro with-case-table (table &rest body)
- "Execute the forms in BODY with TABLE as the current case table.
-The value returned is the value of the last form in BODY."
- (declare (indent 1) (debug t))
- (let ((old-case-table (make-symbol "table"))
- (old-buffer (make-symbol "buffer")))
- `(let ((,old-case-table (current-case-table))
- (,old-buffer (current-buffer)))
- (unwind-protect
- (progn (set-case-table ,table)
- ,@body)
- (with-current-buffer ,old-buffer
- (set-case-table ,old-case-table))))))
-
-;;; Matching and match data.
-
-(defvar save-match-data-internal)
-
-;; We use save-match-data-internal as the local variable because
-;; that works ok in practice (people should not use that variable elsewhere).
-;; We used to use an uninterned symbol; the compiler handles that properly
-;; now, but it generates slower code.
-(defmacro save-match-data (&rest body)
- "Execute the BODY forms, restoring the global value of the match data.
-The value returned is the value of the last form in BODY."
- ;; It is better not to use backquote here,
- ;; because that makes a bootstrapping problem
- ;; if you need to recompile all the Lisp files using interpreted code.
- (declare (indent 0) (debug t))
- (list 'let
- '((save-match-data-internal (match-data)))
- (list 'unwind-protect
- (cons 'progn body)
- ;; It is safe to free (evaporate) markers immediately here,
- ;; as Lisp programs should not copy from save-match-data-internal.
- '(set-match-data save-match-data-internal 'evaporate))))
-
-(defun match-string (num &optional string)
- "Return string of text matched by last search.
-NUM specifies which parenthesized expression in the last regexp.
- Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
-Zero means the entire text matched by the whole regexp or whole string.
-STRING should be given if the last search was by `string-match' on STRING.
-If STRING is nil, the current buffer should be the same buffer
-the search/match was performed in."
- (if (match-beginning num)
- (if string
- (substring string (match-beginning num) (match-end num))
- (buffer-substring (match-beginning num) (match-end num)))))
-
-(defun match-string-no-properties (num &optional string)
- "Return string of text matched by last search, without text properties.
-NUM specifies which parenthesized expression in the last regexp.
- Value is nil if NUMth pair didn't match, or there were less than NUM pairs.
-Zero means the entire text matched by the whole regexp or whole string.
-STRING should be given if the last search was by `string-match' on STRING.
-If STRING is nil, the current buffer should be the same buffer
-the search/match was performed in."
- (if (match-beginning num)
- (if string
- (substring-no-properties string (match-beginning num)
- (match-end num))
- (buffer-substring-no-properties (match-beginning num)
- (match-end num)))))
-
-
-(defun match-substitute-replacement (replacement
- &optional fixedcase literal string subexp)
- "Return REPLACEMENT as it will be inserted by `replace-match'.
-In other words, all back-references in the form `\\&' and `\\N'
-are substituted with actual strings matched by the last search.
-Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same
-meaning as for `replace-match'."
- (let ((match (match-string 0 string)))
- (save-match-data
- (set-match-data (mapcar (lambda (x)
- (if (numberp x)
- (- x (match-beginning 0))
- x))
- (match-data t)))
- (replace-match replacement fixedcase literal match subexp))))
-
-
-(defun looking-back (regexp &optional limit greedy)
- "Return non-nil if text before point matches regular expression REGEXP.
-Like `looking-at' except matches before point, and is slower.
-LIMIT if non-nil speeds up the search by specifying a minimum
-starting position, to avoid checking matches that would start
-before LIMIT.
-
-If GREEDY is non-nil, extend the match backwards as far as
-possible, stopping when a single additional previous character
-cannot be part of a match for REGEXP. When the match is
-extended, its starting position is allowed to occur before
-LIMIT.
-
-As a general recommendation, try to avoid using `looking-back'
-wherever possible, since it is slow."
- (let ((start (point))
- (pos
- (save-excursion
- (and (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)
- (point)))))
- (if (and greedy pos)
- (save-restriction
- (narrow-to-region (point-min) start)
- (while (and (> pos (point-min))
- (save-excursion
- (goto-char pos)
- (backward-char 1)
- (looking-at (concat "\\(?:" regexp "\\)\\'"))))
- (setq pos (1- pos)))
- (save-excursion
- (goto-char pos)
- (looking-at (concat "\\(?:" regexp "\\)\\'")))))
- (not (null pos))))
-
-(defsubst looking-at-p (regexp)
- "\
-Same as `looking-at' except this function does not change the match data."
- (let ((inhibit-changing-match-data t))
- (looking-at regexp)))
-
-(defsubst string-match-p (regexp string &optional start)
- "\
-Same as `string-match' except this function does not change the match data."
- (let ((inhibit-changing-match-data t))
- (string-match regexp string start)))
-
-(defun subregexp-context-p (regexp pos &optional start)
- "Return non-nil if POS is in a normal subregexp context in REGEXP.
-A subregexp context is one where a sub-regexp can appear.
-A non-subregexp context is for example within brackets, or within a
-repetition bounds operator `\\=\\{...\\}', or right after a `\\'.
-If START is non-nil, it should be a position in REGEXP, smaller
-than POS, and known to be in a subregexp context."
- ;; Here's one possible implementation, with the great benefit that it
- ;; reuses the regexp-matcher's own parser, so it understands all the
- ;; details of the syntax. A disadvantage is that it needs to match the
- ;; error string.
- (condition-case err
- (progn
- (string-match (substring regexp (or start 0) pos) "")
- t)
- (invalid-regexp
- (not (member (cadr err) '("Unmatched [ or [^"
- "Unmatched \\{"
- "Trailing backslash")))))
- ;; An alternative implementation:
- ;; (defconst re-context-re
- ;; (let* ((harmless-ch "[^\\[]")
- ;; (harmless-esc "\\\\[^{]")
- ;; (class-harmless-ch "[^][]")
- ;; (class-lb-harmless "[^]:]")
- ;; (class-lb-colon-maybe-charclass ":\\([a-z]+:]\\)?")
- ;; (class-lb (concat "\\[\\(" class-lb-harmless
- ;; "\\|" class-lb-colon-maybe-charclass "\\)"))
- ;; (class
- ;; (concat "\\[^?]?"
- ;; "\\(" class-harmless-ch
- ;; "\\|" class-lb "\\)*"
- ;; "\\[?]")) ; special handling for bare [ at end of re
- ;; (braces "\\\\{[0-9,]+\\\\}"))
- ;; (concat "\\`\\(" harmless-ch "\\|" harmless-esc
- ;; "\\|" class "\\|" braces "\\)*\\'"))
- ;; "Matches any prefix that corresponds to a normal subregexp context.")
- ;; (string-match re-context-re (substring regexp (or start 0) pos))
- )
-
-;;;; split-string
-
-(defconst split-string-default-separators "[ \f\t\n\r\v]+"
- "The default value of separators for `split-string'.
-
-A regexp matching strings of whitespace. May be locale-dependent
-\(as yet unimplemented). Should not match non-breaking spaces.
-
-Warning: binding this to a different value and using it as default is
-likely to have undesired semantics.")
-
-;; The specification says that if both SEPARATORS and OMIT-NULLS are
-;; defaulted, OMIT-NULLS should be treated as t. Simplifying the logical
-;; expression leads to the equivalent implementation that if SEPARATORS
-;; is defaulted, OMIT-NULLS is treated as t.
-(defun split-string (string &optional separators omit-nulls trim)
- "Split STRING into substrings bounded by matches for SEPARATORS.
-
-The beginning and end of STRING, and each match for SEPARATORS, are
-splitting points. The substrings matching SEPARATORS are removed, and
-the substrings between the splitting points are collected as a list,
-which is returned.
-
-If SEPARATORS is non-nil, it should be a regular expression matching text
-which separates, but is not part of, the substrings. If nil it defaults to
-`split-string-default-separators', normally \"[ \\f\\t\\n\\r\\v]+\", and
-OMIT-NULLS is forced to t.
-
-If OMIT-NULLS is t, zero-length substrings are omitted from the list (so
-that for the default value of SEPARATORS leading and trailing whitespace
-are effectively trimmed). If nil, all zero-length substrings are retained,
-which correctly parses CSV format, for example.
-
-If TRIM is non-nil, it should be a regular expression to match
-text to trim from the beginning and end of each substring. If trimming
-makes the substring empty, it is treated as null.
-
-If you want to trim whitespace from the substrings, the reliably correct
-way is using TRIM. Making SEPARATORS match that whitespace gives incorrect
-results when there is whitespace at the start or end of STRING. If you
-see such calls to `split-string', please fix them.
-
-Note that the effect of `(split-string STRING)' is the same as
-`(split-string STRING split-string-default-separators t)'. In the rare
-case that you wish to retain zero-length substrings when splitting on
-whitespace, use `(split-string STRING split-string-default-separators)'.
-
-Modifies the match data; use `save-match-data' if necessary."
- (let* ((keep-nulls (not (if separators omit-nulls t)))
- (rexp (or separators split-string-default-separators))
- (start 0)
- this-start this-end
- notfirst
- (list nil)
- (push-one
- ;; Push the substring in range THIS-START to THIS-END
- ;; onto LIST, trimming it and perhaps discarding it.
- (lambda ()
- (when trim
- ;; Discard the trim from start of this substring.
- (let ((tem (string-match trim string this-start)))
- (and (eq tem this-start)
- (setq this-start (match-end 0)))))
-
- (when (or keep-nulls (< this-start this-end))
- (let ((this (substring string this-start this-end)))
-
- ;; Discard the trim from end of this substring.
- (when trim
- (let ((tem (string-match (concat trim "\\'") this 0)))
- (and tem (< tem (length this))
- (setq this (substring this 0 tem)))))
-
- ;; Trimming could make it empty; check again.
- (when (or keep-nulls (> (length this) 0))
- (push this list)))))))
-
- (while (and (string-match rexp string
- (if (and notfirst
- (= start (match-beginning 0))
- (< start (length string)))
- (1+ start) start))
- (< start (length string)))
- (setq notfirst t)
- (setq this-start start this-end (match-beginning 0)
- start (match-end 0))
-
- (funcall push-one))
-
- ;; Handle the substring at the end of STRING.
- (setq this-start start this-end (length string))
- (funcall push-one)
-
- (nreverse list)))
-
-(defun combine-and-quote-strings (strings &optional separator)
- "Concatenate the STRINGS, adding the SEPARATOR (default \" \").
-This tries to quote the strings to avoid ambiguity such that
- (split-string-and-unquote (combine-and-quote-strings strs)) == strs
-Only some SEPARATORs will work properly."
- (let* ((sep (or separator " "))
- (re (concat "[\\\"]" "\\|" (regexp-quote sep))))
- (mapconcat
- (lambda (str)
- (if (string-match re str)
- (concat "\"" (replace-regexp-in-string "[\\\"]" "\\\\\\&" str) "\"")
- str))
- strings sep)))
-
-(defun split-string-and-unquote (string &optional separator)
- "Split the STRING into a list of strings.
-It understands Emacs Lisp quoting within STRING, such that
- (split-string-and-unquote (combine-and-quote-strings strs)) == strs
-The SEPARATOR regexp defaults to \"\\s-+\"."
- (let ((sep (or separator "\\s-+"))
- (i (string-match "\"" string)))
- (if (null i)
- (split-string string sep t) ; no quoting: easy
- (append (unless (eq i 0) (split-string (substring string 0 i) sep t))
- (let ((rfs (read-from-string string i)))
- (cons (car rfs)
- (split-string-and-unquote (substring string (cdr rfs))
- sep)))))))
-
-
-;;;; Replacement in strings.
-
-(defun subst-char-in-string (fromchar tochar string &optional inplace)
- "Replace FROMCHAR with TOCHAR in STRING each time it occurs.
-Unless optional argument INPLACE is non-nil, return a new string."
- (let ((i (length string))
- (newstr (if inplace string (copy-sequence string))))
- (while (> i 0)
- (setq i (1- i))
- (if (eq (aref newstr i) fromchar)
- (aset newstr i tochar)))
- newstr))
-
-(defun replace-regexp-in-string (regexp rep string &optional
- fixedcase literal subexp start)
- "Replace all matches for REGEXP with REP in STRING.
-
-Return a new string containing the replacements.
-
-Optional arguments FIXEDCASE, LITERAL and SUBEXP are like the
-arguments with the same names of function `replace-match'. If START
-is non-nil, start replacements at that index in STRING.
-
-REP is either a string used as the NEWTEXT arg of `replace-match' or a
-function. If it is a function, it is called with the actual text of each
-match, and its value is used as the replacement text. When REP is called,
-the match data are the result of matching REGEXP against a substring
-of STRING.
-
-To replace only the first match (if any), make REGEXP match up to \\'
-and replace a sub-expression, e.g.
- (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\'\" \"bar\" \" foo foo\" nil
nil 1)
- => \" bar foo\""
-
- ;; To avoid excessive consing from multiple matches in long strings,
- ;; don't just call `replace-match' continually. Walk down the
- ;; string looking for matches of REGEXP and building up a (reversed)
- ;; list MATCHES. This comprises segments of STRING which weren't
- ;; matched interspersed with replacements for segments that were.
- ;; [For a `large' number of replacements it's more efficient to
- ;; operate in a temporary buffer; we can't tell from the function's
- ;; args whether to choose the buffer-based implementation, though it
- ;; might be reasonable to do so for long enough STRING.]
- (let ((l (length string))
- (start (or start 0))
- matches str mb me)
- (save-match-data
- (while (and (< start l) (string-match regexp string start))
- (setq mb (match-beginning 0)
- me (match-end 0))
- ;; If we matched the empty string, make sure we advance by one char
- (when (= me mb) (setq me (min l (1+ mb))))
- ;; Generate a replacement for the matched substring.
- ;; Operate only on the substring to minimize string consing.
- ;; Set up match data for the substring for replacement;
- ;; presumably this is likely to be faster than munging the
- ;; match data directly in Lisp.
- (string-match regexp (setq str (substring string mb me)))
- (setq matches
- (cons (replace-match (if (stringp rep)
- rep
- (funcall rep (match-string 0 str)))
- fixedcase literal str subexp)
- (cons (substring string start mb) ; unmatched prefix
- matches)))
- (setq start me))
- ;; Reconstruct a string from the pieces.
- (setq matches (cons (substring string start l) matches)) ; leftover
- (apply #'concat (nreverse matches)))))
-
-(defun string-prefix-p (str1 str2 &optional ignore-case)
- "Return non-nil if STR1 is a prefix of STR2.
-If IGNORE-CASE is non-nil, the comparison is done without paying attention
-to case differences."
- (eq t (compare-strings str1 nil nil
- str2 0 (length str1) ignore-case)))
-
-(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)))))
-
-(defun bidi-string-mark-left-to-right (str)
- "Return a string that can be safely inserted in left-to-right text.
-
-Normally, inserting a string with right-to-left (RTL) script into
-a buffer may cause some subsequent text to be displayed as part
-of the RTL segment (usually this affects punctuation characters).
-This function returns a string which displays as STR but forces
-subsequent text to be displayed as left-to-right.
-
-If STR contains any RTL character, this function returns a string
-consisting of STR followed by an invisible left-to-right mark
-\(LRM) character. Otherwise, it returns STR."
- (unless (stringp str)
- (signal 'wrong-type-argument (list 'stringp str)))
- (if (string-match "\\cR" str)
- (concat str (propertize (string ?\x200e) 'invisible t))
- str))
-
-;;;; Specifying things to do later.
-
-(defun load-history-regexp (file)
- "Form a regexp to find FILE in `load-history'.
-FILE, a string, is described in the function `eval-after-load'."
- (if (file-name-absolute-p file)
- (setq file (file-truename file)))
- (concat (if (file-name-absolute-p file) "\\`" "\\(\\`\\|/\\)")
- (regexp-quote file)
- (if (file-name-extension file)
- ""
- ;; Note: regexp-opt can't be used here, since we need to call
- ;; this before Emacs has been fully started. 2006-05-21
- (concat "\\(" (mapconcat 'regexp-quote load-suffixes "\\|") "\\)?"))
- "\\(" (mapconcat 'regexp-quote jka-compr-load-suffixes "\\|")
- "\\)?\\'"))
-
-(defun load-history-filename-element (file-regexp)
- "Get the first elt of `load-history' whose car matches FILE-REGEXP.
-Return nil if there isn't one."
- (let* ((loads load-history)
- (load-elt (and loads (car loads))))
- (save-match-data
- (while (and loads
- (or (null (car load-elt))
- (not (string-match file-regexp (car load-elt)))))
- (setq loads (cdr loads)
- load-elt (and loads (car loads)))))
- load-elt))
-
-(put 'eval-after-load 'lisp-indent-function 1)
-(defun eval-after-load (file form)
- "Arrange that if FILE is loaded, FORM will be run immediately afterwards.
-If FILE is already loaded, evaluate FORM right now.
-FORM can be an Elisp expression (in which case it's passed to `eval'),
-or a function (in which case it's passed to `funcall' with no argument).
-
-If a matching file is loaded again, FORM will be evaluated again.
-
-If FILE is a string, it may be either an absolute or a relative file
-name, and may have an extension (e.g. \".el\") or may lack one, and
-additionally may or may not have an extension denoting a compressed
-format (e.g. \".gz\").
-
-When FILE is absolute, this first converts it to a true name by chasing
-symbolic links. Only a file of this name (see next paragraph regarding
-extensions) will trigger the evaluation of FORM. When FILE is relative,
-a file whose absolute true name ends in FILE will trigger evaluation.
-
-When FILE lacks an extension, a file name with any extension will trigger
-evaluation. Otherwise, its extension must match FILE's. A further
-extension for a compressed format (e.g. \".gz\") on FILE will not affect
-this name matching.
-
-Alternatively, FILE can be a feature (i.e. a symbol), in which case FORM
-is evaluated at the end of any file that `provide's this feature.
-If the feature is provided when evaluating code not associated with a
-file, FORM is evaluated immediately after the provide statement.
-
-Usually FILE is just a library name like \"font-lock\" or a feature name
-like 'font-lock.
-
-This function makes or adds to an entry on `after-load-alist'."
- (declare (compiler-macro
- (lambda (whole)
- (if (eq 'quote (car-safe form))
- ;; Quote with lambda so the compiler can look inside.
- `(eval-after-load ,file (lambda () ,(nth 1 form)))
- whole))))
- ;; Add this FORM into after-load-alist (regardless of whether we'll be
- ;; evaluating it now).
- (let* ((regexp-or-feature
- (if (stringp file)
- (setq file (purecopy (load-history-regexp file)))
- file))
- (elt (assoc regexp-or-feature after-load-alist))
- (func
- (if (functionp form) form
- ;; Try to use the "current" lexical/dynamic mode for `form'.
- (eval `(lambda () ,form) lexical-binding))))
- (unless elt
- (setq elt (list regexp-or-feature))
- (push elt after-load-alist))
- ;; Is there an already loaded file whose name (or `provide' name)
- ;; matches FILE?
- (prog1 (if (if (stringp file)
- (load-history-filename-element regexp-or-feature)
- (featurep file))
- (funcall func))
- (let ((delayed-func
- (if (not (symbolp regexp-or-feature)) func
- ;; For features, the after-load-alist elements get run when
- ;; `provide' is called rather than at the end of the file.
- ;; So add an indirection to make sure that `func' is really run
- ;; "after-load" in case the provide call happens early.
- (lambda ()
- (if (not load-file-name)
- ;; Not being provided from a file, run func right now.
- (funcall func)
- (let ((lfn load-file-name)
- ;; Don't use letrec, because equal (in
- ;; add/remove-hook) would get trapped in a cycle.
- (fun (make-symbol "eval-after-load-helper")))
- (fset fun (lambda (file)
- (when (equal file lfn)
- (remove-hook 'after-load-functions fun)
- (funcall func))))
- (add-hook 'after-load-functions fun 'append)))))))
- ;; Add FORM to the element unless it's already there.
- (unless (member delayed-func (cdr elt))
- (nconc elt (list delayed-func)))))))
-
-(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."
- (declare (indent 1) (debug t))
- `(eval-after-load ,file (lambda () ,@body)))
-
-(defvar after-load-functions nil
- "Special hook run after loading a file.
-Each function there is called with a single argument, the absolute
-name of the file just loaded.")
-
-(defun do-after-load-evaluation (abs-file)
- "Evaluate all `eval-after-load' forms, if any, for ABS-FILE.
-ABS-FILE, a string, should be the absolute true name of a file just loaded.
-This function is called directly from the C code."
- ;; Run the relevant eval-after-load forms.
- (dolist (a-l-element after-load-alist)
- (when (and (stringp (car a-l-element))
- (string-match-p (car a-l-element) abs-file))
- ;; discard the file name regexp
- (mapc #'funcall (cdr a-l-element))))
- ;; Complain when the user uses obsolete files.
- (when (string-match-p "/obsolete/[^/]*\\'" abs-file)
- ;; Maybe we should just use display-warning? This seems yucky...
- (let* ((file (file-name-nondirectory abs-file))
- (msg (format "Package %s is obsolete!"
- (substring file 0
- (string-match "\\.elc?\\>" file)))))
- ;; Cribbed from cl--compiling-file.
- (if (and (boundp 'byte-compile--outbuffer)
- (bufferp (symbol-value 'byte-compile--outbuffer))
- (equal (buffer-name (symbol-value 'byte-compile--outbuffer))
- " *Compiler Output*"))
- ;; Don't warn about obsolete files using other obsolete files.
- (unless (and (stringp byte-compile-current-file)
- (string-match-p "/obsolete/[^/]*\\'"
- (expand-file-name
- byte-compile-current-file
- byte-compile-root-dir)))
- (byte-compile-log-warning msg))
- (run-with-timer 0 nil
- (lambda (msg)
- (message "%s" msg)) msg))))
-
- ;; Finally, run any other hook.
- (run-hook-with-args 'after-load-functions abs-file))
-
-(defun eval-next-after-load (file)
- "Read the following input sexp, and run it whenever FILE is loaded.
-This makes or adds to an entry on `after-load-alist'.
-FILE should be the name of a library, with no directory name."
- (declare (obsolete eval-after-load "23.2"))
- (eval-after-load file (read)))
-
-
-(defun display-delayed-warnings ()
- "Display delayed warnings from `delayed-warnings-list'.
-Used from `delayed-warnings-hook' (which see)."
- (dolist (warning (nreverse delayed-warnings-list))
- (apply 'display-warning warning))
- (setq delayed-warnings-list nil))
-
-(defun collapse-delayed-warnings ()
- "Remove duplicates from `delayed-warnings-list'.
-Collapse identical adjacent warnings into one (plus count).
-Used from `delayed-warnings-hook' (which see)."
- (let ((count 1)
- collapsed warning)
- (while delayed-warnings-list
- (setq warning (pop delayed-warnings-list))
- (if (equal warning (car delayed-warnings-list))
- (setq count (1+ count))
- (when (> count 1)
- (setcdr warning (cons (format "%s [%d times]" (cadr warning) count)
- (cddr warning)))
- (setq count 1))
- (push warning collapsed)))
- (setq delayed-warnings-list (nreverse collapsed))))
-
-;; At present this is only used for Emacs internals.
-;; Ref http://lists.gnu.org/archive/html/emacs-devel/2012-02/msg00085.html
-(defvar delayed-warnings-hook '(collapse-delayed-warnings
- display-delayed-warnings)
- "Normal hook run to process and display delayed warnings.
-By default, this hook contains functions to consolidate the
-warnings listed in `delayed-warnings-list', display them, and set
-`delayed-warnings-list' back to nil.")
-
-(defun delay-warning (type message &optional level buffer-name)
- "Display a delayed warning.
-Aside from going through `delayed-warnings-list', this is equivalent
-to `display-warning'."
- (push (list type message level buffer-name) delayed-warnings-list))
-
-
-;;;; invisibility specs
-
-(defun add-to-invisibility-spec (element)
- "Add ELEMENT to `buffer-invisibility-spec'.
-See documentation for `buffer-invisibility-spec' for the kind of elements
-that can be added."
- (if (eq buffer-invisibility-spec t)
- (setq buffer-invisibility-spec (list t)))
- (setq buffer-invisibility-spec
- (cons element buffer-invisibility-spec)))
-
-(defun remove-from-invisibility-spec (element)
- "Remove ELEMENT from `buffer-invisibility-spec'."
- (if (consp buffer-invisibility-spec)
- (setq buffer-invisibility-spec
- (delete element buffer-invisibility-spec))))
-
-;;;; Syntax tables.
-
-(defmacro with-syntax-table (table &rest body)
- "Evaluate BODY with syntax table of current buffer set to TABLE.
-The syntax table of the current buffer is saved, BODY is evaluated, and the
-saved table is restored, even in case of an abnormal exit.
-Value is what BODY returns."
- (declare (debug t) (indent 1))
- (let ((old-table (make-symbol "table"))
- (old-buffer (make-symbol "buffer")))
- `(let ((,old-table (syntax-table))
- (,old-buffer (current-buffer)))
- (unwind-protect
- (progn
- (set-syntax-table ,table)
- ,@body)
- (save-current-buffer
- (set-buffer ,old-buffer)
- (set-syntax-table ,old-table))))))
-
-(defun make-syntax-table (&optional oldtable)
- "Return a new syntax table.
-Create a syntax table which inherits from OLDTABLE (if non-nil) or
-from `standard-syntax-table' otherwise."
- (let ((table (make-char-table 'syntax-table nil)))
- (set-char-table-parent table (or oldtable (standard-syntax-table)))
- table))
-
-(defun syntax-after (pos)
- "Return the raw syntax descriptor for the char after POS.
-If POS is outside the buffer's accessible portion, return nil."
- (unless (or (< pos (point-min)) (>= pos (point-max)))
- (let ((st (if parse-sexp-lookup-properties
- (get-char-property pos 'syntax-table))))
- (if (consp st) st
- (aref (or st (syntax-table)) (char-after pos))))))
-
-(defun syntax-class (syntax)
- "Return the code for the syntax class described by SYNTAX.
-
-SYNTAX should be a raw syntax descriptor; the return value is a
-integer which encodes the corresponding syntax class. See Info
-node `(elisp)Syntax Table Internals' for a list of codes.
-
-If SYNTAX is nil, return nil."
- (and syntax (logand (car syntax) 65535)))
-
-;; Utility motion commands
-
-;; Whitespace
-
-(defun forward-whitespace (arg)
- "Move point to the end of the next sequence of whitespace chars.
-Each such sequence may be a single newline, or a sequence of
-consecutive space and/or tab characters.
-With prefix argument ARG, do it ARG times if positive, or move
-backwards ARG times if negative."
- (interactive "^p")
- (if (natnump arg)
- (re-search-forward "[ \t]+\\|\n" nil 'move arg)
- (while (< arg 0)
- (if (re-search-backward "[ \t]+\\|\n" nil 'move)
- (or (eq (char-after (match-beginning 0)) ?\n)
- (skip-chars-backward " \t")))
- (setq arg (1+ arg)))))
-
-;; Symbols
-
-(defun forward-symbol (arg)
- "Move point to the next position that is the end of a symbol.
-A symbol is any sequence of characters that are in either the
-word constituent or symbol constituent syntax class.
-With prefix argument ARG, do it ARG times if positive, or move
-backwards ARG times if negative."
- (interactive "^p")
- (if (natnump arg)
- (re-search-forward "\\(\\sw\\|\\s_\\)+" nil 'move arg)
- (while (< arg 0)
- (if (re-search-backward "\\(\\sw\\|\\s_\\)+" nil 'move)
- (skip-syntax-backward "w_"))
- (setq arg (1+ arg)))))
-
-;; Syntax blocks
-
-(defun forward-same-syntax (&optional arg)
- "Move point past all characters with the same syntax class.
-With prefix argument ARG, do it ARG times if positive, or move
-backwards ARG times if negative."
- (interactive "^p")
- (or arg (setq arg 1))
- (while (< arg 0)
- (skip-syntax-backward
- (char-to-string (char-syntax (char-before))))
- (setq arg (1+ arg)))
- (while (> arg 0)
- (skip-syntax-forward (char-to-string (char-syntax (char-after))))
- (setq arg (1- arg))))
-
-
-;;;; Text clones
-
-(defvar text-clone--maintaining nil)
-
-(defun text-clone--maintain (ol1 after beg end &optional _len)
- "Propagate the changes made under the overlay OL1 to the other clones.
-This is used on the `modification-hooks' property of text clones."
- (when (and after (not undo-in-progress)
- (not text-clone--maintaining)
- (overlay-start ol1))
- (let ((margin (if (overlay-get ol1 'text-clone-spreadp) 1 0)))
- (setq beg (max beg (+ (overlay-start ol1) margin)))
- (setq end (min end (- (overlay-end ol1) margin)))
- (when (<= beg end)
- (save-excursion
- (when (overlay-get ol1 'text-clone-syntax)
- ;; Check content of the clone's text.
- (let ((cbeg (+ (overlay-start ol1) margin))
- (cend (- (overlay-end ol1) margin)))
- (goto-char cbeg)
- (save-match-data
- (if (not (re-search-forward
- (overlay-get ol1 'text-clone-syntax) cend t))
- ;; Mark the overlay for deletion.
- (setq end cbeg)
- (when (< (match-end 0) cend)
- ;; Shrink the clone at its end.
- (setq end (min end (match-end 0)))
- (move-overlay ol1 (overlay-start ol1)
- (+ (match-end 0) margin)))
- (when (> (match-beginning 0) cbeg)
- ;; Shrink the clone at its beginning.
- (setq beg (max (match-beginning 0) beg))
- (move-overlay ol1 (- (match-beginning 0) margin)
- (overlay-end ol1)))))))
- ;; Now go ahead and update the clones.
- (let ((head (- beg (overlay-start ol1)))
- (tail (- (overlay-end ol1) end))
- (str (buffer-substring beg end))
- (nothing-left t)
- (text-clone--maintaining t))
- (dolist (ol2 (overlay-get ol1 'text-clones))
- (let ((oe (overlay-end ol2)))
- (unless (or (eq ol1 ol2) (null oe))
- (setq nothing-left nil)
- (let ((mod-beg (+ (overlay-start ol2) head)))
- ;;(overlay-put ol2 'modification-hooks nil)
- (goto-char (- (overlay-end ol2) tail))
- (unless (> mod-beg (point))
- (save-excursion (insert str))
- (delete-region mod-beg (point)))
- ;;(overlay-put ol2 'modification-hooks
'(text-clone--maintain))
- ))))
- (if nothing-left (delete-overlay ol1))))))))
-
-(defun text-clone-create (start end &optional spreadp syntax)
- "Create a text clone of START...END at point.
-Text clones are chunks of text that are automatically kept identical:
-changes done to one of the clones will be immediately propagated to the other.
-
-The buffer's content at point is assumed to be already identical to
-the one between START and END.
-If SYNTAX is provided it's a regexp that describes the possible text of
-the clones; the clone will be shrunk or killed if necessary to ensure that
-its text matches the regexp.
-If SPREADP is non-nil it indicates that text inserted before/after the
-clone should be incorporated in the clone."
- ;; To deal with SPREADP we can either use an overlay with `nil t' along
- ;; with insert-(behind|in-front-of)-hooks or use a slightly larger overlay
- ;; (with a one-char margin at each end) with `t nil'.
- ;; We opted for a larger overlay because it behaves better in the case
- ;; where the clone is reduced to the empty string (we want the overlay to
- ;; stay when the clone's content is the empty string and we want to use
- ;; `evaporate' to make sure those overlays get deleted when needed).
- ;;
- (let* ((pt-end (+ (point) (- end start)))
- (start-margin (if (or (not spreadp) (bobp) (<= start (point-min)))
- 0 1))
- (end-margin (if (or (not spreadp)
- (>= pt-end (point-max))
- (>= start (point-max)))
- 0 1))
- ;; FIXME: Reuse overlays at point to extend dups!
- (ol1 (make-overlay (- start start-margin) (+ end end-margin) nil t))
- (ol2 (make-overlay (- (point) start-margin) (+ pt-end end-margin) nil
t))
- (dups (list ol1 ol2)))
- (overlay-put ol1 'modification-hooks '(text-clone--maintain))
- (when spreadp (overlay-put ol1 'text-clone-spreadp t))
- (when syntax (overlay-put ol1 'text-clone-syntax syntax))
- ;;(overlay-put ol1 'face 'underline)
- (overlay-put ol1 'evaporate t)
- (overlay-put ol1 'text-clones dups)
- ;;
- (overlay-put ol2 'modification-hooks '(text-clone--maintain))
- (when spreadp (overlay-put ol2 'text-clone-spreadp t))
- (when syntax (overlay-put ol2 'text-clone-syntax syntax))
- ;;(overlay-put ol2 'face 'underline)
- (overlay-put ol2 'evaporate t)
- (overlay-put ol2 'text-clones dups)))
-
-;;;; Mail user agents.
-
-;; Here we include just enough for other packages to be able
-;; to define them.
-
-(defun define-mail-user-agent (symbol composefunc sendfunc
- &optional abortfunc hookvar)
- "Define a symbol to identify a mail-sending package for `mail-user-agent'.
-
-SYMBOL can be any Lisp symbol. Its function definition and/or
-value as a variable do not matter for this usage; we use only certain
-properties on its property list, to encode the rest of the arguments.
-
-COMPOSEFUNC is program callable function that composes an outgoing
-mail message buffer. This function should set up the basics of the
-buffer without requiring user interaction. It should populate the
-standard mail headers, leaving the `to:' and `subject:' headers blank
-by default.
-
-COMPOSEFUNC should accept several optional arguments--the same
-arguments that `compose-mail' takes. See that function's documentation.
-
-SENDFUNC is the command a user would run to send the message.
-
-Optional ABORTFUNC is the command a user would run to abort the
-message. For mail packages that don't have a separate abort function,
-this can be `kill-buffer' (the equivalent of omitting this argument).
-
-Optional HOOKVAR is a hook variable that gets run before the message
-is actually sent. Callers that use the `mail-user-agent' may
-install a hook function temporarily on this hook variable.
-If HOOKVAR is nil, `mail-send-hook' is used.
-
-The properties used on SYMBOL are `composefunc', `sendfunc',
-`abortfunc', and `hookvar'."
- (put symbol 'composefunc composefunc)
- (put symbol 'sendfunc sendfunc)
- (put symbol 'abortfunc (or abortfunc 'kill-buffer))
- (put symbol 'hookvar (or hookvar 'mail-send-hook)))
-
-(defvar called-interactively-p-functions nil
- "Special hook called to skip special frames in `called-interactively-p'.
-The functions are called with 3 arguments: (I FRAME1 FRAME2),
-where FRAME1 is a \"current frame\", FRAME2 is the next frame,
-I is the index of the frame after FRAME2. It should return nil
-if those frames don't seem special and otherwise, it should return
-the number of frames to skip (minus 1).")
-
-(defconst internal--call-interactively (symbol-function 'call-interactively))
-
-(defun called-interactively-p (&optional kind)
- "Return t if the containing function was called by `call-interactively'.
-If KIND is `interactive', then only return t if the call was made
-interactively by the user, i.e. not in `noninteractive' mode nor
-when `executing-kbd-macro'.
-If KIND is `any', on the other hand, it will return t for any kind of
-interactive call, including being called as the binding of a key or
-from a keyboard macro, even in `noninteractive' mode.
-
-This function is very brittle, it may fail to return the intended result when
-the code is debugged, advised, or instrumented in some form. Some macros and
-special forms (such as `condition-case') may also sometimes wrap their bodies
-in a `lambda', so any call to `called-interactively-p' from those bodies will
-indicate whether that lambda (rather than the surrounding function) was called
-interactively.
-
-Instead of using this function, it is cleaner and more reliable to give your
-function an extra optional argument whose `interactive' spec specifies
-non-nil unconditionally (\"p\" is a good way to do this), or via
-\(not (or executing-kbd-macro noninteractive)).
-
-The only known proper use of `interactive' for KIND is in deciding
-whether to display a helpful message, or how to display it. If you're
-thinking of using it for any other purpose, it is quite likely that
-you're making a mistake. Think: what do you want to do when the
-command is called from a keyboard macro?"
- (declare (advertised-calling-convention (kind) "23.1"))
- (when (not (and (eq kind 'interactive)
- (or executing-kbd-macro noninteractive)))
- (let* ((i 1) ;; 0 is the called-interactively-p frame.
- frame nextframe
- (get-next-frame
- (lambda ()
- (setq frame nextframe)
- (setq nextframe (backtrace-frame i 'called-interactively-p))
- ;; (message "Frame %d = %S" i nextframe)
- (setq i (1+ i)))))
- (funcall get-next-frame) ;; Get the first frame.
- (while
- ;; FIXME: The edebug and advice handling should be made modular and
- ;; provided directly by edebug.el and nadvice.el.
- (progn
- ;; frame =(backtrace-frame i-2)
- ;; nextframe=(backtrace-frame i-1)
- (funcall get-next-frame)
- ;; `pcase' would be a fairly good fit here, but it sometimes moves
- ;; branches within local functions, which then messes up the
- ;; `backtrace-frame' data we get,
- (or
- ;; Skip special forms (from non-compiled code).
- (and frame (null (car frame)))
- ;; Skip also `interactive-p' (because we don't want to know if
- ;; interactive-p was called interactively but if it's caller was)
- ;; and `byte-code' (idem; this appears in subexpressions of things
- ;; like condition-case, which are wrapped in a separate bytecode
- ;; chunk).
- ;; FIXME: For lexical-binding code, this is much worse,
- ;; because the frames look like "byte-code -> funcall -> #[...]",
- ;; which is not a reliable signature.
- (memq (nth 1 frame) '(interactive-p 'byte-code))
- ;; Skip package-specific stack-frames.
- (let ((skip (run-hook-with-args-until-success
- 'called-interactively-p-functions
- i frame nextframe)))
- (pcase skip
- (`nil nil)
- (`0 t)
- (_ (setq i (+ i skip -1)) (funcall get-next-frame)))))))
- ;; Now `frame' should be "the function from which we were called".
- (pcase (cons frame nextframe)
- ;; No subr calls `interactive-p', so we can rule that out.
- (`((,_ ,(pred (lambda (f) (subrp (indirect-function f)))) . ,_) . ,_)
nil)
- ;; In case #<subr call-interactively> without going through the
- ;; `call-interactively' symbol (bug#3984).
- (`(,_ . (t ,(pred (eq internal--call-interactively)) . ,_)) t)
- (`(,_ . (t call-interactively . ,_)) t)))))
-
-(defun interactive-p ()
- "Return t if the containing function was run directly by user input.
-This means that the function was called with `call-interactively'
-\(which includes being called as the binding of a key)
-and input is currently coming from the keyboard (not a keyboard macro),
-and Emacs is not running in batch mode (`noninteractive' is nil).
-
-The only known proper use of `interactive-p' is in deciding whether to
-display a helpful message, or how to display it. If you're thinking
-of using it for any other purpose, it is quite likely that you're
-making a mistake. Think: what do you want to do when the command is
-called from a keyboard macro or in batch mode?
-
-To test whether your function was called with `call-interactively',
-either (i) add an extra optional argument and give it an `interactive'
-spec that specifies non-nil unconditionally (such as \"p\"); or (ii)
-use `called-interactively-p'."
- (declare (obsolete called-interactively-p "23.2"))
- (called-interactively-p 'interactive))
-
-(defun internal-push-keymap (keymap symbol)
- (let ((map (symbol-value symbol)))
- (unless (memq keymap map)
- (unless (memq 'add-keymap-witness (symbol-value symbol))
- (setq map (make-composed-keymap nil (symbol-value symbol)))
- (push 'add-keymap-witness (cdr map))
- (set symbol map))
- (push keymap (cdr map)))))
-
-(defun internal-pop-keymap (keymap symbol)
- (let ((map (symbol-value symbol)))
- (when (memq keymap map)
- (setf (cdr map) (delq keymap (cdr map))))
- (let ((tail (cddr map)))
- (and (or (null tail) (keymapp tail))
- (eq 'add-keymap-witness (nth 1 map))
- (set symbol tail)))))
-
-(define-obsolete-function-alias
- 'set-temporary-overlay-map 'set-transient-map "24.4")
-
-(defun set-transient-map (map &optional keep-pred on-exit)
- "Set MAP as a temporary keymap taking precedence over other keymaps.
-Normally, MAP is used only once, to look up the very next key.
-However, if the optional argument KEEP-PRED is t, MAP stays
-active if a key from MAP is used. KEEP-PRED can also be a
-function of no arguments: if it returns non-nil, then MAP stays
-active.
-
-Optional arg ON-EXIT, if non-nil, specifies a function that is
-called, with no arguments, after MAP is deactivated.
-
-This uses `overriding-terminal-local-map' which takes precedence over all other
-keymaps. As usual, if no match for a key is found in MAP, the normal key
-lookup sequence then continues."
- (let ((clearfun (make-symbol "clear-transient-map")))
- ;; Don't use letrec, because equal (in add/remove-hook) would get trapped
- ;; in a cycle.
- (fset clearfun
- (lambda ()
- (with-demoted-errors "set-transient-map PCH: %S"
- (unless (cond
- ((null keep-pred) nil)
- ((not (eq map (cadr overriding-terminal-local-map)))
- ;; There's presumably some other transient-map in
- ;; effect. Wait for that one to terminate before we
- ;; remove ourselves.
- ;; For example, if isearch and C-u both use transient
- ;; maps, then the lifetime of the C-u should be nested
- ;; within isearch's, so the pre-command-hook of
- ;; isearch should be suspended during the C-u one so
- ;; we don't exit isearch just because we hit 1 after
- ;; C-u and that 1 exits isearch whereas it doesn't
- ;; exit C-u.
- t)
- ((eq t keep-pred)
- (eq this-command
- (lookup-key map (this-command-keys-vector))))
- (t (funcall keep-pred)))
- (internal-pop-keymap map 'overriding-terminal-local-map)
- (remove-hook 'pre-command-hook clearfun)
- (when on-exit (funcall on-exit))))))
- (add-hook 'pre-command-hook clearfun)
- (internal-push-keymap map 'overriding-terminal-local-map)))
-
-;;;; Progress reporters.
-
-;; Progress reporter has the following structure:
-;;
-;; (NEXT-UPDATE-VALUE . [NEXT-UPDATE-TIME
-;; MIN-VALUE
-;; MAX-VALUE
-;; MESSAGE
-;; MIN-CHANGE
-;; MIN-TIME])
-;;
-;; This weirdness is for optimization reasons: we want
-;; `progress-reporter-update' to be as fast as possible, so
-;; `(car reporter)' is better than `(aref reporter 0)'.
-;;
-;; NEXT-UPDATE-TIME is a float. While `float-time' loses a couple
-;; digits of precision, it doesn't really matter here. On the other
-;; hand, it greatly simplifies the code.
-
-(defsubst progress-reporter-update (reporter &optional value)
- "Report progress of an operation in the echo area.
-REPORTER should be the result of a call to `make-progress-reporter'.
-
-If REPORTER is a numerical progress reporter---i.e. if it was
- made using non-nil MIN-VALUE and MAX-VALUE arguments to
- `make-progress-reporter'---then VALUE should be a number between
- MIN-VALUE and MAX-VALUE.
-
-If REPORTER is a non-numerical reporter, VALUE should be nil.
-
-This function is relatively inexpensive. If the change since
-last update is too small or insufficient time has passed, it does
-nothing."
- (when (or (not (numberp value)) ; For pulsing reporter
- (>= value (car reporter))) ; For numerical reporter
- (progress-reporter-do-update reporter value)))
-
-(defun make-progress-reporter (message &optional min-value max-value
- current-value min-change min-time)
- "Return progress reporter object for use with `progress-reporter-update'.
-
-MESSAGE is shown in the echo area, with a status indicator
-appended to the end. When you call `progress-reporter-done', the
-word \"done\" is printed after the MESSAGE. You can change the
-MESSAGE of an existing progress reporter by calling
-`progress-reporter-force-update'.
-
-MIN-VALUE and MAX-VALUE, if non-nil, are starting (0% complete)
-and final (100% complete) states of operation; the latter should
-be larger. In this case, the status message shows the percentage
-progress.
-
-If MIN-VALUE and/or MAX-VALUE is omitted or nil, the status
-message shows a \"spinning\", non-numeric indicator.
-
-Optional CURRENT-VALUE is the initial progress; the default is
-MIN-VALUE.
-Optional MIN-CHANGE is the minimal change in percents to report;
-the default is 1%.
-CURRENT-VALUE and MIN-CHANGE do not have any effect if MIN-VALUE
-and/or MAX-VALUE are nil.
-
-Optional MIN-TIME specifies the minimum interval time between
-echo area updates (default is 0.2 seconds.) If the function
-`float-time' is not present, time is not tracked at all. If the
-OS is not capable of measuring fractions of seconds, this
-parameter is effectively rounded up."
- (when (string-match "[[:alnum:]]\\'" message)
- (setq message (concat message "...")))
- (unless min-time
- (setq min-time 0.2))
- (let ((reporter
- ;; Force a call to `message' now
- (cons (or min-value 0)
- (vector (if (and (fboundp 'float-time)
- (>= min-time 0.02))
- (float-time) nil)
- min-value
- max-value
- message
- (if min-change (max (min min-change 50) 1) 1)
- min-time))))
- (progress-reporter-update reporter (or current-value min-value))
- reporter))
-
-(defun progress-reporter-force-update (reporter &optional value new-message)
- "Report progress of an operation in the echo area unconditionally.
-
-The first two arguments are the same as in `progress-reporter-update'.
-NEW-MESSAGE, if non-nil, sets a new message for the reporter."
- (let ((parameters (cdr reporter)))
- (when new-message
- (aset parameters 3 new-message))
- (when (aref parameters 0)
- (aset parameters 0 (float-time)))
- (progress-reporter-do-update reporter value)))
-
-(defvar progress-reporter--pulse-characters ["-" "\\" "|" "/"]
- "Characters to use for pulsing progress reporters.")
-
-(defun progress-reporter-do-update (reporter value)
- (let* ((parameters (cdr reporter))
- (update-time (aref parameters 0))
- (min-value (aref parameters 1))
- (max-value (aref parameters 2))
- (text (aref parameters 3))
- (current-time (float-time))
- (enough-time-passed
- ;; See if enough time has passed since the last update.
- (or (not update-time)
- (when (>= current-time update-time)
- ;; Calculate time for the next update
- (aset parameters 0 (+ update-time (aref parameters 5)))))))
- (cond ((and min-value max-value)
- ;; Numerical indicator
- (let* ((one-percent (/ (- max-value min-value) 100.0))
- (percentage (if (= max-value min-value)
- 0
- (truncate (/ (- value min-value)
- one-percent)))))
- ;; Calculate NEXT-UPDATE-VALUE. If we are not printing
- ;; message because not enough time has passed, use 1
- ;; instead of MIN-CHANGE. This makes delays between echo
- ;; area updates closer to MIN-TIME.
- (setcar reporter
- (min (+ min-value (* (+ percentage
- (if enough-time-passed
- ;; MIN-CHANGE
- (aref parameters 4)
- 1))
- one-percent))
- max-value))
- (when (integerp value)
- (setcar reporter (ceiling (car reporter))))
- ;; Only print message if enough time has passed
- (when enough-time-passed
- (if (> percentage 0)
- (message "%s%d%%" text percentage)
- (message "%s" text)))))
- ;; Pulsing indicator
- (enough-time-passed
- (let ((index (mod (1+ (car reporter)) 4))
- (message-log-max nil))
- (setcar reporter index)
- (message "%s %s"
- text
- (aref progress-reporter--pulse-characters
- index)))))))
-
-(defun progress-reporter-done (reporter)
- "Print reporter's message followed by word \"done\" in echo area."
- (message "%sdone" (aref (cdr reporter) 3)))
-
-(defmacro dotimes-with-progress-reporter (spec message &rest body)
- "Loop a certain number of times and report progress in the echo area.
-Evaluate BODY with VAR bound to successive integers running from
-0, inclusive, to COUNT, exclusive. Then evaluate RESULT to get
-the return value (nil if RESULT is omitted).
-
-At each iteration MESSAGE followed by progress percentage is
-printed in the echo area. After the loop is finished, MESSAGE
-followed by word \"done\" is printed. This macro is a
-convenience wrapper around `make-progress-reporter' and friends.
-
-\(fn (VAR COUNT [RESULT]) MESSAGE BODY...)"
- (declare (indent 2) (debug ((symbolp form &optional form) form body)))
- (let ((temp (make-symbol "--dotimes-temp--"))
- (temp2 (make-symbol "--dotimes-temp2--"))
- (start 0)
- (end (nth 1 spec)))
- `(let ((,temp ,end)
- (,(car spec) ,start)
- (,temp2 (make-progress-reporter ,message ,start ,end)))
- (while (< ,(car spec) ,temp)
- ,@body
- (progress-reporter-update ,temp2
- (setq ,(car spec) (1+ ,(car spec)))))
- (progress-reporter-done ,temp2)
- nil ,@(cdr (cdr spec)))))
-
-
-;;;; Comparing version strings.
-
-(defconst version-separator "."
- "Specify the string used to separate the version elements.
-
-Usually the separator is \".\", but it can be any other string.")
-
-
-(defconst version-regexp-alist
- '(("^[-_+ ]?snapshot$" . -4)
- ;; treat "1.2.3-20050920" and "1.2-3" as snapshot releases
- ("^[-_+]$" . -4)
- ;; treat "1.2.3-CVS" as snapshot release
- ("^[-_+ ]?\\(cvs\\|git\\|bzr\\|svn\\|hg\\|darcs\\)$" . -4)
- ("^[-_+ ]?alpha$" . -3)
- ("^[-_+ ]?beta$" . -2)
- ("^[-_+ ]?\\(pre\\|rc\\)$" . -1))
- "Specify association between non-numeric version and its priority.
-
-This association is used to handle version string like \"1.0pre2\",
-\"0.9alpha1\", etc. It's used by `version-to-list' (which see) to convert the
-non-numeric part of a version string to an integer. For example:
-
- String Version Integer List Version
- \"0.9snapshot\" (0 9 -4)
- \"1.0-git\" (1 0 -4)
- \"1.0pre2\" (1 0 -1 2)
- \"1.0PRE2\" (1 0 -1 2)
- \"22.8beta3\" (22 8 -2 3)
- \"22.8 Beta3\" (22 8 -2 3)
- \"0.9alpha1\" (0 9 -3 1)
- \"0.9AlphA1\" (0 9 -3 1)
- \"0.9 alpha\" (0 9 -3)
-
-Each element has the following form:
-
- (REGEXP . PRIORITY)
-
-Where:
-
-REGEXP regexp used to match non-numeric part of a version string.
- It should begin with the `^' anchor and end with a `$' to
- prevent false hits. Letter-case is ignored while matching
- REGEXP.
-
-PRIORITY a negative integer specifying non-numeric priority of REGEXP.")
-
-
-(defun version-to-list (ver)
- "Convert version string VER into a list of integers.
-
-The version syntax is given by the following EBNF:
-
- VERSION ::= NUMBER ( SEPARATOR NUMBER )*.
-
- NUMBER ::= (0|1|2|3|4|5|6|7|8|9)+.
-
- SEPARATOR ::= `version-separator' (which see)
- | `version-regexp-alist' (which see).
-
-The NUMBER part is optional if SEPARATOR is a match for an element
-in `version-regexp-alist'.
-
-Examples of valid version syntax:
-
- 1.0pre2 1.0.7.5 22.8beta3 0.9alpha1 6.9.30Beta
-
-Examples of invalid version syntax:
-
- 1.0prepre2 1.0..7.5 22.8X3 alpha3.2 .5
-
-Examples of version conversion:
-
- Version String Version as a List of Integers
- \"1.0.7.5\" (1 0 7 5)
- \"1.0pre2\" (1 0 -1 2)
- \"1.0PRE2\" (1 0 -1 2)
- \"22.8beta3\" (22 8 -2 3)
- \"22.8Beta3\" (22 8 -2 3)
- \"0.9alpha1\" (0 9 -3 1)
- \"0.9AlphA1\" (0 9 -3 1)
- \"0.9alpha\" (0 9 -3)
- \"0.9snapshot\" (0 9 -4)
- \"1.0-git\" (1 0 -4)
-
-See documentation for `version-separator' and `version-regexp-alist'."
- (or (and (stringp ver) (> (length ver) 0))
- (error "Invalid version string: '%s'" ver))
- ;; Change .x.y to 0.x.y
- (if (and (>= (length ver) (length version-separator))
- (string-equal (substring ver 0 (length version-separator))
- version-separator))
- (setq ver (concat "0" ver)))
- (save-match-data
- (let ((i 0)
- (case-fold-search t) ; ignore case in matching
- lst s al)
- (while (and (setq s (string-match "[0-9]+" ver i))
- (= s i))
- ;; handle numeric part
- (setq lst (cons (string-to-number (substring ver i (match-end 0)))
- lst)
- i (match-end 0))
- ;; handle non-numeric part
- (when (and (setq s (string-match "[^0-9]+" ver i))
- (= s i))
- (setq s (substring ver i (match-end 0))
- i (match-end 0))
- ;; handle alpha, beta, pre, etc. separator
- (unless (string= s version-separator)
- (setq al version-regexp-alist)
- (while (and al (not (string-match (caar al) s)))
- (setq al (cdr al)))
- (cond (al
- (push (cdar al) lst))
- ;; Convert 22.3a to 22.3.1, 22.3b to 22.3.2, etc.
- ((string-match "^[-_+ ]?\\([a-zA-Z]\\)$" s)
- (push (- (aref (downcase (match-string 1 s)) 0) ?a -1)
- lst))
- (t (error "Invalid version syntax: '%s'" ver))))))
- (if (null lst)
- (error "Invalid version syntax: '%s'" ver)
- (nreverse lst)))))
-
-
-(defun version-list-< (l1 l2)
- "Return t if L1, a list specification of a version, is lower than L2.
-
-Note that a version specified by the list (1) is equal to (1 0),
-\(1 0 0), (1 0 0 0), etc. That is, the trailing zeros are insignificant.
-Also, a version given by the list (1) is higher than (1 -1), which in
-turn is higher than (1 -2), which is higher than (1 -3)."
- (while (and l1 l2 (= (car l1) (car l2)))
- (setq l1 (cdr l1)
- l2 (cdr l2)))
- (cond
- ;; l1 not null and l2 not null
- ((and l1 l2) (< (car l1) (car l2)))
- ;; l1 null and l2 null ==> l1 length = l2 length
- ((and (null l1) (null l2)) nil)
- ;; l1 not null and l2 null ==> l1 length > l2 length
- (l1 (< (version-list-not-zero l1) 0))
- ;; l1 null and l2 not null ==> l2 length > l1 length
- (t (< 0 (version-list-not-zero l2)))))
-
-
-(defun version-list-= (l1 l2)
- "Return t if L1, a list specification of a version, is equal to L2.
-
-Note that a version specified by the list (1) is equal to (1 0),
-\(1 0 0), (1 0 0 0), etc. That is, the trailing zeros are insignificant.
-Also, a version given by the list (1) is higher than (1 -1), which in
-turn is higher than (1 -2), which is higher than (1 -3)."
- (while (and l1 l2 (= (car l1) (car l2)))
- (setq l1 (cdr l1)
- l2 (cdr l2)))
- (cond
- ;; l1 not null and l2 not null
- ((and l1 l2) nil)
- ;; l1 null and l2 null ==> l1 length = l2 length
- ((and (null l1) (null l2)))
- ;; l1 not null and l2 null ==> l1 length > l2 length
- (l1 (zerop (version-list-not-zero l1)))
- ;; l1 null and l2 not null ==> l2 length > l1 length
- (t (zerop (version-list-not-zero l2)))))
-
-
-(defun version-list-<= (l1 l2)
- "Return t if L1, a list specification of a version, is lower or equal to L2.
-
-Note that integer list (1) is equal to (1 0), (1 0 0), (1 0 0 0),
-etc. That is, the trailing zeroes are insignificant. Also, integer
-list (1) is greater than (1 -1) which is greater than (1 -2)
-which is greater than (1 -3)."
- (while (and l1 l2 (= (car l1) (car l2)))
- (setq l1 (cdr l1)
- l2 (cdr l2)))
- (cond
- ;; l1 not null and l2 not null
- ((and l1 l2) (< (car l1) (car l2)))
- ;; l1 null and l2 null ==> l1 length = l2 length
- ((and (null l1) (null l2)))
- ;; l1 not null and l2 null ==> l1 length > l2 length
- (l1 (<= (version-list-not-zero l1) 0))
- ;; l1 null and l2 not null ==> l2 length > l1 length
- (t (<= 0 (version-list-not-zero l2)))))
-
-(defun version-list-not-zero (lst)
- "Return the first non-zero element of LST, which is a list of integers.
-
-If all LST elements are zeros or LST is nil, return zero."
- (while (and lst (zerop (car lst)))
- (setq lst (cdr lst)))
- (if lst
- (car lst)
- ;; there is no element different of zero
- 0))
-
-
-(defun version< (v1 v2)
- "Return t if version V1 is lower (older) than V2.
-
-Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\",
-etc. That is, the trailing \".0\"s are insignificant. Also, version
-string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
-which is higher than \"1alpha\", which is higher than \"1snapshot\".
-Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
- (version-list-< (version-to-list v1) (version-to-list v2)))
-
-(defun version<= (v1 v2)
- "Return t if version V1 is lower (older) than or equal to V2.
-
-Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\",
-etc. That is, the trailing \".0\"s are insignificant. Also, version
-string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
-which is higher than \"1alpha\", which is higher than \"1snapshot\".
-Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
- (version-list-<= (version-to-list v1) (version-to-list v2)))
-
-(defun version= (v1 v2)
- "Return t if version V1 is equal to V2.
-
-Note that version string \"1\" is equal to \"1.0\", \"1.0.0\", \"1.0.0.0\",
-etc. That is, the trailing \".0\"s are insignificant. Also, version
-string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\",
-which is higher than \"1alpha\", which is higher than \"1snapshot\".
-Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions."
- (version-list-= (version-to-list v1) (version-to-list v2)))
-
-
-;;; Misc.
-(defconst menu-bar-separator '("--")
- "Separator for menus.")
-
-;; The following statement ought to be in print.c, but `provide' can't
-;; be used there.
-;; http://lists.gnu.org/archive/html/emacs-devel/2009-08/msg00236.html
-(when (hash-table-p (car (read-from-string
- (prin1-to-string (make-hash-table)))))
- (provide 'hashtable-print-readable))
-
-;; This is used in lisp/Makefile.in and in leim/Makefile.in to
-;; generate file names for autoloads, custom-deps, and finder-data.
-(defun unmsys--file-name (file)
- "Produce the canonical file name for FILE from its MSYS form.
-
-On systems other than MS-Windows, just returns FILE.
-On MS-Windows, converts /d/foo/bar form of file names
-passed by MSYS Make into d:/foo/bar that Emacs can grok.
-
-This function is called from lisp/Makefile and leim/Makefile."
- (when (and (eq system-type 'windows-nt)
- (string-match "\\`/[a-zA-Z]/" file))
- (setq file (concat (substring file 1 2) ":" (substring file 2))))
- file)
-
-
-;;; subr.el ends here
diff --git a/packages/context-coloring/fixtures/test/README
b/packages/context-coloring/fixtures/test/README
deleted file mode 100644
index 65f3434..0000000
--- a/packages/context-coloring/fixtures/test/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Files in this directory contain text which is matched against some data in
-context-coloring-test.el. No change can be performed on one without
-matching changes to the other (not even adding/removing whitespace or
-comments).
diff --git a/packages/context-coloring/fixtures/test/block-scopes.js
b/packages/context-coloring/fixtures/test/block-scopes.js
deleted file mode 100644
index 34a40ba..0000000
--- a/packages/context-coloring/fixtures/test/block-scopes.js
+++ /dev/null
@@ -1,7 +0,0 @@
-(function () {
- if (1) {
- var a;
- let b;
- const c;
- }
-}());
diff --git a/packages/context-coloring/fixtures/test/catch.js
b/packages/context-coloring/fixtures/test/catch.js
deleted file mode 100644
index a542ce9..0000000
--- a/packages/context-coloring/fixtures/test/catch.js
+++ /dev/null
@@ -1,8 +0,0 @@
-(function () {
- try {} catch (e) {
- var a = e;
- try {} catch (e) {
- var a = e;
- }
- }
-}());
diff --git a/packages/context-coloring/fixtures/test/changed.el
b/packages/context-coloring/fixtures/test/changed.el
deleted file mode 100644
index 28c9602..0000000
--- a/packages/context-coloring/fixtures/test/changed.el
+++ /dev/null
@@ -1,5 +0,0 @@
-(l1) ; Not colored.
-(l2)
-
-(l4)
-(l5) ; Not colored.
diff --git a/packages/context-coloring/fixtures/test/comment.el
b/packages/context-coloring/fixtures/test/comment.el
deleted file mode 100644
index c3ba432..0000000
--- a/packages/context-coloring/fixtures/test/comment.el
+++ /dev/null
@@ -1,3 +0,0 @@
-(defun a ()
- (or (= token-char 96) ; 96 = '`'
- (= token-char 44))) ; 44 = ','
diff --git a/packages/context-coloring/fixtures/test/comments-and-strings.js
b/packages/context-coloring/fixtures/test/comments-and-strings.js
deleted file mode 100644
index 4297011..0000000
--- a/packages/context-coloring/fixtures/test/comments-and-strings.js
+++ /dev/null
@@ -1,4 +0,0 @@
-void 0;
-// Foo.
-/* Bar. */
-'use strict';
diff --git a/packages/context-coloring/fixtures/test/cond.el
b/packages/context-coloring/fixtures/test/cond.el
deleted file mode 100644
index d5aae5b..0000000
--- a/packages/context-coloring/fixtures/test/cond.el
+++ /dev/null
@@ -1,8 +0,0 @@
-(let (a)
- (cond
- (a t)
- (free t)
- ((eq a free) t)
- (t (list a free))
- ;; c
- "s"))
diff --git a/packages/context-coloring/fixtures/test/condition-case.el
b/packages/context-coloring/fixtures/test/condition-case.el
deleted file mode 100644
index 151f591..0000000
--- a/packages/context-coloring/fixtures/test/condition-case.el
+++ /dev/null
@@ -1,10 +0,0 @@
-(condition-case err
- (progn err free)
- (error err free)
- ((debug error) err free))
-
-(condition-case-unless-debug nil
- ;; c
- (let () nil)
- (error (let () nil))
- "s")
diff --git a/packages/context-coloring/fixtures/test/defadvice.el
b/packages/context-coloring/fixtures/test/defadvice.el
deleted file mode 100644
index da1f0eb..0000000
--- a/packages/context-coloring/fixtures/test/defadvice.el
+++ /dev/null
@@ -1,3 +0,0 @@
-(defadvice a (before advice first (b) activate)
- (let ((c b))
- (+ b c)))
diff --git a/packages/context-coloring/fixtures/test/defun.el
b/packages/context-coloring/fixtures/test/defun.el
deleted file mode 100644
index 10a52f6..0000000
--- a/packages/context-coloring/fixtures/test/defun.el
+++ /dev/null
@@ -1,8 +0,0 @@
-(defun abc (def ghi &optional jkl)
- (+ def ghi jkl free))
-
-(abc 1 2 3)
-
-(defun a)
-(defun ())
-(defun b ("a"))
diff --git a/packages/context-coloring/fixtures/test/dolist.el
b/packages/context-coloring/fixtures/test/dolist.el
deleted file mode 100644
index f103670..0000000
--- a/packages/context-coloring/fixtures/test/dolist.el
+++ /dev/null
@@ -1,3 +0,0 @@
-(lambda (list)
- (dolist (var list result)
- (lambda () (+ var list result))))
diff --git a/packages/context-coloring/fixtures/test/empty
b/packages/context-coloring/fixtures/test/empty
deleted file mode 100644
index e69de29..0000000
diff --git a/packages/context-coloring/fixtures/test/empty-varlist.el
b/packages/context-coloring/fixtures/test/empty-varlist.el
deleted file mode 100644
index 5ee6a78..0000000
--- a/packages/context-coloring/fixtures/test/empty-varlist.el
+++ /dev/null
@@ -1,6 +0,0 @@
-(lambda ( ))
-(lambda ())
-
-(let (;;
- ))
-(lambda ())
diff --git a/packages/context-coloring/fixtures/test/function-scopes.js
b/packages/context-coloring/fixtures/test/function-scopes.js
deleted file mode 100644
index 2f6ed32..0000000
--- a/packages/context-coloring/fixtures/test/function-scopes.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var a = function () {};
-function b() {
- var c = function () {};
- function d() {}
-}
diff --git a/packages/context-coloring/fixtures/test/global.js
b/packages/context-coloring/fixtures/test/global.js
deleted file mode 100644
index 3de2147..0000000
--- a/packages/context-coloring/fixtures/test/global.js
+++ /dev/null
@@ -1,3 +0,0 @@
-(function () {
- var a = global('a');
-}());
diff --git a/packages/context-coloring/fixtures/test/ignored.el
b/packages/context-coloring/fixtures/test/ignored.el
deleted file mode 100644
index 1f5fd42..0000000
--- a/packages/context-coloring/fixtures/test/ignored.el
+++ /dev/null
@@ -1,2 +0,0 @@
-(defun a ()
- (+ a 1 +1 -1 1.0 #x0 ,a \a :a t nil (0 . 0)))
diff --git a/packages/context-coloring/fixtures/test/initial-level.js
b/packages/context-coloring/fixtures/test/initial-level.js
deleted file mode 100644
index 24a4b71..0000000
--- a/packages/context-coloring/fixtures/test/initial-level.js
+++ /dev/null
@@ -1,2 +0,0 @@
-
-var a = global('a');
diff --git a/packages/context-coloring/fixtures/test/iteration.el
b/packages/context-coloring/fixtures/test/iteration.el
deleted file mode 100644
index c4e99ac..0000000
--- a/packages/context-coloring/fixtures/test/iteration.el
+++ /dev/null
@@ -1,2 +0,0 @@
-;; `aa' `bb'
-(defun a ())
diff --git a/packages/context-coloring/fixtures/test/key-names.js
b/packages/context-coloring/fixtures/test/key-names.js
deleted file mode 100644
index d8ad17c..0000000
--- a/packages/context-coloring/fixtures/test/key-names.js
+++ /dev/null
@@ -1,6 +0,0 @@
-(function () {
- return {
- a: 0,
- b : 2
- };
-}());
diff --git a/packages/context-coloring/fixtures/test/key-values.js
b/packages/context-coloring/fixtures/test/key-values.js
deleted file mode 100644
index 41bdedd..0000000
--- a/packages/context-coloring/fixtures/test/key-values.js
+++ /dev/null
@@ -1,8 +0,0 @@
-(function () {
- var a;
- (function () {
- return {
- b: a
- };
- }());
-}());
diff --git a/packages/context-coloring/fixtures/test/lambda.el
b/packages/context-coloring/fixtures/test/lambda.el
deleted file mode 100644
index 9ab7be2..0000000
--- a/packages/context-coloring/fixtures/test/lambda.el
+++ /dev/null
@@ -1,3 +0,0 @@
-(funcall (lambda (fn a)
- (funcall fn (lambda (fn)
- (fn fn a) fn)) fn) 0 1)
diff --git a/packages/context-coloring/fixtures/test/let-star.el
b/packages/context-coloring/fixtures/test/let-star.el
deleted file mode 100644
index 44d743c..0000000
--- a/packages/context-coloring/fixtures/test/let-star.el
+++ /dev/null
@@ -1,11 +0,0 @@
-(let* (a
- (b a)
- (c free))
- (and a b c d e free)
- (let* (d
- (e a)
- (c free)
- (g f)
- (f g))
- (and a b c d e free))
- (and a b c d e free))
diff --git a/packages/context-coloring/fixtures/test/let.el
b/packages/context-coloring/fixtures/test/let.el
deleted file mode 100644
index 49edb50..0000000
--- a/packages/context-coloring/fixtures/test/let.el
+++ /dev/null
@@ -1,13 +0,0 @@
-(let (a
- (b a)
- (c free)
- (d (let (a
- (b a)
- (c free))
- (and a b c free))))
- (and a b c free))
-
-(let ;; comment
- ("s"))
-
-(let (a '))
diff --git a/packages/context-coloring/fixtures/test/macroexp-let2.el
b/packages/context-coloring/fixtures/test/macroexp-let2.el
deleted file mode 100644
index 1b61df2..0000000
--- a/packages/context-coloring/fixtures/test/macroexp-let2.el
+++ /dev/null
@@ -1,6 +0,0 @@
-(let (exp)
- (macroexp-let2 macroexp-copyable-p v exp
- v exp))
-
-(macroexp-let2 macroexp-copyable-p)
-(macroexp-let2)
diff --git a/packages/context-coloring/fixtures/test/narrow-to-region.js
b/packages/context-coloring/fixtures/test/narrow-to-region.js
deleted file mode 100644
index 29f9aef..0000000
--- a/packages/context-coloring/fixtures/test/narrow-to-region.js
+++ /dev/null
@@ -1,3 +0,0 @@
-function a () {}
-function b () {}
-function c () {}
diff --git a/packages/context-coloring/fixtures/test/prettify-symbols.el
b/packages/context-coloring/fixtures/test/prettify-symbols.el
deleted file mode 100644
index 0863230..0000000
--- a/packages/context-coloring/fixtures/test/prettify-symbols.el
+++ /dev/null
@@ -1 +0,0 @@
-(lambda () (lambda ()))
diff --git a/packages/context-coloring/fixtures/test/property-lookup.js
b/packages/context-coloring/fixtures/test/property-lookup.js
deleted file mode 100644
index 4edcb41..0000000
--- a/packages/context-coloring/fixtures/test/property-lookup.js
+++ /dev/null
@@ -1,5 +0,0 @@
-(function () {
- window.foo();
- window. bar();
- window.foo.bar();
-}());
diff --git a/packages/context-coloring/fixtures/test/quote.el
b/packages/context-coloring/fixtures/test/quote.el
deleted file mode 100644
index 5fc126d..0000000
--- a/packages/context-coloring/fixtures/test/quote.el
+++ /dev/null
@@ -1,15 +0,0 @@
-(quote (lambda () free))
-(let () (backquote (,free)))
-
-(defun a (a)
- (or (eq a 'b)
- (equal a '(a b))
- (equal a `(,(append () `(a b ,(+ 1 free) ,free b) free) b ,free
- "s" ; c
- ))))
-
-(append '("a" ; b
- "b" ; a
- ))
-
-(lambda () '((?\" ?\")))
diff --git a/packages/context-coloring/fixtures/test/sexp.el
b/packages/context-coloring/fixtures/test/sexp.el
deleted file mode 100644
index 438dc02..0000000
--- a/packages/context-coloring/fixtures/test/sexp.el
+++ /dev/null
@@ -1,4 +0,0 @@
-(let ()
- `,@"a"
- `,@'b
- `,@\c)
diff --git a/packages/context-coloring/fixtures/test/splice.el
b/packages/context-coloring/fixtures/test/splice.el
deleted file mode 100644
index 3a857a7..0000000
--- a/packages/context-coloring/fixtures/test/splice.el
+++ /dev/null
@@ -1,2 +0,0 @@
-(lambda ()
- `(,@(a free) ,free))
diff --git a/packages/context-coloring/fixtures/test/string.el
b/packages/context-coloring/fixtures/test/string.el
deleted file mode 100644
index 4172642..0000000
--- a/packages/context-coloring/fixtures/test/string.el
+++ /dev/null
@@ -1,2 +0,0 @@
-(defun a (a)
- (concat a b "(" a b "(\"" b a "(\"\""))
diff --git a/packages/context-coloring/fixtures/test/unbalanced-parenthesis.el
b/packages/context-coloring/fixtures/test/unbalanced-parenthesis.el
deleted file mode 100644
index caaf7e2..0000000
--- a/packages/context-coloring/fixtures/test/unbalanced-parenthesis.el
+++ /dev/null
@@ -1,2 +0,0 @@
-(let ())
-(let ()
diff --git a/packages/context-coloring/fixtures/test/unterminated-comment.js
b/packages/context-coloring/fixtures/test/unterminated-comment.js
deleted file mode 100644
index 94d4703..0000000
--- a/packages/context-coloring/fixtures/test/unterminated-comment.js
+++ /dev/null
@@ -1,6 +0,0 @@
-function a() {
- /*
- function b() {
-
- }
-}
diff --git a/packages/context-coloring/fixtures/test/varlist-spacing.el
b/packages/context-coloring/fixtures/test/varlist-spacing.el
deleted file mode 100644
index 97ec208..0000000
--- a/packages/context-coloring/fixtures/test/varlist-spacing.el
+++ /dev/null
@@ -1,8 +0,0 @@
-(let (
- (a (lambda ()))))
-
-(lambda ( a b )
- a b)
-
-(defadvice a ( (b) )
- b)
diff --git a/packages/context-coloring/screenshot.png
b/packages/context-coloring/screenshot.png
deleted file mode 100644
index 89665b7..0000000
Binary files a/packages/context-coloring/screenshot.png and /dev/null differ
diff --git a/packages/diff-hl/.elpaignore b/packages/diff-hl/.elpaignore
deleted file mode 100644
index fc72b33..0000000
--- a/packages/diff-hl/.elpaignore
+++ /dev/null
@@ -1,2 +0,0 @@
-README.md
-screenshot*
diff --git a/packages/diff-hl/LICENSE b/packages/diff-hl/LICENSE
deleted file mode 100644
index 94a9ed0..0000000
--- a/packages/diff-hl/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 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.
-
- 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 <http://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
-<http://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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/diff-hl/README.md b/packages/diff-hl/README.md
deleted file mode 100644
index de07ffe..0000000
--- a/packages/diff-hl/README.md
+++ /dev/null
@@ -1,118 +0,0 @@
-About
-=====
-
-`diff-hl-mode` highlights uncommitted changes on the left side of the window,
-allows you to jump between and revert them selectively.
-
-For the usage instructions and the list of commands, see the Commentary section
-inside the file.
-
-Tested with Git, Mercurial, Bazaar and SVN. May work with other VC backends,
too.
-
-The package also contains auxiliary modes:
-
-* `diff-hl-dired-mode` provides similar functionality in Dired.
-* `diff-hl-margin-mode` changes the highlighting function to
- use the margin instead of the fringe.
-* `diff-hl-amend-mode` shifts the reference revision back by one.
-* `diff-hl-flydiff-mode` implements highlighting changes on the fly.
- It requires Emacs 24.4 or newer.
-
-Usage
-=====
-
-Put this into your init script:
-
-```lisp
-(global-diff-hl-mode)
-```
-
-Check out the Commentary section in each file for more detailed usage
-instructions.
-
-Screenshots
-=====
-
-diff-hl-mode
------
-Top window: a buffer in this minor mode, bottom window: the corresponding diff.
-
-![screenie](screenshot.png)
-
-diff-hl-dired-mode
------
-
-![screenie](screenshot-dired.png)
-
-diff-hl-margin-mode
------
-
-![screenie](screenshot-margin.png)
-
-Requirements
-=====
-
-Emacs 24.3+.
-
-Notes
-=====
-
-* By default `diff-hl-mode` uses the corresponding VC diff command, so
- it's only accurate when the buffer is in saved state. Check out
- `diff-hl-flydiff-mode`, it aims to handle unsaved buffers as well.
-
-* To use an
- [alternative diff
algorithm](http://stackoverflow.com/questions/32365271/whats-the-difference-between-git-diff-patience-and-git-diff-histogram)
- with Git, add a corresponding argument to `vc-git-diff-switches`,
- e.g. `(setq vc-git-diff-switches '("--histogram"))`. Using the
- `diff.algorithm` option doesn't work
- [because](http://article.gmane.org/gmane.comp.version-control.git/294622)
- `vc-git-diff` calls `git diff-index`. `diff-hl-flydiff-mode` does
- not support alternative algorithms, because it uses the external
- `diff` program.
-
-* We conflict with other modes when they put indicators on the fringe,
- such as [Flycheck](https://github.com/flycheck/flycheck). This is
- rarely a significant problem, since if you're using such a mode,
- you'd usually want to fix all errors and warnings before continuing,
- and then the conflicting indicators go away.
-
-* There's no fringe when Emacs is running in the console, but the navigation
- and revert commands still work. Consider turning `diff-hl-margin-mode` on,
- to show the indicators in the margin instead.
-
-* Frame-local and buffer-local values of `line-spacing` are not supported.
-
-* Fringe width up to 16 works best (because we can't define a bitmap
- with width above that number).
-
-* [emacs-git-gutter](https://github.com/syohex/emacs-git-gutter) shows
- indicators in the margin by default, allows you to customize how the
- indicators look more easily, and has a "stage hunk" command.
-
-Integration
-=====
-
-If you're using some package other than `vc` to commit changes, it might
-not run `vc-checkin-hook` after commits. In that case, you'll need to
-either add `diff-hl-update` to the hook it does run, or advise some
-function that's called in the buffer after its state has changed.
-
-psvn
------
-
-```lisp
-(advice-add 'svn-status-update-modeline :after #'diff-hl-update)
-```
-
-Magit
------
-
-If you're using a version before 2.4.0, it defines `magit-revert-buffer-hook`
-(or `magit-not-reverted-hook`), which we use.
-
-When using Magit 2.4 or newer, add this to your init script:
-
-```lisp
-(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
-```
diff --git a/packages/diff-hl/diff-hl-amend.el
b/packages/diff-hl/diff-hl-amend.el
deleted file mode 100644
index 1bb3de1..0000000
--- a/packages/diff-hl/diff-hl-amend.el
+++ /dev/null
@@ -1,68 +0,0 @@
-;; Copyright (C) 2012-2013 Free Software Foundation, Inc.
-
-;; Author: Dmitry Gutov <dgutov@yandex.ru>
-;; URL: https://github.com/dgutov/diff-hl
-
-;; 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:
-
-;; Toggle in the current buffer with `M-x diff-hl-amend-mode'.
-;; Toggle in all buffers with `M-x global-diff-hl-amend-mode'.
-
-;;; Code:
-
-(require 'diff-hl)
-
-;;;###autoload
-(define-minor-mode diff-hl-amend-mode
- "Show changes against the second-last revision in `diff-hl-mode'.
-Most useful with backends that support rewriting local commits,
-and most importantly, \"amending\" the most recent one.
-Currently only supports Git, Mercurial and Bazaar."
- :lighter " Amend"
- (if diff-hl-amend-mode
- (progn
- (diff-hl-amend-setup)
- (add-hook 'after-revert-hook 'diff-hl-amend-setup nil t))
- (remove-hook 'after-revert-hook 'diff-hl-amend-setup t)
- (setq-local diff-hl-reference-revision nil))
- (when diff-hl-mode
- (diff-hl-update)))
-
-(defun diff-hl-amend-setup ()
- (let ((backend (vc-backend buffer-file-name)))
- (when backend
- (setq-local diff-hl-reference-revision
- (cl-case backend
- (Git
- "HEAD^")
- (Hg
- "-2")
- (Bzr
- "revno:-2"))))))
-
-;;;###autoload
-(define-globalized-minor-mode global-diff-hl-amend-mode diff-hl-amend-mode
- turn-on-diff-hl-amend-mode)
-
-(defun turn-on-diff-hl-amend-mode ()
- "Turn on `diff-hl-amend-mode' in a buffer if appropriate."
- (and buffer-file-name (diff-hl-amend-mode 1)))
-
-(provide 'diff-hl-amend)
-
-;;; diff-hl-amend.el ends here
diff --git a/packages/diff-hl/diff-hl-dired.el
b/packages/diff-hl/diff-hl-dired.el
deleted file mode 100644
index af2df46..0000000
--- a/packages/diff-hl/diff-hl-dired.el
+++ /dev/null
@@ -1,184 +0,0 @@
-;;; diff-hl-dired.el --- Highlight changed files in Dired -*- lexical-binding:
t -*-
-
-;; Copyright (C) 2012-2017 Free Software Foundation, Inc.
-
-;; 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:
-
-;; To enable in all Dired buffers, add this to your init file:
-;;
-;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode)
-;;
-;; or
-;;
-;; (add-hook 'dired-mode-hook 'diff-hl-dired-mode-unless-remote)
-;;
-;; to do it only in local Dired buffers.
-
-;;; Code:
-
-(require 'diff-hl)
-(require 'dired)
-(require 'vc-hooks)
-
-(defvar diff-hl-dired-process-buffer nil)
-
-(defgroup diff-hl-dired nil
- "VC diff highlighting on the side of a Dired window."
- :group 'diff-hl)
-
-(defface diff-hl-dired-insert
- '((default :inherit diff-hl-insert))
- "Face used to highlight added files.")
-
-(defface diff-hl-dired-delete
- '((default :inherit diff-hl-delete))
- "Face used to highlight directories with deleted files.")
-
-(defface diff-hl-dired-change
- '((default :inherit diff-hl-change))
- "Face used to highlight changed files.")
-
-(defface diff-hl-dired-unknown
- '((default :inherit dired-ignored))
- "Face used to highlight unregistered files.")
-
-(defface diff-hl-dired-ignored
- '((default :inherit dired-ignored))
- "Face used to highlight unregistered files.")
-
-(defcustom diff-hl-dired-extra-indicators t
- "Non-nil to indicate ignored files."
- :type 'boolean)
-
-(defcustom diff-hl-dired-ignored-backends '(RCS)
- "VC backends to ignore.
-The directories registered to one of these backends won't have
-status indicators."
- :type `(repeat (choice ,@(mapcar
- (lambda (name)
- `(const :tag ,(symbol-name name) ,name))
- vc-handled-backends))))
-
-;;;###autoload
-(define-minor-mode diff-hl-dired-mode
- "Toggle VC diff highlighting on the side of a Dired window."
- :lighter ""
- (if diff-hl-dired-mode
- (progn
- (diff-hl-maybe-define-bitmaps)
- (set (make-local-variable 'diff-hl-dired-process-buffer) nil)
- (add-hook 'dired-after-readin-hook 'diff-hl-dired-update nil t))
- (remove-hook 'dired-after-readin-hook 'diff-hl-dired-update t)
- (diff-hl-dired-clear)))
-
-(defun diff-hl-dired-update ()
- "Highlight the Dired buffer."
- (let ((backend (ignore-errors (vc-responsible-backend default-directory)))
- (def-dir default-directory)
- (buffer (current-buffer))
- dirs-alist files-alist)
- (when (and backend (not (memq backend diff-hl-dired-ignored-backends)))
- (diff-hl-dired-clear)
- (if (buffer-live-p diff-hl-dired-process-buffer)
- (let ((proc (get-buffer-process diff-hl-dired-process-buffer)))
- (when proc (kill-process proc)))
- (setq diff-hl-dired-process-buffer
- (generate-new-buffer " *diff-hl-dired* tmp status")))
- (with-current-buffer diff-hl-dired-process-buffer
- (setq default-directory (expand-file-name def-dir))
- (erase-buffer)
- (diff-hl-dired-status-files
- backend def-dir
- (when diff-hl-dired-extra-indicators
- (cl-loop for file in (directory-files def-dir)
- unless (member file '("." ".." ".hg"))
- collect file))
- (lambda (entries &optional more-to-come)
- (when (buffer-live-p buffer)
- (with-current-buffer buffer
- (dolist (entry entries)
- (cl-destructuring-bind (file state &rest r) entry
- ;; Work around http://debbugs.gnu.org/18605
- (setq file (replace-regexp-in-string "\\` " "" file))
- (let ((type (plist-get
- '(edited change added insert removed delete
- unregistered unknown ignored ignored)
- state)))
- (if (string-match "\\`\\([^/]+\\)/" file)
- (let* ((dir (match-string 1 file))
- (value (cdr (assoc dir dirs-alist))))
- (unless (eq value type)
- (cond
- ((eq state 'up-to-date))
- ((null value)
- (push (cons dir type) dirs-alist))
- ((not (eq type 'ignored))
- (setcdr (assoc dir dirs-alist) 'change)))))
- (push (cons file type) files-alist)))))
- (unless more-to-come
- (diff-hl-dired-highlight-items
- (append dirs-alist files-alist))))
- (unless more-to-come
- (kill-buffer diff-hl-dired-process-buffer))))
- )))))
-
-(defun diff-hl-dired-status-files (backend dir files update-function)
- "Using version control BACKEND, return list of (FILE STATE EXTRA) entries
-for DIR containing FILES. Call UPDATE-FUNCTION as entries are added."
- (if (version< "25" emacs-version)
- (vc-call-backend backend 'dir-status-files dir files update-function)
- (vc-call-backend backend 'dir-status-files dir files nil update-function)))
-
-(when (version< emacs-version "24.4.51.5")
- ;; Work around http://debbugs.gnu.org/19386
- (defadvice vc-git-dir-status-goto-stage (around
- diff-hl-dired-skip-up-to-date
- (stage files update-function)
- activate)
- (when (eq stage 'ls-files-up-to-date)
- (setq stage 'diff-index))
- ad-do-it))
-
-(defun diff-hl-dired-highlight-items (alist)
- "Highlight ALIST containing (FILE . TYPE) elements."
- (dolist (pair alist)
- (let ((file (car pair))
- (type (cdr pair)))
- (save-excursion
- (goto-char (point-min))
- (when (and type (dired-goto-file-1
- file (expand-file-name file) nil))
- (let* ((diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type)
- (diff-hl-fringe-face-function 'diff-hl-dired-face-from-type)
- (o (diff-hl-add-highlighting type 'single)))
- (overlay-put o 'modification-hooks '(diff-hl-overlay-modified))
- ))))))
-
-(defun diff-hl-dired-face-from-type (type _pos)
- (intern (format "diff-hl-dired-%s" type)))
-
-(defalias 'diff-hl-dired-clear 'diff-hl-remove-overlays)
-
-;;;###autoload
-(defun diff-hl-dired-mode-unless-remote ()
- (unless (file-remote-p default-directory)
- (diff-hl-dired-mode)))
-
-(provide 'diff-hl-dired)
-
-;;; diff-hl-dired.el ends here
diff --git a/packages/diff-hl/diff-hl-flydiff.el
b/packages/diff-hl/diff-hl-flydiff.el
deleted file mode 100644
index 6f9be29..0000000
--- a/packages/diff-hl/diff-hl-flydiff.el
+++ /dev/null
@@ -1,176 +0,0 @@
-;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
-
-;; Author: Jonathan Hayase <PythonNut@gmail.com>
-;; URL: https://github.com/dgutov/diff-hl
-
-;; 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:
-
-;; This mode enables diffing on-the-fly (i.e. without saving the buffer first)
-;; Toggle in all buffers with M-x diff-hl-flydiff-mode
-
-;;; Code:
-
-(require 'diff-hl)
-(require 'diff)
-(unless (require 'nadvice nil t)
- (error "`diff-hl-flydiff-mode' requires Emacs 24.4 or newer"))
-
-(defgroup diff-hl-flydiff nil
- "Highlight changes on the fly"
- :group 'diff-hl)
-
-(defcustom diff-hl-flydiff-delay 0.3
- "The idle delay in seconds before highlighting is updated."
- :type 'number)
-
-(defvar diff-hl-flydiff-modified-tick nil)
-(defvar diff-hl-flydiff-timer nil)
-(make-variable-buffer-local 'diff-hl-flydiff-modified-tick)
-
-(defun diff-hl-flydiff/vc-git--symbolic-ref (file)
- (or
- (vc-file-getprop file 'vc-git-symbolic-ref)
- (let* (process-file-side-effects
- (str (vc-git--run-command-string nil "symbolic-ref" "HEAD")))
- (vc-file-setprop file 'vc-git-symbolic-ref
- (if str
- (if (string-match "^\\(refs/heads/\\)?\\(.+\\)$" str)
- (match-string 2 str)
- str))))))
-
-(defun diff-hl-flydiff/vc-git-working-revision (_file)
- "Git-specific version of `vc-working-revision'."
- (let (process-file-side-effects)
- (vc-git--rev-parse "HEAD")))
-
-(defun diff-hl-flydiff/vc-git-mode-line-string (file)
- "Return a string for `vc-mode-line' to put in the mode line for FILE."
- (let* ((rev (vc-working-revision file))
- (disp-rev (or (diff-hl-flydiff/vc-git--symbolic-ref file)
- (substring rev 0 7)))
- (def-ml (vc-default-mode-line-string 'Git file))
- (help-echo (get-text-property 0 'help-echo def-ml))
- (face (get-text-property 0 'face def-ml)))
- (propertize (replace-regexp-in-string (concat rev "\\'") disp-rev def-ml t
t)
- 'face face
- 'help-echo (concat help-echo "\nCurrent revision: " rev))))
-
-;; Polyfill concrete revisions for vc-git-working-revision in Emacs 24.4, 24.5
-(when (version<= emacs-version "25.0")
- (with-eval-after-load 'vc-git
- (advice-add 'vc-git-working-revision :override
- #'diff-hl-flydiff/vc-git-working-revision)
- (advice-add 'vc-git-mode-line-string :override
- #'diff-hl-flydiff/vc-git-mode-line-string)))
-
-(defun diff-hl-flydiff/working-revision (file)
- "Like vc-working-revision, but always up-to-date"
- (vc-file-setprop file 'vc-working-revision
- (vc-call-backend (vc-backend file) 'working-revision file)))
-
-(defun diff-hl-flydiff-make-temp-file-name (file rev &optional manual)
- "Return a backup file name for REV or the current version of FILE.
-If MANUAL is non-nil it means that a name for backups created by
-the user should be returned."
- (let* ((auto-save-file-name-transforms
- `((".*" ,temporary-file-directory t))))
- (expand-file-name
- (concat (make-auto-save-file-name)
- ".~" (subst-char-in-string
- ?/ ?_ rev)
- (unless manual ".") "~")
- temporary-file-directory)))
-
-(defun diff-hl-flydiff-create-revision (file revision)
- "Read REVISION of FILE into a buffer and return the buffer."
- (let ((automatic-backup (diff-hl-flydiff-make-temp-file-name file revision))
- (filebuf (get-file-buffer file))
- (filename (diff-hl-flydiff-make-temp-file-name file revision 'manual)))
- (unless (file-exists-p filename)
- (if (file-exists-p automatic-backup)
- (rename-file automatic-backup filename nil)
- (with-current-buffer filebuf
- (let ((coding-system-for-read 'no-conversion)
- (coding-system-for-write 'no-conversion))
- (condition-case nil
- (with-temp-file filename
- (let ((outbuf (current-buffer)))
- ;; Change buffer to get local value of
- ;; vc-checkout-switches.
- (with-current-buffer filebuf
- (vc-call find-revision file revision outbuf))))
- (error
- (when (file-exists-p filename)
- (delete-file filename))))))))
- filename))
-
-(defun diff-hl-flydiff-buffer-with-head (file &optional backend)
- "View the differences between BUFFER and its associated file.
-This requires the external program `diff' to be in your `exec-path'."
- (interactive)
- (vc-ensure-vc-buffer)
- (setq diff-hl-flydiff-modified-tick (buffer-chars-modified-tick))
- (save-current-buffer
- (let* ((temporary-file-directory
- (if (file-directory-p "/dev/shm/")
- "/dev/shm/"
- temporary-file-directory))
- (rev (diff-hl-flydiff-create-revision
- file
- (diff-hl-flydiff/working-revision file))))
- ;; FIXME: When against staging, do it differently!
- (diff-no-select rev (current-buffer) "-U 0 --strip-trailing-cr" 'noasync
- (get-buffer-create " *diff-hl-diff*")))))
-
-(defun diff-hl-flydiff-update ()
- (unless (or
- (not diff-hl-mode)
- (eq diff-hl-flydiff-modified-tick (buffer-chars-modified-tick))
- (not buffer-file-name)
- (not (file-exists-p buffer-file-name))
- (file-remote-p default-directory))
- (diff-hl-update)))
-
-(defun diff-hl-flydiff/modified-p (state)
- (buffer-modified-p))
-
-;;;###autoload
-(define-minor-mode diff-hl-flydiff-mode
- "Perform highlighting on-the-fly.
-This is a global minor mode. It alters how `diff-hl-mode' works."
- :lighter "" :global t
- (if diff-hl-flydiff-mode
- (progn
- (advice-add 'diff-hl-overlay-modified :override #'ignore)
-
- (advice-add 'diff-hl-modified-p :before-until
- #'diff-hl-flydiff/modified-p)
- (advice-add 'diff-hl-changes-buffer :override
- #'diff-hl-flydiff-buffer-with-head)
- (setq diff-hl-flydiff-timer
- (run-with-idle-timer diff-hl-flydiff-delay t
#'diff-hl-flydiff-update)))
-
- (advice-remove 'diff-hl-overlay-modified #'ignore)
-
- (advice-remove 'diff-hl-modified-p #'diff-hl-flydiff/modified-p)
- (advice-remove 'diff-hl-changes-buffer #'diff-hl-flydiff-buffer-with-head)
-
- (and diff-hl-flydiff-timer
- (cancel-timer diff-hl-flydiff-timer))))
-
-(provide 'diff-hl-flydiff)
diff --git a/packages/diff-hl/diff-hl-margin.el
b/packages/diff-hl/diff-hl-margin.el
deleted file mode 100644
index 4d0198e..0000000
--- a/packages/diff-hl/diff-hl-margin.el
+++ /dev/null
@@ -1,153 +0,0 @@
-;;; diff-hl-margin.el --- Highlight buffer changes on margins -*-
lexical-binding: t -*-
-
-;; Copyright (C) 2012-2017 Free Software Foundation, Inc.
-
-;; 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:
-
-;; This is a global mode, it modifies `diff-hl-mode' to use the margin
-;; instead of the fringe. To toggle, type `M-x diff-hl-margin-mode'.
-;;
-;; Compared to the default behavior, this makes `diff-hl-mode'
-;; indicators show up even when Emacs is running in a terminal.
-;;
-;; On the flip side, the indicators look simpler, and they are
-;; incompatible with `linum-mode' or any other mode that uses the
-;; margin.
-;;
-;; You might want to enable it conditionally in your init file
-;; depending on whether Emacs is running in graphical mode:
-;;
-;; (unless (window-system) (diff-hl-margin-mode))
-
-(require 'cl-lib)
-(require 'diff-hl)
-(require 'diff-hl-dired)
-
-(defvar diff-hl-margin-old-highlight-function nil)
-
-(defgroup diff-hl-margin nil
- "Highlight buffer changes on margin"
- :group 'diff-hl)
-
-(defface diff-hl-margin-insert
- '((default :inherit diff-hl-insert))
- "Face used to highlight inserted lines on the margin.")
-
-(defface diff-hl-margin-delete
- '((default :inherit diff-hl-delete))
- "Face used to highlight deleted lines on the margin.")
-
-(defface diff-hl-margin-change
- '((default :inherit diff-hl-change))
- "Face used to highlight changed lines on the margin.")
-
-(defface diff-hl-margin-ignored
- '((default :inherit dired-ignored))
- "Face used to highlight changed lines on the margin.")
-
-(defface diff-hl-margin-unknown
- '((default :inherit dired-ignored))
- "Face used to highlight changed lines on the margin.")
-
-(defcustom diff-hl-margin-symbols-alist
- '((insert . "+") (delete . "-") (change . "!")
- (unknown . "?") (ignored . "i"))
- "Associative list from symbols to strings."
- :type '(alist :key-type symbol
- :value-type string
- :options (insert delete change unknown ignored))
- :set (lambda (symbol value)
- (defvar diff-hl-margin-spec-cache)
- (set-default symbol value)
- (setq diff-hl-margin-spec-cache nil)))
-
-;;;###autoload
-(define-minor-mode diff-hl-margin-mode
- "Toggle displaying `diff-hl-mode' highlights on the margin."
- :lighter "" :global t
- (if diff-hl-margin-mode
- (progn
- (add-hook 'diff-hl-mode-on-hook 'diff-hl-margin-minor-mode)
- (add-hook 'diff-hl-mode-off-hook 'diff-hl-margin-minor-mode-off)
- (add-hook 'diff-hl-dired-mode-on-hook 'diff-hl-margin-minor-mode)
- (add-hook 'diff-hl-dired-mode-off-hook 'diff-hl-margin-minor-mode-off))
- (remove-hook 'diff-hl-mode-on-hook 'diff-hl-margin-minor-mode)
- (remove-hook 'diff-hl-mode-off-hook 'diff-hl-margin-minor-mode-off)
- (remove-hook 'diff-hl-dired-mode-on-hook 'diff-hl-margin-minor-mode)
- (remove-hook 'diff-hl-dired-mode-off-hook 'diff-hl-margin-minor-mode-off))
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (cond
- (diff-hl-mode
- (diff-hl-margin-minor-mode (if diff-hl-margin-mode 1 -1))
- (diff-hl-update))
- (diff-hl-dired-mode
- (diff-hl-margin-minor-mode (if diff-hl-margin-mode 1 -1))
- (diff-hl-dired-update))))))
-
-(define-minor-mode diff-hl-margin-minor-mode
- "Toggle displaying `diff-hl-mode' highlights on the margin locally.
-You probably shouldn't use this function directly."
- :lighter ""
- (let ((width-var (intern (format "%s-margin-width" diff-hl-side))))
- (if diff-hl-margin-minor-mode
- (progn
- (set (make-local-variable 'diff-hl-margin-old-highlight-function)
- diff-hl-highlight-function)
- (set (make-local-variable 'diff-hl-highlight-function)
- 'diff-hl-highlight-on-margin)
- (set width-var 1))
- (setq diff-hl-highlight-function diff-hl-margin-old-highlight-function
- diff-hl-margin-old-highlight-function nil)
- (set width-var 0)))
- (dolist (win (get-buffer-window-list))
- (set-window-buffer win (current-buffer))))
-
-(define-obsolete-variable-alias 'diff-hl-margin-side 'diff-hl-side "1.7.1")
-
-(defun diff-hl-margin-minor-mode-off ()
- (diff-hl-margin-minor-mode -1))
-
-(defvar diff-hl-margin-spec-cache nil)
-
-(defun diff-hl-margin-spec-cache ()
- (or diff-hl-margin-spec-cache
- (setq diff-hl-margin-spec-cache
- (diff-hl-margin-build-spec-cache))))
-
-(defun diff-hl-margin-build-spec-cache ()
- (cl-loop for (type . char) in diff-hl-margin-symbols-alist
- nconc
- (cl-loop for side in '(left right)
- collect
- (cons
- (cons type side)
- (propertize
- " " 'display
- `((margin ,(intern (format "%s-margin" side)))
- ,(propertize char 'face
- (intern (format "diff-hl-margin-%s"
type)))))))))
-
-(defun diff-hl-highlight-on-margin (ovl type _shape)
- (let ((spec (cdr (assoc (cons type diff-hl-side)
- (diff-hl-margin-spec-cache)))))
- (overlay-put ovl 'before-string spec)))
-
-(provide 'diff-hl-margin)
-
-;;; diff-hl-margin.el ends here
diff --git a/packages/diff-hl/diff-hl.el b/packages/diff-hl/diff-hl.el
deleted file mode 100644
index a560bf2..0000000
--- a/packages/diff-hl/diff-hl.el
+++ /dev/null
@@ -1,643 +0,0 @@
-;;; diff-hl.el --- Highlight uncommitted changes using VC -*- lexical-binding:
t -*-
-
-;; Copyright (C) 2012-2019 Free Software Foundation, Inc.
-
-;; Author: Dmitry Gutov <dgutov@yandex.ru>
-;; URL: https://github.com/dgutov/diff-hl
-;; Keywords: vc, diff
-;; Version: 1.8.7
-;; Package-Requires: ((cl-lib "0.2") (emacs "24.3"))
-
-;; 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:
-
-;; `diff-hl-mode' highlights uncommitted changes on the side of the
-;; window (using the fringe, by default), allows you to jump between
-;; the hunks and revert them selectively.
-
-;; Provided commands:
-;;
-;; `diff-hl-diff-goto-hunk' C-x v =
-;; `diff-hl-revert-hunk' C-x v n
-;; `diff-hl-previous-hunk' C-x v [
-;; `diff-hl-next-hunk' C-x v ]
-;;
-;; The mode takes advantage of `smartrep' if it is installed.
-
-;; Add either of the following to your init file.
-;;
-;; To use it in all buffers:
-;;
-;; (global-diff-hl-mode)
-;;
-;; Only in `prog-mode' buffers, with `vc-dir' integration:
-;;
-;; (add-hook 'prog-mode-hook 'turn-on-diff-hl-mode)
-;; (add-hook 'vc-dir-mode-hook 'turn-on-diff-hl-mode)
-
-;;; Code:
-
-(require 'fringe)
-(require 'diff-mode)
-(require 'vc)
-(require 'vc-dir)
-(eval-when-compile
- (require 'cl-lib)
- (require 'vc-git)
- (require 'vc-hg)
- (require 'face-remap)
- (declare-function smartrep-define-key 'smartrep))
-
-(defgroup diff-hl nil
- "VC diff highlighting on the side of a window"
- :group 'vc)
-
-(defface diff-hl-insert
- '((default :inherit diff-added)
- (((class color)) :foreground "green4"))
- "Face used to highlight inserted lines."
- :group 'diff-hl)
-
-(defface diff-hl-delete
- '((default :inherit diff-removed)
- (((class color)) :foreground "red3"))
- "Face used to highlight deleted lines."
- :group 'diff-hl)
-
-(defface diff-hl-change
- '((default :foreground "blue3")
- (((class color) (min-colors 88) (background light))
- :background "#ddddff")
- (((class color) (min-colors 88) (background dark))
- :background "#333355"))
- "Face used to highlight changed lines."
- :group 'diff-hl)
-
-(defcustom diff-hl-command-prefix (kbd "C-x v")
- "The prefix for all `diff-hl' commands."
- :group 'diff-hl
- :type 'string)
-
-(defcustom diff-hl-draw-borders t
- "Non-nil to draw borders around fringe indicators."
- :group 'diff-hl
- :type 'boolean)
-
-(defcustom diff-hl-highlight-function 'diff-hl-highlight-on-fringe
- "Function to highlight the current line. Its arguments are
- overlay, change type and position within a hunk."
- :group 'diff-hl
- :type 'function)
-
-(defcustom diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-pos
- "Function to choose the fringe bitmap for a given change type
- and position within a hunk. Should accept two arguments."
- :group 'diff-hl
- :type '(choice (const diff-hl-fringe-bmp-from-pos)
- (const diff-hl-fringe-bmp-from-type)
- function))
-
-(defcustom diff-hl-fringe-face-function 'diff-hl-fringe-face-from-type
- "Function to choose the fringe face for a given change type
- and position within a hunk. Should accept two arguments."
- :group 'diff-hl
- :type 'function)
-
-(defcustom diff-hl-side 'left
- "Which side to use for indicators."
- :type '(choice (const left)
- (const right))
- :set (lambda (var value)
- (let ((on (bound-and-true-p global-diff-hl-mode)))
- (when on (global-diff-hl-mode -1))
- (set-default var value)
- (when on (global-diff-hl-mode 1)))))
-
-(defcustom diff-hl-highlight-revert-hunk-function
- #'diff-hl-revert-highlight-first-column
- "Function to highlight the current hunk in `diff-hl-revert-hunk'.
-The function is called at the beginning of the hunk and passed
-the end position as its only argument."
- :type '(choice (const :tag "Do nothing" ignore)
- (const :tag "Highlight the first column"
- diff-hl-revert-highlight-first-column)))
-
-(defvar diff-hl-reference-revision nil
- "Revision to diff against. nil means the most recent one.")
-
-(defun diff-hl-define-bitmaps ()
- (let* ((scale (if (and (boundp 'text-scale-mode-amount)
- (numberp text-scale-mode-amount))
- (expt text-scale-mode-step text-scale-mode-amount)
- 1))
- (spacing (or (and (display-graphic-p) (default-value 'line-spacing))
0))
- (h (+ (ceiling (* (frame-char-height) scale))
- (if (floatp spacing)
- (truncate (* (frame-char-height) spacing))
- spacing)))
- (w (min (frame-parameter nil (intern (format "%s-fringe"
diff-hl-side)))
- 16))
- (middle (make-vector h (expt 2 (1- w))))
- (ones (1- (expt 2 w)))
- (top (copy-sequence middle))
- (bottom (copy-sequence middle))
- (single (copy-sequence middle)))
- (aset top 0 ones)
- (aset bottom (1- h) ones)
- (aset single 0 ones)
- (aset single (1- h) ones)
- (define-fringe-bitmap 'diff-hl-bmp-top top h w 'top)
- (define-fringe-bitmap 'diff-hl-bmp-middle middle h w 'center)
- (define-fringe-bitmap 'diff-hl-bmp-bottom bottom h w 'bottom)
- (define-fringe-bitmap 'diff-hl-bmp-single single h w 'top)
- (define-fringe-bitmap 'diff-hl-bmp-i [3 3 0 3 3 3 3 3 3 3] nil 2 'center)
- (let* ((w2 (* (/ w 2) 2))
- ;; When fringes are disabled, it's easier to fix up the width,
- ;; instead of doing nothing (#20).
- (w2 (if (zerop w2) 2 w2))
- (delete-row (- (expt 2 (1- w2)) 2))
- (middle-pos (1- (/ w2 2)))
- (middle-bit (expt 2 middle-pos))
- (insert-bmp (make-vector w2 (* 3 middle-bit))))
- (define-fringe-bitmap 'diff-hl-bmp-delete (make-vector 2 delete-row) w2
w2)
- (aset insert-bmp 0 0)
- (aset insert-bmp middle-pos delete-row)
- (aset insert-bmp (1+ middle-pos) delete-row)
- (aset insert-bmp (1- w2) 0)
- (define-fringe-bitmap 'diff-hl-bmp-insert insert-bmp w2 w2)
- )))
-
-(defun diff-hl-maybe-define-bitmaps ()
- (when (window-system) ;; No fringes in the console.
- (unless (fringe-bitmap-p 'diff-hl-bmp-empty)
- (diff-hl-define-bitmaps)
- (define-fringe-bitmap 'diff-hl-bmp-empty [0] 1 1 'center))))
-
-(defun diff-hl-maybe-redefine-bitmaps ()
- (when (window-system)
- (diff-hl-define-bitmaps)))
-
-(defvar diff-hl-spec-cache (make-hash-table :test 'equal))
-
-(defun diff-hl-fringe-spec (type pos side)
- (let* ((key (list type pos side
- diff-hl-fringe-face-function
- diff-hl-fringe-bmp-function))
- (val (gethash key diff-hl-spec-cache)))
- (unless val
- (let* ((face-sym (funcall diff-hl-fringe-face-function type pos))
- (bmp-sym (funcall diff-hl-fringe-bmp-function type pos)))
- (setq val (propertize " " 'display `((,(intern (format "%s-fringe"
side))
- ,bmp-sym ,face-sym))))
- (puthash key val diff-hl-spec-cache)))
- val))
-
-(defun diff-hl-fringe-face-from-type (type _pos)
- (intern (format "diff-hl-%s" type)))
-
-(defun diff-hl-fringe-bmp-from-pos (_type pos)
- (intern (format "diff-hl-bmp-%s" pos)))
-
-(defun diff-hl-fringe-bmp-from-type (type _pos)
- (cl-case type
- (unknown 'question-mark)
- (change 'exclamation-mark)
- (ignored 'diff-hl-bmp-i)
- (t (intern (format "diff-hl-bmp-%s" type)))))
-
-(defvar vc-svn-diff-switches)
-
-(defmacro diff-hl-with-diff-switches (body)
- `(let ((vc-git-diff-switches
- ;; https://github.com/dgutov/diff-hl/issues/67
- (cons "-U0"
- ;; https://github.com/dgutov/diff-hl/issues/9
- (and (boundp 'vc-git-diff-switches)
- (listp vc-git-diff-switches)
- (cl-remove-if-not
- (lambda (arg)
- (member arg '("--histogram" "--patience" "--minimal")))
- vc-git-diff-switches))))
- (vc-hg-diff-switches nil)
- (vc-svn-diff-switches nil)
- (vc-diff-switches '("-U0"))
- ,@(when (boundp 'vc-disable-async-diff)
- '((vc-disable-async-diff t))))
- ,body))
-
-(defun diff-hl-modified-p (state)
- (or (eq state 'edited)
- (and (eq state 'up-to-date)
- ;; VC state is stale in after-revert-hook.
- (or revert-buffer-in-progress-p
- ;; Diffing against an older revision.
- diff-hl-reference-revision))))
-
-(defun diff-hl-changes-buffer (file backend)
- ;; FIXME: To diff against the staging area, call 'git diff-files -p'.
- (let ((buf-name " *diff-hl* "))
- (condition-case err
- (diff-hl-with-diff-switches
- (vc-call-backend backend 'diff (list file)
- diff-hl-reference-revision nil
- buf-name))
- (error
- ;; https://github.com/dgutov/diff-hl/issues/117
- (when (string-match-p "\\`Failed (status 128)" (error-message-string
err))
- (diff-hl-with-diff-switches
- (vc-call-backend backend 'diff (list file)
- "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
- nil
- buf-name)))))
- buf-name))
-
-(defun diff-hl-changes ()
- (let* ((file buffer-file-name)
- (backend (vc-backend file)))
- (when backend
- (let ((state (vc-state file backend)))
- (cond
- ((diff-hl-modified-p state)
- (let* (diff-auto-refine-mode res)
- (with-current-buffer (diff-hl-changes-buffer file backend)
- (goto-char (point-min))
- (unless (eobp)
- (ignore-errors
- (diff-beginning-of-hunk t))
- (while (looking-at diff-hunk-header-re-unified)
- (let ((line (string-to-number (match-string 3)))
- (len (let ((m (match-string 4)))
- (if m (string-to-number m) 1)))
- (beg (point)))
- (diff-end-of-hunk)
- (let* ((inserts (diff-count-matches "^\\+" beg (point)))
- (deletes (diff-count-matches "^-" beg (point)))
- (type (cond ((zerop deletes) 'insert)
- ((zerop inserts) 'delete)
- (t 'change))))
- (when (eq type 'delete)
- (setq len 1)
- (cl-incf line))
- (push (list line len type) res))))))
- (nreverse res)))
- ((eq state 'added)
- `((1 ,(line-number-at-pos (point-max)) insert)))
- ((eq state 'removed)
- `((1 ,(line-number-at-pos (point-max)) delete))))))))
-
-(defun diff-hl-update ()
- (let ((changes (diff-hl-changes))
- (current-line 1))
- (diff-hl-remove-overlays)
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (point-min))
- (dolist (c changes)
- (cl-destructuring-bind (line len type) c
- (forward-line (- line current-line))
- (setq current-line line)
- (let ((hunk-beg (point)))
- (while (cl-plusp len)
- (diff-hl-add-highlighting
- type
- (cond
- ((not diff-hl-draw-borders) 'empty)
- ((and (= len 1) (= line current-line)) 'single)
- ((= len 1) 'bottom)
- ((= line current-line) 'top)
- (t 'middle)))
- (forward-line 1)
- (cl-incf current-line)
- (cl-decf len))
- (let ((h (make-overlay hunk-beg (point)))
- (hook '(diff-hl-overlay-modified)))
- (overlay-put h 'diff-hl t)
- (overlay-put h 'diff-hl-hunk t)
- (overlay-put h 'modification-hooks hook)
- (overlay-put h 'insert-in-front-hooks hook)
- (overlay-put h 'insert-behind-hooks hook)))))))))
-
-(defun diff-hl-add-highlighting (type shape)
- (let ((o (make-overlay (point) (point))))
- (overlay-put o 'diff-hl t)
- (funcall diff-hl-highlight-function o type shape)
- o))
-
-(defun diff-hl-highlight-on-fringe (ovl type shape)
- (overlay-put ovl 'before-string (diff-hl-fringe-spec type shape
- diff-hl-side)))
-
-(defun diff-hl-remove-overlays (&optional beg end)
- (save-restriction
- (widen)
- (dolist (o (overlays-in (or beg (point-min)) (or end (point-max))))
- (when (overlay-get o 'diff-hl) (delete-overlay o)))))
-
-(defun diff-hl-overlay-modified (ov after-p _beg _end &optional _length)
- "Delete the hunk overlay and all our line overlays inside it."
- (unless after-p
- (when (overlay-buffer ov)
- (diff-hl-remove-overlays (overlay-start ov) (overlay-end ov))
- (delete-overlay ov))))
-
-(defvar diff-hl-timer nil)
-
-(defun diff-hl-edit (_beg _end _len)
- "DTRT when we've `undo'-ne the buffer into unmodified state."
- (when undo-in-progress
- (when diff-hl-timer
- (cancel-timer diff-hl-timer))
- (setq diff-hl-timer
- (run-with-idle-timer 0.01 nil #'diff-hl-after-undo
(current-buffer)))))
-
-(defun diff-hl-after-undo (buffer)
- (with-current-buffer buffer
- (unless (buffer-modified-p)
- (diff-hl-update))))
-
-(defun diff-hl-diff-goto-hunk ()
- "Run VC diff command and go to the line corresponding to the current."
- (interactive)
- (vc-buffer-sync)
- (let* ((line (line-number-at-pos))
- (buffer (current-buffer)))
- (vc-diff-internal t (vc-deduce-fileset) diff-hl-reference-revision nil t)
- (vc-exec-after `(if (< (line-number-at-pos (point-max)) 3)
- (with-current-buffer ,buffer (diff-hl-remove-overlays))
- (diff-hl-diff-skip-to ,line)
- (setq vc-sentinel-movepoint (point))))))
-
-(defun diff-hl-diff-skip-to (line)
- "In `diff-mode', skip to the hunk and line corresponding to LINE
-in the source file, or the last line of the hunk above it."
- (diff-hunk-next)
- (let (found)
- (while (and (looking-at diff-hunk-header-re-unified) (not found))
- (let ((hunk-line (string-to-number (match-string 3)))
- (len (let ((m (match-string 4)))
- (if m (string-to-number m) 1))))
- (if (> line (+ hunk-line len))
- (diff-hunk-next)
- (setq found t)
- (if (< line hunk-line)
- ;; Retreat to the previous hunk.
- (forward-line -1)
- (let ((to-go (1+ (- line hunk-line))))
- (while (cl-plusp to-go)
- (forward-line 1)
- (unless (looking-at "^-")
- (cl-decf to-go))))))))))
-
-(defface diff-hl-reverted-hunk-highlight
- '((default :inverse-video t))
- "Face used to highlight the first column of the hunk to be reverted.")
-
-(defun diff-hl-revert-highlight-first-column (end)
- (let ((inhibit-read-only t))
- (save-excursion
- (while (< (point) end)
- (font-lock-prepend-text-property (point) (1+ (point)) 'font-lock-face
- 'diff-hl-reverted-hunk-highlight)
- (forward-line 1)))))
-
-(defun diff-hl-revert-hunk ()
- "Revert the diff hunk with changes at or above the point."
- (interactive)
- (save-restriction
- (widen)
- (vc-buffer-sync)
- (let ((diff-buffer (generate-new-buffer-name "*diff-hl*"))
- (buffer (current-buffer))
- (line (save-excursion
- (unless (diff-hl-hunk-overlay-at (point))
- (diff-hl-previous-hunk))
- (line-number-at-pos)))
- (fileset (vc-deduce-fileset)))
- (unwind-protect
- (progn
- (vc-diff-internal nil fileset diff-hl-reference-revision nil
- nil diff-buffer)
- (vc-exec-after
- `(let (beg-line end-line m-end)
- (when (eobp)
- (with-current-buffer ,buffer (diff-hl-remove-overlays))
- (user-error "Buffer is up-to-date"))
- (let (diff-auto-refine-mode)
- (diff-hl-diff-skip-to ,line))
- (save-excursion
- (while (looking-at "[-+]") (forward-line 1))
- (setq end-line (line-number-at-pos (point)))
- (setq m-end (point-marker))
- (unless (eobp) (diff-split-hunk)))
- (unless (looking-at "[-+]") (forward-line -1))
- (while (looking-at "[-+]") (forward-line -1))
- (setq beg-line (line-number-at-pos (point)))
- (unless (looking-at "@")
- (forward-line 1)
- (diff-split-hunk))
- (funcall diff-hl-highlight-revert-hunk-function m-end)
- (let ((wbh (window-body-height)))
- (if (>= wbh (- end-line beg-line))
- (recenter (/ (+ wbh (- beg-line end-line) 2) 2))
- (recenter 1)))
- (when diff-auto-refine-mode
- (diff-refine-hunk))
- (unless (yes-or-no-p (format "Revert current hunk in %s? "
- ,(cl-caadr fileset)))
- (user-error "Revert canceled"))
- (let ((diff-advance-after-apply-hunk nil))
- (diff-apply-hunk t))
- (with-current-buffer ,buffer
- (save-buffer))
- (message "Hunk reverted"))))
- (quit-windows-on diff-buffer t)))))
-
-(defun diff-hl-hunk-overlay-at (pos)
- (cl-loop for o in (overlays-in pos (1+ pos))
- when (overlay-get o 'diff-hl-hunk)
- return o))
-
-(defun diff-hl-next-hunk (&optional backward)
- "Go to the beginning of the next hunk in the current buffer."
- (interactive)
- (let ((pos (save-excursion
- (catch 'found
- (while (not (if backward (bobp) (eobp)))
- (goto-char (if backward
- (previous-overlay-change (point))
- (next-overlay-change (point))))
- (let ((o (diff-hl-hunk-overlay-at (point))))
- (when (and o (= (overlay-start o) (point)))
- (throw 'found (overlay-start o)))))))))
- (if pos
- (goto-char pos)
- (user-error "No further hunks found"))))
-
-(defun diff-hl-previous-hunk ()
- "Go to the beginning of the previous hunk in the current buffer."
- (interactive)
- (diff-hl-next-hunk t))
-
-(defun diff-hl-mark-hunk ()
- (interactive)
- (let ((hunk (diff-hl-hunk-overlay-at (point))))
- (unless hunk
- (user-error "No hunk at point"))
- (goto-char (overlay-start hunk))
- (push-mark (overlay-end hunk) nil t)))
-
-(defvar diff-hl-command-map
- (let ((map (make-sparse-keymap)))
- (define-key map "n" 'diff-hl-revert-hunk)
- (define-key map "[" 'diff-hl-previous-hunk)
- (define-key map "]" 'diff-hl-next-hunk)
- map))
-(fset 'diff-hl-command-map diff-hl-command-map)
-
-(defvar diff-hl-lighter ""
- "Mode line lighter for Diff Hl.
-
-The value of this variable is a mode line template as in
-`mode-line-format'.")
-
-;;;###autoload
-(define-minor-mode diff-hl-mode
- "Toggle VC diff highlighting."
- :lighter diff-hl-lighter
- :keymap `(([remap vc-diff] . diff-hl-diff-goto-hunk)
- (,diff-hl-command-prefix . diff-hl-command-map))
- (if diff-hl-mode
- (progn
- (diff-hl-maybe-define-bitmaps)
- (add-hook 'after-save-hook 'diff-hl-update nil t)
- (add-hook 'after-change-functions 'diff-hl-edit nil t)
- (add-hook (if vc-mode
- ;; Defer until the end of this hook, so that its
- ;; elements can modify the update behavior.
- 'diff-hl-mode-on-hook
- ;; If we're only opening the file now,
- ;; `vc-find-file-hook' likely hasn't run yet, so
- ;; let's wait until the state information is
- ;; saved, in order not to fetch it twice.
- 'find-file-hook)
- 'diff-hl-update t t)
- (add-hook 'vc-checkin-hook 'diff-hl-update nil t)
- (add-hook 'after-revert-hook 'diff-hl-update nil t)
- ;; Magit does call `auto-revert-handler', but it usually
- ;; doesn't do much, because `buffer-stale--default-function'
- ;; doesn't care about changed VC state.
- ;; https://github.com/magit/magit/issues/603
- (add-hook 'magit-revert-buffer-hook 'diff-hl-update nil t)
- ;; Magit versions 2.0-2.3 don't do the above and call this
- ;; instead, but only when they dosn't call `revert-buffer':
- (add-hook 'magit-not-reverted-hook 'diff-hl-update nil t)
- (add-hook 'text-scale-mode-hook 'diff-hl-maybe-redefine-bitmaps nil t))
- (remove-hook 'after-save-hook 'diff-hl-update t)
- (remove-hook 'after-change-functions 'diff-hl-edit t)
- (remove-hook 'find-file-hook 'diff-hl-update t)
- (remove-hook 'vc-checkin-hook 'diff-hl-update t)
- (remove-hook 'after-revert-hook 'diff-hl-update t)
- (remove-hook 'magit-revert-buffer-hook 'diff-hl-update t)
- (remove-hook 'magit-not-reverted-hook 'diff-hl-update t)
- (remove-hook 'text-scale-mode-hook 'diff-hl-maybe-redefine-bitmaps t)
- (diff-hl-remove-overlays)))
-
-(when (require 'smartrep nil t)
- (let (smart-keys)
- (cl-labels ((scan (map)
- (map-keymap
- (lambda (event binding)
- (if (consp binding)
- (scan binding)
- (when (characterp event)
- (push (cons (string event) binding) smart-keys))))
- map)))
- (scan diff-hl-command-map)
- (smartrep-define-key diff-hl-mode-map diff-hl-command-prefix
smart-keys))))
-
-(declare-function magit-toplevel "magit-git")
-(declare-function magit-unstaged-files "magit-git")
-
-(defun diff-hl-magit-post-refresh ()
- (let* ((topdir (magit-toplevel))
- (modified-files
- (mapcar (lambda (file) (expand-file-name file topdir))
- (magit-unstaged-files t)))
- (unmodified-states '(up-to-date ignored unregistered)))
- (dolist (buf (buffer-list))
- (when (and (buffer-local-value 'diff-hl-mode buf)
- (not (buffer-modified-p buf))
- ;; Solve the "cloned indirect buffer" problem
- ;; (diff-hl-mode could be non-nil there, even if
- ;; buffer-file-name is nil):
- (buffer-file-name buf)
- (file-in-directory-p (buffer-file-name buf) topdir)
- (file-exists-p (buffer-file-name buf)))
- (with-current-buffer buf
- (let* ((file buffer-file-name)
- (backend (vc-backend file)))
- (when backend
- (cond
- ((member file modified-files)
- (when (memq (vc-state file) unmodified-states)
- (vc-state-refresh file backend))
- (diff-hl-update))
- ((not (memq (vc-state file backend) unmodified-states))
- (vc-state-refresh file backend)
- (diff-hl-update))))))))))
-
-(defun diff-hl-dir-update ()
- (dolist (pair (if (vc-dir-marked-files)
- (vc-dir-marked-only-files-and-states)
- (vc-dir-child-files-and-states)))
- (when (eq 'up-to-date (cdr pair))
- (let ((buffer (find-buffer-visiting (car pair))))
- (when buffer
- (with-current-buffer buffer
- (diff-hl-remove-overlays)))))))
-
-(define-minor-mode diff-hl-dir-mode
- "Toggle `diff-hl-mode' integration in a `vc-dir-mode' buffer."
- :lighter ""
- (if diff-hl-dir-mode
- (add-hook 'vc-checkin-hook 'diff-hl-dir-update t t)
- (remove-hook 'vc-checkin-hook 'diff-hl-dir-update t)))
-
-;;;###autoload
-(defun turn-on-diff-hl-mode ()
- "Turn on `diff-hl-mode' or `diff-hl-dir-mode' in a buffer if appropriate."
- (cond
- (buffer-file-name
- (diff-hl-mode 1))
- ((eq major-mode 'vc-dir-mode)
- (diff-hl-dir-mode 1))))
-
-;;;###autoload
-(define-globalized-minor-mode global-diff-hl-mode diff-hl-mode
- turn-on-diff-hl-mode :after-hook (diff-hl-global-mode-change))
-
-(defun diff-hl-global-mode-change ()
- (unless global-diff-hl-mode
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (when diff-hl-dir-mode
- (diff-hl-dir-mode -1))))))
-
-(provide 'diff-hl)
-
-;;; diff-hl.el ends here
diff --git a/packages/diff-hl/screenshot-dired.png
b/packages/diff-hl/screenshot-dired.png
deleted file mode 100644
index 97df41b..0000000
Binary files a/packages/diff-hl/screenshot-dired.png and /dev/null differ
diff --git a/packages/diff-hl/screenshot-margin.png
b/packages/diff-hl/screenshot-margin.png
deleted file mode 100644
index 6698a29..0000000
Binary files a/packages/diff-hl/screenshot-margin.png and /dev/null differ
diff --git a/packages/diff-hl/screenshot.png b/packages/diff-hl/screenshot.png
deleted file mode 100644
index 5f99db7..0000000
Binary files a/packages/diff-hl/screenshot.png and /dev/null differ
diff --git a/packages/diffview/Makefile b/packages/diffview/Makefile
deleted file mode 100644
index a422376..0000000
--- a/packages/diffview/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-README.md: make-readme-markdown.el diffview.el
- emacs --script $< < diffview.el >$@
-
-ifeq ($(LOCAL),1)
-make-readme-markdown.el:
- cp -v ../make-readme-markdown/make-readme-markdown.el .
-else
-make-readme-markdown.el:
- wget -q -O $@
https://raw.github.com/mgalgs/make-readme-markdown/master/make-readme-markdown.el
-endif
-
-.INTERMEDIATE: make-readme-markdown.el
-.PHONY: README.md
diff --git a/packages/diffview/README.md b/packages/diffview/README.md
deleted file mode 100644
index d64002d..0000000
--- a/packages/diffview/README.md
+++ /dev/null
@@ -1,59 +0,0 @@
-## diffview.el
-*View diffs in side-by-side format*
-
----
-[![License
GPLv3](https://img.shields.io/badge/license-GPL_v3-green.svg)](http://www.gnu.org/licenses/gpl-3.0.html)
-[![MELPA](http://melpa.org/packages/diffview-badge.svg)](http://melpa.org/#/diffview)
-[![MELPA
Stable](http://stable.melpa.org/packages/diffview-badge.svg)](http://stable.melpa.org/#/diffview)
-
-Render a unified diff (top/bottom) in an easy-to-comprehend side-by-side
-format. This comes in handy for reading patches from mailing lists (or
-from whencever you might acquire them).
-
-### Installation
-
-
- M-x package-install diffview
-
-### Usage
-
-
-The following functions are provided for launching a side-by-side diff:
-
-* `diffview-current` : View the current diff buffer side-by-side
-* `diffview-region` : View the current diff region side-by-side
-* `diffview-message` : View the current email message (which presumably
- contains a patch) side-by-side
-
-
-### Screenshots
-
-
-Before:
-<img
src="https://raw.github.com/mgalgs/diffview-mode/master/screenshots/diffview-before.png">
-
-After:
-<img
src="https://raw.github.com/mgalgs/diffview-mode/master/screenshots/diffview-after.png">
-
-### Function Documentation
-
-
-#### `(diffview-current)`
-
-Show current diff buffer in a side-by-side view.
-
-#### `(diffview-region)`
-
-Show current diff region in a side-by-side view.
-
-#### `(diffview-message)`
-
-Show `message-mode` buffer in a side-by-side view.
-
-This is useful for reading patches from mailing lists.
-
------
-<div style="padding-top:15px;color: #d0d0d0;">
-Markdown README file generated by
-<a
href="https://github.com/mgalgs/make-readme-markdown">make-readme-markdown.el</a>
-</div>
diff --git a/packages/diffview/diffview.el b/packages/diffview/diffview.el
deleted file mode 100644
index a684b05..0000000
--- a/packages/diffview/diffview.el
+++ /dev/null
@@ -1,200 +0,0 @@
-;;; diffview.el --- View diffs in side-by-side format
-
-;; Copyright (C) 2013-2016 Free Software Foundation, Inc.
-
-;; Author: Mitchel Humpherys <mitch.special@gmail.com>
-;; Maintainer: Mitchel Humpherys <mitch.special@gmail.com>
-;; Keywords: convenience, diff
-;; Version: 1.0
-;; URL: https://github.com/mgalgs/diffview-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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Render a unified diff (top/bottom) in an easy-to-comprehend side-by-side
-;; format. This comes in handy for reading patches from mailing lists (or
-;; from whencever you might acquire them).
-;;
-;;; Installation:
-;;
-;; M-x package-install diffview
-;;
-;;; Usage:
-;;
-;; The following functions are provided for launching a side-by-side diff:
-;;
-;; o `diffview-current' : View the current diff buffer side-by-side
-;; o `diffview-region' : View the current diff region side-by-side
-;; o `diffview-message' : View the current email message (which presumably
-;; contains a patch) side-by-side
-;;
-;;
-;;; Screenshots:
-;;
-;; Before:
-;;
https://raw.github.com/mgalgs/diffview-mode/master/screenshots/diffview-before.png
-;;
-;; After:
-;;
https://raw.github.com/mgalgs/diffview-mode/master/screenshots/diffview-after.png
-;;
-;;; Code:
-
-(require 'message)
-
-(defun diffview--print-all-lines-to-buffer (lines buffer-name)
- "Prints each line in `LINES' to a buffer named `BUFFER-NAME'."
- (let ((old-temp-buffer (get-buffer buffer-name)))
- ;; (with-output-to-temp-buffer buffer-name
- (when old-temp-buffer
- (kill-buffer old-temp-buffer))
- (with-current-buffer (get-buffer-create buffer-name)
- (erase-buffer)
- (dolist (line lines)
- (insert line "\n")))))
-
-(defvar diffview--minus-bufname "*side-by-side-1*")
-(defvar diffview--plus-bufname "*side-by-side-2*")
-(defvar diffview--saved-wincfg nil)
-(defvar diffview--regexp-is-plus-line "^\\+\\([^+]\\{1\\}\\|$\\)"
- "A + followed by one non + or the end of the line.")
-(defvar diffview--regexp-is-minus-line "^-\\([^-]\\{1\\}\\|$\\)"
- "A - followed by one non - or the end of the line.")
-
-(defun diffview--view-string (input-string)
- "Displays `INPUT-STRING' (a diff) in a side-by-side view."
- (setq diffview--saved-wincfg (current-window-configuration))
- (delete-other-windows)
- (let (plus-lines
- minus-lines
- tmp-line
- (current-state 'in-common)
- (last-state 'in-common)
- (current-lines-in-plus 0)
- (current-lines-in-minus 0)
- (total-lines 0)
- (all-lines (split-string input-string "\n")))
- (dolist (line all-lines)
- (cond
- ((string-match diffview--regexp-is-plus-line line)
- (push line plus-lines)
- (setq current-state 'in-plus)
- (setq current-lines-in-plus (1+ current-lines-in-plus)))
- ((string-match diffview--regexp-is-minus-line line)
- (push line minus-lines)
- (setq current-state 'in-minus)
- (setq current-lines-in-minus (1+ current-lines-in-minus)))
- ;; everything else must be common
- (t
- (push line plus-lines)
- (push line minus-lines)
- (setq current-state 'in-common)))
-
- (setq total-lines (1+ total-lines))
-
- ;; Process hunk state transitions
- (when (not (equal current-state last-state))
- ;; there's been a state change
- (when (equal current-state 'in-common)
- ;; we're transitioning out the +/- part of a hunk. We would
- ;; like both sides to have the same number lines for this
- ;; hunk, so we might need to fill one side or the other with
- ;; empty lines.
- (cond
- ((> current-lines-in-plus current-lines-in-minus)
- ;; need to fill minus
- (setq tmp-line (pop minus-lines))
- (dotimes (i (- current-lines-in-plus current-lines-in-minus))
- (push "" minus-lines))
- (push tmp-line minus-lines))
- ((< current-lines-in-plus current-lines-in-minus)
- ;; need to fill plus
- (setq tmp-line (pop plus-lines))
- (dotimes (i (- current-lines-in-minus current-lines-in-plus))
- (push "" plus-lines))
- (push tmp-line plus-lines)))
-
- (setq current-lines-in-plus 0
- current-lines-in-minus 0)))
-
- (setq last-state current-state))
-
- (diffview--print-all-lines-to-buffer (reverse minus-lines)
diffview--minus-bufname)
- (diffview--print-all-lines-to-buffer (reverse plus-lines)
diffview--plus-bufname)
-
- (switch-to-buffer diffview--minus-bufname nil t)
- (goto-char (point-min))
- (diffview-mode)
-
- (split-window-right)
- (other-window 1)
-
- (switch-to-buffer diffview--plus-bufname nil t)
- (goto-char (point-min))
- (diffview-mode)
-
- (scroll-all-mode)))
-
-;;;###autoload
-(defun diffview-current ()
- "Show current diff buffer in a side-by-side view."
- (interactive)
- (diffview--view-string (buffer-string)))
-
-;;;###autoload
-(defun diffview-region ()
- "Show current diff region in a side-by-side view."
- (interactive)
- (diffview--view-string (buffer-substring (point) (mark))))
-
-;;;###autoload
-(defun diffview-message ()
- "Show `message-mode' buffer in a side-by-side view.
-
-This is useful for reading patches from mailing lists."
- (interactive)
- (let (beg end)
- (save-excursion
- (message-goto-body)
- (search-forward-regexp "^---$")
- (setq beg (1+ (point)))
- (search-forward-regexp "^-- $")
- (setq end (1+ (point)))
- (diffview--view-string (buffer-substring beg end)))))
-
-(defvar diffview-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "q") 'diffview--quit)
- map))
-
-;; You probably don't want to invoke `diffview-mode' directly. Just use
-;; one of the autoload functions above.
-(define-derived-mode diffview-mode special-mode "Diffview"
- "Mode for viewing diffs side-by-side"
- (setq font-lock-defaults '(diff-font-lock-keywords t nil nil nil
(font-lock-multiline . nil))))
-
-(defun diffview--quit ()
- "Quit diffview and clean up diffview buffers."
- (interactive)
- (delete-other-windows)
- (scroll-all-mode 0)
- (let ((plusbuf (get-buffer diffview--plus-bufname))
- (minusbuf (get-buffer diffview--minus-bufname)))
- (if plusbuf (kill-buffer plusbuf))
- (if minusbuf (kill-buffer minusbuf)))
- (set-window-configuration diffview--saved-wincfg))
-
-(provide 'diffview)
-;;; diffview.el ends here
-;;
diff --git a/packages/diffview/screenshots/diffview-after.png
b/packages/diffview/screenshots/diffview-after.png
deleted file mode 100644
index a59d9b5..0000000
Binary files a/packages/diffview/screenshots/diffview-after.png and /dev/null
differ
diff --git a/packages/diffview/screenshots/diffview-before.png
b/packages/diffview/screenshots/diffview-before.png
deleted file mode 100644
index b33fca7..0000000
Binary files a/packages/diffview/screenshots/diffview-before.png and /dev/null
differ
diff --git a/packages/dts-mode/README.mkd b/packages/dts-mode/README.mkd
deleted file mode 100644
index 8de2d90..0000000
--- a/packages/dts-mode/README.mkd
+++ /dev/null
@@ -1,12 +0,0 @@
-# dts-mode — A Device Tree major mode for emacs
-
-This is a quick attempt at getting basic highlighting for [Device
-Tree][devicetree] syntax in emacs. While it's fairly functional, it's not
-pretty; pull requests welcome.
-
-[devicetree]: http://www.devicetree.org/
-
-## Installation
-
-Available through [MELPA](http://melpa.milkbox.net/#/). Alternatively ensure
-`dts-mode.el` is available in `load-path` and `(require 'dts-mode)`.
diff --git a/packages/dts-mode/dts-mode.el b/packages/dts-mode/dts-mode.el
deleted file mode 100644
index e1ce4fd..0000000
--- a/packages/dts-mode/dts-mode.el
+++ /dev/null
@@ -1,177 +0,0 @@
-;;; dts-mode.el --- Major mode for Device Tree source files
-
-;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
-
-;; Version: 0.1.0
-;; Author: Ben Gamari <ben@smart-cactus.org>
-;; 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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(defconst dts-re-ident "\\([[:alpha:]_][[:alnum:]_,-]*\\)")
-
-(defvar dts-mode-font-lock-keywords
- `(
- ;; Names like `name: hi {`
- (,(concat dts-re-ident ":") 1 font-lock-variable-name-face)
- ;; Nodes
- (,(concat dts-re-ident "\\(@[[:xdigit:]]+\\)?[[:space:]]*{")
- (1 font-lock-type-face))
- ;; Assignments
- (,(concat dts-re-ident "[[:space:]]*=") 1 font-lock-variable-name-face)
- (,(concat dts-re-ident "[[:space:]]*;") 1 font-lock-variable-name-face)
- ;; References
- (,(concat "&" dts-re-ident) 1 font-lock-variable-name-face)
- )
- )
-
-(defvar dts-mode-syntax-table
- (let ((table (make-syntax-table)))
- (modify-syntax-entry ?< "(>" table)
- (modify-syntax-entry ?> ")<" table)
-
- (modify-syntax-entry ?& "." table)
- (modify-syntax-entry ?| "." table)
- (modify-syntax-entry ?~ "." table)
-
- ;; _ and , are both symbol constituents.
- (modify-syntax-entry ?, "_" table)
- (modify-syntax-entry ?_ "_" table)
-
- ;; Strings
- (modify-syntax-entry ?\" "\"" table)
- (modify-syntax-entry ?\\ "\\" table)
-
- ;; Comments
- (modify-syntax-entry ?/ ". 124b" table)
- (modify-syntax-entry ?* ". 23" table)
- (modify-syntax-entry ?\n "> b" table)
- (modify-syntax-entry ?\^m "> b" table)
-
- table))
-
-;;;; Original manual indentation code.
-
-(defun dts--calculate-indentation ()
- (interactive)
- (save-excursion
- (let ((end (point-at-eol))
- (cnt 0)
- (initial-point (point)))
- (goto-char 0)
- (while (re-search-forward "\\([{}]\\)" end t)
- (if (string= (match-string-no-properties 0) "{")
- (setq cnt (1+ cnt))
- (setq cnt (1- cnt))))
- ;; subtract one if the current line has an opening brace since we
- ;; shouldn't add the indentation level until the following line
- (goto-char initial-point)
- (beginning-of-line)
- (when (re-search-forward "{" (point-at-eol) t)
- (setq cnt (1- cnt)))
- cnt)))
-
-(defun dts-indent-line ()
- (interactive)
- (let ((indent (dts--calculate-indentation)))
- (indent-line-to (* indent tab-width))))
-
-;;;; New SMIE-based indentation code.
-
-;; Compatibility macro.
-(defmacro dts--using-macro (name exp)
- (declare (indent 1) (debug (symbolp form)))
- (if (fboundp name) ;If macro exists at compiler-time, just use it.
- exp
- `(when (fboundp ',name) ;Else, check if it exists at run-time.
- (eval ',exp)))) ;If it does, then run the code.
-
-(require 'smie nil t)
-
-(defvar dts-use-smie (and (fboundp 'smie-prec2->grammar) (fboundp 'pcase)))
-
-(defconst dts-grammar
- ;; FIXME: The syntax-table gives symbol-constituent syntax to the comma,
- ;; but the comma is also used as a separator!
- (when (fboundp 'smie-prec2->grammar)
- (smie-prec2->grammar
- (smie-bnf->prec2
- '((id) (val ("<" val ">"))
- (exp ("{" exps "}")
- ;; The "foo,bar = toto" can be handled either by considering
- ;; "foo,bar" as a single token or as 3 tokens.
- ;; Currently I consider it as 3 tokens, so the LHS of "=" can't be
- ;; just `id' but has to be `vals'.
- (vals "=" vals))
- (exps (exp) (exps ";" exps))
- (vals (val "," val)))
- '((assoc ";")) '((assoc ","))))))
-
-(defun dts-indent-rules (kind token)
- (dts--using-macro pcase
- (pcase (cons kind token)
- (`(:elem . basic) tab-width)
- ;; (`(:elem . args) 0)
- (`(:list-intro . "") ;FIXME: Not sure why we get "" here!
- ;; After < we either have a plain list of data, as in: "operating-points
- ;; = <1008000 1400000 ...>" or we have sometimes "refs with args" as in
- ;; "clocks = <&apb1_gates 6>;".
- (and (eq (char-before) ?<) (not (looking-at "&"))))
- (`(:before . "{") (smie-rule-parent))
- (`(:before . "<") (if (smie-rule-hanging-p) (smie-rule-parent)))
- (`(:after . "=") (dts-indent-rules :elem 'basic))
- )))
-
-;;;; The major mode itself.
-
-(defalias 'dts-parent-mode
- (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
-
-;;;###autoload
-(define-derived-mode dts-mode dts-parent-mode "Devicetree";DTS would be
shorter!
- "Major mode for editing Device Tree source files."
-
- ;; Fonts
- (set (make-local-variable 'font-lock-defaults)
- '(dts-mode-font-lock-keywords nil nil nil nil))
- (set (make-local-variable 'comment-start) "/* ")
- (set (make-local-variable 'comment-end) " */")
- (set (make-local-variable 'comment-multi-line) t)
-
- ;; This is not specific to the DTS format, really, but DTS is mostly
- ;; used in the context of the Linux kernel (and U-boot loader) where
- ;; there's a strong preference to indent with TABs.
- (set (make-local-variable 'indent-tabs-mode) t)
-
- (dts--using-macro syntax-propertize-rules
- (set (make-local-variable 'syntax-propertize-function)
- (syntax-propertize-rules
- ("#include[ \t]+\\(<\\).*\\(>\\)" (1 "|") (2 "|"))
- ;; Treat things like /delete-property/ as a single identifier.
- ("\\(/\\)[a-z]+\\(/\\)" (1 "_") (2 "_")))))
- (if dts-use-smie
- (smie-setup dts-grammar #'dts-indent-rules)
- (set (make-local-variable 'indent-line-function) #'dts-indent-line)))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist '("\\.dtsi?\\'" . dts-mode))
-
-(provide 'dts-mode)
-;;; dts-mode.el ends here
diff --git a/packages/eldoc-eval/README.md b/packages/eldoc-eval/README.md
deleted file mode 100644
index d290902..0000000
--- a/packages/eldoc-eval/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-Enable eldoc support when minibuffer is in use.
-
-# Commentary:
-
-This package enables eldoc support when minibuffer is in use.
-
-Eldoc info is shown by default in mode-line,
-but you can have eldoc info somewhere else by setting
-`eldoc-in-minibuffer-show-fn` to another function (e.g `tooltip-show`).
-
-By default with this package `M-:` will use `pp-eval-expression`
-instead of `eval-expression`; you can change that by setting
-`eval-preferred-function` to something else.
-
-It also provides a convenient macro to enable eldoc support
-in your own functions using minibuffer or in your defadvices,
-that is `with-eldoc-in-minibuffer`, e.g:
-
-```lisp
-(defadvice edebug-eval-expression (around with-eldoc activate)
- "This advice enable eldoc support."
- (interactive (list (with-eldoc-in-minibuffer
- (read-from-minibuffer
- "Eval: " nil read-expression-map t
- 'read-expression-history))))
- ad-do-it)
-```
-
-Users of own minibuffer frame will have to set
-`eldoc-in-minibuffer-own-frame-p` to non-nil.
-
-You can turn On/Off eldoc support in minibuffer at any time
-with `eldoc-in-minibuffer-mode`.
-
-# Install:
-
-Add to .emacs:
-
-```lisp
- (autoload 'eldoc-in-minibuffer-mode "eldoc-eval")
- (eldoc-in-minibuffer-mode 1)
-```
diff --git a/packages/eldoc-eval/eldoc-eval.el
b/packages/eldoc-eval/eldoc-eval.el
deleted file mode 100644
index bf208e0..0000000
--- a/packages/eldoc-eval/eldoc-eval.el
+++ /dev/null
@@ -1,225 +0,0 @@
-;;; eldoc-eval.el --- Enable eldoc support when minibuffer is in use.
-
-;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc.
-
-;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
-;; Version: 0.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 <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; This package enables eldoc support when minibuffer is in use.
-;;
-;; Eldoc info is shown by default in mode-line,
-;; but you can have eldoc info somewhere else by setting
-;; `eldoc-in-minibuffer-show-fn' to another function (e.g `tooltip-show').
-;;
-;; By default with this package `M-:' will use `pp-eval-expression'
-;; instead of `eval-expression'; you can change that by setting
-;; `eldoc-eval-preferred-function'.
-;;
-;; It also provides a convenient macro to enable eldoc support
-;; in your own functions using minibuffer or in your defadvices,
-;; that is `with-eldoc-in-minibuffer'.
-;;
-;; Users of own minibuffer frame will have to set
-;; `eldoc-in-minibuffer-own-frame-p' to non-nil.
-;;
-;; You can turn On/Off eldoc support in minibuffer any time
-;; with `eldoc-in-minibuffer-mode'.
-;;
-;;; Install:
-;; Add to .emacs:
-;;
-;; (autoload 'eldoc-in-minibuffer-mode "eldoc-eval")
-;; (eldoc-in-minibuffer-mode 1)
-
-
-;;; Code:
-(require 'eldoc)
-
-;;; Minibuffer support.
-;; Enable displaying eldoc info in something else
-;; Than minibuffer when this one is in use.
-;;
-(defgroup eldoc-eval nil
- "Show eldoc infos in mode line while minibuffer is in use."
- :group 'eldoc)
-
-(defcustom eldoc-in-minibuffer-show-fn 'eldoc-show-in-mode-line
- "A function to display eldoc info.
-Should take one arg: the string to display"
- :type 'function)
-
-(defcustom eldoc-show-in-mode-line-delay 12
- "The time we show eldoc when Emacs is idle."
- :type 'number)
-
-(defcustom eldoc-eval-preferred-function 'pp-eval-expression
- "Preferred function to use with `M-:'."
- :type 'function)
-
-(defcustom eldoc-in-minibuffer-own-frame-p nil
- "Whether minibuffer has its own frame or not."
- :type 'boolean)
-
-;;; Compatibility with Emacs-24.4
-;; New implementation of eldoc in minibuffer that come
-;; with Emacs-24.4 show the eldoc info of current-buffer while
-;; minibuffer is in use, disable this and inline old Emacs behavior.
-;;
-(defconst eldoc-eval--old-message-function
- (and (boundp 'eldoc-message-function) eldoc-message-function))
-
-(defadvice eldoc-display-message-no-interference-p
- (after eldoc-eval activate)
- (when eldoc-in-minibuffer-mode
- (setq ad-return-value
- (and ad-return-value
- ;; Having this mode operate in an active minibuffer/echo area
- ;; causes interference with what's going on there.
- (not cursor-in-echo-area)
- (not (eq (selected-window) (minibuffer-window)))))))
-
-;; Internal.
-(defvar eldoc-active-minibuffers-list nil
- "List of active minibuffers with eldoc enabled.")
-(defvar eldoc-mode-line-rolling-flag nil)
-
-(defun eldoc-store-minibuffer ()
- "Store minibuffer buffer name in `eldoc-active-minibuffers-list'.
-This function is called by each minibuffer started with eldoc support.
-See `with-eldoc-in-minibuffer'."
- (with-selected-window (minibuffer-window)
- (push (current-buffer) eldoc-active-minibuffers-list)))
-
-(defmacro with-eldoc-in-minibuffer (&rest body)
- "Enable eldoc support for minibuffer input that runs in BODY."
- (declare (indent 0) (debug t))
- `(let ((timer (and eldoc-in-minibuffer-mode
- (run-with-idle-timer
- eldoc-idle-delay
- 'repeat #'eldoc-run-in-minibuffer))))
- (unwind-protect
- (minibuffer-with-setup-hook
- ;; When minibuffer is activated in body, store it.
- #'eldoc-store-minibuffer
- ,@body)
- (and timer (cancel-timer timer))
- ;; Each time a minibuffer exits or aborts
- ;; its buffer is removed from stack,
- ;; assuming we can only exit the active minibuffer
- ;; on top of stack.
- (setq eldoc-active-minibuffers-list
- (cdr eldoc-active-minibuffers-list)))))
-
-(defun eldoc-current-buffer ()
- "Return the current buffer prior to activating the minibuffer."
- (with-selected-frame (last-nonminibuffer-frame)
- (window-buffer
- (cond (eldoc-in-minibuffer-own-frame-p
- (selected-window))
- ((fboundp 'window-in-direction)
- (window-in-direction
- 'above (minibuffer-window)))
- (t (minibuffer-selected-window))))))
-
-(defun eldoc-show-in-mode-line (str)
- "Display string STR in the mode-line next to minibuffer."
- (let (mode-line-in-non-selected-windows)
- (with-current-buffer (eldoc-current-buffer)
- (make-local-variable 'mode-line-format)
- (let ((mode-line-format (concat " " str)))
- (eldoc-maybe-roll-message-in-mode-line mode-line-format))
- (force-mode-line-update))))
-
-(defun eldoc-maybe-roll-message-in-mode-line (str)
- (let* ((max (window-width (get-buffer-window (eldoc-current-buffer))))
- (len (length str))
- (tmp-str str))
- (if (and (> len max) eldoc-mode-line-rolling-flag)
- (while (sit-for 0.3)
- (setq tmp-str (substring tmp-str 2)
- mode-line-format (concat tmp-str " [<]" str))
- (force-mode-line-update nil)
- (when (< (length tmp-str) 2) (setq tmp-str str)))
- (force-mode-line-update nil)
- (sit-for eldoc-show-in-mode-line-delay))))
-
-(defun eldoc-mode-line-toggle-rolling ()
- (interactive)
- (if (and eldoc-in-minibuffer-mode
- (minibuffer-window-active-p (selected-window)))
- (setq eldoc-mode-line-rolling-flag (not eldoc-mode-line-rolling-flag))
- (error "No active minibuffer found")))
-
-(defvar eldoc-in-minibuffer-mode-map
- (let ((map (make-sparse-keymap)))
- ;; FIXME: Should we use [remap eval-expression] instead?
- (define-key map (kbd "M-:") 'eldoc-eval-expression)
- map))
-
-;;;###autoload
-(define-minor-mode eldoc-in-minibuffer-mode
- "Show eldoc for current minibuffer input."
- :global t
- (if eldoc-in-minibuffer-mode
- (progn
- (add-hook 'minibuffer-exit-hook
- (lambda ()
- (setq eldoc-mode-line-rolling-flag nil)))
- (and (boundp 'eldoc-message-function)
- (setq eldoc-message-function 'message))
- (define-key minibuffer-local-map (kbd "C-@")
- 'eldoc-mode-line-toggle-rolling)
- (setq eldoc-minor-mode-string " Eldoc-eval"))
- (setq eldoc-minor-mode-string " Eldoc")
- (and (boundp 'eldoc-message-function)
- (setq eldoc-message-function eldoc-eval--old-message-function))
- (define-key minibuffer-local-map (kbd "C-@") 'set-mark-command)))
-
-(defun eldoc-run-in-minibuffer ()
- (let ((buf (window-buffer (active-minibuffer-window))))
- ;; If this minibuffer have been started with
- ;;`with-eldoc-in-minibuffer' give it eldoc support
- ;; and update mode-line, otherwise do nothing.
- (condition-case err
- (when (member buf eldoc-active-minibuffers-list)
- (with-current-buffer buf
- (let* ((sym (save-excursion
- (unless (looking-back ")\\|\"")
- (forward-char -1))
- (eldoc-current-symbol)))
- (info-fn (eldoc-fnsym-in-current-sexp))
- (doc (or (eldoc-get-var-docstring sym)
- (eldoc-get-fnsym-args-string
- (car info-fn) (cadr info-fn)))))
- (when doc (funcall eldoc-in-minibuffer-show-fn doc)))))
- (scan-error nil)
- (beginning-of-buffer nil)
- (error (message "Eldoc in minibuffer error: %S" err)))))
-
-;;;###autoload
-(defun eldoc-eval-expression ()
- "Eval expression with eldoc support in mode-line."
- (interactive)
- (with-eldoc-in-minibuffer
- (call-interactively eldoc-eval-preferred-function)))
-
-
-(provide 'eldoc-eval)
-;;; eldoc-eval.el ends here
diff --git a/packages/f90-interface-browser/README.org
b/packages/f90-interface-browser/README.org
deleted file mode 100644
index e620b49..0000000
--- a/packages/f90-interface-browser/README.org
+++ /dev/null
@@ -1,82 +0,0 @@
-* Fortran editing helpers for Emacs
-
-** Overview
-
-You write (or work on) large, modern fortran code bases. These make
-heavy use of function overloading and generic interfaces. Your brain
-is too small to remember what all the specialisers are called.
-Therefore, your editor should help you. This is an attempt to do
-this for Emacs.
-
-f90-interface-browser.el is a (simple-minded) parser of fortran that
-understands a little about generic interfaces and derived types.
-
-** External functions
-
-- =f90-parse-interfaces-in-dir= :: Parse all the fortran files in a
- directory
-- =f90-parse-all-interfaces= :: Parse all the fortran files in a
- directory and recursively in its subdirectories
-- =f90-browse-interface-specialisers= :: Pop up a buffer showing all
- the specialisers for a particular generic interface (prompted
- for with completion)
-- =f90-find-tag-interface= :: On a procedure call, show a list of the
- interfaces that match the (possibly typed) argument list. If no
- interface is found, this falls back to =find-tag=.
-- =f90-list-in-scope-vars= :: List all variables in local scope. This
- just goes to the top of the current procedure and collects named
- variables, so it doesn't work with module or global scope
- variables or local procedures.
-- =f90-show-type-definition= :: Pop up a buffer showing a derived type
- definition.
-
-** Customisable variables
-
-- =f90-file-extensions= :: A list of extensions that the parser will
- use to decide if a file is a fortran file.
-
-** Details and caveats
-
-The parser assumes you write fortran in the style espoused in Metcalf,
-Reid and Cohen. Particularly, variable declarations use a double
-colon to separate the type from the name list.
-
-Here's an example of a derived type definition:
-#+BEGIN_SRC f90
-type foo
- real, allocatable, dimension(:) :: a
- integer, pointer :: b, c(:)
- type(bar) :: d
-end type foo
-#+END_SRC
-
-Here's a subroutine declaration:
-#+BEGIN_SRC f90
-subroutine foo(a, b)
- integer, intent(in) :: a
- real, intent(inout), dimension(:,:) :: b
- ...
-end subroutine foo
-#+END_SRC
-
-Local procedures whose names conflict with global ones will likely
-confuse the parser. For example:
-#+BEGIN_SRC f90
-subroutine foo(a, b)
- ...
-end subroutine foo
-
-subroutine bar(a, b)
- ...
- call subroutine foo
- ...
- contains
- subroutine foo
- ...
- end subroutine foo
-end subroutine bar
-#+END_SRC
-
-Also not handled are overloaded operators, scalar precision modifiers,
-like =integer(kind=c_int)=, for which the precision is just ignored, and
-many other of the hairier aspects of the fortran language.
diff --git a/packages/f90-interface-browser/f90-interface-browser.el
b/packages/f90-interface-browser/f90-interface-browser.el
deleted file mode 100644
index 1b69061..0000000
--- a/packages/f90-interface-browser/f90-interface-browser.el
+++ /dev/null
@@ -1,1032 +0,0 @@
-;;; f90-interface-browser.el --- Parse and browse f90 interfaces
-
-;; Copyright (C) 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc
-
-;; Author: Lawrence Mitchell <wence@gmx.li>
-;; Created: 2011-07-06
-;; URL: http://github.com/wence-/f90-iface/
-;; Version: 1.1
-;; Package-Type: simple
-
-;; COPYRIGHT NOTICE
-
-;; 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:
-;; You write (or work on) large, modern fortran code bases. These
-;; make heavy use of function overloading and generic interfaces. Your
-;; brain is too small to remember what all the specialisers are
-;; called. Therefore, your editor should help you.
-
-;; Load this file and tell it to parse all the fortran files in your
-;; code base. You can do this one directory at a time by calling
-;; `f90-parse-interfaces-in-dir' (M-x f90-parse-interfaces-in-dir
-;; RET). Or you can parse all the fortran files in a directory and
-;; recursively in its subdirectories by calling
-;; `f90-parse-all-interfaces'.
-
-;; Now you are able to browse (with completion) all defined interfaces
-;; in your code by calling `f90-browse-interface-specialisers'.
-;; Alternatively, if `point' is on a procedure call, you can call
-;; `f90-find-tag-interface' and you'll be shown a list of the
-;; interfaces that match the (possibly typed) argument list of the
-;; current procedure. This latter hooks into the `find-tag' machinery
-;; so that you can use it on the M-. keybinding and it will fall back
-;; to completing tag names if you don't want to look for an interface
-;; definition.
-;; In addition, if you're in a large procedure and want the list of
-;; the variables in scope (perhaps you want to define a new loop
-;; variable), you can use `f90-list-in-scope-vars' to pop up a buffer
-;; giving a reasonable guess. Note this doesn't give you module
-;; variables, or the variables of parent procedures if the current
-;; subroutine is contained within another.
-
-;; Derived types are also parsed, so that slot types of derived types
-;; are given the correct type (rather than a UNION-TYPE) when arglist
-;; matching. You can show the definition of a known derived type by
-;; calling `f90-show-type-definition' which prompts (with completion)
-;; for a typename to show.
-
-;; The parser assumes you write Fortran in the style espoused in
-;; Metcalf, Reid and Cohen. Particularly, variable declarations use a
-;; double colon to separate the type from the name list.
-
-;; Here's an example of a derived type definition
-;; type foo
-;; real, allocatable, dimension(:) :: a
-;; integer, pointer :: b, c(:)
-;; type(bar) :: d
-;; end type
-
-;; Here's a subroutine declaration
-;; subroutine foo(a, b)
-;; integer, intent(in) :: a
-;; real, intent(inout), dimension(:,:) :: b
-;; ...
-;; end subroutine foo
-
-;; Local procedures whose names conflict with global ones will likely
-;; confuse the parser. For example
-
-;; subroutine foo(a, b)
-;; ...
-;; end subroutine foo
-;;
-;; subroutine bar(a, b)
-;; ...
-;; call subroutine foo
-;; ...
-;; contains
-;; subroutine foo
-;; ...
-;; end subroutine foo
-;; end subroutine bar
-
-;; Also not handled are overloaded operators, scalar precision
-;; modifiers, like integer(kind=c_int), for which the precision is
-;; just ignored, and many other aspects.
-
-;; Some tests of the parser are available in f90-tests.el (in the same
-;; repository as this file).
-
-;;; Code:
-
-;;; Preamble
-(eval-when-compile (require 'cl))
-(require 'thingatpt)
-(require 'f90)
-(require 'etags)
-
-(defgroup f90-iface nil
- "Static parser for Fortran 90 code"
- :prefix "f90-"
- :group 'f90)
-
-(defcustom f90-file-extensions (list "f90" "F90" "fpp")
- "Extensions to consider when looking for Fortran 90 files."
- :type '(repeat string)
- :group 'f90-iface)
-
-(defcustom f90-file-name-check-functions '(f90-check-fluidity-refcount)
- "List of functions to call to check if a file should be parsed.
-
-In addition to checking if a file exists and is readable, you can
-add extra checks before deciding to parse a file. Each function
-will be called with one argument, the fully qualified name of the
-file to test, it should return non-nil if the file should be
-parsed. For an example test function see
-`f90-check-fluidity-refcount'."
- :type '(repeat function)
- :group 'f90-iface)
-
-(defcustom f90-extra-file-functions '(f90-insert-fluidity-refcount)
- "List of functions to call to insert extra files to parse.
-
-Each function should be a function of two arguments, the first is the
-fully qualified filename (with directory) the second is the
-unqualified filename."
- :type '(repeat function)
- :group 'f90-iface)
-
-;;; Internal variables
-(defvar f90-interface-type nil)
-(make-variable-buffer-local 'f90-interface-type)
-
-(defvar f90-buffer-to-switch-to nil)
-(make-variable-buffer-local 'f90-buffer-to-switch-to)
-
-(defvar f90-invocation-marker nil)
-(make-variable-buffer-local 'f90-invocation-marker)
-
-;; Data types for storing interface and specialiser definitions
-(defstruct f90-interface
- (name "" :read-only t)
- (publicp nil)
- specialisers)
-
-(defstruct f90-specialiser
- (name "" :read-only t)
- (type "")
- (arglist "")
- location)
-
-(defvar f90-all-interfaces (make-hash-table :test 'equal)
- "Hash table populated with all known f90 interfaces.")
-
-(defvar f90-types (make-hash-table :test 'equal)
- "Hash table populated with all known f90 derived types.
-The keys are type names and the values are lists of pairs of the form
-\(NAME . REST) where NAME is the name of a slot of that type and REST
-describes that slot.")
-
-;;; Inlineable utility functions
-(defsubst f90-specialisers (name interfaces)
- "Return all specialisers for NAME in INTERFACES."
- (f90-interface-specialisers (f90-get-interface name interfaces)))
-
-(defsubst f90-valid-interface-name (name)
- "Return non-nil if NAME is an interface name."
- (gethash name f90-all-interfaces))
-
-(defsubst f90-count-commas (str &optional level)
- "Count commas in STR.
-
-If LEVEL is non-nil, only count commas up to the specified nesting
-level. For example, a LEVEL of 0 counts top-level commas."
- (1- (length (f90-split-arglist str level))))
-
-(defsubst f90-get-parsed-type-varname (type)
- "Return the variable name of TYPE."
- (car type))
-
-(defsubst f90-get-parsed-type-typename (type)
- "Return the type name of TYPE."
- (cadr type))
-
-(defsubst f90-get-parsed-type-modifiers (type)
- "Return the modifiers of TYPE."
- (cddr type))
-
-(defsubst f90-get-type (type)
- "Return the struct definition corresponding to TYPE."
- (gethash (f90-get-parsed-type-typename type) f90-types))
-
-(defsubst f90-get-slot-type (slot type)
- "Get the type of SLOT in TYPE."
- (assoc slot (f90-get-type type)))
-
-(defsubst f90-merge-into-tags-completion-table (ctable)
- "Merge completions in CTABLE into the tags completion table."
- (if (or tags-file-name tags-table-list)
- (let ((table (tags-completion-table)))
- (maphash (lambda (k v)
- (ignore v)
- (intern k table))
- ctable)
- table)
- ctable))
-
-(defun f90-lazy-completion-table ()
- "Lazily produce a completion table of all interfaces and tag names."
- (lexical-let ((buf (current-buffer)))
- (lambda (string pred action)
- (with-current-buffer buf
- (save-excursion
- ;; If we need to ask for the tag table, allow that.
- (let ((enable-recursive-minibuffers t))
- (visit-tags-table-buffer))
- (complete-with-action action (f90-merge-into-tags-completion-table
f90-all-interfaces) string pred))))))
-
-(defsubst f90-extract-type-name (name)
- "Return the typename from NAME.
-
-If NAME is like type(TYPENAME) return TYPENAME, otherwise just NAME."
- (if (and name (string-match "\\`type(\\([^)]+\\))\\'" name))
- (match-string 1 name)
- name))
-
-;;; User-visible routines
-
-(defun f90-parse-all-interfaces (dir)
- "Parse all interfaces found in DIR and its subdirectories.
-
-Recurse over all (non-hidden) directories below DIR and parse
-interfaces found within them using `f90-parse-interfaces-in-dir',
-a directory is considered hidden if its name doesn't start with
-an alphanumeric character."
- (interactive "DParse files in tree: ")
- (let (dirs
- attrs
- seen
- (pending (list (expand-file-name dir))))
- (while pending
- (push (pop pending) dirs)
- (let* ((this-dir (car dirs))
- (contents (directory-files this-dir))
- (default-directory this-dir))
- (setq attrs (nthcdr 10 (file-attributes this-dir)))
- (unless (member attrs seen)
- (push attrs seen)
- (dolist (file contents)
- ;; Ignore hidden directories
- (and (string-match "\\`[[:alnum:]]" file)
- (file-directory-p file)
- (setq pending (nconc pending
- (list (expand-file-name file)))))))))
- (mapc 'f90-parse-interfaces-in-dir dirs)))
-
-(defun f90-parse-interfaces-in-dir (dir)
- "Parse all Fortran 90 files in DIR to populate `f90-all-interfaces'."
- (interactive "DParse files in directory: ")
- (loop for file in (directory-files dir t
- (rx-to-string
- `(and "." (or ,@f90-file-extensions)
- eos)
- t))
- do (f90-parse-interfaces file f90-all-interfaces)))
-
-(defun f90-find-tag-interface (name &optional match-sublist)
- "List all interfaces matching NAME.
-
-Restricts list to those matching the (possibly typed) arglist of
-the word at point. If MATCH-SUBLIST is non-nil, only check if
-the arglist is a sublist of the specialiser's arglist. For more
-details see `f90-approx-arglist-match' and
-`f90-browse-interface-specialisers'."
- (interactive (let ((def (thing-at-point 'symbol)))
- (list (completing-read
- (format "Find interface/tag (default %s): " def)
- (f90-lazy-completion-table)
- nil t nil nil def)
- current-prefix-arg)))
- (if (f90-valid-interface-name name)
- (f90-browse-interface-specialisers name (f90-arglist-types)
- match-sublist
- (point-marker))
- (find-tag name match-sublist)))
-
-(defun f90-browse-interface-specialisers (name &optional arglist-to-match
- match-sublist
- invocation-point)
- "Browse all interfaces matching NAME.
-
-If ARGLIST-TO-MATCH is non-nil restrict to those interfaces that match
-it.
-If MATCH-SUBLIST is non-nil only restrict to those interfaces for
-which ARGLIST-TO-MATCH is a sublist of the specialiser's arglist.
-
-If INVOCATION-POINT is non-nil it should be a `point-marker'
-indicating where we were called from, for jumping back to with
-`pop-tag-mark'."
- (interactive (let ((def (thing-at-point 'symbol)))
- (list (completing-read
- (format "Interface%s: "
- (if def
- (format " (default %s)" def)
- ""))
- f90-all-interfaces
- nil t nil nil def))))
- (let ((buf (current-buffer)))
- (or invocation-point (setq invocation-point (point-marker)))
- (with-current-buffer (get-buffer-create "*Interface Browser*")
- (let ((interface (f90-get-interface name f90-all-interfaces))
- (type nil)
- (n-specs 0))
- (setq buffer-read-only nil)
- (erase-buffer)
- (setq n-specs
- (loop for s being the hash-values of
- (f90-interface-specialisers interface)
- do (setq type (f90-specialiser-type s))
- when (or (null arglist-to-match)
- (f90-approx-arglist-match
- arglist-to-match s match-sublist))
- do (insert
- (propertize
- (concat
- (propertize
- (format "%s [defined in %s]\n (%s)\n"
- (propertize (f90-specialiser-name s)
- 'face 'bold)
- (let ((f (car
- (f90-specialiser-location s))))
- (format "%s/%s"
- (file-name-nondirectory
- (directory-file-name
- (file-name-directory f)))
- (file-name-nondirectory f)))
- (f90-fontify-arglist
- (f90-specialiser-arglist s)))
- 'f90-specialiser-location
- (f90-specialiser-location s)
- 'f90-specialiser-name (f90-specialiser-name s)
- 'mouse-face 'highlight
- 'help-echo
- "mouse-1: find definition in other window")
- "\n")
- 'f90-specialiser-extent (f90-specialiser-name s)))
- and count 1))
- (goto-char (point-min))
- (insert (format "Interfaces for %s:\n\n"
- (f90-interface-name interface)))
- (when arglist-to-match
- (insert (format "%s\n%s\n\n"
- (if (zerop n-specs)
- "No interfaces matching arglist (intrinsic?):"
- "Only showing interfaces matching arglist:")
- (f90-fontify-arglist arglist-to-match))))
- (f90-interface-browser-mode)
- (setq f90-buffer-to-switch-to buf)
- (setq f90-interface-type type)
- (setq f90-invocation-marker invocation-point)
- (pop-to-buffer (current-buffer))))))
-
-(defun f90-next-definition (&optional arg)
- "Go to the next ARG'th specialiser definition."
- (interactive "p")
- (unless arg
- (setq arg 1))
- (while (> arg 0)
- (goto-char (next-single-property-change
- (point)
- 'f90-specialiser-extent
- nil (point-max)))
- (decf arg)))
-
-(defun f90-previous-definition (&optional arg)
- "Go to the previous ARG'th specialiser definition."
- (interactive "p")
- (unless arg
- (setq arg 1))
- (while (> arg 0)
- (loop repeat 2
- do (goto-char (previous-single-property-change
- (point)
- 'f90-specialiser-extent
- nil (point-min))))
- (f90-next-definition 1)
- (decf arg)))
-
-(defun f90-mouse-find-definition (e)
- "Visit the definition at the position of the event E."
- (interactive "e")
- (let ((win (posn-window (event-end e)))
- (point (posn-point (event-end e))))
- (when (not (windowp win))
- (error "No definition here"))
- (with-current-buffer (window-buffer win)
- (goto-char point)
- (f90-find-definition))))
-
-(defun f90-quit-browser ()
- "Quit the interface browser."
- (interactive)
- (let ((buf f90-buffer-to-switch-to))
- (kill-buffer (current-buffer))
- (pop-to-buffer buf)))
-
-(defun f90-find-definition ()
- "Visit the definition at `point'."
- (interactive)
- (let ((location (get-text-property (point) 'f90-specialiser-location))
- (name (get-text-property (point) 'f90-specialiser-name))
- (type f90-interface-type)
- (buf (current-buffer))
- buf-to)
- (if location
- (progn (ring-insert find-tag-marker-ring f90-invocation-marker)
- (find-file-other-window (car location))
- (setq buf-to (current-buffer))
- (goto-char (cadr location))
- ;; Try forwards then backwards near the recorded
- ;; location
- (or (re-search-forward (format "%s[ \t]+%s[ \t]*("
- type name) nil t)
- (re-search-backward (format "%s[ \t]+%s[ \t]*("
- type name) nil t))
- (beginning-of-line)
- (recenter 0)
- (pop-to-buffer buf)
- (setq f90-buffer-to-switch-to buf-to))
- (error "No definition at point"))))
-
-(defvar f90-interface-browser-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "RET") 'f90-find-definition)
- (define-key map (kbd "<down>") 'f90-next-definition)
- (define-key map (kbd "TAB") 'f90-next-definition)
- (define-key map (kbd "<up>") 'f90-previous-definition)
- (define-key map (kbd "<backtab>") 'f90-previous-definition)
- (define-key map (kbd "q") 'f90-quit-browser)
- (define-key map (kbd "<mouse-1>") 'f90-mouse-find-definition)
- map)
- "Keymap for `f90-interface-browser-mode'.")
-
-(define-derived-mode f90-interface-browser-mode fundamental-mode "IBrowse"
- "Major mode for browsing f90 interfaces."
- (setq buffer-read-only t)
- (set-buffer-modified-p nil))
-
-;;; Type definitions
-
-(defun f90-type-at-point ()
- "Return a guess for the type of the thing at `point'.
-
-If `point' is currently on a line containing a variable declaration,
-return the typename of the declaration. Otherwise try and figure out
-the typename of the variable at point (possibly including slot
-references)."
- (let ((name (or
- ;; Are we on a line with type(TYPENAME)?
- (save-excursion
- (forward-line 0)
- (f90-parse-single-type-declaration))
- ;; No, try and derive the type of the variable at point
- (save-excursion
- (let ((syntax (copy-syntax-table f90-mode-syntax-table)))
- (modify-syntax-entry ?% "w" syntax)
- (with-syntax-table syntax
- (skip-syntax-backward "w")
- (f90-arg-types
- (list
- (buffer-substring-no-properties
- (point)
- (progn (skip-syntax-forward "w") (point)))))))))))
- (f90-extract-type-name (f90-get-parsed-type-typename (car name)))))
-
-(defun f90-show-type-definition (type)
- "Show the definition of TYPE.
-
-This formats the parsed definition of TYPE, rather than jumping to the
-existing definition.
-
-When called interactively, default to the type of the thing at `point'.
-If `point' is on a type declaration line, the default is the
-declaration type.
-If `point' is on a variable name (possibly with slot references) the
-default is the type of the variable."
- (interactive (list (let ((def (f90-type-at-point)))
- (completing-read
- (if def (format "Type (default %s): " def) "Type: ")
- (loop for type being the hash-keys of f90-types
- collect (f90-extract-type-name type))
- nil t nil nil def))))
- (with-current-buffer (get-buffer-create "*Type definition*")
- (setq buffer-read-only nil)
- (fundamental-mode)
- (erase-buffer)
- (let* ((tname (format "type(%s)" type))
- (slots (f90-get-type (list nil tname))))
- (if (null slots)
- (insert (format "The type %s is not a known derived type."
- type))
- (insert (format "type %s\n" type))
- (loop for slot in slots
- do
- (insert (format " %s :: %s\n"
- (f90-format-parsed-slot-type slot)
- (f90-get-parsed-type-varname slot))))
- (insert (format "end type %s\n" type))
- (f90-mode))
- (goto-char (point-min))
- (view-mode)
- (pop-to-buffer (current-buffer)))))
-
-;;; Arglist matching/formatting
-
-(defun f90-format-parsed-slot-type (type)
- "Turn a parsed TYPE into a valid f90 type declaration."
- (if (null type)
- "UNION-TYPE"
- ;; Ignore name
- (setq type (cdr type))
- (mapconcat #'identity (loop for a in type
- if (and (consp a)
- (string= (car a) "dimension"))
- collect (format "dimension(%s)"
- (mapconcat #'identity
- (make-list (cdr a)
- ":")
- ","))
- else if (not
- (string-match
- "\\`intent(\\(?:in\\|out\\|inout\\))"
- a))
- collect a)
- ", ")))
-
-(defun f90-fontify-arglist (arglist)
- "Fontify ARGLIST using `f90-mode'."
- (with-temp-buffer
- (if (stringp arglist)
- (insert (format "%s :: foo\n" arglist))
- (insert (mapconcat (lambda (x)
- (format "%s :: foo" (f90-format-parsed-slot-type
x)))
- arglist "\n")))
- (f90-mode)
- (if (fboundp 'font-lock-ensure)
- (font-lock-ensure)
- (with-no-warnings (font-lock-fontify-buffer)))
- (goto-char (point-min))
- (mapconcat #'identity
- (loop while (not (eobp))
- collect (buffer-substring (line-beginning-position)
- (- (line-end-position)
- (length " :: foo")))
- do (forward-line 1))
- "; ")))
-
-(defun f90-count-non-optional-args (arglist)
- "Count non-optional args in ARGLIST."
- (loop for arg in arglist
- count (not (member "optional" (f90-get-parsed-type-modifiers arg)))))
-
-(defun f90-approx-arglist-match (arglist specialiser &optional match-sub-list)
- "Return non-nil if ARGLIST matches the arglist of SPECIALISER.
-
-If MATCH-SUB-LIST is non-nil just require that ARGLIST matches the
-first (length ARGLIST) args of SPECIALISER."
- (let* ((n-passed-args (length arglist))
- (spec-arglist (f90-specialiser-arglist specialiser))
- (n-spec-args (length spec-arglist))
- (n-required-args (f90-count-non-optional-args spec-arglist)))
- (when (or match-sub-list
- (and (<= n-required-args n-passed-args)
- (<= n-passed-args n-spec-args)))
- (loop for arg in arglist
- for spec-arg in spec-arglist
- unless (or (null arg)
- (string= (f90-get-parsed-type-typename arg)
- (f90-get-parsed-type-typename spec-arg)))
- do (return nil)
- finally (return t)))))
-
-;;; Internal functions
-
-(defun f90-clean-comments ()
- "Clean Fortran 90 comments from the current buffer."
- (save-excursion
- (goto-char (point-min))
- (set-syntax-table f90-mode-syntax-table)
- (while (search-forward "!" nil t)
- (when (nth 4 (parse-partial-sexp (line-beginning-position) (point)))
- (delete-region (max (1- (point)) (line-beginning-position))
- (line-end-position))))))
-
-(defun f90-clean-continuation-lines ()
- "Splat Fortran continuation lines in the current buffer onto one line."
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "&[ \t]*\n[ \t]*&?" nil t)
- (replace-match "" nil t))))
-
-(defun f90-normalise-string (string)
- "Return a suitably normalised version of STRING."
- ;; Trim whitespace
- (save-match-data
- (when (string-match "\\`[ \t]+" string)
- (setq string (replace-match "" t t string)))
- (when (string-match "[ \t]+\\'" string)
- (setq string (replace-match "" t t string)))
- (downcase string)))
-
-(defun f90-get-interface (name &optional interfaces)
- "Get the interface with NAME from INTERFACES.
-
-If INTERFACES is nil use `f90-all-interfaces' instead."
- (gethash name (or interfaces f90-all-interfaces)))
-
-(defsetf f90-get-interface (name &optional interfaces) (val)
- `(setf (gethash ,name (or ,interfaces f90-all-interfaces)) ,val))
-
-;;; Entry point to parsing routines
-
-(defun f90-parse-file-p (file)
- "Return non-nil if FILE should be parsed.
-
-This checks that FILE exists and is readable, and then calls
-additional test functions from `f90-file-name-check-functions'."
- (and (file-exists-p file)
- (file-readable-p file)
- (loop for test in f90-file-name-check-functions
- unless (funcall test file)
- do (return nil)
- finally (return t))))
-
-(defun f90-check-fluidity-refcount (file)
- "Return nil if FILE is that of a Fluidity refcount template."
- (let ((fname (file-name-nondirectory file)))
- (and (not (string-match "\\`Reference_count_interface" fname))
- (not (string-equal "Refcount_interface_templates.F90" fname))
- (not (string-equal "Refcount_templates.F90" fname)))))
-
-(defun f90-maybe-insert-extra-files (file)
- "Maybe insert extra files corresponding to FILE when parsing.
-
-To actually insert extra files, customize the variable
-`f90-extra-file-functions'. For an example insertion function
-see `f90-insert-fluidity-refcount'."
- (let ((fname (file-name-nondirectory file)))
- (loop for fn in f90-extra-file-functions
- do (funcall fn file fname))))
-
-(defun f90-insert-fluidity-refcount (file fname)
- "Insert a Fluidity reference count template for FILE.
-
-If FNAME matches \\\\=`Reference_count_\\([^\\.]+\\)\\.F90 then this file
-needs a reference count interface, so insert one."
- (when (string-match "\\`Reference_count_\\([^\\.]+\\)\\.F90" fname)
- (insert-file-contents-literally
- (expand-file-name
- (format "Reference_count_interface_%s.F90"
- (match-string 1 fname))
- (file-name-directory file)))))
-
-(defun f90-parse-interfaces (file existing)
- "Parse interfaces in FILE and merge into EXISTING interface data."
- (with-temp-buffer
- (let ((interfaces (make-hash-table :test 'equal)))
- ;; Is this file valid for parsing
- (when (f90-parse-file-p file)
- (insert-file-contents-literally file)
- ;; Does this file have other parts elsewhere?
- (f90-maybe-insert-extra-files file)
- ;; Easier if we don't have to worry about line wrap
- (f90-clean-comments)
- (f90-clean-continuation-lines)
- (goto-char (point-min))
- ;; Search forward for a named interface block
- (while (re-search-forward
- "^[ \t]*interface[ \t]+\\([^ \t\n]+\\)[ \t]*$" nil t)
- (let* ((name (f90-normalise-string (match-string 1)))
- interface)
- (unless (string= name "")
- (setq interface (make-f90-interface :name name))
- (save-restriction
- ;; Figure out all the specialisers for this generic name
- (narrow-to-region
- (point)
- (re-search-forward
- (format "[ \t]*end interface\\(?:[ \t]+%s\\)?[ \t]*$" name)
- nil t))
- (f90-populate-specialisers interface))
- ;; Multiple interface blocks with same name (this seems to
- ;; be allowed). In which case merge rather than overwrite.
- (if (f90-get-interface name interfaces)
- (f90-merge-interface interface interfaces)
- (setf (f90-get-interface name interfaces) interface)))))
- (goto-char (point-min))
- ;; Parse type definitions
- (save-excursion
- (while (re-search-forward
- "^[ \t]*type[ \t]+\\(?:[^ \t\n]+\\)[ \t]*$" nil t)
- (let ((beg (match-beginning 0)))
- (unless (re-search-forward "^[ \t]*end[ \t]+type.*$" nil t)
- (error "Unable to find end of type definition"))
- (save-restriction
- (narrow-to-region beg (match-beginning 0))
- (f90-parse-type-definition)))))
-
- ;; Now find out if an interface is public or private to the module
- (f90-set-public-attribute interfaces)
-
- ;; Now find the arglists corresponding to the interface (so we
- ;; can disambiguate) and record their location in the file.
- (loop for interface being the hash-values of interfaces
- do (when (f90-interface-specialisers interface)
- (maphash (lambda (specialiser val)
- (save-excursion
- (goto-char (point-min))
- (let ((thing (f90-argument-list specialiser)))
- (setf (f90-specialiser-arglist
- val)
- (cadr thing))
- (setf (f90-specialiser-location
- val)
- (list file (caddr thing)))
- (setf (f90-specialiser-type
- val)
- (car thing)))))
- (f90-interface-specialisers interface))))
- ;; Finally merge these new interfaces into the existing data.
- (f90-merge-interfaces interfaces existing)))))
-
-(defun f90-merge-interface (interface interfaces)
- "Merge INTERFACE into the existing set of INTERFACES."
- (let ((name (f90-interface-name interface))
- spec-name)
- (when (f90-interface-specialisers interface)
- (loop for val being the hash-values of
- (f90-interface-specialisers interface)
- do (setq spec-name (f90-specialiser-name val))
- (setf (gethash spec-name (f90-specialisers name interfaces))
- val)))))
-
-(defun f90-merge-interfaces (new existing)
- "Merge NEW interfaces into EXISTING ones."
- (maphash (lambda (name val)
- (if (gethash name existing)
- (f90-merge-interface val existing)
- (setf (gethash name existing)
- val)))
- new))
-
-(defun f90-populate-specialisers (interface)
- "Find all specialisers for INTERFACE."
- (save-excursion
- (goto-char (point-min))
- (setf (f90-interface-specialisers interface)
- (make-hash-table :test 'equal))
- (while (search-forward "module procedure" nil t)
- (let ((names (buffer-substring-no-properties
- (point)
- (line-end-position))))
- (mapc (lambda (x)
- (setq x (f90-normalise-string x))
- (setf (gethash x (f90-interface-specialisers interface))
- (make-f90-specialiser :name x)))
- (split-string names "[, \n]+" t))))))
-
-(defun f90-set-public-attribute (interfaces)
- "Set public/private flag on all INTERFACES."
- (save-excursion
- ;; Default public unless private is specified.
- (let ((public (not (save-excursion
- (re-search-forward "^[ \t]*private[ \t]*$" nil t)))))
- (while (re-search-forward (format "^[ \t]*%s[ \t]+"
- (if public "private" "public"))
- nil t)
- (let ((names (buffer-substring-no-properties
- (match-end 0)
- (line-end-position))))
- ;; Set default
- (maphash (lambda (k v)
- (ignore k)
- (setf (f90-interface-publicp v) public))
- interfaces)
- ;; Override for those specified
- (mapc (lambda (name)
- (let ((interface (f90-get-interface name interfaces)))
- (when interface
- (setf (f90-interface-publicp interface) (not public)))))
- (split-string names "[, \t]" t)))))))
-
-;;; Type/arglist parsing
-(defun f90-argument-list (name)
- "Return typed argument list of function or subroutine NAME."
- (save-excursion
- (when (re-search-forward
- (format "\\(function\\|subroutine\\)[ \t]+%s[ \t]*("
- name)
- nil t)
- (let* ((point (match-beginning 0))
- (type (match-string 1))
- (args (f90-split-arglist (buffer-substring-no-properties
- (point)
- (f90-end-of-arglist)))))
- (list type (f90-arg-types args) point)))))
-
-(defun f90-parse-type-definition ()
- "Parse a type definition at (or in front of) `point'."
- (goto-char (point-min))
- (unless (re-search-forward "^[ \t]*type[ \t]+\\(.+?\\)[ \t]*$" nil t)
- (error "Trying parse a type but no type found"))
- (let ((type (format "type(%s)" (f90-normalise-string (match-string 1))))
- (slots ()))
- (while (not (eobp))
- (let ((slot (f90-parse-single-type-declaration)))
- (when slot
- (setf slots (nconc slot slots)))
- (forward-line 1)))
- (setf (gethash type f90-types) slots)))
-
-(defun f90-arglist-types ()
- "Return the types of the arguments to the function at `point'."
- (save-excursion
- (let* ((e (save-excursion (f90-end-of-subprogram) (point)))
- (b (save-excursion (f90-beginning-of-subprogram) (point)))
- (str (buffer-substring-no-properties b e))
- (p (point))
- names)
- (with-temp-buffer
- (with-syntax-table f90-mode-syntax-table
- (insert str)
- (goto-char (- p b))
- (setq p (point-marker))
- (f90-clean-continuation-lines)
- (goto-char p)
- (search-forward "(")
- (setq names (f90-split-arglist (buffer-substring
- (point)
- (f90-end-of-arglist))))
- (goto-char (point-min))
- (f90-arg-types names))))))
-
-(defun f90-list-in-scope-vars ()
- "Pop up a buffer showing all variables in scope in the procedure at `point'"
- (interactive)
- (let* ((e (save-excursion (f90-end-of-subprogram) (point)))
- (b (save-excursion (f90-beginning-of-subprogram) (point)))
- (str (buffer-substring-no-properties b e))
- types)
- (with-temp-buffer
- (with-syntax-table f90-mode-syntax-table
- (insert str)
- (goto-char (point-min))
- (f90-clean-comments)
- (f90-clean-continuation-lines)
- (forward-line 1) ; skip procedure name
- (let ((not-done t)
- type)
- (while (and not-done (not (eobp)))
- ;; skip "implicit none" which may appear at top of procedure
- (when (looking-at "\\s-*implicit\\s-+none")
- (forward-line 1))
- (when (not (looking-at "^\\s-*$"))
- (setq type (ignore-errors (f90-parse-single-type-declaration)))
- ;; If we were on a line with text and failed to parse a
- ;; type, we must have reached the end of the type
- ;; definitions, so don't push it on and finish.
- (if type
- (push type types)
- (setq not-done nil)))
- (forward-line 1)))))
- (with-current-buffer (get-buffer-create "*Variables in scope*")
- (setq buffer-read-only nil)
- (erase-buffer)
- (f90-mode)
- ;; Show types of the same type together
- (setq types (sort types (lambda (x y)
- (string< (cadar x) (cadar y)))))
- (loop for (type _name) in types
- do
- (insert (format "%s :: %s\n"
- (f90-format-parsed-slot-type type)
- (f90-get-parsed-type-varname type))))
- (pop-to-buffer (current-buffer))
- (goto-char (point-min))
- (setq buffer-read-only t))))
-
-(defun f90-arg-types (names)
- "Given NAMES of arguments return their types.
-
-This works even with derived type subtypes (e.g. if A is a type(foo)
-with slot B of type REAL, then A%B is returned being a REAL)."
- (loop for arg in names
- for subspec = nil then nil
- do (setq arg (f90-normalise-string arg))
- if (string-match "\\`\\([^%]+?\\)[ \t]*%\\(.+\\)\\'" arg)
- do (setq subspec (match-string 2 arg)
- arg (match-string 1 arg))
- collect (save-excursion
- (save-restriction
- (when (re-search-forward
- (format "^[ \t]*\\([^!\n].+?\\)[ \t]*::.*\\_<%s\\_>"
- arg) nil t)
- (goto-char (match-beginning 0))
- (let ((type (assoc arg
- (f90-parse-single-type-declaration))))
- (f90-get-type-subtype type subspec)))))))
-
-(defun f90-get-type-subtype (type subspec)
- "Return the type of TYPE possibly including slot references in SUBSPEC."
- (cond ((null subspec)
- type)
- ((string-match "\\`\\([^%]+?\\)[ \t]*%\\(.+\\)\\'" subspec)
- (f90-get-type-subtype (f90-get-slot-type (match-string 1 subspec)
- type)
- (match-string 2 subspec)))
- (t
- (f90-get-slot-type subspec type))))
-
-(defun f90-split-arglist (arglist &optional level)
- "Split ARGLIST into words.
-
-Split based on top-level commas. For example
-
- (f90-split-arglist \"foo, bar, baz(quux, zot)\")
- => (\"foo\" \"bar\" \"baz(quux, zot)\").
-
-If LEVEL is non-nil split on commas up to and including LEVEL.
-For example:
-
- (f90-split-arglist \"foo, bar, baz(quux, zot)\" 1)
- => (\"foo\" \"bar\" \"baz(quux\" \"zot)\")."
- (setq level (or level 0))
- (loop for c across arglist
- for i = 0 then (1+ i)
- with cur-level = 0
- with b = 0
- with len = (length arglist)
- if (eq c ?\()
- do (incf cur-level)
- else if (eq c ?\))
- do (decf cur-level)
- if (and (<= cur-level level)
- (eq c ?,))
- collect (f90-normalise-string (substring arglist b i))
- and do (setq b (1+ i))
- if (and (<= cur-level level)
- (= (1+ i) len))
- collect (f90-normalise-string (substring arglist b))))
-
-(defun f90-end-of-arglist ()
- "Find the end of the arglist at `point'."
- (save-excursion
- (let ((level 0))
- (while (> level -1)
- (cond ((eq (char-after) ?\()
- (incf level))
- ((eq (char-after) ?\))
- (decf level))
- (t nil))
- (forward-char)))
- (1- (point))))
-
-(defun f90-parse-names-list (names)
- "Return a list of NAMES from the RHS of a :: type declaration."
- (let ((names-list (f90-split-arglist names)))
- (loop for name in names-list
- if (string-match "\\`\\([^=]+\\)[ \t]*=.*\\'" name)
- collect (f90-normalise-string (match-string 1 name))
- else
- collect (f90-normalise-string name))))
-
-(defun f90-parse-single-type-declaration ()
- "Parse a single f90 type declaration at `point'.
-
-Assumes that this has the form
- TYPENAME[, MODIFIERS]* :: NAME[, NAMES]*
-
-NAMES can optionally have initialisation attached to them which is
-dealt with correctly."
- (when (looking-at "^[ \t]*\\(.*?\\)[ \t]*::[ \t]*\\(.*\\)$")
- (let ((dec-orig (match-string 1))
- (names (f90-parse-names-list (match-string 2))))
- (loop for name in names
- for dec = (f90-split-declaration dec-orig)
- then (f90-split-declaration dec-orig)
- if (string-match "\\([^(]+\\)(\\([^)]+\\))" name)
- do (progn (if (assoc "dimension" dec)
- (setcdr (assoc "dimension" dec)
- (1+ (f90-count-commas
- (match-string 2 name))))
- (push (cons "dimension"
- (1+ (f90-count-commas
- (match-string 2 name))))
- dec))
- (setq name (match-string 1 name)))
- collect (cons name (nreverse dec))))))
-
-(defun f90-split-declaration (dec)
- "Split and parse a type declaration DEC.
-
-This takes the bit before the :: and returns a list of the typename
-and any modifiers."
- (let ((things (f90-split-arglist dec)))
- (cons (if (string-match
- "\\([^(]+?\\)[ \t]*([ \t]*\\(:?len\\|kind\\)[ \t]*=[^)]+)"
- (car things))
- (match-string 1 (car things))
- (car things))
- (loop for thing in (cdr things)
- if (string-match "dimension[ \t]*(\\(.+\\))" thing)
- collect (cons "dimension"
- (1+ (f90-count-commas (match-string 1 thing))))
- else
- collect thing))))
-
-(provide 'f90-interface-browser)
-
-;;; f90-interface-browser.el ends here
diff --git a/packages/f90-interface-browser/f90-tests.el
b/packages/f90-interface-browser/f90-tests.el
deleted file mode 100644
index 5f221a6..0000000
--- a/packages/f90-interface-browser/f90-tests.el
+++ /dev/null
@@ -1,120 +0,0 @@
-;;; f90-tests.el --- Tests for f90-interface-browser
-
-;; Copyright (C) 2013 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'cl-lib)
-
-;; FIXME: Convert to use ERT.
-
-(defvar *test-name* nil)
-
-(defvar *test-tests* (make-hash-table :test 'eq))
-
-(defvar *test-running-tests* nil)
-(defmacro deftest (name parameters &rest body)
- "Define a test function. Within a test function we can call
- other test functions or use `check' to run individual test
- cases."
- `(prog1 ',name
- (setf (gethash ',name *test-tests*)
- (lambda ,parameters
- (let ((*test-name* (append *test-name* (list ',name))))
- ,@body)))))
-
-(defmacro test-check (&rest forms)
- "Run each expression in FORMS as a test case."
- `(test-combine-results
- ,@(cl-loop for (expr res) in forms
- collect `(test-report-result (equal (condition-case _
- ,expr
- (error (cl-gensym)))
- ',res)
- ',expr ',res))))
-
-(defmacro test-combine-results (&rest forms)
- "Combine the results (as booleans) of evaluating FORMS in order."
- (let ((result (make-symbol "result")))
- `(let ((,result t))
- ,@(cl-loop for f in forms collect `(unless ,f (setf ,result nil)))
- ,result)))
-
-(defun test-report-result (result res req)
- "Report the results of a single test case. Called by `check'."
- (if result
- (insert (format "%s ... %S: %S\n"
- (propertize "pass"
- 'face '(:weight bold :foreground "green"))
- *test-name* res))
- (insert (format "%s ... %S: %S is not %S\n"
- (propertize "FAIL"
- 'face '(:weight bold :foreground "red"))
- *test-name*
- res req)))
- result)
-
-(defun test-run-test (name)
- (with-current-buffer (get-buffer-create "*test-results*")
- (unless *test-running-tests*
- (erase-buffer))
- (let ((*test-running-tests* t))
- (funcall (gethash name *test-tests*)))
- (pop-to-buffer (current-buffer))))
-
-(deftest type-modifiers ()
- (test-check
- ((f90-split-declaration "integer") ("integer"))
- ((f90-split-declaration "integer, pointer") ("integer" "pointer"))
- ((f90-split-declaration "integer (kind = c_int(8) )") ("integer"))
- ((f90-split-declaration "character(len=*)") ("character"))
- ((f90-split-declaration "integer, dimension(:)")
- ("integer" ("dimension" . 1)))))
-
-(deftest parse-declaration ()
- (cl-flet ((fun (str) (with-temp-buffer
- (insert str)
- (goto-char (point-min))
- (f90-parse-single-type-declaration))))
- (test-check
- ((fun "integer :: name") (("name" "integer")))
- ((fun "integer :: name1, name2") (("name1" "integer")
- ("name2" "integer")))
- ((fun "integer, dimension(:) :: name1, name2(:, :)") (("name1" "integer"
- ("dimension" . 1))
- ("name2" "integer"
- ("dimension" .
2))))
- ((fun "integer, pointer :: name(:, :)") (("name" "integer" "pointer"
- ("dimension" . 2))))
- ((fun "integer, pointer :: NAmE => null()") (("name" "integer"
"pointer"))))))
-
-
-(deftest splits ()
- (test-check
- ((f90-count-commas ",") 1)
- ((f90-count-commas "(,)") 0)
- ((f90-count-commas "a, b, size(c, d)") 2)
- ((f90-count-commas "a, b, size(c, d)" 1) 3)
- ((f90-split-arglist "a,B") ("a" "b"))
- ((f90-split-arglist "foo, dimension(1, size(a, b))")
- ("foo" "dimension(1, size(a, b))"))
- ((f90-parse-names-list "a=1, B=>null()") ("a" "b"))))
-
-(deftest all ()
- (test-combine-results
- (test-run-test 'type-modifiers)
- (test-run-test 'parse-declaration)
- (test-run-test 'splits)))
diff --git a/packages/ioccur/ioccur.el b/packages/ioccur/ioccur.el
deleted file mode 100644
index e88ca3d..0000000
--- a/packages/ioccur/ioccur.el
+++ /dev/null
@@ -1,1116 +0,0 @@
-;;; ioccur.el --- Incremental occur -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2010-2020 Free Software Foundation, Inc.
-
-;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
-;; X-URL: https://github.com/thierryvolpiatto/ioccur
-;; Version: 2.4
-;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
-
-;; 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; if not, see <http://www.gnu.org/licenses/>.
-
-;;; Install:
-;;
-;; Add this file to your `load-path', BYTE-COMPILE it and
-;; add (require 'ioccur) in your .emacs.
-;;
-;; Start with (C-u) M-x ioccur
-;; or
-;; (C-u) M-x ioccur-find-buffer-matching
-;;
-;; Do C-h f ioccur or ioccur-find-buffer-matching for more info.
-
-;;; Commentary:
-;;
-;; This package provides the command M-x ioccur, which is similar to
-;; M-x occur, except that it is incremental.
-;;
-;; You can jump and quit to an occurrence, or jump and save the search
-;; buffer (ioccur-buffer) for further use. You can toggle literal and
-;; regexp searching while running. It is auto documented both in
-;; mode-line and tooltip. It has its own history, `ioccur-history',
-;; which is a real ring.
-;;
-;; To save `ioccur-history' via the Desktop package, add this to your
-;; init file (see (info "(emacs) Saving Emacs Sessions") for details):
-;;
-;; (add-to-list 'desktop-globals-to-save 'ioccur-history)
-
-;;; Code:
-(require 'derived)
-(eval-when-compile (require 'cl-lib))
-(require 'outline)
-(eval-when-compile (require 'wdired))
-
-(defvar ioccur-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "q") 'ioccur-quit)
- (define-key map (kbd "RET") 'ioccur-jump-and-quit)
- (define-key map (kbd "<left>") 'ioccur-jump-and-quit)
- (define-key map (kbd "<right>") 'ioccur-jump-without-quit)
- (define-key map (kbd "C-z") 'ioccur-jump-without-quit)
- (define-key map (kbd "<C-down>") 'ioccur-scroll-down)
- (define-key map (kbd "<C-up>") 'ioccur-scroll-up)
- (define-key map (kbd "C-v") 'ioccur-scroll-other-window-up)
- (define-key map (kbd "M-v") 'ioccur-scroll-other-window-down)
- (define-key map (kbd "<down>") 'ioccur-next-line)
- (define-key map (kbd "<up>") 'ioccur-precedent-line)
- (define-key map (kbd "C-n") 'ioccur-next-line)
- (define-key map (kbd "C-p") 'ioccur-precedent-line)
- (define-key map (kbd "R") 'ioccur-restart)
- (define-key map (kbd "C-|") 'ioccur-split-window)
- (define-key map (kbd "M-<") 'ioccur-beginning-of-buffer)
- (define-key map (kbd "M->") 'ioccur-end-of-buffer)
- map)
- "Keymap used for ioccur commands.")
-
-
-(defgroup ioccur nil
- "Mode that provide incremental searching in buffer."
- :prefix "ioccur-"
- :group 'text)
-
-;;; User variables.
-(defcustom ioccur-search-delay 0.5
- "During incremental searching, display is updated all these seconds."
- :type 'integer)
-
-(defcustom ioccur-search-prompt "Pattern: "
- "Prompt used for `ioccur-occur'."
- :type 'string)
-
-(defcustom ioccur-mode-line-string
- (if (window-system)
- " RET:Exit,C-g:Quit,C-j/left:Jump&quit,C-z/right:Jump,\
-C-k/x:Kill(as sexp),M-p/n:Hist,C/M-v:Scroll,C-down/up:Follow,C-w:Yank tap"
-
- " RET:Exit,C-g:Quit,C-j:Jump&quit,C-z:Jump,C-k/x:Kill(as sexp),\
-S-/Tab:Hist,C-v/t:Scroll,C-d/u:Follow,C-w:Yank tap")
-
- "Minimal documentation of `ioccur' commands displayed in mode-line.
-Set it to nil to remove doc in mode-line."
- :type 'string)
-
-(defcustom ioccur-length-line 80
- "Length of the line displayed in ioccur buffer.
-When set to nil lines displayed in `ioccur-buffer' will not be modified.
-See `ioccur-truncate-line'."
- :type 'integer)
-
-(defcustom ioccur-max-length-history 100
- "Maximum number of element stored in `ioccur-history'."
- :type 'integer)
-
-(defcustom ioccur-buffer-completion-use-ido nil
- "Use ido to choose buffers in `ioccur-find-buffer-matching'."
- :type 'symbol)
-
-(defcustom ioccur-default-search-function #'re-search-forward
- "Default search function.
-Use here one of `re-search-forward' or `search-forward'."
- :type 'symbol)
-
-(defcustom ioccur-highlight-match-p t
- "Highlight matchs in `ioccur-buffer' when non--nil."
- :type 'boolean)
-
-(defcustom ioccur-fontify-buffer-p nil
- "Fontify `ioccur-current-buffer' when non--nil.
-This allow to have syntactic coloration in `ioccur-buffer' but
-it slow down the start of ioccur at first time on large buffers."
- :type 'boolean)
-
-(defcustom ioccur-case-fold-search 'smart
- "Add smart option to `case-fold-search'.
-When smart is enabled, Ignore case in the search strings
-if pattern contains no uppercase characters.
-Otherwise, with a nil or t value, the behavior is same as
-`case-fold-search'.
-Default value is `smart', other possible values are nil and t."
- :type 'symbol)
-
-(defvar ioccur-read-char-or-event-skip-read-key nil
- "Force not using `read-key' to read input in minibuffer even if bounded.
-Set it to non--nil if menu disapear or if keys are echoing in minibuffer.
-Deprecated, should be used only in old Emacs versions.")
-
-(defvar ioccur-save-pos-before-jump-hook nil
- "A hook that run before jumping and quitting `ioccur'.")
-
-;;; Faces.
-(defface ioccur-overlay-face
- '((t (:background "Green4" :underline t)))
- "Face for highlight line in ioccur buffer.")
-
-(defface ioccur-match-overlay-face
- '((t (:background "Indianred4" :underline t)))
- "Face for highlight line in matched buffer.")
-
-(defface ioccur-title-face
- '((t (:background "Dodgerblue4")))
- "Face for highlight incremental buffer title.")
-
-(defface ioccur-regexp-face
- '((t (:background "DeepSkyBlue" :underline t)))
- "Face for highlight found regexp in `ioccur-buffer'.")
-
-(defface ioccur-match-face
- '((t (:background "DeepSkyBlue")))
- "Face for highlight matches in `ioccur-buffer'.")
-
-(defface ioccur-num-line-face
- '((t (:foreground "OrangeRed")))
- "Face for highlight number line in ioccur buffer.")
-
-(defface ioccur-invalid-regexp
- '((t (:foreground "Goldenrod")))
- "Face for highlight wrong regexp message in ioccur buffer.")
-
-(defface ioccur-cursor
- '((t (:foreground "green")))
- "Face for cursor color in minibuffer.")
-
-;;; Internal variables.
-;; String entered in prompt.
-(defvar ioccur-pattern "")
-;; The ioccur timer.
-(defvar ioccur-search-timer nil)
-;; Signal C-g hit.
-(defvar ioccur-quit-flag nil)
-;; The buffer we search in.
-(defvar ioccur-current-buffer nil)
-;; The overlay in `ioccur-buffer'.
-(defvar ioccur-occur-overlay nil)
-(make-variable-buffer-local 'ioccur-occur-overlay)
-;; Signal we quit and kill `ioccur-buffer'.
-(defvar ioccur-exit-and-quit-p nil)
-;; A list to store history.
-(defvar ioccur-history nil)
-;; The overlay in `ioccur-current-buffer'.
-(defvar ioccur-match-overlay nil)
-;; Number of occurences found.
-(defvar ioccur-count-occurences 0)
-;;The buffer where we send results.
-(defvar ioccur-buffer nil)
-(make-variable-buffer-local 'ioccur-buffer)
-;; True when jumping to a founded occurence.
-(defvar ioccur-success nil)
-;; Search function actually in use.
-(defvar ioccur-search-function ioccur-default-search-function)
-;; Message to send when ioccur exit
-(defvar ioccur-message nil)
-;; Store last window-configuration
-(defvar ioccur-last-window-configuration nil)
-;; Save point in current buffer here.
-(defvar ioccur-current-pos nil)
-
-(define-derived-mode ioccur-mode
- text-mode "ioccur"
- "Major mode to search occurences of regexp in current buffer.
-
-Special commands:
-\\{ioccur-mode-map}"
- (if ioccur-mode-line-string
- (setq mode-line-format
- '(" " mode-line-buffer-identification " "
- (line-number-mode "%l") " "
- ioccur-mode-line-string "-%-"))
- (kill-local-variable 'mode-line-format)))
-
-(cl-defsubst ioccur-position (item seq &key (test #'eq))
- ;; FIXME: Probably not worth inlining since it's a loop with an indirect
- ;; function call inside and the compiler likely won't figure out which
- ;; function is called indirectly to turn it into a direct call.
- "A simple replacement of CL `position'."
- ;; FIXME: We could (require 'cl-lib) and use `cl-position' (or
- ;; `seq-position') nowadays.
- (cl-loop for i in seq for index from 0
- when (funcall test i item) return index))
-
-;; Compatibility
-(unless (fboundp 'window-system)
- (defun window-system (&optional _arg)
- window-system))
-
-;;; Iterators.
-(defun ioccur-iter-list (list)
- "Return an iterator from list LIST-OBJ."
- (lambda () (pop list)))
-
-(defalias 'ioccur-iter-next #'funcall
- "Return next elm of ITERATOR.
-
-\(fn ITERATOR)")
-
-(defun ioccur-iter-circular (seq)
- "Infinite iteration on SEQ."
- (let ((it (ioccur-iter-list seq))
- (lis seq))
- (lambda ()
- (let ((elm (ioccur-iter-next it)))
- (or elm
- (progn (setq it (ioccur-iter-list lis))
- (ioccur-iter-next it)))))))
-
-(defun ioccur-butlast (seq pos)
- "Return SEQ from index 0 to POS."
- (butlast seq (- (length seq) pos)))
-
-(cl-defun ioccur-sub-prec-circular (seq elm &key (test #'eq))
- "Infinite reverse iteration of SEQ starting at ELM."
- (let* ((rev-seq (reverse seq))
- (pos (ioccur-position elm rev-seq :test test))
- (sub (append (nthcdr (1+ pos) rev-seq)
- (ioccur-butlast rev-seq pos)))
- (iterator (ioccur-iter-list sub)))
- (lambda ()
- (let ((elm (ioccur-iter-next iterator)))
- (or elm
- (progn (setq iterator (ioccur-iter-list sub))
- (ioccur-iter-next iterator)))))))
-
-(cl-defun ioccur-sub-next-circular (seq elm &key (test #'eq))
- "Infinite iteration of SEQ starting at ELM."
- (let* ((pos (ioccur-position elm seq :test test))
- (sub (append (nthcdr (1+ pos) seq)
- (ioccur-butlast seq pos)))
- (iterator (ioccur-iter-list sub)))
- (lambda ()
- (let ((elm (ioccur-iter-next iterator)))
- (or elm (progn
- (setq iterator (ioccur-iter-list sub))
- (ioccur-iter-next iterator)))))))
-
-(defun ioccur-print-results (regexp)
- "Print in `ioccur-buffer' lines matching REGEXP in `ioccur-current-buffer'."
- (setq ioccur-count-occurences 0)
- (with-current-buffer ioccur-current-buffer
- (let ((case-fold-search
- (pcase ioccur-case-fold-search
- (`smart (let ((case-fold-search nil))
- (if (string-match "[A-Z]" regexp) nil t)))
- (_ ioccur-case-fold-search))))
- (save-excursion
- (goto-char (point-min))
- (cl-loop
- while (not (eobp))
- ;; We need to read also C-g from here
- ;; Because when loop is started `ioccur-read-search-input'
- ;; will read key only when loop is finished
- ;; and we have no chance to exit loop.
- when quit-flag do (setq ioccur-quit-flag t) and return nil
- for count from 0
- when (funcall ioccur-search-function regexp (point-at-eol) t)
- do (ioccur-print-line
- (buffer-substring (point-at-bol) (point-at-eol))
- count (match-string 0))
- do (forward-line 1))))))
-
-
-(defun ioccur-print-match (str &optional all)
- "Highlight in string STR all occurences matching `ioccur-pattern'.
-If ALL is non--nil highlight the whole string STR."
- (condition-case nil
- (with-temp-buffer
- (insert str)
- (goto-char (point-min))
- (if all
- (add-text-properties
- (point) (point-at-eol)
- '(face ioccur-match-face))
- (while (and (funcall ioccur-search-function ioccur-pattern nil t)
- ;; Don't try to highlight line with a length <= 0.
- (> (- (match-end 0) (match-beginning 0)) 0))
- (add-text-properties
- (match-beginning 0) (match-end 0)
- '(face ioccur-match-face))))
- (buffer-string))
- (error nil)))
-
-(defun ioccur-print-line (line nline match)
- "Prepare and insert a matched LINE at line number NLINE in `ioccur-buffer'."
- (with-current-buffer ioccur-buffer
- (let* ((lineno (int-to-string (1+ nline)))
- (whole-line-matched (string= match line))
- (hightline (if ioccur-highlight-match-p
- (ioccur-print-match
- line
- whole-line-matched)
- line))
- (trunc-line (ioccur-truncate-line hightline)))
- (cl-incf ioccur-count-occurences)
- (insert " " (propertize lineno 'face 'ioccur-num-line-face
- 'help-echo line)
- ":" trunc-line "\n"))))
-
-(cl-defun ioccur-truncate-line (line &optional (columns ioccur-length-line))
- "Remove indentation in LINE and truncate modified LINE of num COLUMNS.
-COLUMNS default value is `ioccur-length-line'.
-If COLUMNS is nil return original indented LINE.
-If COLUMNS is 0 only remove indentation in LINE.
-So just set `ioccur-length-line' to nil if you don't want lines truncated."
- (let ((old-line line))
- (when (string-match "^[[:blank:]]*" line)
- ;; Remove tab and spaces at beginning of LINE.
- (setq line (replace-match "" nil nil line)))
- (if (and columns (> columns 0) (> (length line) columns))
- (substring line 0 columns)
- (if columns line old-line))))
-
-(defun ioccur-buffer-contain (buffer regexp)
- "Return BUFFER if it contain an occurence of REGEXP."
- (with-current-buffer buffer
- (save-excursion
- (goto-char (point-min))
- (when (re-search-forward regexp nil t) buffer))))
-
-(defun ioccur-list-buffers-matching (buffer-match regexp buffer-list)
- "Collect all buffers in BUFFER-LIST whose names match BUFFER-MATCH and \
-contain lines matching REGEXP."
- (cl-loop
- with ini-buf-list = (cl-loop for buf in buffer-list
- unless (rassq buf dired-buffers)
- collect buf)
- for buf in ini-buf-list
- for bname = (buffer-name buf)
- when (and (string-match buffer-match bname)
- (ioccur-buffer-contain buf regexp))
- collect bname))
-
-(defun ioccur-list-buffers-containing (regexp buffer-list)
- "Collect all buffers in BUFFER-LIST containing lines matching REGEXP."
- (cl-loop with buf-list = (cl-loop for i in buffer-list
- when (buffer-file-name (get-buffer i))
- collect i)
- for buf in buf-list
- when (ioccur-buffer-contain buf regexp)
- collect (buffer-name buf)))
-
-(cl-defun ioccur-find-buffer-matching1 (regexp
- &optional
- match-buf-name
- (buffer-list (buffer-list)))
- "Find all buffers containing a text matching REGEXP \
-and connect `ioccur' to the selected one.
-
-If MATCH-BUF-NAME is non--nil search is performed only in buffers
-with name matching specified expression (prompt).
-
-Hitting C-g in a `ioccur' session will return to completion list.
-Hitting C-g in the completion list will jump back to initial buffer.
-
-The buffer completion list is provided by one of:
-`ido-completing-read', `completing-read'
-depending on which `ioccur-buffer-completion-use-ido' you have choosen."
- ;; Remove doublons maybe added by minibuffer in `ioccur-history'.
- (setq ioccur-history
- (cl-loop for i in ioccur-history
- when (not (member i hist)) collect i into hist
- finally return hist))
-
- (let ((prompt (format "Search (%s) in Buffer: " regexp))
- (win-conf (current-window-configuration))
- (buf-list (if match-buf-name
- (ioccur-list-buffers-matching
- (read-string "In Buffer names matching: ")
- regexp buffer-list)
- (ioccur-list-buffers-containing regexp buffer-list))))
-
- (cl-labels
- ((find-buffer ()
- (let ((buf (if (and ido-mode
- (eq ioccur-buffer-completion-use-ido 'ido))
- (ido-completing-read prompt buf-list nil t)
- (completing-read prompt buf-list nil t))))
- (unwind-protect
- (progn
- (switch-to-buffer buf)
- (ioccur regexp)
- ;; Exit if we jump to this `ioccur-current-buffer',
- ;; otherwise, if C-g is hitten,
- ;; go back to buffer completion list.
- (unless ioccur-success
- (find-buffer)))
- ;; C-g hit in buffer completion restore window config.
- (unless ioccur-success
- (set-window-configuration win-conf))))))
-
- (find-buffer))))
-
-(defvar savehist-save-minibuffer-history)
-
-;;;###autoload
-(defun ioccur-find-buffer-matching (regexp)
- "Find all buffers containing a text matching REGEXP.
-See `ioccur-find-buffer-matching1'."
- (interactive (list (let ((savehist-save-minibuffer-history nil))
- (read-from-minibuffer "Search for Pattern: "
- nil nil nil '(ioccur-history . 0)
- (thing-at-point 'symbol)))))
- (ioccur-find-buffer-matching1 regexp current-prefix-arg))
-
-;;; Ioccur dired
-;;;###autoload
-(defun ioccur-dired (regexp)
- ;; FIXME: Missing docstring!
- (interactive (list (let ((savehist-save-minibuffer-history nil))
- (read-from-minibuffer "Search for Pattern: "
- nil nil nil '(ioccur-history . 0)
- (thing-at-point 'symbol)))))
- (cl-assert (derived-mode-p 'dired-mode))
- (declare-function dired-get-marked-files "dired")
- (let ((buf-list (cl-loop for f in (dired-get-marked-files)
- do (find-file-noselect f)
- unless (file-directory-p f)
- collect (get-buffer (file-name-nondirectory f)))))
- (ioccur-find-buffer-matching1 regexp nil buf-list)))
-
-;;;###autoload
-(defun ioccur-restart ()
- "Restart `ioccur' from `ioccur-buffer'.
-`ioccur-buffer' is erased and a new search is started."
- (interactive)
- (when (eq major-mode 'ioccur-mode)
- (pop-to-buffer ioccur-current-buffer)
- (kill-buffer ioccur-buffer)
- (set-window-configuration ioccur-last-window-configuration)
- (ioccur)))
-
-;;;###autoload
-(defun ioccur-quit ()
- "Quit `ioccur-buffer'."
- (interactive)
- (let ((pos (with-current-buffer ioccur-current-buffer (point))))
- (when ioccur-match-overlay
- (delete-overlay ioccur-match-overlay))
- (quit-window)
- (set-window-configuration ioccur-last-window-configuration)
- (pop-to-buffer ioccur-current-buffer)
- (goto-char pos)))
-
-(defun ioccur-goto-line (lineno)
- "Goto LINENO without modifying outline visibility if needed."
- (goto-char (point-min))
- (forward-line (1- lineno))
- (if (and (fboundp 'org-reveal)
- (or (derived-mode-p 'org-mode)
- outline-minor-mode))
- (org-reveal)))
-
-(defun ioccur-forward-line (n)
- "Forward N lines but empty one's."
- (let (pos)
- (save-excursion
- (forward-line n) (forward-line 0)
- (when (looking-at "^\\s-[0-9]+:")
- (forward-line 0) (setq pos (point))))
- (when pos (goto-char pos) (ioccur-color-current-line))))
-
-;;;###autoload
-(defun ioccur-next-line ()
- "Goto next line if it is not an empty line."
- (interactive)
- (ioccur-forward-line 1))
-
-;;;###autoload
-(defun ioccur-precedent-line ()
- "Goto precedent line if it is not an empty line."
- (interactive)
- (ioccur-forward-line -1))
-
-;;;###autoload
-(defun ioccur-beginning-of-buffer ()
- "Goto beginning of `ioccur-buffer'."
- (interactive)
- (when (looking-at "^\\s-[0-9]+:")
- (goto-char (point-min))
- (re-search-forward "^\\s-[0-9]+:" nil t)
- (forward-line 0)
- (ioccur-color-current-line)))
-
-;;;###autoload
-(defun ioccur-end-of-buffer ()
- "Go to end of `ioccur-buffer'."
- (interactive)
- (when (looking-at "^\\s-[0-9]+:")
- (goto-char (point-max))
- (forward-line -1)
- (ioccur-color-current-line)))
-
-(defun ioccur-jump (&optional win-conf)
- "Jump to line in other buffer and put an overlay on it.
-Move point to first occurence of `ioccur-pattern'."
- (let* ((line (buffer-substring (point-at-bol) (point-at-eol)))
- (pos (string-to-number line)))
- (unless (string= line "")
- (if win-conf
- (set-window-configuration win-conf)
- (pop-to-buffer ioccur-current-buffer))
- (ioccur-goto-line pos)
- (recenter)
- ;; Go to beginning of first occurence in this line
- ;; of what match `ioccur-pattern'.
- (when (funcall ioccur-search-function
- ioccur-pattern (point-at-eol) t)
- (goto-char (match-beginning 0)))
- (ioccur-color-matched-line))))
-
-;;;###autoload
-(defun ioccur-jump-and-quit ()
- "Jump to line in other buffer and quit search buffer."
- (interactive)
- (run-hooks 'ioccur-save-pos-before-jump-hook)
- (when (ioccur-jump ioccur-last-window-configuration)
- (sit-for 0.3)
- (when ioccur-match-overlay
- (delete-overlay ioccur-match-overlay))))
-
-(defun ioccur-save-current-pos-to-mark-ring ()
- "Save current buffer position to mark ring.
-To use this add it to `ioccur-save-pos-before-jump-hook'."
- (with-current-buffer ioccur-current-buffer
- (set-marker (mark-marker) ioccur-current-pos)
- (push-mark ioccur-current-pos 'nomsg)))
-
-;;;###autoload
-(defun ioccur-jump-without-quit (&optional mark)
- "Jump to line in `ioccur-current-buffer' without quitting."
- (interactive)
- (when (ioccur-jump ioccur-last-window-configuration)
- (and mark (set-marker (mark-marker) (point))
- (push-mark (point) 'nomsg))
- (switch-to-buffer-other-window ioccur-buffer t)))
-
-;;;###autoload
-(defun ioccur-scroll-other-window-down ()
- "Scroll other window down."
- (interactive)
- (let ((other-window-scroll-buffer ioccur-current-buffer))
- (scroll-other-window 1)))
-
-;;;###autoload
-(defun ioccur-scroll-other-window-up ()
- "Scroll other window up."
- (interactive)
- (let ((other-window-scroll-buffer ioccur-current-buffer))
- (scroll-other-window -1)))
-
-(defun ioccur-scroll (n)
- "Scroll `ioccur-buffer' and `ioccur-current-buffer' simultaneously."
- (ioccur-forward-line n)
- (ioccur-color-current-line)
- (and (ioccur-jump ioccur-last-window-configuration)
- (switch-to-buffer-other-window ioccur-buffer t)))
-
-;;;###autoload
-(defun ioccur-scroll-down ()
- "Scroll down `ioccur-buffer' and `ioccur-current-buffer' simultaneously."
- (interactive)
- (ioccur-scroll 1))
-
-;;;###autoload
-(defun ioccur-scroll-up ()
- "Scroll up `ioccur-buffer' and `ioccur-current-buffer' simultaneously."
- (interactive)
- (ioccur-scroll -1))
-
-;;;###autoload
-(defun ioccur-split-window ()
- "Toggle split window, vertically or horizontally."
- (interactive)
- (with-current-buffer ioccur-current-buffer
- (let ((old-size (window-height)))
- (delete-window)
- (set-window-buffer
- (select-window (if (= (window-height) old-size)
- (split-window-vertically)
- (split-window-horizontally)))
- (get-buffer ioccur-buffer)))))
-
-(defun ioccur-read-char-or-event (prompt)
- "Replace `read-key' when not available using PROMPT."
- (if (and (fboundp 'read-key)
- (not ioccur-read-char-or-event-skip-read-key))
- (read-key prompt)
- (let* ((chr (condition-case nil (read-char prompt) (error nil)))
- (evt (unless chr (read-event prompt))))
- (or chr evt))))
-
-(defun ioccur-read-search-input (initial-input start-point)
- "Read each keyboard input and add it to `ioccur-pattern'.
-INITIAL-INPUT is a string given as default input, generally thing at point.
-START-POINT is the point where we start searching in buffer."
- (let* ((prompt (propertize ioccur-search-prompt
- 'face 'minibuffer-prompt))
- (inhibit-quit (or (eq system-type 'windows-nt)
- (not (fboundp 'read-key))
- ioccur-read-char-or-event-skip-read-key))
- (tmp-list ())
- (it-prec nil)
- (it-next nil)
- (cur-hist-elm (car ioccur-history))
- (start-hist nil) ; Flag to notify if cycling history started.
- yank-point
- (index 0))
- (unless (string= initial-input "")
- (cl-loop for char across initial-input do (push char tmp-list)))
- (setq ioccur-pattern initial-input)
- ;; Cycle history function.
- ;;
- (cl-flet
- ((cycle-hist (arg)
- ;; ARG can be positive or negative depending we call M-p or M-n.
- (if ioccur-history
- (progn
- ;; Cycle history will start at second call,
- ;; at first call just use the car of hist ring.
- ;; We build a new iterator based on a sublist
- ;; starting at the current element of history.
- ;; This is a circular iterator. (no end)
- (if start-hist ; At first call, start-hist is nil.
- (progn
- (if (< arg 0)
- ;; M-p (move from left to right in hist ring).
- (unless it-prec ; Don't rebuild iterator if exists.
- (setq it-prec (ioccur-sub-next-circular
- ioccur-history
- cur-hist-elm :test #'equal))
- (setq it-next nil)) ; Kill forward iterator.
- ;; M-n (move from right to left in hist ring).
- (unless it-next ; Don't rebuild iterator if exists.
- (setq it-next (ioccur-sub-prec-circular
- ioccur-history
- cur-hist-elm :test #'equal))
- (setq it-prec nil))) ; kill backward iterator.
- (let ((it (or it-prec it-next)))
- (setq cur-hist-elm (ioccur-iter-next it))
- (setq tmp-list nil)
- (cl-loop for char across cur-hist-elm
- do (push char tmp-list))
- (setq ioccur-pattern cur-hist-elm)))
- ;; First call use car of history ring.
- (setq tmp-list nil)
- (cl-loop for char across cur-hist-elm
- do (push char tmp-list))
- (setq ioccur-pattern cur-hist-elm)
- (setq start-hist t)))
- (message "No history available.") (sit-for 2) t))
- ;; Insert INITIAL-INPUT.
- ;;
- (insert-initial-input ()
- (unless (string= initial-input "")
- (cl-loop for char across initial-input
- do (push char (nthcdr index tmp-list)))))
- ;; Maybe start timer.
- ;;
- (start-timer ()
- (unless ioccur-search-timer
- (ioccur-start-timer)))
- ;; Maybe stop timer.
- ;;
- (stop-timer ()
- (when ioccur-search-timer
- (ioccur-cancel-search)))
- ;; Kill pattern
- ;;
- (kill (str)
- (with-current-buffer ioccur-current-buffer
- (goto-char start-point)
- (setq yank-point start-point))
- (kill-new (substring str (- (length tmp-list) index)))
- (setq tmp-list (nthcdr index tmp-list)))
- ;; Add cursor in minibuffer
- ;;
- (set-cursor (str pos)
- (setq pos (min index (1- (length tmp-list))))
- (when (not (string= str ""))
- (let* ((real-index (- (1- (length tmp-list)) pos))
- (cur-str (substring str real-index (1+ real-index))))
- (concat (substring str 0 real-index)
- (propertize cur-str 'display
- (if (= index (length tmp-list))
- (concat
- (propertize "|" 'face 'ioccur-cursor)
- cur-str)
- (concat
- cur-str
- (propertize "|" 'face
'ioccur-cursor))))
- (substring str (1+ real-index)))))))
-
- ;; Start incremental loop.
- (while (let ((char (ioccur-read-char-or-event
- (concat prompt (set-cursor ioccur-pattern index)))))
- (message nil)
- (pcase char
- ;; FIXME: The old code used CL's `case' with the following
- ;; first branch:
- ;;
- ;; ((not (?\M-p ?\M-n ?\t C-tab)) ; Reset history
- ;; (setq start-hist nil)
- ;; (setq cur-hist-elm (car ioccur-history)) t)
- ;;
- ;; This was clearly not working since it could only match if
- ;; `char' was equal to `not' or to the list
- ;; (?\M-p ?\M-n ?\t C-tab), which is clearly not what was
- ;; intended, but it's not clear what this was meant to do!
- ((or `down `?\C-n) ; Next line.
- (stop-timer) (ioccur-next-line)
- (ioccur-color-current-line) t)
- ((or `up `?\C-p) ; Precedent line.
- (stop-timer) (ioccur-precedent-line)
- (ioccur-color-current-line) t)
- (`?\M-< ; Beginning of buffer.
- (when (ioccur-beginning-of-buffer)
- (stop-timer))
- t)
- (`?\M-> ; End of buffer.
- (when (ioccur-end-of-buffer)
- (stop-timer))
- t)
- ((or `?\C-d `C-down) ; Scroll both windows down.
- (stop-timer) (ioccur-scroll-down) t)
- ((or `?\C-u `C-up) ; Scroll both windows up.
- (stop-timer) (ioccur-scroll-up) t)
- (`?\r ; RET break and exit code.
- nil)
- (`?\d ; Delete backward with DEL.
- (start-timer)
- (with-current-buffer ioccur-current-buffer
- (goto-char start-point)
- (setq yank-point start-point))
- (with-no-warnings (pop (nthcdr index tmp-list)))
- t)
- (`?\C-g ; Quit and restore buffers.
- (setq ioccur-quit-flag t) nil)
- ((or `right `?\C-z) ; Persistent action.
- (ioccur-jump-without-quit) t)
- (`?\C- ; Persistent action save mark.
- (ioccur-jump-without-quit t) t)
- ((or `left `?\C-j) ; Jump and kill search buffer.
- (setq ioccur-exit-and-quit-p t) nil)
- ((or `next `?\C-v) ; Scroll down.
- (ioccur-scroll-other-window-down) t)
- ((or `?\C-t `?\M-v `prior) ; Scroll up.
- (ioccur-scroll-other-window-up) t)
- (`?\C-s ; Toggle split window.
- (ioccur-split-window) t)
- ((or `?\C-: `?\C-l) ; Toggle regexp/litteral
search.
- (start-timer)
- (setq ioccur-search-function
- (if (eq ioccur-search-function #'re-search-forward)
- #'search-forward
- #'re-search-forward))
- t)
- (`?\C-k ; Kill input.
- (start-timer)
- (kill ioccur-pattern) (setq index 0) t)
- ((or `?\M-k `?\C-x) ; Kill input as sexp.
- (start-timer)
- (let ((sexp (prin1-to-string ioccur-pattern)))
- (kill sexp)
- (setq ioccur-quit-flag t)
- (setq ioccur-message (format "Killed: %s" sexp)))
- nil)
- (`?\C-y ; Yank from `kill-ring'.
- (setq initial-input (car kill-ring))
- (insert-initial-input) t)
- (`?\C-w ; Yank stuff at point.
- (start-timer)
- (with-current-buffer ioccur-current-buffer
- ;; Start to initial point if C-w have never been hit.
- (unless yank-point (setq yank-point start-point))
- ;; After a search `ioccur-print-results' have put point
- ;; to point-max, so reset position.
- (when yank-point (goto-char yank-point))
- (let ((pmax (point-at-eol))
- (eoword (save-excursion (forward-word 1) (point))))
- ;; Don't yank further than eol.
- (unless (> eoword pmax)
- (goto-char eoword)
- (setq initial-input (buffer-substring-no-properties
- yank-point (point)))
- (setq yank-point (point)) ; End of last forward-word
- (insert-initial-input))))
- t)
- ((or `?\t `?\M-p) ; Precedent history elm.
- (start-timer)
- (setq index 0)
- (cycle-hist -1))
- ((or `backtab `?\M-n) ; Next history elm.
- (start-timer)
- (setq index 0)
- (cycle-hist 1))
- (`?\C-q ; quoted-insert.
- (stop-timer)
- (let ((char (with-temp-buffer
- (call-interactively 'quoted-insert)
- (buffer-string))))
- (push (string-to-char char) tmp-list))
- (start-timer)
- t)
- ;; Movements in minibuffer
- (`?\C-b ; backward-char.
- (setq index (min (1+ index) (length tmp-list))) t)
- (`?\C-f ; forward-char.
- (setq index (max (1- index) 0)) t)
- (`?\C-a ; move bol.
- (setq index (length tmp-list)) t)
- (`?\C-e ; move eol.
- (setq index 0) t)
- (_ ; Store character.
- (start-timer)
- (if (characterp char)
- (push char (nthcdr index tmp-list))
- (setq unread-command-events
- (nconc (mapcar #'identity
- (this-single-command-raw-keys))
- unread-command-events))
- nil))))
- (setq ioccur-pattern (apply #'string (reverse tmp-list)))))))
-
-(defun ioccur-print-buffer (regexp)
- "Pretty Print results matching REGEXP in `ioccur-buffer'."
- ;; FIXME: Why force tooltip-mode? What about sessions with both GUI and
- ;; tty frames?
- (unless (window-system) (setq tooltip-use-echo-area t) (tooltip-mode 1))
- (let* ((cur-method (if (eq ioccur-search-function #'re-search-forward)
- "Regexp" "Literal"))
- (title (propertize
- (format
- "* Ioccur %s searching %s"
- cur-method
- (if (window-system)
- "* (`C-:' to Toggle Method, Mouse over for help.)"
- "* (`C-l' to Toggle Method.)"))
- 'face 'ioccur-title-face
- 'help-echo
- " Ioccur map:\n
-C-n or <down> Next line.\n
-C-p or <up> Precedent line.\n
-C-v and M-v/C-t Scroll up and down.\n
-C-z or <right> Jump without quitting loop.\n
-C-TAB Jump without quitting and save to mark-ring.\n
-C-j or <left> Jump and kill `ioccur-buffer'.\n
-RET Exit keeping `ioccur-buffer'.\n
-DEL Remove last character entered.\n
-C-k Kill current input.\n
-C-a/e/b/f Movements in minibuffer.\n
-M-k/C-x Kill current input as sexp.\n
-C-w Yank stuff at point.\n
-C-g Quit and restore buffer.\n
-C-s Toggle split window.\n
-C-:/l Toggle regexp/litteral search.\n
-C-down or C-u Follow in other buffer.\n
-C-up/d or C-d Follow in other buffer.\n
-M-<, M-> Beginning and end of buffer.\n
-M-p/n or tab/S-tab History."))
- wrong-regexp)
- (if (string= regexp "")
- (progn (erase-buffer) (insert title "\n\n"))
- (erase-buffer)
- (condition-case _
- (ioccur-print-results regexp)
- (error (setq wrong-regexp t)))
- (goto-char (point-min))
- (if wrong-regexp
- (insert
- title "\n\n"
- (propertize "Invalid Regexp: "
- 'face 'ioccur-invalid-regexp)
- (format "No match for `%s'" regexp) "\n\n")
- (insert title "\n\n"
- (propertize (format "Found %s occurences matching "
- ioccur-count-occurences)
- 'face 'underline)
- (propertize regexp 'face 'ioccur-regexp-face)
- (propertize
- (format " in %s" ioccur-current-buffer)
- 'face 'underline) "\n\n")
- (ioccur-color-current-line)))))
-
-(defun ioccur-start-timer ()
- "Start ioccur incremental timer."
- (setq ioccur-search-timer
- (run-with-idle-timer
- ioccur-search-delay 'repeat
- #'(lambda ()
- (ioccur-print-buffer
- ioccur-pattern)))))
-
-(defun ioccur-send-message ()
- "Send message defined in `ioccur-message'."
- (message ioccur-message))
-
-;;;###autoload
-(defun ioccur (&optional initial-input)
- "Incremental search of lines in current buffer matching input.
-With a prefix arg search symbol at point (INITIAL-INPUT).
-
-While you are incremental searching, commands provided are:
-
-C-n or <down> next line.
-C-p or <up> precedent line.
-C-v and M-v scroll up and down.
-C-z or <right> jump without quitting loop.
-C-j or <left> jump and kill `ioccur-buffer'.
-RET exit keeping `ioccur-buffer'.
-DEL remove last character entered.
-C-k Kill current input from cursor to eol.
-C-a/e/b/f Movements in minibuffer.
-M-k Kill current input as sexp.
-C-w Yank stuff at point.
-C-g quit and restore buffer.
-C-s Toggle split window.
-C-: Toggle regexp/litteral search.
-C-down Follow in other buffer.
-C-up Follow in other buffer.
-M-p/n Precedent and next `ioccur-history' element.
-M-<, M-> Beginning and end of buffer.
-
-Unlike minibuffer history, cycling in ioccur history have no end:
-
-M-p ,-->A B C D E F G H I---,
- | |
- `---I H G F E D C B A<--'
-
-M-n ,-->I H G F E D C B A---,
- | |
- `---A B C D E F G H I<--'
-
-
-Special NOTE for terms:
-=======================
- tab/S-tab are bound to history.
- C-d/u are for following in other buffer.
- Use C-t to Scroll up.
-
-When you quit incremental search with RET, see `ioccur-mode'
-for commands provided in the `ioccur-buffer'."
- (interactive "P")
- (let (pop-up-frames)
- (setq ioccur-exit-and-quit-p nil)
- (setq ioccur-success nil)
- (setq ioccur-current-buffer (buffer-name (current-buffer)))
- (when ioccur-fontify-buffer-p
- (message "Fontifying buffer...Please wait it could be long.")
- (jit-lock-fontify-now) (message nil))
- (setq ioccur-buffer (concat "*ioccur-" ioccur-current-buffer "*"))
- (setq ioccur-last-window-configuration (current-window-configuration))
- (setq ioccur-current-pos (point))
- (if (and (not initial-input)
- (get-buffer ioccur-buffer)
- (not (get-buffer-window ioccur-buffer)))
- ;; An hidden `ioccur-buffer' exists jump to it and reuse it.
- (switch-to-buffer-other-window ioccur-buffer t)
- ;; `ioccur-buffer' doesn't exists or is visible, start searching
- ;; Creating a new `ioccur-buffer' or reusing the visible one after
- ;; erasing it.
- (let* ((init-str (if initial-input
- (if (stringp initial-input)
- initial-input (thing-at-point 'symbol))
- ""))
- (len (length init-str))
- (curpos (point))
- (inhibit-read-only t)
- (wdired (with-current-buffer ioccur-current-buffer
- ;; If current `major-mode' is wdired Turn it off.
- (when (derived-mode-p 'wdired-mode)
- (declare-function wdired-change-to-dired-mode
- "wdired" ())
- (wdired-change-to-dired-mode)
- t)))
- str-no-prop)
- (set-text-properties 0 len nil init-str)
- (setq str-no-prop init-str)
- (pop-to-buffer (get-buffer-create ioccur-buffer))
- (ioccur-mode)
- (unwind-protect
- ;; Start incremental search.
- (progn
- (ioccur-start-timer)
- (ioccur-read-search-input str-no-prop curpos))
- ;; At this point incremental search loop is exited.
- (progn
- (ioccur-cancel-search)
- (kill-local-variable 'mode-line-format)
- (when (equal (buffer-substring (point-at-bol) (point-at-eol)) "")
- (setq ioccur-quit-flag t))
- (cond (ioccur-quit-flag ; C-g hit or empty `ioccur-buffer'.
- (kill-buffer ioccur-buffer)
- (pop-to-buffer ioccur-current-buffer)
- (when ioccur-match-overlay
- (delete-overlay ioccur-match-overlay))
- (set-window-configuration
ioccur-last-window-configuration)
- (goto-char curpos)
- (ioccur-send-message)
- ;; If `ioccur-message' is non--nil, thats mean we exit
- ;; with a specific action other than `C-g',
- ;; e.g kill-as-sexp, so we save history.
- (when ioccur-message (ioccur-save-history)))
- (ioccur-exit-and-quit-p ; Jump and kill `ioccur-buffer'.
- (ioccur-jump-and-quit)
- (kill-buffer ioccur-buffer)
- (ioccur-send-message) (ioccur-save-history))
- (t ; Jump keeping `ioccur-buffer'.
- (ioccur-jump)
- (pop-to-buffer ioccur-buffer)
- (setq buffer-read-only t)
- (ioccur-save-history)))
- ;; Maybe reenable `wdired-mode'.
- (when wdired (wdired-change-to-wdired-mode))
- (setq ioccur-count-occurences 0)
- (setq ioccur-quit-flag nil)
- (setq ioccur-message nil)
- (setq ioccur-search-function ioccur-default-search-function)
- (setq ioccur-current-pos nil)))))))
-
-(defun ioccur-save-history ()
- "Save last ioccur element found in `ioccur-history'."
- (unless (string= ioccur-pattern "")
- (setq ioccur-history
- (cons ioccur-pattern (delete ioccur-pattern ioccur-history)))
- (when (> (length ioccur-history) ioccur-max-length-history)
- (setq ioccur-history (delete (car (last ioccur-history))
- ioccur-history)))
- (setq ioccur-success t)))
-
-(defun ioccur-cancel-search ()
- "Cancel timer used for ioccur searching."
- (when ioccur-search-timer
- (cancel-timer ioccur-search-timer)
- (setq ioccur-search-timer nil)))
-
-(defun ioccur-color-current-line ()
- "Highlight and underline current line in `ioccur-buffer'."
- (if ioccur-occur-overlay
- (move-overlay ioccur-occur-overlay
- (point-at-bol) (1+ (point-at-eol)) ioccur-buffer)
- (setq ioccur-occur-overlay
- (make-overlay (point-at-bol) (1+ (point-at-eol)) ioccur-buffer)))
- (overlay-put ioccur-occur-overlay 'face 'ioccur-overlay-face))
-
-(defun ioccur-color-matched-line ()
- "Highlight and underline current position \
-of matched line in `ioccur-current-buffer'."
- (if ioccur-match-overlay
- (move-overlay ioccur-match-overlay
- (point-at-bol) (1+ (point-at-eol)))
- (setq ioccur-match-overlay
- (make-overlay (point-at-bol) (1+ (point-at-eol)))))
- (overlay-put ioccur-match-overlay 'face 'ioccur-match-overlay-face))
-
-
-(provide 'ioccur)
-
-;;; ioccur.el ends here
diff --git a/packages/js2-mode/.dir-locals.el b/packages/js2-mode/.dir-locals.el
deleted file mode 100644
index db35973..0000000
--- a/packages/js2-mode/.dir-locals.el
+++ /dev/null
@@ -1 +0,0 @@
-((nil . ((sentence-end-double-space . t))))
diff --git a/packages/js2-mode/.elpaignore b/packages/js2-mode/.elpaignore
deleted file mode 100644
index b51163d..0000000
--- a/packages/js2-mode/.elpaignore
+++ /dev/null
@@ -1,4 +0,0 @@
-.travis.yml
-.gitignore
-Makefile
-tests
diff --git a/packages/js2-mode/.gitignore b/packages/js2-mode/.gitignore
deleted file mode 100644
index c531d98..0000000
--- a/packages/js2-mode/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.elc
diff --git a/packages/js2-mode/.travis.yml b/packages/js2-mode/.travis.yml
deleted file mode 100644
index bb0a9e0..0000000
--- a/packages/js2-mode/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-# https://github.com/rolandwalker/emacs-travis
-
-language: emacs-lisp
-
-env:
- matrix:
- - EMACS=emacs24
- - EMACS=emacs-snapshot
-
-install:
- - if [ "$EMACS" = "emacs24" ]; then
- sudo add-apt-repository -y ppa:cassou/emacs &&
- sudo apt-get update -qq &&
- sudo apt-get install -qq emacs24 emacs24-el;
- fi
- - if [ "$EMACS" = "emacs-snapshot" ]; then
- sudo add-apt-repository -y ppa:cassou/emacs &&
- sudo apt-get update -qq &&
- sudo apt-get install -qq emacs-snapshot &&
- sudo apt-get install -qq emacs-snapshot-el emacs-snapshot-gtk;
- fi
-
-script:
- make test EMACS=${EMACS}
diff --git a/packages/js2-mode/LICENSE b/packages/js2-mode/LICENSE
deleted file mode 100644
index 94a9ed0..0000000
--- a/packages/js2-mode/LICENSE
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 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.
-
- 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 <http://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
-<http://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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/js2-mode/Makefile b/packages/js2-mode/Makefile
deleted file mode 100644
index bad22c9..0000000
--- a/packages/js2-mode/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# -*- Makefile -*-
-
-EMACS = emacs
-
-# Compile with noninteractive and relatively clean environment.
-BATCHFLAGS = -batch -Q
-
-SRCS = js2-mode.el js2-imenu-extras.el
-
-OBJS = $(SRCS:.el=.elc)
-
-%.elc: %.el
- ${EMACS} $(BATCHFLAGS) -L . -f batch-byte-compile $^
-
-all: $(OBJS)
-
-clean:
- -rm -f $(OBJS)
-
-test:
- ${EMACS} $(BATCHFLAGS) -L . -l js2-mode.el -l js2-old-indent.el -l
tests/parser.el \
- -l tests/indent.el -l tests/externs.el -l tests/json-path.el -l
tests/consume.el \
- -l tests/navigation.el -f ert-run-tests-batch-and-exit
diff --git a/packages/js2-mode/NEWS.md b/packages/js2-mode/NEWS.md
deleted file mode 100644
index c120be7..0000000
--- a/packages/js2-mode/NEWS.md
+++ /dev/null
@@ -1,265 +0,0 @@
-# History of user-visible changes
-
-## 2019-02-19
-
-* Changed the default of `js2-strict-trailing-comma-warning` to nil.
-
-## 2018-03-01
-
-* Support single-line JSDocs.
-* New face `js2-object-property-access`.
-* Support for trailing comma in function arguments
-* JSDoc highlighting for `@yield`, `@yields`, `@abstract`, `@virtual` and
`@typedef`.
-* Support for anonymous class exports.
-
-## 2017-07-21
-
-* Support for async arrow function without parentheses.
-* Support for `/*jslint` declarations.
-* User option `js2-getprop-has-side-effects`.
-* Support for trailing commas in function parameter lists.
-* Support for ES7 public class fields.
-* New user option `js2-ignored-warnings`.
-
-## 2017-01-16
-
-* `js2-include-*-externs` are now evaluated on demand. As a result,
- they can now be effectively used as file- or directory-local
- variables.
-* Support for ES7 exponentiation operator.
-
-## 2016-06-23
-
-* New variable `js2-mode-assume-strict`, for use with ES6 modules.
-* Support for JSDoc @callback, @func and @method tags.
-* Object properties are highlighted using a different face:
- `js2-object-property`, which has no color by default.
-* Experimental support for object rest/spread ECMAScript proposal.
-* `js2-getter-setter-node` is renamed to `js2-method-node`, together with
- its related functions. It already handles generator methods, and we
- added support for async methods (see below), so the old name would get
- more confusing.
-* Support for default parameters in destructuring. It should work for both
- objects and arrays, in both literals and function arguments.
-* New mode: `js2-jsx-mode`, deriving from `js2-mode`. Supports indentation of
- JSXElement expressions wrapped within parentheses or as function arguments.
- Indentation is customizable via `sgml-attribute-offset`.
-* Experimental support for async/await ECMAScript proposal.
-
-## 20150909
-
-* `js2-mode` now derives from `js-mode`. That means the former
- function will run `js-mode-hook`, as well as `js2-mode-hook`. The
- key bindings will default to `js-mode-map` where they're not set in
- `js2-mode-map`. And in Emacs 25 or later (including the snapshot
- builds), `js2-mode` uses the indentation code from `js-mode`. Where
- feasible, the user options (and functions) now have aliases, but if
- you're using Emacs 25 and you see an indentation-related setting
- that stopped working, try looking for a corresponding one in the
- `js` group: `M-x customize-group RET js RET`.
-
-* New command: `js2-jump-to-definition`. It's bound to `M-.` by
- default, via remapping `js-find-symbol`. To get back to the default
- `M-.` binding (e.g. `find-tag`), put this in your init file:
-
- (eval-after-load 'js (define-key js-mode-map (kbd "M-.") nil))
-
-## 20150713
-
-* More comprehensive strict mode warnings and syntax errors.
-* New minor mode: `js2-highlight-unused-variables-mode`.
-* `js2-pretty-multiline-declarations` can take the value `dynamic` now.
-
-## 20150202
-
-Support for:
-
-* [ES6 modules](http://www.2ality.com/2014/09/es6-modules-final.html).
-* [Short-hand object
literals](http://ariya.ofilabs.com/2013/02/es6-and-object-literal-property-value-shorthand.html).
-* [Method
definitions](http://ariya.ofilabs.com/2013/03/es6-and-method-definitions.html).
-* ['u' and 'y' RegExp flags](https://mathiasbynens.be/notes/es6-unicode-regex).
-* [Computed property
names](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-object-initializer).
-* [Class statements and
expressions](https://github.com/lukehoban/es6features#classes).
-* [Template strings](http://tc39wiki.calculist.org/es6/template-strings/),
including tagged ones.
-
-The variable `js2-allow-keywords-as-property-names` has been
-removed. Instead we check if `js2-language-version` is 180 or highter.
-
-## 20141115
-
-Support for:
-
-* Unicode characters in identifiers (improved).
-* [Delegating
yield](http://wiki.ecmascript.org/doku.php?id=harmony:generators#delegating_yield).
-* [ES6 numeric
literals](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-numeric-literals)
(octal, binary).
-* Harmony [array and generator
comprehensions](http://wingolog.org/archives/2014/03/07/es6-generator-and-array-comprehensions-in-spidermonkey).
-
-## 20131106
-
-Support for:
-
-* [Arrow
functions](http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax)
-* [Generators](http://wiki.ecmascript.org/doku.php?id=harmony:generators)
-* [Spread operator](http://wiki.ecmascript.org/doku.php?id=harmony:spread)
-
-## 20130510
-
-### Support for JSLint global declaration
-
-See the docstring for `js2-include-jslint-globals`.
-
-## 20130216
-
-### We don't rebind `RET` anymore
-
-Because well-behaving major modes aren't supposed to do that.
-
-So pressing it won't continue a block comment, or turn a string into a
concatenation.
-Pressing `M-j`, however, will.
-
-The options `js2-indent-on-enter-key` and `js2-enter-indents-newline` were
also removed.
-
-To bring back the previous behavior, put this in your init file:
-
-```js
-(eval-after-load 'js2-mode
- '(define-key js2-mode-map (kbd "RET") 'js2-line-break))
-```
-
-## 20120617
-
-### Support for
[default](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/default_parameters)
and
[rest](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/rest_parameters)
parameters
-
-## 20120614
-
-### Support for [for..of
loops](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
-
-## Older changes
-
-### Popular indentation style
-
-```js
-[foo, bar, baz].forEach(function (v) {
- if (validate(v))
- process(v);
-});
-
-[a, b, c].some(function (v) {
- return validate(v);
-});
-```
-
-### Pretty multiline variable declaration
-
-In the original mode,
-
-```js
-var foo = 10,
-bar = 20,
-baz = 30;
-```
-
-In this mode when the value of `js2-pretty-multiline-declarations` is non-nil,
-
-```js
-var foo = 10,
- bar = 20,
- baz = 30;
-```
-
-### Abbreviated destructuring assignments
-
-```js
-let {a, b} = {a: 10, b: 20}; // Abbreviated (Not supported in the
original mode)
-let {a: a, b: b} = {a: 10, b: 20}; // Same as above (Supported in the original
mode)
-
-(function ({responseText}) { /* */ })(xhr); // As the argument of function
-
-for (let [k, { name, age }] in Iterator(obj)) // nested
- print(k, name, age);
-```
-
-### Expression closure in property value
-
-```js
-let worker = {
- get age() 20,
- get sex() "male",
- fire: function () _fire()
-};
-```
-
-### Fix for odd indentation of "else if" with no braces
-
-In the original mode,
-
-```js
-if (foo)
- return foo;
-else if (bar)
-return bar; // here
-```
-
-In this mode,
-
-```js
-if (foo)
- return foo;
-else if (bar)
- return bar; // fixed
-```
-
-### Imenu support for function nesting
-
-Supports function nesting and anonymous wrappers:
-
-```js
-(function() {
- var foo = function() {
- function bar() { // shown as foo.bar.<definition-1>
- function baz() {} // foo.bar.baz
- var qux = function() {}; // foo.bar.quux
- }
- };
-});
-```
-
-Examples of output:
-
-* [jQuery 1.5](https://gist.github.com/845449)
-* [Underscore.js](https://gist.github.com/824262)
-* [Backbone.js](https://gist.github.com/824260)
-
-For library-specific extension methods like `$.extend` and `dojo.declare`, see
[js2-imenu-extras](/mooz/js2-mode/blob/master/js2-imenu-extras.el).
-
-### Undeclared/external variables highlighting
-
-Original mode highlights them only on the left side of assignments:
-
-```js
-var house;
-hose = new House(); // highlights "hose"
-```
-
-Here they are highlighted in all expressions:
-
-```js
-function feed(fishes, food) {
- for each (var fish in fshes) { // highlights "fshes"
- food.feed(fsh); // highlights "fsh"
- }
- hood.discard(); // highlights "hood"
-}
-```
-
-Destructuring assignments and array comprehensions (JS 1.7) are supported:
-
-```js
-let three, [one, two] = [1, 2];
-thee = one + two; // highlights "thee"
-
-function revenue(goods) {
- // highlights "coast"
- return [price - coast for each ({price, cost} in goods)].reduce(add);
-}
-```
diff --git a/packages/js2-mode/README.md b/packages/js2-mode/README.md
deleted file mode 100644
index 755a818..0000000
--- a/packages/js2-mode/README.md
+++ /dev/null
@@ -1,58 +0,0 @@
-About [![Build
Status](https://travis-ci.org/mooz/js2-mode.svg?branch=master)](https://travis-ci.org/mooz/js2-mode)
[![MELPA](https://melpa.org/packages/js2-mode-badge.svg)](https://melpa.org/#/js2-mode)
-======
-
-Improved JavaScript editing mode for GNU Emacs ([description
here](http://elpa.gnu.org/packages/js2-mode.html)).
-
-For some of the latest changes, see [latest user-visible
changes](https://github.com/mooz/js2-mode/blob/master/NEWS.md).
-
-Installation
-======
-
-The stable versions are hosted at [GNU ELPA](http://elpa.gnu.org/)
-(<kbd>M-x list-packages</kbd>).
-
-You can also install the latest development version from
-[MELPA](https://melpa.org/#/getting-started).
-
-Emacs 22 and 23
-===============
-
-This version requires Emacs 24 and `cl-lib` (either built-in or from GNU ELPA
above).
-For a backward compatible version, check out the branch
-[emacs23](https://github.com/mooz/js2-mode/tree/emacs23).
-
-Bugs
-====
-
-* See broken syntax highlighting and timer errors? Recently upgraded
-Emacs from version 24.2 or earlier? Try
-[reinstalling or byte-recompiling](https://github.com/mooz/js2-mode/issues/72)
-the package.
-
-* Any indentation problems should be reported with `M-x report-emacs-bug`
-(please try reproducing them with `js-mode` first, for clarity).
-Starting with Emacs 25, `js2-mode` delegates indentation to
-the indentation engine of `js-mode`.
-
-Please report other problems at <http://github.com/mooz/js2-mode/issues>.
-
-Contributing
-======
-
-`js2-mode` is subject to the same
-[copyright
assignment](http://www.gnu.org/prep/maintain/html_node/Copyright-Papers.html)
-policy as Emacs itself, `org-mode`, `CEDET` and other packages in
-[GNU ELPA](http://elpa.gnu.org/packages/).
-
-Any
-[legally
significant](http://www.gnu.org/prep/maintain/html_node/Legally-Significant.html#Legally-Significant)
-contributions can only be accepted after the author has completed their
-paperwork. Please ask for the request form, and we'll send it to you.
-
-See Also
-======
-
-Some third-party modes that use the generated syntax tree:
-
-* [js2-refactor](https://github.com/magnars/js2-refactor.el)
-* [skewer-mode](https://github.com/skeeto/skewer-mode)
diff --git a/packages/js2-mode/js2-imenu-extras.el
b/packages/js2-mode/js2-imenu-extras.el
deleted file mode 100644
index 81c6d08..0000000
--- a/packages/js2-mode/js2-imenu-extras.el
+++ /dev/null
@@ -1,349 +0,0 @@
-;;; js2-imenu-extras.el --- Imenu support for additional constructs
-
-;; Copyright (C) 2012-2014 Free Software Foundation, Inc.
-
-;; Author: Dmitry Gutov <dgutov@yandex.ru>
-;; Keywords: languages, javascript, imenu
-
-;; 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 adds Imenu support for additional framework constructs and
-;; structural patterns to `js2-mode'.
-
-;; Usage:
-
-;; (add-hook 'js2-mode-hook 'js2-imenu-extras-mode)
-
-;; To customize how it works:
-;; M-x customize-group RET js2-imenu RET
-
-(eval-when-compile
- (require 'cl))
-
-(require 'js2-mode)
-
-(defvar js2-imenu-extension-styles
- `((:framework jquery
- :call-re "\\_<\\(?:jQuery\\|\\$\\|_\\)\\.extend\\s-*("
- :recorder js2-imenu-record-jquery-extend)
-
- (:framework jquery-ui
- :call-re "^\\s-*\\(?:jQuery\\|\\$\\)\\.widget\\s-*("
- :recorder js2-imenu-record-string-declare)
-
- (:framework dojo
- :call-re "^\\s-*dojo.declare\\s-*("
- :recorder js2-imenu-record-string-declare)
-
- (:framework backbone
- :call-re ,(concat "\\_<" js2-mode-identifier-re "\\.extend\\s-*(")
- :recorder js2-imenu-record-backbone-extend)
-
- (:framework enyo
- :call-re "\\_<enyo\\.kind\\s-*("
- :recorder js2-imenu-record-enyo-kind)
-
- (:framework react
- :call-re "\\_<React\\.createClass\\s-*("
- :recorder js2-imenu-record-react-class)
-
- (:framework sencha
- :call-re "^\\s-*Ext\\.define\\s-*("
- :recorder js2-imenu-record-sencha-class))
- "List of JavaScript class definition or extension styles.
-
-:framework is a valid value in `js2-imenu-enabled-frameworks'.
-
-:call-re is a regular expression that has no capturing groups.
-
-:recorder is a function name that will be called when the regular
-expression matches some text in the buffer. When it's called, point will be
-at the end of the match. The function must keep the point position.")
-
-(defconst js2-imenu-available-frameworks
- (mapcar (lambda (style) (plist-get style :framework))
js2-imenu-extension-styles)
- "List of available JavaScript framework symbols.")
-
-(defcustom js2-imenu-enabled-frameworks js2-imenu-available-frameworks
- "Frameworks to be recognized by `js2-mode'."
- :type (cons 'set (mapcar (lambda (x) (list 'const x))
- js2-imenu-available-frameworks))
- :group 'js2-imenu)
-
-(defcustom js2-imenu-show-other-functions t
- "Non-nil to show functions not recognized by other mechanisms,
-in a shared namespace."
- :type 'boolean
- :group 'js2-imenu)
-
-(defcustom js2-imenu-other-functions-ns "?"
- "Namespace name to use for other functions."
- :type 'string
- :group 'js2-imenu)
-
-(defcustom js2-imenu-show-module-pattern t
- "Non-nil to recognize the module pattern:
-
-var foobs = (function(a) {
- return {fib: function() {}, fub: function() {}};
-})(b);
-
-We record the returned hash as belonging to the named module, and
-prefix any functions defined inside the IIFE with the module name."
- :type 'boolean
- :group 'js2-imenu)
-
-(defcustom js2-imenu-split-string-identifiers t
- "When non-nil, split string identifiers on dots.
-Currently used for jQuery widgets, Dojo and Enyo declarations."
- :type 'boolean
- :group 'js2-imenu)
-
-;;;###autoload
-(defun js2-imenu-extras-setup ()
- (when js2-imenu-enabled-frameworks
- (add-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t t))
- (when (or js2-imenu-show-other-functions js2-imenu-show-module-pattern)
- (add-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t t)))
-
-(defun js2-imenu-extras-remove ()
- (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-record-declarations t)
- (remove-hook 'js2-build-imenu-callbacks 'js2-imenu-walk-ast t))
-
-(defun js2-imenu-record-declarations ()
- (let* ((styles (loop for style in js2-imenu-extension-styles
- when (memq (plist-get style :framework)
- js2-imenu-enabled-frameworks)
- collect style))
- (re (mapconcat (lambda (style)
- (concat "\\(" (plist-get style :call-re) "\\)"))
- styles "\\|")))
- (goto-char (point-min))
- (while (js2-re-search-forward re nil t)
- (loop for i from 0 to (1- (length styles))
- when (match-beginning (1+ i))
- return (funcall (plist-get (nth i styles) :recorder))))))
-
-(defun js2-imenu-record-jquery-extend ()
- (let ((pred (lambda (subject)
- (and
- (js2-prop-get-node-p subject)
- (string= (js2-name-node-name (js2-prop-get-node-right
subject))
- "prototype")))))
- (js2-imenu-record-extend-first-arg (1- (point)) pred
- 'js2-compute-nested-prop-get)))
-
-(defun js2-imenu-record-string-declare ()
- (js2-imenu-record-extend-first-arg
- (1- (point)) 'js2-string-node-p
- (lambda (node)
- (if js2-imenu-split-string-identifiers
- (split-string (js2-string-node-value node) "\\." t)
- (list (js2-string-node-value node))))))
-
-(defun js2-imenu-record-extend-first-arg (point pred qname-fn)
- (let* ((node (js2-node-at-point point))
- (args (js2-call-node-args node))
- (subject (first args)))
- (when (funcall pred subject)
- (loop for arg in (cdr args)
- when (js2-object-node-p arg)
- do (js2-record-object-literal
- arg (funcall qname-fn subject) (js2-node-abs-pos arg))))))
-
-(defun js2-imenu-record-backbone-or-react ()
- (let* ((node (js2-node-at-point (1- (point))))
- (args (js2-call-node-args node))
- (methods (first args))
- (parent (js2-node-parent node)))
- (when (js2-object-node-p methods)
- (let ((subject (cond ((js2-var-init-node-p parent)
- (js2-var-init-node-target parent))
- ((js2-assign-node-p parent)
- (js2-assign-node-left parent)))))
- (when subject
- (js2-record-object-literal methods
- (js2-compute-nested-prop-get subject)
- (js2-node-abs-pos methods)))))))
-
-(defalias 'js2-imenu-record-backbone-extend
'js2-imenu-record-backbone-or-react)
-
-(defalias 'js2-imenu-record-react-class 'js2-imenu-record-backbone-or-react)
-
-(defun js2-imenu-record-enyo-kind ()
- (let* ((node (js2-node-at-point (1- (point))))
- (args (js2-call-node-args node))
- (options (first args)))
- (when (js2-object-node-p options)
- (let ((name-value
- (loop for elem in (js2-object-node-elems options)
- thereis
- (let ((key (js2-object-prop-node-left elem))
- (value (js2-object-prop-node-right elem)))
- (when (and (equal
- (cond ((js2-name-node-p key)
- (js2-name-node-name key))
- ((js2-string-node-p key)
- (js2-string-node-value key)))
- "name")
- (js2-string-node-p value))
- (js2-string-node-value value))))))
- (when name-value
- (js2-record-object-literal options
- (if js2-imenu-split-string-identifiers
- (split-string name-value "\\.")
- (list name-value))
- (js2-node-abs-pos options)))))))
-
-(defun js2-imenu-record-sencha-class ()
- (let* ((node (js2-node-at-point (1- (point))))
- (args (js2-call-node-args node))
- (name (first args))
- (methods (second args)))
- (when (and (js2-string-node-p name) (js2-object-node-p methods))
- (let ((name-value (js2-string-node-value name)))
- (js2-record-object-literal methods
- (if js2-imenu-split-string-identifiers
- (split-string name-value "\\." t)
- (list name-value))
- (js2-node-abs-pos methods))))))
-
-(defun js2-imenu-walk-ast ()
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (unless end-p
- (cond
- ((and js2-imenu-show-other-functions
- (js2-object-prop-node-p node))
- (js2-imenu-record-orphan-prop-node-function node))
- ((js2-assign-node-p node)
- (cond
- ((and js2-imenu-show-other-functions
- (js2-function-node-p
- (js2-assign-node-right node)))
- (js2-imenu-record-orphan-assign-node-function
- (js2-assign-node-left node)
- (js2-assign-node-right node)))
- ((and js2-imenu-show-module-pattern
- (js2-call-node-p
- (js2-assign-node-right node)))
- (js2-imenu-record-module-pattern
- (js2-assign-node-left node)
- (js2-assign-node-right node)))))
- ((js2-var-init-node-p node)
- (cond
- ((and js2-imenu-show-other-functions
- (js2-function-node-p
- (js2-var-init-node-initializer node)))
- (js2-imenu-record-orphan-assign-node-function
- (js2-var-init-node-target node)
- (js2-var-init-node-initializer node)))
- ((and js2-imenu-show-module-pattern
- (js2-call-node-p
- (js2-var-init-node-initializer node)))
- (js2-imenu-record-module-pattern
- (js2-var-init-node-target node)
- (js2-var-init-node-initializer node))))))
- t))))
-
-(defun js2-imenu-parent-key-names (node)
- "Get the list of parent key names of NODE.
-
-For example, for code
-
- {rules: {password: {required: function() {}}}}
-
-when NODE is the inner `js2-object-prop-mode',
-it returns (\"rules\" \"password\")."
- (let (rlt (n node))
- (while (setq n (js2-imenu-parent-prop-node n))
- (push (js2-prop-node-name (js2-object-prop-node-left n)) rlt))
- rlt))
-
-(defun js2-imenu-parent-prop-node (node)
- "When the parent of NODE is `js2-object-node',
-and the grandparent is `js2-object-prop-node',
-return the grandparent."
- ;; Suppose the code is:
- ;; {parent-key: {required: function() {}}}
- ;; NODE is `required: function() {}'.
- (let (p2 p3)
- ;; Parent is `{required: function() {}}'.
- (setq p2 (js2-node-parent node))
- ;; GP is `parent-key: {required: function() {}}'.
- (when (and p2 (js2-object-node-p p2))
- (setq p3 (js2-node-parent p2))
- (if (and p3 (js2-object-prop-node-p p3)) p3))))
-
-(defun js2-imenu-record-orphan-prop-node-function (node)
- "Record orphan function when it's the value of NODE.
-NODE must be `js2-object-prop-node'."
- (when (js2-function-node-p (js2-object-prop-node-right node))
- (let ((fn-node (js2-object-prop-node-right node)))
- (unless (and js2-imenu-function-map
- (gethash fn-node js2-imenu-function-map))
- (let ((key-node (js2-object-prop-node-left node))
- (parent-prop-node (js2-imenu-parent-prop-node node))
- chain)
- (setq chain (nconc (js2-imenu-parent-key-names node)
- (list (js2-prop-node-name key-node))))
- (push js2-imenu-other-functions-ns chain)
- (js2-record-imenu-entry fn-node chain
- (js2-node-abs-pos key-node)))))))
-
-(defun js2-imenu-record-orphan-assign-node-function (target-node fn-node)
- "Record orphan function FN-NODE assigned to node TARGET."
- (when (or (not js2-imenu-function-map)
- (eq 'skip
- (gethash fn-node js2-imenu-function-map 'skip)))
- (let ((chain (js2-compute-nested-prop-get target-node)))
- (when chain
- (push js2-imenu-other-functions-ns chain)
- (js2-record-imenu-entry fn-node chain (js2-node-abs-pos fn-node))))))
-
-(defun js2-imenu-record-module-pattern (target init)
- "Recognize and record module pattern use instance.
-INIT must be `js2-call-node'."
- (let ((callt (js2-call-node-target init)))
- ;; Just basic call form: (function() {...})();
- ;; TODO: Handle variations without duplicating `js2-wrapper-function-p'?
- (when (and (js2-paren-node-p callt)
- (js2-function-node-p (js2-paren-node-expr callt)))
- (let* ((fn (js2-paren-node-expr callt))
- (blk (js2-function-node-body fn))
- (ret (car (last (js2-block-node-kids blk)))))
- (when (and (js2-return-node-p ret)
- (js2-object-node-p (js2-return-node-retval ret)))
- ;; TODO: Map function names when revealing module pattern is used.
- (let ((retval (js2-return-node-retval ret))
- (target-qname (js2-compute-nested-prop-get target)))
- (js2-record-object-literal retval target-qname
- (js2-node-abs-pos retval))
- (js2-record-imenu-entry fn target-qname
- (js2-node-abs-pos target))))))))
-
-;;;###autoload
-(define-minor-mode js2-imenu-extras-mode
- "Toggle Imenu support for frameworks and structural patterns."
- :lighter ""
- (if js2-imenu-extras-mode
- (js2-imenu-extras-setup)
- (js2-imenu-extras-remove)))
-
-(provide 'js2-imenu-extras)
diff --git a/packages/js2-mode/js2-mode.el b/packages/js2-mode/js2-mode.el
deleted file mode 100644
index 3f789fa..0000000
--- a/packages/js2-mode/js2-mode.el
+++ /dev/null
@@ -1,12852 +0,0 @@
-;;; js2-mode.el --- Improved JavaScript editing mode -*- lexical-binding: t -*-
-
-;; Copyright (C) 2009, 2011-2018 Free Software Foundation, Inc.
-
-;; Author: Steve Yegge <steve.yegge@gmail.com>
-;; mooz <stillpedant@gmail.com>
-;; Dmitry Gutov <dgutov@yandex.ru>
-;; URL: https://github.com/mooz/js2-mode/
-;; http://code.google.com/p/js2-mode/
-;; Version: 20190219
-;; Keywords: languages, javascript
-;; Package-Requires: ((emacs "24.1") (cl-lib "0.5"))
-
-;; 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 JavaScript editing mode supports:
-
-;; - strict recognition of the Ecma-262 language standard
-;; - support for most Rhino and SpiderMonkey extensions from 1.5 and up
-;; - parsing support for ECMAScript for XML (E4X, ECMA-357)
-;; - accurate syntax highlighting using a recursive-descent parser
-;; - on-the-fly reporting of syntax errors and strict-mode warnings
-;; - undeclared-variable warnings using a configurable externs framework
-;; - "bouncing" line indentation to choose among alternate indentation points
-;; - smart line-wrapping within comments and strings
-;; - code folding:
-;; - show some or all function bodies as {...}
-;; - show some or all block comments as /*...*/
-;; - context-sensitive menu bar and popup menus
-;; - code browsing using the `imenu' package
-;; - many customization options
-
-;; Installation:
-;;
-;; To install it as your major mode for JavaScript editing:
-
-;; (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
-
-;; Alternatively, to install it as a minor mode just for JavaScript linting,
-;; you must add it to the appropriate major-mode hook. Normally this would be:
-
-;; (add-hook 'js-mode-hook 'js2-minor-mode)
-
-;; You may also want to hook it in for shell scripts running via node.js:
-
-;; (add-to-list 'interpreter-mode-alist '("node" . js2-mode))
-
-;; Support for JSX is available via the derived mode `js2-jsx-mode'. If you
-;; also want JSX support, use that mode instead:
-
-;; (add-to-list 'auto-mode-alist '("\\.jsx?\\'" . js2-jsx-mode))
-;; (add-to-list 'interpreter-mode-alist '("node" . js2-jsx-mode))
-
-;; To customize how it works:
-;; M-x customize-group RET js2-mode RET
-
-;; Notes:
-
-;; This mode includes a port of Mozilla Rhino's scanner, parser and
-;; symbol table. Ideally it should stay in sync with Rhino, keeping
-;; `js2-mode' current as the EcmaScript language standard evolves.
-
-;; Unlike cc-engine based language modes, js2-mode's line-indentation is not
-;; customizable. It is a surprising amount of work to support customizable
-;; indentation. The current compromise is that the tab key lets you cycle
among
-;; various likely indentation points, similar to the behavior of python-mode.
-
-;; This mode does not yet work with "multi-mode" modes such as `mmm-mode'
-;; and `mumamo', although it could be made to do so with some effort.
-;; This means that `js2-mode' is currently only useful for editing JavaScript
-;; files, and not for editing JavaScript within <script> tags or templates.
-
-;; The project page on GitHub is used for development and issue tracking.
-;; The original homepage at Google Code has outdated information and is mostly
-;; unmaintained.
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'imenu)
-(require 'js)
-(require 'etags)
-
-(eval-and-compile
- (if (version< emacs-version "25.0")
- (require 'js2-old-indent)
- (defvaralias 'js2-basic-offset 'js-indent-level nil)
- (defalias 'js2-proper-indentation 'js--proper-indentation)
- (defalias 'js2-jsx-indent-line 'js-jsx-indent-line)
- (defalias 'js2-indent-line 'js-indent-line)
- (defalias 'js2-re-search-forward 'js--re-search-forward)))
-
-;;; Externs (variables presumed to be defined by the host system)
-
-(defvar js2-ecma-262-externs
- (mapcar 'symbol-name
- '(Array Boolean Date Error EvalError Function Infinity JSON
- Math NaN Number Object RangeError ReferenceError RegExp
- String SyntaxError TypeError URIError
- decodeURI decodeURIComponent encodeURI
- encodeURIComponent escape eval isFinite isNaN
- parseFloat parseInt undefined unescape))
-"Ecma-262 externs. Never highlighted as undeclared variables.")
-
-(defvar js2-browser-externs
- (mapcar 'symbol-name
- '(;; DOM level 1
- Attr CDATASection CharacterData Comment DOMException
- DOMImplementation Document DocumentFragment
- DocumentType Element Entity EntityReference
- ExceptionCode NamedNodeMap Node NodeList Notation
- ProcessingInstruction Text
-
- ;; DOM level 2
- HTMLAnchorElement HTMLAppletElement HTMLAreaElement
- HTMLBRElement HTMLBaseElement HTMLBaseFontElement
- HTMLBodyElement HTMLButtonElement HTMLCollection
- HTMLDListElement HTMLDirectoryElement HTMLDivElement
- HTMLDocument HTMLElement HTMLFieldSetElement
- HTMLFontElement HTMLFormElement HTMLFrameElement
- HTMLFrameSetElement HTMLHRElement HTMLHeadElement
- HTMLHeadingElement HTMLHtmlElement HTMLIFrameElement
- HTMLImageElement HTMLInputElement HTMLIsIndexElement
- HTMLLIElement HTMLLabelElement HTMLLegendElement
- HTMLLinkElement HTMLMapElement HTMLMenuElement
- HTMLMetaElement HTMLModElement HTMLOListElement
- HTMLObjectElement HTMLOptGroupElement
- HTMLOptionElement HTMLOptionsCollection
- HTMLParagraphElement HTMLParamElement HTMLPreElement
- HTMLQuoteElement HTMLScriptElement HTMLSelectElement
- HTMLStyleElement HTMLTableCaptionElement
- HTMLTableCellElement HTMLTableColElement
- HTMLTableElement HTMLTableRowElement
- HTMLTableSectionElement HTMLTextAreaElement
- HTMLTitleElement HTMLUListElement
-
- ;; DOM level 3
- DOMConfiguration DOMError DOMException
- DOMImplementationList DOMImplementationSource
- DOMLocator DOMStringList NameList TypeInfo
- UserDataHandler
-
- ;; Window
- window alert confirm document java navigator prompt screen
- self top requestAnimationFrame cancelAnimationFrame
-
- ;; W3C CSS
- CSSCharsetRule CSSFontFace CSSFontFaceRule
- CSSImportRule CSSMediaRule CSSPageRule
- CSSPrimitiveValue CSSProperties CSSRule CSSRuleList
- CSSStyleDeclaration CSSStyleRule CSSStyleSheet
- CSSValue CSSValueList Counter DOMImplementationCSS
- DocumentCSS DocumentStyle ElementCSSInlineStyle
- LinkStyle MediaList RGBColor Rect StyleSheet
- StyleSheetList ViewCSS
-
- ;; W3C Event
- EventListener EventTarget Event DocumentEvent UIEvent
- MouseEvent MutationEvent KeyboardEvent
-
- ;; W3C Range
- DocumentRange Range RangeException
-
- ;; W3C XML
- XPathResult XMLHttpRequest
-
- ;; console object. Provided by at least Chrome and Firefox.
- console))
- "Browser externs.
-You can cause these to be included or excluded with the custom
-variable `js2-include-browser-externs'.")
-
-(defvar js2-rhino-externs
- (mapcar 'symbol-name
- '(Packages importClass importPackage com org java
- ;; Global object (shell) externs.
- defineClass deserialize doctest gc help load
- loadClass print quit readFile readUrl runCommand seal
- serialize spawn sync toint32 version))
- "Mozilla Rhino externs.
-Set `js2-include-rhino-externs' to t to include them.")
-
-(defvar js2-node-externs
- (mapcar 'symbol-name
- '(__dirname __filename Buffer clearInterval clearTimeout require
- console exports global module process setInterval setTimeout
- querystring setImmediate clearImmediate))
- "Node.js externs.
-Set `js2-include-node-externs' to t to include them.")
-
-(defvar js2-typed-array-externs
- (mapcar 'symbol-name
- '(ArrayBuffer Uint8ClampedArray DataView
- Int8Array Uint8Array Int16Array Uint16Array Int32Array Uint32Array
- Float32Array Float64Array))
- "Khronos typed array externs. Available in most modern browsers and
-in node.js >= 0.6. If `js2-include-node-externs' or
`js2-include-browser-externs'
-are enabled, these will also be included.")
-
-(defvar js2-harmony-externs
- (mapcar 'symbol-name
- '(Map Promise Proxy Reflect Set Symbol WeakMap WeakSet))
- "ES6 externs. If `js2-include-browser-externs' is enabled and
-`js2-language-version' is sufficiently high, these will be included.")
-
-;;; Variables
-
-(defcustom js2-ignored-warnings nil
- "A list of warning message types that will not be reported.
-
-Possible values are the keys of `js2-message-table'."
- :group 'js2-mode
- :type '(repeat string))
-
-(defcustom js2-highlight-level 2
- "Amount of syntax highlighting to perform.
-0 or a negative value means none.
-1 adds basic syntax highlighting.
-2 adds highlighting of some Ecma built-in properties.
-3 adds highlighting of many Ecma built-in functions."
- :group 'js2-mode
- :type '(choice (const :tag "None" 0)
- (const :tag "Basic" 1)
- (const :tag "Include Properties" 2)
- (const :tag "Include Functions" 3)))
-
-(defvar js2-mode-dev-mode-p nil
- "Non-nil if running in development mode. Normally nil.")
-
-(defgroup js2-mode nil
- "An improved JavaScript mode."
- :group 'languages)
-
-(defcustom js2-idle-timer-delay 0.2
- "Delay in secs before re-parsing after user makes changes.
-Multiplied by `js2-dynamic-idle-timer-adjust', which see."
- :type 'number
- :group 'js2-mode)
-(make-variable-buffer-local 'js2-idle-timer-delay)
-
-(defcustom js2-dynamic-idle-timer-adjust 0
- "Positive to adjust `js2-idle-timer-delay' based on file size.
-The idea is that for short files, parsing is faster so we can be
-more responsive to user edits without interfering with editing.
-The buffer length in characters (typically bytes) is divided by
-this value and used to multiply `js2-idle-timer-delay' for the
-buffer. For example, a 21k file and 10k adjust yields 21k/10k
-== 2, so js2-idle-timer-delay is multiplied by 2.
-If `js2-dynamic-idle-timer-adjust' is 0 or negative,
-`js2-idle-timer-delay' is not dependent on the file size."
- :type 'number
- :group 'js2-mode)
-
-(defcustom js2-concat-multiline-strings t
- "When non-nil, `js2-line-break' in mid-string will make it a
-string concatenation. When `eol', the `+' will be inserted at the
-end of the line, otherwise, at the beginning of the next line."
- :type '(choice (const t) (const eol) (const nil))
- :group 'js2-mode)
-
-(defcustom js2-mode-show-parse-errors t
- "True to highlight parse errors."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-mode-assume-strict nil
- "Non-nil to start files in strict mode automatically."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-mode-show-strict-warnings t
- "Non-nil to emit Ecma strict-mode warnings.
-Some of the warnings can be individually disabled by other flags,
-even if this flag is non-nil."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-trailing-comma-warning nil
- "Non-nil to warn about trailing commas in array literals.
-Ecma-262-5.1 allows them, but older versions of IE raise an error."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-missing-semi-warning t
- "Non-nil to warn about semicolon auto-insertion after statement.
-Technically this is legal per Ecma-262, but some style guides disallow
-depending on it."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-missing-semi-one-line-override nil
- "Non-nil to permit missing semicolons in one-line functions.
-In one-liner functions such as `function identity(x) {return x}'
-people often omit the semicolon for a cleaner look. If you are
-such a person, you can suppress the missing-semicolon warning
-by setting this variable to t."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-inconsistent-return-warning t
- "Non-nil to warn about mixing returns with value-returns.
-It's perfectly legal to have a `return' and a `return foo' in the
-same function, but it's often an indicator of a bug, and it also
-interferes with type inference (in systems that support it.)"
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-cond-assign-warning t
- "Non-nil to warn about usage like `if (a = b)'.
-This often should have been `==' instead of `='. If the warning
-is enabled, you can suppress it on a per-expression basis by
-parenthesizing the expression, e.g., `if ((a = b)) ...'."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-var-redeclaration-warning t
- "Non-nil to warn about redeclaring variables in a script or function."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-strict-var-hides-function-arg-warning t
- "Non-nil to warn about a var decl hiding a function argument."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-skip-preprocessor-directives nil
- "Non-nil to treat lines beginning with # as comments.
-Useful for viewing Mozilla JavaScript source code."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-language-version 200
- "Configures what JavaScript language version to recognize.
-Currently versions 150, 160, 170, 180 and 200 are supported,
-corresponding to JavaScript 1.5, 1.6, 1.7, 1.8 and 2.0 (Harmony),
-respectively. In a nutshell, 1.6 adds E4X support, 1.7 adds let,
-yield, and Array comprehensions, and 1.8 adds function closures."
- :type 'integer
- :group 'js2-mode)
-
-(defcustom js2-instanceof-has-side-effects nil
- "If non-nil, treats the instanceof operator as having side effects.
-This is useful for xulrunner apps."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-getprop-has-side-effects nil
- "If non-nil, treats the getprop operator as having side effects.
-This is useful for testing libraries with nontrivial getters and for
-compilers that use empty getprops to declare interface properties."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-move-point-on-right-click t
- "Non-nil to move insertion point when you right-click.
-This makes right-click context menu behavior a bit more intuitive,
-since menu operations generally apply to the point. The exception
-is if there is a region selection, in which case the point does -not-
-move, so cut/copy/paste can work properly.
-
-Note that IntelliJ moves the point, and Eclipse leaves it alone,
-so this behavior is customizable."
- :group 'js2-mode
- :type 'boolean)
-
-(defcustom js2-allow-rhino-new-expr-initializer t
- "Non-nil to support a Rhino's experimental syntactic construct.
-
-Rhino supports the ability to follow a `new' expression with an object
-literal, which is used to set additional properties on the new object
-after calling its constructor. Syntax:
-
- new <expr> [ ( arglist ) ] [initializer]
-
-Hence, this expression:
-
- new Object {a: 1, b: 2}
-
-results in an Object with properties a=1 and b=2. This syntax is
-apparently not configurable in Rhino - it's currently always enabled,
-as of Rhino version 1.7R2."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-allow-member-expr-as-function-name nil
- "Non-nil to support experimental Rhino syntax for function names.
-
-Rhino supports an experimental syntax configured via the Rhino Context
-setting `allowMemberExprAsFunctionName'. The experimental syntax is:
-
- function <member-expr> ( [ arg-list ] ) { <body> }
-
-Where member-expr is a non-parenthesized `member expression', which
-is anything at the grammar level of a new-expression or lower, meaning
-any expression that does not involve infix or unary operators.
-
-When <member-expr> is not a simple identifier, then it is syntactic
-sugar for assigning the anonymous function to the <member-expr>. Hence,
-this code:
-
- function a.b().c[2] (x, y) { ... }
-
-is rewritten as:
-
- a.b().c[2] = function(x, y) {...}
-
-which doesn't seem particularly useful, but Rhino permits it."
- :type 'boolean
- :group 'js2-mode)
-
-;; scanner variables
-
-(defmacro js2-deflocal (name value &optional comment)
- "Define a buffer-local variable NAME with VALUE and COMMENT."
- (declare (debug defvar) (doc-string 3))
- `(progn
- (defvar ,name ,value ,comment)
- (make-variable-buffer-local ',name)))
-
-(defvar js2-EOF_CHAR -1
- "Represents end of stream. Distinct from js2-EOF token type.")
-
-;; I originally used symbols to represent tokens, but Rhino uses
-;; ints and then sets various flag bits in them, so ints it is.
-;; The upshot is that we need a `js2-' prefix in front of each name.
-(defvar js2-ERROR -1)
-(defvar js2-EOF 0)
-(defvar js2-EOL 1)
-(defvar js2-ENTERWITH 2) ; begin interpreter bytecodes
-(defvar js2-LEAVEWITH 3)
-(defvar js2-RETURN 4)
-(defvar js2-GOTO 5)
-(defvar js2-IFEQ 6)
-(defvar js2-IFNE 7)
-(defvar js2-SETNAME 8)
-(defvar js2-BITOR 9)
-(defvar js2-BITXOR 10)
-(defvar js2-BITAND 11)
-(defvar js2-EQ 12)
-(defvar js2-NE 13)
-(defvar js2-LT 14)
-(defvar js2-LE 15)
-(defvar js2-GT 16)
-(defvar js2-GE 17)
-(defvar js2-LSH 18)
-(defvar js2-RSH 19)
-(defvar js2-URSH 20)
-(defvar js2-ADD 21) ; infix plus
-(defvar js2-SUB 22) ; infix minus
-(defvar js2-MUL 23)
-(defvar js2-DIV 24)
-(defvar js2-MOD 25)
-(defvar js2-NOT 26)
-(defvar js2-BITNOT 27)
-(defvar js2-POS 28) ; unary plus
-(defvar js2-NEG 29) ; unary minus
-(defvar js2-NEW 30)
-(defvar js2-DELPROP 31)
-(defvar js2-TYPEOF 32)
-(defvar js2-GETPROP 33)
-(defvar js2-GETPROPNOWARN 34)
-(defvar js2-SETPROP 35)
-(defvar js2-GETELEM 36)
-(defvar js2-SETELEM 37)
-(defvar js2-CALL 38)
-(defvar js2-NAME 39) ; an identifier
-(defvar js2-NUMBER 40)
-(defvar js2-STRING 41)
-(defvar js2-NULL 42)
-(defvar js2-THIS 43)
-(defvar js2-FALSE 44)
-(defvar js2-TRUE 45)
-(defvar js2-SHEQ 46) ; shallow equality (===)
-(defvar js2-SHNE 47) ; shallow inequality (!==)
-(defvar js2-REGEXP 48)
-(defvar js2-BINDNAME 49)
-(defvar js2-THROW 50)
-(defvar js2-RETHROW 51) ; rethrow caught exception: catch (e if ) uses
it
-(defvar js2-IN 52)
-(defvar js2-INSTANCEOF 53)
-(defvar js2-LOCAL_LOAD 54)
-(defvar js2-GETVAR 55)
-(defvar js2-SETVAR 56)
-(defvar js2-CATCH_SCOPE 57)
-(defvar js2-ENUM_INIT_KEYS 58) ; FIXME: what are these?
-(defvar js2-ENUM_INIT_VALUES 59)
-(defvar js2-ENUM_INIT_ARRAY 60)
-(defvar js2-ENUM_NEXT 61)
-(defvar js2-ENUM_ID 62)
-(defvar js2-THISFN 63)
-(defvar js2-RETURN_RESULT 64) ; to return previously stored return result
-(defvar js2-ARRAYLIT 65) ; array literal
-(defvar js2-OBJECTLIT 66) ; object literal
-(defvar js2-GET_REF 67) ; *reference
-(defvar js2-SET_REF 68) ; *reference = something
-(defvar js2-DEL_REF 69) ; delete reference
-(defvar js2-REF_CALL 70) ; f(args) = something or f(args)++
-(defvar js2-REF_SPECIAL 71) ; reference for special properties like __proto
-(defvar js2-YIELD 72) ; JS 1.7 yield pseudo keyword
-
-;; XML support
-(defvar js2-DEFAULTNAMESPACE 73)
-(defvar js2-ESCXMLATTR 74)
-(defvar js2-ESCXMLTEXT 75)
-(defvar js2-REF_MEMBER 76) ; Reference for x.@y, x..y etc.
-(defvar js2-REF_NS_MEMBER 77) ; Reference for x.ns::y, x..ns::y etc.
-(defvar js2-REF_NAME 78) ; Reference for @y, @[y] etc.
-(defvar js2-REF_NS_NAME 79) ; Reference for ns::y, @ns::y@[y] etc.
-
-(defvar js2-first-bytecode js2-ENTERWITH)
-(defvar js2-last-bytecode js2-REF_NS_NAME)
-
-(defvar js2-TRY 80)
-(defvar js2-SEMI 81) ; semicolon
-(defvar js2-LB 82) ; left and right brackets
-(defvar js2-RB 83)
-(defvar js2-LC 84) ; left and right curly-braces
-(defvar js2-RC 85)
-(defvar js2-LP 86) ; left and right parens
-(defvar js2-RP 87)
-(defvar js2-COMMA 88) ; comma operator
-
-(defvar js2-ASSIGN 89) ; simple assignment (=)
-(defvar js2-ASSIGN_BITOR 90) ; |=
-(defvar js2-ASSIGN_BITXOR 91) ; ^=
-(defvar js2-ASSIGN_BITAND 92) ; &=
-(defvar js2-ASSIGN_LSH 93) ; <<=
-(defvar js2-ASSIGN_RSH 94) ; >>=
-(defvar js2-ASSIGN_URSH 95) ; >>>=
-(defvar js2-ASSIGN_ADD 96) ; +=
-(defvar js2-ASSIGN_SUB 97) ; -=
-(defvar js2-ASSIGN_MUL 98) ; *=
-(defvar js2-ASSIGN_DIV 99) ; /=
-(defvar js2-ASSIGN_MOD 100) ; %=
-(defvar js2-ASSIGN_EXPON 101)
-
-(defvar js2-first-assign js2-ASSIGN)
-(defvar js2-last-assign js2-ASSIGN_EXPON)
-
-(defvar js2-COLON 102)
-(defvar js2-OR 103) ; logical or (||)
-(defvar js2-AND 104) ; logical and (&&)
-(defvar js2-INC 105) ; increment/decrement (++ --)
-(defvar js2-DEC 106)
-(defvar js2-DOT 107) ; member operator (.)
-(defvar js2-FUNCTION 108) ; function keyword
-(defvar js2-EXPORT 109) ; export keyword
-(defvar js2-IMPORT 110) ; import keyword
-(defvar js2-IF 111) ; if keyword
-(defvar js2-ELSE 112) ; else keyword
-(defvar js2-SWITCH 113) ; switch keyword
-(defvar js2-CASE 114) ; case keyword
-(defvar js2-DEFAULT 115) ; default keyword
-(defvar js2-WHILE 116) ; while keyword
-(defvar js2-DO 117) ; do keyword
-(defvar js2-FOR 118) ; for keyword
-(defvar js2-BREAK 119) ; break keyword
-(defvar js2-CONTINUE 120) ; continue keyword
-(defvar js2-VAR 121) ; var keyword
-(defvar js2-WITH 122) ; with keyword
-(defvar js2-CATCH 123) ; catch keyword
-(defvar js2-FINALLY 124) ; finally keyword
-(defvar js2-VOID 125) ; void keyword
-(defvar js2-RESERVED 126) ; reserved keywords
-
-(defvar js2-EMPTY 127)
-
-;; Types used for the parse tree - never returned by scanner.
-
-(defvar js2-BLOCK 128) ; statement block
-(defvar js2-LABEL 129) ; label
-(defvar js2-TARGET 130)
-(defvar js2-LOOP 131)
-(defvar js2-EXPR_VOID 132) ; expression statement in functions
-(defvar js2-EXPR_RESULT 133) ; expression statement in scripts
-(defvar js2-JSR 134)
-(defvar js2-SCRIPT 135) ; top-level node for entire script
-(defvar js2-TYPEOFNAME 136) ; for typeof(simple-name)
-(defvar js2-USE_STACK 137)
-(defvar js2-SETPROP_OP 138) ; x.y op= something
-(defvar js2-SETELEM_OP 139) ; x[y] op= something
-(defvar js2-LOCAL_BLOCK 140)
-(defvar js2-SET_REF_OP 141) ; *reference op= something
-
-;; For XML support:
-(defvar js2-DOTDOT 142) ; member operator (..)
-(defvar js2-COLONCOLON 143) ; namespace::name
-(defvar js2-XML 144) ; XML type
-(defvar js2-DOTQUERY 145) ; .() -- e.g., x.emps.emp.(name == "terry")
-(defvar js2-XMLATTR 146) ; @
-(defvar js2-XMLEND 147)
-
-;; Optimizer-only tokens
-(defvar js2-TO_OBJECT 148)
-(defvar js2-TO_DOUBLE 149)
-
-(defvar js2-GET 150) ; JS 1.5 get pseudo keyword
-(defvar js2-SET 151) ; JS 1.5 set pseudo keyword
-(defvar js2-LET 152) ; JS 1.7 let pseudo keyword
-(defvar js2-CONST 153)
-(defvar js2-SETCONST 154)
-(defvar js2-SETCONSTVAR 155)
-(defvar js2-ARRAYCOMP 156)
-(defvar js2-LETEXPR 157)
-(defvar js2-WITHEXPR 158)
-(defvar js2-DEBUGGER 159)
-
-(defvar js2-COMMENT 160)
-(defvar js2-TRIPLEDOT 161) ; for rest parameter
-(defvar js2-ARROW 162) ; function arrow (=>)
-(defvar js2-CLASS 163)
-(defvar js2-EXTENDS 164)
-(defvar js2-SUPER 165)
-(defvar js2-TEMPLATE_HEAD 166) ; part of template literal before
substitution
-(defvar js2-NO_SUBS_TEMPLATE 167) ; template literal without substitutions
-(defvar js2-TAGGED_TEMPLATE 168) ; tagged template literal
-
-(defvar js2-AWAIT 169) ; await (pseudo keyword)
-
-(defvar js2-HOOK 170) ; conditional (?:)
-(defvar js2-EXPON 171)
-
-(defconst js2-num-tokens (1+ js2-EXPON))
-
-(defconst js2-debug-print-trees nil)
-
-;; Rhino accepts any string or stream as input. Emacs character
-;; processing works best in buffers, so we'll assume the input is a
-;; buffer. JavaScript strings can be copied into temp buffers before
-;; scanning them.
-
-;; Buffer-local variables yield much cleaner code than using `defstruct'.
-;; They're the Emacs equivalent of instance variables, more or less.
-
-(js2-deflocal js2-ts-dirty-line nil
- "Token stream buffer-local variable.
-Indicates stuff other than whitespace since start of line.")
-
-(js2-deflocal js2-ts-hit-eof nil
- "Token stream buffer-local variable.")
-
-;; FIXME: Unused.
-(js2-deflocal js2-ts-line-start 0
- "Token stream buffer-local variable.")
-
-(js2-deflocal js2-ts-lineno 1
- "Token stream buffer-local variable.")
-
-;; FIXME: Unused.
-(js2-deflocal js2-ts-line-end-char -1
- "Token stream buffer-local variable.")
-
-(js2-deflocal js2-ts-cursor 1 ; emacs buffers are 1-indexed
- "Token stream buffer-local variable.
-Current scan position.")
-
-;; FIXME: Unused.
-(js2-deflocal js2-ts-is-xml-attribute nil
- "Token stream buffer-local variable.")
-
-(js2-deflocal js2-ts-xml-is-tag-content nil
- "Token stream buffer-local variable.")
-
-(js2-deflocal js2-ts-xml-open-tags-count 0
- "Token stream buffer-local variable.")
-
-(js2-deflocal js2-ts-string-buffer nil
- "Token stream buffer-local variable.
-List of chars built up while scanning various tokens.")
-
-(cl-defstruct (js2-token
- (:constructor make-js2-token (beg)))
- "Value returned from the token stream."
- (type js2-EOF)
- (beg 1)
- (end -1)
- (string "")
- number
- number-base
- number-legacy-octal-p
- regexp-flags
- comment-type
- follows-eol-p)
-
-;; Have to call `js2-init-scanner' to initialize the values.
-(js2-deflocal js2-ti-tokens nil)
-(js2-deflocal js2-ti-tokens-cursor nil)
-(js2-deflocal js2-ti-lookahead nil)
-
-(cl-defstruct (js2-ts-state
- (:constructor make-js2-ts-state (&key (lineno js2-ts-lineno)
- (cursor js2-ts-cursor)
- (tokens (copy-sequence
js2-ti-tokens))
- (tokens-cursor
js2-ti-tokens-cursor)
- (lookahead
js2-ti-lookahead))))
- lineno
- cursor
- tokens
- tokens-cursor
- lookahead)
-
-;;; Parser variables
-
-(js2-deflocal js2-parsed-errors nil
- "List of errors produced during scanning/parsing.")
-
-(js2-deflocal js2-parsed-warnings nil
- "List of warnings produced during scanning/parsing.")
-
-(js2-deflocal js2-recover-from-parse-errors t
- "Non-nil to continue parsing after a syntax error.
-
-In recovery mode, the AST will be built in full, and any error
-nodes will be flagged with appropriate error information. If
-this flag is nil, a syntax error will result in an error being
-signaled.
-
-The variable is automatically buffer-local, because different
-modes that use the parser will need different settings.")
-
-(js2-deflocal js2-parse-hook nil
- "List of callbacks for receiving parsing progress.")
-
-(defvar js2-parse-finished-hook nil
- "List of callbacks to notify when parsing finishes.
-Not called if parsing was interrupted.")
-
-(js2-deflocal js2-is-eval-code nil
- "True if we're evaluating code in a string.
-If non-nil, the tokenizer will record the token text, and the AST nodes
-will record their source text. Off by default for IDE modes, since the
-text is available in the buffer.")
-
-(defvar js2-parse-ide-mode t
- "Non-nil if the parser is being used for `js2-mode'.
-If non-nil, the parser will set text properties for fontification
-and the syntax table. The value should be nil when using the
-parser as a frontend to an interpreter or byte compiler.")
-
-;;; Parser instance variables (buffer-local vars for js2-parse)
-
-(defconst js2-ti-after-eol (lsh 1 16)
- "Flag: first token of the source line.")
-
-;; Inline Rhino's CompilerEnvirons vars as buffer-locals.
-
-(js2-deflocal js2-compiler-generate-debug-info t)
-(js2-deflocal js2-compiler-use-dynamic-scope nil)
-(js2-deflocal js2-compiler-reserved-keywords-as-identifier nil)
-(js2-deflocal js2-compiler-xml-available t)
-(js2-deflocal js2-compiler-optimization-level 0)
-(js2-deflocal js2-compiler-generating-source t)
-(js2-deflocal js2-compiler-strict-mode nil)
-(js2-deflocal js2-compiler-report-warning-as-error nil)
-(js2-deflocal js2-compiler-generate-observer-count nil)
-(js2-deflocal js2-compiler-activation-names nil)
-
-;; SKIP: sourceURI
-
-;; There's a compileFunction method in Context.java - may need it.
-(js2-deflocal js2-called-by-compile-function nil
- "True if `js2-parse' was called by `js2-compile-function'.
-Will only be used when we finish implementing the interpreter.")
-
-;; SKIP: ts (we just call `js2-init-scanner' and use its vars)
-
-;; SKIP: node factory - we're going to just call functions directly,
-;; and eventually go to a unified AST format.
-
-(js2-deflocal js2-nesting-of-function 0)
-
-(js2-deflocal js2-recorded-identifiers nil
- "Tracks identifiers found during parsing.")
-
-(js2-deflocal js2-is-in-destructuring nil
- "True while parsing destructuring expression.")
-
-(js2-deflocal js2-in-use-strict-directive nil
- "True while inside a script or function under strict mode.")
-
-(defcustom js2-global-externs nil
- "A list of any extern names you'd like to consider always declared.
-This list is global and is used by all `js2-mode' files.
-You can create buffer-local externs list using `js2-additional-externs'."
- :type 'list
- :group 'js2-mode)
-
-(defcustom js2-include-browser-externs t
- "Non-nil to include browser externs in the master externs list.
-If you work on JavaScript files that are not intended for browsers,
-such as Mozilla Rhino server-side JavaScript, set this to nil.
-See `js2-additional-externs' for more information about externs."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-include-rhino-externs nil
- "Non-nil to include Mozilla Rhino externs in the master externs list.
-See `js2-additional-externs' for more information about externs."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-include-node-externs nil
- "Non-nil to include Node.js externs in the master externs list.
-See `js2-additional-externs' for more information about externs."
- :type 'boolean
- :group 'js2-mode)
-
-(js2-deflocal js2-additional-externs nil
- "A buffer-local list of additional external declarations.
-It is used to decide whether variables are considered undeclared
-for purposes of highlighting. See `js2-highlight-undeclared-vars'.
-
-Each entry is a Lisp string. The string should be the fully qualified
-name of an external entity. All externs should be added to this list,
-so that as js2-mode's processing improves it can take advantage of them.
-
-You may want to declare your externs in three ways.
-First, you can add externs that are valid for all your JavaScript files.
-You should probably do this by adding them to `js2-global-externs', which
-is a global list used for all js2-mode files.
-
-Next, you can add a function to `js2-init-hook' that adds additional
-externs appropriate for the specific file, perhaps based on its path.
-These should go in `js2-additional-externs', which is buffer-local.
-
-Third, you can use JSLint's global declaration, as long as
-`js2-include-jslint-globals' is non-nil, which see.
-
-Finally, you can add a function to `js2-post-parse-callbacks',
-which is called after parsing completes, and `js2-mode-ast' is bound to
-the root of the parse tree. At this stage you can set up an AST
-node visitor using `js2-visit-ast' and examine the parse tree
-for specific import patterns that may imply the existence of
-other externs, possibly tied to your build system. These should also
-be added to `js2-additional-externs'.
-
-Your post-parse callback may of course also use the simpler and
-faster (but perhaps less robust) approach of simply scanning the
-buffer text for your imports, using regular expressions.")
-
-(put 'js2-additional-externs 'safe-local-variable
- (lambda (val) (cl-every #'stringp val)))
-
-;; SKIP: decompiler
-;; SKIP: encoded-source
-
-;;; The following variables are per-function and should be saved/restored
-;;; during function parsing...
-
-(js2-deflocal js2-current-script-or-fn nil)
-(js2-deflocal js2-current-scope nil)
-(js2-deflocal js2-nesting-of-with 0)
-(js2-deflocal js2-label-set nil
- "An alist mapping label names to nodes.")
-
-(js2-deflocal js2-loop-set nil)
-(js2-deflocal js2-loop-and-switch-set nil)
-(js2-deflocal js2-has-return-value nil)
-(js2-deflocal js2-end-flags 0)
-
-;;; ...end of per function variables
-
-;; These flags enumerate the possible ways a statement/function can
-;; terminate. These flags are used by endCheck() and by the Parser to
-;; detect inconsistent return usage.
-;;
-;; END_UNREACHED is reserved for code paths that are assumed to always be
-;; able to execute (example: throw, continue)
-;;
-;; END_DROPS_OFF indicates if the statement can transfer control to the
-;; next one. Statement such as return dont. A compound statement may have
-;; some branch that drops off control to the next statement.
-;;
-;; END_RETURNS indicates that the statement can return (without arguments)
-;; END_RETURNS_VALUE indicates that the statement can return a value.
-;;
-;; A compound statement such as
-;; if (condition) {
-;; return value;
-;; }
-;; Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
-
-(defconst js2-end-unreached #x0)
-(defconst js2-end-drops-off #x1)
-(defconst js2-end-returns #x2)
-(defconst js2-end-returns-value #x4)
-
-;; Rhino awkwardly passes a statementLabel parameter to the
-;; statementHelper() function, the main statement parser, which
-;; is then used by quite a few of the sub-parsers. We just make
-;; it a buffer-local variable and make sure it's cleaned up properly.
-(js2-deflocal js2-labeled-stmt nil) ; type `js2-labeled-stmt-node'
-
-;; Similarly, Rhino passes an inForInit boolean through about half
-;; the expression parsers. We use a dynamically-scoped variable,
-;; which makes it easier to funcall the parsers individually without
-;; worrying about whether they take the parameter or not.
-(js2-deflocal js2-in-for-init nil)
-(js2-deflocal js2-temp-name-counter 0)
-(js2-deflocal js2-parse-stmt-count 0)
-
-(defsubst js2-get-next-temp-name ()
- (format "$%d" (cl-incf js2-temp-name-counter)))
-
-(defvar js2-parse-interruptable-p t
- "Set this to nil to force parse to continue until finished.
-This will mostly be useful for interpreters.")
-
-(defvar js2-statements-per-pause 50
- "Pause after this many statements to check for user input.
-If user input is pending, stop the parse and discard the tree.
-This makes for a smoother user experience for large files.
-You may have to wait a second or two before the highlighting
-and error-reporting appear, but you can always type ahead if
-you wish. This appears to be more or less how Eclipse, IntelliJ
-and other editors work.")
-
-(js2-deflocal js2-record-comments t
- "Instructs the scanner to record comments in `js2-scanned-comments'.")
-
-(js2-deflocal js2-scanned-comments nil
- "List of all comments from the current parse.")
-
-(defcustom js2-mode-indent-inhibit-undo nil
- "Non-nil to disable collection of Undo information when indenting lines.
-Some users have requested this behavior. It's nil by default because
-other Emacs modes don't work this way."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-mode-indent-ignore-first-tab nil
- "If non-nil, ignore first TAB keypress if we look indented properly.
-It's fairly common for users to navigate to an already-indented line
-and press TAB for reassurance that it's been indented. For this class
-of users, we want the first TAB press on a line to be ignored if the
-line is already indented to one of the precomputed alternatives.
-
-This behavior is only partly implemented. If you TAB-indent a line,
-navigate to another line, and then navigate back, it fails to clear
-the last-indented variable, so it thinks you've already hit TAB once,
-and performs the indent. A full solution would involve getting on the
-point-motion hooks for the entire buffer. If we come across another
-use cases that requires watching point motion, I'll consider doing it.
-
-If you set this variable to nil, then the TAB key will always change
-the indentation of the current line, if more than one alternative
-indentation spot exists."
- :type 'boolean
- :group 'js2-mode)
-
-(defvar js2-indent-hook nil
- "A hook for user-defined indentation rules.
-
-Functions on this hook should expect two arguments: (LIST INDEX)
-The LIST argument is the list of computed indentation points for
-the current line. INDEX is the list index of the indentation point
-that `js2-bounce-indent' plans to use. If INDEX is nil, then the
-indent function is not going to change the current line indentation.
-
-If a hook function on this list returns a non-nil value, then
-`js2-bounce-indent' assumes the hook function has performed its own
-indentation, and will do nothing. If all hook functions on the list
-return nil, then `js2-bounce-indent' will use its computed indentation
-and reindent the line.
-
-When hook functions on this hook list are called, the variable
-`js2-mode-ast' may or may not be set, depending on whether the
-parse tree is available. If the variable is nil, you can pass a
-callback to `js2-mode-wait-for-parse', and your callback will be
-called after the new parse tree is built. This can take some time
-in large files.")
-
-(defface js2-warning
- `((((class color) (background light))
- (:underline "orange"))
- (((class color) (background dark))
- (:underline "orange"))
- (t (:underline t)))
- "Face for JavaScript warnings."
- :group 'js2-mode)
-
-(defface js2-error
- `((((class color) (background light))
- (:foreground "red"))
- (((class color) (background dark))
- (:foreground "red"))
- (t (:foreground "red")))
- "Face for JavaScript errors."
- :group 'js2-mode)
-
-(defface js2-jsdoc-tag
- '((t :foreground "SlateGray"))
- "Face used to highlight @whatever tags in jsdoc comments."
- :group 'js2-mode)
-
-(defface js2-jsdoc-type
- '((t :foreground "SteelBlue"))
- "Face used to highlight {FooBar} types in jsdoc comments."
- :group 'js2-mode)
-
-(defface js2-jsdoc-value
- '((t :foreground "PeachPuff3"))
- "Face used to highlight tag values in jsdoc comments."
- :group 'js2-mode)
-
-(defface js2-function-param
- '((t :foreground "SeaGreen"))
- "Face used to highlight function parameters in javascript."
- :group 'js2-mode)
-
-(defface js2-function-call
- '((t :inherit default))
- "Face used to highlight function name in calls."
- :group 'js2-mode)
-
-(defface js2-object-property
- '((t :inherit default))
- "Face used to highlight named property in object literal."
- :group 'js2-mode)
-
-(defface js2-object-property-access
- '((t :inherit js2-object-property))
- "Face used to highlight property access with dot on an object."
- :group 'js2-mode)
-
-(defface js2-instance-member
- '((t :foreground "DarkOrchid"))
- "Face used to highlight instance variables in javascript.
-Not currently used."
- :group 'js2-mode)
-
-(defface js2-private-member
- '((t :foreground "PeachPuff3"))
- "Face used to highlight calls to private methods in javascript.
-Not currently used."
- :group 'js2-mode)
-
-(defface js2-private-function-call
- '((t :foreground "goldenrod"))
- "Face used to highlight calls to private functions in javascript.
-Not currently used."
- :group 'js2-mode)
-
-(defface js2-jsdoc-html-tag-name
- '((((class color) (min-colors 88) (background light))
- (:foreground "rosybrown"))
- (((class color) (min-colors 8) (background dark))
- (:foreground "yellow"))
- (((class color) (min-colors 8) (background light))
- (:foreground "magenta")))
- "Face used to highlight jsdoc html tag names"
- :group 'js2-mode)
-
-(defface js2-jsdoc-html-tag-delimiter
- '((((class color) (min-colors 88) (background light))
- (:foreground "dark khaki"))
- (((class color) (min-colors 8) (background dark))
- (:foreground "green"))
- (((class color) (min-colors 8) (background light))
- (:foreground "green")))
- "Face used to highlight brackets in jsdoc html tags."
- :group 'js2-mode)
-
-(defface js2-external-variable
- '((t :foreground "orange"))
- "Face used to highlight undeclared variable identifiers.")
-
-(defcustom js2-init-hook nil
- ;; FIXME: We don't really need this anymore.
- "List of functions to be called after `js2-mode' or
-`js2-minor-mode' has initialized all variables, before parsing
-the buffer for the first time."
- :type 'hook
- :group 'js2-mode
- :version "20130608")
-
-(defcustom js2-post-parse-callbacks nil
- "List of callback functions invoked after parsing finishes.
-Currently, the main use for this function is to add synthetic
-declarations to `js2-recorded-identifiers', which see."
- :type 'hook
- :group 'js2-mode)
-
-(defcustom js2-build-imenu-callbacks nil
- "List of functions called during Imenu index generation.
-It's a good place to add additional entries to it, using
-`js2-record-imenu-entry'."
- :type 'hook
- :group 'js2-mode)
-
-(defcustom js2-highlight-external-variables t
- "Non-nil to highlight undeclared variable identifiers.
-An undeclared variable is any variable not declared with var or let
-in the current scope or any lexically enclosing scope. If you use
-such a variable, then you are either expecting it to originate from
-another file, or you've got a potential bug."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-warn-about-unused-function-arguments nil
- "Non-nil to treat function arguments like declared-but-unused variables."
- :type 'booleanp
- :group 'js2-mode)
-
-(defcustom js2-include-jslint-globals t
- "Non-nil to include the identifiers from JSLint global
-declaration (see http://www.jslint.com/help.html#global) in the
-buffer-local externs list. See `js2-additional-externs' for more
-information."
- :type 'boolean
- :group 'js2-mode)
-
-(defcustom js2-include-jslint-declaration-externs t
- "Non-nil to include the identifiers JSLint assumes to be there
-under certain declarations in the buffer-local externs list. See
-`js2-additional-externs' for more information."
- :type 'boolean
- :group 'js2-mode)
-
-(defvar js2-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [remap indent-new-comment-line] #'js2-line-break)
- (define-key map (kbd "C-c C-e") #'js2-mode-hide-element)
- (define-key map (kbd "C-c C-s") #'js2-mode-show-element)
- (define-key map (kbd "C-c C-a") #'js2-mode-show-all)
- (define-key map (kbd "C-c C-f") #'js2-mode-toggle-hide-functions)
- (define-key map (kbd "C-c C-t") #'js2-mode-toggle-hide-comments)
- (define-key map (kbd "C-c C-o") #'js2-mode-toggle-element)
- (define-key map (kbd "C-c C-w") #'js2-mode-toggle-warnings-and-errors)
- (define-key map [down-mouse-3] #'js2-down-mouse-3)
- (define-key map [remap js-find-symbol] #'js2-jump-to-definition)
-
- (define-key map [menu-bar javascript]
- (cons "JavaScript" (make-sparse-keymap "JavaScript")))
-
- (define-key map [menu-bar javascript customize-js2-mode]
- '(menu-item "Customize js2-mode" js2-mode-customize
- :help "Customize the behavior of this mode"))
-
- (define-key map [menu-bar javascript js2-force-refresh]
- '(menu-item "Force buffer refresh" js2-mode-reset
- :help "Re-parse the buffer from scratch"))
-
- (define-key map [menu-bar javascript separator-2]
- '("--"))
-
- (define-key map [menu-bar javascript next-error]
- '(menu-item "Next warning or error" next-error
- :enabled (and js2-mode-ast
- (or (js2-ast-root-errors js2-mode-ast)
- (js2-ast-root-warnings js2-mode-ast)))
- :help "Move to next warning or error"))
-
- (define-key map [menu-bar javascript display-errors]
- '(menu-item "Show errors and warnings"
js2-mode-display-warnings-and-errors
- :visible (not js2-mode-show-parse-errors)
- :help "Turn on display of warnings and errors"))
-
- (define-key map [menu-bar javascript hide-errors]
- '(menu-item "Hide errors and warnings" js2-mode-hide-warnings-and-errors
- :visible js2-mode-show-parse-errors
- :help "Turn off display of warnings and errors"))
-
- (define-key map [menu-bar javascript separator-1]
- '("--"))
-
- (define-key map [menu-bar javascript js2-toggle-function]
- '(menu-item "Show/collapse element" js2-mode-toggle-element
- :help "Hide or show function body or comment"))
-
- (define-key map [menu-bar javascript show-comments]
- '(menu-item "Show block comments" js2-mode-toggle-hide-comments
- :visible js2-mode-comments-hidden
- :help "Expand all hidden block comments"))
-
- (define-key map [menu-bar javascript hide-comments]
- '(menu-item "Hide block comments" js2-mode-toggle-hide-comments
- :visible (not js2-mode-comments-hidden)
- :help "Show block comments as /*...*/"))
-
- (define-key map [menu-bar javascript show-all-functions]
- '(menu-item "Show function bodies" js2-mode-toggle-hide-functions
- :visible js2-mode-functions-hidden
- :help "Expand all hidden function bodies"))
-
- (define-key map [menu-bar javascript hide-all-functions]
- '(menu-item "Hide function bodies" js2-mode-toggle-hide-functions
- :visible (not js2-mode-functions-hidden)
- :help "Show {...} for all top-level function bodies"))
-
- map)
- "Keymap used in `js2-mode' buffers.")
-
-(defcustom js2-bounce-indent-p nil
- "Non-nil to bind `js2-indent-bounce' and `js2-indent-bounce-backward'.
-They will augment the default indent-line behavior with cycling
-among several computed alternatives. See the function
-`js2-bounce-indent' for details. The above commands will be
-bound to TAB and backtab."
- :type 'boolean
- :group 'js2-mode
- :set (lambda (sym value)
- (set-default sym value)
- (let ((map js2-mode-map))
- (if (not value)
- (progn
- (define-key map "\t" nil)
- (define-key map (kbd "<backtab>") nil))
- (define-key map "\t" #'js2-indent-bounce)
- (define-key map (kbd "<backtab>")
#'js2-indent-bounce-backward)))))
-
-(defconst js2-mode-identifier-re "[[:alpha:]_$][[:alnum:]_$]*")
-
-(defvar js2-mode-//-comment-re "^\\(\\s-*\\)//.+"
- "Matches a //-comment line. Must be first non-whitespace on line.
-First match-group is the leading whitespace.")
-
-(defvar js2-mode-hook nil)
-
-(js2-deflocal js2-mode-ast nil "Private variable.")
-(js2-deflocal js2-mode-parse-timer nil "Private variable.")
-(js2-deflocal js2-mode-buffer-dirty-p nil "Private variable.")
-(js2-deflocal js2-mode-parsing nil "Private variable.")
-(js2-deflocal js2-mode-node-overlay nil)
-
-(defvar js2-mode-show-overlay js2-mode-dev-mode-p
- "Debug: Non-nil to highlight AST nodes on mouse-down.")
-
-(js2-deflocal js2-mode-fontifications nil "Private variable")
-(js2-deflocal js2-mode-deferred-properties nil "Private variable")
-(js2-deflocal js2-imenu-recorder nil "Private variable")
-(js2-deflocal js2-imenu-function-map nil "Private variable")
-
-(defvar js2-mode-verbose-parse-p js2-mode-dev-mode-p
- "Non-nil to emit status messages during parsing.")
-
-(defvar js2-mode-functions-hidden nil "Private variable.")
-(defvar js2-mode-comments-hidden nil "Private variable.")
-
-(defvar js2-mode-syntax-table
- (let ((table (make-syntax-table)))
- (c-populate-syntax-table table)
- (modify-syntax-entry ?` "\"" table)
- table)
- "Syntax table used in `js2-mode' buffers.")
-
-(defvar js2-mode-abbrev-table nil
- "Abbrev table in use in `js2-mode' buffers.")
-(define-abbrev-table 'js2-mode-abbrev-table ())
-
-(defvar js2-mode-pending-parse-callbacks nil
- "List of functions waiting to be notified that parse is finished.")
-
-(defvar js2-mode-last-indented-line -1)
-
-;;; Localizable error and warning messages
-
-;; Messages are copied from Rhino's Messages.properties.
-;; Many of the Java-specific messages have been elided.
-;; Add any js2-specific ones at the end, so we can keep
-;; this file synced with changes to Rhino's.
-
-(defvar js2-message-table
- (make-hash-table :test 'equal :size 250)
- "Contains localized messages for `js2-mode'.")
-
-;; TODO(stevey): construct this table at compile-time.
-(defmacro js2-msg (key &rest strings)
- `(puthash ,key (concat ,@strings)
- js2-message-table))
-
-(defun js2-get-msg (msg-key)
- "Look up a localized message.
-MSG-KEY is a list of (MSG ARGS). If the message takes parameters,
-the correct number of ARGS must be provided."
- (let* ((key (if (listp msg-key) (car msg-key) msg-key))
- (args (if (listp msg-key) (cdr msg-key)))
- (msg (gethash key js2-message-table)))
- (if msg
- (apply #'format msg args)
- key))) ; default to showing the key
-
-(js2-msg "msg.dup.parms"
- "Duplicate parameter name '%s'.")
-
-(js2-msg "msg.too.big.jump"
- "Program too complex: jump offset too big.")
-
-(js2-msg "msg.too.big.index"
- "Program too complex: internal index exceeds 64K limit.")
-
-(js2-msg "msg.while.compiling.fn"
- "Encountered code generation error while compiling function '%s': %s")
-
-(js2-msg "msg.while.compiling.script"
- "Encountered code generation error while compiling script: %s")
-
-;; Context
-(js2-msg "msg.ctor.not.found"
- "Constructor for '%s' not found.")
-
-(js2-msg "msg.not.ctor"
- "'%s' is not a constructor.")
-
-;; FunctionObject
-(js2-msg "msg.varargs.ctor"
- "Method or constructor '%s' must be static "
- "with the signature (Context cx, Object[] args, "
- "Function ctorObj, boolean inNewExpr) "
- "to define a variable arguments constructor.")
-
-(js2-msg "msg.varargs.fun"
- "Method '%s' must be static with the signature "
- "(Context cx, Scriptable thisObj, Object[] args, Function funObj) "
- "to define a variable arguments function.")
-
-(js2-msg "msg.incompat.call"
- "Method '%s' called on incompatible object.")
-
-(js2-msg "msg.bad.parms"
- "Unsupported parameter type '%s' in method '%s'.")
-
-(js2-msg "msg.bad.method.return"
- "Unsupported return type '%s' in method '%s'.")
-
-(js2-msg "msg.bad.ctor.return"
- "Construction of objects of type '%s' is not supported.")
-
-(js2-msg "msg.no.overload"
- "Method '%s' occurs multiple times in class '%s'.")
-
-(js2-msg "msg.method.not.found"
- "Method '%s' not found in '%s'.")
-
-;; IRFactory
-
-(js2-msg "msg.bad.for.in.lhs"
- "Invalid left-hand side of for..in loop.")
-
-(js2-msg "msg.mult.index"
- "Only one variable allowed in for..in loop.")
-
-(js2-msg "msg.bad.for.in.destruct"
- "Left hand side of for..in loop must be an array of "
- "length 2 to accept key/value pair.")
-
-(js2-msg "msg.cant.convert"
- "Can't convert to type '%s'.")
-
-(js2-msg "msg.bad.assign.left"
- "Invalid assignment left-hand side.")
-
-(js2-msg "msg.bad.decr"
- "Invalid decrement operand.")
-
-(js2-msg "msg.bad.incr"
- "Invalid increment operand.")
-
-(js2-msg "msg.bad.yield"
- "yield must be in a function.")
-
-(js2-msg "msg.bad.await"
- "await must be in async functions.")
-
-;; NativeGlobal
-(js2-msg "msg.cant.call.indirect"
- "Function '%s' must be called directly, and not by way of a "
- "function of another name.")
-
-(js2-msg "msg.eval.nonstring"
- "Calling eval() with anything other than a primitive "
- "string value will simply return the value. "
- "Is this what you intended?")
-
-(js2-msg "msg.eval.nonstring.strict"
- "Calling eval() with anything other than a primitive "
- "string value is not allowed in strict mode.")
-
-(js2-msg "msg.bad.destruct.op"
- "Invalid destructuring assignment operator")
-
-;; NativeCall
-(js2-msg "msg.only.from.new"
- "'%s' may only be invoked from a `new' expression.")
-
-(js2-msg "msg.deprec.ctor"
- "The '%s' constructor is deprecated.")
-
-;; NativeFunction
-(js2-msg "msg.no.function.ref.found"
- "no source found to decompile function reference %s")
-
-(js2-msg "msg.arg.isnt.array"
- "second argument to Function.prototype.apply must be an array")
-
-;; NativeGlobal
-(js2-msg "msg.bad.esc.mask"
- "invalid string escape mask")
-
-;; NativeRegExp
-(js2-msg "msg.bad.quant"
- "Invalid quantifier %s")
-
-(js2-msg "msg.overlarge.backref"
- "Overly large back reference %s")
-
-(js2-msg "msg.overlarge.min"
- "Overly large minimum %s")
-
-(js2-msg "msg.overlarge.max"
- "Overly large maximum %s")
-
-(js2-msg "msg.zero.quant"
- "Zero quantifier %s")
-
-(js2-msg "msg.max.lt.min"
- "Maximum %s less than minimum")
-
-(js2-msg "msg.unterm.quant"
- "Unterminated quantifier %s")
-
-(js2-msg "msg.unterm.paren"
- "Unterminated parenthetical %s")
-
-(js2-msg "msg.unterm.class"
- "Unterminated character class %s")
-
-(js2-msg "msg.bad.range"
- "Invalid range in character class.")
-
-(js2-msg "msg.trail.backslash"
- "Trailing \\ in regular expression.")
-
-(js2-msg "msg.re.unmatched.right.paren"
- "unmatched ) in regular expression.")
-
-(js2-msg "msg.no.regexp"
- "Regular expressions are not available.")
-
-(js2-msg "msg.bad.backref"
- "back-reference exceeds number of capturing parentheses.")
-
-(js2-msg "msg.bad.regexp.compile"
- "Only one argument may be specified if the first "
- "argument to RegExp.prototype.compile is a RegExp object.")
-
-;; Parser
-(js2-msg "msg.got.syntax.errors"
- "Compilation produced %s syntax errors.")
-
-(js2-msg "msg.var.redecl"
- "Redeclaration of var %s.")
-
-(js2-msg "msg.const.redecl"
- "TypeError: redeclaration of const %s.")
-
-(js2-msg "msg.let.redecl"
- "TypeError: redeclaration of variable %s.")
-
-(js2-msg "msg.parm.redecl"
- "TypeError: redeclaration of formal parameter %s.")
-
-(js2-msg "msg.fn.redecl"
- "TypeError: redeclaration of function %s.")
-
-(js2-msg "msg.let.decl.not.in.block"
- "SyntaxError: let declaration not directly within block")
-
-(js2-msg "msg.mod.import.decl.at.top.level"
- "SyntaxError: import declarations may only appear at the top level")
-
-(js2-msg "msg.mod.as.after.reserved.word"
- "SyntaxError: missing keyword 'as' after reserved word %s")
-
-(js2-msg "msg.mod.rc.after.import.spec.list"
- "SyntaxError: missing '}' after module specifier list")
-
-(js2-msg "msg.mod.from.after.import.spec.set"
- "SyntaxError: missing keyword 'from' after import specifier set")
-
-(js2-msg "msg.mod.declaration.after.import"
- "SyntaxError: missing declaration after 'import' keyword")
-
-(js2-msg "msg.mod.spec.after.from"
- "SyntaxError: missing module specifier after 'from' keyword")
-
-(js2-msg "msg.mod.export.decl.at.top.level"
- "SyntaxError: export declarations may only appear at top level")
-
-(js2-msg "msg.mod.rc.after.export.spec.list"
- "SyntaxError: missing '}' after export specifier list")
-
-;; NodeTransformer
-(js2-msg "msg.dup.label"
- "duplicated label")
-
-(js2-msg "msg.undef.label"
- "undefined label")
-
-(js2-msg "msg.bad.break"
- "unlabelled break must be inside loop or switch")
-
-(js2-msg "msg.continue.outside"
- "continue must be inside loop")
-
-(js2-msg "msg.continue.nonloop"
- "continue can only use labels of iteration statements")
-
-(js2-msg "msg.bad.throw.eol"
- "Line terminator is not allowed between the throw "
- "keyword and throw expression.")
-
-(js2-msg "msg.unnamed.function.stmt" ; added by js2-mode
- "function statement requires a name")
-
-(js2-msg "msg.no.paren.parms"
- "missing ( before function parameters.")
-
-(js2-msg "msg.no.parm"
- "missing formal parameter")
-
-(js2-msg "msg.no.paren.after.parms"
- "missing ) after formal parameters")
-
-(js2-msg "msg.no.default.after.default.param" ; added by js2-mode
- "parameter without default follows parameter with default")
-
-(js2-msg "msg.param.after.rest" ; added by js2-mode
- "parameter after rest parameter")
-
-(js2-msg "msg.bad.arrow.args" ; added by js2-mode
- "invalid arrow-function arguments (parentheses around the
arrow-function may help)")
-
-(js2-msg "msg.no.brace.body"
- "missing '{' before function body")
-
-(js2-msg "msg.no.brace.after.body"
- "missing } after function body")
-
-(js2-msg "msg.no.paren.cond"
- "missing ( before condition")
-
-(js2-msg "msg.no.paren.after.cond"
- "missing ) after condition")
-
-(js2-msg "msg.no.semi.stmt"
- "missing ; before statement")
-
-(js2-msg "msg.missing.semi"
- "missing ; after statement")
-
-(js2-msg "msg.no.name.after.dot"
- "missing name after . operator")
-
-(js2-msg "msg.no.name.after.coloncolon"
- "missing name after :: operator")
-
-(js2-msg "msg.no.name.after.dotdot"
- "missing name after .. operator")
-
-(js2-msg "msg.no.name.after.xmlAttr"
- "missing name after .@")
-
-(js2-msg "msg.no.bracket.index"
- "missing ] in index expression")
-
-(js2-msg "msg.no.paren.switch"
- "missing ( before switch expression")
-
-(js2-msg "msg.no.paren.after.switch"
- "missing ) after switch expression")
-
-(js2-msg "msg.no.brace.switch"
- "missing '{' before switch body")
-
-(js2-msg "msg.bad.switch"
- "invalid switch statement")
-
-(js2-msg "msg.no.colon.case"
- "missing : after case expression")
-
-(js2-msg "msg.double.switch.default"
- "double default label in the switch statement")
-
-(js2-msg "msg.no.while.do"
- "missing while after do-loop body")
-
-(js2-msg "msg.no.paren.for"
- "missing ( after for")
-
-(js2-msg "msg.no.semi.for"
- "missing ; after for-loop initializer")
-
-(js2-msg "msg.no.semi.for.cond"
- "missing ; after for-loop condition")
-
-(js2-msg "msg.in.after.for.name"
- "missing in or of after for")
-
-(js2-msg "msg.no.paren.for.ctrl"
- "missing ) after for-loop control")
-
-(js2-msg "msg.no.paren.with"
- "missing ( before with-statement object")
-
-(js2-msg "msg.no.paren.after.with"
- "missing ) after with-statement object")
-
-(js2-msg "msg.no.with.strict"
- "with statements not allowed in strict mode")
-
-(js2-msg "msg.no.paren.after.let"
- "missing ( after let")
-
-(js2-msg "msg.no.paren.let"
- "missing ) after variable list")
-
-(js2-msg "msg.no.curly.let"
- "missing } after let statement")
-
-(js2-msg "msg.bad.return"
- "invalid return")
-
-(js2-msg "msg.no.brace.block"
- "missing } in compound statement")
-
-(js2-msg "msg.bad.label"
- "invalid label")
-
-(js2-msg "msg.bad.var"
- "missing variable name")
-
-(js2-msg "msg.bad.var.init"
- "invalid variable initialization")
-
-(js2-msg "msg.no.colon.cond"
- "missing : in conditional expression")
-
-(js2-msg "msg.no.paren.arg"
- "missing ) after argument list")
-
-(js2-msg "msg.no.bracket.arg"
- "missing ] after element list")
-
-(js2-msg "msg.bad.prop"
- "invalid property id")
-
-(js2-msg "msg.no.colon.prop"
- "missing : after property id")
-
-(js2-msg "msg.no.brace.prop"
- "missing } after property list")
-
-(js2-msg "msg.no.paren"
- "missing ) in parenthetical")
-
-(js2-msg "msg.reserved.id"
- "'%s' is a reserved identifier")
-
-(js2-msg "msg.no.paren.catch"
- "missing ( before catch-block condition")
-
-(js2-msg "msg.bad.catchcond"
- "invalid catch block condition")
-
-(js2-msg "msg.catch.unreachable"
- "any catch clauses following an unqualified catch are unreachable")
-
-(js2-msg "msg.no.brace.try"
- "missing '{' before try block")
-
-(js2-msg "msg.no.brace.catchblock"
- "missing '{' before catch-block body")
-
-(js2-msg "msg.try.no.catchfinally"
- "'try' without 'catch' or 'finally'")
-
-(js2-msg "msg.no.return.value"
- "function %s does not always return a value")
-
-(js2-msg "msg.anon.no.return.value"
- "anonymous function does not always return a value")
-
-(js2-msg "msg.return.inconsistent"
- "return statement is inconsistent with previous usage")
-
-(js2-msg "msg.generator.returns"
- "TypeError: legacy generator function '%s' returns a value")
-
-(js2-msg "msg.anon.generator.returns"
- "TypeError: anonymous legacy generator function returns a value")
-
-(js2-msg "msg.syntax"
- "syntax error")
-
-(js2-msg "msg.unexpected.eof"
- "Unexpected end of file")
-
-(js2-msg "msg.XML.bad.form"
- "illegally formed XML syntax")
-
-(js2-msg "msg.XML.not.available"
- "XML runtime not available")
-
-(js2-msg "msg.too.deep.parser.recursion"
- "Too deep recursion while parsing")
-
-(js2-msg "msg.no.side.effects"
- "Code has no side effects")
-
-(js2-msg "msg.extra.trailing.comma"
- "Trailing comma is not supported in some browsers")
-
-(js2-msg "msg.array.trailing.comma"
- "Trailing comma yields different behavior across browsers")
-
-(js2-msg "msg.equal.as.assign"
- (concat "Test for equality (==) mistyped as assignment (=)?"
- " (parenthesize to suppress warning)"))
-
-(js2-msg "msg.var.hides.arg"
- "Variable %s hides argument")
-
-(js2-msg "msg.destruct.assign.no.init"
- "Missing = in destructuring declaration")
-
-(js2-msg "msg.init.no.destruct"
- "Binding initializer not in destructuring assignment")
-
-(js2-msg "msg.no.octal.strict"
- "Octal numbers prohibited in strict mode.")
-
-(js2-msg "msg.dup.obj.lit.prop.strict"
- "Property '%s' already defined in this object literal.")
-
-(js2-msg "msg.dup.param.strict"
- "Parameter '%s' already declared in this function.")
-
-(js2-msg "msg.bad.id.strict"
- "'%s' is not a valid identifier for this use in strict mode.")
-
-;; ScriptRuntime
-(js2-msg "msg.no.properties"
- "%s has no properties.")
-
-(js2-msg "msg.invalid.iterator"
- "Invalid iterator value")
-
-(js2-msg "msg.iterator.primitive"
- "__iterator__ returned a primitive value")
-
-(js2-msg "msg.assn.create.strict"
- "Assignment to undeclared variable %s")
-
-(js2-msg "msg.undeclared.variable" ; added by js2-mode
- "Undeclared variable or function '%s'")
-
-(js2-msg "msg.unused.variable" ; added by js2-mode
- "Unused variable or function '%s'")
-
-(js2-msg "msg.uninitialized.variable" ; added by js2-mode
- "Variable '%s' referenced but never initialized")
-
-(js2-msg "msg.ref.undefined.prop"
- "Reference to undefined property '%s'")
-
-(js2-msg "msg.prop.not.found"
- "Property %s not found.")
-
-(js2-msg "msg.invalid.type"
- "Invalid JavaScript value of type %s")
-
-(js2-msg "msg.primitive.expected"
- "Primitive type expected (had %s instead)")
-
-(js2-msg "msg.namespace.expected"
- "Namespace object expected to left of :: (found %s instead)")
-
-(js2-msg "msg.null.to.object"
- "Cannot convert null to an object.")
-
-(js2-msg "msg.undef.to.object"
- "Cannot convert undefined to an object.")
-
-(js2-msg "msg.cyclic.value"
- "Cyclic %s value not allowed.")
-
-(js2-msg "msg.is.not.defined"
- "'%s' is not defined.")
-
-(js2-msg "msg.undef.prop.read"
- "Cannot read property '%s' from %s")
-
-(js2-msg "msg.undef.prop.write"
- "Cannot set property '%s' of %s to '%s'")
-
-(js2-msg "msg.undef.prop.delete"
- "Cannot delete property '%s' of %s")
-
-(js2-msg "msg.undef.method.call"
- "Cannot call method '%s' of %s")
-
-(js2-msg "msg.undef.with"
- "Cannot apply 'with' to %s")
-
-(js2-msg "msg.isnt.function"
- "%s is not a function, it is %s.")
-
-(js2-msg "msg.isnt.function.in"
- "Cannot call property %s in object %s. "
- "It is not a function, it is '%s'.")
-
-(js2-msg "msg.function.not.found"
- "Cannot find function %s.")
-
-(js2-msg "msg.function.not.found.in"
- "Cannot find function %s in object %s.")
-
-(js2-msg "msg.isnt.xml.object"
- "%s is not an xml object.")
-
-(js2-msg "msg.no.ref.to.get"
- "%s is not a reference to read reference value.")
-
-(js2-msg "msg.no.ref.to.set"
- "%s is not a reference to set reference value to %s.")
-
-(js2-msg "msg.no.ref.from.function"
- "Function %s can not be used as the left-hand "
- "side of assignment or as an operand of ++ or -- operator.")
-
-(js2-msg "msg.bad.default.value"
- "Object's getDefaultValue() method returned an object.")
-
-(js2-msg "msg.instanceof.not.object"
- "Can't use instanceof on a non-object.")
-
-(js2-msg "msg.instanceof.bad.prototype"
- "'prototype' property of %s is not an object.")
-
-(js2-msg "msg.bad.radix"
- "illegal radix %s.")
-
-;; ScriptableObject
-(js2-msg "msg.default.value"
- "Cannot find default value for object.")
-
-(js2-msg "msg.zero.arg.ctor"
- "Cannot load class '%s' which has no zero-parameter constructor.")
-
-(js2-msg "msg.ctor.multiple.parms"
- "Can't define constructor or class %s since more than "
- "one constructor has multiple parameters.")
-
-(js2-msg "msg.extend.scriptable"
- "%s must extend ScriptableObject in order to define property %s.")
-
-(js2-msg "msg.bad.getter.parms"
- "In order to define a property, getter %s must have zero "
- "parameters or a single ScriptableObject parameter.")
-
-(js2-msg "msg.obj.getter.parms"
- "Expected static or delegated getter %s to take "
- "a ScriptableObject parameter.")
-
-(js2-msg "msg.getter.static"
- "Getter and setter must both be static or neither be static.")
-
-(js2-msg "msg.setter.return"
- "Setter must have void return type: %s")
-
-(js2-msg "msg.setter2.parms"
- "Two-parameter setter must take a ScriptableObject as "
- "its first parameter.")
-
-(js2-msg "msg.setter1.parms"
- "Expected single parameter setter for %s")
-
-(js2-msg "msg.setter2.expected"
- "Expected static or delegated setter %s to take two parameters.")
-
-(js2-msg "msg.setter.parms"
- "Expected either one or two parameters for setter.")
-
-(js2-msg "msg.setter.bad.type"
- "Unsupported parameter type '%s' in setter '%s'.")
-
-(js2-msg "msg.add.sealed"
- "Cannot add a property to a sealed object: %s.")
-
-(js2-msg "msg.remove.sealed"
- "Cannot remove a property from a sealed object: %s.")
-
-(js2-msg "msg.modify.sealed"
- "Cannot modify a property of a sealed object: %s.")
-
-(js2-msg "msg.modify.readonly"
- "Cannot modify readonly property: %s.")
-
-;; TokenStream
-(js2-msg "msg.missing.exponent"
- "missing exponent")
-
-(js2-msg "msg.caught.nfe"
- "number format error")
-
-(js2-msg "msg.unterminated.string.lit"
- "unterminated string literal")
-
-(js2-msg "msg.unterminated.comment"
- "unterminated comment")
-
-(js2-msg "msg.unterminated.re.lit"
- "unterminated regular expression literal")
-
-(js2-msg "msg.invalid.re.flag"
- "invalid flag after regular expression")
-
-(js2-msg "msg.no.re.input.for"
- "no input for %s")
-
-(js2-msg "msg.illegal.character"
- "illegal character")
-
-(js2-msg "msg.invalid.escape"
- "invalid Unicode escape sequence")
-
-(js2-msg "msg.bad.namespace"
- "not a valid default namespace statement. "
- "Syntax is: default xml namespace = EXPRESSION;")
-
-;; TokensStream warnings
-(js2-msg "msg.bad.octal.literal"
- "illegal octal literal digit %s; "
- "interpreting it as a decimal digit")
-
-(js2-msg "msg.missing.hex.digits"
- "missing hexadecimal digits after '0x'")
-
-(js2-msg "msg.missing.binary.digits"
- "missing binary digits after '0b'")
-
-(js2-msg "msg.missing.octal.digits"
- "missing octal digits after '0o'")
-
-(js2-msg "msg.script.is.not.constructor"
- "Script objects are not constructors.")
-
-;; Arrays
-(js2-msg "msg.arraylength.bad"
- "Inappropriate array length.")
-
-;; Arrays
-(js2-msg "msg.arraylength.too.big"
- "Array length %s exceeds supported capacity limit.")
-
-;; URI
-(js2-msg "msg.bad.uri"
- "Malformed URI sequence.")
-
-;; Number
-(js2-msg "msg.bad.precision"
- "Precision %s out of range.")
-
-;; NativeGenerator
-(js2-msg "msg.send.newborn"
- "Attempt to send value to newborn generator")
-
-(js2-msg "msg.already.exec.gen"
- "Already executing generator")
-
-(js2-msg "msg.StopIteration.invalid"
- "StopIteration may not be changed to an arbitrary object.")
-
-;; Interpreter
-(js2-msg "msg.yield.closing"
- "Yield from closing generator")
-
-;; Classes
-(js2-msg "msg.unnamed.class.stmt" ; added by js2-mode
- "class statement requires a name")
-
-(js2-msg "msg.class.unexpected.comma" ; added by js2-mode
- "unexpected ',' between class properties")
-
-(js2-msg "msg.unexpected.static" ; added by js2-mode
- "unexpected 'static'")
-
-(js2-msg "msg.missing.extends" ; added by js2-mode
- "name is required after extends")
-
-(js2-msg "msg.no.brace.class" ; added by js2-mode
- "missing '{' before class body")
-
-(js2-msg "msg.missing.computed.rb" ; added by js2-mode
- "missing ']' after computed property expression")
-
-;;; Tokens Buffer
-
-(defconst js2-ti-max-lookahead 2)
-(defconst js2-ti-ntokens (1+ js2-ti-max-lookahead))
-
-(defun js2-new-token (offset)
- (let ((token (make-js2-token (+ offset js2-ts-cursor))))
- (setq js2-ti-tokens-cursor (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens))
- (aset js2-ti-tokens js2-ti-tokens-cursor token)
- token))
-
-(defsubst js2-current-token ()
- (aref js2-ti-tokens js2-ti-tokens-cursor))
-
-(defsubst js2-current-token-string ()
- (js2-token-string (js2-current-token)))
-
-(defsubst js2-current-token-type ()
- (js2-token-type (js2-current-token)))
-
-(defsubst js2-current-token-beg ()
- (js2-token-beg (js2-current-token)))
-
-(defsubst js2-current-token-end ()
- (js2-token-end (js2-current-token)))
-
-(defun js2-current-token-len ()
- (let ((token (js2-current-token)))
- (- (js2-token-end token)
- (js2-token-beg token))))
-
-(defun js2-ts-seek (state)
- (setq js2-ts-lineno (js2-ts-state-lineno state)
- js2-ts-cursor (js2-ts-state-cursor state)
- js2-ti-tokens (js2-ts-state-tokens state)
- js2-ti-tokens-cursor (js2-ts-state-tokens-cursor state)
- js2-ti-lookahead (js2-ts-state-lookahead state)))
-
-;;; Utilities
-
-(defun js2-delete-if (predicate list)
- "Remove all items satisfying PREDICATE in LIST."
- (cl-loop for item in list
- if (not (funcall predicate item))
- collect item))
-
-(defun js2-position (element list)
- "Find 0-indexed position of ELEMENT in LIST comparing with `eq'.
-Returns nil if element is not found in the list."
- (let ((count 0)
- found)
- (while (and list (not found))
- (if (eq element (car list))
- (setq found t)
- (setq count (1+ count)
- list (cdr list))))
- (if found count)))
-
-(defun js2-find-if (predicate list)
- "Find first item satisfying PREDICATE in LIST."
- (let (result)
- (while (and list (not result))
- (if (funcall predicate (car list))
- (setq result (car list)))
- (setq list (cdr list)))
- result))
-
-(defmacro js2-time (form)
- "Evaluate FORM, discard result, and return elapsed time in sec."
- (declare (debug t))
- (let ((beg (make-symbol "--js2-time-beg--")))
- `(let ((,beg (current-time)))
- ,form
- (/ (truncate (* (- (float-time (current-time))
- (float-time ,beg))
- 10000))
- 10000.0))))
-
-(defsubst js2-same-line (pos)
- "Return t if POS is on the same line as current point."
- (and (>= pos (point-at-bol))
- (<= pos (point-at-eol))))
-
-(defun js2-code-bug ()
- "Signal an error when we encounter an unexpected code path."
- (error "failed assertion"))
-
-(defsubst js2-record-text-property (beg end prop value)
- "Record a text property to set when parsing finishes."
- (push (list beg end prop value) js2-mode-deferred-properties))
-
-;; I'd like to associate errors with nodes, but for now the
-;; easiest thing to do is get the context info from the last token.
-(defun js2-record-parse-error (msg &optional arg pos len)
- (push (list (list msg arg)
- (or pos (js2-current-token-beg))
- (or len (js2-current-token-len)))
- js2-parsed-errors))
-
-(defun js2-report-error (msg &optional msg-arg pos len)
- "Signal a syntax error or record a parse error."
- (if js2-recover-from-parse-errors
- (js2-record-parse-error msg msg-arg pos len)
- (signal 'js2-syntax-error
- (list msg
- js2-ts-lineno
- (save-excursion
- (goto-char js2-ts-cursor)
- (current-column))
- js2-ts-hit-eof))))
-
-(defun js2-report-warning (msg &optional msg-arg pos len face)
- (if js2-compiler-report-warning-as-error
- (js2-report-error msg msg-arg pos len)
- (push (list (list msg msg-arg)
- (or pos (js2-current-token-beg))
- (or len (js2-current-token-len))
- face)
- js2-parsed-warnings)))
-
-(defun js2-add-strict-warning (msg-id &optional msg-arg beg end)
- (if js2-compiler-strict-mode
- (js2-report-warning msg-id msg-arg beg
- (and beg end (- end beg)))))
-
-(put 'js2-syntax-error 'error-conditions
- '(error syntax-error js2-syntax-error))
-(put 'js2-syntax-error 'error-message "Syntax error")
-
-(put 'js2-parse-error 'error-conditions
- '(error parse-error js2-parse-error))
-(put 'js2-parse-error 'error-message "Parse error")
-
-(defmacro js2-clear-flag (flags flag)
- `(setq ,flags (logand ,flags (lognot ,flag))))
-
-(defmacro js2-set-flag (flags flag)
- "Logical-or FLAG into FLAGS."
- `(setq ,flags (logior ,flags ,flag)))
-
-(defsubst js2-flag-set-p (flags flag)
- (/= 0 (logand flags flag)))
-
-(defsubst js2-flag-not-set-p (flags flag)
- (zerop (logand flags flag)))
-
-;;; AST struct and function definitions
-
-;; flags for ast node property 'member-type (used for e4x operators)
-(defvar js2-property-flag #x1 "Property access: element is valid name.")
-(defvar js2-attribute-flag #x2 "x.@y or x..@y.")
-(defvar js2-descendants-flag #x4 "x..y or x..@i.")
-
-(defsubst js2-relpos (pos anchor)
- "Convert POS to be relative to ANCHOR.
-If POS is nil, returns nil."
- (and pos (- pos anchor)))
-
-(defun js2-make-pad (indent)
- (if (zerop indent)
- ""
- (make-string (* indent js2-basic-offset) ? )))
-
-(defun js2-visit-ast (node callback)
- "Visit every node in ast NODE with visitor CALLBACK.
-
-CALLBACK is a function that takes two arguments: (NODE END-P). It is
-called twice: once to visit the node, and again after all the node's
-children have been processed. The END-P argument is nil on the first
-call and non-nil on the second call. The return value of the callback
-affects the traversal: if non-nil, the children of NODE are processed.
-If the callback returns nil, or if the node has no children, then the
-callback is called immediately with a non-nil END-P argument.
-
-The node traversal is approximately lexical-order, although there
-are currently no guarantees around this."
- (when node
- (let ((vfunc (get (aref node 0) 'js2-visitor)))
- ;; visit the node
- (when (funcall callback node nil)
- ;; visit the kids
- (cond
- ((eq vfunc 'js2-visit-none)
- nil) ; don't even bother calling it
- ;; Each AST node type has to define a `js2-visitor' function
- ;; that takes a node and a callback, and calls `js2-visit-ast'
- ;; on each child of the node.
- (vfunc
- (funcall vfunc node callback))
- (t
- (error "%s does not define a visitor-traversal function"
- (aref node 0)))))
- ;; call the end-visit
- (funcall callback node t))))
-
-(cl-defstruct (js2-node
- (:constructor nil)) ; abstract
- "Base AST node type."
- (type -1) ; token type
- (pos -1) ; start position of this AST node in parsed input
- (len 1) ; num characters spanned by the node
- props ; optional node property list (an alist)
- parent) ; link to parent node; null for root
-
-(defsubst js2-node-get-prop (node prop &optional default)
- (or (cadr (assoc prop (js2-node-props node))) default))
-
-(defsubst js2-node-set-prop (node prop value)
- (setf (js2-node-props node)
- (cons (list prop value) (js2-node-props node))))
-
-(defun js2-fixup-starts (n nodes)
- "Adjust the start positions of NODES to be relative to N.
-Any node in the list may be nil, for convenience."
- (dolist (node nodes)
- (when node
- (setf (js2-node-pos node) (- (js2-node-pos node)
- (js2-node-pos n))))))
-
-(defun js2-node-add-children (parent &rest nodes)
- "Set parent node of NODES to PARENT, and return PARENT.
-Does nothing if we're not recording parent links.
-If any given node in NODES is nil, doesn't record that link."
- (js2-fixup-starts parent nodes)
- (dolist (node nodes)
- (and node
- (setf (js2-node-parent node) parent))))
-
-;; Non-recursive since it's called a frightening number of times.
-(defun js2-node-abs-pos (n)
- (let ((pos (js2-node-pos n)))
- (while (setq n (js2-node-parent n))
- (setq pos (+ pos (js2-node-pos n))))
- pos))
-
-(defsubst js2-node-abs-end (n)
- "Return absolute buffer position of end of N."
- (+ (js2-node-abs-pos n) (js2-node-len n)))
-
-(defun js2--struct-put (name key value)
- (put name key value)
- (put (intern (format "cl-struct-%s" name)) key value))
-
-;; It's important to make sure block nodes have a Lisp list for the
-;; child nodes, to limit printing recursion depth in an AST that
-;; otherwise consists of defstruct vectors. Emacs will crash printing
-;; a sufficiently large vector tree.
-
-(cl-defstruct (js2-block-node
- (:include js2-node)
- (:constructor make-js2-block-node (&key (type js2-BLOCK)
- (pos
(js2-current-token-beg))
- len
- props
- kids)))
- "A block of statements."
- kids) ; a Lisp list of the child statement nodes
-
-(js2--struct-put 'js2-block-node 'js2-visitor 'js2-visit-block)
-(js2--struct-put 'js2-block-node 'js2-printer 'js2-print-block)
-
-(defun js2-visit-block (ast callback)
- "Visit the `js2-block-node' children of AST."
- (dolist (kid (js2-block-node-kids ast))
- (js2-visit-ast kid callback)))
-
-(defun js2-print-block (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad "{\n")
- (dolist (kid (js2-block-node-kids n))
- (js2-print-ast kid (1+ i)))
- (insert pad "}")))
-
-(cl-defstruct (js2-scope
- (:include js2-block-node)
- (:constructor make-js2-scope (&key (type js2-BLOCK)
- (pos (js2-current-token-beg))
- len
- kids)))
- ;; The symbol-table is a LinkedHashMap<String,Symbol> in Rhino.
- ;; I don't have one of those handy, so I'll use an alist for now.
- ;; It's as fast as an emacs hashtable for up to about 50 elements,
- ;; and is much lighter-weight to construct (both CPU and mem).
- ;; The keys are interned strings (symbols) for faster lookup.
- ;; Should switch to hybrid alist/hashtable eventually.
- symbol-table ; an alist of (symbol . js2-symbol)
- parent-scope ; a `js2-scope'
- top) ; top-level `js2-scope' (script/function)
-
-(js2--struct-put 'js2-scope 'js2-visitor 'js2-visit-block)
-(js2--struct-put 'js2-scope 'js2-printer 'js2-print-none)
-
-(defun js2-node-get-enclosing-scope (node)
- "Return the innermost `js2-scope' node surrounding NODE.
-Returns nil if there is no enclosing scope node."
- (while (and (setq node (js2-node-parent node))
- (not (js2-scope-p node))))
- node)
-
-(defun js2-get-defining-scope (scope name &optional point)
- "Search up scope chain from SCOPE looking for NAME, a string or symbol.
-Returns `js2-scope' in which NAME is defined, or nil if not found.
-
-If POINT is non-nil, and if the found declaration type is
-`js2-LET', also check that the declaration node is before POINT."
- (let ((sym (if (symbolp name)
- name
- (intern name)))
- result
- (continue t))
- (while (and scope continue)
- (if (or
- (let ((entry (cdr (assq sym (js2-scope-symbol-table scope)))))
- (and entry
- (or (not point)
- (not (eq js2-LET (js2-symbol-decl-type entry)))
- (>= point
- (js2-node-abs-pos (js2-symbol-ast-node entry))))))
- (and (eq sym 'arguments)
- (js2-function-node-p scope)))
- (setq continue nil
- result scope)
- (setq scope (js2-scope-parent-scope scope))))
- result))
-
-(defun js2-scope-get-symbol (scope name)
- "Return symbol table entry for NAME in SCOPE.
-NAME can be a string or symbol. Returns a `js2-symbol' or nil if not found."
- (and (js2-scope-symbol-table scope)
- (cdr (assq (if (symbolp name)
- name
- (intern name))
- (js2-scope-symbol-table scope)))))
-
-(defun js2-scope-put-symbol (scope name symbol)
- "Enter SYMBOL into symbol-table for SCOPE under NAME.
-NAME can be a Lisp symbol or string. SYMBOL is a `js2-symbol'."
- (let* ((table (js2-scope-symbol-table scope))
- (sym (if (symbolp name) name (intern name)))
- (entry (assq sym table)))
- (if entry
- (setcdr entry symbol)
- (push (cons sym symbol)
- (js2-scope-symbol-table scope)))))
-
-(cl-defstruct (js2-symbol
- (:constructor make-js2-symbol (decl-type name &optional
ast-node)))
- "A symbol table entry."
- ;; One of js2-FUNCTION, js2-LP (for parameters), js2-VAR,
- ;; js2-LET, or js2-CONST
- decl-type
- name ; string
- ast-node) ; a `js2-node'
-
-(cl-defstruct (js2-error-node
- (:include js2-node)
- (:constructor make-js2-error-node (&key (type js2-ERROR)
- (pos
(js2-current-token-beg))
- len)))
- "AST node representing a parse error.")
-
-(js2--struct-put 'js2-error-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-error-node 'js2-printer 'js2-print-none)
-
-(cl-defstruct (js2-script-node
- (:include js2-scope)
- (:constructor make-js2-script-node (&key (type js2-SCRIPT)
- (pos
(js2-current-token-beg))
- len)))
- functions ; Lisp list of nested functions
- regexps ; Lisp list of (string . flags)
- symbols ; alist (every symbol gets unique index)
- (param-count 0)
- var-names ; vector of string names
- consts ; bool-vector matching var-decls
- (temp-number 0)) ; for generating temp variables
-
-(js2--struct-put 'js2-script-node 'js2-visitor 'js2-visit-block)
-(js2--struct-put 'js2-script-node 'js2-printer 'js2-print-script)
-
-(defun js2-print-script (node indent)
- (dolist (kid (js2-block-node-kids node))
- (js2-print-ast kid indent)))
-
-(cl-defstruct (js2-ast-root
- (:include js2-script-node)
- (:constructor make-js2-ast-root (&key (type js2-SCRIPT)
- (pos
(js2-current-token-beg))
- len
- buffer)))
- "The root node of a js2 AST."
- buffer ; the source buffer from which the code was parsed
- comments ; a Lisp list of comments, ordered by start position
- errors ; a Lisp list of errors found during parsing
- warnings ; a Lisp list of warnings found during parsing
- node-count) ; number of nodes in the tree, including the root
-
-(js2--struct-put 'js2-ast-root 'js2-visitor 'js2-visit-ast-root)
-(js2--struct-put 'js2-ast-root 'js2-printer 'js2-print-script)
-
-(defun js2-visit-ast-root (ast callback)
- (dolist (kid (js2-ast-root-kids ast))
- (js2-visit-ast kid callback))
- (dolist (comment (js2-ast-root-comments ast))
- (js2-visit-ast comment callback)))
-
-(cl-defstruct (js2-comment-node
- (:include js2-node)
- (:constructor make-js2-comment-node (&key (type js2-COMMENT)
- (pos
(js2-current-token-beg))
- len
- format)))
- format) ; 'line, 'block, 'jsdoc or 'html
-
-(js2--struct-put 'js2-comment-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-comment-node 'js2-printer 'js2-print-comment)
-
-(defun js2-print-comment (n i)
- ;; We really ought to link end-of-line comments to their nodes.
- ;; Or maybe we could add a new comment type, 'endline.
- (insert (js2-make-pad i)
- (js2-node-string n)))
-
-(cl-defstruct (js2-expr-stmt-node
- (:include js2-node)
- (:constructor make-js2-expr-stmt-node (&key (type js2-EXPR_VOID)
- (pos js2-ts-cursor)
- len
- expr)))
- "An expression statement."
- expr)
-
-(defsubst js2-expr-stmt-node-set-has-result (node)
- "Change NODE type to `js2-EXPR_RESULT'. Used for code generation."
- (setf (js2-node-type node) js2-EXPR_RESULT))
-
-(js2--struct-put 'js2-expr-stmt-node 'js2-visitor 'js2-visit-expr-stmt-node)
-(js2--struct-put 'js2-expr-stmt-node 'js2-printer 'js2-print-expr-stmt-node)
-
-(defun js2-visit-expr-stmt-node (n v)
- (js2-visit-ast (js2-expr-stmt-node-expr n) v))
-
-(defun js2-print-expr-stmt-node (n indent)
- (js2-print-ast (js2-expr-stmt-node-expr n) indent)
- (insert ";\n"))
-
-(cl-defstruct (js2-loop-node
- (:include js2-scope)
- (:constructor nil))
- "Abstract supertype of loop nodes."
- body ; a `js2-block-node'
- lp ; position of left-paren, nil if omitted
- rp) ; position of right-paren, nil if omitted
-
-(cl-defstruct (js2-do-node
- (:include js2-loop-node)
- (:constructor make-js2-do-node (&key (type js2-DO)
- (pos
(js2-current-token-beg))
- len
- body
- condition
- while-pos
- lp
- rp)))
- "AST node for do-loop."
- condition ; while (expression)
- while-pos) ; buffer position of 'while' keyword
-
-(js2--struct-put 'js2-do-node 'js2-visitor 'js2-visit-do-node)
-(js2--struct-put 'js2-do-node 'js2-printer 'js2-print-do-node)
-
-(defun js2-visit-do-node (n v)
- (js2-visit-ast (js2-do-node-body n) v)
- (js2-visit-ast (js2-do-node-condition n) v))
-
-(defun js2-print-do-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad "do {\n")
- (dolist (kid (js2-block-node-kids (js2-do-node-body n)))
- (js2-print-ast kid (1+ i)))
- (insert pad "} while (")
- (js2-print-ast (js2-do-node-condition n) 0)
- (insert ");\n")))
-
-(cl-defstruct (js2-export-node
- (:include js2-node)
- (:constructor make-js2-export-node (&key (type js2-EXPORT)
- (pos
(js2-current-token-beg))
- len
- exports-list
- from-clause
- declaration
- default)))
- "AST node for an export statement. There are many things that can be
exported,
-so many of its properties will be nil.
-"
- exports-list ; lisp list of js2-export-binding-node to export
- from-clause ; js2-from-clause-node for re-exporting symbols from another
module
- declaration ; js2-var-decl-node (var, let, const) or js2-class-node
- default) ; js2-function-node or js2-assign-node
-
-(js2--struct-put 'js2-export-node 'js2-visitor 'js2-visit-export-node)
-(js2--struct-put 'js2-export-node 'js2-printer 'js2-print-export-node)
-
-(defun js2-visit-export-node (n v)
- (let ((exports-list (js2-export-node-exports-list n))
- (from (js2-export-node-from-clause n))
- (declaration (js2-export-node-declaration n))
- (default (js2-export-node-default n)))
- (when exports-list
- (dolist (export exports-list)
- (js2-visit-ast export v)))
- (when from
- (js2-visit-ast from v))
- (when declaration
- (js2-visit-ast declaration v))
- (when default
- (js2-visit-ast default v))))
-
-(defun js2-print-export-node (n i)
- (let ((pad (js2-make-pad i))
- (exports-list (js2-export-node-exports-list n))
- (from (js2-export-node-from-clause n))
- (declaration (js2-export-node-declaration n))
- (default (js2-export-node-default n)))
- (insert pad "export ")
- (cond
- (default
- (insert "default ")
- (js2-print-ast default i))
- (declaration
- (js2-print-ast declaration i))
- ((and exports-list from)
- (js2-print-named-imports exports-list)
- (insert " ")
- (js2-print-from-clause from))
- (from
- (insert "* ")
- (js2-print-from-clause from))
- (exports-list
- (js2-print-named-imports exports-list)))
- (unless (or (and default (not (js2-assign-node-p default)))
- (and declaration (or (js2-function-node-p declaration)
- (js2-class-node-p declaration))))
- (insert ";\n"))))
-
-(cl-defstruct (js2-while-node
- (:include js2-loop-node)
- (:constructor make-js2-while-node (&key (type js2-WHILE)
- (pos
(js2-current-token-beg))
- len body
- condition lp
- rp)))
- "AST node for while-loop."
- condition) ; while-condition
-
-(js2--struct-put 'js2-while-node 'js2-visitor 'js2-visit-while-node)
-(js2--struct-put 'js2-while-node 'js2-printer 'js2-print-while-node)
-
-(defun js2-visit-while-node (n v)
- (js2-visit-ast (js2-while-node-condition n) v)
- (js2-visit-ast (js2-while-node-body n) v))
-
-(defun js2-print-while-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad "while (")
- (js2-print-ast (js2-while-node-condition n) 0)
- (insert ") {\n")
- (js2-print-body (js2-while-node-body n) (1+ i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-for-node
- (:include js2-loop-node)
- (:constructor make-js2-for-node (&key (type js2-FOR)
- (pos js2-ts-cursor)
- len body init
- condition
- update lp rp)))
- "AST node for a C-style for-loop."
- init ; initialization expression
- condition ; loop condition
- update) ; update clause
-
-(js2--struct-put 'js2-for-node 'js2-visitor 'js2-visit-for-node)
-(js2--struct-put 'js2-for-node 'js2-printer 'js2-print-for-node)
-
-(defun js2-visit-for-node (n v)
- (js2-visit-ast (js2-for-node-init n) v)
- (js2-visit-ast (js2-for-node-condition n) v)
- (js2-visit-ast (js2-for-node-update n) v)
- (js2-visit-ast (js2-for-node-body n) v))
-
-(defun js2-print-for-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad "for (")
- (js2-print-ast (js2-for-node-init n) 0)
- (insert "; ")
- (js2-print-ast (js2-for-node-condition n) 0)
- (insert "; ")
- (js2-print-ast (js2-for-node-update n) 0)
- (insert ") {\n")
- (js2-print-body (js2-for-node-body n) (1+ i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-for-in-node
- (:include js2-loop-node)
- (:constructor make-js2-for-in-node (&key (type js2-FOR)
- (pos js2-ts-cursor)
- len body
- iterator
- object
- in-pos
- each-pos
- foreach-p forof-p
- lp rp)))
- "AST node for a for..in loop."
- iterator ; [var] foo in ...
- object ; object over which we're iterating
- in-pos ; buffer position of 'in' keyword
- each-pos ; buffer position of 'each' keyword, if foreach-p
- foreach-p ; t if it's a for-each loop
- forof-p) ; t if it's a for-of loop
-
-(js2--struct-put 'js2-for-in-node 'js2-visitor 'js2-visit-for-in-node)
-(js2--struct-put 'js2-for-in-node 'js2-printer 'js2-print-for-in-node)
-
-(defun js2-visit-for-in-node (n v)
- (js2-visit-ast (js2-for-in-node-iterator n) v)
- (js2-visit-ast (js2-for-in-node-object n) v)
- (js2-visit-ast (js2-for-in-node-body n) v))
-
-(defun js2-print-for-in-node (n i)
- (let ((pad (js2-make-pad i))
- (foreach (js2-for-in-node-foreach-p n))
- (forof (js2-for-in-node-forof-p n)))
- (insert pad "for ")
- (if foreach
- (insert "each "))
- (insert "(")
- (js2-print-ast (js2-for-in-node-iterator n) 0)
- (insert (if forof " of " " in "))
- (js2-print-ast (js2-for-in-node-object n) 0)
- (insert ") {\n")
- (js2-print-body (js2-for-in-node-body n) (1+ i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-return-node
- (:include js2-node)
- (:constructor make-js2-return-node (&key (type js2-RETURN)
- (pos js2-ts-cursor)
- len
- retval)))
- "AST node for a return statement."
- retval) ; expression to return, or 'undefined
-
-(js2--struct-put 'js2-return-node 'js2-visitor 'js2-visit-return-node)
-(js2--struct-put 'js2-return-node 'js2-printer 'js2-print-return-node)
-
-(defun js2-visit-return-node (n v)
- (js2-visit-ast (js2-return-node-retval n) v))
-
-(defun js2-print-return-node (n i)
- (insert (js2-make-pad i) "return")
- (when (js2-return-node-retval n)
- (insert " ")
- (js2-print-ast (js2-return-node-retval n) 0))
- (insert ";\n"))
-
-(cl-defstruct (js2-if-node
- (:include js2-node)
- (:constructor make-js2-if-node (&key (type js2-IF)
- (pos js2-ts-cursor)
- len condition
- then-part
- else-pos
- else-part lp
- rp)))
- "AST node for an if-statement."
- condition ; expression
- then-part ; statement or block
- else-pos ; optional buffer position of 'else' keyword
- else-part ; optional statement or block
- lp ; position of left-paren, nil if omitted
- rp) ; position of right-paren, nil if omitted
-
-(js2--struct-put 'js2-if-node 'js2-visitor 'js2-visit-if-node)
-(js2--struct-put 'js2-if-node 'js2-printer 'js2-print-if-node)
-
-(defun js2-visit-if-node (n v)
- (js2-visit-ast (js2-if-node-condition n) v)
- (js2-visit-ast (js2-if-node-then-part n) v)
- (js2-visit-ast (js2-if-node-else-part n) v))
-
-(defun js2-print-if-node (n i)
- (let ((pad (js2-make-pad i))
- (then-part (js2-if-node-then-part n))
- (else-part (js2-if-node-else-part n)))
- (insert pad "if (")
- (js2-print-ast (js2-if-node-condition n) 0)
- (insert ") {\n")
- (js2-print-body then-part (1+ i))
- (insert pad "}")
- (cond
- ((not else-part)
- (insert "\n"))
- ((js2-if-node-p else-part)
- (insert " else ")
- (js2-print-body else-part i))
- (t
- (insert " else {\n")
- (js2-print-body else-part (1+ i))
- (insert pad "}\n")))))
-
-(cl-defstruct (js2-export-binding-node
- (:include js2-node)
- (:constructor make-js2-export-binding-node (&key (type -1)
- pos
- len
- local-name
- extern-name)))
- "AST node for an external symbol binding.
-It contains a local-name node which is the name of the value in the
-current scope, and extern-name which is the name of the value in the
-imported or exported scope. By default these are the same, but if the
-name is aliased as in {foo as bar}, it would have an extern-name node
-containing `foo' and a local-name node containing `bar'."
- local-name ; js2-name-node with the variable name in this scope
- extern-name) ; js2-name-node with the value name in the exporting module
-
-(js2--struct-put 'js2-export-binding-node 'js2-printer
'js2-print-extern-binding)
-(js2--struct-put 'js2-export-binding-node 'js2-visitor
'js2-visit-extern-binding)
-
-(defun js2-visit-extern-binding (n v)
- "Visit an extern binding node. First visit the local-name, and, if
-different, visit the extern-name."
- (let ((local-name (js2-export-binding-node-local-name n))
- (extern-name (js2-export-binding-node-extern-name n)))
- (when local-name
- (js2-visit-ast local-name v))
- (when (not (equal local-name extern-name))
- (js2-visit-ast extern-name v))))
-
-(defun js2-print-extern-binding (n _i)
- "Print a representation of a single extern binding. E.g. `foo' or
-`foo as bar'."
- (let ((local-name (js2-export-binding-node-local-name n))
- (extern-name (js2-export-binding-node-extern-name n)))
- (insert (js2-name-node-name extern-name))
- (when (not (equal local-name extern-name))
- (insert " as ")
- (insert (js2-name-node-name local-name)))))
-
-
-(cl-defstruct (js2-import-node
- (:include js2-node)
- (:constructor make-js2-import-node (&key (type js2-IMPORT)
- (pos
(js2-current-token-beg))
- len
- import
- from
- module-id)))
- "AST node for an import statement. It follows the form
-
-import ModuleSpecifier;
-import ImportClause FromClause;"
- import ; js2-import-clause-node specifying which names are to imported.
- from ; js2-from-clause-node indicating the module from which to import.
- module-id) ; module-id of the import. E.g. 'src/mylib'.
-
-(js2--struct-put 'js2-import-node 'js2-printer 'js2-print-import)
-(js2--struct-put 'js2-import-node 'js2-visitor 'js2-visit-import)
-
-(defun js2-visit-import (n v)
- (let ((import-clause (js2-import-node-import n))
- (from-clause (js2-import-node-from n)))
- (when import-clause
- (js2-visit-ast import-clause v))
- (when from-clause
- (js2-visit-ast from-clause v))))
-
-(defun js2-print-import (n i)
- "Prints a representation of the import node"
- (let ((pad (js2-make-pad i))
- (import-clause (js2-import-node-import n))
- (from-clause (js2-import-node-from n))
- (module-id (js2-import-node-module-id n)))
- (insert pad "import ")
- (if import-clause
- (progn
- (js2-print-import-clause import-clause)
- (insert " ")
- (js2-print-from-clause from-clause))
- (insert "'")
- (insert module-id)
- (insert "'"))
- (insert ";\n")))
-
-(cl-defstruct (js2-import-clause-node
- (:include js2-node)
- (:constructor make-js2-import-clause-node (&key (type -1)
- pos
- len
- namespace-import
- named-imports
-
default-binding)))
- "AST node corresponding to the import clause of an import statement. This is
-the portion of the import that bindings names from the external context to the
-local context."
- namespace-import ; js2-namespace-import-node. E.g. '* as lib'
- named-imports ; lisp list of js2-export-binding-node for all named
imports.
- default-binding) ; js2-export-binding-node for the default import binding
-
-(js2--struct-put 'js2-import-clause-node 'js2-visitor 'js2-visit-import-clause)
-(js2--struct-put 'js2-import-clause-node 'js2-printer 'js2-print-import-clause)
-
-(defun js2-visit-import-clause (n v)
- (let ((ns-import (js2-import-clause-node-namespace-import n))
- (named-imports (js2-import-clause-node-named-imports n))
- (default (js2-import-clause-node-default-binding n)))
- (when default
- (js2-visit-ast default v))
- (when ns-import
- (js2-visit-ast ns-import v))
- (when named-imports
- (dolist (import named-imports)
- (js2-visit-ast import v)))))
-
-(defun js2-print-import-clause (n)
- (let ((ns-import (js2-import-clause-node-namespace-import n))
- (named-imports (js2-import-clause-node-named-imports n))
- (default (js2-import-clause-node-default-binding n)))
- (cond
- ((and default ns-import)
- (js2-print-ast default)
- (insert ", ")
- (js2-print-namespace-import ns-import))
- ((and default named-imports)
- (js2-print-ast default)
- (insert ", ")
- (js2-print-named-imports named-imports))
- (default
- (js2-print-ast default))
- (ns-import
- (js2-print-namespace-import ns-import))
- (named-imports
- (js2-print-named-imports named-imports)))))
-
-(defun js2-print-namespace-import (node)
- (insert "* as ")
- (insert (js2-name-node-name (js2-namespace-import-node-name node))))
-
-(defun js2-print-named-imports (imports)
- (insert "{")
- (let ((len (length imports))
- (n 0))
- (while (< n len)
- (js2-print-extern-binding (nth n imports) 0)
- (unless (= n (- len 1))
- (insert ", "))
- (setq n (+ n 1))))
- (insert "}"))
-
-(cl-defstruct (js2-namespace-import-node
- (:include js2-node)
- (:constructor make-js2-namespace-import-node (&key (type -1)
- pos
- len
- name)))
- "AST node for a complete namespace import.
-E.g. the `* as lib' expression in:
-
-import * as lib from \\='src/lib\\='
-
-It contains a single name node referring to the bound name."
- name) ; js2-name-node of the bound name.
-
-(defun js2-visit-namespace-import (n v)
- (js2-visit-ast (js2-namespace-import-node-name n) v))
-
-(js2--struct-put 'js2-namespace-import-node 'js2-visitor
'js2-visit-namespace-import)
-(js2--struct-put 'js2-namespace-import-node 'js2-printer
'js2-print-namespace-import)
-
-(cl-defstruct (js2-from-clause-node
- (:include js2-node)
- (:constructor make-js2-from-clause-node (&key (type js2-NAME)
- pos
- len
- module-id
- metadata-p)))
- "AST node for the from clause in an import or export statement.
-E.g. from \\='my/module\\='. It can refere to either an external module, or to
the
-modules metadata itself."
- module-id ; string containing the module specifier.
- metadata-p) ; true if this clause refers to the module's metadata
-
-(js2--struct-put 'js2-from-clause-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-from-clause-node 'js2-printer 'js2-print-from-clause)
-
-(defun js2-print-from-clause (n)
- (insert "from ")
- (if (js2-from-clause-node-metadata-p n)
- (insert "this module")
- (insert "'")
- (insert (js2-from-clause-node-module-id n))
- (insert "'")))
-
-(cl-defstruct (js2-try-node
- (:include js2-node)
- (:constructor make-js2-try-node (&key (type js2-TRY)
- (pos js2-ts-cursor)
- len
- try-block
- catch-clauses
- finally-block)))
- "AST node for a try-statement."
- try-block
- catch-clauses ; a Lisp list of `js2-catch-node'
- finally-block) ; a `js2-finally-node'
-
-(js2--struct-put 'js2-try-node 'js2-visitor 'js2-visit-try-node)
-(js2--struct-put 'js2-try-node 'js2-printer 'js2-print-try-node)
-
-(defun js2-visit-try-node (n v)
- (js2-visit-ast (js2-try-node-try-block n) v)
- (dolist (clause (js2-try-node-catch-clauses n))
- (js2-visit-ast clause v))
- (js2-visit-ast (js2-try-node-finally-block n) v))
-
-(defun js2-print-try-node (n i)
- (let ((pad (js2-make-pad i))
- (catches (js2-try-node-catch-clauses n))
- (finally (js2-try-node-finally-block n)))
- (insert pad "try {\n")
- (js2-print-body (js2-try-node-try-block n) (1+ i))
- (insert pad "}")
- (when catches
- (dolist (catch catches)
- (js2-print-ast catch i)))
- (if finally
- (js2-print-ast finally i)
- (insert "\n"))))
-
-(cl-defstruct (js2-catch-node
- (:include js2-scope)
- (:constructor make-js2-catch-node (&key (type js2-CATCH)
- (pos js2-ts-cursor)
- len
- param
- guard-kwd
- guard-expr
- lp rp)))
- "AST node for a catch clause."
- param ; destructuring form or simple name node
- guard-kwd ; relative buffer position of "if" in "catch (x if ...)"
- guard-expr ; catch condition, a `js2-node'
- lp ; buffer position of left-paren, nil if omitted
- rp) ; buffer position of right-paren, nil if omitted
-
-(js2--struct-put 'js2-catch-node 'js2-visitor 'js2-visit-catch-node)
-(js2--struct-put 'js2-catch-node 'js2-printer 'js2-print-catch-node)
-
-(defun js2-visit-catch-node (n v)
- (js2-visit-ast (js2-catch-node-param n) v)
- (when (js2-catch-node-guard-kwd n)
- (js2-visit-ast (js2-catch-node-guard-expr n) v))
- (js2-visit-block n v))
-
-(defun js2-print-catch-node (n i)
- (let ((pad (js2-make-pad i))
- (guard-kwd (js2-catch-node-guard-kwd n))
- (guard-expr (js2-catch-node-guard-expr n)))
- (insert " catch (")
- (js2-print-ast (js2-catch-node-param n) 0)
- (when guard-kwd
- (insert " if ")
- (js2-print-ast guard-expr 0))
- (insert ") {\n")
- (js2-print-body n (1+ i))
- (insert pad "}")))
-
-(cl-defstruct (js2-finally-node
- (:include js2-node)
- (:constructor make-js2-finally-node (&key (type js2-FINALLY)
- (pos js2-ts-cursor)
- len body)))
- "AST node for a finally clause."
- body) ; a `js2-node', often but not always a block node
-
-(js2--struct-put 'js2-finally-node 'js2-visitor 'js2-visit-finally-node)
-(js2--struct-put 'js2-finally-node 'js2-printer 'js2-print-finally-node)
-
-(defun js2-visit-finally-node (n v)
- (js2-visit-ast (js2-finally-node-body n) v))
-
-(defun js2-print-finally-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert " finally {\n")
- (js2-print-body (js2-finally-node-body n) (1+ i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-switch-node
- (:include js2-scope)
- (:constructor make-js2-switch-node (&key (type js2-SWITCH)
- (pos js2-ts-cursor)
- len
- discriminant
- cases lp
- rp)))
- "AST node for a switch statement."
- discriminant ; a `js2-node' (switch expression)
- cases ; a Lisp list of `js2-case-node'
- lp ; position of open-paren for discriminant, nil if omitted
- rp) ; position of close-paren for discriminant, nil if omitted
-
-(js2--struct-put 'js2-switch-node 'js2-visitor 'js2-visit-switch-node)
-(js2--struct-put 'js2-switch-node 'js2-printer 'js2-print-switch-node)
-
-(defun js2-visit-switch-node (n v)
- (js2-visit-ast (js2-switch-node-discriminant n) v)
- (dolist (c (js2-switch-node-cases n))
- (js2-visit-ast c v)))
-
-(defun js2-print-switch-node (n i)
- (let ((pad (js2-make-pad i))
- (cases (js2-switch-node-cases n)))
- (insert pad "switch (")
- (js2-print-ast (js2-switch-node-discriminant n) 0)
- (insert ") {\n")
- (dolist (case cases)
- (js2-print-ast case i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-case-node
- (:include js2-block-node)
- (:constructor make-js2-case-node (&key (type js2-CASE)
- (pos js2-ts-cursor)
- len kids expr)))
- "AST node for a case clause of a switch statement."
- expr) ; the case expression (nil for default)
-
-(js2--struct-put 'js2-case-node 'js2-visitor 'js2-visit-case-node)
-(js2--struct-put 'js2-case-node 'js2-printer 'js2-print-case-node)
-
-(defun js2-visit-case-node (n v)
- (js2-visit-ast (js2-case-node-expr n) v)
- (js2-visit-block n v))
-
-(defun js2-print-case-node (n i)
- (let ((pad (js2-make-pad i))
- (expr (js2-case-node-expr n)))
- (insert pad)
- (if (null expr)
- (insert "default:\n")
- (insert "case ")
- (js2-print-ast expr 0)
- (insert ":\n"))
- (dolist (kid (js2-case-node-kids n))
- (js2-print-ast kid (1+ i)))))
-
-(cl-defstruct (js2-throw-node
- (:include js2-node)
- (:constructor make-js2-throw-node (&key (type js2-THROW)
- (pos js2-ts-cursor)
- len expr)))
- "AST node for a throw statement."
- expr) ; the expression to throw
-
-(js2--struct-put 'js2-throw-node 'js2-visitor 'js2-visit-throw-node)
-(js2--struct-put 'js2-throw-node 'js2-printer 'js2-print-throw-node)
-
-(defun js2-visit-throw-node (n v)
- (js2-visit-ast (js2-throw-node-expr n) v))
-
-(defun js2-print-throw-node (n i)
- (insert (js2-make-pad i) "throw ")
- (js2-print-ast (js2-throw-node-expr n) 0)
- (insert ";\n"))
-
-(cl-defstruct (js2-with-node
- (:include js2-node)
- (:constructor make-js2-with-node (&key (type js2-WITH)
- (pos js2-ts-cursor)
- len object
- body lp rp)))
- "AST node for a with-statement."
- object
- body
- lp ; buffer position of left-paren around object, nil if omitted
- rp) ; buffer position of right-paren around object, nil if omitted
-
-(js2--struct-put 'js2-with-node 'js2-visitor 'js2-visit-with-node)
-(js2--struct-put 'js2-with-node 'js2-printer 'js2-print-with-node)
-
-(defun js2-visit-with-node (n v)
- (js2-visit-ast (js2-with-node-object n) v)
- (js2-visit-ast (js2-with-node-body n) v))
-
-(defun js2-print-with-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad "with (")
- (js2-print-ast (js2-with-node-object n) 0)
- (insert ") {\n")
- (js2-print-body (js2-with-node-body n) (1+ i))
- (insert pad "}\n")))
-
-(cl-defstruct (js2-label-node
- (:include js2-node)
- (:constructor make-js2-label-node (&key (type js2-LABEL)
- (pos js2-ts-cursor)
- len name)))
- "AST node for a statement label or case label."
- name ; a string
- loop) ; for validating and code-generating continue-to-label
-
-(js2--struct-put 'js2-label-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-label-node 'js2-printer 'js2-print-label)
-
-(defun js2-print-label (n i)
- (insert (js2-make-pad i)
- (js2-label-node-name n)
- ":\n"))
-
-(cl-defstruct (js2-labeled-stmt-node
- (:include js2-node)
- ;; type needs to be in `js2-side-effecting-tokens' to avoid
spurious
- ;; no-side-effects warnings, hence js2-EXPR_RESULT.
- (:constructor make-js2-labeled-stmt-node (&key (type
js2-EXPR_RESULT)
- (pos
js2-ts-cursor)
- len labels
stmt)))
- "AST node for a statement with one or more labels.
-Multiple labels for a statement are collapsed into the labels field."
- labels ; Lisp list of `js2-label-node'
- stmt) ; the statement these labels are for
-
-(js2--struct-put 'js2-labeled-stmt-node 'js2-visitor 'js2-visit-labeled-stmt)
-(js2--struct-put 'js2-labeled-stmt-node 'js2-printer 'js2-print-labeled-stmt)
-
-(defun js2-get-label-by-name (lbl-stmt name)
- "Return a `js2-label-node' by NAME from LBL-STMT's labels list.
-Returns nil if no such label is in the list."
- (let ((label-list (js2-labeled-stmt-node-labels lbl-stmt))
- result)
- (while (and label-list (not result))
- (if (string= (js2-label-node-name (car label-list)) name)
- (setq result (car label-list))
- (setq label-list (cdr label-list))))
- result))
-
-(defun js2-visit-labeled-stmt (n v)
- (dolist (label (js2-labeled-stmt-node-labels n))
- (js2-visit-ast label v))
- (js2-visit-ast (js2-labeled-stmt-node-stmt n) v))
-
-(defun js2-print-labeled-stmt (n i)
- (dolist (label (js2-labeled-stmt-node-labels n))
- (js2-print-ast label i))
- (js2-print-ast (js2-labeled-stmt-node-stmt n) i))
-
-(defun js2-labeled-stmt-node-contains (node label)
- "Return t if NODE contains LABEL in its label set.
-NODE is a `js2-labels-node'. LABEL is an identifier."
- (cl-loop for nl in (js2-labeled-stmt-node-labels node)
- if (string= label (js2-label-node-name nl))
- return t
- finally return nil))
-
-(defsubst js2-labeled-stmt-node-add-label (node label)
- "Add a `js2-label-node' to the label set for this statement."
- (setf (js2-labeled-stmt-node-labels node)
- (nconc (js2-labeled-stmt-node-labels node) (list label))))
-
-(cl-defstruct (js2-jump-node
- (:include js2-node)
- (:constructor nil))
- "Abstract supertype of break and continue nodes."
- label ; `js2-name-node' for location of label identifier, if present
- target) ; target js2-labels-node or loop/switch statement
-
-(defun js2-visit-jump-node (n v)
- ;; We don't visit the target, since it's a back-link.
- (js2-visit-ast (js2-jump-node-label n) v))
-
-(cl-defstruct (js2-break-node
- (:include js2-jump-node)
- (:constructor make-js2-break-node (&key (type js2-BREAK)
- (pos js2-ts-cursor)
- len label target)))
- "AST node for a break statement.
-The label field is a `js2-name-node', possibly nil, for the named label
-if provided. E.g. in `break foo', it represents `foo'. The target field
-is the target of the break - a label node or enclosing loop/switch statement.")
-
-(js2--struct-put 'js2-break-node 'js2-visitor 'js2-visit-jump-node)
-(js2--struct-put 'js2-break-node 'js2-printer 'js2-print-break-node)
-
-(defun js2-print-break-node (n i)
- (insert (js2-make-pad i) "break")
- (when (js2-break-node-label n)
- (insert " ")
- (js2-print-ast (js2-break-node-label n) 0))
- (insert ";\n"))
-
-(cl-defstruct (js2-continue-node
- (:include js2-jump-node)
- (:constructor make-js2-continue-node (&key (type js2-CONTINUE)
- (pos js2-ts-cursor)
- len label target)))
- "AST node for a continue statement.
-The label field is the user-supplied enclosing label name, a `js2-name-node'.
-It is nil if continue specifies no label. The target field is the jump target:
-a `js2-label-node' or the innermost enclosing loop.")
-
-(js2--struct-put 'js2-continue-node 'js2-visitor 'js2-visit-jump-node)
-(js2--struct-put 'js2-continue-node 'js2-printer 'js2-print-continue-node)
-
-(defun js2-print-continue-node (n i)
- (insert (js2-make-pad i) "continue")
- (when (js2-continue-node-label n)
- (insert " ")
- (js2-print-ast (js2-continue-node-label n) 0))
- (insert ";\n"))
-
-(cl-defstruct (js2-function-node
- (:include js2-script-node)
- (:constructor make-js2-function-node (&key (type js2-FUNCTION)
- (pos js2-ts-cursor)
- len
- (ftype 'FUNCTION)
- (form
'FUNCTION_STATEMENT)
- (name "")
- params rest-p
- body
- generator-type
- async
- lp rp)))
- "AST node for a function declaration.
-The `params' field is a Lisp list of nodes. Each node is either a simple
-`js2-name-node', or if it's a destructuring-assignment parameter, a
-`js2-array-node' or `js2-object-node'."
- ftype ; FUNCTION, GETTER or SETTER
- form ; FUNCTION_{STATEMENT|EXPRESSION|ARROW}
- name ; function name (a `js2-name-node', or nil if anonymous)
- params ; a Lisp list of destructuring forms or simple name nodes
- rest-p ; if t, the last parameter is rest parameter
- body ; a `js2-block-node' or expression node (1.8 only)
- lp ; position of arg-list open-paren, or nil if omitted
- rp ; position of arg-list close-paren, or nil if omitted
- ignore-dynamic ; ignore value of the dynamic-scope flag (interpreter only)
- needs-activation ; t if we need an activation object for this frame
- generator-type ; STAR, LEGACY, COMPREHENSION or nil
- async ; t if the function is defined as `async function`
- member-expr) ; nonstandard Ecma extension from Rhino
-
-(js2--struct-put 'js2-function-node 'js2-visitor 'js2-visit-function-node)
-(js2--struct-put 'js2-function-node 'js2-printer 'js2-print-function-node)
-
-(defun js2-visit-function-node (n v)
- (js2-visit-ast (js2-function-node-name n) v)
- (dolist (p (js2-function-node-params n))
- (js2-visit-ast p v))
- (js2-visit-ast (js2-function-node-body n) v))
-
-(defun js2-print-function-node (n i)
- (let* ((pad (js2-make-pad i))
- (method (js2-node-get-prop n 'METHOD_TYPE))
- (name (or (js2-function-node-name n)
- (js2-function-node-member-expr n)))
- (params (js2-function-node-params n))
- (arrow (eq (js2-function-node-form n) 'FUNCTION_ARROW))
- (rest-p (js2-function-node-rest-p n))
- (body (js2-function-node-body n))
- (expr (not (eq (js2-function-node-form n) 'FUNCTION_STATEMENT))))
- (unless method
- (insert pad)
- (when (js2-function-node-async n) (insert "async "))
- (unless arrow (insert "function"))
- (when (eq (js2-function-node-generator-type n) 'STAR)
- (insert "*")))
- (when name
- (insert " ")
- (js2-print-ast name 0))
- (insert "(")
- (cl-loop with len = (length params)
- for param in params
- for count from 1
- do
- (when (and rest-p (= count len))
- (insert "..."))
- (js2-print-ast param 0)
- (when (< count len)
- (insert ", ")))
- (insert ") ")
- (when arrow
- (insert "=> "))
- (insert "{")
- ;; TODO: fix this to be smarter about indenting, etc.
- (unless expr
- (insert "\n"))
- (if (js2-block-node-p body)
- (js2-print-body body (1+ i))
- (js2-print-ast body 0))
- (insert pad "}")
- (unless expr
- (insert "\n"))))
-
-(defun js2-function-name (node)
- "Return function name for NODE, a `js2-function-node', or nil if anonymous."
- (and (js2-function-node-name node)
- (js2-name-node-name (js2-function-node-name node))))
-
-;; Having this be an expression node makes it more flexible.
-;; There are IDE contexts, such as indentation in a for-loop initializer,
-;; that work better if you assume it's an expression. Whenever we have
-;; a standalone var/const declaration, we just wrap with an expr stmt.
-;; Eclipse apparently screwed this up and now has two versions, expr and stmt.
-(cl-defstruct (js2-var-decl-node
- (:include js2-node)
- (:constructor make-js2-var-decl-node (&key (type js2-VAR)
- (pos
(js2-current-token-beg))
- len kids
- decl-type)))
- "AST node for a variable declaration list (VAR, CONST or LET).
-The node bounds differ depending on the declaration type. For VAR or
-CONST declarations, the bounds include the var/const keyword. For LET
-declarations, the node begins at the position of the first child."
- kids ; a Lisp list of `js2-var-init-node' structs.
- decl-type) ; js2-VAR, js2-CONST or js2-LET
-
-(js2--struct-put 'js2-var-decl-node 'js2-visitor 'js2-visit-var-decl)
-(js2--struct-put 'js2-var-decl-node 'js2-printer 'js2-print-var-decl)
-
-(defun js2-visit-var-decl (n v)
- (dolist (kid (js2-var-decl-node-kids n))
- (js2-visit-ast kid v)))
-
-(defun js2-print-var-decl (n i)
- (let ((pad (js2-make-pad i))
- (tt (js2-var-decl-node-decl-type n)))
- (insert pad)
- (insert (cond
- ((= tt js2-VAR) "var ")
- ((= tt js2-LET) "let ")
- ((= tt js2-CONST) "const ")
- (t
- (error "malformed var-decl node"))))
- (cl-loop with kids = (js2-var-decl-node-kids n)
- with len = (length kids)
- for kid in kids
- for count from 1
- do
- (js2-print-ast kid 0)
- (if (< count len)
- (insert ", ")))))
-
-(cl-defstruct (js2-var-init-node
- (:include js2-node)
- (:constructor make-js2-var-init-node (&key (type js2-VAR)
- (pos js2-ts-cursor)
- len target
- initializer)))
- "AST node for a variable declaration.
-The type field will be js2-CONST for a const decl."
- target ; `js2-name-node', `js2-object-node', or `js2-array-node'
- initializer) ; initializer expression, a `js2-node'
-
-(js2--struct-put 'js2-var-init-node 'js2-visitor 'js2-visit-var-init-node)
-(js2--struct-put 'js2-var-init-node 'js2-printer 'js2-print-var-init-node)
-
-(defun js2-visit-var-init-node (n v)
- (js2-visit-ast (js2-var-init-node-target n) v)
- (js2-visit-ast (js2-var-init-node-initializer n) v))
-
-(defun js2-print-var-init-node (n i)
- (let ((pad (js2-make-pad i))
- (name (js2-var-init-node-target n))
- (init (js2-var-init-node-initializer n)))
- (insert pad)
- (js2-print-ast name 0)
- (when init
- (insert " = ")
- (js2-print-ast init 0))))
-
-(cl-defstruct (js2-cond-node
- (:include js2-node)
- (:constructor make-js2-cond-node (&key (type js2-HOOK)
- (pos js2-ts-cursor)
- len
- test-expr
- true-expr
- false-expr
- q-pos c-pos)))
- "AST node for the ternary operator"
- test-expr
- true-expr
- false-expr
- q-pos ; buffer position of ?
- c-pos) ; buffer position of :
-
-(js2--struct-put 'js2-cond-node 'js2-visitor 'js2-visit-cond-node)
-(js2--struct-put 'js2-cond-node 'js2-printer 'js2-print-cond-node)
-
-(defun js2-visit-cond-node (n v)
- (js2-visit-ast (js2-cond-node-test-expr n) v)
- (js2-visit-ast (js2-cond-node-true-expr n) v)
- (js2-visit-ast (js2-cond-node-false-expr n) v))
-
-(defun js2-print-cond-node (n i)
- (let ((pad (js2-make-pad i)))
- (insert pad)
- (js2-print-ast (js2-cond-node-test-expr n) 0)
- (insert " ? ")
- (js2-print-ast (js2-cond-node-true-expr n) 0)
- (insert " : ")
- (js2-print-ast (js2-cond-node-false-expr n) 0)))
-
-(cl-defstruct (js2-infix-node
- (:include js2-node)
- (:constructor make-js2-infix-node (&key type
- (pos js2-ts-cursor)
- len op-pos
- left right)))
- "Represents infix expressions.
-Includes assignment ops like `|=', and the comma operator.
-The type field inherited from `js2-node' holds the operator."
- op-pos ; buffer position where operator begins
- left ; any `js2-node'
- right) ; any `js2-node'
-
-(js2--struct-put 'js2-infix-node 'js2-visitor 'js2-visit-infix-node)
-(js2--struct-put 'js2-infix-node 'js2-printer 'js2-print-infix-node)
-
-(defun js2-visit-infix-node (n v)
- (js2-visit-ast (js2-infix-node-left n) v)
- (js2-visit-ast (js2-infix-node-right n) v))
-
-(defconst js2-operator-tokens
- (let ((table (make-hash-table :test 'eq))
- (tokens
- (list (cons js2-IN "in")
- (cons js2-TYPEOF "typeof")
- (cons js2-INSTANCEOF "instanceof")
- (cons js2-DELPROP "delete")
- (cons js2-AWAIT "await")
- (cons js2-VOID "void")
- (cons js2-COMMA ",")
- (cons js2-COLON ":")
- (cons js2-OR "||")
- (cons js2-AND "&&")
- (cons js2-INC "++")
- (cons js2-DEC "--")
- (cons js2-BITOR "|")
- (cons js2-BITXOR "^")
- (cons js2-BITAND "&")
- (cons js2-EQ "==")
- (cons js2-NE "!=")
- (cons js2-LT "<")
- (cons js2-LE "<=")
- (cons js2-GT ">")
- (cons js2-GE ">=")
- (cons js2-LSH "<<")
- (cons js2-RSH ">>")
- (cons js2-URSH ">>>")
- (cons js2-ADD "+") ; infix plus
- (cons js2-SUB "-") ; infix minus
- (cons js2-MUL "*")
- (cons js2-EXPON "**")
- (cons js2-DIV "/")
- (cons js2-MOD "%")
- (cons js2-NOT "!")
- (cons js2-BITNOT "~")
- (cons js2-POS "+") ; unary plus
- (cons js2-NEG "-") ; unary minus
- (cons js2-TRIPLEDOT "...")
- (cons js2-SHEQ "===") ; shallow equality
- (cons js2-SHNE "!==") ; shallow inequality
- (cons js2-ASSIGN "=")
- (cons js2-ASSIGN_BITOR "|=")
- (cons js2-ASSIGN_BITXOR "^=")
- (cons js2-ASSIGN_BITAND "&=")
- (cons js2-ASSIGN_LSH "<<=")
- (cons js2-ASSIGN_RSH ">>=")
- (cons js2-ASSIGN_URSH ">>>=")
- (cons js2-ASSIGN_ADD "+=")
- (cons js2-ASSIGN_SUB "-=")
- (cons js2-ASSIGN_MUL "*=")
- (cons js2-ASSIGN_EXPON "**=")
- (cons js2-ASSIGN_DIV "/=")
- (cons js2-ASSIGN_MOD "%="))))
- (cl-loop for (k . v) in tokens do
- (puthash k v table))
- table))
-
-(defun js2-print-infix-node (n i)
- (let* ((tt (js2-node-type n))
- (op (gethash tt js2-operator-tokens)))
- (unless op
- (error "unrecognized infix operator %s" (js2-node-type n)))
- (insert (js2-make-pad i))
- (js2-print-ast (js2-infix-node-left n) 0)
- (unless (= tt js2-COMMA)
- (insert " "))
- (insert op)
- (insert " ")
- (js2-print-ast (js2-infix-node-right n) 0)))
-
-(cl-defstruct (js2-assign-node
- (:include js2-infix-node)
- (:constructor make-js2-assign-node (&key type
- (pos js2-ts-cursor)
- len op-pos
- left right)))
- "Represents any assignment.
-The type field holds the actual assignment operator.")
-
-(js2--struct-put 'js2-assign-node 'js2-visitor 'js2-visit-infix-node)
-(js2--struct-put 'js2-assign-node 'js2-printer 'js2-print-infix-node)
-
-(cl-defstruct (js2-unary-node
- (:include js2-node)
- (:constructor make-js2-unary-node (&key type ; required
- (pos js2-ts-cursor)
- len operand)))
- "AST node type for unary operator nodes.
-The type field can be NOT, BITNOT, POS, NEG, INC, DEC,
-TYPEOF, DELPROP, TRIPLEDOT or AWAIT. For INC or DEC, a 'postfix node
-property is added if the operator follows the operand."
- operand) ; a `js2-node' expression
-
-(js2--struct-put 'js2-unary-node 'js2-visitor 'js2-visit-unary-node)
-(js2--struct-put 'js2-unary-node 'js2-printer 'js2-print-unary-node)
-
-(defun js2-visit-unary-node (n v)
- (js2-visit-ast (js2-unary-node-operand n) v))
-
-(defun js2-print-unary-node (n i)
- (let* ((tt (js2-node-type n))
- (op (gethash tt js2-operator-tokens))
- (postfix (js2-node-get-prop n 'postfix)))
- (unless op
- (error "unrecognized unary operator %s" tt))
- (insert (js2-make-pad i))
- (unless postfix
- (insert op))
- (if (or (= tt js2-TYPEOF)
- (= tt js2-DELPROP)
- (= tt js2-AWAIT)
- (= tt js2-VOID))
- (insert " "))
- (js2-print-ast (js2-unary-node-operand n) 0)
- (when postfix
- (insert op))))
-
-(cl-defstruct (js2-let-node
- (:include js2-scope)
- (:constructor make-js2-let-node (&key (type js2-LETEXPR)
- (pos
(js2-current-token-beg))
- len vars body
- lp rp)))
- "AST node for a let expression or a let statement.
-Note that a let declaration such as let x=6, y=7 is a `js2-var-decl-node'."
- vars ; a `js2-var-decl-node'
- body ; a `js2-node' representing the expression or body block
- lp
- rp)
-
-(js2--struct-put 'js2-let-node 'js2-visitor 'js2-visit-let-node)
-(js2--struct-put 'js2-let-node 'js2-printer 'js2-print-let-node)
-
-(defun js2-visit-let-node (n v)
- (js2-visit-ast (js2-let-node-vars n) v)
- (js2-visit-ast (js2-let-node-body n) v))
-
-(defun js2-print-let-node (n i)
- (insert (js2-make-pad i) "let (")
- (let ((p (point)))
- (js2-print-ast (js2-let-node-vars n) 0)
- (delete-region p (+ p 4)))
- (insert ") ")
- (js2-print-ast (js2-let-node-body n) i))
-
-(cl-defstruct (js2-keyword-node
- (:include js2-node)
- (:constructor make-js2-keyword-node (&key type
- (pos
(js2-current-token-beg))
- (len (- js2-ts-cursor
pos)))))
- "AST node representing a literal keyword such as `null'.
-Used for `null', `this', `true', `false' and `debugger'.
-The node type is set to js2-NULL, js2-THIS, etc.")
-
-(js2--struct-put 'js2-keyword-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-keyword-node 'js2-printer 'js2-print-keyword-node)
-
-(defun js2-print-keyword-node (n i)
- (insert (js2-make-pad i)
- (let ((tt (js2-node-type n)))
- (cond
- ((= tt js2-THIS) "this")
- ((= tt js2-SUPER) "super")
- ((= tt js2-NULL) "null")
- ((= tt js2-TRUE) "true")
- ((= tt js2-FALSE) "false")
- ((= tt js2-DEBUGGER) "debugger")
- (t (error "Invalid keyword literal type: %d" tt))))))
-
-(defsubst js2-this-or-super-node-p (node)
- "Return t if NODE is a `js2-literal-node' of type js2-THIS or js2-SUPER."
- (let ((type (js2-node-type node)))
- (or (eq type js2-THIS) (eq type js2-SUPER))))
-
-(cl-defstruct (js2-new-node
- (:include js2-node)
- (:constructor make-js2-new-node (&key (type js2-NEW)
- (pos
(js2-current-token-beg))
- len target
- args initializer
- lp rp)))
- "AST node for new-expression such as new Foo()."
- target ; an identifier or reference
- args ; a Lisp list of argument nodes
- lp ; position of left-paren, nil if omitted
- rp ; position of right-paren, nil if omitted
- initializer) ; experimental Rhino syntax: optional `js2-object-node'
-
-(js2--struct-put 'js2-new-node 'js2-visitor 'js2-visit-new-node)
-(js2--struct-put 'js2-new-node 'js2-printer 'js2-print-new-node)
-
-(defun js2-visit-new-node (n v)
- (js2-visit-ast (js2-new-node-target n) v)
- (dolist (arg (js2-new-node-args n))
- (js2-visit-ast arg v))
- (js2-visit-ast (js2-new-node-initializer n) v))
-
-(defun js2-print-new-node (n i)
- (insert (js2-make-pad i) "new ")
- (js2-print-ast (js2-new-node-target n))
- (insert "(")
- (js2-print-list (js2-new-node-args n))
- (insert ")")
- (when (js2-new-node-initializer n)
- (insert " ")
- (js2-print-ast (js2-new-node-initializer n))))
-
-(cl-defstruct (js2-name-node
- (:include js2-node)
- (:constructor make-js2-name-node (&key (type js2-NAME)
- (pos
(js2-current-token-beg))
- (len (- js2-ts-cursor
-
(js2-current-token-beg)))
- (name
(js2-current-token-string)))))
- "AST node for a JavaScript identifier"
- name ; a string
- scope) ; a `js2-scope' (optional, used for codegen)
-
-(js2--struct-put 'js2-name-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-name-node 'js2-printer 'js2-print-name-node)
-
-(defun js2-print-name-node (n i)
- (insert (js2-make-pad i)
- (js2-name-node-name n)))
-
-(defsubst js2-name-node-length (node)
- "Return identifier length of NODE, a `js2-name-node'.
-Returns 0 if NODE is nil or its identifier field is nil."
- (if node
- (length (js2-name-node-name node))
- 0))
-
-(cl-defstruct (js2-number-node
- (:include js2-node)
- (:constructor make-js2-number-node (&key (type js2-NUMBER)
- (pos
(js2-current-token-beg))
- (len (- js2-ts-cursor
-
(js2-current-token-beg)))
- (value
(js2-current-token-string))
- (num-value
(js2-token-number
-
(js2-current-token)))
- (num-base
(js2-token-number-base
-
(js2-current-token)))
- (legacy-octal-p
(js2-token-number-legacy-octal-p
-
(js2-current-token))))))
- "AST node for a number literal."
- value ; the original string, e.g. "6.02e23"
- num-value ; the parsed number value
- num-base ; the number's base
- legacy-octal-p) ; whether the number is a legacy octal (0123 instead of
0o123)
-
-(js2--struct-put 'js2-number-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-number-node 'js2-printer 'js2-print-number-node)
-
-(defun js2-print-number-node (n i)
- (insert (js2-make-pad i)
- (number-to-string (js2-number-node-num-value n))))
-
-(cl-defstruct (js2-regexp-node
- (:include js2-node)
- (:constructor make-js2-regexp-node (&key (type js2-REGEXP)
- (pos
(js2-current-token-beg))
- (len (- js2-ts-cursor
-
(js2-current-token-beg)))
- value flags)))
- "AST node for a regular expression literal."
- value ; the regexp string, without // delimiters
- flags) ; a string of flags, e.g. `mi'.
-
-(js2--struct-put 'js2-regexp-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-regexp-node 'js2-printer 'js2-print-regexp)
-
-(defun js2-print-regexp (n i)
- (insert (js2-make-pad i)
- "/"
- (js2-regexp-node-value n)
- "/")
- (if (js2-regexp-node-flags n)
- (insert (js2-regexp-node-flags n))))
-
-(cl-defstruct (js2-string-node
- (:include js2-node)
- (:constructor make-js2-string-node (&key (type js2-STRING)
- (pos
(js2-current-token-beg))
- (len (- js2-ts-cursor
-
(js2-current-token-beg)))
- (value
(js2-current-token-string)))))
- "String literal.
-Escape characters are not evaluated; e.g. \n is 2 chars in value field.
-You can tell the quote type by looking at the first character."
- value) ; the characters of the string, including the quotes
-
-(js2--struct-put 'js2-string-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-string-node 'js2-printer 'js2-print-string-node)
-
-(defun js2-print-string-node (n i)
- (insert (js2-make-pad i)
- (js2-node-string n)))
-
-(cl-defstruct (js2-template-node
- (:include js2-node)
- (:constructor make-js2-template-node (&key (type
js2-TEMPLATE_HEAD)
- pos len kids)))
- "Template literal."
- kids) ; `js2-string-node' is used for string segments, other nodes
- ; for substitutions inside.
-
-(js2--struct-put 'js2-template-node 'js2-visitor 'js2-visit-template)
-(js2--struct-put 'js2-template-node 'js2-printer 'js2-print-template)
-
-(defun js2-visit-template (n callback)
- (dolist (kid (js2-template-node-kids n))
- (js2-visit-ast kid callback)))
-
-(defun js2-print-template (n i)
- (insert (js2-make-pad i))
- (dolist (kid (js2-template-node-kids n))
- (if (js2-string-node-p kid)
- (insert (js2-node-string kid))
- (js2-print-ast kid))))
-
-(cl-defstruct (js2-tagged-template-node
- (:include js2-node)
- (:constructor make-js2-tagged-template-node (&key (type
js2-TAGGED_TEMPLATE)
- pos len tag
template)))
- "Tagged template literal."
- tag ; `js2-node' with the tag expression.
- template) ; `js2-template-node' with the template.
-
-(js2--struct-put 'js2-tagged-template-node 'js2-visitor
'js2-visit-tagged-template)
-(js2--struct-put 'js2-tagged-template-node 'js2-printer
'js2-print-tagged-template)
-
-(defun js2-visit-tagged-template (n callback)
- (js2-visit-ast (js2-tagged-template-node-tag n) callback)
- (js2-visit-ast (js2-tagged-template-node-template n) callback))
-
-(defun js2-print-tagged-template (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-tagged-template-node-tag n))
- (js2-print-ast (js2-tagged-template-node-template n)))
-
-(cl-defstruct (js2-array-node
- (:include js2-node)
- (:constructor make-js2-array-node (&key (type js2-ARRAYLIT)
- (pos js2-ts-cursor)
- len elems)))
- "AST node for an array literal."
- elems) ; list of expressions. [foo,,bar] yields a nil middle element.
-
-(js2--struct-put 'js2-array-node 'js2-visitor 'js2-visit-array-node)
-(js2--struct-put 'js2-array-node 'js2-printer 'js2-print-array-node)
-
-(defun js2-visit-array-node (n v)
- (dolist (e (js2-array-node-elems n))
- (js2-visit-ast e v))) ; Can be nil; e.g. [a, ,b].
-
-(defun js2-print-array-node (n i)
- (insert (js2-make-pad i) "[")
- (let ((elems (js2-array-node-elems n)))
- (js2-print-list elems)
- (when (and elems (null (car (last elems))))
- (insert ",")))
- (insert "]"))
-
-(cl-defstruct (js2-object-node
- (:include js2-node)
- (:constructor make-js2-object-node (&key (type js2-OBJECTLIT)
- (pos js2-ts-cursor)
- len
- elems)))
- "AST node for an object literal expression.
-`elems' is a list of `js2-object-prop-node'."
- elems)
-
-(js2--struct-put 'js2-object-node 'js2-visitor 'js2-visit-object-node)
-(js2--struct-put 'js2-object-node 'js2-printer 'js2-print-object-node)
-
-(defun js2-visit-object-node (n v)
- (dolist (e (js2-object-node-elems n))
- (js2-visit-ast e v)))
-
-(defun js2-print-object-node (n i)
- (insert (js2-make-pad i) "{")
- (js2-print-list (js2-object-node-elems n))
- (insert "}"))
-
-(cl-defstruct (js2-class-node
- (:include js2-object-node)
- (:constructor make-js2-class-node (&key (type js2-CLASS)
- (pos js2-ts-cursor)
- (form 'CLASS_STATEMENT)
- (name "")
- extends len elems)))
- "AST node for an class expression.
-`elems' is a list of `js2-object-prop-node', and `extends' is an
-optional `js2-expr-node'"
- form ; CLASS_{STATEMENT|EXPRESSION}
- name ; class name (a `js2-node-name', or nil if anonymous)
- extends ; class heritage (a `js2-expr-node', or nil if none)
- )
-
-(js2--struct-put 'js2-class-node 'js2-visitor 'js2-visit-class-node)
-(js2--struct-put 'js2-class-node 'js2-printer 'js2-print-class-node)
-
-(defun js2-visit-class-node (n v)
- (js2-visit-ast (js2-class-node-name n) v)
- (js2-visit-ast (js2-class-node-extends n) v)
- (dolist (e (js2-class-node-elems n))
- (js2-visit-ast e v)))
-
-(defun js2-print-class-node (n i)
- (let* ((pad (js2-make-pad i))
- (name (js2-class-node-name n))
- (extends (js2-class-node-extends n))
- (elems (js2-class-node-elems n)))
- (insert pad "class")
- (when name
- (insert " ")
- (js2-print-ast name 0))
- (when extends
- (insert " extends ")
- (js2-print-ast extends))
- (insert " {")
- (dolist (elem elems)
- (insert "\n")
- (if (js2-node-get-prop elem 'STATIC)
- (progn (insert (js2-make-pad (1+ i)) "static ")
- (js2-print-ast elem 0)) ;; TODO(sdh): indentation isn't quite
right
- (js2-print-ast elem (1+ i))))
- (insert "\n" pad "}")))
-
-(cl-defstruct (js2-computed-prop-name-node
- (:include js2-node)
- (:constructor make-js2-computed-prop-name-node
- (&key
- (type js2-LB)
- expr
- (pos (js2-current-token-beg))
- (len (- js2-ts-cursor
- (js2-current-token-beg))))))
- "AST node for a `ComputedPropertyName'."
- expr)
-
-(js2--struct-put 'js2-computed-prop-name-node 'js2-visitor
'js2-visit-computed-prop-name-node)
-(js2--struct-put 'js2-computed-prop-name-node 'js2-printer
'js2-print-computed-prop-name-node)
-
-(defun js2-visit-computed-prop-name-node (n v)
- (js2-visit-ast (js2-computed-prop-name-node-expr n) v))
-
-(defun js2-print-computed-prop-name-node (n i)
- (insert (js2-make-pad i) "[")
- (js2-print-ast (js2-computed-prop-name-node-expr n) 0)
- (insert "]"))
-
-(cl-defstruct (js2-object-prop-node
- (:include js2-infix-node)
- (:constructor make-js2-object-prop-node (&key (type js2-COLON)
- (pos
js2-ts-cursor)
- len left
- right op-pos)))
- "AST node for an object literal prop:value entry.
-The `left' field is the property: a name node, string node,
-number node or expression node. The `right' field is a
-`js2-node' representing the initializer value. If the property
-is abbreviated, the node's `SHORTHAND' property is non-nil and
-both fields have the same value.")
-
-(js2--struct-put 'js2-object-prop-node 'js2-visitor 'js2-visit-infix-node)
-(js2--struct-put 'js2-object-prop-node 'js2-printer
'js2-print-object-prop-node)
-
-(defun js2-print-object-prop-node (n i)
- (let* ((left (js2-object-prop-node-left n))
- (right (js2-object-prop-node-right n)))
- (js2-print-ast left i)
- (if (not (js2-node-get-prop n 'SHORTHAND))
- (progn
- (insert ": ")
- (js2-print-ast right 0)))))
-
-(cl-defstruct (js2-method-node
- (:include js2-infix-node)
- (:constructor make-js2-method-node (&key (pos js2-ts-cursor)
- len left right)))
- "AST node for a method in an object literal or a class body.
-The `left' field is the `js2-name-node' naming the method.
-The `right' field is always an anonymous `js2-function-node' with a node
-property `METHOD_TYPE' set to 'GET or 'SET. ")
-
-(js2--struct-put 'js2-method-node 'js2-visitor 'js2-visit-infix-node)
-(js2--struct-put 'js2-method-node 'js2-printer 'js2-print-method)
-
-(defun js2-print-method (n i)
- (let* ((pad (js2-make-pad i))
- (left (js2-method-node-left n))
- (right (js2-method-node-right n))
- (type (js2-node-get-prop right 'METHOD_TYPE)))
- (insert pad)
- (when type
- (insert (cdr (assoc type '((GET . "get ")
- (SET . "set ")
- (ASYNC . "async ")
- (FUNCTION . ""))))))
- (when (and (js2-function-node-p right)
- (eq 'STAR (js2-function-node-generator-type right)))
- (insert "*"))
- (js2-print-ast left 0)
- (js2-print-ast right 0)))
-
-(cl-defstruct (js2-prop-get-node
- (:include js2-infix-node)
- (:constructor make-js2-prop-get-node (&key (type js2-GETPROP)
- (pos js2-ts-cursor)
- len left right)))
- "AST node for a dotted property reference, e.g. foo.bar or foo().bar")
-
-(js2--struct-put 'js2-prop-get-node 'js2-visitor 'js2-visit-prop-get-node)
-(js2--struct-put 'js2-prop-get-node 'js2-printer 'js2-print-prop-get-node)
-
-(defun js2-visit-prop-get-node (n v)
- (js2-visit-ast (js2-prop-get-node-left n) v)
- (js2-visit-ast (js2-prop-get-node-right n) v))
-
-(defun js2-print-prop-get-node (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-prop-get-node-left n) 0)
- (insert ".")
- (js2-print-ast (js2-prop-get-node-right n) 0))
-
-(cl-defstruct (js2-elem-get-node
- (:include js2-node)
- (:constructor make-js2-elem-get-node (&key (type js2-GETELEM)
- (pos js2-ts-cursor)
- len target element
- lb rb)))
- "AST node for an array index expression such as foo[bar]."
- target ; a `js2-node' - the expression preceding the "."
- element ; a `js2-node' - the expression in brackets
- lb ; position of left-bracket, nil if omitted
- rb) ; position of right-bracket, nil if omitted
-
-(js2--struct-put 'js2-elem-get-node 'js2-visitor 'js2-visit-elem-get-node)
-(js2--struct-put 'js2-elem-get-node 'js2-printer 'js2-print-elem-get-node)
-
-(defun js2-visit-elem-get-node (n v)
- (js2-visit-ast (js2-elem-get-node-target n) v)
- (js2-visit-ast (js2-elem-get-node-element n) v))
-
-(defun js2-print-elem-get-node (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-elem-get-node-target n) 0)
- (insert "[")
- (js2-print-ast (js2-elem-get-node-element n) 0)
- (insert "]"))
-
-(cl-defstruct (js2-call-node
- (:include js2-node)
- (:constructor make-js2-call-node (&key (type js2-CALL)
- (pos js2-ts-cursor)
- len target args
- lp rp)))
- "AST node for a JavaScript function call."
- target ; a `js2-node' evaluating to the function to call
- args ; a Lisp list of `js2-node' arguments
- lp ; position of open-paren, or nil if missing
- rp) ; position of close-paren, or nil if missing
-
-(js2--struct-put 'js2-call-node 'js2-visitor 'js2-visit-call-node)
-(js2--struct-put 'js2-call-node 'js2-printer 'js2-print-call-node)
-
-(defun js2-visit-call-node (n v)
- (js2-visit-ast (js2-call-node-target n) v)
- (dolist (arg (js2-call-node-args n))
- (js2-visit-ast arg v)))
-
-(defun js2-print-call-node (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-call-node-target n) 0)
- (insert "(")
- (js2-print-list (js2-call-node-args n))
- (insert ")"))
-
-(cl-defstruct (js2-yield-node
- (:include js2-node)
- (:constructor make-js2-yield-node (&key (type js2-YIELD)
- (pos js2-ts-cursor)
- len value star-p)))
- "AST node for yield statement or expression."
- star-p ; whether it's yield*
- value) ; optional: value to be yielded
-
-(js2--struct-put 'js2-yield-node 'js2-visitor 'js2-visit-yield-node)
-(js2--struct-put 'js2-yield-node 'js2-printer 'js2-print-yield-node)
-
-(defun js2-visit-yield-node (n v)
- (js2-visit-ast (js2-yield-node-value n) v))
-
-(defun js2-print-yield-node (n i)
- (insert (js2-make-pad i))
- (insert "yield")
- (when (js2-yield-node-star-p n)
- (insert "*"))
- (when (js2-yield-node-value n)
- (insert " ")
- (js2-print-ast (js2-yield-node-value n) 0)))
-
-(cl-defstruct (js2-paren-node
- (:include js2-node)
- (:constructor make-js2-paren-node (&key (type js2-LP)
- (pos js2-ts-cursor)
- len expr)))
- "AST node for a parenthesized expression.
-In particular, used when the parens are syntactically optional,
-as opposed to required parens such as those enclosing an if-conditional."
- expr) ; `js2-node'
-
-(js2--struct-put 'js2-paren-node 'js2-visitor 'js2-visit-paren-node)
-(js2--struct-put 'js2-paren-node 'js2-printer 'js2-print-paren-node)
-
-(defun js2-visit-paren-node (n v)
- (js2-visit-ast (js2-paren-node-expr n) v))
-
-(defun js2-print-paren-node (n i)
- (insert (js2-make-pad i))
- (insert "(")
- (js2-print-ast (js2-paren-node-expr n) 0)
- (insert ")"))
-
-(cl-defstruct (js2-comp-node
- (:include js2-scope)
- (:constructor make-js2-comp-node (&key (type js2-ARRAYCOMP)
- (pos js2-ts-cursor)
- len result
- loops filters
- form)))
- "AST node for an Array comprehension such as [[x,y] for (x in foo) for (y in
bar)]."
- result ; result expression (just after left-bracket)
- loops ; a Lisp list of `js2-comp-loop-node'
- filters ; a Lisp list of guard/filter expressions
- form ; ARRAY, LEGACY_ARRAY or STAR_GENERATOR
- ; SpiderMonkey also supports "legacy generator expressions", but we
dont.
- )
-
-(js2--struct-put 'js2-comp-node 'js2-visitor 'js2-visit-comp-node)
-(js2--struct-put 'js2-comp-node 'js2-printer 'js2-print-comp-node)
-
-(defun js2-visit-comp-node (n v)
- (js2-visit-ast (js2-comp-node-result n) v)
- (dolist (l (js2-comp-node-loops n))
- (js2-visit-ast l v))
- (dolist (f (js2-comp-node-filters n))
- (js2-visit-ast f v)))
-
-(defun js2-print-comp-node (n i)
- (let ((pad (js2-make-pad i))
- (result (js2-comp-node-result n))
- (loops (js2-comp-node-loops n))
- (filters (js2-comp-node-filters n))
- (legacy-p (eq (js2-comp-node-form n) 'LEGACY_ARRAY))
- (gen-p (eq (js2-comp-node-form n) 'STAR_GENERATOR)))
- (insert pad (if gen-p "(" "["))
- (when legacy-p
- (js2-print-ast result 0))
- (dolist (l loops)
- (when legacy-p
- (insert " "))
- (js2-print-ast l 0)
- (unless legacy-p
- (insert " ")))
- (dolist (f filters)
- (when legacy-p
- (insert " "))
- (insert "if (")
- (js2-print-ast f 0)
- (insert ")")
- (unless legacy-p
- (insert " ")))
- (unless legacy-p
- (js2-print-ast result 0))
- (insert (if gen-p ")" "]"))))
-
-(cl-defstruct (js2-comp-loop-node
- (:include js2-for-in-node)
- (:constructor make-js2-comp-loop-node (&key (type js2-FOR)
- (pos js2-ts-cursor)
- len iterator
- object in-pos
- foreach-p
- each-pos
- forof-p
- lp rp)))
- "AST subtree for each 'for (foo in bar)' loop in an array comprehension.")
-
-(js2--struct-put 'js2-comp-loop-node 'js2-visitor 'js2-visit-comp-loop)
-(js2--struct-put 'js2-comp-loop-node 'js2-printer 'js2-print-comp-loop)
-
-(defun js2-visit-comp-loop (n v)
- (js2-visit-ast (js2-comp-loop-node-iterator n) v)
- (js2-visit-ast (js2-comp-loop-node-object n) v))
-
-(defun js2-print-comp-loop (n _i)
- (insert "for ")
- (when (js2-comp-loop-node-foreach-p n) (insert "each "))
- (insert "(")
- (js2-print-ast (js2-comp-loop-node-iterator n) 0)
- (insert (if (js2-comp-loop-node-forof-p n)
- " of " " in "))
- (js2-print-ast (js2-comp-loop-node-object n) 0)
- (insert ")"))
-
-(cl-defstruct (js2-empty-expr-node
- (:include js2-node)
- (:constructor make-js2-empty-expr-node (&key (type js2-EMPTY)
- (pos
(js2-current-token-beg))
- len)))
- "AST node for an empty expression.")
-
-(js2--struct-put 'js2-empty-expr-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-empty-expr-node 'js2-printer 'js2-print-none)
-
-(cl-defstruct (js2-xml-node
- (:include js2-block-node)
- (:constructor make-js2-xml-node (&key (type js2-XML)
- (pos
(js2-current-token-beg))
- len kids)))
- "AST node for initial parse of E4X literals.
-The kids field is a list of XML fragments, each a `js2-string-node' or
-a `js2-xml-js-expr-node'. Equivalent to Rhino's XmlLiteral node.")
-
-(js2--struct-put 'js2-xml-node 'js2-visitor 'js2-visit-block)
-(js2--struct-put 'js2-xml-node 'js2-printer 'js2-print-xml-node)
-
-(defun js2-print-xml-node (n i)
- (dolist (kid (js2-xml-node-kids n))
- (js2-print-ast kid i)))
-
-(cl-defstruct (js2-xml-js-expr-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-js-expr-node (&key (type js2-XML)
- (pos
js2-ts-cursor)
- len expr)))
- "AST node for an embedded JavaScript {expression} in an E4X literal.
-The start and end fields correspond to the curly-braces."
- expr) ; a `js2-expr-node' of some sort
-
-(js2--struct-put 'js2-xml-js-expr-node 'js2-visitor 'js2-visit-xml-js-expr)
-(js2--struct-put 'js2-xml-js-expr-node 'js2-printer 'js2-print-xml-js-expr)
-
-(defun js2-visit-xml-js-expr (n v)
- (js2-visit-ast (js2-xml-js-expr-node-expr n) v))
-
-(defun js2-print-xml-js-expr (n i)
- (insert (js2-make-pad i))
- (insert "{")
- (js2-print-ast (js2-xml-js-expr-node-expr n) 0)
- (insert "}"))
-
-(cl-defstruct (js2-xml-dot-query-node
- (:include js2-infix-node)
- (:constructor make-js2-xml-dot-query-node (&key (type
js2-DOTQUERY)
- (pos
js2-ts-cursor)
- op-pos len left
- right rp)))
- "AST node for an E4X foo.(bar) filter expression.
-Note that the left-paren is automatically the character immediately
-following the dot (.) in the operator. No whitespace is permitted
-between the dot and the lp by the scanner."
- rp)
-
-(js2--struct-put 'js2-xml-dot-query-node 'js2-visitor 'js2-visit-infix-node)
-(js2--struct-put 'js2-xml-dot-query-node 'js2-printer 'js2-print-xml-dot-query)
-
-(defun js2-print-xml-dot-query (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-xml-dot-query-node-left n) 0)
- (insert ".(")
- (js2-print-ast (js2-xml-dot-query-node-right n) 0)
- (insert ")"))
-
-(cl-defstruct (js2-xml-ref-node
- (:include js2-node)
- (:constructor nil)) ; abstract
- "Base type for E4X XML attribute-access or property-get expressions.
-Such expressions can take a variety of forms. The general syntax has
-three parts:
-
- - (optional) an @ (specifying an attribute access)
- - (optional) a namespace (a `js2-name-node') and double-colon
- - (required) either a `js2-name-node' or a bracketed [expression]
-
-The property-name expressions (examples: ns::name, @name) are
-represented as `js2-xml-prop-ref' nodes. The bracketed-expression
-versions (examples: ns::[name], @[name]) become `js2-xml-elem-ref' nodes.
-
-This node type (or more specifically, its subclasses) will sometimes
-be the right-hand child of a `js2-prop-get-node' or a
-`js2-infix-node' of type `js2-DOTDOT', the .. xml-descendants operator.
-The `js2-xml-ref-node' may also be a standalone primary expression with
-no explicit target, which is valid in certain expression contexts such as
-
- company..employee.(@id < 100)
-
-in this case, the @id is a `js2-xml-ref' that is part of an infix `<'
-expression whose parent is a `js2-xml-dot-query-node'."
- namespace
- at-pos
- colon-pos)
-
-(defsubst js2-xml-ref-node-attr-access-p (node)
- "Return non-nil if this expression began with an @-token."
- (and (numberp (js2-xml-ref-node-at-pos node))
- (cl-plusp (js2-xml-ref-node-at-pos node))))
-
-(cl-defstruct (js2-xml-prop-ref-node
- (:include js2-xml-ref-node)
- (:constructor make-js2-xml-prop-ref-node (&key (type
js2-REF_NAME)
- (pos
(js2-current-token-beg))
- len propname
- namespace at-pos
- colon-pos)))
- "AST node for an E4X XML [expr] property-ref expression.
-The JavaScript syntax is an optional @, an optional ns::, and a name.
-
- [ `@' ] [ name `::' ] name
-
-Examples include name, ns::name, ns::*, *::name, *::*, @attr, @ns::attr,
-@ns::*, @*::attr, @*::*, and @*.
-
-The node starts at the @ token, if present. Otherwise it starts at the
-namespace name. The node bounds extend through the closing right-bracket,
-or if it is missing due to a syntax error, through the end of the index
-expression."
- propname)
-
-(js2--struct-put 'js2-xml-prop-ref-node 'js2-visitor
'js2-visit-xml-prop-ref-node)
-(js2--struct-put 'js2-xml-prop-ref-node 'js2-printer
'js2-print-xml-prop-ref-node)
-
-(defun js2-visit-xml-prop-ref-node (n v)
- (js2-visit-ast (js2-xml-prop-ref-node-namespace n) v)
- (js2-visit-ast (js2-xml-prop-ref-node-propname n) v))
-
-(defun js2-print-xml-prop-ref-node (n i)
- (insert (js2-make-pad i))
- (if (js2-xml-ref-node-attr-access-p n)
- (insert "@"))
- (when (js2-xml-prop-ref-node-namespace n)
- (js2-print-ast (js2-xml-prop-ref-node-namespace n) 0)
- (insert "::"))
- (if (js2-xml-prop-ref-node-propname n)
- (js2-print-ast (js2-xml-prop-ref-node-propname n) 0)))
-
-(cl-defstruct (js2-xml-elem-ref-node
- (:include js2-xml-ref-node)
- (:constructor make-js2-xml-elem-ref-node (&key (type
js2-REF_MEMBER)
- (pos
(js2-current-token-beg))
- len expr lb rb
- namespace at-pos
- colon-pos)))
- "AST node for an E4X XML [expr] member-ref expression.
-Syntax:
-
- [ `@' ] [ name `::' ] `[' expr `]'
-
-Examples include ns::[expr], @ns::[expr], @[expr], *::[expr] and @*::[expr].
-
-Note that the form [expr] (i.e. no namespace or attribute-qualifier)
-is not a legal E4X XML element-ref expression, since it's already used
-for standard JavaScript element-get array indexing. Hence, a
-`js2-xml-elem-ref-node' always has either the attribute-qualifier, a
-non-nil namespace node, or both.
-
-The node starts at the @ token, if present. Otherwise it starts
-at the namespace name. The node bounds extend through the closing
-right-bracket, or if it is missing due to a syntax error, through the
-end of the index expression."
- expr ; the bracketed index expression
- lb
- rb)
-
-(js2--struct-put 'js2-xml-elem-ref-node 'js2-visitor
'js2-visit-xml-elem-ref-node)
-(js2--struct-put 'js2-xml-elem-ref-node 'js2-printer
'js2-print-xml-elem-ref-node)
-
-(defun js2-visit-xml-elem-ref-node (n v)
- (js2-visit-ast (js2-xml-elem-ref-node-namespace n) v)
- (js2-visit-ast (js2-xml-elem-ref-node-expr n) v))
-
-(defun js2-print-xml-elem-ref-node (n i)
- (insert (js2-make-pad i))
- (if (js2-xml-ref-node-attr-access-p n)
- (insert "@"))
- (when (js2-xml-elem-ref-node-namespace n)
- (js2-print-ast (js2-xml-elem-ref-node-namespace n) 0)
- (insert "::"))
- (insert "[")
- (if (js2-xml-elem-ref-node-expr n)
- (js2-print-ast (js2-xml-elem-ref-node-expr n) 0))
- (insert "]"))
-
-;;; Placeholder nodes for when we try parsing the XML literals structurally.
-
-(cl-defstruct (js2-xml-start-tag-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-start-tag-node (&key (type js2-XML)
- (pos
js2-ts-cursor)
- len name attrs
kids
- empty-p)))
- "AST node for an XML start-tag. Not currently used.
-The `kids' field is a Lisp list of child content nodes."
- name ; a `js2-xml-name-node'
- attrs ; a Lisp list of `js2-xml-attr-node'
- empty-p) ; t if this is an empty element such as <foo bar="baz"/>
-
-(js2--struct-put 'js2-xml-start-tag-node 'js2-visitor 'js2-visit-xml-start-tag)
-(js2--struct-put 'js2-xml-start-tag-node 'js2-printer 'js2-print-xml-start-tag)
-
-(defun js2-visit-xml-start-tag (n v)
- (js2-visit-ast (js2-xml-start-tag-node-name n) v)
- (dolist (attr (js2-xml-start-tag-node-attrs n))
- (js2-visit-ast attr v))
- (js2-visit-block n v))
-
-(defun js2-print-xml-start-tag (n i)
- (insert (js2-make-pad i) "<")
- (js2-print-ast (js2-xml-start-tag-node-name n) 0)
- (when (js2-xml-start-tag-node-attrs n)
- (insert " ")
- (js2-print-list (js2-xml-start-tag-node-attrs n) " "))
- (insert ">"))
-
-;; I -think- I'm going to make the parent node the corresponding start-tag,
-;; and add the end-tag to the kids list of the parent as well.
-(cl-defstruct (js2-xml-end-tag-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-end-tag-node (&key (type js2-XML)
- (pos
js2-ts-cursor)
- len name)))
- "AST node for an XML end-tag. Not currently used."
- name) ; a `js2-xml-name-node'
-
-(js2--struct-put 'js2-xml-end-tag-node 'js2-visitor 'js2-visit-xml-end-tag)
-(js2--struct-put 'js2-xml-end-tag-node 'js2-printer 'js2-print-xml-end-tag)
-
-(defun js2-visit-xml-end-tag (n v)
- (js2-visit-ast (js2-xml-end-tag-node-name n) v))
-
-(defun js2-print-xml-end-tag (n i)
- (insert (js2-make-pad i))
- (insert "</")
- (js2-print-ast (js2-xml-end-tag-node-name n) 0)
- (insert ">"))
-
-(cl-defstruct (js2-xml-name-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-name-node (&key (type js2-XML)
- (pos js2-ts-cursor)
- len namespace kids)))
- "AST node for an E4X XML name. Not currently used.
-Any XML name can be qualified with a namespace, hence the namespace field.
-Further, any E4X name can be comprised of arbitrary JavaScript {} expressions.
-The kids field is a list of `js2-name-node' and `js2-xml-js-expr-node'.
-For a simple name, the kids list has exactly one node, a `js2-name-node'."
- namespace) ; a `js2-string-node'
-
-(js2--struct-put 'js2-xml-name-node 'js2-visitor 'js2-visit-xml-name-node)
-(js2--struct-put 'js2-xml-name-node 'js2-printer 'js2-print-xml-name-node)
-
-(defun js2-visit-xml-name-node (n v)
- (js2-visit-ast (js2-xml-name-node-namespace n) v))
-
-(defun js2-print-xml-name-node (n i)
- (insert (js2-make-pad i))
- (when (js2-xml-name-node-namespace n)
- (js2-print-ast (js2-xml-name-node-namespace n) 0)
- (insert "::"))
- (dolist (kid (js2-xml-name-node-kids n))
- (js2-print-ast kid 0)))
-
-(cl-defstruct (js2-xml-pi-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-pi-node (&key (type js2-XML)
- (pos js2-ts-cursor)
- len name attrs)))
- "AST node for an E4X XML processing instruction. Not currently used."
- name ; a `js2-xml-name-node'
- attrs) ; a list of `js2-xml-attr-node'
-
-(js2--struct-put 'js2-xml-pi-node 'js2-visitor 'js2-visit-xml-pi-node)
-(js2--struct-put 'js2-xml-pi-node 'js2-printer 'js2-print-xml-pi-node)
-
-(defun js2-visit-xml-pi-node (n v)
- (js2-visit-ast (js2-xml-pi-node-name n) v)
- (dolist (attr (js2-xml-pi-node-attrs n))
- (js2-visit-ast attr v)))
-
-(defun js2-print-xml-pi-node (n i)
- (insert (js2-make-pad i) "<?")
- (js2-print-ast (js2-xml-pi-node-name n))
- (when (js2-xml-pi-node-attrs n)
- (insert " ")
- (js2-print-list (js2-xml-pi-node-attrs n)))
- (insert "?>"))
-
-(cl-defstruct (js2-xml-cdata-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-cdata-node (&key (type js2-XML)
- (pos js2-ts-cursor)
- len content)))
- "AST node for a CDATA escape section. Not currently used."
- content) ; a `js2-string-node' with node-property 'quote-type 'cdata
-
-(js2--struct-put 'js2-xml-cdata-node 'js2-visitor 'js2-visit-xml-cdata-node)
-(js2--struct-put 'js2-xml-cdata-node 'js2-printer 'js2-print-xml-cdata-node)
-
-(defun js2-visit-xml-cdata-node (n v)
- (js2-visit-ast (js2-xml-cdata-node-content n) v))
-
-(defun js2-print-xml-cdata-node (n i)
- (insert (js2-make-pad i))
- (js2-print-ast (js2-xml-cdata-node-content n)))
-
-(cl-defstruct (js2-xml-attr-node
- (:include js2-xml-node)
- (:constructor make-js2-attr-node (&key (type js2-XML)
- (pos js2-ts-cursor)
- len name value
- eq-pos quote-type)))
- "AST node representing a foo=\\='bar\\=' XML attribute value. Not yet used."
- name ; a `js2-xml-name-node'
- value ; a `js2-xml-name-node'
- eq-pos ; buffer position of "=" sign
- quote-type) ; 'single or 'double
-
-(js2--struct-put 'js2-xml-attr-node 'js2-visitor 'js2-visit-xml-attr-node)
-(js2--struct-put 'js2-xml-attr-node 'js2-printer 'js2-print-xml-attr-node)
-
-(defun js2-visit-xml-attr-node (n v)
- (js2-visit-ast (js2-xml-attr-node-name n) v)
- (js2-visit-ast (js2-xml-attr-node-value n) v))
-
-(defun js2-print-xml-attr-node (n i)
- (let ((quote (if (eq (js2-xml-attr-node-quote-type n) 'single)
- "'"
- "\"")))
- (insert (js2-make-pad i))
- (js2-print-ast (js2-xml-attr-node-name n) 0)
- (insert "=" quote)
- (js2-print-ast (js2-xml-attr-node-value n) 0)
- (insert quote)))
-
-(cl-defstruct (js2-xml-text-node
- (:include js2-xml-node)
- (:constructor make-js2-text-node (&key (type js2-XML)
- (pos js2-ts-cursor)
- len content)))
- "AST node for an E4X XML text node. Not currently used."
- content) ; a Lisp list of `js2-string-node' and `js2-xml-js-expr-node'
-
-(js2--struct-put 'js2-xml-text-node 'js2-visitor 'js2-visit-xml-text-node)
-(js2--struct-put 'js2-xml-text-node 'js2-printer 'js2-print-xml-text-node)
-
-(defun js2-visit-xml-text-node (n v)
- (js2-visit-ast (js2-xml-text-node-content n) v))
-
-(defun js2-print-xml-text-node (n i)
- (insert (js2-make-pad i))
- (dolist (kid (js2-xml-text-node-content n))
- (js2-print-ast kid)))
-
-(cl-defstruct (js2-xml-comment-node
- (:include js2-xml-node)
- (:constructor make-js2-xml-comment-node (&key (type js2-XML)
- (pos
js2-ts-cursor)
- len)))
- "AST node for E4X XML comment. Not currently used.")
-
-(js2--struct-put 'js2-xml-comment-node 'js2-visitor 'js2-visit-none)
-(js2--struct-put 'js2-xml-comment-node 'js2-printer 'js2-print-xml-comment)
-
-(defun js2-print-xml-comment (n i)
- (insert (js2-make-pad i)
- (js2-node-string n)))
-
-;;; Node utilities
-
-(defsubst js2-node-line (n)
- "Fetch the source line number at the start of node N.
-This is O(n) in the length of the source buffer; use prudently."
- (1+ (count-lines (point-min) (js2-node-abs-pos n))))
-
-(defsubst js2-block-node-kid (n i)
- "Return child I of node N, or nil if there aren't that many."
- (nth i (js2-block-node-kids n)))
-
-(defsubst js2-block-node-first (n)
- "Return first child of block node N, or nil if there is none."
- (cl-first (js2-block-node-kids n)))
-
-(defun js2-node-root (n)
- "Return the root of the AST containing N.
-If N has no parent pointer, returns N."
- (let ((parent (js2-node-parent n)))
- (if parent
- (js2-node-root parent)
- n)))
-
-(defsubst js2-node-short-name (n)
- "Return the short name of node N as a string, e.g. `js2-if-node'."
- (let ((name (symbol-name (aref n 0))))
- (if (string-prefix-p "cl-struct-" name)
- (substring (symbol-name (aref n 0))
- (length "cl-struct-"))
- name)))
-
-(defun js2-node-child-list (node)
- "Return the child list for NODE, a Lisp list of nodes.
-Works for block nodes, array nodes, obj literals, funarg lists,
-var decls and try nodes (for catch clauses). Note that you should call
-`js2-block-node-kids' on the function body for the body statements.
-Returns nil for zero-length child lists or unsupported nodes."
- (cond
- ((js2-function-node-p node)
- (js2-function-node-params node))
- ((js2-block-node-p node)
- (js2-block-node-kids node))
- ((js2-try-node-p node)
- (js2-try-node-catch-clauses node))
- ((js2-array-node-p node)
- (js2-array-node-elems node))
- ((js2-object-node-p node)
- (js2-object-node-elems node))
- ((js2-call-node-p node)
- (js2-call-node-args node))
- ((js2-new-node-p node)
- (js2-new-node-args node))
- ((js2-var-decl-node-p node)
- (js2-var-decl-node-kids node))
- (t
- nil)))
-
-(defun js2-node-set-child-list (node kids)
- "Set the child list for NODE to KIDS."
- (cond
- ((js2-function-node-p node)
- (setf (js2-function-node-params node) kids))
- ((js2-block-node-p node)
- (setf (js2-block-node-kids node) kids))
- ((js2-try-node-p node)
- (setf (js2-try-node-catch-clauses node) kids))
- ((js2-array-node-p node)
- (setf (js2-array-node-elems node) kids))
- ((js2-object-node-p node)
- (setf (js2-object-node-elems node) kids))
- ((js2-call-node-p node)
- (setf (js2-call-node-args node) kids))
- ((js2-new-node-p node)
- (setf (js2-new-node-args node) kids))
- ((js2-var-decl-node-p node)
- (setf (js2-var-decl-node-kids node) kids))
- (t
- (error "Unsupported node type: %s" (js2-node-short-name node))))
- kids)
-
-;; All because Common Lisp doesn't support multiple inheritance for defstructs.
-(defconst js2-paren-expr-nodes
- '(cl-struct-js2-comp-loop-node
- cl-struct-js2-comp-node
- cl-struct-js2-call-node
- cl-struct-js2-catch-node
- cl-struct-js2-do-node
- cl-struct-js2-elem-get-node
- cl-struct-js2-for-in-node
- cl-struct-js2-for-node
- cl-struct-js2-function-node
- cl-struct-js2-if-node
- cl-struct-js2-let-node
- cl-struct-js2-new-node
- cl-struct-js2-paren-node
- cl-struct-js2-switch-node
- cl-struct-js2-while-node
- cl-struct-js2-with-node
- cl-struct-js2-xml-dot-query-node)
- "Node types that can have a parenthesized child expression.
-In particular, nodes that respond to `js2-node-lp' and `js2-node-rp'.")
-
-(defsubst js2-paren-expr-node-p (node)
- "Return t for nodes that typically have a parenthesized child expression.
-Useful for computing the indentation anchors for arg-lists and conditions.
-Note that it may return a false positive, for instance when NODE is
-a `js2-new-node' and there are no arguments or parentheses."
- (memq (aref node 0) js2-paren-expr-nodes))
-
-;; Fake polymorphism... yech.
-(defun js2-node-lp (node)
- "Return relative left-paren position for NODE, if applicable.
-For `js2-elem-get-node' structs, returns left-bracket position.
-Note that the position may be nil in the case of a parse error."
- (cond
- ((js2-elem-get-node-p node)
- (js2-elem-get-node-lb node))
- ((js2-loop-node-p node)
- (js2-loop-node-lp node))
- ((js2-function-node-p node)
- (js2-function-node-lp node))
- ((js2-if-node-p node)
- (js2-if-node-lp node))
- ((js2-new-node-p node)
- (js2-new-node-lp node))
- ((js2-call-node-p node)
- (js2-call-node-lp node))
- ((js2-paren-node-p node)
- 0)
- ((js2-switch-node-p node)
- (js2-switch-node-lp node))
- ((js2-catch-node-p node)
- (js2-catch-node-lp node))
- ((js2-let-node-p node)
- (js2-let-node-lp node))
- ((js2-comp-node-p node)
- 0)
- ((js2-with-node-p node)
- (js2-with-node-lp node))
- ((js2-xml-dot-query-node-p node)
- (1+ (js2-infix-node-op-pos node)))
- (t
- (error "Unsupported node type: %s" (js2-node-short-name node)))))
-
-;; Fake polymorphism... blech.
-(defun js2-node-rp (node)
- "Return relative right-paren position for NODE, if applicable.
-For `js2-elem-get-node' structs, returns right-bracket position.
-Note that the position may be nil in the case of a parse error."
- (cond
- ((js2-elem-get-node-p node)
- (js2-elem-get-node-rb node))
- ((js2-loop-node-p node)
- (js2-loop-node-rp node))
- ((js2-function-node-p node)
- (js2-function-node-rp node))
- ((js2-if-node-p node)
- (js2-if-node-rp node))
- ((js2-new-node-p node)
- (js2-new-node-rp node))
- ((js2-call-node-p node)
- (js2-call-node-rp node))
- ((js2-paren-node-p node)
- (1- (js2-node-len node)))
- ((js2-switch-node-p node)
- (js2-switch-node-rp node))
- ((js2-catch-node-p node)
- (js2-catch-node-rp node))
- ((js2-let-node-p node)
- (js2-let-node-rp node))
- ((js2-comp-node-p node)
- (1- (js2-node-len node)))
- ((js2-with-node-p node)
- (js2-with-node-rp node))
- ((js2-xml-dot-query-node-p node)
- (1+ (js2-xml-dot-query-node-rp node)))
- (t
- (error "Unsupported node type: %s" (js2-node-short-name node)))))
-
-(defsubst js2-node-first-child (node)
- "Return the first element of `js2-node-child-list' for NODE."
- (car (js2-node-child-list node)))
-
-(defsubst js2-node-last-child (node)
- "Return the last element of `js2-node-last-child' for NODE."
- (car (last (js2-node-child-list node))))
-
-(defun js2-node-prev-sibling (node)
- "Return the previous statement in parent.
-Works for parents supported by `js2-node-child-list'.
-Returns nil if NODE is not in the parent, or PARENT is
-not a supported node, or if NODE is the first child."
- (let* ((p (js2-node-parent node))
- (kids (js2-node-child-list p))
- (sib (car kids)))
- (while (and kids
- (not (eq node (cadr kids))))
- (setq kids (cdr kids)
- sib (car kids)))
- sib))
-
-(defun js2-node-next-sibling (node)
- "Return the next statement in parent block.
-Returns nil if NODE is not in the block, or PARENT is not
-a block node, or if NODE is the last statement."
- (let* ((p (js2-node-parent node))
- (kids (js2-node-child-list p)))
- (while (and kids
- (not (eq node (car kids))))
- (setq kids (cdr kids)))
- (cadr kids)))
-
-(defun js2-node-find-child-before (pos parent &optional after)
- "Find the last child that starts before POS in parent.
-If AFTER is non-nil, returns first child starting after POS.
-POS is an absolute buffer position. PARENT is any node
-supported by `js2-node-child-list'.
-Returns nil if no applicable child is found."
- (let ((kids (if (js2-function-node-p parent)
- (js2-block-node-kids (js2-function-node-body parent))
- (js2-node-child-list parent)))
- (beg (js2-node-abs-pos (if (js2-function-node-p parent)
- (js2-function-node-body parent)
- parent)))
- kid result fn
- (continue t))
- (setq fn (if after '>= '<))
- (while (and kids continue)
- (setq kid (car kids))
- (if (funcall fn (+ beg (js2-node-pos kid)) pos)
- (setq result kid
- continue (not after))
- (setq continue after))
- (setq kids (cdr kids)))
- result))
-
-(defun js2-node-find-child-after (pos parent)
- "Find first child that starts after POS in parent.
-POS is an absolute buffer position. PARENT is any node
-supported by `js2-node-child-list'.
-Returns nil if no applicable child is found."
- (js2-node-find-child-before pos parent 'after))
-
-(defun js2-node-replace-child (pos parent new-node)
- "Replace node at index POS in PARENT with NEW-NODE.
-Only works for parents supported by `js2-node-child-list'."
- (let ((kids (js2-node-child-list parent))
- (i 0))
- (while (< i pos)
- (setq kids (cdr kids)
- i (1+ i)))
- (setcar kids new-node)
- (js2-node-add-children parent new-node)))
-
-(defun js2-node-buffer (n)
- "Return the buffer associated with AST N.
-Returns nil if the buffer is not set as a property on the root
-node, or if parent links were not recorded during parsing."
- (let ((root (js2-node-root n)))
- (and root
- (js2-ast-root-p root)
- (js2-ast-root-buffer root))))
-
-(defun js2-block-node-push (n kid)
- "Push js2-node KID onto the end of js2-block-node N's child list.
-KID is always added to the -end- of the kids list.
-Function also calls `js2-node-add-children' to add the parent link."
- (let ((kids (js2-node-child-list n)))
- (if kids
- (setcdr kids (nconc (cdr kids) (list kid)))
- (js2-node-set-child-list n (list kid)))
- (js2-node-add-children n kid)))
-
-(defun js2-node-string (node)
- (with-current-buffer (or (js2-node-buffer node)
- (error "No buffer available for node %s" node))
- (let ((pos (js2-node-abs-pos node)))
- (buffer-substring-no-properties pos (+ pos (js2-node-len node))))))
-
-;; Container for storing the node we're looking for in a traversal.
-(js2-deflocal js2-discovered-node nil)
-
-;; Keep track of absolute node position during traversals.
-(js2-deflocal js2-visitor-offset nil)
-
-(js2-deflocal js2-node-search-point nil)
-
-(when js2-mode-dev-mode-p
- (defun js2-find-node-at-point ()
- (interactive)
- (let ((node (js2-node-at-point)))
- (message "%s" (or node "No node found at point"))))
- (defun js2-node-name-at-point ()
- (interactive)
- (let ((node (js2-node-at-point)))
- (message "%s" (if node
- (js2-node-short-name node)
- "No node found at point.")))))
-
-(defun js2-node-at-point (&optional pos skip-comments)
- "Return AST node at POS, a buffer position, defaulting to current point.
-The `js2-mode-ast' variable must be set to the current parse tree.
-Signals an error if the AST (`js2-mode-ast') is nil.
-Always returns a node - if it can't find one, it returns the root.
-If SKIP-COMMENTS is non-nil, comment nodes are ignored."
- (let ((ast js2-mode-ast)
- result)
- (unless ast
- (error "No JavaScript AST available"))
- ;; Look through comments first, since they may be inside nodes that
- ;; would otherwise report a match.
- (setq pos (or pos (point))
- result (if (> pos (js2-node-abs-end ast))
- ast
- (if (not skip-comments)
- (js2-comment-at-point pos))))
- (unless result
- (setq js2-discovered-node nil
- js2-visitor-offset 0
- js2-node-search-point pos)
- (unwind-protect
- (catch 'js2-visit-done
- (js2-visit-ast ast #'js2-node-at-point-visitor))
- (setq js2-visitor-offset nil
- js2-node-search-point nil))
- (setq result js2-discovered-node))
- ;; may have found a comment beyond end of last child node,
- ;; since visiting the ast-root looks at the comment-list last.
- (if (and skip-comments
- (js2-comment-node-p result))
- (setq result nil))
- (or result js2-mode-ast)))
-
-(defun js2-node-at-point-visitor (node end-p)
- (let ((rel-pos (js2-node-pos node))
- abs-pos
- abs-end
- (point js2-node-search-point))
- (cond
- (end-p
- ;; this evaluates to a non-nil return value, even if it's zero
- (cl-decf js2-visitor-offset rel-pos))
- ;; we already looked for comments before visiting, and don't want them now
- ((js2-comment-node-p node)
- nil)
- (t
- (setq abs-pos (cl-incf js2-visitor-offset rel-pos)
- ;; we only want to use the node if the point is before
- ;; the last character position in the node, so we decrement
- ;; the absolute end by 1.
- abs-end (+ abs-pos (js2-node-len node) -1))
- (cond
- ;; If this node starts after search-point, stop the search.
- ((> abs-pos point)
- (throw 'js2-visit-done nil))
- ;; If this node ends before the search-point, don't check kids.
- ((> point abs-end)
- nil)
- (t
- ;; Otherwise point is within this node, possibly in a child.
- (setq js2-discovered-node node)
- t)))))) ; keep processing kids to look for more specific match
-
-(defsubst js2-block-comment-p (node)
- "Return non-nil if NODE is a comment node of format `jsdoc' or `block'."
- (and (js2-comment-node-p node)
- (memq (js2-comment-node-format node) '(jsdoc block))))
-
-;; TODO: put the comments in a vector and binary-search them instead
-(defun js2-comment-at-point (&optional pos)
- "Look through scanned comment nodes for one containing POS.
-POS is a buffer position that defaults to current point.
-Function returns nil if POS was not in any comment node."
- (let ((ast js2-mode-ast)
- (x (or pos (point)))
- beg end)
- (unless ast
- (error "No JavaScript AST available"))
- (catch 'done
- ;; Comments are stored in lexical order.
- (dolist (comment (js2-ast-root-comments ast) nil)
- (setq beg (js2-node-abs-pos comment)
- end (+ beg (js2-node-len comment)))
- (if (and (>= x beg)
- (<= x end))
- (throw 'done comment))))))
-
-(defun js2-comments-between (start end comments-list)
- "Return comment nodes between START and END, nil if not found.
-START and END are absolute positions in current buffer.
-COMMENTS-LIST is the comments list to check."
- (let (comments c-start c-end)
- (nreverse
- (dolist (comment comments-list comments)
- (setq c-start (js2-node-abs-pos comment)
- c-end (1- (+ c-start (js2-node-len comment))))
- (unless (or (< c-end start)
- (> c-start end))
- (push comment comments))))))
-
-(defun js2-mode-find-parent-fn (node)
- "Find function enclosing NODE.
-Returns nil if NODE is not inside a function."
- (setq node (js2-node-parent node))
- (while (and node (not (js2-function-node-p node)))
- (setq node (js2-node-parent node)))
- (and (js2-function-node-p node) node))
-
-(defun js2-mode-find-enclosing-fn (node)
- "Find function or root enclosing NODE."
- (if (js2-ast-root-p node)
- node
- (setq node (js2-node-parent node))
- (while (not (or (js2-ast-root-p node)
- (js2-function-node-p node)))
- (setq node (js2-node-parent node)))
- node))
-
- (defun js2-mode-find-enclosing-node (beg end)
- "Find node fully enclosing BEG and END."
- (let ((node (js2-node-at-point beg))
- pos
- (continue t))
- (while continue
- (if (or (js2-ast-root-p node)
- (and
- (<= (setq pos (js2-node-abs-pos node)) beg)
- (>= (+ pos (js2-node-len node)) end)))
- (setq continue nil)
- (setq node (js2-node-parent node))))
- node))
-
-(defun js2-node-parent-script-or-fn (node)
- "Find script or function immediately enclosing NODE.
-If NODE is the ast-root, returns nil."
- (if (js2-ast-root-p node)
- nil
- (setq node (js2-node-parent node))
- (while (and node (not (or (js2-function-node-p node)
- (js2-script-node-p node))))
- (setq node (js2-node-parent node)))
- node))
-
-(defun js2-node-is-descendant (node ancestor)
- "Return t if NODE is a descendant of ANCESTOR."
- (while (and node
- (not (eq node ancestor)))
- (setq node (js2-node-parent node)))
- node)
-
-;;; visitor infrastructure
-
-(defun js2-visit-none (_node _callback)
- "Visitor for AST node that have no node children."
- nil)
-
-(defun js2-print-none (_node _indent)
- "Visitor for AST node with no printed representation.")
-
-(defun js2-print-body (node indent)
- "Print a statement, or a block without braces."
- (if (js2-block-node-p node)
- (dolist (kid (js2-block-node-kids node))
- (js2-print-ast kid indent))
- (js2-print-ast node indent)))
-
-(defun js2-print-list (args &optional delimiter)
- (cl-loop with len = (length args)
- for arg in args
- for count from 1
- do
- (when arg (js2-print-ast arg 0))
- (if (< count len)
- (insert (or delimiter ", ")))))
-
-(defun js2-print-tree (ast)
- "Prints an AST to the current buffer.
-Makes `js2-ast-parent-nodes' available to the printer functions."
- (let ((max-lisp-eval-depth (max max-lisp-eval-depth 1500)))
- (js2-print-ast ast)))
-
-(defun js2-print-ast (node &optional indent)
- "Helper function for printing AST nodes.
-Requires `js2-ast-parent-nodes' to be non-nil.
-You should use `js2-print-tree' instead of this function."
- (let ((printer (get (aref node 0) 'js2-printer))
- (i (or indent 0)))
- ;; TODO: wedge comments in here somewhere
- (if printer
- (funcall printer node i))))
-
-(defconst js2-side-effecting-tokens
- (let ((tokens (make-bool-vector js2-num-tokens nil)))
- (dolist (tt (list js2-ASSIGN
- js2-ASSIGN_ADD
- js2-ASSIGN_BITAND
- js2-ASSIGN_BITOR
- js2-ASSIGN_BITXOR
- js2-ASSIGN_DIV
- js2-ASSIGN_LSH
- js2-ASSIGN_MOD
- js2-ASSIGN_MUL
- js2-ASSIGN_RSH
- js2-ASSIGN_SUB
- js2-ASSIGN_URSH
- js2-ASSIGN_EXPON
- js2-BLOCK
- js2-BREAK
- js2-CALL
- js2-CATCH
- js2-CATCH_SCOPE
- js2-CLASS
- js2-CONST
- js2-CONTINUE
- js2-DEBUGGER
- js2-DEC
- js2-DELPROP
- js2-DEL_REF
- js2-DO
- js2-ELSE
- js2-EMPTY
- js2-ENTERWITH
- js2-EXPORT
- js2-EXPR_RESULT
- js2-FINALLY
- js2-FOR
- js2-FUNCTION
- js2-GOTO
- js2-IF
- js2-IFEQ
- js2-IFNE
- js2-IMPORT
- js2-INC
- js2-JSR
- js2-LABEL
- js2-LEAVEWITH
- js2-LET
- js2-LETEXPR
- js2-LOCAL_BLOCK
- js2-LOOP
- js2-NEW
- js2-REF_CALL
- js2-RETHROW
- js2-RETURN
- js2-RETURN_RESULT
- js2-SEMI
- js2-SETELEM
- js2-SETELEM_OP
- js2-SETNAME
- js2-SETPROP
- js2-SETPROP_OP
- js2-SETVAR
- js2-SET_REF
- js2-SET_REF_OP
- js2-SWITCH
- js2-TARGET
- js2-THROW
- js2-TRY
- js2-VAR
- js2-WHILE
- js2-WITH
- js2-WITHEXPR
- js2-YIELD))
- (aset tokens tt t))
- tokens))
-
-(defun js2-node-has-side-effects (node)
- "Return t if NODE has side effects."
- (when node ; makes it easier to handle malformed expressions
- (let ((tt (js2-node-type node)))
- (cond
- ;; This doubtless needs some work, since EXPR_VOID is used
- ;; in several ways in Rhino and I may not have caught them all.
- ;; I'll wait for people to notice incorrect warnings.
- ((and (= tt js2-EXPR_VOID)
- (js2-expr-stmt-node-p node)) ; but not if EXPR_RESULT
- (let ((expr (js2-expr-stmt-node-expr node)))
- (or (js2-node-has-side-effects expr)
- (when (js2-string-node-p expr)
- (member (js2-string-node-value expr) '("use strict" "use
asm"))))))
- ((= tt js2-AWAIT) t)
- ((= tt js2-COMMA)
- (js2-node-has-side-effects (js2-infix-node-right node)))
- ((or (= tt js2-AND)
- (= tt js2-OR))
- (or (js2-node-has-side-effects (js2-infix-node-right node))
- (js2-node-has-side-effects (js2-infix-node-left node))))
- ((= tt js2-HOOK)
- (and (js2-node-has-side-effects (js2-cond-node-true-expr node))
- (js2-node-has-side-effects (js2-cond-node-false-expr node))))
- ((js2-paren-node-p node)
- (js2-node-has-side-effects (js2-paren-node-expr node)))
- ((= tt js2-ERROR) ; avoid cascaded error messages
- nil)
- ((or (and js2-instanceof-has-side-effects (= tt js2-INSTANCEOF))
- (and js2-getprop-has-side-effects (= tt js2-GETPROP)))
- t)
- (t
- (aref js2-side-effecting-tokens tt))))))
-
-(defconst js2-stmt-node-types
- (list js2-BLOCK
- js2-BREAK
- js2-CONTINUE
- js2-DEFAULT ; e4x "default xml namespace" statement
- js2-DO
- js2-EXPORT
- js2-EXPR_RESULT
- js2-EXPR_VOID
- js2-FOR
- js2-IF
- js2-IMPORT
- js2-RETURN
- js2-SWITCH
- js2-THROW
- js2-TRY
- js2-WHILE
- js2-WITH)
- "Node types that only appear in statement contexts.
-The list does not include nodes that always appear as the child
-of another specific statement type, such as switch-cases,
-catch and finally blocks, and else-clauses. The list also excludes
-nodes like yield, let and var, which may appear in either expression
-or statement context, and in the latter context always have a
-`js2-expr-stmt-node' parent. Finally, the list does not include
-functions or scripts, which are treated separately from statements
-by the JavaScript parser and runtime.")
-
-(defun js2-stmt-node-p (node)
- "Heuristic for figuring out if NODE is a statement.
-Some node types can appear in either an expression context or a
-statement context, e.g. let-nodes, yield-nodes, and var-decl nodes.
-For these node types in a statement context, the parent will be a
-`js2-expr-stmt-node'.
-Functions aren't included in the check."
- (memq (js2-node-type node) js2-stmt-node-types))
-
-(defun js2-mode-find-first-stmt (node)
- "Search upward starting from NODE looking for a statement.
-For purposes of this function, a `js2-function-node' counts."
- (while (not (or (js2-stmt-node-p node)
- (js2-function-node-p node)))
- (setq node (js2-node-parent node)))
- node)
-
-(defun js2-node-parent-stmt (node)
- "Return the node's first ancestor that is a statement.
-Returns nil if NODE is a `js2-ast-root'. Note that any expression
-appearing in a statement context will have a parent that is a
-`js2-expr-stmt-node' that will be returned by this function."
- (let ((parent (js2-node-parent node)))
- (if (or (null parent)
- (js2-stmt-node-p parent)
- (and (js2-function-node-p parent)
- (eq (js2-function-node-form parent) 'FUNCTION_STATEMENT)))
- parent
- (js2-node-parent-stmt parent))))
-
-;; In the Mozilla Rhino sources, Roshan James writes:
-;; Does consistent-return analysis on the function body when strict mode is
-;; enabled.
-;;
-;; function (x) { return (x+1) }
-;;
-;; is ok, but
-;;
-;; function (x) { if (x < 0) return (x+1); }
-;;
-;; is not because the function can potentially return a value when the
-;; condition is satisfied and if not, the function does not explicitly
-;; return a value.
-;;
-;; This extends to checking mismatches such as "return" and "return <value>"
-;; used in the same function. Warnings are not emitted if inconsistent
-;; returns exist in code that can be statically shown to be unreachable.
-;; Ex.
-;; function (x) { while (true) { ... if (..) { return value } ... } }
-;;
-;; emits no warning. However if the loop had a break statement, then a
-;; warning would be emitted.
-;;
-;; The consistency analysis looks at control structures such as loops, ifs,
-;; switch, try-catch-finally blocks, examines the reachable code paths and
-;; warns the user about an inconsistent set of termination possibilities.
-;;
-;; These flags enumerate the possible ways a statement/function can
-;; terminate. These flags are used by endCheck() and by the Parser to
-;; detect inconsistent return usage.
-;;
-;; END_UNREACHED is reserved for code paths that are assumed to always be
-;; able to execute (example: throw, continue)
-;;
-;; END_DROPS_OFF indicates if the statement can transfer control to the
-;; next one. Statement such as return dont. A compound statement may have
-;; some branch that drops off control to the next statement.
-;;
-;; END_RETURNS indicates that the statement can return with no value.
-;; END_RETURNS_VALUE indicates that the statement can return a value.
-;;
-;; A compound statement such as
-;; if (condition) {
-;; return value;
-;; }
-;; Will be detected as (END_DROPS_OFF | END_RETURN_VALUE) by endCheck()
-
-(defconst js2-END_UNREACHED 0)
-(defconst js2-END_DROPS_OFF 1)
-(defconst js2-END_RETURNS 2)
-(defconst js2-END_RETURNS_VALUE 4)
-(defconst js2-END_YIELDS 8)
-
-(defun js2-has-consistent-return-usage (node)
- "Check that every return usage in a function body is consistent.
-Returns t if the function satisfies strict mode requirement."
- (let ((n (js2-end-check node)))
- ;; either it doesn't return a value in any branch...
- (or (js2-flag-not-set-p n js2-END_RETURNS_VALUE)
- ;; or it returns a value (or is unreached) at every branch
- (js2-flag-not-set-p n (logior js2-END_DROPS_OFF
- js2-END_RETURNS
- js2-END_YIELDS)))))
-
-(defun js2-end-check-if (node)
- "Ensure that return usage in then/else blocks is consistent.
-If there is no else block, then the return statement can fall through.
-Returns logical OR of END_* flags"
- (let ((th (js2-if-node-then-part node))
- (el (js2-if-node-else-part node)))
- (if (null th)
- js2-END_UNREACHED
- (logior (js2-end-check th) (if el
- (js2-end-check el)
- js2-END_DROPS_OFF)))))
-
-(defun js2-end-check-switch (node)
- "Consistency of return statements is checked between the case statements.
-If there is no default, then the switch can fall through. If there is a
-default, we check to see if all code paths in the default return or if
-there is a code path that can fall through.
-Returns logical OR of END_* flags."
- (let ((rv js2-END_UNREACHED)
- default-case)
- ;; examine the cases
- (catch 'break
- (dolist (c (js2-switch-node-cases node))
- (if (js2-case-node-expr c)
- (js2-set-flag rv (js2-end-check-block c))
- (setq default-case c)
- (throw 'break nil))))
- ;; we don't care how the cases drop into each other
- (js2-clear-flag rv js2-END_DROPS_OFF)
- ;; examine the default
- (js2-set-flag rv (if default-case
- (js2-end-check default-case)
- js2-END_DROPS_OFF))
- rv))
-
-(defun js2-end-check-try (node)
- "If the block has a finally, return consistency is checked in the
-finally block. If all code paths in the finally return, then the
-returns in the try-catch blocks don't matter. If there is a code path
-that does not return or if there is no finally block, the returns
-of the try and catch blocks are checked for mismatch.
-Returns logical OR of END_* flags."
- (let ((finally (js2-try-node-finally-block node))
- rv)
- ;; check the finally if it exists
- (setq rv (if finally
- (js2-end-check (js2-finally-node-body finally))
- js2-END_DROPS_OFF))
- ;; If the finally block always returns, then none of the returns
- ;; in the try or catch blocks matter.
- (when (js2-flag-set-p rv js2-END_DROPS_OFF)
- (js2-clear-flag rv js2-END_DROPS_OFF)
- ;; examine the try block
- (js2-set-flag rv (js2-end-check (js2-try-node-try-block node)))
- ;; check each catch block
- (dolist (cb (js2-try-node-catch-clauses node))
- (js2-set-flag rv (js2-end-check cb))))
- rv))
-
-(defun js2-end-check-loop (node)
- "Return statement in the loop body must be consistent.
-The default assumption for any kind of a loop is that it will eventually
-terminate. The only exception is a loop with a constant true condition.
-Code that follows such a loop is examined only if one can determine
-statically that there is a break out of the loop.
-
- for(... ; ... ; ...) {}
- for(... in ... ) {}
- while(...) { }
- do { } while(...)
-
-Returns logical OR of END_* flags."
- (let ((rv (js2-end-check (js2-loop-node-body node)))
- (condition (cond
- ((js2-while-node-p node)
- (js2-while-node-condition node))
- ((js2-do-node-p node)
- (js2-do-node-condition node))
- ((js2-for-node-p node)
- (js2-for-node-condition node)))))
-
- ;; check to see if the loop condition is always true
- (if (and condition
- (eq (js2-always-defined-boolean-p condition) 'ALWAYS_TRUE))
- (js2-clear-flag rv js2-END_DROPS_OFF))
-
- ;; look for effect of breaks
- (js2-set-flag rv (js2-node-get-prop node
- 'CONTROL_BLOCK_PROP
- js2-END_UNREACHED))
- rv))
-
-(defun js2-end-check-block (node)
- "A general block of code is examined statement by statement.
-If any statement (even a compound one) returns in all branches, then
-subsequent statements are not examined.
-Returns logical OR of END_* flags."
- (let* ((rv js2-END_DROPS_OFF)
- (kids (js2-block-node-kids node))
- (n (car kids)))
- ;; Check each statement. If the statement can continue onto the next
- ;; one (i.e. END_DROPS_OFF is set), then check the next statement.
- (while (and n (js2-flag-set-p rv js2-END_DROPS_OFF))
- (js2-clear-flag rv js2-END_DROPS_OFF)
- (js2-set-flag rv (js2-end-check n))
- (setq kids (cdr kids)
- n (car kids)))
- rv))
-
-(defun js2-end-check-label (node)
- "A labeled statement implies that there may be a break to the label.
-The function processes the labeled statement and then checks the
-CONTROL_BLOCK_PROP property to see if there is ever a break to the
-particular label.
-Returns logical OR of END_* flags."
- (let ((rv (js2-end-check (js2-labeled-stmt-node-stmt node))))
- (logior rv (js2-node-get-prop node
- 'CONTROL_BLOCK_PROP
- js2-END_UNREACHED))))
-
-(defun js2-end-check-break (node)
- "When a break is encountered annotate the statement being broken
-out of by setting its CONTROL_BLOCK_PROP property.
-Returns logical OR of END_* flags."
- (and (js2-break-node-target node)
- (js2-node-set-prop (js2-break-node-target node)
- 'CONTROL_BLOCK_PROP
- js2-END_DROPS_OFF))
- js2-END_UNREACHED)
-
-(defun js2-end-check (node)
- "Examine the body of a function, doing a basic reachability analysis.
-Returns a combination of flags END_* flags that indicate
-how the function execution can terminate. These constitute only the
-pessimistic set of termination conditions. It is possible that at
-runtime certain code paths will never be actually taken. Hence this
-analysis will flag errors in cases where there may not be errors.
-Returns logical OR of END_* flags"
- (let (kid)
- (cond
- ((js2-break-node-p node)
- (js2-end-check-break node))
- ((js2-expr-stmt-node-p node)
- (if (setq kid (js2-expr-stmt-node-expr node))
- (js2-end-check kid)
- js2-END_DROPS_OFF))
- ((or (js2-continue-node-p node)
- (js2-throw-node-p node))
- js2-END_UNREACHED)
- ((js2-return-node-p node)
- (if (setq kid (js2-return-node-retval node))
- js2-END_RETURNS_VALUE
- js2-END_RETURNS))
- ((js2-loop-node-p node)
- (js2-end-check-loop node))
- ((js2-switch-node-p node)
- (js2-end-check-switch node))
- ((js2-labeled-stmt-node-p node)
- (js2-end-check-label node))
- ((js2-if-node-p node)
- (js2-end-check-if node))
- ((js2-try-node-p node)
- (js2-end-check-try node))
- ((js2-block-node-p node)
- (if (null (js2-block-node-kids node))
- js2-END_DROPS_OFF
- (js2-end-check-block node)))
- ((js2-yield-node-p node)
- js2-END_YIELDS)
- (t
- js2-END_DROPS_OFF))))
-
-(defun js2-always-defined-boolean-p (node)
- "Check if NODE always evaluates to true or false in boolean context.
-Returns `ALWAYS_TRUE', `ALWAYS_FALSE', or nil if it's neither always true
-nor always false."
- (let ((tt (js2-node-type node))
- num)
- (cond
- ((or (= tt js2-FALSE) (= tt js2-NULL))
- 'ALWAYS_FALSE)
- ((= tt js2-TRUE)
- 'ALWAYS_TRUE)
- ((= tt js2-NUMBER)
- (setq num (js2-number-node-num-value node))
- (if (and (not (eq num 0.0e+NaN))
- (not (zerop num)))
- 'ALWAYS_TRUE
- 'ALWAYS_FALSE))
- (t
- nil))))
-
-;;; Scanner -- a port of Mozilla Rhino's lexer.
-;; Corresponds to Rhino files Token.java and TokenStream.java.
-
-(defvar js2-tokens nil
- "List of all defined token names.") ; initialized in `js2-token-names'
-
-(defconst js2-token-names
- (let* ((names (make-vector js2-num-tokens -1))
- (case-fold-search nil) ; only match js2-UPPER_CASE
- (syms (apropos-internal "^js2-\\(?:[[:upper:]_]+\\)")))
- (cl-loop for sym in syms
- for i from 0
- do
- (unless (or (memq sym '(js2-EOF_CHAR js2-ERROR))
- (not (boundp sym)))
- (aset names (symbol-value sym) ; code, e.g. 152
- (downcase
- (substring (symbol-name sym) 4))) ; name, e.g. "let"
- (push sym js2-tokens)))
- names)
- "Vector mapping int values to token string names, sans `js2-' prefix.")
-
-(defun js2-tt-name (tok)
- "Return a string name for TOK, a token symbol or code.
-Signals an error if it's not a recognized token."
- (let ((code tok))
- (if (symbolp tok)
- (setq code (symbol-value tok)))
- (if (eq code -1)
- "ERROR"
- (if (and (numberp code)
- (not (cl-minusp code))
- (< code js2-num-tokens))
- (aref js2-token-names code)
- (error "Invalid token: %s" code)))))
-
-(defsubst js2-tt-sym (tok)
- "Return symbol for TOK given its code, e.g. `js2-LP' for code 86."
- (intern (js2-tt-name tok)))
-
-(defconst js2-token-codes
- (let ((table (make-hash-table :test 'eq :size 256)))
- (cl-loop for name across js2-token-names
- for sym = (intern (concat "js2-" (upcase name)))
- do
- (puthash sym (symbol-value sym) table))
- ;; clean up a few that are "wrong" in Rhino's token codes
- (puthash 'js2-DELETE js2-DELPROP table)
- table)
- "Hashtable mapping token type symbols to their bytecodes.")
-
-(defsubst js2-tt-code (sym)
- "Return code for token symbol SYM, e.g. 86 for `js2-LP'."
- (or (gethash sym js2-token-codes)
- (error "Invalid token symbol: %s " sym))) ; signal code bug
-
-(defun js2-report-scan-error (msg &optional no-throw beg len)
- (setf (js2-token-end (js2-current-token)) js2-ts-cursor)
- (js2-report-error msg nil
- (or beg (js2-current-token-beg))
- (or len (js2-current-token-len)))
- (unless no-throw
- (throw 'return js2-ERROR)))
-
-(defun js2-set-string-from-buffer (token)
- "Set `string' and `end' slots for TOKEN, return the string."
- (setf (js2-token-end token) js2-ts-cursor
- (js2-token-string token) (js2-collect-string js2-ts-string-buffer)))
-
-;; TODO: could potentially avoid a lot of consing by allocating a
-;; char buffer the way Rhino does.
-(defsubst js2-add-to-string (c)
- (push c js2-ts-string-buffer))
-
-;; Note that when we "read" the end-of-file, we advance js2-ts-cursor
-;; to (1+ (point-max)), which lets the scanner treat end-of-file like
-;; any other character: when it's not part of the current token, we
-;; unget it, allowing it to be read again by the following call.
-(defsubst js2-unget-char ()
- (cl-decf js2-ts-cursor))
-
-;; Rhino distinguishes \r and \n line endings. We don't need to
-;; because we only scan from Emacs buffers, which always use \n.
-(defun js2-get-char ()
- "Read and return the next character from the input buffer.
-Increments `js2-ts-lineno' if the return value is a newline char.
-Updates `js2-ts-cursor' to the point after the returned char.
-Returns `js2-EOF_CHAR' if we hit the end of the buffer.
-Also updates `js2-ts-hit-eof' and `js2-ts-line-start' as needed."
- (let (c)
- ;; check for end of buffer
- (if (>= js2-ts-cursor (point-max))
- (setq js2-ts-hit-eof t
- js2-ts-cursor (1+ js2-ts-cursor)
- c js2-EOF_CHAR) ; return value
- ;; otherwise read next char
- (setq c (char-before (cl-incf js2-ts-cursor)))
- ;; if we read a newline, update counters
- (if (= c ?\n)
- (setq js2-ts-line-start js2-ts-cursor
- js2-ts-lineno (1+ js2-ts-lineno)))
- ;; TODO: skip over format characters
- c)))
-
-(defun js2-read-unicode-escape ()
- "Read a \\uNNNN sequence from the input.
-Assumes the ?\\ and ?u have already been read.
-Returns the unicode character, or nil if it wasn't a valid character.
-Doesn't change the values of any scanner variables."
- ;; I really wish I knew a better way to do this, but I can't
- ;; find the Emacs function that takes a 16-bit int and converts
- ;; it to a Unicode/utf-8 character. So I basically eval it with (read).
- ;; Have to first check that it's 4 hex characters or it may stop
- ;; the read early.
- (ignore-errors
- (let ((s (buffer-substring-no-properties js2-ts-cursor
- (+ 4 js2-ts-cursor))))
- (if (string-match "[0-9a-fA-F]\\{4\\}" s)
- (read (concat "?\\u" s))))))
-
-(defun js2-match-char (test)
- "Consume and return next character if it matches TEST, a character.
-Returns nil and consumes nothing if TEST is not the next character."
- (let ((c (js2-get-char)))
- (if (eq c test)
- t
- (js2-unget-char)
- nil)))
-
-(defun js2-peek-char ()
- (prog1
- (js2-get-char)
- (js2-unget-char)))
-
-(defun js2-identifier-start-p (c)
- "Is C a valid start to an ES5 Identifier?
-See http://es5.github.io/#x7.6"
- (or
- (memq c '(?$ ?_))
- (memq (get-char-code-property c 'general-category)
- ;; Letters
- '(Lu Ll Lt Lm Lo Nl))))
-
-(defun js2-identifier-part-p (c)
- "Is C a valid part of an ES5 Identifier?
-See http://es5.github.io/#x7.6"
- (or
- (memq c '(?$ ?_ ?\u200c ?\u200d))
- (memq (get-char-code-property c 'general-category)
- '(;; Letters
- Lu Ll Lt Lm Lo Nl
- ;; Combining Marks
- Mn Mc
- ;; Digits
- Nd
- ;; Connector Punctuation
- Pc))))
-
-(defun js2-alpha-p (c)
- (cond ((and (<= ?A c) (<= c ?Z)) t)
- ((and (<= ?a c) (<= c ?z)) t)
- (t nil)))
-
-(defsubst js2-digit-p (c)
- (and (<= ?0 c) (<= c ?9)))
-
-(defun js2-js-space-p (c)
- (if (<= c 127)
- (memq c '(#x20 #x9 #xB #xC #xD))
- (or
- (eq c #xA0)
- ;; TODO: change this nil to check for Unicode space character
- nil)))
-
-(defconst js2-eol-chars (list js2-EOF_CHAR ?\n ?\r))
-
-(defun js2-skip-line ()
- "Skip to end of line."
- (while (not (memq (js2-get-char) js2-eol-chars)))
- (js2-unget-char)
- (setf (js2-token-end (js2-current-token)) js2-ts-cursor))
-
-(defun js2-init-scanner (&optional buf line)
- "Create token stream for BUF starting on LINE.
-BUF defaults to `current-buffer' and LINE defaults to 1.
-
-A buffer can only have one scanner active at a time, which yields
-dramatically simpler code than using a defstruct. If you need to
-have simultaneous scanners in a buffer, copy the regions to scan
-into temp buffers."
- (with-current-buffer (or buf (current-buffer))
- (setq js2-ts-dirty-line nil
- js2-ts-hit-eof nil
- js2-ts-line-start 0
- js2-ts-lineno (or line 1)
- js2-ts-line-end-char -1
- js2-ts-cursor (point-min)
- js2-ti-tokens (make-vector js2-ti-ntokens nil)
- js2-ti-tokens-cursor 0
- js2-ti-lookahead 0
- js2-ts-is-xml-attribute nil
- js2-ts-xml-is-tag-content nil
- js2-ts-xml-open-tags-count 0
- js2-ts-string-buffer nil)))
-
-;; This function uses the cached op, string and number fields in
-;; TokenStream; if getToken has been called since the passed token
-;; was scanned, the op or string printed may be incorrect.
-(defun js2-token-to-string (token)
- ;; Not sure where this function is used in Rhino. Not tested.
- (if (not js2-debug-print-trees)
- ""
- (let ((name (js2-tt-name token)))
- (cond
- ((memq token '(js2-STRING js2-REGEXP js2-NAME
- js2-TEMPLATE_HEAD js2-NO_SUBS_TEMPLATE))
- (concat name " `" (js2-current-token-string) "'"))
- ((eq token js2-NUMBER)
- (format "NUMBER %g" (js2-token-number (js2-current-token))))
- (t
- name)))))
-
-(defconst js2-keywords
- '(break
- case catch class const continue
- debugger default delete do
- else extends export
- false finally for function
- if in instanceof import
- let
- new null
- return
- super switch
- this throw true try typeof
- var void
- while with
- yield))
-
-;; Token names aren't exactly the same as the keywords, unfortunately.
-;; E.g. delete is js2-DELPROP.
-(defconst js2-kwd-tokens
- (let ((table (make-vector js2-num-tokens nil))
- (tokens
- (list js2-BREAK
- js2-CASE js2-CATCH js2-CLASS js2-CONST js2-CONTINUE
- js2-DEBUGGER js2-DEFAULT js2-DELPROP js2-DO
- js2-ELSE js2-EXPORT
- js2-ELSE js2-EXTENDS js2-EXPORT
- js2-FALSE js2-FINALLY js2-FOR js2-FUNCTION
- js2-IF js2-IN js2-INSTANCEOF js2-IMPORT
- js2-LET
- js2-NEW js2-NULL
- js2-RETURN
- js2-SUPER js2-SWITCH
- js2-THIS js2-THROW js2-TRUE js2-TRY js2-TYPEOF
- js2-VAR
- js2-WHILE js2-WITH
- js2-YIELD)))
- (dolist (i tokens)
- (aset table i 'font-lock-keyword-face))
- (aset table js2-STRING 'font-lock-string-face)
- (aset table js2-REGEXP 'font-lock-string-face)
- (aset table js2-NO_SUBS_TEMPLATE 'font-lock-string-face)
- (aset table js2-TEMPLATE_HEAD 'font-lock-string-face)
- (aset table js2-COMMENT 'font-lock-comment-face)
- (aset table js2-THIS 'font-lock-builtin-face)
- (aset table js2-SUPER 'font-lock-builtin-face)
- (aset table js2-VOID 'font-lock-constant-face)
- (aset table js2-NULL 'font-lock-constant-face)
- (aset table js2-TRUE 'font-lock-constant-face)
- (aset table js2-FALSE 'font-lock-constant-face)
- (aset table js2-NOT 'font-lock-negation-char-face)
- table)
- "Vector whose values are non-nil for tokens that are keywords.
-The values are default faces to use for highlighting the keywords.")
-
-;; FIXME: Support strict mode-only future reserved words, after we know
-;; which parts scopes are in strict mode, and which are not.
-(defconst js2-reserved-words '(class enum export extends import static super)
- "Future reserved keywords in ECMAScript 5.1.")
-
-(defconst js2-keyword-names
- (let ((table (make-hash-table :test 'equal)))
- (cl-loop for k in js2-keywords
- do (puthash
- (symbol-name k) ; instanceof
- (intern (concat "js2-"
- (upcase (symbol-name k)))) ; js2-INSTANCEOF
- table))
- table)
- "JavaScript keywords by name, mapped to their symbols.")
-
-(defconst js2-reserved-word-names
- (let ((table (make-hash-table :test 'equal)))
- (cl-loop for k in js2-reserved-words
- do
- (puthash (symbol-name k) 'js2-RESERVED table))
- table)
- "JavaScript reserved words by name, mapped to `js2-RESERVED'.")
-
-(defun js2-collect-string (buf)
- "Convert BUF, a list of chars, to a string.
-Reverses BUF before converting."
- (if buf
- (apply #'string (nreverse buf))
- ""))
-
-(defun js2-string-to-keyword (s)
- "Return token for S, a string, if S is a keyword or reserved word.
-Returns a symbol such as `js2-BREAK', or nil if not keyword/reserved."
- (or (gethash s js2-keyword-names)
- (gethash s js2-reserved-word-names)))
-
-(defsubst js2-ts-set-char-token-bounds (token)
- "Used when next token is one character."
- (setf (js2-token-beg token) (1- js2-ts-cursor)
- (js2-token-end token) js2-ts-cursor))
-
-(defsubst js2-ts-return (token type)
- "Update the `end' and `type' slots of TOKEN,
-then throw `return' with value TYPE."
- (setf (js2-token-end token) js2-ts-cursor
- (js2-token-type token) type)
- (throw 'return type))
-
-(defun js2-x-digit-to-int (c accumulator)
- "Build up a hex number.
-If C is a hexadecimal digit, return ACCUMULATOR * 16 plus
-corresponding number. Otherwise return -1."
- (catch 'return
- (catch 'check
- ;; Use 0..9 < A..Z < a..z
- (cond
- ((<= c ?9)
- (cl-decf c ?0)
- (if (<= 0 c)
- (throw 'check nil)))
- ((<= c ?F)
- (when (<= ?A c)
- (cl-decf c (- ?A 10))
- (throw 'check nil)))
- ((<= c ?f)
- (when (<= ?a c)
- (cl-decf c (- ?a 10))
- (throw 'check nil))))
- (throw 'return -1))
- (logior c (lsh accumulator 4))))
-
-(defun js2-get-token (&optional modifier)
- "If `js2-ti-lookahead' is zero, call scanner to get new token.
-Otherwise, move `js2-ti-tokens-cursor' and return the type of
-next saved token.
-
-This function will not return a newline (js2-EOL) - instead, it
-gobbles newlines until it finds a non-newline token. Call
-`js2-peek-token-or-eol' when you care about newlines.
-
-This function will also not return a js2-COMMENT. Instead, it
-records comments found in `js2-scanned-comments'. If the token
-returned by this function immediately follows a jsdoc comment,
-the token is flagged as such."
- (if (zerop js2-ti-lookahead)
- (js2-get-token-internal modifier)
- (cl-decf js2-ti-lookahead)
- (setq js2-ti-tokens-cursor (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens))
- (let ((tt (js2-current-token-type)))
- (cl-assert (not (= tt js2-EOL)))
- tt)))
-
-(defun js2-unget-token ()
- (cl-assert (< js2-ti-lookahead js2-ti-max-lookahead))
- (cl-incf js2-ti-lookahead)
- (setq js2-ti-tokens-cursor (mod (1- js2-ti-tokens-cursor) js2-ti-ntokens)))
-
-(defun js2-get-token-internal (modifier)
- (let* ((token (js2-get-token-internal-1 modifier)) ; call scanner
- (tt (js2-token-type token))
- saw-eol
- face)
- ;; process comments
- (while (or (= tt js2-EOL) (= tt js2-COMMENT))
- (if (= tt js2-EOL)
- (setq saw-eol t)
- (setq saw-eol nil)
- (when js2-record-comments
- (js2-record-comment token)))
- (setq js2-ti-tokens-cursor (mod (1- js2-ti-tokens-cursor)
js2-ti-ntokens))
- (setq token (js2-get-token-internal-1 modifier) ; call scanner again
- tt (js2-token-type token)))
-
- (when saw-eol
- (setf (js2-token-follows-eol-p token) t))
-
- ;; perform lexical fontification as soon as token is scanned
- (when js2-parse-ide-mode
- (cond
- ((cl-minusp tt)
- (js2-record-face 'js2-error token))
- ((setq face (aref js2-kwd-tokens tt))
- (js2-record-face face token))
- ((and (= tt js2-NAME)
- (equal (js2-token-string token) "undefined"))
- (js2-record-face 'font-lock-constant-face token))))
- tt))
-
-(defsubst js2-string-to-number (str base)
- ;; TODO: Maybe port ScriptRuntime.stringToNumber.
- (condition-case nil
- (string-to-number str base)
- (overflow-error -1)))
-
-(defun js2-get-token-internal-1 (modifier)
- "Return next JavaScript token type, an int such as js2-RETURN.
-During operation, creates an instance of `js2-token' struct, sets
-its relevant fields and puts it into `js2-ti-tokens'."
- (let (identifier-start
- is-unicode-escape-start c
- contains-escape escape-val str result base
- look-for-slash continue tt legacy-octal
- (token (js2-new-token 0)))
- (setq
- tt
- (catch 'return
- (when (eq modifier 'TEMPLATE_TAIL)
- (setf (js2-token-beg token) (1- js2-ts-cursor))
- (throw 'return (js2-get-string-or-template-token ?` token)))
- (while t
- ;; Eat whitespace, possibly sensitive to newlines.
- (setq continue t)
- (while continue
- (setq c (js2-get-char))
- (cond
- ((eq c js2-EOF_CHAR)
- (js2-unget-char)
- (js2-ts-set-char-token-bounds token)
- (throw 'return js2-EOF))
- ((eq c ?\n)
- (js2-ts-set-char-token-bounds token)
- (setq js2-ts-dirty-line nil)
- (throw 'return js2-EOL))
- ((not (js2-js-space-p c))
- (if (/= c ?-) ; in case end of HTML comment
- (setq js2-ts-dirty-line t))
- (setq continue nil))))
- ;; Assume the token will be 1 char - fixed up below.
- (js2-ts-set-char-token-bounds token)
- (when (eq c ?@)
- (throw 'return js2-XMLATTR))
- ;; identifier/keyword/instanceof?
- ;; watch out for starting with a <backslash>
- (cond
- ((eq c ?\\)
- (setq c (js2-get-char))
- (if (eq c ?u)
- (setq identifier-start t
- is-unicode-escape-start t
- js2-ts-string-buffer nil)
- (setq identifier-start nil)
- (js2-unget-char)
- (setq c ?\\)))
- (t
- (when (setq identifier-start (js2-identifier-start-p c))
- (setq js2-ts-string-buffer nil)
- (js2-add-to-string c))))
- (when identifier-start
- (setq contains-escape is-unicode-escape-start)
- (catch 'break
- (while t
- (if is-unicode-escape-start
- ;; strictly speaking we should probably push-back
- ;; all the bad characters if the <backslash>uXXXX
- ;; sequence is malformed. But since there isn't a
- ;; correct context(is there?) for a bad Unicode
- ;; escape sequence in an identifier, we can report
- ;; an error here.
- (progn
- (setq escape-val 0)
- (dotimes (_ 4)
- (setq c (js2-get-char)
- escape-val (js2-x-digit-to-int c escape-val))
- ;; Next check takes care of c < 0 and bad escape
- (if (cl-minusp escape-val)
- (throw 'break nil)))
- (if (cl-minusp escape-val)
- (js2-report-scan-error "msg.invalid.escape" t))
- (js2-add-to-string escape-val)
- (setq is-unicode-escape-start nil))
- (setq c (js2-get-char))
- (cond
- ((eq c ?\\)
- (setq c (js2-get-char))
- (if (eq c ?u)
- (setq is-unicode-escape-start t
- contains-escape t)
- (js2-report-scan-error "msg.illegal.character" t)))
- (t
- (if (or (eq c js2-EOF_CHAR)
- (not (js2-identifier-part-p c)))
- (throw 'break nil))
- (js2-add-to-string c))))))
- (js2-unget-char)
- (setf str (js2-collect-string js2-ts-string-buffer)
- (js2-token-end token) js2-ts-cursor)
- ;; FIXME: Invalid in ES5 and ES6, see
- ;; https://bugzilla.mozilla.org/show_bug.cgi?id=694360
- ;; Probably should just drop this conditional.
- (unless contains-escape
- ;; OPT we shouldn't have to make a string (object!) to
- ;; check if it's a keyword.
- ;; Return the corresponding token if it's a keyword
- (when (and (not (eq modifier 'KEYWORD_IS_NAME))
- (setq result (js2-string-to-keyword str)))
- (if (and (< js2-language-version 170)
- (memq result '(js2-LET js2-YIELD)))
- ;; LET and YIELD are tokens only in 1.7 and later
- (setq result 'js2-NAME))
- (when (eq result 'js2-RESERVED)
- (setf (js2-token-string token) str))
- (throw 'return (js2-tt-code result))))
- ;; If we want to intern these as Rhino does, just use (intern str)
- (setf (js2-token-string token) str)
- (throw 'return js2-NAME)) ; end identifier/kwd check
- ;; is it a number?
- (when (or (js2-digit-p c)
- (and (eq c ?.) (js2-digit-p (js2-peek-char))))
- (setq js2-ts-string-buffer nil
- base 10)
- (when (eq c ?0)
- (setq c (js2-get-char))
- (cond
- ((or (eq c ?x) (eq c ?X))
- (setq base 16)
- (setq c (js2-get-char)))
- ((and (or (eq c ?b) (eq c ?B))
- (>= js2-language-version 200))
- (setq base 2)
- (setq c (js2-get-char)))
- ((and (or (eq c ?o) (eq c ?O))
- (>= js2-language-version 200))
- (setq base 8)
- (setq legacy-octal nil)
- (setq c (js2-get-char)))
- ((js2-digit-p c)
- (setq base 'maybe-8))
- (t
- (js2-add-to-string ?0))))
- (cond
- ((eq base 16)
- (if (> 0 (js2-x-digit-to-int c 0))
- (js2-report-scan-error "msg.missing.hex.digits")
- (while (<= 0 (js2-x-digit-to-int c 0))
- (js2-add-to-string c)
- (setq c (js2-get-char)))))
- ((eq base 2)
- (if (not (memq c '(?0 ?1)))
- (js2-report-scan-error "msg.missing.binary.digits")
- (while (memq c '(?0 ?1))
- (js2-add-to-string c)
- (setq c (js2-get-char)))))
- ((eq base 8)
- (if (or (> ?0 c) (< ?7 c))
- (js2-report-scan-error "msg.missing.octal.digits")
- (while (and (<= ?0 c) (>= ?7 c))
- (js2-add-to-string c)
- (setq c (js2-get-char)))))
- (t
- (while (and (<= ?0 c) (<= c ?9))
- ;; We permit 08 and 09 as decimal numbers, which
- ;; makes our behavior a superset of the ECMA
- ;; numeric grammar. We might not always be so
- ;; permissive, so we warn about it.
- (when (and (eq base 'maybe-8) (>= c ?8))
- (js2-report-warning "msg.bad.octal.literal"
- (if (eq c ?8) "8" "9"))
- (setq base 10))
- (js2-add-to-string c)
- (setq c (js2-get-char)))
- (when (eq base 'maybe-8)
- (setq base 8
- legacy-octal t))))
- (when (and (eq base 10) (memq c '(?. ?e ?E)))
- (when (eq c ?.)
- (cl-loop do
- (js2-add-to-string c)
- (setq c (js2-get-char))
- while (js2-digit-p c)))
- (when (memq c '(?e ?E))
- (js2-add-to-string c)
- (setq c (js2-get-char))
- (when (memq c '(?+ ?-))
- (js2-add-to-string c)
- (setq c (js2-get-char)))
- (unless (js2-digit-p c)
- (js2-report-scan-error "msg.missing.exponent" t))
- (cl-loop do
- (js2-add-to-string c)
- (setq c (js2-get-char))
- while (js2-digit-p c))))
- (js2-unget-char)
- (let ((str (js2-set-string-from-buffer token)))
- (setf (js2-token-number token) (js2-string-to-number str base)
- (js2-token-number-base token) base
- (js2-token-number-legacy-octal-p token) (and (= base 8)
legacy-octal)))
- (throw 'return js2-NUMBER))
- ;; is it a string?
- (when (or (memq c '(?\" ?\'))
- (and (>= js2-language-version 200)
- (= c ?`)))
- (throw 'return
- (js2-get-string-or-template-token c token)))
- (js2-ts-return token
- (cl-case c
- (?\;
- (throw 'return js2-SEMI))
- (?\[
- (throw 'return js2-LB))
- (?\]
- (throw 'return js2-RB))
- (?{
- (throw 'return js2-LC))
- (?}
- (throw 'return js2-RC))
- (?\(
- (throw 'return js2-LP))
- (?\)
- (throw 'return js2-RP))
- (?,
- (throw 'return js2-COMMA))
- (??
- (throw 'return js2-HOOK))
- (?:
- (if (js2-match-char ?:)
- js2-COLONCOLON
- (throw 'return js2-COLON)))
- (?.
- (if (js2-match-char ?.)
- (if (js2-match-char ?.)
- js2-TRIPLEDOT js2-DOTDOT)
- (if (js2-match-char ?\()
- js2-DOTQUERY
- (throw 'return js2-DOT))))
- (?|
- (if (js2-match-char ?|)
- (throw 'return js2-OR)
- (if (js2-match-char ?=)
- js2-ASSIGN_BITOR
- (throw 'return js2-BITOR))))
- (?^
- (if (js2-match-char ?=)
- js2-ASSIGN_BITOR
- (throw 'return js2-BITXOR)))
- (?&
- (if (js2-match-char ?&)
- (throw 'return js2-AND)
- (if (js2-match-char ?=)
- js2-ASSIGN_BITAND
- (throw 'return js2-BITAND))))
- (?=
- (if (js2-match-char ?=)
- (if (js2-match-char ?=)
- js2-SHEQ
- (throw 'return js2-EQ))
- (if (js2-match-char ?>)
- (js2-ts-return token js2-ARROW)
- (throw 'return js2-ASSIGN))))
- (?!
- (if (js2-match-char ?=)
- (if (js2-match-char ?=)
- js2-SHNE
- js2-NE)
- (throw 'return js2-NOT)))
- (?<
- ;; NB:treat HTML begin-comment as comment-till-eol
- (when (js2-match-char ?!)
- (when (js2-match-char ?-)
- (when (js2-match-char ?-)
- (js2-skip-line)
- (setf (js2-token-comment-type
(js2-current-token)) 'html)
- (throw 'return js2-COMMENT)))
- (js2-unget-char))
- (if (js2-match-char ?<)
- (if (js2-match-char ?=)
- js2-ASSIGN_LSH
- js2-LSH)
- (if (js2-match-char ?=)
- js2-LE
- (throw 'return js2-LT))))
- (?>
- (if (js2-match-char ?>)
- (if (js2-match-char ?>)
- (if (js2-match-char ?=)
- js2-ASSIGN_URSH
- js2-URSH)
- (if (js2-match-char ?=)
- js2-ASSIGN_RSH
- js2-RSH))
- (if (js2-match-char ?=)
- js2-GE
- (throw 'return js2-GT))))
- (?*
- (if (js2-match-char ?=)
- js2-ASSIGN_MUL
- (if (js2-match-char ?*)
- (if (js2-match-char ?=)
- js2-ASSIGN_EXPON
- js2-EXPON)
- (throw 'return js2-MUL))))
- (?/
- ;; is it a // comment?
- (when (js2-match-char ?/)
- (setf (js2-token-beg token) (- js2-ts-cursor 2))
- (js2-skip-line)
- (setf (js2-token-comment-type token) 'line)
- ;; include newline so highlighting goes to end of
- ;; window, if there actually is a newline; if we
- ;; hit eof, then implicitly there isn't
- (unless js2-ts-hit-eof
- (cl-incf (js2-token-end token)))
- (throw 'return js2-COMMENT))
- ;; is it a /* comment?
- (when (js2-match-char ?*)
- (setf look-for-slash nil
- (js2-token-beg token) (- js2-ts-cursor 2)
- (js2-token-comment-type token)
- (if (js2-match-char ?*)
- (progn
- (setq look-for-slash t)
- 'jsdoc)
- 'block))
- (while t
- (setq c (js2-get-char))
- (cond
- ((eq c js2-EOF_CHAR)
- (setf (js2-token-end token) (1-
js2-ts-cursor))
- (js2-report-error "msg.unterminated.comment")
- (throw 'return js2-COMMENT))
- ((eq c ?*)
- (setq look-for-slash t))
- ((eq c ?/)
- (if look-for-slash
- (js2-ts-return token js2-COMMENT)))
- (t
- (setf look-for-slash nil
- (js2-token-end token) js2-ts-cursor)))))
- (if (js2-match-char ?=)
- js2-ASSIGN_DIV
- (throw 'return js2-DIV)))
- (?#
- (when js2-skip-preprocessor-directives
- (js2-skip-line)
- (setf (js2-token-comment-type token) 'preprocessor
- (js2-token-end token) js2-ts-cursor)
- (throw 'return js2-COMMENT))
- (throw 'return js2-ERROR))
- (?%
- (if (js2-match-char ?=)
- js2-ASSIGN_MOD
- (throw 'return js2-MOD)))
- (?~
- (throw 'return js2-BITNOT))
- (?+
- (if (js2-match-char ?=)
- js2-ASSIGN_ADD
- (if (js2-match-char ?+)
- js2-INC
- (throw 'return js2-ADD))))
- (?-
- (cond
- ((js2-match-char ?=)
- (setq c js2-ASSIGN_SUB))
- ((js2-match-char ?-)
- (unless js2-ts-dirty-line
- ;; treat HTML end-comment after possible
whitespace
- ;; after line start as comment-until-eol
- (when (js2-match-char ?>)
- (js2-skip-line)
- (setf (js2-token-comment-type
(js2-current-token)) 'html)
- (throw 'return js2-COMMENT)))
- (setq c js2-DEC))
- (t
- (setq c js2-SUB)))
- (setq js2-ts-dirty-line t)
- c)
- (otherwise
- (js2-report-scan-error
"msg.illegal.character")))))))
- (setf (js2-token-type token) tt)
- token))
-
-(defun js2-get-string-or-template-token (quote-char token)
- ;; We attempt to accumulate a string the fast way, by
- ;; building it directly out of the reader. But if there
- ;; are any escaped characters in the string, we revert to
- ;; building it out of a string buffer.
- (let ((c (js2-get-char))
- js2-ts-string-buffer
- nc c1 val escape-val)
- (catch 'break
- (while (/= c quote-char)
- (catch 'continue
- (when (eq c js2-EOF_CHAR)
- (js2-unget-char)
- (js2-report-error "msg.unterminated.string.lit")
- (throw 'break nil))
- (when (and (eq c ?\n) (not (eq quote-char ?`)))
- (js2-unget-char)
- (js2-report-error "msg.unterminated.string.lit")
- (throw 'break nil))
- (when (eq c ?\\)
- ;; We've hit an escaped character
- (setq c (js2-get-char))
- (cl-case c
- (?b (setq c ?\b))
- (?f (setq c ?\f))
- (?n (setq c ?\n))
- (?r (setq c ?\r))
- (?t (setq c ?\t))
- (?v (setq c ?\v))
- (?u
- (setq c1 (js2-read-unicode-escape))
- (if js2-parse-ide-mode
- (if c1
- (progn
- ;; just copy the string in IDE-mode
- (js2-add-to-string ?\\)
- (js2-add-to-string ?u)
- (dotimes (_ 3)
- (js2-add-to-string (js2-get-char)))
- (setq c (js2-get-char))) ; added at end of loop
- ;; flag it as an invalid escape
- (js2-report-warning "msg.invalid.escape"
- nil (- js2-ts-cursor 2) 6))
- ;; Get 4 hex digits; if the u escape is not
- ;; followed by 4 hex digits, use 'u' + the
- ;; literal character sequence that follows.
- (js2-add-to-string ?u)
- (setq escape-val 0)
- (dotimes (_ 4)
- (setq c (js2-get-char)
- escape-val (js2-x-digit-to-int c escape-val))
- (if (cl-minusp escape-val)
- (throw 'continue nil))
- (js2-add-to-string c))
- ;; prepare for replace of stored 'u' sequence by escape value
- (setq js2-ts-string-buffer (nthcdr 5 js2-ts-string-buffer)
- c escape-val)))
- (?x
- ;; Get 2 hex digits, defaulting to 'x'+literal
- ;; sequence, as above.
- (setq c (js2-get-char)
- escape-val (js2-x-digit-to-int c 0))
- (if (cl-minusp escape-val)
- (progn
- (js2-add-to-string ?x)
- (throw 'continue nil))
- (setq c1 c
- c (js2-get-char)
- escape-val (js2-x-digit-to-int c escape-val))
- (if (cl-minusp escape-val)
- (progn
- (js2-add-to-string ?x)
- (js2-add-to-string c1)
- (throw 'continue nil))
- ;; got 2 hex digits
- (setq c escape-val))))
- (?\n
- ;; Remove line terminator after escape to follow
- ;; SpiderMonkey and C/C++
- (setq c (js2-get-char))
- (throw 'continue nil))
- (t
- (when (and (<= ?0 c) (< c ?8))
- (setq val (- c ?0)
- c (js2-get-char))
- (when (and (<= ?0 c) (< c ?8))
- (setq val (- (+ (* 8 val) c) ?0)
- c (js2-get-char))
- (when (and (<= ?0 c)
- (< c ?8)
- (< val #o37))
- ;; c is 3rd char of octal sequence only
- ;; if the resulting val <= 0377
- (setq val (- (+ (* 8 val) c) ?0)
- c (js2-get-char))))
- (js2-unget-char)
- (setq c val)))))
- (when (and (eq quote-char ?`) (eq c ?$))
- (when (eq (setq nc (js2-get-char)) ?\{)
- (throw 'break nil))
- (js2-unget-char))
- (js2-add-to-string c)
- (setq c (js2-get-char)))))
- (js2-set-string-from-buffer token)
- (if (not (eq quote-char ?`))
- js2-STRING
- (if (and (eq c ?$) (eq nc ?\{))
- js2-TEMPLATE_HEAD
- js2-NO_SUBS_TEMPLATE))))
-
-(defun js2-read-regexp (start-tt start-pos)
- "Called by parser when it gets / or /= in literal context."
- (let (c err
- in-class ; inside a '[' .. ']' character-class
- flags
- (continue t)
- (token (js2-new-token 0)))
- (js2-record-text-property start-pos (1+ start-pos)
- 'syntax-table (string-to-syntax "\"/"))
- (setq js2-ts-string-buffer nil)
- (if (eq start-tt js2-ASSIGN_DIV)
- ;; mis-scanned /=
- (js2-add-to-string ?=)
- (if (not (eq start-tt js2-DIV))
- (error "failed assertion")))
- (while (and (not err)
- (or (/= (setq c (js2-get-char)) ?/)
- in-class))
- (cond
- ((or (= c ?\n)
- (= c js2-EOF_CHAR))
- (setf (js2-token-end token) (1- js2-ts-cursor)
- err t
- (js2-token-string token) (js2-collect-string
js2-ts-string-buffer))
- (js2-report-error "msg.unterminated.re.lit"))
- (t (cond
- ((= c ?\\)
- (js2-add-to-string c)
- (setq c (js2-get-char)))
- ((= c ?\[)
- (setq in-class t))
- ((= c ?\])
- (setq in-class nil)))
- (js2-add-to-string c))))
- (unless err
- (js2-record-text-property (1- js2-ts-cursor) js2-ts-cursor
- 'syntax-table (string-to-syntax "\"/"))
- (while continue
- (cond
- ((js2-match-char ?g)
- (push ?g flags))
- ((js2-match-char ?i)
- (push ?i flags))
- ((js2-match-char ?m)
- (push ?m flags))
- ((and (js2-match-char ?u)
- (>= js2-language-version 200))
- (push ?u flags))
- ((and (js2-match-char ?y)
- (>= js2-language-version 200))
- (push ?y flags))
- (t
- (setq continue nil))))
- (if (js2-alpha-p (js2-peek-char))
- (js2-report-scan-error "msg.invalid.re.flag" t
- js2-ts-cursor 1))
- (js2-set-string-from-buffer token))
- (js2-collect-string flags)))
-
-(defun js2-get-first-xml-token ()
- (setq js2-ts-xml-open-tags-count 0
- js2-ts-is-xml-attribute nil
- js2-ts-xml-is-tag-content nil)
- (js2-unget-char)
- (js2-get-next-xml-token))
-
-(defun js2-xml-discard-string (token)
- "Throw away the string in progress and flag an XML parse error."
- (setf js2-ts-string-buffer nil
- (js2-token-string token) nil)
- (js2-report-scan-error "msg.XML.bad.form" t))
-
-(defun js2-get-next-xml-token ()
- (setq js2-ts-string-buffer nil) ; for recording the XML
- (let ((token (js2-new-token 0))
- c result)
- (setq result
- (catch 'return
- (while t
- (setq c (js2-get-char))
- (cond
- ((= c js2-EOF_CHAR)
- (throw 'return js2-ERROR))
- (js2-ts-xml-is-tag-content
- (cl-case c
- (?>
- (js2-add-to-string c)
- (setq js2-ts-xml-is-tag-content nil
- js2-ts-is-xml-attribute nil))
- (?/
- (js2-add-to-string c)
- (when (eq ?> (js2-peek-char))
- (setq c (js2-get-char))
- (js2-add-to-string c)
- (setq js2-ts-xml-is-tag-content nil)
- (cl-decf js2-ts-xml-open-tags-count)))
- (?{
- (js2-unget-char)
- (js2-set-string-from-buffer token)
- (throw 'return js2-XML))
- ((?\' ?\")
- (js2-add-to-string c)
- (unless (js2-read-quoted-string c token)
- (throw 'return js2-ERROR)))
- (?=
- (js2-add-to-string c)
- (setq js2-ts-is-xml-attribute t))
- ((? ?\t ?\r ?\n)
- (js2-add-to-string c))
- (t
- (js2-add-to-string c)
- (setq js2-ts-is-xml-attribute nil)))
- (when (and (not js2-ts-xml-is-tag-content)
- (zerop js2-ts-xml-open-tags-count))
- (js2-set-string-from-buffer token)
- (throw 'return js2-XMLEND)))
- (t
- ;; else not tag content
- (cl-case c
- (?<
- (js2-add-to-string c)
- (setq c (js2-peek-char))
- (cl-case c
- (?!
- (setq c (js2-get-char)) ;; skip !
- (js2-add-to-string c)
- (setq c (js2-peek-char))
- (cl-case c
- (?-
- (setq c (js2-get-char)) ;; skip -
- (js2-add-to-string c)
- (if (eq c ?-)
- (progn
- (js2-add-to-string c)
- (unless (js2-read-xml-comment token)
- (throw 'return js2-ERROR)))
- (js2-xml-discard-string token)
- (throw 'return js2-ERROR)))
- (?\[
- (setq c (js2-get-char)) ;; skip [
- (js2-add-to-string c)
- (if (and (= (js2-get-char) ?C)
- (= (js2-get-char) ?D)
- (= (js2-get-char) ?A)
- (= (js2-get-char) ?T)
- (= (js2-get-char) ?A)
- (= (js2-get-char) ?\[))
- (progn
- (js2-add-to-string ?C)
- (js2-add-to-string ?D)
- (js2-add-to-string ?A)
- (js2-add-to-string ?T)
- (js2-add-to-string ?A)
- (js2-add-to-string ?\[)
- (unless (js2-read-cdata token)
- (throw 'return js2-ERROR)))
- (js2-xml-discard-string token)
- (throw 'return js2-ERROR)))
- (t
- (unless (js2-read-entity token)
- (throw 'return js2-ERROR))))
- ;; Allow bare CDATA section, e.g.:
- ;; let xml = <![CDATA[ foo bar baz ]]>;
- (when (zerop js2-ts-xml-open-tags-count)
- (throw 'return js2-XMLEND)))
- (??
- (setq c (js2-get-char)) ;; skip ?
- (js2-add-to-string c)
- (unless (js2-read-PI token)
- (throw 'return js2-ERROR)))
- (?/
- ;; end tag
- (setq c (js2-get-char)) ;; skip /
- (js2-add-to-string c)
- (when (zerop js2-ts-xml-open-tags-count)
- (js2-xml-discard-string token)
- (throw 'return js2-ERROR))
- (setq js2-ts-xml-is-tag-content t)
- (cl-decf js2-ts-xml-open-tags-count))
- (t
- ;; start tag
- (setq js2-ts-xml-is-tag-content t)
- (cl-incf js2-ts-xml-open-tags-count))))
- (?{
- (js2-unget-char)
- (js2-set-string-from-buffer token)
- (throw 'return js2-XML))
- (t
- (js2-add-to-string c))))))))
- (setf (js2-token-end token) js2-ts-cursor)
- (setf (js2-token-type token) result)
- result))
-
-(defun js2-read-quoted-string (quote token)
- (let (c)
- (catch 'return
- (while (/= (setq c (js2-get-char)) js2-EOF_CHAR)
- (js2-add-to-string c)
- (if (eq c quote)
- (throw 'return t)))
- (js2-xml-discard-string token) ;; throw away string in progress
- nil)))
-
-(defun js2-read-xml-comment (token)
- (let ((c (js2-get-char)))
- (catch 'return
- (while (/= c js2-EOF_CHAR)
- (catch 'continue
- (js2-add-to-string c)
- (when (and (eq c ?-) (eq ?- (js2-peek-char)))
- (setq c (js2-get-char))
- (js2-add-to-string c)
- (if (eq (js2-peek-char) ?>)
- (progn
- (setq c (js2-get-char)) ;; skip >
- (js2-add-to-string c)
- (throw 'return t))
- (throw 'continue nil)))
- (setq c (js2-get-char))))
- (js2-xml-discard-string token)
- nil)))
-
-(defun js2-read-cdata (token)
- (let ((c (js2-get-char)))
- (catch 'return
- (while (/= c js2-EOF_CHAR)
- (catch 'continue
- (js2-add-to-string c)
- (when (and (eq c ?\]) (eq (js2-peek-char) ?\]))
- (setq c (js2-get-char))
- (js2-add-to-string c)
- (if (eq (js2-peek-char) ?>)
- (progn
- (setq c (js2-get-char)) ;; Skip >
- (js2-add-to-string c)
- (throw 'return t))
- (throw 'continue nil)))
- (setq c (js2-get-char))))
- (js2-xml-discard-string token)
- nil)))
-
-(defun js2-read-entity (token)
- (let ((decl-tags 1)
- c)
- (catch 'return
- (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
- (js2-add-to-string c)
- (cl-case c
- (?<
- (cl-incf decl-tags))
- (?>
- (cl-decf decl-tags)
- (if (zerop decl-tags)
- (throw 'return t)))))
- (js2-xml-discard-string token)
- nil)))
-
-(defun js2-read-PI (token)
- "Scan an XML processing instruction."
- (let (c)
- (catch 'return
- (while (/= js2-EOF_CHAR (setq c (js2-get-char)))
- (js2-add-to-string c)
- (when (and (eq c ??) (eq (js2-peek-char) ?>))
- (setq c (js2-get-char)) ;; Skip >
- (js2-add-to-string c)
- (throw 'return t)))
- (js2-xml-discard-string token)
- nil)))
-
-;;; Highlighting
-
-(defun js2-set-face (beg end face &optional record)
- "Fontify a region. If RECORD is non-nil, record for later."
- (when (cl-plusp js2-highlight-level)
- (setq beg (min (point-max) beg)
- beg (max (point-min) beg)
- end (min (point-max) end)
- end (max (point-min) end))
- (if record
- (push (list beg end face) js2-mode-fontifications)
- (put-text-property beg end 'font-lock-face face))))
-
-(defsubst js2-clear-face (beg end)
- (remove-text-properties beg end '(font-lock-face nil
- help-echo nil
- point-entered nil
- cursor-sensor-functions nil
- c-in-sws nil)))
-
-(defconst js2-ecma-global-props
- (concat "^"
- (regexp-opt
- '("Infinity" "NaN" "undefined" "arguments") t)
- "$")
- "Value properties of the Ecma-262 Global Object.
-Shown at or above `js2-highlight-level' 2.")
-
-;; might want to add the name "arguments" to this list?
-(defconst js2-ecma-object-props
- (concat "^"
- (regexp-opt
- '("prototype" "__proto__" "__parent__") t)
- "$")
- "Value properties of the Ecma-262 Object constructor.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-global-funcs
- (concat
- "^"
- (regexp-opt
- '("decodeURI" "decodeURIComponent" "encodeURI" "encodeURIComponent"
- "eval" "isFinite" "isNaN" "parseFloat" "parseInt") t)
- "$")
- "Function properties of the Ecma-262 Global object.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-number-props
- (concat "^"
- (regexp-opt '("MAX_VALUE" "MIN_VALUE" "NaN"
- "NEGATIVE_INFINITY"
- "POSITIVE_INFINITY") t)
- "$")
- "Properties of the Ecma-262 Number constructor.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-date-props "^\\(parse\\|UTC\\)$"
- "Properties of the Ecma-262 Date constructor.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-math-props
- (concat "^"
- (regexp-opt
- '("E" "LN10" "LN2" "LOG2E" "LOG10E" "PI" "SQRT1_2" "SQRT2")
- t)
- "$")
- "Properties of the Ecma-262 Math object.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-math-funcs
- (concat "^"
- (regexp-opt
- '("abs" "acos" "asin" "atan" "atan2" "ceil" "cos" "exp" "floor"
- "log" "max" "min" "pow" "random" "round" "sin" "sqrt" "tan") t)
- "$")
- "Function properties of the Ecma-262 Math object.
-Shown at or above `js2-highlight-level' 2.")
-
-(defconst js2-ecma-function-props
- (concat
- "^"
- (regexp-opt
- '(;; properties of the Object prototype object
- "hasOwnProperty" "isPrototypeOf" "propertyIsEnumerable"
- "toLocaleString" "toString" "valueOf"
- ;; properties of the Function prototype object
- "apply" "call"
- ;; properties of the Array prototype object
- "concat" "join" "pop" "push" "reverse" "shift" "slice" "sort"
- "splice" "unshift"
- ;; properties of the String prototype object
- "charAt" "charCodeAt" "fromCharCode" "indexOf" "lastIndexOf"
- "localeCompare" "match" "replace" "search" "split" "substring"
- "toLocaleLowerCase" "toLocaleUpperCase" "toLowerCase"
- "toUpperCase"
- ;; properties of the Number prototype object
- "toExponential" "toFixed" "toPrecision"
- ;; properties of the Date prototype object
- "getDate" "getDay" "getFullYear" "getHours" "getMilliseconds"
- "getMinutes" "getMonth" "getSeconds" "getTime"
- "getTimezoneOffset" "getUTCDate" "getUTCDay" "getUTCFullYear"
- "getUTCHours" "getUTCMilliseconds" "getUTCMinutes" "getUTCMonth"
- "getUTCSeconds" "setDate" "setFullYear" "setHours"
- "setMilliseconds" "setMinutes" "setMonth" "setSeconds" "setTime"
- "setUTCDate" "setUTCFullYear" "setUTCHours" "setUTCMilliseconds"
- "setUTCMinutes" "setUTCMonth" "setUTCSeconds" "toDateString"
- "toLocaleDateString" "toLocaleString" "toLocaleTimeString"
- "toTimeString" "toUTCString"
- ;; properties of the RegExp prototype object
- "exec" "test"
- ;; properties of the JSON prototype object
- "parse" "stringify"
- ;; SpiderMonkey/Rhino extensions, versions 1.5+
- "toSource" "__defineGetter__" "__defineSetter__"
- "__lookupGetter__" "__lookupSetter__" "__noSuchMethod__"
- "every" "filter" "forEach" "lastIndexOf" "map" "some")
- t)
- "$")
- "Built-in functions defined by Ecma-262 and SpiderMonkey extensions.
-Shown at or above `js2-highlight-level' 3.")
-
-(defun js2-parse-highlight-prop-get (parent target prop call-p)
- (let ((target-name (and target
- (js2-name-node-p target)
- (js2-name-node-name target)))
- (prop-name (if prop (js2-name-node-name prop)))
- (level2 (>= js2-highlight-level 2))
- (level3 (>= js2-highlight-level 3)))
- (when level2
- (let ((face
- (if call-p
- (cond
- ((and target prop)
- (cond
- ((and level3 (string-match js2-ecma-function-props
prop-name))
- 'font-lock-builtin-face)
- ((and target-name prop)
- (cond
- ((string= target-name "Date")
- (if (string-match js2-ecma-date-props prop-name)
- 'font-lock-builtin-face))
- ((string= target-name "Math")
- (if (string-match js2-ecma-math-funcs prop-name)
- 'font-lock-builtin-face))))))
- (prop
- (if (string-match js2-ecma-global-funcs prop-name)
- 'font-lock-builtin-face)))
- (cond
- ((and target prop)
- (cond
- ((string= target-name "Number")
- (if (string-match js2-ecma-number-props prop-name)
- 'font-lock-constant-face))
- ((string= target-name "Math")
- (if (string-match js2-ecma-math-props prop-name)
- 'font-lock-constant-face))))
- (prop
- (if (string-match js2-ecma-object-props prop-name)
- 'font-lock-constant-face))))))
- (when (and (not face) target (not call-p) prop-name)
- (setq face 'js2-object-property-access))
- (when face
- (let ((pos (+ (js2-node-pos parent) ; absolute
- (js2-node-pos prop)))) ; relative
- (js2-set-face pos
- (+ pos (js2-node-len prop))
- face 'record)))))))
-
-(defun js2-parse-highlight-member-expr-node (node)
- "Perform syntax highlighting of EcmaScript built-in properties.
-The variable `js2-highlight-level' governs this highlighting."
- (let (face target prop name pos end parent call-p callee)
- (cond
- ;; case 1: simple name, e.g. foo
- ((js2-name-node-p node)
- (setq name (js2-name-node-name node))
- ;; possible for name to be nil in rare cases - saw it when
- ;; running js2-mode on an elisp buffer. Might as well try to
- ;; make it so js2-mode never barfs.
- (when name
- (setq face (if (string-match js2-ecma-global-props name)
- 'font-lock-constant-face))
- (when face
- (setq pos (js2-node-pos node)
- end (+ pos (js2-node-len node)))
- (js2-set-face pos end face 'record))))
- ;; case 2: property access or function call
- ((or (js2-prop-get-node-p node)
- ;; highlight function call if expr is a prop-get node
- ;; or a plain name (i.e. unqualified function call)
- (and (setq call-p (js2-call-node-p node))
- (setq callee (js2-call-node-target node)) ; separate setq!
- (or (js2-prop-get-node-p callee)
- (js2-name-node-p callee))))
- (setq parent node
- node (if call-p callee node))
- (if (and call-p (js2-name-node-p callee))
- (setq prop callee)
- (setq target (js2-prop-get-node-left node)
- prop (js2-prop-get-node-right node)))
- (cond
- ((js2-name-node-p prop)
- ;; case 2(a&c): simple or complex target, simple name, e.g. x[y].bar
- (js2-parse-highlight-prop-get parent target prop call-p))
- ((js2-name-node-p target)
- ;; case 2b: simple target, complex name, e.g. foo.x[y]
- (js2-parse-highlight-prop-get parent target nil call-p)))))))
-
-(defun js2-parse-highlight-member-expr-fn-name (expr)
- "Highlight the `baz' in function foo.bar.baz(args) {...}.
-This is experimental Rhino syntax. EXPR is the foo.bar.baz member expr.
-We currently only handle the case where the last component is a prop-get
-of a simple name. Called before EXPR has a parent node."
- (let (pos
- (name (and (js2-prop-get-node-p expr)
- (js2-prop-get-node-right expr))))
- (when (js2-name-node-p name)
- (js2-set-face (setq pos (+ (js2-node-pos expr) ; parent is absolute
- (js2-node-pos name)))
- (+ pos (js2-node-len name))
- 'font-lock-function-name-face
- 'record))))
-
-;; source: http://jsdoc.sourceforge.net/
-;; Note - this syntax is for Google's enhanced jsdoc parser that
-;; allows type specifications, and needs work before entering the wild.
-
-(defconst js2-jsdoc-param-tag-regexp
- (concat "^\\s-*\\*+\\s-*\\(@"
- (regexp-opt '("param" "arg" "argument" "prop" "property" "typedef"))
- "\\)"
- "\\s-*\\({[^}]+}\\)?" ; optional type
- "\\s-*\\[?\\([[:alnum:]_$\.]+\\)?\\]?" ; name
- "\\_>")
- "Matches jsdoc tags with optional type and optional param name.")
-
-(defconst js2-jsdoc-typed-tag-regexp
- (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
- (regexp-opt
- '("enum"
- "extends"
- "field"
- "id"
- "implements"
- "lends"
- "mods"
- "requires"
- "return"
- "returns"
- "yield"
- "yields"
- "type"
- "throw"
- "throws"))
- "\\)\\)\\s-*\\({[^}]+}\\)?")
- "Matches jsdoc tags with optional type.")
-
-(defconst js2-jsdoc-arg-tag-regexp
- (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
- (regexp-opt
- '("alias"
- "augments"
- "borrows"
- "callback"
- "bug"
- "base"
- "config"
- "default"
- "define"
- "exception"
- "func"
- "function"
- "member"
- "memberOf"
- "method"
- "module"
- "name"
- "namespace"
- "since"
- "suppress"
- "this"
- "throws"
- "version"))
- "\\)\\)\\s-+\\([^ \t\n]+\\)")
- "Matches jsdoc tags with a single argument.")
-
-(defconst js2-jsdoc-empty-tag-regexp
- (concat "^\\s-*\\*+\\s-*\\(@\\(?:"
- (regexp-opt
- '("abstract"
- "addon"
- "author"
- "class"
- "const"
- "constant"
- "constructor"
- "constructs"
- "deprecated"
- "desc"
- "description"
- "event"
- "example"
- "exec"
- "export"
- "fileoverview"
- "final"
- "func"
- "function"
- "hidden"
- "ignore"
- "implicitCast"
- "inheritDoc"
- "inner"
- "interface"
- "license"
- "method"
- "noalias"
- "noshadow"
- "notypecheck"
- "override"
- "owner"
- "preserve"
- "preserveTry"
- "private"
- "protected"
- "public"
- "static"
- "supported"
- "virtual"
- ))
- "\\)\\)\\s-*")
- "Matches empty jsdoc tags.")
-
-(defconst js2-jsdoc-link-tag-regexp
- "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?}"
- "Matches a jsdoc link or code tag.")
-
-(defconst js2-jsdoc-see-tag-regexp
- "^\\s-*\\*+\\s-*\\(@see\\)\\s-+\\([^#}\n]+\\)\\(#.+\\)?"
- "Matches a jsdoc @see tag.")
-
-(defconst js2-jsdoc-html-tag-regexp
- "\\(</?\\)\\([[:alpha:]]+\\)\\s-*\\(/?>\\)"
- "Matches a simple (no attributes) html start- or end-tag.")
-
-(defun js2-jsdoc-highlight-helper ()
- (js2-set-face (match-beginning 1)
- (match-end 1)
- 'js2-jsdoc-tag)
- (if (match-beginning 2)
- (if (save-excursion
- (goto-char (match-beginning 2))
- (= (char-after) ?{))
- (js2-set-face (1+ (match-beginning 2))
- (1- (match-end 2))
- 'js2-jsdoc-type)
- (js2-set-face (match-beginning 2)
- (match-end 2)
- 'js2-jsdoc-value)))
- (if (match-beginning 3)
- (js2-set-face (match-beginning 3)
- (match-end 3)
- 'js2-jsdoc-value)))
-
-(defun js2-highlight-jsdoc (ast)
- "Highlight doc comment tags."
- (let ((comments (js2-ast-root-comments ast))
- beg end)
- (save-excursion
- (dolist (node comments)
- (when (eq (js2-comment-node-format node) 'jsdoc)
- ;; Slice off the leading /* and trailing */ in case there
- ;; are tags on the first line
- (setq beg (+ 2 (js2-node-abs-pos node))
- end (+ beg -4 (js2-node-len node)))
- (save-restriction
- (narrow-to-region beg end)
- (dolist (re (list js2-jsdoc-param-tag-regexp
- js2-jsdoc-typed-tag-regexp
- js2-jsdoc-arg-tag-regexp
- js2-jsdoc-link-tag-regexp
- js2-jsdoc-see-tag-regexp
- js2-jsdoc-empty-tag-regexp))
- (goto-char beg)
- (while (re-search-forward re nil t)
- (js2-jsdoc-highlight-helper)))
- ;; simple highlighting for html tags
- (goto-char beg)
- (while (re-search-forward js2-jsdoc-html-tag-regexp nil t)
- (js2-set-face (match-beginning 1)
- (match-end 1)
- 'js2-jsdoc-html-tag-delimiter)
- (js2-set-face (match-beginning 2)
- (match-end 2)
- 'js2-jsdoc-html-tag-name)
- (js2-set-face (match-beginning 3)
- (match-end 3)
- 'js2-jsdoc-html-tag-delimiter))))))))
-
-(defun js2-highlight-assign-targets (_node left right)
- "Highlight function properties and external variables."
- (let (leftpos name)
- ;; highlight vars and props assigned function values
- (when (or (js2-function-node-p right)
- (js2-class-node-p right))
- (cond
- ;; var foo = function() {...}
- ((js2-name-node-p left)
- (setq name left))
- ;; foo.bar.baz = function() {...}
- ((and (js2-prop-get-node-p left)
- (js2-name-node-p (js2-prop-get-node-right left)))
- (setq name (js2-prop-get-node-right left))))
- (when name
- (js2-set-face (setq leftpos (js2-node-abs-pos name))
- (+ leftpos (js2-node-len name))
- 'font-lock-function-name-face
- 'record)))))
-
-(defun js2-record-name-node (node)
- "Saves NODE to `js2-recorded-identifiers' to check for undeclared variables
-later. NODE must be a name node."
- (let ((leftpos (js2-node-abs-pos node)))
- (push (list node js2-current-scope
- leftpos
- (+ leftpos (js2-node-len node)))
- js2-recorded-identifiers)))
-
-(defun js2-highlight-undeclared-vars ()
- "After entire parse is finished, look for undeclared variable references.
-We have to wait until entire buffer is parsed, since JavaScript permits var
-declarations to occur after they're used.
-
-Some identifiers may be assumed to be externally defined.
-These externs are not highlighted, even if there is no declaration
-for them in the source code (in the current file).
-
-The list of externs consists of the following:
-
- - `js2-ecma262-externs' for basic names from the ECMAScript language
standard.
- - Depending on the buffer-local variables `js2-include-*-externs'
- the corresponding `js2-*-externs' to add names for certain environments
- like the browser, Node or Rhino.
- - Two customizable lists `js2-global-externs' and `js2-additional-externs',
- the latter of which should be set per-buffer.
-
-See especially `js2-additional-externs' for further details about externs."
- (let ((default-externs
- (append js2-ecma-262-externs
- (if (and js2-include-browser-externs
- (>= js2-language-version 200)) js2-harmony-externs)
- (if js2-include-rhino-externs js2-rhino-externs)
- (if js2-include-node-externs js2-node-externs)
- (if (or js2-include-browser-externs js2-include-node-externs)
- js2-typed-array-externs)
- (if js2-include-browser-externs js2-browser-externs)))
- name)
- (dolist (entry js2-recorded-identifiers)
- (cl-destructuring-bind (name-node scope pos end) entry
- (setq name (js2-name-node-name name-node))
- (unless (or (member name js2-global-externs)
- (member name default-externs)
- (member name js2-additional-externs)
- (js2-get-defining-scope scope name pos))
- (js2-report-warning "msg.undeclared.variable" name pos (- end pos)
- 'js2-external-variable))))))
-
-(defun js2--add-or-update-symbol (symbol inition used vars)
- "Add or update SYMBOL entry in VARS, an hash table.
-SYMBOL is a js2-name-node, INITION either nil, t, or ?P,
-respectively meaning that SYMBOL is a mere declaration, an
-assignment or a function parameter; when USED is t, the symbol
-node is assumed to be an usage and thus added to the list stored
-in the cdr of the entry.
-"
- (let* ((nm (js2-name-node-name symbol))
- (es (js2-node-get-enclosing-scope symbol))
- (ds (js2-get-defining-scope es nm)))
- (when (and ds (not (equal nm "arguments")))
- (let* ((sym (js2-scope-get-symbol ds nm))
- (var (gethash sym vars))
- (err-var-p (js2-catch-node-p ds)))
- (unless inition
- (setq inition err-var-p))
- (if var
- (progn
- (when (and inition (not (equal (car var) ?P)))
- (setcar var inition))
- (when (and used (not (memq symbol (cdr var))))
- (push symbol (cdr var))))
- ;; do not consider the declaration of catch parameter as an usage
- (when (and err-var-p used)
- (setq used nil))
- (puthash sym (cons inition (if used (list symbol))) vars))))))
-
-(defun js2--collect-target-symbols (node strict)
- "Collect the `js-name-node' symbols declared in NODE and return a list of
them.
-NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'.
-When STRICT, signal an error if NODE is not one of the expected types."
- (let (targets)
- (cond
- ((js2-name-node-p node)
- (push node targets))
- ((js2-array-node-p node)
- (dolist (elt (js2-array-node-elems node))
- (when elt
- (setq elt (cond ((js2-infix-node-p elt) ;; default (=)
- (js2-infix-node-left elt))
- ((js2-unary-node-p elt) ;; rest (...)
- (js2-unary-node-operand elt))
- (t elt)))
- (setq targets (append (js2--collect-target-symbols elt strict)
- targets)))))
- ((js2-object-node-p node)
- (dolist (elt (js2-object-node-elems node))
- (let ((subexpr (cond
- ((and (js2-infix-node-p elt)
- (= js2-ASSIGN (js2-infix-node-type elt)))
- ;; Destructuring with default argument.
- (js2-infix-node-left elt))
- ((and (js2-infix-node-p elt)
- (= js2-COLON (js2-infix-node-type elt)))
- ;; In regular destructuring {a: aa, b: bb},
- ;; the var is on the right. In abbreviated
- ;; destructuring {a, b}, right == left.
- (js2-infix-node-right elt))
- ((and (js2-unary-node-p elt)
- (= js2-TRIPLEDOT (js2-unary-node-type elt)))
- ;; Destructuring with spread.
- (js2-unary-node-operand elt)))))
- (when subexpr
- (setq targets (append
- (js2--collect-target-symbols subexpr strict)
- targets))))))
- ((js2-assign-node-p node)
- (setq targets (append (js2--collect-target-symbols
- (js2-assign-node-left node) strict)
- targets)))
- (strict
- (js2-report-error "msg.no.parm" nil (js2-node-abs-pos node)
- (js2-node-len node))
- nil))
- targets))
-
-(defun js2--examine-variable (parent node var-init-node)
- "Examine the usage of the variable NODE, a js2-name-node.
-PARENT is its direct ancestor and VAR-INIT-NODE is the node to be
-examined: return a list of three values, respectively if the
-variable is declared and/or assigned or whether it is simply a
-key of a literal object."
- (let ((target (js2-var-init-node-target var-init-node))
- declared assigned object-key)
- (setq declared (memq node (js2--collect-target-symbols target nil)))
- ;; Is there an initializer for the declared variable?
- (when (js2-var-init-node-initializer var-init-node)
- (setq assigned declared)
- ;; Determine if the name is actually a literal object key that we shall
- ;; ignore later
- (when (and (not declared)
- (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left parent)))
- (setq object-key t)))
- ;; Maybe this is a for loop and the variable is one of its iterators?
- (unless assigned
- (let* ((gp (js2-node-parent parent))
- (ggp (if gp (js2-node-parent gp))))
- (when (and ggp (js2-for-in-node-p ggp))
- (setq assigned (memq node
- (cl-loop
- for kid in (js2-var-decl-node-kids
- (js2-for-in-node-iterator ggp))
- with syms = '()
- do
- (setq syms (append syms
- (js2--collect-target-symbols
- (js2-var-init-node-target
kid)
- nil)))
- finally return syms))))))
- (list declared assigned object-key)))
-
-(defun js2--classify-variable (parent node vars)
- "Classify the single variable NODE, a js2-name-node."
- (let ((function-param (and (js2-function-node-p parent)
- (memq node (js2-function-node-params parent)))))
- (if (js2-prop-get-node-p parent)
- ;; If we are within a prop-get, e.g. the "bar" in "foo.bar",
- ;; just mark "foo" as used
- (let ((left (js2-prop-get-node-left parent)))
- (when (js2-name-node-p left)
- (js2--add-or-update-symbol left nil t vars)))
- ;; If the node is the external name of an export-binding-node, and
- ;; it is different from the local name, ignore it
- (when (or (not (js2-export-binding-node-p parent))
- (not (and (eq (js2-export-binding-node-extern-name parent)
node)
- (not (eq (js2-export-binding-node-local-name parent)
node)))))
- (let ((granparent parent)
- var-init-node
- assign-node
- object-key ; is name actually an object prop key?
- declared ; is it declared in narrowest scope?
- assigned ; does it get assigned or initialized?
- (used (null function-param)))
- ;; Determine the closest var-init-node and assign-node: this
- ;; is needed because the name may be within a "destructured"
- ;; declaration/assignment, so we cannot just take its parent
- (while (and granparent (not (js2-scope-p granparent)))
- (cond
- ((js2-var-init-node-p granparent)
- (when (null var-init-node)
- (setq var-init-node granparent)))
- ((js2-assign-node-p granparent)
- (when (null assign-node)
- (setq assign-node granparent))))
- (setq granparent (js2-node-parent granparent)))
-
- ;; If we are within a var-init-node, determine if the name is
- ;; declared and initialized
- (when var-init-node
- (let ((result (js2--examine-variable parent node var-init-node)))
- (setq declared (car result)
- assigned (cadr result)
- object-key (car (cddr result)))))
-
- ;; Ignore literal object keys, which are not really variables
- (unless object-key
- (when function-param
- (setq assigned ?P))
-
- (when (null assigned)
- (cond
- ((js2-for-in-node-p parent)
- (setq assigned (eq node (js2-for-in-node-iterator parent))
- used (not assigned)))
- ((js2-function-node-p parent)
- (setq assigned t
- used (js2-wrapper-function-p parent)))
- ((js2-export-binding-node-p parent)
- (if (js2-import-clause-node-p (js2-node-parent parent))
- (setq declared t
- assigned t)
- (setq used t)))
- ((js2-namespace-import-node-p parent)
- (setq assigned t
- used nil))
- (assign-node
- (setq assigned (memq node
- (js2--collect-target-symbols
- (js2-assign-node-left assign-node)
- nil))
- used (not assigned)))))
-
- (when declared
- (setq used nil))
-
- (js2--add-or-update-symbol node assigned used vars)))))))
-
-(defun js2--classify-variables ()
- "Collect and classify variables declared or used within js2-mode-ast.
-Traverse the whole ast tree returning a summary of the variables
-usage as an hash-table, keyed by their corresponding symbol table
-entry.
-Each variable is described by a tuple where the car is a flag
-indicating whether the variable has been initialized and the cdr
-is a possibly empty list of name nodes where it is used. External
-symbols, i.e. those not present in the whole scopes hierarchy,
-are ignored."
- (let ((vars (make-hash-table :test #'eq :size 100)))
- (js2-visit-ast
- js2-mode-ast
- (lambda (node end-p)
- (when (and (null end-p) (js2-name-node-p node))
- (let ((parent (js2-node-parent node)))
- (when parent
- (js2--classify-variable parent node vars))))
- t))
- vars))
-
-(defun js2--get-name-node (node)
- (cond
- ((js2-name-node-p node) node)
- ((js2-function-node-p node)
- (js2-function-node-name node))
- ((js2-class-node-p node)
- (js2-class-node-name node))
- ((js2-comp-loop-node-p node)
- (js2-comp-loop-node-iterator node))
- (t node)))
-
-(defun js2--highlight-unused-variable (symbol info)
- (let ((name (js2-symbol-name symbol))
- (inited (car info))
- (refs (cdr info))
- pos len)
- (unless (and inited refs)
- (if refs
- (dolist (ref refs)
- (setq pos (js2-node-abs-pos ref))
- (setq len (js2-name-node-len ref))
- (js2-report-warning "msg.uninitialized.variable" name pos len
- 'js2-warning))
- (when (or js2-warn-about-unused-function-arguments
- (not (eq inited ?P)))
- (let* ((symn (js2-symbol-ast-node symbol))
- (namen (js2--get-name-node symn)))
- (unless (js2-node-top-level-decl-p namen)
- (setq pos (js2-node-abs-pos namen))
- (setq len (js2-name-node-len namen))
- (js2-report-warning "msg.unused.variable" name pos len
- 'js2-warning))))))))
-
-(defun js2-highlight-unused-variables ()
- "Highlight unused variables."
- (let ((vars (js2--classify-variables)))
- (maphash #'js2--highlight-unused-variable vars)))
-
-;;;###autoload
-(define-minor-mode js2-highlight-unused-variables-mode
- "Toggle highlight of unused variables."
- :lighter ""
- (if js2-highlight-unused-variables-mode
- (add-hook 'js2-post-parse-callbacks
- #'js2-highlight-unused-variables nil t)
- (remove-hook 'js2-post-parse-callbacks
- #'js2-highlight-unused-variables t)))
-
-(defun js2-add-additional-externs (externs)
- (setq js2-additional-externs
- (nconc externs
- js2-additional-externs)))
-
-(defun js2-get-jslint-comment-identifiers (comment)
- (js2-reparse)
- (cl-loop for node in (js2-ast-root-comments js2-mode-ast)
- when (and (eq 'block (js2-comment-node-format node))
- (save-excursion
- (goto-char (js2-node-abs-pos node))
- (looking-at (concat "/\\* *" comment "\\(?: \\|$\\)"))))
- append (js2-get-jslint-comment-identifiers-in
- (match-end 0)
- (js2-node-abs-end node))))
-
-(defun js2-get-jslint-comment-identifiers-in (beg end)
- (let (res)
- (save-excursion
- (goto-char beg)
- (while (re-search-forward js2-mode-identifier-re end t)
- (let ((match (match-string 0)))
- (unless (member match '("true" "false"))
- (push match res)))))
- (nreverse res)))
-
-(defun js2-apply-jslint-globals ()
- (js2-add-additional-externs (js2-get-jslint-globals)))
-
-(defun js2-get-jslint-globals ()
- (js2-get-jslint-comment-identifiers "global"))
-
-(defun js2-apply-jslint-declaration-externs ()
- (js2-add-additional-externs (js2-get-jslint-declaration-externs)))
-
-(defvar js2-jslint-declaration-externs
- `(("browser" . ,(mapcar 'symbol-name
- '(Audio clearInterval clearTimeout document
- event history Image location name
- navigator Option screen setInterval
- setTimeout XMLHttpRequest)))
- ("node" . ,(mapcar 'symbol-name
- '(Buffer clearImmediate clearInterval
- clearTimeout console exports global module
- process querystring require setImmediate
- setInterval setTimeout __dirname
- __filename)))
- ("es6" . ,(mapcar 'symbol-name
- '(ArrayBuffer DataView Float32Array
- Float64Array Int8Array Int16Array Int32Array
- Intl Map Promise Proxy Reflect Set Symbol
- System Uint8Array Uint8ClampedArray
- Uint16Array Uint32Array WeakMap WeakSet)))
- ("couch" . ,(mapcar 'symbol-name
- '(emit getRow isArray log provides
- registerType require send start sum
- toJSON)))
- ("devel" . ,(mapcar 'symbol-name
- '(alert confirm console Debug opera prompt
- WSH)))))
-
-(defun js2-get-jslint-declaration-externs ()
- (apply 'append
- (mapcar (lambda (identifier)
- (cdr (assoc identifier
- js2-jslint-declaration-externs)))
- (js2-get-jslint-comment-identifiers "jslint"))))
-
-;;; IMenu support
-
-;; We currently only support imenu, but eventually should support speedbar and
-;; possibly other browsing mechanisms.
-
-;; The basic strategy is to identify function assignment targets of the form
-;; `foo.bar.baz', convert them to (list fn foo bar baz <position>), and push
the
-;; list into `js2-imenu-recorder'. The lists are merged into a trie-like tree
-;; for imenu after parsing is finished.
-
-;; A `foo.bar.baz' assignment target may be expressed in many ways in
-;; JavaScript, and the general problem is undecidable. However, several forms
-;; are readily recognizable at parse-time; the forms we attempt to recognize
-;; include:
-
-;; function foo() -- function declaration
-;; foo = function() -- function expression assigned to variable
-;; foo.bar.baz = function() -- function expr assigned to nested property-get
-;; foo = {bar: function()} -- fun prop in object literal assigned to var
-;; foo = {bar: {baz: function()}} -- inside nested object literal
-;; foo.bar = {baz: function()}} -- obj lit assigned to nested prop get
-;; a.b = {c: {d: function()}} -- nested obj lit assigned to nested prop get
-;; foo = {get bar() {...}} -- getter/setter in obj literal
-;; function foo() {function bar() {...}} -- nested function
-;; foo['a'] = function() -- fun expr assigned to deterministic element-get
-
-;; This list boils down to a few forms that can be combined recursively.
-;; Top-level named function declarations include both the left-hand (name)
-;; and the right-hand (function value) expressions needed to produce an imenu
-;; entry. The other "right-hand" forms we need to look for are:
-;; - functions declared as props/getters/setters in object literals
-;; - nested named function declarations
-;; The "left-hand" expressions that functions can be assigned to include:
-;; - local/global variables
-;; - nested property-get expressions like a.b.c.d
-;; - element gets like foo[10] or foo['bar'] where the index
-;; expression can be trivially converted to a property name. They
-;; effectively then become property gets.
-
-;; All the different definition types are canonicalized into the form
-;; foo.bar.baz = position-of-function-keyword
-
-;; We need to build a trie-like structure for imenu. As an example,
-;; consider the following JavaScript code:
-
-;; a = function() {...} // function at position 5
-;; b = function() {...} // function at position 25
-;; foo = function() {...} // function at position 100
-;; foo.bar = function() {...} // function at position 200
-;; foo.bar.baz = function() {...} // function at position 300
-;; foo.bar.zab = function() {...} // function at position 400
-
-;; During parsing we accumulate an entry for each definition in
-;; the variable `js2-imenu-recorder', like so:
-
-;; '((fn a 5)
-;; (fn b 25)
-;; (fn foo 100)
-;; (fn foo bar 200)
-;; (fn foo bar baz 300)
-;; (fn foo bar zab 400))
-
-;; Where 'fn' is the respective function node.
-;; After parsing these entries are merged into this alist-trie:
-
-;; '((a . 1)
-;; (b . 2)
-;; (foo (<definition> . 3)
-;; (bar (<definition> . 6)
-;; (baz . 100)
-;; (zab . 200))))
-
-;; Note the wacky need for a <definition> name. The token can be anything
-;; that isn't a valid JavaScript identifier, because you might make foo
-;; a function and then start setting properties on it that are also functions.
-
-(defun js2-prop-node-name (node)
- "Return the name of a node that may be a property-get/property-name.
-If NODE is not a valid name-node, string-node or integral number-node,
-returns nil. Otherwise returns the string name/value of the node."
- (cond
- ((js2-name-node-p node)
- (js2-name-node-name node))
- ((js2-string-node-p node)
- (js2-string-node-value node))
- ((and (js2-number-node-p node)
- (string-match "^[0-9]+$" (js2-number-node-value node)))
- (js2-number-node-value node))
- ((eq (js2-node-type node) js2-THIS)
- "this")
- ((eq (js2-node-type node) js2-SUPER)
- "super")))
-
-(defun js2-node-qname-component (node)
- "Return the name of this node, if it contributes to a qname.
-Returns nil if the node doesn't contribute."
- (copy-sequence
- (or (js2-prop-node-name node)
- (cond
- ((and (js2-function-node-p node)
- (js2-function-node-name node))
- (js2-name-node-name (js2-function-node-name node)))
- ((js2-computed-prop-name-node-p node)
- "[computed]")))))
-
-(defun js2-record-imenu-entry (fn-node qname pos)
- "Add an entry to `js2-imenu-recorder'.
-FN-NODE should be the current item's function node.
-
-Associate FN-NODE with its QNAME for later lookup.
-This is used in postprocessing the chain list. For each chain, we find
-the parent function, look up its qname, then prepend a copy of it to the
chain."
- (push (cons fn-node (append qname (list pos))) js2-imenu-recorder)
- (unless js2-imenu-function-map
- (setq js2-imenu-function-map (make-hash-table :test 'eq)))
- (puthash fn-node qname js2-imenu-function-map))
-
-(defun js2-record-imenu-functions (node &optional var)
- "Record function definitions for imenu.
-NODE is a function node or an object literal.
-VAR, if non-nil, is the expression that NODE is being assigned to.
-When passed arguments of wrong type, does nothing."
- (when js2-parse-ide-mode
- (let ((fun-p (js2-function-node-p node))
- qname fname-node)
- (cond
- ;; non-anonymous function declaration?
- ((and fun-p
- (not var)
- (setq fname-node (js2-function-node-name node)))
- (js2-record-imenu-entry node (list fname-node) (js2-node-pos node)))
- ;; for remaining forms, compute left-side tree branch first
- ((and var (setq qname (js2-compute-nested-prop-get var)))
- (cond
- ;; foo.bar.baz = function
- (fun-p
- (js2-record-imenu-entry node qname (js2-node-pos node)))
- ;; foo.bar.baz = object-literal
- ;; look for nested functions: {a: {b: function() {...} }}
- ((js2-object-node-p node)
- ;; Node position here is still absolute, since the parser
- ;; passes the assignment target and value expressions
- ;; to us before they are added as children of the assignment node.
- (js2-record-object-literal node qname (js2-node-pos node)))))))))
-
-(defun js2-compute-nested-prop-get (node)
- "If NODE is of form foo.bar, foo[\\='bar\\='], or any nested combination,
return
-component nodes as a list. Otherwise return nil. Element-gets are treated
-as property-gets if the index expression is a string, or a positive integer."
- (let (left right head)
- (cond
- ((or (js2-name-node-p node)
- (js2-this-or-super-node-p node))
- (list node))
- ;; foo.bar.baz is parenthesized as (foo.bar).baz => right operand is a
leaf
- ((js2-prop-get-node-p node) ; foo.bar
- (setq left (js2-prop-get-node-left node)
- right (js2-prop-get-node-right node))
- (if (setq head (js2-compute-nested-prop-get left))
- (nconc head (list right))))
- ((js2-elem-get-node-p node) ; foo['bar'] or foo[101]
- (setq left (js2-elem-get-node-target node)
- right (js2-elem-get-node-element node))
- (if (or (js2-string-node-p right) ; ['bar']
- (and (js2-number-node-p right) ; [10]
- (string-match "^[0-9]+$"
- (js2-number-node-value right))))
- (if (setq head (js2-compute-nested-prop-get left))
- (nconc head (list right))))))))
-
-(defun js2-record-object-literal (node qname pos)
- "Recursively process an object literal looking for functions.
-NODE is an object literal that is the right-hand child of an assignment
-expression. QNAME is a list of nodes representing the assignment target,
-e.g. for foo.bar.baz = {...}, QNAME is (foo-node bar-node baz-node).
-POS is the absolute position of the node.
-We do a depth-first traversal of NODE. For any functions we find,
-we append the property name to QNAME, then call `js2-record-imenu-entry'."
- (let (right)
- (dolist (e (js2-object-node-elems node)) ; e is a `js2-object-prop-node'
- (when (js2-infix-node-p e)
- (let ((left (js2-infix-node-left e))
- ;; Element positions are relative to the parent position.
- (pos (+ pos (js2-node-pos e))))
- (cond
- ;; foo: function() {...}
- ((js2-function-node-p (setq right (js2-infix-node-right e)))
- (when (js2-prop-node-name left)
- ;; As a policy decision, we record the position of the property,
- ;; not the position of the `function' keyword, since the property
- ;; is effectively the name of the function.
- (js2-record-imenu-entry right (append qname (list left)) pos)))
- ;; foo: {object-literal} -- add foo to qname, offset position, and
recurse
- ((js2-object-node-p right)
- (js2-record-object-literal right
- (append qname (list
(js2-infix-node-left e)))
- (+ pos (js2-node-pos right))))))))))
-
-(defun js2-node-top-level-decl-p (node)
- "Return t if NODE's name is defined in the top-level scope.
-Also returns t if NODE's name is not defined in any scope, since it implies
-that it's an external variable, which must also be in the top-level scope."
- (let* ((name (js2-prop-node-name node))
- (this-scope (js2-node-get-enclosing-scope node))
- defining-scope)
- (cond
- ((js2-this-or-super-node-p node)
- nil)
- ((null this-scope)
- t)
- ((setq defining-scope (js2-get-defining-scope this-scope name))
- (js2-ast-root-p defining-scope))
- (t t))))
-
-(defun js2-wrapper-function-p (node)
- "Return t if NODE is a function expression that's immediately invoked.
-NODE must be `js2-function-node'."
- (let ((parent (js2-node-parent node)))
- (or
- ;; function(){...}();
- (and (js2-call-node-p parent)
- (eq node (js2-call-node-target parent)))
- (and (js2-paren-node-p parent)
- ;; (function(){...})();
- (or (js2-call-node-p (setq parent (js2-node-parent parent)))
- ;; (function(){...}).call(this);
- (and (js2-prop-get-node-p parent)
- (member (js2-name-node-name (js2-prop-get-node-right
parent))
- '("call" "apply"))
- (js2-call-node-p (js2-node-parent parent))))))))
-
-(defun js2-browse-postprocess-chains ()
- "Modify function-declaration name chains after parsing finishes.
-Some of the information is only available after the parse tree is complete.
-For instance, processing a nested scope requires a parent function node."
- (let (result fn parent-qname p elem)
- (dolist (entry js2-imenu-recorder)
- ;; function node goes first
- (cl-destructuring-bind (current-fn &rest (&whole chain head &rest)) entry
- ;; Examine head's defining scope:
- ;; Pre-processed chain, or top-level/external, keep as-is.
- (if (or (stringp head) (js2-node-top-level-decl-p head))
- (push chain result)
- (when (js2-this-or-super-node-p head)
- (setq chain (cdr chain))) ; discard this-node
- (when (setq fn (js2-node-parent-script-or-fn current-fn))
- (setq parent-qname (gethash fn js2-imenu-function-map 'not-found))
- (when (eq parent-qname 'not-found)
- ;; anonymous function expressions are not recorded
- ;; during the parse, so we need to handle this case here
- (setq parent-qname
- (if (js2-wrapper-function-p fn)
- (let ((grandparent (js2-node-parent-script-or-fn fn)))
- (if (js2-ast-root-p grandparent)
- nil
- (gethash grandparent js2-imenu-function-map
'skip)))
- 'skip))
- (puthash fn parent-qname js2-imenu-function-map))
- (if (eq parent-qname 'skip)
- ;; We don't show it, let's record that fact.
- (remhash current-fn js2-imenu-function-map)
- ;; Prepend parent fn qname to this chain.
- (let ((qname (append parent-qname chain)))
- (puthash current-fn (butlast qname) js2-imenu-function-map)
- (push qname result)))))))
- ;; Collect chains obtained by third-party code.
- (let (js2-imenu-recorder)
- (run-hooks 'js2-build-imenu-callbacks)
- (dolist (entry js2-imenu-recorder)
- (push (cdr entry) result)))
- ;; Finally replace each node in each chain with its name.
- (dolist (chain result)
- (setq p chain)
- (while p
- (if (js2-node-p (setq elem (car p)))
- (setcar p (js2-node-qname-component elem)))
- (setq p (cdr p))))
- result))
-
-;; Merge name chains into a trie-like tree structure of nested lists.
-;; To simplify construction of the trie, we first build it out using the rule
-;; that the trie consists of lists of pairs. Each pair is a 2-element array:
-;; [key, num-or-list]. The second element can be a number; if so, this key
-;; is a leaf-node with only one value. (I.e. there is only one declaration
-;; associated with the key at this level.) Otherwise the second element is
-;; a list of pairs, with the rule applied recursively. This symmetry permits
-;; a simple recursive formulation.
-;;
-;; js2-mode is building the data structure for imenu. The imenu documentation
-;; claims that it's the structure above, but in practice it wants the children
-;; at the same list level as the key for that level, which is how I've drawn
-;; the "Expected final result" above. We'll postprocess the trie to remove the
-;; list wrapper around the children at each level.
-;;
-;; A completed nested imenu-alist entry looks like this:
-;; '(("foo"
-;; ("<definition>" . 7)
-;; ("bar"
-;; ("a" . 40)
-;; ("b" . 60))))
-;;
-;; In particular, the documentation for `imenu--index-alist' says that
-;; a nested sub-alist element looks like (INDEX-NAME SUB-ALIST).
-;; The sub-alist entries immediately follow INDEX-NAME, the head of the list.
-
-(defun js2-treeify (lst)
- "Convert (a b c d) to (a ((b ((c d)))))."
- (if (null (cddr lst)) ; list length <= 2
- lst
- (list (car lst) (list (js2-treeify (cdr lst))))))
-
-(defun js2-build-alist-trie (chains trie)
- "Merge declaration name chains into a trie-like alist structure for imenu.
-CHAINS is the qname chain list produced during parsing. TRIE is a
-list of elements built up so far."
- (let (head tail pos branch kids)
- (dolist (chain chains)
- (setq head (car chain)
- tail (cdr chain)
- pos (if (numberp (car tail)) (car tail))
- branch (js2-find-if (lambda (n)
- (string= (car n) head))
- trie)
- kids (cl-second branch))
- (cond
- ;; case 1: this key isn't in the trie yet
- ((null branch)
- (if trie
- (setcdr (last trie) (list (js2-treeify chain)))
- (setq trie (list (js2-treeify chain)))))
- ;; case 2: key is present with a single number entry: replace w/ list
- ;; ("a1" 10) + ("a1" 20) => ("a1" (("<definition>" 10)
- ;; ("<definition>" 20)))
- ((numberp kids)
- (setcar (cdr branch)
- (list (list "<definition-1>" kids)
- (if pos
- (list "<definition-2>" pos)
- (js2-treeify tail)))))
- ;; case 3: key is there (with kids), and we're a number entry
- (pos
- (setcdr (last kids)
- (list
- (list (format "<definition-%d>"
- (1+ (cl-loop for kid in kids
- count (eq ?< (aref (car kid) 0)))))
- pos))))
- ;; case 4: key is there with kids, need to merge in our chain
- (t
- (js2-build-alist-trie (list tail) kids))))
- trie))
-
-(defun js2-flatten-trie (trie)
- "Convert TRIE to imenu-format.
-Recurses through nodes, and for each one whose second element is a list,
-appends the list's flattened elements to the current element. Also
-changes the tails into conses. For instance, this pre-flattened trie
-
- (a ((b 20)
- (c ((d 30)
- (e 40)))))
-
-becomes
-
- (a (b . 20)
- (c (d . 30)
- (e . 40)))
-
-Note that the root of the trie has no key, just a list of chains.
-This is also true for the value of any key with multiple children,
-e.g. key `c' in the example above."
- (cond
- ((listp (car trie))
- (mapcar #'js2-flatten-trie trie))
- (t
- (if (numberp (cl-second trie))
- (cons (car trie) (cl-second trie))
- ;; else pop list and append its kids
- (apply #'append (list (car trie)) (js2-flatten-trie (cdr trie)))))))
-
-(defun js2-build-imenu-index ()
- "Turn `js2-imenu-recorder' into an imenu data structure."
- (when (eq js2-imenu-recorder 'empty)
- (setq js2-imenu-recorder nil))
- (let* ((chains (js2-browse-postprocess-chains))
- (result (js2-build-alist-trie chains nil)))
- (js2-flatten-trie result)))
-
-(defun js2-test-print-chains (chains)
- "Print a list of qname chains.
-Each element of CHAINS is a list of the form (NODE [NODE *] pos);
-i.e. one or more nodes, and an integer position as the list tail."
- (mapconcat (lambda (chain)
- (concat "("
- (mapconcat (lambda (elem)
- (if (js2-node-p elem)
- (or (js2-node-qname-component elem)
- "nil")
- (number-to-string elem)))
- chain
- " ")
- ")"))
- chains
- "\n"))
-
-;;; Parser
-
-(defconst js2-version "1.8.5"
- "Version of JavaScript supported.")
-
-(defun js2-record-face (face &optional token)
- "Record a style run of FACE for TOKEN or the current token."
- (unless token (setq token (js2-current-token)))
- (js2-set-face (js2-token-beg token) (js2-token-end token) face 'record))
-
-(defsubst js2-node-end (n)
- "Computes the absolute end of node N.
-Use with caution! Assumes `js2-node-pos' is -absolute-, which
-is only true until the node is added to its parent; i.e., while parsing."
- (+ (js2-node-pos n)
- (js2-node-len n)))
-
-(defun js2-record-comment (token)
- "Record a comment in `js2-scanned-comments'."
- (let ((ct (js2-token-comment-type token))
- (beg (js2-token-beg token))
- (end (js2-token-end token)))
- (push (make-js2-comment-node :len (- end beg)
- :format ct)
- js2-scanned-comments)
- (when js2-parse-ide-mode
- (js2-record-face (if (eq ct 'jsdoc)
- 'font-lock-doc-face
- 'font-lock-comment-face)
- token)
- (when (memq ct '(html preprocessor))
- ;; Tell cc-engine the bounds of the comment.
- (js2-record-text-property beg (1- end) 'c-in-sws t)))))
-
-(defun js2-peek-token (&optional modifier)
- "Return the next token type without consuming it.
-If `js2-ti-lookahead' is positive, return the type of next token
-from `js2-ti-tokens'. Otherwise, call `js2-get-token'."
- (if (not (zerop js2-ti-lookahead))
- (js2-token-type
- (aref js2-ti-tokens (mod (1+ js2-ti-tokens-cursor) js2-ti-ntokens)))
- (let ((tt (js2-get-token-internal modifier)))
- (js2-unget-token)
- tt)))
-
-(defalias 'js2-next-token 'js2-get-token)
-
-(defun js2-match-token (match &optional dont-unget)
- "Get next token and return t if it matches MATCH, a bytecode.
-Returns nil and consumes nothing if MATCH is not the next token."
- (if (/= (js2-get-token) match)
- (ignore (unless dont-unget (js2-unget-token)))
- t))
-
-(defun js2-match-contextual-kwd (name)
- "Consume and return t if next token is `js2-NAME', and its
-string is NAME. Returns nil and keeps current token otherwise."
- (if (js2-contextual-kwd-p (progn (js2-get-token)
- (js2-current-token))
- name)
- (progn (js2-record-face 'font-lock-keyword-face) t)
- (js2-unget-token)
- nil))
-
-(defun js2-contextual-kwd-p (token name)
- "Return t if TOKEN is `js2-NAME', and its string is NAME."
- (and (= (js2-token-type token) js2-NAME)
- (string= (js2-token-string token) name)))
-
-(defun js2-match-async-function ()
- (when (and (js2-contextual-kwd-p (js2-current-token) "async")
- (= (js2-peek-token) js2-FUNCTION))
- (js2-record-face 'font-lock-keyword-face)
- (js2-get-token)
- t))
-
-(defun js2-match-async-arrow-function ()
- (and (js2-contextual-kwd-p (js2-current-token) "async")
- (/= (js2-peek-token) js2-FUNCTION)))
-
-(defsubst js2-inside-function ()
- (cl-plusp js2-nesting-of-function))
-
-(defsubst js2-inside-async-function ()
- (and (js2-inside-function)
- (js2-function-node-async js2-current-script-or-fn)))
-
-(defun js2-parse-await-maybe (tt)
- "Parse \"await\" as an AwaitExpression, if it is one."
- (and (= tt js2-NAME)
- (js2-contextual-kwd-p (js2-current-token) "await")
- ;; Per the proposal, AwaitExpression consists of "await"
- ;; followed by a UnaryExpression. So look ahead for one.
- (let ((ts-state (make-js2-ts-state))
- (recorded-identifiers js2-recorded-identifiers)
- (parsed-errors js2-parsed-errors)
- (current-token (js2-current-token))
- (beg (js2-current-token-beg))
- (end (js2-current-token-end))
- pn)
- (js2-get-token)
- (setq pn (js2-make-unary beg js2-AWAIT 'js2-parse-unary-expr))
- (if (= (js2-node-type (js2-unary-node-operand pn)) js2-ERROR)
- ;; The parse failed, so pretend like nothing happened and restore
- ;; the previous parsing state.
- (progn
- (js2-ts-seek ts-state)
- (setq js2-recorded-identifiers recorded-identifiers
- js2-parsed-errors parsed-errors)
- ;; And ensure the caller knows about the failure.
- nil)
- ;; The parse was successful, so process and return the "await".
- (js2-record-face 'font-lock-keyword-face current-token)
- (unless (js2-inside-async-function)
- (js2-report-error "msg.bad.await" nil
- beg (- end beg)))
- pn))))
-
-(defun js2-get-prop-name-token ()
- (js2-get-token (and (>= js2-language-version 170) 'KEYWORD_IS_NAME)))
-
-(defun js2-match-prop-name ()
- "Consume token and return t if next token is a valid property name.
-If `js2-language-version' is >= 180, a keyword or reserved word
-is considered valid name as well."
- (if (eq js2-NAME (js2-get-prop-name-token))
- t
- (js2-unget-token)
- nil))
-
-(defun js2-must-match-prop-name (msg-id &optional pos len)
- (if (js2-match-prop-name)
- t
- (js2-report-error msg-id nil pos len)
- nil))
-
-(defun js2-peek-token-or-eol ()
- "Return js2-EOL if the next token immediately follows a newline.
-Else returns the next token. Used in situations where we don't
-consider certain token types valid if they are preceded by a newline.
-One example is the postfix ++ or -- operator, which has to be on the
-same line as its operand."
- (let ((tt (js2-get-token))
- (follows-eol (js2-token-follows-eol-p (js2-current-token))))
- (js2-unget-token)
- (if follows-eol
- js2-EOL
- tt)))
-
-(defun js2-must-match (token msg-id &optional pos len)
- "Match next token to token code TOKEN, or record a syntax error.
-MSG-ID is the error message to report if the match fails.
-Returns t on match, nil if no match."
- (if (js2-match-token token t)
- t
- (js2-report-error msg-id nil pos len)
- (js2-unget-token)
- nil))
-
-(defun js2-must-match-name (msg-id)
- (if (js2-match-token js2-NAME t)
- t
- (if (eq (js2-current-token-type) js2-RESERVED)
- (js2-report-error "msg.reserved.id" (js2-current-token-string))
- (js2-report-error msg-id)
- (js2-unget-token))
- nil))
-
-(defun js2-set-requires-activation ()
- (if (js2-function-node-p js2-current-script-or-fn)
- (setf (js2-function-node-needs-activation js2-current-script-or-fn) t)))
-
-(defun js2-check-activation-name (name _token)
- (when (js2-inside-function)
- ;; skip language-version 1.2 check from Rhino
- (if (or (string= "arguments" name)
- (and js2-compiler-activation-names ; only used in codegen
- (gethash name js2-compiler-activation-names)))
- (js2-set-requires-activation))))
-
-(defun js2-set-is-generator ()
- (let ((fn-node js2-current-script-or-fn))
- (when (and (js2-function-node-p fn-node)
- (not (js2-function-node-generator-type fn-node)))
- (setf (js2-function-node-generator-type js2-current-script-or-fn)
'LEGACY))))
-
-(defun js2-must-have-xml ()
- (unless js2-compiler-xml-available
- (js2-report-error "msg.XML.not.available")))
-
-(defun js2-push-scope (scope)
- "Push SCOPE, a `js2-scope', onto the lexical scope chain."
- (cl-assert (js2-scope-p scope))
- (cl-assert (null (js2-scope-parent-scope scope)))
- (cl-assert (not (eq js2-current-scope scope)))
- (setf (js2-scope-parent-scope scope) js2-current-scope
- js2-current-scope scope))
-
-(defsubst js2-pop-scope ()
- (setq js2-current-scope
- (js2-scope-parent-scope js2-current-scope)))
-
-(defun js2-enter-loop (loop-node)
- (push loop-node js2-loop-set)
- (push loop-node js2-loop-and-switch-set)
- (js2-push-scope loop-node)
- ;; Tell the current labeled statement (if any) its statement,
- ;; and set the jump target of the first label to the loop.
- ;; These are used in `js2-parse-continue' to verify that the
- ;; continue target is an actual labeled loop. (And for codegen.)
- (when js2-labeled-stmt
- (setf (js2-labeled-stmt-node-stmt js2-labeled-stmt) loop-node
- (js2-label-node-loop (car (js2-labeled-stmt-node-labels
- js2-labeled-stmt))) loop-node)))
-
-(defun js2-exit-loop ()
- (pop js2-loop-set)
- (pop js2-loop-and-switch-set)
- (js2-pop-scope))
-
-(defsubst js2-enter-switch (switch-node)
- (js2-push-scope switch-node)
- (push switch-node js2-loop-and-switch-set))
-
-(defsubst js2-exit-switch ()
- (js2-pop-scope)
- (pop js2-loop-and-switch-set))
-
-(defsubst js2-get-directive (node)
- "Return NODE's value if it is a directive, nil otherwise.
-
-A directive is an otherwise-meaningless expression statement
-consisting of a string literal, such as \"use strict\"."
- (and (js2-expr-stmt-node-p node)
- (js2-string-node-p (setq node (js2-expr-stmt-node-expr node)))
- (js2-string-node-value node)))
-
-(defun js2-parse (&optional buf cb)
- "Tell the js2 parser to parse a region of JavaScript.
-
-BUF is a buffer or buffer name containing the code to parse.
-Call `narrow-to-region' first to parse only part of the buffer.
-
-The returned AST root node is given some additional properties:
- `node-count' - total number of nodes in the AST
- `buffer' - BUF. The buffer it refers to may change or be killed,
- so the value is not necessarily reliable.
-
-An optional callback CB can be specified to report parsing
-progress. If (functionp CB) returns t, it will be called with
-the current line number once before parsing begins, then again
-each time the lexer reaches a new line number.
-
-CB can also be a list of the form (symbol cb ...) to specify
-multiple callbacks with different criteria. Each symbol is a
-criterion keyword, and the following element is the callback to
-call
-
- :line - called whenever the line number changes
- :token - called for each new token consumed
-
-The list of criteria could be extended to include entering or
-leaving a statement, an expression, or a function definition."
- (if (and cb (not (functionp cb)))
- (error "criteria callbacks not yet implemented"))
- (let ((inhibit-point-motion-hooks t)
- (js2-compiler-xml-available (>= js2-language-version 160))
- ;; This is a recursive-descent parser, so give it a big stack.
- (max-lisp-eval-depth (max max-lisp-eval-depth 3000))
- (max-specpdl-size (max max-specpdl-size 3000))
- (case-fold-search nil)
- ast)
- (with-current-buffer (or buf (current-buffer))
- (setq js2-scanned-comments nil
- js2-parsed-errors nil
- js2-parsed-warnings nil
- js2-imenu-recorder nil
- js2-imenu-function-map nil
- js2-label-set nil)
- (js2-init-scanner)
- (setq ast (js2-do-parse))
- (unless js2-ts-hit-eof
- (js2-report-error "msg.got.syntax.errors" (length js2-parsed-errors)))
- (setf (js2-ast-root-errors ast) js2-parsed-errors
- (js2-ast-root-warnings ast) js2-parsed-warnings)
- ;; if we didn't find any declarations, put a dummy in this list so we
- ;; don't end up re-parsing the buffer in `js2-mode-create-imenu-index'
- (unless js2-imenu-recorder
- (setq js2-imenu-recorder 'empty))
- (run-hooks 'js2-parse-finished-hook)
- ast)))
-
-;; Corresponds to Rhino's Parser.parse() method.
-(defun js2-do-parse ()
- "Parse current buffer starting from current point.
-Scanner should be initialized."
- (let ((pos js2-ts-cursor)
- (end js2-ts-cursor) ; in case file is empty
- root n tt
- (in-directive-prologue t)
- (js2-in-use-strict-directive js2-in-use-strict-directive)
- directive)
- ;; initialize buffer-local parsing vars
- (setf root (make-js2-ast-root :buffer (buffer-name) :pos pos)
- js2-current-script-or-fn root
- js2-current-scope root
- js2-nesting-of-function 0
- js2-labeled-stmt nil
- js2-recorded-identifiers nil ; for js2-highlight
- js2-in-use-strict-directive js2-mode-assume-strict)
- (while (/= (setq tt (js2-get-token)) js2-EOF)
- (if (= tt js2-FUNCTION)
- (progn
- (setq n (if js2-called-by-compile-function
- (js2-parse-function-expr)
- (js2-parse-function-stmt))))
- ;; not a function - parse a statement
- (js2-unget-token)
- (setq n (js2-parse-statement))
- (when in-directive-prologue
- (setq directive (js2-get-directive n))
- (cond
- ((null directive)
- (setq in-directive-prologue nil))
- ((string= directive "use strict")
- (setq js2-in-use-strict-directive t)))))
- ;; add function or statement to script
- (setq end (js2-node-end n))
- (js2-block-node-push root n))
- ;; add comments to root in lexical order
- (when js2-scanned-comments
- ;; if we find a comment beyond end of normal kids, use its end
- (setq end (max end (js2-node-end (cl-first js2-scanned-comments))))
- (dolist (comment js2-scanned-comments)
- (push comment (js2-ast-root-comments root))
- (js2-node-add-children root comment)))
- (setf (js2-node-len root) (- end pos))
- (setq js2-mode-ast root) ; Make sure this is available for callbacks.
- ;; Give extensions a chance to muck with things before highlighting starts.
- (let ((js2-additional-externs js2-additional-externs))
- (js2-filter-parsed-warnings)
- (save-excursion
- (run-hooks 'js2-post-parse-callbacks))
- (js2-highlight-undeclared-vars))
- root))
-
-(defun js2-filter-parsed-warnings ()
- "Remove `js2-parsed-warnings' elements that match `js2-ignored-warnings'."
- (when js2-ignored-warnings
- (setq js2-parsed-warnings
- (cl-remove-if
- (lambda (warning)
- (let ((msg (caar warning)))
- (member msg js2-ignored-warnings)))
- js2-parsed-warnings)))
- js2-parsed-warnings)
-
-(defun js2-parse-function-closure-body (fn-node)
- "Parse a JavaScript 1.8 function closure body."
- (let ((js2-nesting-of-function (1+ js2-nesting-of-function)))
- (if js2-ts-hit-eof
- (js2-report-error "msg.no.brace.body" nil
- (js2-node-pos fn-node)
- (- js2-ts-cursor (js2-node-pos fn-node)))
- (js2-node-add-children fn-node
- (setf (js2-function-node-body fn-node)
- (js2-parse-expr t))))))
-
-(defun js2-parse-function-body (fn-node)
- (js2-must-match js2-LC "msg.no.brace.body"
- (js2-node-pos fn-node)
- (- js2-ts-cursor (js2-node-pos fn-node)))
- (let ((pos (js2-current-token-beg)) ; LC position
- (pn (make-js2-block-node)) ; starts at LC position
- tt
- end
- not-in-directive-prologue
- node
- directive)
- (cl-incf js2-nesting-of-function)
- (unwind-protect
- (while (not (or (= (setq tt (js2-peek-token)) js2-ERROR)
- (= tt js2-EOF)
- (= tt js2-RC)))
- (js2-block-node-push
- pn
- (if (/= tt js2-FUNCTION)
- (if not-in-directive-prologue
- (js2-parse-statement)
- (setq node (js2-parse-statement)
- directive (js2-get-directive node))
- (cond
- ((null directive)
- (setq not-in-directive-prologue t))
- ((string= directive "use strict")
- ;; Back up and reparse the function, because new rules apply
- ;; to the function name and parameters.
- (when (not js2-in-use-strict-directive)
- (setq js2-in-use-strict-directive t)
- (throw 'reparse t))))
- node)
- (js2-get-token)
- (js2-parse-function-stmt))))
- (cl-decf js2-nesting-of-function))
- (setq end (js2-current-token-end)) ; assume no curly and leave at current
token
- (if (js2-must-match js2-RC "msg.no.brace.after.body" pos)
- (setq end (js2-current-token-end)))
- (setf (js2-node-pos pn) pos
- (js2-node-len pn) (- end pos))
- (setf (js2-function-node-body fn-node) pn)
- (js2-node-add-children fn-node pn)
- pn))
-
-(defun js2-define-destruct-symbols (node decl-type face &optional
ignore-not-in-block)
- "Declare and fontify destructuring parameters inside NODE.
-NODE is either `js2-array-node', `js2-object-node', or `js2-name-node'.
-
-Return a list of `js2-name-node' nodes representing the symbols
-declared; probably to check them for errors."
- (let ((name-nodes (js2--collect-target-symbols node t)))
- (dolist (node name-nodes)
- (let (leftpos)
- (js2-define-symbol decl-type (js2-name-node-name node)
- node ignore-not-in-block)
- (when face
- (js2-set-face (setq leftpos (js2-node-abs-pos node))
- (+ leftpos (js2-node-len node))
- face 'record))))
- name-nodes))
-
-(defvar js2-illegal-strict-identifiers
- '("eval" "arguments")
- "Identifiers not allowed as variables in strict mode.")
-
-(defun js2-check-strict-identifier (name-node)
- "Check that NAME-NODE makes a legal strict mode identifier."
- (when js2-in-use-strict-directive
- (let ((param-name (js2-name-node-name name-node)))
- (when (member param-name js2-illegal-strict-identifiers)
- (js2-report-error "msg.bad.id.strict" param-name
- (js2-node-abs-pos name-node) (js2-node-len
name-node))))))
-
-(defun js2-check-strict-function-params (preceding-params params)
- "Given PRECEDING-PARAMS in a function's parameter list, check
-for strict mode errors caused by PARAMS."
- (when js2-in-use-strict-directive
- (dolist (param params)
- (let ((param-name (js2-name-node-name param)))
- (js2-check-strict-identifier param)
- (when (cl-some (lambda (param)
- (string= (js2-name-node-name param) param-name))
- preceding-params)
- (js2-report-error "msg.dup.param.strict" param-name
- (js2-node-abs-pos param) (js2-node-len param)))))))
-
-(defun js2-parse-function-params (function-type fn-node pos)
- "Parse the parameters of a function of FUNCTION-TYPE
-represented by FN-NODE at POS."
- (if (js2-match-token js2-RP)
- (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos))
- (let ((paren-free-arrow (and (eq function-type 'FUNCTION_ARROW)
- (eq (js2-current-token-type) js2-NAME)))
- params param
- param-name-nodes new-param-name-nodes
- rest-param-at)
- (when paren-free-arrow
- (js2-unget-token))
- (cl-loop for tt = (js2-peek-token)
- do
- (cond
- ;; destructuring param
- ((and (not paren-free-arrow)
- (or (= tt js2-LB) (= tt js2-LC)))
- (js2-get-token)
- (setq param (js2-parse-destruct-primary-expr)
- new-param-name-nodes (js2-define-destruct-symbols
- param js2-LP 'js2-function-param))
- (js2-check-strict-function-params param-name-nodes
new-param-name-nodes)
- (setq param-name-nodes (append param-name-nodes
new-param-name-nodes)))
- ;; variable name
- (t
- (when (and (>= js2-language-version 200)
- (not paren-free-arrow)
- (js2-match-token js2-TRIPLEDOT)
- (not rest-param-at))
- ;; to report errors if there are more parameters
- (setq rest-param-at (length params)))
- (js2-must-match-name "msg.no.parm")
- (js2-record-face 'js2-function-param)
- (setq param (js2-create-name-node))
- (js2-define-symbol js2-LP (js2-current-token-string) param)
- (js2-check-strict-function-params param-name-nodes (list
param))
- (setq param-name-nodes (append param-name-nodes (list
param)))))
- ;; default parameter value
- (when (and (not rest-param-at)
- (>= js2-language-version 200)
- (js2-match-token js2-ASSIGN))
- (cl-assert (not paren-free-arrow))
- (let* ((pos (js2-node-pos param))
- (tt (js2-current-token-type))
- (op-pos (- (js2-current-token-beg) pos))
- (left param)
- (right (js2-parse-assign-expr))
- (len (- (js2-node-end right) pos)))
- (setq param (make-js2-assign-node
- :type tt :pos pos :len len :op-pos op-pos
- :left left :right right))
- (js2-node-add-children param left right)))
- (push param params)
- (when (and rest-param-at (> (length params) (1+ rest-param-at)))
- (js2-report-error "msg.param.after.rest" nil
- (js2-node-pos param) (js2-node-len param)))
- while
- (and (js2-match-token js2-COMMA)
- (or (< js2-language-version 200)
- (not (= js2-RP (js2-peek-token))))))
- (when (and (not paren-free-arrow)
- (js2-must-match js2-RP "msg.no.paren.after.parms"))
- (setf (js2-function-node-rp fn-node) (- (js2-current-token-beg) pos)))
- (when rest-param-at
- (setf (js2-function-node-rest-p fn-node) t))
- (dolist (p params)
- (js2-node-add-children fn-node p)
- (push p (js2-function-node-params fn-node))))))
-
-(defun js2-check-inconsistent-return-warning (fn-node name)
- "Possibly show inconsistent-return warning.
-Last token scanned is the close-curly for the function body."
- (when (and js2-mode-show-strict-warnings
- js2-strict-inconsistent-return-warning
- (not (js2-has-consistent-return-usage
- (js2-function-node-body fn-node))))
- ;; Have it extend from close-curly to bol or beginning of block.
- (let ((pos (save-excursion
- (goto-char (js2-current-token-end))
- (max (js2-node-abs-pos (js2-function-node-body fn-node))
- (point-at-bol))))
- (end (js2-current-token-end)))
- (if (cl-plusp (js2-name-node-length name))
- (js2-add-strict-warning "msg.no.return.value"
- (js2-name-node-name name) pos end)
- (js2-add-strict-warning "msg.anon.no.return.value" nil pos end)))))
-
-(defun js2-parse-function-stmt (&optional async-p)
- (let ((pos (js2-current-token-beg))
- (star-p (js2-match-token js2-MUL)))
- (js2-must-match-name "msg.unnamed.function.stmt")
- (let ((name (js2-create-name-node t))
- pn member-expr)
- (cond
- ((js2-match-token js2-LP)
- (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p name))
- (js2-allow-member-expr-as-function-name
- (setq member-expr (js2-parse-member-expr-tail nil name))
- (js2-parse-highlight-member-expr-fn-name member-expr)
- (js2-must-match js2-LP "msg.no.paren.parms")
- (setf pn (js2-parse-function 'FUNCTION_STATEMENT pos star-p async-p)
- (js2-function-node-member-expr pn) member-expr)
- pn)
- (t
- (js2-report-error "msg.no.paren.parms")
- (make-js2-error-node))))))
-
-(defun js2-parse-async-function-stmt ()
- (js2-parse-function-stmt t))
-
-(defun js2-parse-function-expr (&optional async-p)
- (let ((pos (js2-current-token-beg))
- (star-p (js2-match-token js2-MUL))
- name)
- (when (js2-match-token js2-NAME)
- (setq name (js2-create-name-node t)))
- (js2-must-match js2-LP "msg.no.paren.parms")
- (js2-parse-function 'FUNCTION_EXPRESSION pos star-p async-p name)))
-
-(defun js2-parse-function-internal (function-type pos star-p &optional async-p
name)
- (let (fn-node lp)
- (if (= (js2-current-token-type) js2-LP) ; eventually matched LP?
- (setq lp (js2-current-token-beg)))
- (setf fn-node (make-js2-function-node :pos pos
- :name name
- :form function-type
- :lp (if lp (- lp pos))
- :generator-type (and star-p 'STAR)
- :async async-p))
- (when name
- (js2-set-face (js2-node-pos name) (js2-node-end name)
- 'font-lock-function-name-face 'record)
- (when (and (eq function-type 'FUNCTION_STATEMENT)
- (cl-plusp (js2-name-node-length name)))
- ;; Function statements define a symbol in the enclosing scope
- (js2-define-symbol js2-FUNCTION (js2-name-node-name name) fn-node))
- (when js2-in-use-strict-directive
- (js2-check-strict-identifier name)))
- (if (or (js2-inside-function) (cl-plusp js2-nesting-of-with))
- ;; 1. Nested functions are not affected by the dynamic scope flag
- ;; as dynamic scope is already a parent of their scope.
- ;; 2. Functions defined under the with statement also immune to
- ;; this setup, in which case dynamic scope is ignored in favor
- ;; of the with object.
- (setf (js2-function-node-ignore-dynamic fn-node) t))
- ;; dynamically bind all the per-function variables
- (let ((js2-current-script-or-fn fn-node)
- (js2-current-scope fn-node)
- (js2-nesting-of-with 0)
- (js2-end-flags 0)
- js2-label-set
- js2-loop-set
- js2-loop-and-switch-set)
- (js2-parse-function-params function-type fn-node pos)
- (when (eq function-type 'FUNCTION_ARROW)
- (js2-must-match js2-ARROW "msg.bad.arrow.args"))
- (if (and (>= js2-language-version 180)
- (/= (js2-peek-token) js2-LC))
- (js2-parse-function-closure-body fn-node)
- (js2-parse-function-body fn-node))
- (js2-check-inconsistent-return-warning fn-node name)
-
- (when name
- (js2-node-add-children fn-node name)
- ;; Function expressions define a name only in the body of the
- ;; function, and only if not hidden by a parameter name
- (when (and (eq function-type 'FUNCTION_EXPRESSION)
- (null (js2-scope-get-symbol js2-current-scope
- (js2-name-node-name name))))
- (js2-define-symbol js2-FUNCTION
- (js2-name-node-name name)
- fn-node))
- (when (eq function-type 'FUNCTION_STATEMENT)
- (js2-record-imenu-functions fn-node))))
-
- (setf (js2-node-len fn-node) (- (js2-current-token-end) pos))
- ;; Rhino doesn't do this, but we need it for finding undeclared vars.
- ;; We wait until after parsing the function to set its parent scope,
- ;; since `js2-define-symbol' needs the defining-scope check to stop
- ;; at the function boundary when checking for redeclarations.
- (setf (js2-scope-parent-scope fn-node) js2-current-scope)
- fn-node))
-
-(defun js2-parse-function (function-type pos star-p &optional async-p name)
- "Function parser. FUNCTION-TYPE is a symbol, POS is the
-beginning of the first token (function keyword, unless it's an
-arrow function), NAME is js2-name-node."
- (let ((continue t)
- ts-state
- fn-node
- ;; Preserve strict state outside this function.
- (js2-in-use-strict-directive js2-in-use-strict-directive))
- ;; Parse multiple times if a new strict mode directive is discovered in the
- ;; function body, as new rules will be retroactively applied to the
legality
- ;; of function names and parameters.
- (while continue
- (setq ts-state (make-js2-ts-state))
- (setq continue (catch 'reparse
- (setq fn-node (js2-parse-function-internal
- function-type pos star-p async-p name))
- ;; Don't continue.
- nil))
- (when continue
- (js2-ts-seek ts-state)))
- fn-node))
-
-(defun js2-parse-statements (&optional parent)
- "Parse a statement list. Last token consumed must be js2-LC.
-
-PARENT can be a `js2-block-node', in which case the statements are
-appended to PARENT. Otherwise a new `js2-block-node' is created
-and returned.
-
-This function does not match the closing js2-RC: the caller
-matches the RC so it can provide a suitable error message if not
-matched. This means it's up to the caller to set the length of
-the node to include the closing RC. The node start pos is set to
-the absolute buffer start position, and the caller should fix it
-up to be relative to the parent node. All children of this block
-node are given relative start positions and correct lengths."
- (let ((pn (or parent (make-js2-block-node)))
- tt)
- (while (and (> (setq tt (js2-peek-token)) js2-EOF)
- (/= tt js2-RC))
- (js2-block-node-push pn (js2-parse-statement)))
- pn))
-
-(defun js2-parse-statement ()
- (let (pn beg end)
- ;; coarse-grained user-interrupt check - needs work
- (and js2-parse-interruptable-p
- (zerop (% (cl-incf js2-parse-stmt-count)
- js2-statements-per-pause))
- (input-pending-p)
- (throw 'interrupted t))
- (setq pn (js2-statement-helper))
- ;; no-side-effects warning check
- (unless (js2-node-has-side-effects pn)
- (setq end (js2-node-end pn))
- (save-excursion
- (goto-char end)
- (setq beg (max (js2-node-pos pn) (point-at-bol))))
- (js2-add-strict-warning "msg.no.side.effects" nil beg end))
- pn))
-
-;; These correspond to the switch cases in Parser.statementHelper
-(defconst js2-parsers
- (let ((parsers (make-vector js2-num-tokens
- #'js2-parse-expr-stmt)))
- (aset parsers js2-BREAK #'js2-parse-break)
- (aset parsers js2-CLASS #'js2-parse-class-stmt)
- (aset parsers js2-CONST #'js2-parse-const-var)
- (aset parsers js2-CONTINUE #'js2-parse-continue)
- (aset parsers js2-DEBUGGER #'js2-parse-debugger)
- (aset parsers js2-DEFAULT #'js2-parse-default-xml-namespace)
- (aset parsers js2-DO #'js2-parse-do)
- (aset parsers js2-EXPORT #'js2-parse-export)
- (aset parsers js2-FOR #'js2-parse-for)
- (aset parsers js2-FUNCTION #'js2-parse-function-stmt)
- (aset parsers js2-IF #'js2-parse-if)
- (aset parsers js2-IMPORT #'js2-parse-import)
- (aset parsers js2-LC #'js2-parse-block)
- (aset parsers js2-LET #'js2-parse-let-stmt)
- (aset parsers js2-NAME #'js2-parse-name-or-label)
- (aset parsers js2-RETURN #'js2-parse-ret-yield)
- (aset parsers js2-SEMI #'js2-parse-semi)
- (aset parsers js2-SWITCH #'js2-parse-switch)
- (aset parsers js2-THROW #'js2-parse-throw)
- (aset parsers js2-TRY #'js2-parse-try)
- (aset parsers js2-VAR #'js2-parse-const-var)
- (aset parsers js2-WHILE #'js2-parse-while)
- (aset parsers js2-WITH #'js2-parse-with)
- (aset parsers js2-YIELD #'js2-parse-ret-yield)
- parsers)
- "A vector mapping token types to parser functions.")
-
-(defun js2-parse-warn-missing-semi (beg end)
- (and js2-mode-show-strict-warnings
- js2-strict-missing-semi-warning
- (js2-add-strict-warning
- "msg.missing.semi" nil
- ;; back up to beginning of statement or line
- (max beg (save-excursion
- (goto-char end)
- (point-at-bol)))
- end)))
-
-(defconst js2-no-semi-insertion
- (list js2-IF
- js2-SWITCH
- js2-WHILE
- js2-DO
- js2-FOR
- js2-TRY
- js2-WITH
- js2-LC
- js2-ERROR
- js2-SEMI
- js2-CLASS
- js2-FUNCTION
- js2-EXPORT)
- "List of tokens that don't do automatic semicolon insertion.")
-
-(defconst js2-autoinsert-semi-and-warn
- (list js2-ERROR js2-EOF js2-RC))
-
-(defun js2-statement-helper ()
- (let* ((tt (js2-get-token))
- (first-tt tt)
- (async-stmt (js2-match-async-function))
- (parser (if (= tt js2-ERROR)
- #'js2-parse-semi
- (if async-stmt
- #'js2-parse-async-function-stmt
- (aref js2-parsers tt))))
- pn)
- ;; If the statement is set, then it's been told its label by now.
- (and js2-labeled-stmt
- (js2-labeled-stmt-node-stmt js2-labeled-stmt)
- (setq js2-labeled-stmt nil))
- (setq pn (funcall parser))
- ;; Don't do auto semi insertion for certain statement types.
- (unless (or (memq first-tt js2-no-semi-insertion)
- (js2-labeled-stmt-node-p pn)
- async-stmt)
- (js2-auto-insert-semicolon pn))
- pn))
-
-(defun js2-auto-insert-semicolon (pn)
- (let* ((tt (js2-get-token))
- (pos (js2-node-pos pn)))
- (cond
- ((= tt js2-SEMI)
- ;; extend the node bounds to include the semicolon.
- (setf (js2-node-len pn) (- (js2-current-token-end) pos)))
- ((memq tt js2-autoinsert-semi-and-warn)
- (js2-unget-token) ; Not ';', do not consume.
- ;; Autoinsert ;
- (js2-parse-warn-missing-semi pos (js2-node-end pn)))
- (t
- (if (not (js2-token-follows-eol-p (js2-current-token)))
- ;; Report error if no EOL or autoinsert ';' otherwise
- (js2-report-error "msg.no.semi.stmt")
- (js2-parse-warn-missing-semi pos (js2-node-end pn)))
- (js2-unget-token) ; Not ';', do not consume.
- ))))
-
-(defun js2-parse-condition ()
- "Parse a parenthesized boolean expression, e.g. in an if- or while-stmt.
-The parens are discarded and the expression node is returned.
-The `pos' field of the return value is set to an absolute position
-that must be fixed up by the caller.
-Return value is a list (EXPR LP RP), with absolute paren positions."
- (let (pn lp rp)
- (if (js2-must-match js2-LP "msg.no.paren.cond")
- (setq lp (js2-current-token-beg)))
- (setq pn (js2-parse-expr))
- (if (js2-must-match js2-RP "msg.no.paren.after.cond")
- (setq rp (js2-current-token-beg)))
- ;; Report strict warning on code like "if (a = 7) ..."
- (if (and js2-strict-cond-assign-warning
- (js2-assign-node-p pn))
- (js2-add-strict-warning "msg.equal.as.assign" nil
- (js2-node-pos pn)
- (+ (js2-node-pos pn)
- (js2-node-len pn))))
- (list pn lp rp)))
-
-(defun js2-parse-if ()
- "Parser for if-statement. Last matched token must be js2-IF."
- (let ((pos (js2-current-token-beg))
- cond if-true if-false else-pos end pn)
- (setq cond (js2-parse-condition)
- if-true (js2-parse-statement)
- if-false (if (js2-match-token js2-ELSE)
- (progn
- (setq else-pos (- (js2-current-token-beg) pos))
- (js2-parse-statement)))
- end (js2-node-end (or if-false if-true))
- pn (make-js2-if-node :pos pos
- :len (- end pos)
- :condition (car cond)
- :then-part if-true
- :else-part if-false
- :else-pos else-pos
- :lp (js2-relpos (cl-second cond) pos)
- :rp (js2-relpos (cl-third cond) pos)))
- (js2-node-add-children pn (car cond) if-true if-false)
- pn))
-
-(defun js2-parse-import ()
- "Parse import statement. The current token must be js2-IMPORT."
- (unless (js2-ast-root-p js2-current-scope)
- (js2-report-error "msg.mod.import.decl.at.top.level"))
- (let ((beg (js2-current-token-beg)))
- (cond ((js2-match-token js2-STRING)
- (make-js2-import-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :module-id (js2-current-token-string)))
- (t
- (let* ((import-clause (js2-parse-import-clause))
- (from-clause (and import-clause (js2-parse-from-clause)))
- (module-id (when from-clause (js2-from-clause-node-module-id
from-clause)))
- (node (make-js2-import-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :import import-clause
- :from from-clause
- :module-id module-id)))
- (when import-clause
- (js2-node-add-children node import-clause))
- (when from-clause
- (js2-node-add-children node from-clause))
- node)))))
-
-(defun js2-parse-import-clause ()
- "Parse the bindings in an import statement.
-This can take many forms:
-
-ImportedDefaultBinding -> `foo'
-NameSpaceImport -> `* as lib'
-NamedImports -> `{foo as bar, bang}'
-ImportedDefaultBinding , NameSpaceImport -> `foo, * as lib'
-ImportedDefaultBinding , NamedImports -> `foo, {bar, baz as bif}'
-
-Try to match namespace imports and named imports first because nothing can
-come after them. If it is an imported default binding, then it could have named
-imports or a namespace import that follows it.
-"
- (let* ((beg (js2-current-token-beg))
- (clause (make-js2-import-clause-node
- :pos beg))
- (children (list)))
- (cond
- ((js2-match-token js2-MUL)
- (let ((ns-import (js2-parse-namespace-import)))
- (when ns-import
- (let ((name-node (js2-namespace-import-node-name ns-import)))
- (js2-define-symbol
- js2-LET (js2-name-node-name name-node) name-node t))
- (setf (js2-import-clause-node-namespace-import clause) ns-import)
- (push ns-import children))))
- ((js2-match-token js2-LC)
- (let ((imports (js2-parse-export-bindings t)))
- (setf (js2-import-clause-node-named-imports clause) imports)
- (dolist (import imports)
- (push import children)
- (let ((name-node (js2-export-binding-node-local-name import)))
- (when name-node
- (js2-define-symbol
- js2-LET (js2-name-node-name name-node) name-node t))))))
- ((= (js2-peek-token) js2-NAME)
- (let ((binding (js2-maybe-parse-export-binding t)))
- (let ((node-name (js2-export-binding-node-local-name binding)))
- (js2-define-symbol js2-LET (js2-name-node-name node-name) node-name
t))
- (setf (js2-import-clause-node-default-binding clause) binding)
- (push binding children))
- (when (js2-match-token js2-COMMA)
- (cond
- ((js2-match-token js2-MUL)
- (let ((ns-import (js2-parse-namespace-import)))
- (let ((name-node (js2-namespace-import-node-name ns-import)))
- (js2-define-symbol
- js2-LET (js2-name-node-name name-node) name-node t))
- (setf (js2-import-clause-node-namespace-import clause) ns-import)
- (push ns-import children)))
- ((js2-match-token js2-LC)
- (let ((imports (js2-parse-export-bindings t)))
- (setf (js2-import-clause-node-named-imports clause) imports)
- (dolist (import imports)
- (push import children)
- (let ((name-node (js2-export-binding-node-local-name import)))
- (when name-node
- (js2-define-symbol
- js2-LET (js2-name-node-name name-node) name-node t))))))
- (t (js2-report-error "msg.syntax")))))
- (t (js2-report-error "msg.mod.declaration.after.import")))
- (setf (js2-node-len clause) (- (js2-current-token-end) beg))
- (apply #'js2-node-add-children clause children)
- clause))
-
-(defun js2-parse-namespace-import ()
- "Parse a namespace import expression such as `* as bar'.
-The current token must be js2-MUL."
- (let ((beg (js2-current-token-beg)))
- (cond
- ((js2-match-contextual-kwd "as")
- (when (js2-must-match-prop-name "msg.syntax")
- (let ((node (make-js2-namespace-import-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :name (make-js2-name-node
- :pos (js2-current-token-beg)
- :len (- (js2-current-token-end)
- (js2-current-token-beg))
- :name (js2-current-token-string)))))
- (js2-node-add-children node (js2-namespace-import-node-name node))
- node)))
- (t
- (js2-unget-token)
- (js2-report-error "msg.syntax")
- nil))))
-
-
-(defun js2-parse-from-clause ()
- "Parse the from clause in an import or export statement.
-E.g., \"from \\='src/lib\\='\"."
- (if (js2-match-contextual-kwd "from")
- (let ((beg (js2-current-token-beg)))
- (cond
- ((js2-match-token js2-STRING)
- (make-js2-from-clause-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :module-id (js2-current-token-string)
- :metadata-p nil))
- ((js2-match-token js2-THIS)
- (when (js2-must-match-name "msg.mod.spec.after.from")
- (if (equal "module" (js2-current-token-string))
- (make-js2-from-clause-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :module-id "this"
- :metadata-p t)
- (js2-unget-token)
- (js2-unget-token)
- (js2-report-error "msg.mod.spec.after.from")
- nil)))
- (t (js2-report-error "msg.mod.spec.after.from") nil)))
- (js2-report-error "msg.mod.from.after.import.spec.set")
- nil))
-
-(defun js2-parse-export-bindings (&optional import-p)
- "Parse a list of export binding expressions such as {}, {foo, bar}, and
-{foo as bar, baz as bang}. The current token must be
-js2-LC. Return a lisp list of js2-export-binding-node"
- (let ((bindings (list)))
- (while
- (let ((binding (js2-maybe-parse-export-binding import-p)))
- (when binding
- (push binding bindings))
- (js2-match-token js2-COMMA)))
- (when (js2-must-match js2-RC (if import-p
- "msg.mod.rc.after.import.spec.list"
- "msg.mod.rc.after.export.spec.list"))
- (reverse bindings))))
-
-(defun js2-maybe-parse-export-binding (&optional import-p)
- "Attempt to parse a binding expression found inside an import/export
statement.
-This can take the form of either as single js2-NAME token as in `foo' or as in
a
-rebinding expression `bar as foo'. If it matches, it will return an instance of
-js2-export-binding-node and consume all the tokens. If it does not match, it
-consumes no tokens."
- (let ((extern-name (when (js2-match-prop-name) (js2-current-token-string)))
- (beg (js2-current-token-beg))
- (extern-name-len (js2-current-token-len))
- (is-reserved-name (or (= (js2-current-token-type) js2-RESERVED)
- (aref js2-kwd-tokens (js2-current-token-type)))))
- (if extern-name
- (if (js2-match-contextual-kwd "as")
- (let ((name
- (or
- (and (js2-match-token js2-DEFAULT) "default")
- (and (js2-match-token js2-NAME)
(js2-current-token-string)))))
- (if name
- (let ((node (make-js2-export-binding-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :local-name (make-js2-name-node
- :name name
- :pos (js2-current-token-beg)
- :len (js2-current-token-len))
- :extern-name (make-js2-name-node
- :name extern-name
- :pos beg
- :len extern-name-len))))
- (js2-node-add-children
- node
- (js2-export-binding-node-local-name node)
- (js2-export-binding-node-extern-name node))
- (if import-p
- (js2-set-face (js2-current-token-beg)
(js2-current-token-end)
- 'font-lock-variable-name-face 'record))
- node)
- (js2-unget-token)
- nil))
- (let* ((name-node (make-js2-name-node
- :name (js2-current-token-string)
- :pos (js2-current-token-beg)
- :len (js2-current-token-len)))
- (node (make-js2-export-binding-node
- :pos (js2-current-token-beg)
- :len (js2-current-token-len)
- :local-name name-node
- :extern-name name-node)))
- (when is-reserved-name
- (js2-report-error "msg.mod.as.after.reserved.word" extern-name))
- (js2-node-add-children node name-node)
- (if import-p
- (js2-set-face (js2-current-token-beg) (js2-current-token-end)
- 'font-lock-variable-name-face 'record))
- node))
- nil)))
-
-(defun js2-parse-switch ()
- "Parser for switch-statement. Last matched token must be js2-SWITCH."
- (let ((pos (js2-current-token-beg))
- tt pn discriminant has-default case-expr case-node
- case-pos cases stmt lp)
- (if (js2-must-match js2-LP "msg.no.paren.switch")
- (setq lp (js2-current-token-beg)))
- (setq discriminant (js2-parse-expr)
- pn (make-js2-switch-node :discriminant discriminant
- :pos pos
- :lp (js2-relpos lp pos)))
- (js2-node-add-children pn discriminant)
- (js2-enter-switch pn)
- (unwind-protect
- (progn
- (if (js2-must-match js2-RP "msg.no.paren.after.switch")
- (setf (js2-switch-node-rp pn) (- (js2-current-token-beg) pos)))
- (js2-must-match js2-LC "msg.no.brace.switch")
- (catch 'break
- (while t
- (setq tt (js2-next-token)
- case-pos (js2-current-token-beg))
- (cond
- ((= tt js2-RC)
- (setf (js2-node-len pn) (- (js2-current-token-end) pos))
- (throw 'break nil)) ; done
- ((= tt js2-CASE)
- (setq case-expr (js2-parse-expr))
- (js2-must-match js2-COLON "msg.no.colon.case"))
- ((= tt js2-DEFAULT)
- (if has-default
- (js2-report-error "msg.double.switch.default"))
- (setq has-default t
- case-expr nil)
- (js2-must-match js2-COLON "msg.no.colon.case"))
- (t
- (js2-report-error "msg.bad.switch")
- (throw 'break nil)))
- (setq case-node (make-js2-case-node :pos case-pos
- :len (-
(js2-current-token-end) case-pos)
- :expr case-expr))
- (js2-node-add-children case-node case-expr)
- (while (and (/= (setq tt (js2-peek-token)) js2-RC)
- (/= tt js2-CASE)
- (/= tt js2-DEFAULT)
- (/= tt js2-EOF))
- (setf stmt (js2-parse-statement)
- (js2-node-len case-node) (- (js2-node-end stmt)
case-pos))
- (js2-block-node-push case-node stmt))
- (push case-node cases)))
- ;; add cases last, as pushing reverses the order to be correct
- (dolist (kid cases)
- (js2-node-add-children pn kid)
- (push kid (js2-switch-node-cases pn)))
- pn) ; return value
- (js2-exit-switch))))
-
-(defun js2-parse-while ()
- "Parser for while-statement. Last matched token must be js2-WHILE."
- (let ((pos (js2-current-token-beg))
- (pn (make-js2-while-node))
- cond body)
- (js2-enter-loop pn)
- (unwind-protect
- (progn
- (setf cond (js2-parse-condition)
- (js2-while-node-condition pn) (car cond)
- body (js2-parse-statement)
- (js2-while-node-body pn) body
- (js2-node-len pn) (- (js2-node-end body) pos)
- (js2-while-node-lp pn) (js2-relpos (cl-second cond) pos)
- (js2-while-node-rp pn) (js2-relpos (cl-third cond) pos))
- (js2-node-add-children pn body (car cond)))
- (js2-exit-loop))
- pn))
-
-(defun js2-parse-do ()
- "Parser for do-statement. Last matched token must be js2-DO."
- (let ((pos (js2-current-token-beg))
- (pn (make-js2-do-node))
- cond body end)
- (js2-enter-loop pn)
- (unwind-protect
- (progn
- (setq body (js2-parse-statement))
- (js2-must-match js2-WHILE "msg.no.while.do")
- (setf (js2-do-node-while-pos pn) (- (js2-current-token-beg) pos)
- cond (js2-parse-condition)
- (js2-do-node-condition pn) (car cond)
- (js2-do-node-body pn) body
- end js2-ts-cursor
- (js2-do-node-lp pn) (js2-relpos (cl-second cond) pos)
- (js2-do-node-rp pn) (js2-relpos (cl-third cond) pos))
- (js2-node-add-children pn (car cond) body))
- (js2-exit-loop))
- ;; Always auto-insert semicolon to follow SpiderMonkey:
- ;; It is required by ECMAScript but is ignored by the rest of
- ;; world; see bug 238945
- (if (js2-match-token js2-SEMI)
- (setq end js2-ts-cursor))
- (setf (js2-node-len pn) (- end pos))
- pn))
-
-(defun js2-parse-export ()
- "Parse an export statement.
-The Last matched token must be js2-EXPORT. Currently, the `default' and `expr'
-expressions should only be either hoistable expressions (function or generator)
-or assignment expressions, but there is no checking to enforce that and so it
-will parse without error a small subset of
-invalid export statements."
- (unless (js2-ast-root-p js2-current-scope)
- (js2-report-error "msg.mod.export.decl.at.top.level"))
- (let ((beg (js2-current-token-beg))
- (children (list))
- exports-list from-clause declaration default)
- (cond
- ((js2-match-token js2-MUL)
- (setq from-clause (js2-parse-from-clause))
- (when from-clause
- (push from-clause children)))
- ((js2-match-token js2-LC)
- (setq exports-list (js2-parse-export-bindings))
- (when exports-list
- (dolist (export exports-list)
- (push export children)))
- (when (js2-match-contextual-kwd "from")
- (js2-unget-token)
- (setq from-clause (js2-parse-from-clause))))
- ((js2-match-token js2-DEFAULT)
- (setq default (cond ((js2-match-token js2-CLASS)
- (if (eq (js2-peek-token) js2-NAME)
- (js2-parse-class-stmt)
- (js2-parse-class-expr)))
- ((js2-match-token js2-NAME)
- (if (js2-match-async-function)
- (if (eq (js2-peek-token) js2-NAME)
- (js2-parse-async-function-stmt)
- (js2-parse-function-expr t))
- (js2-unget-token)
- (js2-parse-expr)))
- ((js2-match-token js2-FUNCTION)
- (if (eq (js2-peek-token) js2-NAME)
- (js2-parse-function-stmt)
- (js2-parse-function-expr)))
- (t (js2-parse-expr)))))
- ((or (js2-match-token js2-VAR) (js2-match-token js2-CONST)
(js2-match-token js2-LET))
- (setq declaration (js2-parse-variables (js2-current-token-type)
(js2-current-token-beg))))
- ((js2-match-token js2-CLASS)
- (setq declaration (js2-parse-class-stmt)))
- ((js2-match-token js2-NAME)
- (setq declaration
- (if (js2-match-async-function)
- (js2-parse-async-function-stmt)
- (js2-unget-token)
- (js2-parse-expr))))
- ((js2-match-token js2-FUNCTION)
- (setq declaration (js2-parse-function-stmt)))
- (t
- (setq declaration (js2-parse-expr))))
- (when from-clause
- (push from-clause children))
- (when declaration
- (push declaration children)
- (when (not (or (js2-function-node-p declaration)
- (js2-class-node-p declaration)))
- (js2-auto-insert-semicolon declaration)))
- (when default
- (push default children)
- (when (not (or (js2-function-node-p default)
- (js2-class-node-p default)))
- (js2-auto-insert-semicolon default)))
- (let ((node (make-js2-export-node
- :pos beg
- :len (- (js2-current-token-end) beg)
- :exports-list exports-list
- :from-clause from-clause
- :declaration declaration
- :default default)))
- (apply #'js2-node-add-children node children)
- node)))
-
-(defun js2-parse-for ()
- "Parse a for, for-in or for each-in statement.
-Last matched token must be js2-FOR."
- (let ((for-pos (js2-current-token-beg))
- (tmp-scope (make-js2-scope))
- pn is-for-each is-for-in-or-of is-for-of
- in-pos each-pos tmp-pos
- init ; Node init is also foo in 'foo in object'.
- cond ; Node cond is also object in 'foo in object'.
- incr ; 3rd section of for-loop initializer.
- body tt lp rp)
- ;; See if this is a for each () instead of just a for ()
- (when (js2-match-token js2-NAME)
- (if (string= "each" (js2-current-token-string))
- (progn
- (setq is-for-each t
- each-pos (- (js2-current-token-beg) for-pos)) ; relative
- (js2-record-face 'font-lock-keyword-face))
- (js2-report-error "msg.no.paren.for")))
- (if (js2-must-match js2-LP "msg.no.paren.for")
- (setq lp (- (js2-current-token-beg) for-pos)))
- (setq tt (js2-get-token))
- ;; Capture identifiers inside parens. We can't create the node
- ;; (and use it as the current scope) until we know its type.
- (js2-push-scope tmp-scope)
- (unwind-protect
- (progn
- ;; parse init clause
- (let ((js2-in-for-init t)) ; set as dynamic variable
- (cond
- ((= tt js2-SEMI)
- (js2-unget-token)
- (setq init (make-js2-empty-expr-node)))
- ((or (= tt js2-VAR) (= tt js2-LET) (= tt js2-CONST))
- (setq init (js2-parse-variables tt (js2-current-token-beg))))
- (t
- (js2-unget-token)
- (setq init (js2-parse-expr)))))
- (if (or (js2-match-token js2-IN)
- (and (>= js2-language-version 200)
- (js2-match-contextual-kwd "of")
- (setq is-for-of t)))
- (setq is-for-in-or-of t
- in-pos (- (js2-current-token-beg) for-pos)
- ;; scope of iteration target object is not the scope we've
created above.
- ;; stash current scope temporary.
- cond (let ((js2-current-scope (js2-scope-parent-scope
js2-current-scope)))
- (js2-parse-expr))) ; object over which we're
iterating
- ;; else ordinary for loop - parse cond and incr
- (js2-must-match js2-SEMI "msg.no.semi.for")
- (setq cond (if (= (js2-peek-token) js2-SEMI)
- (make-js2-empty-expr-node) ; no loop condition
- (js2-parse-expr)))
- (js2-must-match js2-SEMI "msg.no.semi.for.cond")
- (setq tmp-pos (js2-current-token-end)
- incr (if (= (js2-peek-token) js2-RP)
- (make-js2-empty-expr-node :pos tmp-pos)
- (js2-parse-expr)))))
- (js2-pop-scope))
- (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
- (setq rp (- (js2-current-token-beg) for-pos)))
- (if (not is-for-in-or-of)
- (setq pn (make-js2-for-node :init init
- :condition cond
- :update incr
- :lp lp
- :rp rp))
- ;; cond could be null if 'in obj' got eaten by the init node.
- (if (js2-infix-node-p init)
- ;; it was (foo in bar) instead of (var foo in bar)
- (setq cond (js2-infix-node-right init)
- init (js2-infix-node-left init))
- (if (and (js2-var-decl-node-p init)
- (> (length (js2-var-decl-node-kids init)) 1))
- (js2-report-error "msg.mult.index")))
- (setq pn (make-js2-for-in-node :iterator init
- :object cond
- :in-pos in-pos
- :foreach-p is-for-each
- :each-pos each-pos
- :forof-p is-for-of
- :lp lp
- :rp rp)))
- ;; Transplant the declarations.
- (setf (js2-scope-symbol-table pn)
- (js2-scope-symbol-table tmp-scope))
- (unwind-protect
- (progn
- (js2-enter-loop pn)
- ;; We have to parse the body -after- creating the loop node,
- ;; so that the loop node appears in the js2-loop-set, allowing
- ;; break/continue statements to find the enclosing loop.
- (setf body (js2-parse-statement)
- (js2-loop-node-body pn) body
- (js2-node-pos pn) for-pos
- (js2-node-len pn) (- (js2-node-end body) for-pos))
- (js2-node-add-children pn init cond incr body))
- ;; finally
- (js2-exit-loop))
- pn))
-
-(defun js2-parse-try ()
- "Parse a try statement. Last matched token must be js2-TRY."
- (let ((try-pos (js2-current-token-beg))
- try-end
- try-block
- catch-blocks
- finally-block
- saw-default-catch
- peek)
- (if (/= (js2-peek-token) js2-LC)
- (js2-report-error "msg.no.brace.try"))
- (setq try-block (js2-parse-statement)
- try-end (js2-node-end try-block)
- peek (js2-peek-token))
- (cond
- ((= peek js2-CATCH)
- (while (js2-match-token js2-CATCH)
- (let* ((catch-pos (js2-current-token-beg))
- (catch-node (make-js2-catch-node :pos catch-pos))
- param
- guard-kwd
- catch-cond
- lp rp)
- (if saw-default-catch
- (js2-report-error "msg.catch.unreachable"))
- (if (js2-must-match js2-LP "msg.no.paren.catch")
- (setq lp (- (js2-current-token-beg) catch-pos)))
- (js2-push-scope catch-node)
- (let ((tt (js2-peek-token)))
- (cond
- ;; Destructuring pattern:
- ;; catch ({ message, file }) { ... }
- ((or (= tt js2-LB) (= tt js2-LC))
- (js2-get-token)
- (setq param (js2-parse-destruct-primary-expr))
- (js2-define-destruct-symbols param js2-LET nil))
- ;; Simple name.
- (t
- (js2-must-match-name "msg.bad.catchcond")
- (setq param (js2-create-name-node))
- (js2-define-symbol js2-LET (js2-current-token-string) param)
- (js2-check-strict-identifier param))))
- ;; Catch condition.
- (if (js2-match-token js2-IF)
- (setq guard-kwd (- (js2-current-token-beg) catch-pos)
- catch-cond (js2-parse-expr))
- (setq saw-default-catch t))
- (if (js2-must-match js2-RP "msg.bad.catchcond")
- (setq rp (- (js2-current-token-beg) catch-pos)))
- (js2-must-match js2-LC "msg.no.brace.catchblock")
- (js2-parse-statements catch-node)
- (if (js2-must-match js2-RC "msg.no.brace.after.body")
- (setq try-end (js2-current-token-end)))
- (js2-pop-scope)
- (setf (js2-node-len catch-node) (- try-end catch-pos)
- (js2-catch-node-param catch-node) param
- (js2-catch-node-guard-expr catch-node) catch-cond
- (js2-catch-node-guard-kwd catch-node) guard-kwd
- (js2-catch-node-lp catch-node) lp
- (js2-catch-node-rp catch-node) rp)
- (js2-node-add-children catch-node param catch-cond)
- (push catch-node catch-blocks))))
- ((/= peek js2-FINALLY)
- (js2-must-match js2-FINALLY "msg.try.no.catchfinally"
- (js2-node-pos try-block)
- (- (setq try-end (js2-node-end try-block))
- (js2-node-pos try-block)))))
- (when (js2-match-token js2-FINALLY)
- (let ((finally-pos (js2-current-token-beg))
- (block (js2-parse-statement)))
- (setq try-end (js2-node-end block)
- finally-block (make-js2-finally-node :pos finally-pos
- :len (- try-end finally-pos)
- :body block))
- (js2-node-add-children finally-block block)))
- (let ((pn (make-js2-try-node :pos try-pos
- :len (- try-end try-pos)
- :try-block try-block
- :finally-block finally-block)))
- (js2-node-add-children pn try-block finally-block)
- ;; Push them onto the try-node, which reverses and corrects their order.
- (dolist (cb catch-blocks)
- (js2-node-add-children pn cb)
- (push cb (js2-try-node-catch-clauses pn)))
- pn)))
-
-(defun js2-parse-throw ()
- "Parser for throw-statement. Last matched token must be js2-THROW."
- (let ((pos (js2-current-token-beg))
- expr pn)
- (if (= (js2-peek-token-or-eol) js2-EOL)
- ;; ECMAScript does not allow new lines before throw expression,
- ;; see bug 256617
- (js2-report-error "msg.bad.throw.eol"))
- (setq expr (js2-parse-expr)
- pn (make-js2-throw-node :pos pos
- :len (- (js2-node-end expr) pos)
- :expr expr))
- (js2-node-add-children pn expr)
- pn))
-
-(defun js2-match-jump-label-name (label-name)
- "If break/continue specified a label, return that label's labeled stmt.
-Returns the corresponding `js2-labeled-stmt-node', or if LABEL-NAME
-does not match an existing label, reports an error and returns nil."
- (let ((bundle (cdr (assoc label-name js2-label-set))))
- (if (null bundle)
- (js2-report-error "msg.undef.label"))
- bundle))
-
-(defun js2-parse-break ()
- "Parser for break-statement. Last matched token must be js2-BREAK."
- (let ((pos (js2-current-token-beg))
- (end (js2-current-token-end))
- break-target ; statement to break from
- break-label ; in "break foo", name-node representing the foo
- labels ; matching labeled statement to break to
- pn)
- (when (eq (js2-peek-token-or-eol) js2-NAME)
- (js2-get-token)
- (setq break-label (js2-create-name-node)
- end (js2-node-end break-label)
- ;; matchJumpLabelName only matches if there is one
- labels (js2-match-jump-label-name (js2-current-token-string))
- break-target (if labels (car (js2-labeled-stmt-node-labels
labels)))))
- (unless (or break-target break-label)
- ;; no break target specified - try for innermost enclosing loop/switch
- (if (null js2-loop-and-switch-set)
- (unless break-label
- (js2-report-error "msg.bad.break" nil pos (length "break")))
- (setq break-target (car js2-loop-and-switch-set))))
- (setq pn (make-js2-break-node :pos pos
- :len (- end pos)
- :label break-label
- :target break-target))
- (js2-node-add-children pn break-label) ; but not break-target
- pn))
-
-(defun js2-parse-continue ()
- "Parser for continue-statement. Last matched token must be js2-CONTINUE."
- (let ((pos (js2-current-token-beg))
- (end (js2-current-token-end))
- label ; optional user-specified label, a `js2-name-node'
- labels ; current matching labeled stmt, if any
- target ; the `js2-loop-node' target of this continue stmt
- pn)
- (when (= (js2-peek-token-or-eol) js2-NAME)
- (js2-get-token)
- (setq label (js2-create-name-node)
- end (js2-node-end label)
- ;; matchJumpLabelName only matches if there is one
- labels (js2-match-jump-label-name (js2-current-token-string))))
- (cond
- ((null labels) ; no current label to go to
- (if (null js2-loop-set) ; no loop to continue to
- (js2-report-error "msg.continue.outside" nil pos
- (length "continue"))
- (setq target (car js2-loop-set)))) ; innermost enclosing loop
- (t
- (if (js2-loop-node-p (js2-labeled-stmt-node-stmt labels))
- (setq target (js2-labeled-stmt-node-stmt labels))
- (js2-report-error "msg.continue.nonloop" nil pos (- end pos)))))
- (setq pn (make-js2-continue-node :pos pos
- :len (- end pos)
- :label label
- :target target))
- (js2-node-add-children pn label) ; but not target - it's not our child
- pn))
-
-(defun js2-parse-with ()
- "Parser for with-statement. Last matched token must be js2-WITH."
- (when js2-in-use-strict-directive
- (js2-report-error "msg.no.with.strict"))
- (let ((pos (js2-current-token-beg))
- obj body pn lp rp)
- (if (js2-must-match js2-LP "msg.no.paren.with")
- (setq lp (js2-current-token-beg)))
- (setq obj (js2-parse-expr))
- (if (js2-must-match js2-RP "msg.no.paren.after.with")
- (setq rp (js2-current-token-beg)))
- (let ((js2-nesting-of-with (1+ js2-nesting-of-with)))
- (setq body (js2-parse-statement)))
- (setq pn (make-js2-with-node :pos pos
- :len (- (js2-node-end body) pos)
- :object obj
- :body body
- :lp (js2-relpos lp pos)
- :rp (js2-relpos rp pos)))
- (js2-node-add-children pn obj body)
- pn))
-
-(defun js2-parse-const-var ()
- "Parser for var- or const-statement.
-Last matched token must be js2-CONST or js2-VAR."
- (let ((tt (js2-current-token-type))
- (pos (js2-current-token-beg))
- expr pn)
- (setq expr (js2-parse-variables tt (js2-current-token-beg))
- pn (make-js2-expr-stmt-node :pos pos
- :len (- (js2-node-end expr) pos)
- :expr expr))
- (js2-node-add-children pn expr)
- pn))
-
-(defun js2-wrap-with-expr-stmt (pos expr &optional add-child)
- (let ((pn (make-js2-expr-stmt-node :pos pos
- :len (js2-node-len expr)
- :type (if (js2-inside-function)
- js2-EXPR_VOID
- js2-EXPR_RESULT)
- :expr expr)))
- (if add-child
- (js2-node-add-children pn expr))
- pn))
-
-(defun js2-parse-let-stmt ()
- "Parser for let-statement. Last matched token must be js2-LET."
- (let ((pos (js2-current-token-beg))
- expr pn)
- (if (= (js2-peek-token) js2-LP)
- ;; let expression in statement context
- (setq expr (js2-parse-let pos 'statement)
- pn (js2-wrap-with-expr-stmt pos expr t))
- ;; else we're looking at a statement like let x=6, y=7;
- (setf expr (js2-parse-variables js2-LET pos)
- pn (js2-wrap-with-expr-stmt pos expr t)
- (js2-node-type pn) js2-EXPR_RESULT))
- pn))
-
-(defun js2-parse-ret-yield ()
- (js2-parse-return-or-yield (js2-current-token-type) nil))
-
-(defconst js2-parse-return-stmt-enders
- (list js2-SEMI js2-RC js2-EOF js2-EOL js2-ERROR js2-RB js2-RP))
-
-(defsubst js2-now-all-set (before after mask)
- "Return whether or not the bits in the mask have changed to all set.
-BEFORE is bits before change, AFTER is bits after change, and MASK is
-the mask for bits. Returns t if all the bits in the mask are set in AFTER
-but not BEFORE."
- (and (/= (logand before mask) mask)
- (= (logand after mask) mask)))
-
-(defun js2-parse-return-or-yield (tt expr-context)
- (let* ((pos (js2-current-token-beg))
- (end (js2-current-token-end))
- (before js2-end-flags)
- (inside-function (js2-inside-function))
- (gen-type (and inside-function (js2-function-node-generator-type
- js2-current-script-or-fn)))
- e ret name yield-star-p)
- (unless inside-function
- (js2-report-error (if (eq tt js2-RETURN)
- "msg.bad.return"
- "msg.bad.yield")))
- (when (and inside-function
- (eq gen-type 'STAR)
- (js2-match-token js2-MUL))
- (setq yield-star-p t))
- ;; This is ugly, but we don't want to require a semicolon.
- (unless (memq (js2-peek-token-or-eol) js2-parse-return-stmt-enders)
- (setq e (if (eq gen-type 'STAR)
- (js2-parse-assign-expr)
- (js2-parse-expr))
- end (js2-node-end e)))
- (cond
- ((eq tt js2-RETURN)
- (js2-set-flag js2-end-flags (if (null e)
- js2-end-returns
- js2-end-returns-value))
- (setq ret (make-js2-return-node :pos pos
- :len (- end pos)
- :retval e))
- (js2-node-add-children ret e)
- ;; See if we need a strict mode warning.
- ;; TODO: The analysis done by `js2-has-consistent-return-usage' is
- ;; more thorough and accurate than this before/after flag check.
- ;; E.g. if there's a finally-block that always returns, we shouldn't
- ;; show a warning generated by inconsistent returns in the catch blocks.
- ;; Basically `js2-has-consistent-return-usage' needs to keep more state,
- ;; so we know which returns/yields to highlight, and we should get rid of
- ;; all the checking in `js2-parse-return-or-yield'.
- (if (and js2-strict-inconsistent-return-warning
- (js2-now-all-set before js2-end-flags
- (logior js2-end-returns
js2-end-returns-value)))
- (js2-add-strict-warning "msg.return.inconsistent" nil pos end)))
- ((eq gen-type 'COMPREHENSION)
- ;; FIXME: We should probably switch to saving and using lastYieldOffset,
- ;; like SpiderMonkey does.
- (js2-report-error "msg.syntax" nil pos 5))
- (t
- (setq ret (make-js2-yield-node :pos pos
- :len (- end pos)
- :value e
- :star-p yield-star-p))
- (js2-node-add-children ret e)
- (unless expr-context
- (setq e ret
- ret (js2-wrap-with-expr-stmt pos e t))
- (js2-set-requires-activation)
- (js2-set-is-generator))))
- ;; see if we are mixing yields and value returns.
- (when (and inside-function
- (js2-flag-set-p js2-end-flags js2-end-returns-value)
- (eq (js2-function-node-generator-type js2-current-script-or-fn)
- 'LEGACY))
- (setq name (js2-function-name js2-current-script-or-fn))
- (if (zerop (length name))
- (js2-report-error "msg.anon.generator.returns" nil pos (- end pos))
- (js2-report-error "msg.generator.returns" name pos (- end pos))))
- ret))
-
-(defun js2-parse-debugger ()
- (make-js2-keyword-node :type js2-DEBUGGER))
-
-(defun js2-parse-block ()
- "Parser for a curly-delimited statement block.
-Last token matched must be `js2-LC'."
- (let ((pos (js2-current-token-beg))
- (pn (make-js2-scope)))
- (js2-push-scope pn)
- (unwind-protect
- (progn
- (js2-parse-statements pn)
- (js2-must-match js2-RC "msg.no.brace.block")
- (setf (js2-node-len pn) (- (js2-current-token-end) pos)))
- (js2-pop-scope))
- pn))
-
-;; For `js2-ERROR' too, to have a node for error recovery to work on.
-(defun js2-parse-semi ()
- "Parse a statement or handle an error.
-Current token type is `js2-SEMI' or `js2-ERROR'."
- (let ((tt (js2-current-token-type)) pos len)
- (if (eq tt js2-SEMI)
- (make-js2-empty-expr-node :len 1)
- (setq pos (js2-current-token-beg)
- len (- (js2-current-token-end) pos))
- (js2-report-error "msg.syntax" nil pos len)
- (make-js2-error-node :pos pos :len len))))
-
-(defun js2-parse-default-xml-namespace ()
- "Parse a `default xml namespace = <expr>' e4x statement."
- (let ((pos (js2-current-token-beg))
- end len expr unary)
- (js2-must-have-xml)
- (js2-set-requires-activation)
- (setq len (- js2-ts-cursor pos))
- (unless (and (js2-match-token js2-NAME)
- (string= (js2-current-token-string) "xml"))
- (js2-report-error "msg.bad.namespace" nil pos len))
- (unless (and (js2-match-token js2-NAME)
- (string= (js2-current-token-string) "namespace"))
- (js2-report-error "msg.bad.namespace" nil pos len))
- (unless (js2-match-token js2-ASSIGN)
- (js2-report-error "msg.bad.namespace" nil pos len))
- (setq expr (js2-parse-expr)
- end (js2-node-end expr)
- unary (make-js2-unary-node :type js2-DEFAULTNAMESPACE
- :pos pos
- :len (- end pos)
- :operand expr))
- (js2-node-add-children unary expr)
- (make-js2-expr-stmt-node :pos pos
- :len (- end pos)
- :expr unary)))
-
-(defun js2-record-label (label bundle)
- ;; current token should be colon that `js2-parse-primary-expr' left untouched
- (js2-get-token)
- (let ((name (js2-label-node-name label))
- labeled-stmt
- dup)
- (when (setq labeled-stmt (cdr (assoc name js2-label-set)))
- ;; flag both labels if possible when used in editing mode
- (if (and js2-parse-ide-mode
- (setq dup (js2-get-label-by-name labeled-stmt name)))
- (js2-report-error "msg.dup.label" nil
- (js2-node-abs-pos dup) (js2-node-len dup)))
- (js2-report-error "msg.dup.label" nil
- (js2-node-pos label) (js2-node-len label)))
- (js2-labeled-stmt-node-add-label bundle label)
- (js2-node-add-children bundle label)
- ;; Add one reference to the bundle per label in `js2-label-set'
- (push (cons name bundle) js2-label-set)))
-
-(defun js2-parse-name-or-label ()
- "Parser for identifier or label. Last token matched must be js2-NAME.
-Called when we found a name in a statement context. If it's a label, we gather
-up any following labels and the next non-label statement into a
-`js2-labeled-stmt-node' bundle and return that. Otherwise we parse an
-expression and return it wrapped in a `js2-expr-stmt-node'."
- (let ((pos (js2-current-token-beg))
- expr stmt bundle
- (continue t))
- ;; set check for label and call down to `js2-parse-primary-expr'
- (setq expr (js2-maybe-parse-label))
- (if (null expr)
- ;; Parse the non-label expression and wrap with expression stmt.
- (js2-wrap-with-expr-stmt pos (js2-parse-expr) t)
- ;; else parsed a label
- (setq bundle (make-js2-labeled-stmt-node :pos pos))
- (js2-record-label expr bundle)
- ;; look for more labels
- (while (and continue (= (js2-get-token) js2-NAME))
- (if (setq expr (js2-maybe-parse-label))
- (js2-record-label expr bundle)
- (setq expr (js2-parse-expr)
- stmt (js2-wrap-with-expr-stmt (js2-node-pos expr) expr t)
- continue nil)
- (js2-auto-insert-semicolon stmt)))
- ;; no more labels; now parse the labeled statement
- (unwind-protect
- (unless stmt
- (let ((js2-labeled-stmt bundle)) ; bind dynamically
- (js2-unget-token)
- (setq stmt (js2-statement-helper))))
- ;; remove the labels for this statement from the global set
- (dolist (label (js2-labeled-stmt-node-labels bundle))
- (setq js2-label-set (remove label js2-label-set))))
- (setf (js2-labeled-stmt-node-stmt bundle) stmt
- (js2-node-len bundle) (- (js2-node-end stmt) pos))
- (js2-node-add-children bundle stmt)
- bundle)))
-
-(defun js2-maybe-parse-label ()
- (cl-assert (= (js2-current-token-type) js2-NAME))
- (let (label-pos
- (next-tt (js2-get-token))
- (label-end (js2-current-token-end)))
- ;; Do not consume colon, it is used as unwind indicator
- ;; to return to statementHelper.
- (js2-unget-token)
- (if (= next-tt js2-COLON)
- (prog2
- (setq label-pos (js2-current-token-beg))
- (make-js2-label-node :pos label-pos
- :len (- label-end label-pos)
- :name (js2-current-token-string))
- (js2-set-face label-pos
- label-end
- 'font-lock-variable-name-face 'record))
- ;; Backtrack from the name token, too.
- (js2-unget-token)
- nil)))
-
-(defun js2-parse-expr-stmt ()
- "Default parser in statement context, if no recognized statement found."
- (js2-wrap-with-expr-stmt (js2-current-token-beg)
- (progn
- (js2-unget-token)
- (js2-parse-expr)) t))
-
-(defun js2-parse-variables (decl-type pos)
- "Parse a comma-separated list of variable declarations.
-Could be a `var', `const' or `let' expression, possibly in a for-loop
initializer.
-
-DECL-TYPE is a token value: either VAR, CONST, or LET depending on context.
-For `var' or `const', the keyword should be the token last scanned.
-
-POS is the position where the node should start. It's sometimes the
-var/const/let keyword, and other times the beginning of the first token
-in the first variable declaration.
-
-Returns the parsed `js2-var-decl-node' expression node."
- (let* ((result (make-js2-var-decl-node :decl-type decl-type
- :pos pos))
- destructuring kid-pos tt init name end nbeg nend vi
- (continue t))
- ;; Example:
- ;; var foo = {a: 1, b: 2}, bar = [3, 4];
- ;; var {b: s2, a: s1} = foo, x = 6, y, [s3, s4] = bar;
- ;; var {a, b} = baz;
- (while continue
- (setq destructuring nil
- name nil
- tt (js2-get-token)
- kid-pos (js2-current-token-beg)
- end (js2-current-token-end)
- init nil)
- (if (or (= tt js2-LB) (= tt js2-LC))
- ;; Destructuring assignment, e.g., var [a, b] = ...
- (setq destructuring (js2-parse-destruct-primary-expr)
- end (js2-node-end destructuring))
- ;; Simple variable name
- (js2-unget-token)
- (when (js2-must-match-name "msg.bad.var")
- (setq name (js2-create-name-node)
- nbeg (js2-current-token-beg)
- nend (js2-current-token-end)
- end nend)
- (js2-define-symbol decl-type (js2-current-token-string) name
js2-in-for-init)
- (js2-check-strict-identifier name)))
- (when (js2-match-token js2-ASSIGN)
- (setq init (js2-parse-assign-expr)
- end (js2-node-end init))
- (js2-record-imenu-functions init name))
- (when name
- (js2-set-face nbeg nend (if (js2-function-node-p init)
- 'font-lock-function-name-face
- 'font-lock-variable-name-face)
- 'record))
- (setq vi (make-js2-var-init-node :pos kid-pos
- :len (- end kid-pos)
- :type decl-type))
- (if destructuring
- (progn
- (if (and (null init) (not js2-in-for-init))
- (js2-report-error "msg.destruct.assign.no.init"))
- (js2-define-destruct-symbols destructuring
- decl-type
- 'font-lock-variable-name-face)
- (setf (js2-var-init-node-target vi) destructuring))
- (setf (js2-var-init-node-target vi) name))
- (setf (js2-var-init-node-initializer vi) init)
- (js2-node-add-children vi name destructuring init)
- (js2-block-node-push result vi)
- (unless (js2-match-token js2-COMMA)
- (setq continue nil)))
- (setf (js2-node-len result) (- end pos))
- result))
-
-(defun js2-parse-let (pos &optional stmt-p)
- "Parse a let expression or statement.
-A let-expression is of the form `let (vars) expr'.
-A let-statement is of the form `let (vars) {statements}'.
-The third form of let is a variable declaration list, handled
-by `js2-parse-variables'."
- (let ((pn (make-js2-let-node :pos pos))
- beg vars body)
- (if (js2-must-match js2-LP "msg.no.paren.after.let")
- (setf (js2-let-node-lp pn) (- (js2-current-token-beg) pos)))
- (js2-push-scope pn)
- (unwind-protect
- (progn
- (setq vars (js2-parse-variables js2-LET (js2-current-token-beg)))
- (if (js2-must-match js2-RP "msg.no.paren.let")
- (setf (js2-let-node-rp pn) (- (js2-current-token-beg) pos)))
- (if (and stmt-p (js2-match-token js2-LC))
- ;; let statement
- (progn
- (setf beg (js2-current-token-beg) ; position stmt at LC
- body (js2-parse-statements))
- (js2-must-match js2-RC "msg.no.curly.let")
- (setf (js2-node-len body) (- (js2-current-token-end) beg)
- (js2-node-len pn) (- (js2-current-token-end) pos)
- (js2-let-node-body pn) body
- (js2-node-type pn) js2-LET))
- ;; let expression
- (setf body (js2-parse-expr)
- (js2-node-len pn) (- (js2-node-end body) pos)
- (js2-let-node-body pn) body))
- (setf (js2-let-node-vars pn) vars)
- (js2-node-add-children pn vars body))
- (js2-pop-scope))
- pn))
-
-(defun js2-define-new-symbol (decl-type name node &optional scope)
- (js2-scope-put-symbol (or scope js2-current-scope)
- name
- (make-js2-symbol decl-type name node)))
-
-(defun js2-define-symbol (decl-type name &optional node ignore-not-in-block)
- "Define a symbol in the current scope.
-If NODE is non-nil, it is the AST node associated with the symbol."
- (let* ((defining-scope (js2-get-defining-scope js2-current-scope name))
- (symbol (if defining-scope
- (js2-scope-get-symbol defining-scope name)))
- (sdt (if symbol (js2-symbol-decl-type symbol) -1))
- (pos (if node (js2-node-abs-pos node)))
- (len (if node (js2-node-len node))))
- (cond
- ((and symbol ; already defined in this block
- (or (= sdt js2-LET)
- (= sdt js2-CONST))
- (eq defining-scope js2-current-scope))
- (js2-report-error
- (cond
- ((= sdt js2-CONST) "msg.const.redecl")
- ((= sdt js2-LET) "msg.let.redecl")
- ((= sdt js2-VAR) "msg.var.redecl")
- ((= sdt js2-FUNCTION) "msg.function.redecl")
- (t "msg.parm.redecl"))
- name pos len))
- ((or (= decl-type js2-LET)
- (= decl-type js2-CONST))
- (if (and (= decl-type js2-LET)
- (not ignore-not-in-block)
- (or (= (js2-node-type js2-current-scope) js2-IF)
- (js2-loop-node-p js2-current-scope)))
- (js2-report-error "msg.let.decl.not.in.block")
- (js2-define-new-symbol decl-type name node)))
- ((or (= decl-type js2-VAR)
- (= decl-type js2-FUNCTION))
- (if symbol
- (if (and js2-strict-var-redeclaration-warning (= sdt js2-VAR))
- (js2-add-strict-warning "msg.var.redecl" name)
- (if (and js2-strict-var-hides-function-arg-warning (= sdt js2-LP))
- (js2-add-strict-warning "msg.var.hides.arg" name)))
- (js2-define-new-symbol decl-type name node
- js2-current-script-or-fn)))
- ((= decl-type js2-LP)
- (if symbol
- ;; must be duplicate parameter. Second parameter hides the
- ;; first, so go ahead and add the second pararameter
- (js2-report-warning "msg.dup.parms" name))
- (js2-define-new-symbol decl-type name node))
- (t (js2-code-bug)))))
-
-(defun js2-parse-paren-expr-or-generator-comp ()
- (let ((px-pos (js2-current-token-beg)))
- (cond
- ((and (>= js2-language-version 200)
- (js2-match-token js2-FOR))
- (js2-parse-generator-comp px-pos))
- ((and (>= js2-language-version 200)
- (js2-match-token js2-RP))
- ;; Not valid expression syntax, but this is valid in an arrow
- ;; function with no params: () => body.
- (if (eq (js2-peek-token) js2-ARROW)
- ;; Return whatever, it will hopefully be rewinded and
- ;; reparsed when we reach the =>.
- (make-js2-keyword-node :type js2-NULL)
- (js2-report-error "msg.syntax")
- (make-js2-error-node)))
- (t
- (let* ((js2-in-for-init nil)
- (expr (js2-parse-expr))
- (pn (make-js2-paren-node :pos px-pos
- :expr expr)))
- (js2-node-add-children pn (js2-paren-node-expr pn))
- (js2-must-match js2-RP "msg.no.paren")
- (setf (js2-node-len pn) (- (js2-current-token-end) px-pos))
- pn)))))
-
-(defun js2-parse-expr (&optional oneshot)
- (let* ((pn (js2-parse-assign-expr))
- (pos (js2-node-pos pn))
- left
- right
- op-pos)
- (while (and (not oneshot)
- (js2-match-token js2-COMMA))
- (setq op-pos (- (js2-current-token-beg) pos)) ; relative
- (setq right (js2-parse-assign-expr)
- left pn
- pn (make-js2-infix-node :type js2-COMMA
- :pos pos
- :len (- js2-ts-cursor pos)
- :op-pos op-pos
- :left left
- :right right))
- (js2-node-add-children pn left right))
- pn))
-
-(defun js2-parse-assign-expr ()
- (let ((tt (js2-get-token))
- (pos (js2-current-token-beg))
- pn left right op-pos
- ts-state recorded-identifiers parsed-errors
- async-p)
- (if (= tt js2-YIELD)
- (js2-parse-return-or-yield tt t)
- ;; TODO(mooz): Bit confusing.
- ;; If we meet `async` token and it's not part of `async
- ;; function`, then this `async` is for a succeeding async arrow
- ;; function.
- ;; Since arrow function parsing doesn't rely on neither
- ;; `js2-parse-function-stmt' nor `js2-parse-function-expr' that
- ;; interpret `async` token, we trash `async` and just remember
- ;; we met `async` keyword to `async-p'.
- (when (js2-match-async-arrow-function)
- (setq async-p t))
- ;; Save the tokenizer state in case we find an arrow function
- ;; and have to rewind.
- (setq ts-state (make-js2-ts-state)
- recorded-identifiers js2-recorded-identifiers
- parsed-errors js2-parsed-errors)
- ;; not yield - parse assignment expression
- (setq pn (js2-parse-cond-expr)
- tt (js2-get-token))
- (cond
- ((and (<= js2-first-assign tt)
- (<= tt js2-last-assign))
- ;; tt express assignment (=, |=, ^=, ..., %=)
- (setq op-pos (- (js2-current-token-beg) pos) ; relative
- left pn)
- ;; The assigned node could be a js2-prop-get-node (foo.bar = 0), we
only
- ;; care about assignment to strict variable names.
- (when (js2-name-node-p left)
- (js2-check-strict-identifier left))
- (setq right (js2-parse-assign-expr)
- pn (make-js2-assign-node :type tt
- :pos pos
- :len (- (js2-node-end right) pos)
- :op-pos op-pos
- :left left
- :right right))
- (when js2-parse-ide-mode
- (js2-highlight-assign-targets pn left right)
- (js2-record-imenu-functions right left))
- ;; do this last so ide checks above can use absolute positions
- (js2-node-add-children pn left right))
- ((and (>= js2-language-version 200)
- (or
- (= tt js2-ARROW)
- (and async-p
- (= (js2-peek-token) js2-ARROW))))
- (js2-ts-seek ts-state)
- (when async-p
- (js2-record-face 'font-lock-keyword-face)
- (js2-get-token))
- (setq js2-recorded-identifiers recorded-identifiers
- js2-parsed-errors parsed-errors)
- (setq pn (js2-parse-function 'FUNCTION_ARROW (js2-current-token-beg)
nil async-p)))
- (t
- (js2-unget-token)))
- pn)))
-
-(defun js2-parse-cond-expr ()
- (let ((pos (js2-current-token-beg))
- (pn (js2-parse-or-expr))
- test-expr
- if-true
- if-false
- q-pos
- c-pos)
- (when (js2-match-token js2-HOOK)
- (setq q-pos (- (js2-current-token-beg) pos)
- if-true (let (js2-in-for-init) (js2-parse-assign-expr)))
- (js2-must-match js2-COLON "msg.no.colon.cond")
- (setq c-pos (- (js2-current-token-beg) pos)
- if-false (js2-parse-assign-expr)
- test-expr pn
- pn (make-js2-cond-node :pos pos
- :len (- (js2-node-end if-false) pos)
- :test-expr test-expr
- :true-expr if-true
- :false-expr if-false
- :q-pos q-pos
- :c-pos c-pos))
- (js2-node-add-children pn test-expr if-true if-false))
- pn))
-
-(defun js2-make-binary (type left parser &optional no-get)
- "Helper for constructing a binary-operator AST node.
-LEFT is the left-side-expression, already parsed, and the
-binary operator should have just been matched.
-PARSER is a function to call to parse the right operand,
-or a `js2-node' struct if it has already been parsed.
-FIXME: The latter option is unused?"
- (let* ((pos (js2-node-pos left))
- (op-pos (- (js2-current-token-beg) pos))
- (right (if (js2-node-p parser)
- parser
- (unless no-get (js2-get-token))
- (funcall parser)))
- (pn (make-js2-infix-node :type type
- :pos pos
- :len (- (js2-node-end right) pos)
- :op-pos op-pos
- :left left
- :right right)))
- (js2-node-add-children pn left right)
- pn))
-
-(defun js2-parse-or-expr ()
- (let ((pn (js2-parse-and-expr)))
- (when (js2-match-token js2-OR)
- (setq pn (js2-make-binary js2-OR
- pn
- 'js2-parse-or-expr)))
- pn))
-
-(defun js2-parse-and-expr ()
- (let ((pn (js2-parse-bit-or-expr)))
- (when (js2-match-token js2-AND)
- (setq pn (js2-make-binary js2-AND
- pn
- 'js2-parse-and-expr)))
- pn))
-
-(defun js2-parse-bit-or-expr ()
- (let ((pn (js2-parse-bit-xor-expr)))
- (while (js2-match-token js2-BITOR)
- (setq pn (js2-make-binary js2-BITOR
- pn
- 'js2-parse-bit-xor-expr)))
- pn))
-
-(defun js2-parse-bit-xor-expr ()
- (let ((pn (js2-parse-bit-and-expr)))
- (while (js2-match-token js2-BITXOR)
- (setq pn (js2-make-binary js2-BITXOR
- pn
- 'js2-parse-bit-and-expr)))
- pn))
-
-(defun js2-parse-bit-and-expr ()
- (let ((pn (js2-parse-eq-expr)))
- (while (js2-match-token js2-BITAND)
- (setq pn (js2-make-binary js2-BITAND
- pn
- 'js2-parse-eq-expr)))
- pn))
-
-(defconst js2-parse-eq-ops
- (list js2-EQ js2-NE js2-SHEQ js2-SHNE))
-
-(defun js2-parse-eq-expr ()
- (let ((pn (js2-parse-rel-expr))
- tt)
- (while (memq (setq tt (js2-get-token)) js2-parse-eq-ops)
- (setq pn (js2-make-binary tt
- pn
- 'js2-parse-rel-expr)))
- (js2-unget-token)
- pn))
-
-(defconst js2-parse-rel-ops
- (list js2-IN js2-INSTANCEOF js2-LE js2-LT js2-GE js2-GT))
-
-(defun js2-parse-rel-expr ()
- (let ((pn (js2-parse-shift-expr))
- (continue t)
- tt)
- (while continue
- (setq tt (js2-get-token))
- (cond
- ((and js2-in-for-init (= tt js2-IN))
- (js2-unget-token)
- (setq continue nil))
- ((memq tt js2-parse-rel-ops)
- (setq pn (js2-make-binary tt pn 'js2-parse-shift-expr)))
- (t
- (js2-unget-token)
- (setq continue nil))))
- pn))
-
-(defconst js2-parse-shift-ops
- (list js2-LSH js2-URSH js2-RSH))
-
-(defun js2-parse-shift-expr ()
- (let ((pn (js2-parse-add-expr))
- tt
- (continue t))
- (while continue
- (setq tt (js2-get-token))
- (if (memq tt js2-parse-shift-ops)
- (setq pn (js2-make-binary tt pn 'js2-parse-add-expr))
- (js2-unget-token)
- (setq continue nil)))
- pn))
-
-(defun js2-parse-add-expr ()
- (let ((pn (js2-parse-mul-expr))
- tt
- (continue t))
- (while continue
- (setq tt (js2-get-token))
- (if (or (= tt js2-ADD) (= tt js2-SUB))
- (setq pn (js2-make-binary tt pn 'js2-parse-mul-expr))
- (js2-unget-token)
- (setq continue nil)))
- pn))
-
-(defconst js2-parse-mul-ops
- (list js2-MUL js2-DIV js2-MOD))
-
-(defun js2-parse-mul-expr ()
- (let ((pn (js2-parse-expon-expr))
- tt
- (continue t))
- (while continue
- (setq tt (js2-get-token))
- (if (memq tt js2-parse-mul-ops)
- (setq pn (js2-make-binary tt pn 'js2-parse-expon-expr))
- (js2-unget-token)
- (setq continue nil)))
- pn))
-
-(defun js2-parse-expon-expr ()
- (let ((pn (js2-parse-unary-expr)))
- (when (>= js2-language-version 200)
- (while (js2-match-token js2-EXPON)
- (when (and (js2-unary-node-p pn)
- (not (memq (js2-node-type pn) '(js2-INC js2-DEC))))
- (js2-report-error "msg.syntax" nil
- (js2-node-abs-pos pn) (js2-node-len pn)))
- ;; Make it right-associative.
- (setq pn (js2-make-binary js2-EXPON pn 'js2-parse-expon-expr))))
- pn))
-
-(defun js2-make-unary (beg type parser &rest args)
- "Make a unary node starting at BEG of type TYPE.
-If BEG is nil, `(js2-current-token-beg)' is used for the node
-start position. PARSER is either a node (for postfix operators)
-or a function to call to parse the operand (for prefix
-operators)."
- (let* ((pos (or beg (js2-current-token-beg)))
- (postfix (js2-node-p parser))
- (expr (if postfix
- parser
- (apply parser args)))
- end
- pn)
- (if postfix ; e.g. i++
- (setq pos (js2-node-pos expr)
- end (js2-current-token-end))
- (setq end (js2-node-end expr)))
- (setq pn (make-js2-unary-node :type type
- :pos pos
- :len (- end pos)
- :operand expr))
- (js2-node-add-children pn expr)
- pn))
-
-(defconst js2-incrementable-node-types
- (list js2-NAME js2-GETPROP js2-GETELEM js2-GET_REF js2-CALL)
- "Node types that can be the operand of a ++ or -- operator.")
-
-(defun js2-check-bad-inc-dec (tt beg end unary)
- (unless (memq (js2-node-type (js2-unary-node-operand unary))
- js2-incrementable-node-types)
- (js2-report-error (if (= tt js2-INC)
- "msg.bad.incr"
- "msg.bad.decr")
- nil beg (- end beg))))
-
-(defun js2-parse-unary-expr ()
- (let ((tt (js2-current-token-type))
- (beg (js2-current-token-beg)))
- (cond
- ((or (= tt js2-VOID)
- (= tt js2-NOT)
- (= tt js2-BITNOT)
- (= tt js2-TYPEOF))
- (js2-get-token)
- (js2-make-unary beg tt 'js2-parse-unary-expr))
- ((= tt js2-ADD)
- (js2-get-token)
- ;; Convert to special POS token in decompiler and parse tree
- (js2-make-unary beg js2-POS 'js2-parse-unary-expr))
- ((= tt js2-SUB)
- (js2-get-token)
- ;; Convert to special NEG token in decompiler and parse tree
- (js2-make-unary beg js2-NEG 'js2-parse-unary-expr))
- ((or (= tt js2-INC)
- (= tt js2-DEC))
- (js2-get-token)
- (let ((beg2 (js2-current-token-beg))
- (end (js2-current-token-end))
- (expr (js2-make-unary beg tt 'js2-parse-member-expr t)))
- (js2-check-bad-inc-dec tt beg2 end expr)
- expr))
- ((= tt js2-DELPROP)
- (js2-get-token)
- (js2-make-unary beg js2-DELPROP 'js2-parse-unary-expr))
- ((js2-parse-await-maybe tt))
- ((= tt js2-ERROR)
- (js2-get-token)
- (make-js2-error-node)) ; try to continue
- ((and (= tt js2-LT)
- js2-compiler-xml-available)
- ;; XML stream encountered in expression.
- (js2-parse-member-expr-tail t (js2-parse-xml-initializer)))
- (t
- (let ((pn (js2-parse-member-expr t))
- ;; Don't look across a newline boundary for a postfix incop.
- (tt (js2-peek-token-or-eol))
- expr)
- (when (or (= tt js2-INC) (= tt js2-DEC))
- (js2-get-token)
- (setf expr pn
- pn (js2-make-unary (js2-node-pos expr) tt expr))
- (js2-node-set-prop pn 'postfix t)
- (js2-check-bad-inc-dec tt (js2-current-token-beg)
(js2-current-token-end) pn))
- pn)))))
-
-(defun js2-parse-xml-initializer ()
- "Parse an E4X XML initializer.
-I'm parsing it the way Rhino parses it, but without the tree-rewriting.
-Then I'll postprocess the result, depending on whether we're in IDE
-mode or codegen mode, and generate the appropriate rewritten AST.
-IDE mode uses a rich AST that models the XML structure. Codegen mode
-just concatenates everything and makes a new XML or XMLList out of it."
- (let ((tt (js2-get-first-xml-token))
- pn-xml pn expr kids expr-pos
- (continue t)
- (first-token t))
- (when (not (or (= tt js2-XML) (= tt js2-XMLEND)))
- (js2-report-error "msg.syntax"))
- (setq pn-xml (make-js2-xml-node))
- (while continue
- (if first-token
- (setq first-token nil)
- (setq tt (js2-get-next-xml-token)))
- (cond
- ;; js2-XML means we found a {expr} in the XML stream.
- ;; The token string is the XML up to the left-curly.
- ((= tt js2-XML)
- (push (make-js2-string-node :pos (js2-current-token-beg)
- :len (- js2-ts-cursor
(js2-current-token-beg)))
- kids)
- (js2-must-match js2-LC "msg.syntax")
- (setq expr-pos js2-ts-cursor
- expr (if (eq (js2-peek-token) js2-RC)
- (make-js2-empty-expr-node :pos expr-pos)
- (js2-parse-expr)))
- (js2-must-match js2-RC "msg.syntax")
- (setq pn (make-js2-xml-js-expr-node :pos (js2-node-pos expr)
- :len (js2-node-len expr)
- :expr expr))
- (js2-node-add-children pn expr)
- (push pn kids))
- ;; a js2-XMLEND token means we hit the final close-tag.
- ((= tt js2-XMLEND)
- (push (make-js2-string-node :pos (js2-current-token-beg)
- :len (- js2-ts-cursor
(js2-current-token-beg)))
- kids)
- (dolist (kid (nreverse kids))
- (js2-block-node-push pn-xml kid))
- (setf (js2-node-len pn-xml) (- js2-ts-cursor
- (js2-node-pos pn-xml))
- continue nil))
- (t
- (js2-report-error "msg.syntax")
- (setq continue nil))))
- pn-xml))
-
-
-(defun js2-parse-argument-list ()
- "Parse an argument list and return it as a Lisp list of nodes.
-Returns the list in reverse order. Consumes the right-paren token."
- (let (result)
- (unless (js2-match-token js2-RP)
- (cl-loop do
- (let ((tt (js2-get-token))
- (beg (js2-current-token-beg)))
- (if (and (= tt js2-TRIPLEDOT)
- (>= js2-language-version 200))
- (push (js2-make-unary beg tt 'js2-parse-assign-expr)
result)
- (js2-unget-token)
- (push (js2-parse-assign-expr) result)))
- while
- (and (js2-match-token js2-COMMA)
- (or (< js2-language-version 200)
- (not (= js2-RP (js2-peek-token))))))
- (js2-must-match js2-RP "msg.no.paren.arg")
- result)))
-
-(defun js2-parse-member-expr (&optional allow-call-syntax)
- (let ((tt (js2-current-token-type))
- pn pos target args beg end init)
- (if (/= tt js2-NEW)
- (setq pn (js2-parse-primary-expr))
- ;; parse a 'new' expression
- (js2-get-token)
- (setq pos (js2-current-token-beg)
- beg pos
- target (js2-parse-member-expr)
- end (js2-node-end target)
- pn (make-js2-new-node :pos pos
- :target target
- :len (- end pos)))
- (js2-highlight-function-call (js2-current-token))
- (js2-node-add-children pn target)
- (when (js2-match-token js2-LP)
- ;; Add the arguments to pn, if any are supplied.
- (setf beg pos ; start of "new" keyword
- pos (js2-current-token-beg)
- args (nreverse (js2-parse-argument-list))
- (js2-new-node-args pn) args
- end (js2-current-token-end)
- (js2-new-node-lp pn) (- pos beg)
- (js2-new-node-rp pn) (- end 1 beg))
- (apply #'js2-node-add-children pn args))
- (when (and js2-allow-rhino-new-expr-initializer
- (js2-match-token js2-LC))
- (setf init (js2-parse-object-literal)
- end (js2-node-end init)
- (js2-new-node-initializer pn) init)
- (js2-node-add-children pn init))
- (setf (js2-node-len pn) (- end beg))) ; end outer if
- (js2-parse-member-expr-tail allow-call-syntax pn)))
-
-(defun js2-parse-member-expr-tail (allow-call-syntax pn)
- "Parse a chain of property/array accesses or function calls.
-Includes parsing for E4X operators like `..' and `.@'.
-If ALLOW-CALL-SYNTAX is nil, stops when we encounter a left-paren.
-Returns an expression tree that includes PN, the parent node."
- (let (tt
- (continue t))
- (while continue
- (setq tt (js2-get-token))
- (cond
- ((or (= tt js2-DOT) (= tt js2-DOTDOT))
- (setq pn (js2-parse-property-access tt pn)))
- ((= tt js2-DOTQUERY)
- (setq pn (js2-parse-dot-query pn)))
- ((= tt js2-LB)
- (setq pn (js2-parse-element-get pn)))
- ((= tt js2-LP)
- (js2-unget-token)
- (if allow-call-syntax
- (setq pn (js2-parse-function-call pn))
- (setq continue nil)))
- ((= tt js2-TEMPLATE_HEAD)
- (setq pn (js2-parse-tagged-template pn (js2-parse-template-literal))))
- ((= tt js2-NO_SUBS_TEMPLATE)
- (setq pn (js2-parse-tagged-template pn (make-js2-string-node :type
tt))))
- (t
- (js2-unget-token)
- (setq continue nil)))
- (if (>= js2-highlight-level 2)
- (js2-parse-highlight-member-expr-node pn)))
- pn))
-
-(defun js2-parse-tagged-template (tag-node tpl-node)
- "Parse tagged template expression."
- (let* ((pos (js2-node-pos tag-node))
- (pn (make-js2-tagged-template-node :pos pos
- :len (- (js2-current-token-end)
pos)
- :tag tag-node
- :template tpl-node)))
- (js2-node-add-children pn tag-node tpl-node)
- pn))
-
-(defun js2-parse-dot-query (pn)
- "Parse a dot-query expression, e.g. foo.bar.(@name == 2)
-Last token parsed must be `js2-DOTQUERY'."
- (let ((pos (js2-node-pos pn))
- op-pos expr end)
- (js2-must-have-xml)
- (js2-set-requires-activation)
- (setq op-pos (js2-current-token-beg)
- expr (js2-parse-expr)
- end (js2-node-end expr)
- pn (make-js2-xml-dot-query-node :left pn
- :pos pos
- :op-pos op-pos
- :right expr))
- (js2-node-add-children pn
- (js2-xml-dot-query-node-left pn)
- (js2-xml-dot-query-node-right pn))
- (if (js2-must-match js2-RP "msg.no.paren")
- (setf (js2-xml-dot-query-node-rp pn) (js2-current-token-beg)
- end (js2-current-token-end)))
- (setf (js2-node-len pn) (- end pos))
- pn))
-
-(defun js2-parse-element-get (pn)
- "Parse an element-get expression, e.g. foo[bar].
-Last token parsed must be `js2-RB'."
- (let ((lb (js2-current-token-beg))
- (pos (js2-node-pos pn))
- rb expr)
- (setq expr (js2-parse-expr))
- (if (js2-must-match js2-RB "msg.no.bracket.index")
- (setq rb (js2-current-token-beg)))
- (setq pn (make-js2-elem-get-node :target pn
- :pos pos
- :element expr
- :lb (js2-relpos lb pos)
- :rb (js2-relpos rb pos)
- :len (- (js2-current-token-end) pos)))
- (js2-node-add-children pn
- (js2-elem-get-node-target pn)
- (js2-elem-get-node-element pn))
- pn))
-
-(defun js2-highlight-function-call (token)
- (when (eq (js2-token-type token) js2-NAME)
- (js2-record-face 'js2-function-call token)))
-
-(defun js2-parse-function-call (pn)
- (js2-highlight-function-call (js2-current-token))
- (js2-get-token)
- (let (args
- (pos (js2-node-pos pn)))
- (setq pn (make-js2-call-node :pos pos
- :target pn
- :lp (- (js2-current-token-beg) pos)))
- (js2-node-add-children pn (js2-call-node-target pn))
- ;; Add the arguments to pn, if any are supplied.
- (setf args (nreverse (js2-parse-argument-list))
- (js2-call-node-rp pn) (- (js2-current-token-beg) pos)
- (js2-call-node-args pn) args)
- (apply #'js2-node-add-children pn args)
- (setf (js2-node-len pn) (- js2-ts-cursor pos))
- pn))
-
-(defun js2-parse-property-access (tt pn)
- "Parse a property access, XML descendants access, or XML attr access."
- (let ((member-type-flags 0)
- (dot-pos (js2-current-token-beg))
- (dot-len (if (= tt js2-DOTDOT) 2 1))
- name
- ref ; right side of . or .. operator
- result)
- (when (= tt js2-DOTDOT)
- (js2-must-have-xml)
- (setq member-type-flags js2-descendants-flag))
- (if (not js2-compiler-xml-available)
- (progn
- (js2-must-match-prop-name "msg.no.name.after.dot")
- (setq name (js2-create-name-node t js2-GETPROP)
- result (make-js2-prop-get-node :left pn
- :pos (js2-current-token-beg)
- :right name
- :len (js2-current-token-len)))
- (js2-node-add-children result pn name)
- result)
- ;; otherwise look for XML operators
- (setf result (if (= tt js2-DOT)
- (make-js2-prop-get-node)
- (make-js2-infix-node :type js2-DOTDOT))
- (js2-node-pos result) (js2-node-pos pn)
- (js2-infix-node-op-pos result) dot-pos
- (js2-infix-node-left result) pn ; do this after setting position
- tt (js2-get-prop-name-token))
- (cond
- ;; handles: name, ns::name, ns::*, ns::[expr]
- ((= tt js2-NAME)
- (setq ref (js2-parse-property-name -1 nil member-type-flags)))
- ;; handles: *, *::name, *::*, *::[expr]
- ((= tt js2-MUL)
- (setq ref (js2-parse-property-name nil "*" member-type-flags)))
- ;; handles: '@attr', '@ns::attr', '@ns::*', '@ns::[expr]', etc.
- ((= tt js2-XMLATTR)
- (setq result (js2-parse-attribute-access)))
- (t
- (js2-report-error "msg.no.name.after.dot" nil dot-pos dot-len)))
- (if ref
- (setf (js2-node-len result) (- (js2-node-end ref)
- (js2-node-pos result))
- (js2-infix-node-right result) ref))
- (if (js2-infix-node-p result)
- (js2-node-add-children result
- (js2-infix-node-left result)
- (js2-infix-node-right result)))
- result)))
-
-(defun js2-parse-attribute-access ()
- "Parse an E4X XML attribute expression.
-This includes expressions of the forms:
-
- @attr @ns::attr @ns::*
- @* @*::attr @*::*
- @[expr] @*::[expr] @ns::[expr]
-
-Called if we peeked an `@' token."
- (let ((tt (js2-get-prop-name-token))
- (at-pos (js2-current-token-beg)))
- (cond
- ;; handles: @name, @ns::name, @ns::*, @ns::[expr]
- ((= tt js2-NAME)
- (js2-parse-property-name at-pos nil 0))
- ;; handles: @*, @*::name, @*::*, @*::[expr]
- ((= tt js2-MUL)
- (js2-parse-property-name (js2-current-token-beg) "*" 0))
- ;; handles @[expr]
- ((= tt js2-LB)
- (js2-parse-xml-elem-ref at-pos))
- (t
- (js2-report-error "msg.no.name.after.xmlAttr")
- ;; Avoid cascaded errors that happen if we make an error node here.
- (js2-parse-property-name (js2-current-token-beg) "" 0)))))
-
-(defun js2-parse-property-name (at-pos s member-type-flags)
- "Check if :: follows name in which case it becomes qualified name.
-
-AT-POS is a natural number if we just read an `@' token, else nil.
-S is the name or string that was matched: an identifier, `throw' or `*'.
-MEMBER-TYPE-FLAGS is a bit set tracking whether we're a `.' or `..' child.
-
-Returns a `js2-xml-ref-node' if it's an attribute access, a child of a `..'
-operator, or the name is followed by ::. For a plain name, returns a
-`js2-name-node'. Returns a `js2-error-node' for malformed XML expressions."
- (let ((pos (or at-pos (js2-current-token-beg)))
- colon-pos
- (name (js2-create-name-node t (js2-current-token-type) s))
- ns tt pn)
- (catch 'return
- (when (js2-match-token js2-COLONCOLON)
- (setq ns name
- colon-pos (js2-current-token-beg)
- tt (js2-get-prop-name-token))
- (cond
- ;; handles name::name
- ((= tt js2-NAME)
- (setq name (js2-create-name-node)))
- ;; handles name::*
- ((= tt js2-MUL)
- (setq name (js2-create-name-node nil nil "*")))
- ;; handles name::[expr]
- ((= tt js2-LB)
- (throw 'return (js2-parse-xml-elem-ref at-pos ns colon-pos)))
- (t
- (js2-report-error "msg.no.name.after.coloncolon"))))
- (if (and (null ns) (zerop member-type-flags))
- name
- (prog1
- (setq pn
- (make-js2-xml-prop-ref-node :pos pos
- :len (- (js2-node-end name) pos)
- :at-pos at-pos
- :colon-pos colon-pos
- :propname name))
- (js2-node-add-children pn name))))))
-
-(defun js2-parse-xml-elem-ref (at-pos &optional namespace colon-pos)
- "Parse the [expr] portion of an xml element reference.
-For instance, @[expr], @*::[expr], or ns::[expr]."
- (let* ((lb (js2-current-token-beg))
- (pos (or at-pos lb))
- rb
- (expr (js2-parse-expr))
- (end (js2-node-end expr))
- pn)
- (if (js2-must-match js2-RB "msg.no.bracket.index")
- (setq rb (js2-current-token-beg)
- end (js2-current-token-end)))
- (prog1
- (setq pn
- (make-js2-xml-elem-ref-node :pos pos
- :len (- end pos)
- :namespace namespace
- :colon-pos colon-pos
- :at-pos at-pos
- :expr expr
- :lb (js2-relpos lb pos)
- :rb (js2-relpos rb pos)))
- (js2-node-add-children pn namespace expr))))
-
-(defun js2-parse-destruct-primary-expr ()
- (let ((js2-is-in-destructuring t))
- (js2-parse-primary-expr)))
-
-(defun js2-parse-primary-expr ()
- "Parse a literal (leaf) expression of some sort.
-Includes complex literals such as functions, object-literals,
-array-literals, array comprehensions and regular expressions."
- (let (tt node)
- (setq tt (js2-current-token-type))
- (cond
- ((= tt js2-CLASS)
- (js2-parse-class-expr))
- ((= tt js2-FUNCTION)
- (js2-parse-function-expr))
- ((js2-match-async-function)
- (js2-parse-function-expr t))
- ((= tt js2-LB)
- (js2-parse-array-comp-or-literal))
- ((= tt js2-LC)
- (js2-parse-object-literal))
- ((= tt js2-LET)
- (js2-parse-let (js2-current-token-beg)))
- ((= tt js2-LP)
- (js2-parse-paren-expr-or-generator-comp))
- ((= tt js2-XMLATTR)
- (js2-must-have-xml)
- (js2-parse-attribute-access))
- ((= tt js2-NAME)
- (js2-parse-name tt))
- ((= tt js2-NUMBER)
- (setq node (make-js2-number-node))
- (when (and js2-in-use-strict-directive
- (= (js2-number-node-num-base node) 8)
- (js2-number-node-legacy-octal-p node))
- (js2-report-error "msg.no.octal.strict"))
- node)
- ((or (= tt js2-STRING) (= tt js2-NO_SUBS_TEMPLATE))
- (make-js2-string-node :type tt))
- ((= tt js2-TEMPLATE_HEAD)
- (js2-parse-template-literal))
- ((or (= tt js2-DIV) (= tt js2-ASSIGN_DIV))
- ;; Got / or /= which in this context means a regexp literal
- (let* ((px-pos (js2-current-token-beg))
- (flags (js2-read-regexp tt px-pos))
- (end (js2-current-token-end)))
- (prog1
- (make-js2-regexp-node :pos px-pos
- :len (- end px-pos)
- :value (js2-current-token-string)
- :flags flags)
- (js2-set-face px-pos end 'font-lock-string-face 'record))))
- ((or (= tt js2-NULL)
- (= tt js2-THIS)
- (= tt js2-SUPER)
- (= tt js2-FALSE)
- (= tt js2-TRUE))
- (make-js2-keyword-node :type tt))
- ((= tt js2-TRIPLEDOT)
- ;; Likewise, only valid in an arrow function with a rest param.
- (if (and (js2-match-token js2-NAME)
- (js2-match-token js2-RP)
- (eq (js2-peek-token) js2-ARROW))
- (progn
- (js2-unget-token) ; Put back the right paren.
- ;; See the previous case.
- (make-js2-keyword-node :type js2-NULL))
- (js2-report-error "msg.syntax")
- (make-js2-error-node)))
- ((= tt js2-RESERVED)
- (js2-report-error "msg.reserved.id")
- (make-js2-name-node))
- ((= tt js2-ERROR)
- ;; the scanner or one of its subroutines reported the error.
- (make-js2-error-node))
- ((= tt js2-EOF)
- (let* ((px-pos (point-at-bol))
- (len (- js2-ts-cursor px-pos)))
- (js2-report-error "msg.unexpected.eof" nil px-pos len))
- (make-js2-error-node :pos (1- js2-ts-cursor)))
- (t
- (js2-report-error "msg.syntax")
- (make-js2-error-node)))))
-
-(defun js2-parse-template-literal ()
- (let ((beg (js2-current-token-beg))
- (kids (list (make-js2-string-node :type js2-TEMPLATE_HEAD)))
- (tt js2-TEMPLATE_HEAD))
- (while (eq tt js2-TEMPLATE_HEAD)
- (push (js2-parse-expr) kids)
- (js2-must-match js2-RC "msg.syntax")
- (setq tt (js2-get-token 'TEMPLATE_TAIL))
- (push (make-js2-string-node :type tt) kids))
- (setq kids (nreverse kids))
- (let ((tpl (make-js2-template-node :pos beg
- :len (- (js2-current-token-end) beg)
- :kids kids)))
- (apply #'js2-node-add-children tpl kids)
- tpl)))
-
-(defun js2-parse-name (_tt)
- (let ((name (js2-current-token-string))
- node)
- (setq node (if js2-compiler-xml-available
- (js2-parse-property-name nil name 0)
- (js2-create-name-node 'check-activation nil name)))
- (if (and js2-highlight-external-variables
- ;; FIXME: What's TRT for `js2-xml-ref-node'?
- (js2-name-node-p node))
- (js2-record-name-node node))
- node))
-
-(defun js2-parse-warn-trailing-comma (msg pos elems comma-pos)
- (js2-add-strict-warning
- msg nil
- ;; back up from comma to beginning of line or array/objlit
- (max (if elems
- (js2-node-pos (car elems))
- pos)
- (save-excursion
- (goto-char comma-pos)
- (back-to-indentation)
- (point)))
- comma-pos))
-
-(defun js2-parse-array-comp-or-literal ()
- (let ((pos (js2-current-token-beg)))
- (if (and (>= js2-language-version 200)
- (js2-match-token js2-FOR))
- (js2-parse-array-comp pos)
- (js2-parse-array-literal pos))))
-
-(defun js2-parse-array-literal (pos)
- (let ((after-lb-or-comma t)
- after-comma tt elems pn was-rest
- (continue t))
- (unless js2-is-in-destructuring
- (js2-push-scope (make-js2-scope))) ; for the legacy array comp
- (while continue
- (setq tt (js2-get-token))
- (cond
- ;; end of array
- ((or (= tt js2-RB)
- (= tt js2-EOF)) ; prevent infinite loop
- (if (= tt js2-EOF)
- (js2-report-error "msg.no.bracket.arg" nil pos))
- (when (and after-comma (< js2-language-version 170))
- (js2-parse-warn-trailing-comma "msg.array.trailing.comma"
- pos (remove nil elems) after-comma))
- (setq continue nil
- pn (make-js2-array-node :pos pos
- :len (- js2-ts-cursor pos)
- :elems (nreverse elems)))
- (apply #'js2-node-add-children pn (js2-array-node-elems pn)))
- ;; anything after rest element (...foo)
- (was-rest
- (js2-report-error "msg.param.after.rest"))
- ;; comma
- ((= tt js2-COMMA)
- (setq after-comma (js2-current-token-end))
- (if (not after-lb-or-comma)
- (setq after-lb-or-comma t)
- (push nil elems)))
- ;; array comp
- ((and (>= js2-language-version 170)
- (not js2-is-in-destructuring)
- (= tt js2-FOR) ; check for array comprehension
- (not after-lb-or-comma) ; "for" can't follow a comma
- elems ; must have at least 1 element
- (not (cdr elems))) ; but no 2nd element
- (js2-unget-token)
- (setf continue nil
- pn (js2-parse-legacy-array-comp (car elems) pos)))
- ;; another element
- (t
- (unless after-lb-or-comma
- (js2-report-error "msg.no.bracket.arg"))
- (if (and (= tt js2-TRIPLEDOT)
- (>= js2-language-version 200))
- ;; rest/spread operator
- (progn
- (push (js2-make-unary nil tt 'js2-parse-assign-expr)
- elems)
- (if js2-is-in-destructuring
- (setq was-rest t)))
- (js2-unget-token)
- (push (js2-parse-assign-expr) elems))
- (setq after-lb-or-comma nil
- after-comma nil))))
- (unless js2-is-in-destructuring
- (js2-pop-scope))
- pn))
-
-(defun js2-parse-legacy-array-comp (expr pos)
- "Parse a legacy array comprehension (JavaScript 1.7).
-EXPR is the first expression after the opening left-bracket.
-POS is the beginning of the LB token preceding EXPR.
-We should have just parsed the `for' keyword before calling this function."
- (let ((current-scope js2-current-scope)
- loops first filter result)
- (unwind-protect
- (progn
- (while (js2-match-token js2-FOR)
- (let ((loop (make-js2-comp-loop-node)))
- (js2-push-scope loop)
- (push loop loops)
- (js2-parse-comp-loop loop)))
- ;; First loop takes expr scope's parent.
- (setf (js2-scope-parent-scope (setq first (car (last loops))))
- (js2-scope-parent-scope current-scope))
- ;; Set expr scope's parent to the last loop.
- (setf (js2-scope-parent-scope current-scope) (car loops))
- (if (/= (js2-get-token) js2-IF)
- (js2-unget-token)
- (setq filter (js2-parse-condition))))
- (dotimes (_ (1- (length loops)))
- (js2-pop-scope)))
- (js2-must-match js2-RB "msg.no.bracket.arg" pos)
- (setq result (make-js2-comp-node :pos pos
- :len (- js2-ts-cursor pos)
- :result expr
- :loops (nreverse loops)
- :filters (and filter (list (car filter)))
- :form 'LEGACY_ARRAY))
- ;; Set comp loop's parent to the last loop.
- ;; TODO: Get rid of the bogus expr scope.
- (setf (js2-scope-parent-scope result) first)
- (apply #'js2-node-add-children result expr (car filter)
- (js2-comp-node-loops result))
- result))
-
-(defun js2-parse-array-comp (pos)
- "Parse an ES6 array comprehension.
-POS is the beginning of the LB token.
-We should have just parsed the `for' keyword before calling this function."
- (let ((pn (js2-parse-comprehension pos 'ARRAY)))
- (js2-must-match js2-RB "msg.no.bracket.arg" pos)
- pn))
-
-(defun js2-parse-generator-comp (pos)
- (let* ((js2-nesting-of-function (1+ js2-nesting-of-function))
- (js2-current-script-or-fn
- (make-js2-function-node :generator-type 'COMPREHENSION))
- (pn (js2-parse-comprehension pos 'STAR_GENERATOR)))
- (js2-must-match js2-RP "msg.no.paren" pos)
- pn))
-
-(defun js2-parse-comprehension (pos form)
- (let (loops filters expr result last)
- (unwind-protect
- (progn
- (js2-unget-token)
- (while (js2-match-token js2-FOR)
- (let ((loop (make-js2-comp-loop-node)))
- (js2-push-scope loop)
- (push loop loops)
- (js2-parse-comp-loop loop)))
- (while (js2-match-token js2-IF)
- (push (car (js2-parse-condition)) filters))
- (setq expr (js2-parse-assign-expr))
- (setq last (car loops)))
- (dolist (_ loops)
- (js2-pop-scope)))
- (setq result (make-js2-comp-node :pos pos
- :len (- js2-ts-cursor pos)
- :result expr
- :loops (nreverse loops)
- :filters (nreverse filters)
- :form form))
- (apply #'js2-node-add-children result (js2-comp-node-loops result))
- (apply #'js2-node-add-children result expr (js2-comp-node-filters result))
- (setf (js2-scope-parent-scope result) last)
- result))
-
-(defun js2-parse-comp-loop (pn &optional only-of-p)
- "Parse a `for [each] (foo [in|of] bar)' expression in an Array comprehension.
-The current token should be the initial FOR.
-If ONLY-OF-P is non-nil, only the `for (foo of bar)' form is allowed."
- (let ((pos (js2-comp-loop-node-pos pn))
- tt iter obj foreach-p forof-p in-pos each-pos lp rp)
- (when (and (not only-of-p) (js2-match-token js2-NAME))
- (if (string= (js2-current-token-string) "each")
- (progn
- (setq foreach-p t
- each-pos (- (js2-current-token-beg) pos)) ; relative
- (js2-record-face 'font-lock-keyword-face))
- (js2-report-error "msg.no.paren.for")))
- (if (js2-must-match js2-LP "msg.no.paren.for")
- (setq lp (- (js2-current-token-beg) pos)))
- (setq tt (js2-peek-token))
- (cond
- ((or (= tt js2-LB)
- (= tt js2-LC))
- (js2-get-token)
- (setq iter (js2-parse-destruct-primary-expr))
- (js2-define-destruct-symbols iter js2-LET
- 'font-lock-variable-name-face t))
- ((js2-match-token js2-NAME)
- (setq iter (js2-create-name-node)))
- (t
- (js2-report-error "msg.bad.var")))
- ;; Define as a let since we want the scope of the variable to
- ;; be restricted to the array comprehension
- (if (js2-name-node-p iter)
- (js2-define-symbol js2-LET (js2-name-node-name iter) pn t))
- (if (or (and (not only-of-p) (js2-match-token js2-IN))
- (and (>= js2-language-version 200)
- (js2-match-contextual-kwd "of")
- (setq forof-p t)))
- (setq in-pos (- (js2-current-token-beg) pos))
- (js2-report-error "msg.in.after.for.name"))
- (setq obj (js2-parse-expr))
- (if (js2-must-match js2-RP "msg.no.paren.for.ctrl")
- (setq rp (- (js2-current-token-beg) pos)))
- (setf (js2-node-pos pn) pos
- (js2-node-len pn) (- js2-ts-cursor pos)
- (js2-comp-loop-node-iterator pn) iter
- (js2-comp-loop-node-object pn) obj
- (js2-comp-loop-node-in-pos pn) in-pos
- (js2-comp-loop-node-each-pos pn) each-pos
- (js2-comp-loop-node-foreach-p pn) foreach-p
- (js2-comp-loop-node-forof-p pn) forof-p
- (js2-comp-loop-node-lp pn) lp
- (js2-comp-loop-node-rp pn) rp)
- (js2-node-add-children pn iter obj)
- pn))
-
-(defun js2-parse-class-stmt ()
- (let ((pos (js2-current-token-beg))
- (_ (js2-must-match-name "msg.unnamed.class.stmt"))
- (name (js2-create-name-node t)))
- (js2-set-face (js2-node-pos name) (js2-node-end name)
- 'font-lock-function-name-face 'record)
- (let ((node (js2-parse-class pos 'CLASS_STATEMENT name)))
- (js2-record-imenu-functions node name)
- (js2-define-symbol js2-FUNCTION
- (js2-name-node-name name)
- node)
- node)))
-
-(defun js2-parse-class-expr ()
- (let ((pos (js2-current-token-beg))
- name)
- (when (js2-match-token js2-NAME)
- (setq name (js2-create-name-node t)))
- (js2-parse-class pos 'CLASS_EXPRESSION name)))
-
-(defun js2-parse-class (pos form name)
- ;; class X [extends ...] {
- (let (pn elems extends)
- (if (js2-match-token js2-EXTENDS)
- (if (= (js2-peek-token) js2-LC)
- (js2-report-error "msg.missing.extends")
- ;; TODO(sdh): this should be left-hand-side-expr, not assign-expr
- (setq extends (js2-parse-assign-expr))
- (if (not extends)
- (js2-report-error "msg.bad.extends"))))
- (js2-must-match js2-LC "msg.no.brace.class")
- (setq elems (js2-parse-object-literal-elems t)
- pn (make-js2-class-node :pos pos
- :len (- js2-ts-cursor pos)
- :form form
- :name name
- :extends extends
- :elems elems))
- (apply #'js2-node-add-children
- pn name extends (js2-class-node-elems pn))
- pn))
-
-(defun js2-parse-object-literal ()
- (let* ((pos (js2-current-token-beg))
- (elems (js2-parse-object-literal-elems))
- (result (make-js2-object-node :pos pos
- :len (- js2-ts-cursor pos)
- :elems elems)))
- (apply #'js2-node-add-children result (js2-object-node-elems result))
- result))
-
-(defun js2-property-key-string (property-node)
- "Return the key of PROPERTY-NODE (a `js2-object-prop-node' or
-`js2-method-node') as a string, or nil if it can't be
-represented as a string (e.g., the key is computed by an
-expression)."
- (cond
- ((js2-unary-node-p property-node) nil) ;; {...foo}
- (t
- (let ((key (js2-infix-node-left property-node)))
- (when (js2-computed-prop-name-node-p key)
- (setq key (js2-computed-prop-name-node-expr key)))
- (cond
- ((js2-name-node-p key)
- (js2-name-node-name key))
- ((js2-string-node-p key)
- (js2-string-node-value key))
- ((js2-number-node-p key)
- (js2-number-node-value key)))))))
-
-(defun js2-parse-object-literal-elems (&optional class-p)
- (let ((pos (js2-current-token-beg))
- (static nil)
- (continue t)
- tt elems elem
- elem-key-string previous-elem-key-string
- after-comma previous-token)
- (while continue
- (setq tt (js2-get-prop-name-token)
- static nil
- elem nil
- previous-token nil)
- ;; Handle 'static' keyword only if we're in a class
- (when (and class-p (= js2-NAME tt)
- (string= "static" (js2-current-token-string)))
- (js2-record-face 'font-lock-keyword-face)
- (setq static t
- tt (js2-get-prop-name-token)))
- ;; Handle generator * before the property name for in-line functions
- (when (and (>= js2-language-version 200)
- (= js2-MUL tt))
- (setq previous-token (js2-current-token)
- tt (js2-get-prop-name-token)))
- ;; Handle getter, setter and async methods
- (let ((prop (js2-current-token-string)))
- (when (and (>= js2-language-version 200)
- (= js2-NAME tt)
- (member prop '("get" "set" "async"))
- (member (js2-peek-token 'KEYWORD_IS_NAME)
- (list js2-NAME js2-STRING js2-NUMBER js2-LB)))
- (setq previous-token (js2-current-token)
- tt (js2-get-prop-name-token))))
- (cond
- ;; Rest/spread (...expr)
- ((and (>= js2-language-version 200)
- (not class-p) (not static) (not previous-token)
- (= js2-TRIPLEDOT tt))
- (setq after-comma nil
- elem (js2-make-unary nil js2-TRIPLEDOT 'js2-parse-assign-expr)))
- ;; Found a key/value property (of any sort)
- ((member tt (list js2-NAME js2-STRING js2-NUMBER js2-LB))
- (setq after-comma nil
- elem (js2-parse-named-prop tt previous-token class-p))
- (if (and (null elem)
- (not js2-recover-from-parse-errors))
- (setq continue nil)))
- ;; Break out of loop, and handle trailing commas.
- ((or (= tt js2-RC)
- (= tt js2-EOF))
- (js2-unget-token)
- (setq continue nil)
- (if after-comma
- (js2-parse-warn-trailing-comma "msg.extra.trailing.comma"
- pos elems after-comma)))
- ;; Skip semicolons in a class body
- ((and class-p
- (= tt js2-SEMI))
- nil)
- (t
- (js2-report-error "msg.bad.prop")
- (unless js2-recover-from-parse-errors
- (setq continue nil)))) ; end switch
- ;; Handle static for classes' codegen.
- (if static
- (if elem (js2-node-set-prop elem 'STATIC t)
- (js2-report-error "msg.unexpected.static")))
- ;; Handle commas, depending on class-p.
- (let ((tok (js2-get-prop-name-token)))
- (if (eq tok js2-COMMA)
- (if class-p
- (js2-report-error "msg.class.unexpected.comma")
- (setq after-comma (js2-current-token-end)))
- (js2-unget-token)
- (unless class-p (setq continue nil))))
- (when elem
- (when (and js2-in-use-strict-directive
- (setq elem-key-string (js2-property-key-string elem))
- (cl-some
- (lambda (previous-elem)
- (and (setq previous-elem-key-string
- (js2-property-key-string previous-elem))
- ;; Check if the property is a duplicate.
- (string= previous-elem-key-string elem-key-string)
- ;; But make an exception for getter / setter pairs.
- (not (and (js2-method-node-p elem)
- (js2-method-node-p previous-elem)
- (let ((type (js2-node-get-prop
(js2-method-node-right elem) 'METHOD_TYPE))
- (previous-type (js2-node-get-prop
(js2-method-node-right previous-elem) 'METHOD_TYPE)))
- (and (member type '(GET SET))
- (member previous-type '(GET SET))
- (not (eq type previous-type))))))))
- elems))
- (js2-report-error "msg.dup.obj.lit.prop.strict"
- elem-key-string
- (js2-node-abs-pos (js2-infix-node-left elem))
- (js2-node-len (js2-infix-node-left elem))))
- ;; Append any parsed element.
- (push elem elems))) ; end loop
- (js2-must-match js2-RC "msg.no.brace.prop")
- (nreverse elems)))
-
-(defun js2-parse-named-prop (tt previous-token &optional class-p)
- "Parse a name, string, or getter/setter object property.
-When `js2-is-in-destructuring' is t, forms like {a, b, c} will be permitted."
- (let ((key (js2-parse-prop-name tt))
- (prop (and previous-token (js2-token-string previous-token)))
- (property-type (when previous-token
- (if (= (js2-token-type previous-token) js2-MUL)
- "*"
- (js2-token-string previous-token))))
- pos)
- (when (member prop '("get" "set" "async"))
- (setq pos (js2-token-beg previous-token))
- (js2-set-face (js2-token-beg previous-token)
- (js2-token-end previous-token)
- 'font-lock-keyword-face 'record)) ; get/set/async
- (cond
- ;; method definition: {f() {...}}
- ((and (= (js2-peek-token) js2-LP)
- (>= js2-language-version 200))
- (when (or (js2-name-node-p key) (js2-string-node-p key))
- ;; highlight function name properties
- (js2-record-face 'font-lock-function-name-face))
- (js2-parse-method-prop pos key property-type))
- ;; class field or binding element with initializer
- ((and (= (js2-peek-token) js2-ASSIGN)
- (>= js2-language-version 200))
- (if (not (or class-p
- js2-is-in-destructuring))
- (js2-report-error "msg.init.no.destruct"))
- (js2-parse-initialized-binding key))
- ;; regular prop
- (t
- (let ((beg (js2-current-token-beg))
- (end (js2-current-token-end))
- (expr (js2-parse-plain-property key class-p)))
- (when (and (= tt js2-NAME)
- (not js2-is-in-destructuring)
- js2-highlight-external-variables
- (js2-node-get-prop expr 'SHORTHAND))
- (js2-record-name-node key))
- (js2-set-face beg end
- (if (js2-function-node-p
- (js2-object-prop-node-right expr))
- 'font-lock-function-name-face
- 'js2-object-property)
- 'record)
- expr)))))
-
-(defun js2-parse-initialized-binding (name)
- "Parse a `SingleNameBinding' with initializer.
-
-`name' is the `BindingIdentifier'."
- (when (js2-match-token js2-ASSIGN)
- (js2-make-binary js2-ASSIGN name 'js2-parse-assign-expr t)))
-
-(defun js2-parse-prop-name (tt)
- (cond
- ;; Literal string keys: {'foo': 'bar'}
- ((= tt js2-STRING)
- (make-js2-string-node))
- ;; Handle computed keys: {[Symbol.iterator]: ...}, *[1+2]() {...}},
- ;; {[foo + bar]() { ... }}, {[get ['x' + 1]() {...}}
- ((and (= tt js2-LB)
- (>= js2-language-version 200))
- (make-js2-computed-prop-name-node
- :expr (prog1 (js2-parse-assign-expr)
- (js2-must-match js2-RB "msg.missing.computed.rb"))))
- ;; Numeric keys: {12: 'foo'}, {10.7: 'bar'}
- ((= tt js2-NUMBER)
- (make-js2-number-node))
- ;; Unquoted names: {foo: 12}
- ((= tt js2-NAME)
- (js2-create-name-node))
- ;; Anything else is an error
- (t (js2-report-error "msg.bad.prop"))))
-
-(defun js2-parse-plain-property (prop &optional class-p)
- "Parse a non-getter/setter property in an object literal.
-PROP is the node representing the property: a number, name,
-string or expression."
- (let* (tt
- (pos (js2-node-pos prop))
- colon expr result)
- (cond
- ;; Abbreviated property, as in {foo, bar} or class {a; b}
- ((and (>= js2-language-version 200)
- (if class-p
- (and (setq tt (js2-peek-token-or-eol))
- (member tt (list js2-EOL js2-RC js2-SEMI)))
- (and (setq tt (js2-peek-token))
- (member tt (list js2-COMMA js2-RC))
- (js2-name-node-p prop))))
- (setq result (make-js2-object-prop-node
- :pos pos
- :len (js2-node-len prop)
- :left prop
- :right prop
- :op-pos (- (js2-current-token-beg) pos)))
- (js2-node-add-children result prop)
- (js2-node-set-prop result 'SHORTHAND t)
- result)
- ;; Normal property
- (t
- (setq tt (js2-get-token))
- (if (= tt js2-COLON)
- (setq colon (- (js2-current-token-beg) pos)
- expr (js2-parse-assign-expr))
- (js2-report-error "msg.no.colon.prop")
- (setq expr (make-js2-error-node)))
- (setq result (make-js2-object-prop-node
- :pos pos
- ;; don't include last consumed token in length
- :len (- (+ (js2-node-pos expr)
- (js2-node-len expr))
- pos)
- :left prop
- :right expr
- :op-pos colon))
- (js2-node-add-children result prop expr)
- result))))
-
-(defun js2-parse-method-prop (pos prop type-string)
- "Parse method property in an object literal or a class body.
-JavaScript syntax is:
-
- { foo(...) {...}, get foo() {...}, set foo(x) {...}, *foo(...) {...},
- async foo(...) {...} }
-
-and expression closure style is also supported
-
- { get foo() x, set foo(x) _x = x }
-
-POS is the start position of the `get' or `set' keyword, if any.
-PROP is the `js2-name-node' representing the property name.
-TYPE-STRING is a string `get', `set', `*', or nil, indicating a found keyword."
- (let* ((type (or (cdr (assoc type-string '(("get" . GET)
- ("set" . SET)
- ("async" . ASYNC))))
- 'FUNCTION))
- result end
- (pos (or pos (js2-current-token-beg)))
- (_ (js2-must-match js2-LP "msg.no.paren.parms"))
- (fn (js2-parse-function 'FUNCTION_EXPRESSION pos
- (string= type-string "*")
- (eq type 'ASYNC)
- nil)))
- (js2-node-set-prop fn 'METHOD_TYPE type) ; for codegen
- (unless pos (setq pos (js2-node-pos prop)))
- (setq end (js2-node-end fn)
- result (make-js2-method-node :pos pos
- :len (- end pos)
- :left prop
- :right fn))
- (js2-node-add-children result prop fn)
- result))
-
-(defun js2-create-name-node (&optional check-activation-p token string)
- "Create a name node using the current token and, optionally, STRING.
-And, if CHECK-ACTIVATION-P is non-nil, use the value of TOKEN."
- (let* ((beg (js2-current-token-beg))
- (tt (js2-current-token-type))
- (s (or string
- (if (= js2-NAME tt)
- (js2-current-token-string)
- (js2-tt-name tt))))
- name)
- (setq name (make-js2-name-node :pos beg
- :name s
- :len (length s)))
- (if check-activation-p
- (js2-check-activation-name s (or token js2-NAME)))
- name))
-
-;;; Use AST to extract semantic information
-
-(defun js2-get-element-index-from-array-node (elem array-node &optional
hardcoded-array-index)
- "Get index of ELEM from ARRAY-NODE or 0 and return it as string."
- (let ((idx 0) elems (rlt hardcoded-array-index))
- (setq elems (js2-array-node-elems array-node))
- (if (and elem (not hardcoded-array-index))
- (setq rlt (catch 'nth-elt
- (dolist (x elems)
- ;; We know the ELEM does belong to ARRAY-NODE,
- (if (eq elem x) (throw 'nth-elt idx))
- (setq idx (1+ idx)))
- 0)))
- (format "[%s]" rlt)))
-
-(defun js2-print-json-path (&optional hardcoded-array-index)
- "Print the path to the JSON value under point, and save it in the kill ring.
-If HARDCODED-ARRAY-INDEX provided, array index in JSON path is replaced with
it."
- (interactive "P")
- (js2-reparse)
- (let (previous-node current-node
- key-name
- rlt)
-
- ;; The `js2-node-at-point' starts scanning from AST root node.
- ;; So there is no way to optimize it.
- (setq current-node (js2-node-at-point))
-
- (while (not (js2-ast-root-p current-node))
- (cond
- ;; JSON property node
- ((js2-object-prop-node-p current-node)
- (setq key-name (js2-prop-node-name (js2-object-prop-node-left
current-node)))
- (if rlt (setq rlt (concat "." key-name rlt))
- (setq rlt (concat "." key-name))))
-
- ;; Array node
- ((or (js2-array-node-p current-node))
- (setq rlt (concat (js2-get-element-index-from-array-node previous-node
- current-node
-
hardcoded-array-index)
- rlt)))
-
- ;; Other nodes are ignored
- (t))
-
- ;; current node is archived
- (setq previous-node current-node)
- ;; Get parent node and continue the loop
- (setq current-node (js2-node-parent current-node)))
-
- (cond
- (rlt
- ;; Clean the final result
- (setq rlt (replace-regexp-in-string "^\\." "" rlt))
- (kill-new rlt)
- (message "%s => kill-ring" rlt))
- (t
- (message "No JSON path found!")))
-
- rlt))
-
-;;; Indentation support (bouncing)
-
-;; In recent-enough Emacs, we reuse the indentation code from
-;; `js-mode'. To continue support for the older versions, some code
-;; that was here previously was moved to `js2-old-indent.el'.
-
-;; Whichever indenter is used, it's often "wrong", however, and needs
-;; to be overridden. The right long-term solution is probably to
-;; emulate (or integrate with) cc-engine, but it's a nontrivial amount
-;; of coding. Even when a parse tree from `js2-parse' is present,
-;; which is not true at the moment the user is typing, computing
-;; indentation is still thousands of lines of code to handle every
-;; possible syntactic edge case.
-
-;; In the meantime, the compromise solution is that we offer a "bounce
-;; indenter", configured with `js2-bounce-indent-p', which cycles the
-;; current line indent among various likely guess points. This approach
-;; is far from perfect, but should at least make it slightly easier to
-;; move the line towards its desired indentation when manually
-;; overriding Karl's heuristic nesting guesser.
-
-(defun js2-backward-sws ()
- "Move backward through whitespace and comments."
- (interactive)
- (while (forward-comment -1)))
-
-(defun js2-forward-sws ()
- "Move forward through whitespace and comments."
- (interactive)
- (while (forward-comment 1)))
-
-(defun js2-arglist-close ()
- "Return non-nil if we're on a line beginning with a close-paren/brace."
- (save-excursion
- (goto-char (point-at-bol))
- (js2-forward-sws)
- (looking-at "[])}]")))
-
-(defun js2-indent-looks-like-label-p ()
- (goto-char (point-at-bol))
- (js2-forward-sws)
- (looking-at (concat js2-mode-identifier-re ":")))
-
-(defun js2-indent-in-objlit-p (parse-status)
- "Return non-nil if this looks like an object-literal entry."
- (let ((start (nth 1 parse-status)))
- (and
- start
- (save-excursion
- (and (zerop (forward-line -1))
- (not (< (point) start)) ; crossed a {} boundary
- (js2-indent-looks-like-label-p)))
- (save-excursion
- (js2-indent-looks-like-label-p)))))
-
-;; If prev line looks like foobar({ then we're passing an object
-;; literal to a function call, and people pretty much always want to
-;; de-dent back to the previous line, so move the 'basic-offset'
-;; position to the front.
-(defun js2-indent-objlit-arg-p (parse-status)
- (save-excursion
- (back-to-indentation)
- (js2-backward-sws)
- (and (eq (1- (point)) (nth 1 parse-status))
- (eq (char-before) ?{)
- (progn
- (forward-char -1)
- (skip-chars-backward " \t")
- (eq (char-before) ?\()))))
-
-(defun js2-indent-case-block-p ()
- (save-excursion
- (back-to-indentation)
- (js2-backward-sws)
- (goto-char (point-at-bol))
- (skip-chars-forward " \t")
- (looking-at "case\\s-.+:")))
-
-(defun js2-bounce-indent (normal-col parse-status &optional backward)
- "Cycle among alternate computed indentation positions.
-PARSE-STATUS is the result of `parse-partial-sexp' from the beginning
-of the buffer to the current point. NORMAL-COL is the indentation
-column computed by the heuristic guesser based on current paren,
-bracket, brace and statement nesting. If BACKWARDS, cycle positions
-in reverse."
- (let ((cur-indent (current-indentation))
- (old-buffer-undo-list buffer-undo-list)
- ;; Emacs 21 only has `count-lines', not `line-number-at-pos'
- (current-line (save-excursion
- (forward-line 0) ; move to bol
- (1+ (count-lines (point-min) (point)))))
- positions pos main-pos anchor arglist-cont same-indent
- basic-offset computed-pos)
- ;; temporarily don't record undo info, if user requested this
- (when js2-mode-indent-inhibit-undo
- (setq buffer-undo-list t))
- (unwind-protect
- (progn
- ;; First likely point: indent from beginning of previous code line
- (push (setq basic-offset
- (+ (save-excursion
- (back-to-indentation)
- (js2-backward-sws)
- (back-to-indentation)
- (current-column))
- js2-basic-offset))
- positions)
-
- ;; (First + epsilon) likely point: indent 2x from beginning of
- ;; previous code line. Google does it this way.
- (push (setq basic-offset
- (+ (save-excursion
- (back-to-indentation)
- (js2-backward-sws)
- (back-to-indentation)
- (current-column))
- (* 2 js2-basic-offset)))
- positions)
-
- ;; Second likely point: indent from assign-expr RHS. This
- ;; is just a crude guess based on finding " = " on the previous
- ;; line containing actual code.
- (setq pos (save-excursion
- (forward-line -1)
- (goto-char (point-at-bol))
- (when (re-search-forward "\\s-+\\(=\\)\\s-+"
- (point-at-eol) t)
- (goto-char (match-end 1))
- (skip-chars-forward " \t\r\n")
- (current-column))))
- (when pos
- (cl-incf pos js2-basic-offset)
- (push pos positions))
-
- ;; Third likely point: same indent as previous line of code.
- ;; Make it the first likely point if we're not on an
- ;; arglist-close line and previous line ends in a comma, or
- ;; both this line and prev line look like object-literal
- ;; elements.
- (setq pos (save-excursion
- (goto-char (point-at-bol))
- (js2-backward-sws)
- (back-to-indentation)
- (prog1
- (current-column)
- ;; while we're here, look for trailing comma
- (if (save-excursion
- (goto-char (point-at-eol))
- (js2-backward-sws)
- (eq (char-before) ?,))
- (setq arglist-cont (1- (point)))))))
- (when pos
- (if (and (or arglist-cont
- (js2-indent-in-objlit-p parse-status))
- (not (js2-arglist-close)))
- (setq same-indent pos))
- (push pos positions))
-
- ;; Fourth likely point: first preceding code with less indentation.
- ;; than the immediately preceding code line.
- (setq pos (save-excursion
- (back-to-indentation)
- (js2-backward-sws)
- (back-to-indentation)
- (setq anchor (current-column))
- (while (and (zerop (forward-line -1))
- (>= (progn
- (back-to-indentation)
- (current-column))
- anchor)))
- (setq pos (current-column))))
- (push pos positions)
-
- ;; nesting-heuristic position, main by default
- (push (setq main-pos normal-col) positions)
-
- ;; delete duplicates and sort positions list
- (setq positions (sort (delete-dups positions) '<))
-
- ;; comma-list continuation lines: prev line indent takes precedence
- (if same-indent
- (setq main-pos same-indent))
-
- ;; common special cases where we want to indent in from previous line
- (if (or (js2-indent-case-block-p)
- (js2-indent-objlit-arg-p parse-status))
- (setq main-pos basic-offset))
-
- ;; if bouncing backward, reverse positions list
- (if backward
- (setq positions (reverse positions)))
-
- ;; record whether we're already sitting on one of the alternatives
- (setq pos (member cur-indent positions))
-
- (cond
- ;; case 0: we're one one of the alternatives and this is the
- ;; first time they've pressed TAB on this line (best-guess).
- ((and js2-mode-indent-ignore-first-tab
- pos
- ;; first time pressing TAB on this line?
- (not (eq js2-mode-last-indented-line current-line)))
- ;; do nothing
- (setq computed-pos nil))
- ;; case 1: only one computed position => use it
- ((null (cdr positions))
- (setq computed-pos 0))
- ;; case 2: not on any of the computed spots => use main spot
- ((not pos)
- (setq computed-pos (js2-position main-pos positions)))
- ;; case 3: on last position: cycle to first position
- ((null (cdr pos))
- (setq computed-pos 0))
- ;; case 4: on intermediate position: cycle to next position
- (t
- (setq computed-pos (js2-position (cl-second pos) positions))))
-
- ;; see if any hooks want to indent; otherwise we do it
- (cl-loop with result = nil
- for hook in js2-indent-hook
- while (null result)
- do
- (setq result (funcall hook positions computed-pos))
- finally do
- (unless (or result (null computed-pos))
- (indent-line-to (nth computed-pos positions)))))
-
- ;; finally
- (if js2-mode-indent-inhibit-undo
- (setq buffer-undo-list old-buffer-undo-list))
- ;; see commentary for `js2-mode-last-indented-line'
- (setq js2-mode-last-indented-line current-line))))
-
-(defun js2-1-line-comment-continuation-p ()
- "Return t if we're in a 1-line comment continuation.
-If so, we don't ever want to use bounce-indent."
- (save-excursion
- (and (progn
- (forward-line 0)
- (looking-at "\\s-*//"))
- (progn
- (forward-line -1)
- (forward-line 0)
- (when (looking-at "\\s-*$")
- (js2-backward-sws)
- (forward-line 0))
- (looking-at "\\s-*//")))))
-
-(defun js2-indent-bounce (&optional backward)
- "Indent the current line, bouncing between several positions."
- (interactive)
- (let (parse-status offset indent-col
- ;; Don't whine about errors/warnings when we're indenting.
- ;; This has to be set before calling parse-partial-sexp below.
- (inhibit-point-motion-hooks t))
- (setq parse-status (save-excursion
- (syntax-ppss (point-at-bol)))
- offset (- (point) (save-excursion
- (back-to-indentation)
- (point))))
- ;; Don't touch multiline strings.
- (unless (nth 3 parse-status)
- (setq indent-col (js2-proper-indentation parse-status))
- (cond
- ;; It doesn't work well on first line of buffer.
- ((and (not (nth 4 parse-status))
- (not (js2-same-line (point-min)))
- (not (js2-1-line-comment-continuation-p)))
- (js2-bounce-indent indent-col parse-status backward))
- ;; just indent to the guesser's likely spot
- (t (indent-line-to indent-col)))
- (when (cl-plusp offset)
- (forward-char offset)))))
-
-(defun js2-indent-bounce-backward ()
- "Indent the current line, bouncing between positions in reverse."
- (interactive)
- (js2-indent-bounce t))
-
-(defun js2-indent-region (start end)
- "Indent the region, but don't use bounce indenting."
- (let ((js2-bounce-indent-p nil)
- (indent-region-function nil)
- (after-change-functions (remq 'js2-mode-edit
- after-change-functions)))
- (indent-region start end nil) ; nil for byte-compiler
- (js2-mode-edit start end (- end start))))
-
-(defvar js2-minor-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map (kbd "C-c C-`") #'js2-next-error)
- map)
- "Keymap used when `js2-minor-mode' is active.")
-
-;;;###autoload
-(define-minor-mode js2-minor-mode
- "Minor mode for running js2 as a background linter.
-This allows you to use a different major mode for JavaScript editing,
-such as `js-mode', while retaining the asynchronous error/warning
-highlighting features of `js2-mode'."
- :group 'js2-mode
- :lighter " js-lint"
- (if (derived-mode-p 'js2-mode)
- (setq js2-minor-mode nil)
- (if js2-minor-mode
- (js2-minor-mode-enter)
- (js2-minor-mode-exit))))
-
-(defun js2-minor-mode-enter ()
- "Initialization for `js2-minor-mode'."
- (set (make-local-variable 'max-lisp-eval-depth)
- (max max-lisp-eval-depth 3000))
- (setq next-error-function #'js2-next-error)
- ;; Experiment: make reparse-delay longer for longer files.
- (if (cl-plusp js2-dynamic-idle-timer-adjust)
- (setq js2-idle-timer-delay
- (* js2-idle-timer-delay
- (/ (point-max) js2-dynamic-idle-timer-adjust))))
- (setq js2-mode-buffer-dirty-p t
- js2-mode-parsing nil)
- (set (make-local-variable 'js2-highlight-level) 0) ; no syntax highlighting
- (add-hook 'after-change-functions #'js2-minor-mode-edit nil t)
- (add-hook 'change-major-mode-hook #'js2-minor-mode-exit nil t)
- (when js2-include-jslint-globals
- (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
- (when js2-include-jslint-declaration-externs
- (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs
nil t))
- (run-hooks 'js2-init-hook)
- (js2-reparse))
-
-(defun js2-minor-mode-exit ()
- "Turn off `js2-minor-mode'."
- (setq next-error-function nil)
- (remove-hook 'after-change-functions #'js2-mode-edit t)
- (remove-hook 'change-major-mode-hook #'js2-minor-mode-exit t)
- (when js2-mode-node-overlay
- (delete-overlay js2-mode-node-overlay)
- (setq js2-mode-node-overlay nil))
- (js2-remove-overlays)
- (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals t)
- (remove-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs
t)
- (setq js2-mode-ast nil))
-
-(defvar js2-source-buffer nil "Linked source buffer for diagnostics view")
-(make-variable-buffer-local 'js2-source-buffer)
-
-(cl-defun js2-display-error-list ()
- "Display a navigable buffer listing parse errors/warnings."
- (interactive)
- (unless (js2-have-errors-p)
- (message "No errors")
- (cl-return-from js2-display-error-list))
- (cl-labels ((annotate-list
- (lst type)
- "Add diagnostic TYPE and line number to errs list"
- (mapcar (lambda (err)
- (list err type (line-number-at-pos (nth 1 err))))
- lst)))
- (let* ((srcbuf (current-buffer))
- (errbuf (get-buffer-create "*js-lint*"))
- (errors (annotate-list
- (when js2-mode-ast (js2-ast-root-errors js2-mode-ast))
- 'js2-error)) ; must be a valid face name
- (warnings (annotate-list
- (when js2-mode-ast (js2-ast-root-warnings js2-mode-ast))
- 'js2-warning)) ; must be a valid face name
- (all-errs (sort (append errors warnings)
- (lambda (e1 e2) (< (cl-cadar e1) (cl-cadar e2))))))
- (with-current-buffer errbuf
- (let ((inhibit-read-only t))
- (erase-buffer)
- (dolist (err all-errs)
- (cl-destructuring-bind ((msg-key beg _end &rest) type line) err
- (insert-text-button
- (format "line %d: %s" line (js2-get-msg msg-key))
- 'face type
- 'follow-link "\C-m"
- 'action 'js2-error-buffer-jump
- 'js2-msg (js2-get-msg msg-key)
- 'js2-pos beg)
- (insert "\n"))))
- (js2-error-buffer-mode)
- (setq js2-source-buffer srcbuf)
- (pop-to-buffer errbuf)
- (goto-char (point-min))
- (unless (eobp)
- (js2-error-buffer-view))))))
-
-(defvar js2-error-buffer-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map "n" #'js2-error-buffer-next)
- (define-key map "p" #'js2-error-buffer-prev)
- (define-key map (kbd "RET") #'js2-error-buffer-jump)
- (define-key map "o" #'js2-error-buffer-view)
- (define-key map "q" #'js2-error-buffer-quit)
- map)
- "Keymap used for js2 diagnostics buffers.")
-
-(define-derived-mode js2-error-buffer-mode special-mode "JS Lint Diagnostics"
- "Major mode for js2 diagnostics buffers.
-Selecting an error will jump it to the corresponding source-buffer error.
-\\{js2-error-buffer-mode-map}"
- (setq truncate-lines t)
- (set-buffer-modified-p nil)
- (setq buffer-read-only t))
-
-(defun js2-error-buffer-next ()
- "Move to next error and view it."
- (interactive)
- (when (zerop (forward-line 1))
- (js2-error-buffer-view)))
-
-(defun js2-error-buffer-prev ()
- "Move to previous error and view it."
- (interactive)
- (when (zerop (forward-line -1))
- (js2-error-buffer-view)))
-
-(defun js2-error-buffer-quit ()
- "Kill the current buffer."
- (interactive)
- (kill-buffer))
-
-(defun js2-error-buffer-jump (&rest ignored)
- "Jump cursor to current error in source buffer."
- (interactive)
- (when (js2-error-buffer-view)
- (pop-to-buffer js2-source-buffer)))
-
-(defun js2-error-buffer-view ()
- "Scroll source buffer to show error at current line."
- (interactive)
- (cond
- ((not (derived-mode-p 'js2-error-buffer-mode))
- (message "Not in a js2 errors buffer"))
- ((not (buffer-live-p js2-source-buffer))
- (message "Source buffer has been killed"))
- ((not (wholenump (get-text-property (point) 'js2-pos)))
- (message "There does not seem to be an error here"))
- (t
- (let ((pos (get-text-property (point) 'js2-pos))
- (msg (get-text-property (point) 'js2-msg)))
- (save-selected-window
- (pop-to-buffer js2-source-buffer)
- (goto-char pos)
- (message msg))))))
-
-;;;###autoload
-(define-derived-mode js2-mode js-mode "Javascript-IDE"
- "Major mode for editing JavaScript code."
- (set (make-local-variable 'max-lisp-eval-depth)
- (max max-lisp-eval-depth 3000))
- (set (make-local-variable 'indent-line-function) #'js2-indent-line)
- (set (make-local-variable 'indent-region-function) #'js2-indent-region)
- (set (make-local-variable 'syntax-propertize-function) nil)
- (set (make-local-variable 'comment-line-break-function) #'js2-line-break)
- (set (make-local-variable 'beginning-of-defun-function)
#'js2-beginning-of-defun)
- (set (make-local-variable 'end-of-defun-function) #'js2-end-of-defun)
- ;; We un-confuse `parse-partial-sexp' by setting syntax-table properties
- ;; for characters inside regexp literals.
- (set (make-local-variable 'parse-sexp-lookup-properties) t)
- ;; this is necessary to make `show-paren-function' work properly
- (set (make-local-variable 'parse-sexp-ignore-comments) t)
- ;; needed for M-x rgrep, among other things
- (put 'js2-mode 'find-tag-default-function #'js2-mode-find-tag)
-
- (setq font-lock-defaults '(nil t))
-
- ;; Experiment: make reparse-delay longer for longer files.
- (when (cl-plusp js2-dynamic-idle-timer-adjust)
- (setq js2-idle-timer-delay
- (* js2-idle-timer-delay
- (/ (point-max) js2-dynamic-idle-timer-adjust))))
-
- (add-hook 'change-major-mode-hook #'js2-mode-exit nil t)
- (add-hook 'after-change-functions #'js2-mode-edit nil t)
- (setq imenu-create-index-function #'js2-mode-create-imenu-index)
- (setq next-error-function #'js2-next-error)
- (imenu-add-to-menubar (concat "IM-" mode-name))
- (add-to-invisibility-spec '(js2-outline . t))
- (set (make-local-variable 'line-move-ignore-invisible) t)
- (set (make-local-variable 'forward-sexp-function) #'js2-mode-forward-sexp)
- (when (fboundp 'cursor-sensor-mode) (cursor-sensor-mode 1))
-
- (setq js2-mode-functions-hidden nil
- js2-mode-comments-hidden nil
- js2-mode-buffer-dirty-p t
- js2-mode-parsing nil)
-
- (when js2-include-jslint-globals
- (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-globals nil t))
- (when js2-include-jslint-declaration-externs
- (add-hook 'js2-post-parse-callbacks 'js2-apply-jslint-declaration-externs
nil t))
-
- (run-hooks 'js2-init-hook)
-
- (let ((js2-idle-timer-delay 0))
- ;; Schedule parsing for after when the mode hooks run.
- (js2-mode-reset-timer)))
-
-;; We may eventually want js2-jsx-mode to derive from js-jsx-mode, but that'd
be
-;; a bit more complicated and it doesn't net us much yet.
-;;;###autoload
-(define-derived-mode js2-jsx-mode js2-mode "JSX-IDE"
- "Major mode for editing JSX code.
-
-To customize the indentation for this mode, set the SGML offset
-variables (`sgml-basic-offset' et al) locally, like so:
-
- (defun set-jsx-indentation ()
- (setq-local sgml-basic-offset js2-basic-offset))
- (add-hook \\='js2-jsx-mode-hook #\\='set-jsx-indentation)"
- (set (make-local-variable 'indent-line-function) #'js2-jsx-indent-line))
-
-(defun js2-mode-exit ()
- "Exit `js2-mode' and clean up."
- (interactive)
- (when js2-mode-node-overlay
- (delete-overlay js2-mode-node-overlay)
- (setq js2-mode-node-overlay nil))
- (js2-remove-overlays)
- (setq js2-mode-ast nil)
- (remove-hook 'change-major-mode-hook #'js2-mode-exit t)
- (remove-from-invisibility-spec '(js2-outline . t))
- (js2-mode-show-all)
- (with-silent-modifications
- (js2-clear-face (point-min) (point-max))))
-
-(defun js2-mode-reset-timer ()
- "Cancel any existing parse timer and schedule a new one."
- (if js2-mode-parse-timer
- (cancel-timer js2-mode-parse-timer))
- (setq js2-mode-parsing nil)
- (let ((timer (timer-create)))
- (setq js2-mode-parse-timer timer)
- (timer-set-function timer 'js2-mode-idle-reparse (list (current-buffer)))
- (timer-set-idle-time timer js2-idle-timer-delay)
- ;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=12326
- (timer-activate-when-idle timer nil)))
-
-(defun js2-mode-idle-reparse (buffer)
- "Run `js2-reparse' if BUFFER is the current buffer, or schedule
-it to be reparsed when the buffer is selected."
- (cond ((eq buffer (current-buffer))
- (js2-reparse))
- ((buffer-live-p buffer)
- ;; reparse when the buffer is selected again
- (with-current-buffer buffer
- (add-hook 'window-configuration-change-hook
- #'js2-mode-idle-reparse-inner
- nil t)))))
-
-(defun js2-mode-idle-reparse-inner ()
- (remove-hook 'window-configuration-change-hook
- #'js2-mode-idle-reparse-inner
- t)
- (js2-reparse))
-
-(defun js2-mode-edit (_beg _end _len)
- "Schedule a new parse after buffer is edited.
-Buffer edit spans from BEG to END and is of length LEN."
- (setq js2-mode-buffer-dirty-p t)
- (js2-mode-hide-overlay)
- (js2-mode-reset-timer))
-
-(defun js2-minor-mode-edit (_beg _end _len)
- "Callback for buffer edits in `js2-mode'.
-Schedules a new parse after buffer is edited.
-Buffer edit spans from BEG to END and is of length LEN."
- (setq js2-mode-buffer-dirty-p t)
- (js2-mode-hide-overlay)
- (js2-mode-reset-timer))
-
-(defun js2-reparse (&optional force)
- "Re-parse current buffer after user finishes some data entry.
-If we get any user input while parsing, including cursor motion,
-we discard the parse and reschedule it. If FORCE is nil, then the
-buffer will only rebuild its `js2-mode-ast' if the buffer is dirty."
- (let (time
- interrupted-p
- (js2-compiler-strict-mode js2-mode-show-strict-warnings))
- (unless js2-mode-parsing
- (setq js2-mode-parsing t)
- (unwind-protect
- (when (or js2-mode-buffer-dirty-p force)
- (js2-remove-overlays)
- (setq js2-mode-buffer-dirty-p nil
- js2-mode-fontifications nil
- js2-mode-deferred-properties nil)
- (if js2-mode-verbose-parse-p
- (message "parsing..."))
- (setq time
- (js2-time
- (setq interrupted-p
- (catch 'interrupted
- (js2-parse)
- (with-silent-modifications
- ;; if parsing is interrupted, comments and regex
- ;; literals stay ignored by `parse-partial-sexp'
- (remove-text-properties (point-min) (point-max)
- '(syntax-table))
- (js2-mode-apply-deferred-properties)
- (js2-mode-remove-suppressed-warnings)
- (js2-mode-show-warnings)
- (js2-mode-show-errors)
- (if (>= js2-highlight-level 1)
- (js2-highlight-jsdoc js2-mode-ast)))
- nil))))
- (if interrupted-p
- (progn
- ;; unfinished parse => try again
- (setq js2-mode-buffer-dirty-p t)
- (js2-mode-reset-timer))
- (if js2-mode-verbose-parse-p
- (message "Parse time: %s" time))))
- (setq js2-mode-parsing nil)
- (unless interrupted-p
- (setq js2-mode-parse-timer nil))))))
-
-;; We bound it to [mouse-1] previously. But the signature of
-;; mouse-set-point changed around 24.4, so it's kind of hard to keep
-;; it working in 24.1-24.3. Since the command is not hugely
-;; important, we removed the binding (#356). Maybe we'll bring it
-;; back when supporting <24.4 is not a goal anymore.
-(defun js2-mode-show-node (event &optional promote-to-region)
- "Debugging aid: highlight selected AST node on mouse click."
- (interactive "e\np")
- (mouse-set-point event promote-to-region)
- (when js2-mode-show-overlay
- (let ((node (js2-node-at-point))
- beg end)
- (if (null node)
- (message "No node found at location %s" (point))
- (setq beg (js2-node-abs-pos node)
- end (+ beg (js2-node-len node)))
- (if js2-mode-node-overlay
- (move-overlay js2-mode-node-overlay beg end)
- (setq js2-mode-node-overlay (make-overlay beg end))
- (overlay-put js2-mode-node-overlay 'font-lock-face 'highlight))
- (with-silent-modifications
- (if (fboundp 'cursor-sensor-mode)
- (put-text-property beg end 'cursor-sensor-functions
- '(js2-mode-hide-overlay))
- (put-text-property beg end 'point-left #'js2-mode-hide-overlay)))
- (message "%s, parent: %s"
- (js2-node-short-name node)
- (if (js2-node-parent node)
- (js2-node-short-name (js2-node-parent node))
- "nil"))))))
-
-(defun js2-mode-hide-overlay (&optional arg1 arg2 _arg3)
- "Remove the debugging overlay when point moves.
-ARG1, ARG2 and ARG3 have different values depending on whether this function
-was found on `point-left' or in `cursor-sensor-functions'."
- (when js2-mode-node-overlay
- (let ((beg (overlay-start js2-mode-node-overlay))
- (end (overlay-end js2-mode-node-overlay))
- (p2 (if (windowp arg1)
- ;; Called from cursor-sensor-functions.
- (window-point arg1)
- ;; Called from point-left.
- arg2)))
- ;; Sometimes we're called spuriously.
- (unless (and p2
- (>= p2 beg)
- (<= p2 end))
- (with-silent-modifications
- (remove-text-properties beg end
- '(point-left nil cursor-sensor-functions)))
- (delete-overlay js2-mode-node-overlay)
- (setq js2-mode-node-overlay nil)))))
-
-(defun js2-mode-reset ()
- "Debugging helper: reset everything."
- (interactive)
- (js2-mode-exit)
- (js2-mode))
-
-(defun js2-mode-show-warn-or-err (e face)
- "Highlight a warning or error E with FACE.
-E is a list of ((MSG-KEY MSG-ARG) BEG LEN OVERRIDE-FACE).
-The last element is optional. When present, use instead of FACE."
- (let* ((key (cl-first e))
- (beg (cl-second e))
- (end (+ beg (cl-third e)))
- ;; Don't inadvertently go out of bounds.
- (beg (max (point-min) (min beg (point-max))))
- (end (max (point-min) (min end (point-max))))
- (ovl (make-overlay beg end)))
- ;; FIXME: Why a mix of overlays and text-properties?
- (overlay-put ovl 'font-lock-face (or (cl-fourth e) face))
- (overlay-put ovl 'js2-error t)
- (put-text-property beg end 'help-echo (js2-get-msg key))
- (if (fboundp 'cursor-sensor-mode)
- (put-text-property beg end 'cursor-sensor-functions '(js2-echo-error))
- (put-text-property beg end 'point-entered #'js2-echo-error))))
-
-(defun js2-remove-overlays ()
- "Remove overlays from buffer that have a `js2-error' property."
- (let ((beg (point-min))
- (end (point-max)))
- (save-excursion
- (dolist (o (overlays-in beg end))
- (when (overlay-get o 'js2-error)
- (delete-overlay o))))))
-
-(defun js2-mode-apply-deferred-properties ()
- "Apply fontifications and other text properties recorded during parsing."
- (when (cl-plusp js2-highlight-level)
- ;; We defer clearing faces as long as possible to eliminate flashing.
- (js2-clear-face (point-min) (point-max))
- ;; Have to reverse the recorded fontifications list so that errors
- ;; and warnings overwrite the normal fontifications.
- (dolist (f (nreverse js2-mode-fontifications))
- (put-text-property (cl-first f) (cl-second f) 'font-lock-face (cl-third
f)))
- (setq js2-mode-fontifications nil))
- (dolist (p js2-mode-deferred-properties)
- (apply #'put-text-property p))
- (setq js2-mode-deferred-properties nil))
-
-(defun js2-mode-show-errors ()
- "Highlight syntax errors."
- (when js2-mode-show-parse-errors
- (dolist (e (js2-ast-root-errors js2-mode-ast))
- (js2-mode-show-warn-or-err e 'js2-error))))
-
-(defun js2-mode-remove-suppressed-warnings ()
- "Take suppressed warnings out of the AST warnings list.
-This ensures that the counts and `next-error' are correct."
- (setf (js2-ast-root-warnings js2-mode-ast)
- (js2-delete-if
- (lambda (e)
- (let ((key (caar e)))
- (or
- (and (not js2-strict-trailing-comma-warning)
- (string-match "trailing\\.comma" key))
- (and (not js2-strict-cond-assign-warning)
- (string= key "msg.equal.as.assign"))
- (and js2-missing-semi-one-line-override
- (string= key "msg.missing.semi")
- (let* ((beg (cl-second e))
- (node (js2-node-at-point beg))
- (fn (js2-mode-find-parent-fn node))
- (body (and fn (js2-function-node-body fn)))
- (lc (and body (js2-node-abs-pos body)))
- (rc (and lc (+ lc (js2-node-len body)))))
- (and fn
- (or (null body)
- (save-excursion
- (goto-char beg)
- (and (js2-same-line lc)
- (js2-same-line rc))))))))))
- (js2-ast-root-warnings js2-mode-ast))))
-
-(defun js2-mode-show-warnings ()
- "Highlight strict-mode warnings."
- (when js2-mode-show-strict-warnings
- (dolist (e (js2-ast-root-warnings js2-mode-ast))
- (js2-mode-show-warn-or-err e 'js2-warning))))
-
-(defun js2-echo-error (arg1 arg2 &optional _arg3)
- "Called by point-motion hooks.
-ARG1, ARG2 and ARG3 have different values depending on whether this function
-was found on `point-entered' or in `cursor-sensor-functions'."
- (let* ((new-point (if (windowp arg1)
- ;; Called from cursor-sensor-functions.
- (window-point arg1)
- ;; Called from point-left.
- arg2))
- (msg (get-text-property new-point 'help-echo)))
- (when (and (stringp msg)
- (not (active-minibuffer-window))
- (not (current-message)))
- (message msg))))
-
-(defun js2-line-break (&optional _soft)
- "Break line at point and indent, continuing comment if within one.
-If inside a string, and `js2-concat-multiline-strings' is not
-nil, turn it into concatenation."
- (interactive)
- (let ((parse-status (syntax-ppss)))
- (cond
- ;; Check if we're inside a string.
- ((nth 3 parse-status)
- (if js2-concat-multiline-strings
- (js2-mode-split-string parse-status)
- (insert "\n")))
- ;; Check if inside a block comment.
- ((nth 4 parse-status)
- (js2-mode-extend-comment (nth 8 parse-status)))
- (t
- (newline-and-indent)))))
-
-(defun js2-mode-split-string (parse-status)
- "Turn a newline in mid-string into a string concatenation.
-PARSE-STATUS is as documented in `parse-partial-sexp'."
- (let* ((quote-char (nth 3 parse-status))
- (at-eol (eq js2-concat-multiline-strings 'eol)))
- (insert quote-char)
- (insert (if at-eol " +\n" "\n"))
- (unless at-eol
- (insert "+ "))
- (js2-indent-line)
- (insert quote-char)
- (when (eolp)
- (insert quote-char)
- (backward-char 1))))
-
-(defun js2-mode-extend-comment (start-pos)
- "Indent the line and, when inside a comment block, add comment prefix."
- (let (star single col first-line needs-close)
- (save-excursion
- (back-to-indentation)
- (when (< (point) start-pos)
- (goto-char start-pos))
- (cond
- ((looking-at "\\*[^/]")
- (setq star t
- col (current-column)))
- ((looking-at "/\\*")
- (setq star t
- first-line t
- col (1+ (current-column))))
- ((looking-at "//")
- (setq single t
- col (current-column)))))
- ;; Heuristic for whether we need to close the comment:
- ;; if we've got a parse error here, assume it's an unterminated
- ;; comment.
- (setq needs-close
- (or
- (get-char-property (1- (point)) 'js2-error)
- ;; The heuristic above doesn't work well when we're
- ;; creating a comment and there's another one downstream,
- ;; as our parser thinks this one ends at the end of the
- ;; next one. (You can have a /* inside a js block comment.)
- ;; So just close it if the next non-ws char isn't a *.
- (and first-line
- (eolp)
- (save-excursion
- (skip-chars-forward " \t\r\n")
- (not (eq (char-after) ?*))))))
- (delete-horizontal-space)
- (insert "\n")
- (cond
- (star
- (indent-to col)
- (insert "* ")
- (if (and first-line needs-close)
- (save-excursion
- (insert "\n")
- (indent-to col)
- (insert "*/"))))
- (single
- (indent-to col)
- (insert "// ")))
- ;; Don't need to extend the comment after all.
- (js2-indent-line)))
-
-(defun js2-beginning-of-line ()
- "Toggle point between bol and first non-whitespace char in line.
-Also moves past comment delimiters when inside comments."
- (interactive)
- (let (node)
- (cond
- ((bolp)
- (back-to-indentation))
- ((looking-at "//")
- (skip-chars-forward "/ \t"))
- ((and (eq (char-after) ?*)
- (setq node (js2-comment-at-point))
- (memq (js2-comment-node-format node) '(jsdoc block))
- (save-excursion
- (skip-chars-backward " \t")
- (bolp)))
- (skip-chars-forward "\* \t"))
- (t
- (goto-char (point-at-bol))))))
-
-(defun js2-end-of-line ()
- "Toggle point between eol and last non-whitespace char in line."
- (interactive)
- (if (eolp)
- (skip-chars-backward " \t")
- (goto-char (point-at-eol))))
-
-(defun js2-mode-wait-for-parse (callback)
- "Invoke CALLBACK when parsing is finished.
-If parsing is already finished, calls CALLBACK immediately."
- (if (not js2-mode-buffer-dirty-p)
- (funcall callback)
- (push callback js2-mode-pending-parse-callbacks)
- (add-hook 'js2-parse-finished-hook #'js2-mode-parse-finished)))
-
-(defun js2-mode-parse-finished ()
- "Invoke callbacks in `js2-mode-pending-parse-callbacks'."
- ;; We can't let errors propagate up, since it prevents the
- ;; `js2-parse' method from completing normally and returning
- ;; the ast, which makes things mysteriously not work right.
- (unwind-protect
- (dolist (cb js2-mode-pending-parse-callbacks)
- (condition-case err
- (funcall cb)
- (error (message "%s" err))))
- (setq js2-mode-pending-parse-callbacks nil)))
-
-(defun js2-mode-flag-region (from to flag)
- "Hide or show text from FROM to TO, according to FLAG.
-If FLAG is nil then text is shown, while if FLAG is t the text is hidden.
-Returns the created overlay if FLAG is non-nil."
- (remove-overlays from to 'invisible 'js2-outline)
- (when flag
- (let ((o (make-overlay from to)))
- (overlay-put o 'invisible 'js2-outline)
- (overlay-put o 'isearch-open-invisible
- 'js2-isearch-open-invisible)
- o)))
-
-;; Function to be set as an outline-isearch-open-invisible' property
-;; to the overlay that makes the outline invisible (see
-;; `js2-mode-flag-region').
-(defun js2-isearch-open-invisible (_overlay)
- ;; We rely on the fact that isearch places point on the matched text.
- (js2-mode-show-element))
-
-(defun js2-mode-invisible-overlay-bounds (&optional pos)
- "Return cons cell of bounds of folding overlay at POS.
-Returns nil if not found."
- (let ((overlays (overlays-at (or pos (point))))
- o)
- (while (and overlays
- (not o))
- (if (overlay-get (car overlays) 'invisible)
- (setq o (car overlays))
- (setq overlays (cdr overlays))))
- (if o
- (cons (overlay-start o) (overlay-end o)))))
-
-(defun js2-mode-function-at-point (&optional pos)
- "Return the innermost function node enclosing current point.
-Returns nil if point is not in a function."
- (let ((node (js2-node-at-point pos)))
- (while (and node (not (js2-function-node-p node)))
- (setq node (js2-node-parent node)))
- (if (js2-function-node-p node)
- node)))
-
-(defun js2-mode-toggle-element ()
- "Hide or show the foldable element at the point."
- (interactive)
- (let (comment fn pos)
- (save-excursion
- (cond
- ;; /* ... */ comment?
- ((js2-block-comment-p (setq comment (js2-comment-at-point)))
- (if (js2-mode-invisible-overlay-bounds
- (setq pos (+ 3 (js2-node-abs-pos comment))))
- (progn
- (goto-char pos)
- (js2-mode-show-element))
- (js2-mode-hide-element)))
- ;; //-comment?
- ((save-excursion
- (back-to-indentation)
- (looking-at js2-mode-//-comment-re))
- (js2-mode-toggle-//-comment))
- ;; function?
- ((setq fn (js2-mode-function-at-point))
- (setq pos (and (js2-function-node-body fn)
- (js2-node-abs-pos (js2-function-node-body fn))))
- (goto-char (1+ pos))
- (if (js2-mode-invisible-overlay-bounds)
- (js2-mode-show-element)
- (js2-mode-hide-element)))
- (t
- (message "Nothing at point to hide or show"))))))
-
-(defun js2-mode-hide-element ()
- "Fold/hide contents of a block, showing ellipses.
-Show the hidden text with \\[js2-mode-show-element]."
- (interactive)
- (if js2-mode-buffer-dirty-p
- (js2-mode-wait-for-parse #'js2-mode-hide-element))
- (let (node body beg end)
- (cond
- ((js2-mode-invisible-overlay-bounds)
- (message "already hidden"))
- (t
- (setq node (js2-node-at-point))
- (cond
- ((js2-block-comment-p node)
- (js2-mode-hide-comment node))
- (t
- (while (and node (not (js2-function-node-p node)))
- (setq node (js2-node-parent node)))
- (if (and node
- (setq body (js2-function-node-body node)))
- (progn
- (setq beg (js2-node-abs-pos body)
- end (+ beg (js2-node-len body)))
- (js2-mode-flag-region (1+ beg) (1- end) 'hide))
- (message "No collapsable element found at point"))))))))
-
-(defun js2-mode-show-element ()
- "Show the hidden element at current point."
- (interactive)
- (let ((bounds (js2-mode-invisible-overlay-bounds)))
- (if bounds
- (js2-mode-flag-region (car bounds) (cdr bounds) nil)
- (message "Nothing to un-hide"))))
-
-(defun js2-mode-show-all ()
- "Show all of the text in the buffer."
- (interactive)
- (js2-mode-flag-region (point-min) (point-max) nil))
-
-(defun js2-mode-toggle-hide-functions ()
- (interactive)
- (if js2-mode-functions-hidden
- (js2-mode-show-functions)
- (js2-mode-hide-functions)))
-
-(defun js2-mode-hide-functions ()
- "Hides all non-nested function bodies in the buffer.
-Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
-to open an individual entry."
- (interactive)
- (if js2-mode-buffer-dirty-p
- (js2-mode-wait-for-parse #'js2-mode-hide-functions))
- (if (null js2-mode-ast)
- (message "Oops - parsing failed")
- (setq js2-mode-functions-hidden t)
- (js2-visit-ast js2-mode-ast #'js2-mode-function-hider)))
-
-(defun js2-mode-function-hider (n endp)
- (when (not endp)
- (let ((tt (js2-node-type n))
- body beg end)
- (cond
- ((and (= tt js2-FUNCTION)
- (setq body (js2-function-node-body n)))
- (setq beg (js2-node-abs-pos body)
- end (+ beg (js2-node-len body)))
- (js2-mode-flag-region (1+ beg) (1- end) 'hide)
- nil) ; don't process children of function
- (t
- t))))) ; keep processing other AST nodes
-
-(defun js2-mode-show-functions ()
- "Un-hide any folded function bodies in the buffer."
- (interactive)
- (setq js2-mode-functions-hidden nil)
- (save-excursion
- (goto-char (point-min))
- (while (/= (goto-char (next-overlay-change (point)))
- (point-max))
- (dolist (o (overlays-at (point)))
- (when (and (overlay-get o 'invisible)
- (not (overlay-get o 'comment)))
- (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
-
-(defun js2-mode-hide-comment (n)
- (let* ((head (if (eq (js2-comment-node-format n) 'jsdoc)
- 3 ; /**
- 2)) ; /*
- (beg (+ (js2-node-abs-pos n) head))
- (end (- (+ beg (js2-node-len n)) head 2))
- (o (js2-mode-flag-region beg end 'hide)))
- (overlay-put o 'comment t)))
-
-(defun js2-mode-toggle-hide-comments ()
- "Folds all block comments in the buffer.
-Use \\[js2-mode-show-all] to reveal them, or \\[js2-mode-show-element]
-to open an individual entry."
- (interactive)
- (if js2-mode-comments-hidden
- (js2-mode-show-comments)
- (js2-mode-hide-comments)))
-
-(defun js2-mode-hide-comments ()
- (interactive)
- (if js2-mode-buffer-dirty-p
- (js2-mode-wait-for-parse #'js2-mode-hide-comments))
- (if (null js2-mode-ast)
- (message "Oops - parsing failed")
- (setq js2-mode-comments-hidden t)
- (dolist (n (js2-ast-root-comments js2-mode-ast))
- (when (js2-block-comment-p n)
- (js2-mode-hide-comment n)))
- (js2-mode-hide-//-comments)))
-
-(defun js2-mode-extend-//-comment (direction)
- "Find start or end of a block of similar //-comment lines.
-DIRECTION is -1 to look back, 1 to look forward.
-INDENT is the indentation level to match.
-Returns the end-of-line position of the furthest adjacent
-//-comment line with the same indentation as the current line.
-If there is no such matching line, returns current end of line."
- (let ((pos (point-at-eol))
- (indent (current-indentation)))
- (save-excursion
- (while (and (zerop (forward-line direction))
- (looking-at js2-mode-//-comment-re)
- (eq indent (length (match-string 1))))
- (setq pos (point-at-eol)))
- pos)))
-
-(defun js2-mode-hide-//-comments ()
- "Fold adjacent 1-line comments, showing only snippet of first one."
- (let (beg end)
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward js2-mode-//-comment-re nil t)
- (setq beg (point)
- end (js2-mode-extend-//-comment 1))
- (unless (eq beg end)
- (overlay-put (js2-mode-flag-region beg end 'hide)
- 'comment t))
- (goto-char end)
- (forward-char 1)))))
-
-(defun js2-mode-toggle-//-comment ()
- "Fold or un-fold any multi-line //-comment at point.
-Caller should have determined that this line starts with a //-comment."
- (let* ((beg (point-at-eol))
- (end beg))
- (save-excursion
- (goto-char end)
- (if (js2-mode-invisible-overlay-bounds)
- (js2-mode-show-element)
- ;; else hide the comment
- (setq beg (js2-mode-extend-//-comment -1)
- end (js2-mode-extend-//-comment 1))
- (unless (eq beg end)
- (overlay-put (js2-mode-flag-region beg end 'hide)
- 'comment t))))))
-
-(defun js2-mode-show-comments ()
- "Un-hide any hidden comments, leaving other hidden elements alone."
- (interactive)
- (setq js2-mode-comments-hidden nil)
- (save-excursion
- (goto-char (point-min))
- (while (/= (goto-char (next-overlay-change (point)))
- (point-max))
- (dolist (o (overlays-at (point)))
- (when (overlay-get o 'comment)
- (js2-mode-flag-region (overlay-start o) (overlay-end o) nil))))))
-
-(defun js2-mode-display-warnings-and-errors ()
- "Turn on display of warnings and errors."
- (interactive)
- (setq js2-mode-show-parse-errors t
- js2-mode-show-strict-warnings t)
- (js2-reparse 'force))
-
-(defun js2-mode-hide-warnings-and-errors ()
- "Turn off display of warnings and errors."
- (interactive)
- (setq js2-mode-show-parse-errors nil
- js2-mode-show-strict-warnings nil)
- (js2-reparse 'force))
-
-(defun js2-mode-toggle-warnings-and-errors ()
- "Toggle the display of warnings and errors.
-Some users don't like having warnings/errors reported while they type."
- (interactive)
- (setq js2-mode-show-parse-errors (not js2-mode-show-parse-errors)
- js2-mode-show-strict-warnings (not js2-mode-show-strict-warnings))
- (if (called-interactively-p 'any)
- (message "warnings and errors %s"
- (if js2-mode-show-parse-errors
- "enabled"
- "disabled")))
- (js2-reparse 'force))
-
-(defun js2-mode-customize ()
- (interactive)
- (customize-group 'js2-mode))
-
-(defun js2-mode-forward-sexp (&optional arg)
- "Move forward across one statement or balanced expression.
-With ARG, do it that many times. Negative arg -N means
-move backward across N balanced expressions."
- (interactive "p")
- (setq arg (or arg 1))
- (save-restriction
- (widen) ;; `blink-matching-open' calls `narrow-to-region'
- (js2-reparse)
- (let (forward-sexp-function
- node (start (point)) pos lp rp child)
- (cond
- ((js2-string-node-p (js2-node-at-point))
- (forward-sexp arg))
- ;; backward-sexp
- ;; could probably make this better for some cases:
- ;; - if in statement block (e.g. function body), go to parent
- ;; - infix exprs like (foo in bar) - maybe go to beginning
- ;; of infix expr if in the right-side expression?
- ((and arg (cl-minusp arg))
- (dotimes (_ (- arg))
- (js2-backward-sws)
- (forward-char -1) ; Enter the node we backed up to.
- (when (setq node (js2-node-at-point (point) t))
- (setq pos (js2-node-abs-pos node))
- (let ((parens (js2-mode-forward-sexp-parens node pos)))
- (setq lp (car parens)
- rp (cdr parens)))
- (when (and lp (> start lp))
- (if (and rp (<= start rp))
- ;; Between parens, check if there's a child node we can jump.
- (when (setq child (js2-node-closest-child node (point) lp t))
- (setq pos (js2-node-abs-pos child)))
- ;; Before both parens.
- (setq pos lp)))
- (let ((state (parse-partial-sexp start pos)))
- (goto-char (if (not (zerop (car state)))
- ;; Stumble at the unbalanced paren if < 0, or
- ;; jump a bit further if > 0.
- (scan-sexps start -1)
- pos))))
- (unless pos (goto-char (point-min)))))
- (t
- ;; forward-sexp
- (dotimes (_ arg)
- (js2-forward-sws)
- (when (setq node (js2-node-at-point (point) t))
- (setq pos (js2-node-abs-pos node))
- (let ((parens (js2-mode-forward-sexp-parens node pos)))
- (setq lp (car parens)
- rp (cdr parens)))
- (or
- (when (and rp (<= start rp))
- (if (> start lp)
- (when (setq child (js2-node-closest-child node (point) rp))
- (setq pos (js2-node-abs-end child)))
- (setq pos (1+ rp))))
- ;; No parens or child nodes, looks for the end of the current
node.
- (cl-incf pos (js2-node-len
- (if (js2-expr-stmt-node-p (js2-node-parent node))
- ;; Stop after the semicolon.
- (js2-node-parent node)
- node))))
- (let ((state (save-excursion (parse-partial-sexp start pos))))
- (goto-char (if (not (zerop (car state)))
- (scan-sexps start 1)
- pos))))
- (unless pos (goto-char (point-max)))))))))
-
-(defun js2-mode-forward-sexp-parens (node abs-pos)
- "Return a cons cell with positions of main parens in NODE."
- (cond
- ((or (js2-array-node-p node)
- (js2-object-node-p node)
- (js2-comp-node-p node)
- (memq (aref node 0) '(cl-struct-js2-block-node cl-struct-js2-scope)))
- (cons abs-pos (+ abs-pos (js2-node-len node) -1)))
- ((js2-paren-expr-node-p node)
- (let ((lp (js2-node-lp node))
- (rp (js2-node-rp node)))
- (cons (when lp (+ abs-pos lp))
- (when rp (+ abs-pos rp)))))))
-
-(defun js2-node-closest-child (parent point limit &optional before)
- (let* ((parent-pos (js2-node-abs-pos parent))
- (rpoint (- point parent-pos))
- (rlimit (- limit parent-pos))
- (min (min rpoint rlimit))
- (max (max rpoint rlimit))
- found)
- (catch 'done
- (js2-visit-ast
- parent
- (lambda (node _end-p)
- (if (eq node parent)
- t
- (let ((pos (js2-node-pos node)) ;; Both relative values.
- (end (+ (js2-node-pos node) (js2-node-len node))))
- (when (and (>= pos min) (<= end max)
- (if before (< pos rpoint) (> end rpoint)))
- (setq found node))
- (when (> end rpoint)
- (throw 'done nil)))
- nil))))
- found))
-
-(defun js2-errors ()
- "Return a list of errors found."
- (and js2-mode-ast
- (js2-ast-root-errors js2-mode-ast)))
-
-(defun js2-warnings ()
- "Return a list of warnings found."
- (and js2-mode-ast
- (js2-ast-root-warnings js2-mode-ast)))
-
-(defun js2-have-errors-p ()
- "Return non-nil if any parse errors or warnings were found."
- (or (js2-errors) (js2-warnings)))
-
-(defun js2-errors-and-warnings ()
- "Return a copy of the concatenated errors and warnings lists.
-They are appended: first the errors, then the warnings.
-Entries are of the form (MSG BEG END)."
- (when js2-mode-ast
- (append (js2-ast-root-errors js2-mode-ast)
- (copy-sequence (js2-ast-root-warnings js2-mode-ast)))))
-
-(defun js2-next-error (&optional arg reset)
- "Move to next parse error.
-Typically invoked via \\[next-error].
-ARG is the number of errors, forward or backward, to move.
-RESET means start over from the beginning."
- (interactive "p")
- (if (not (or (js2-errors) (js2-warnings)))
- (message "No errors")
- (when reset
- (goto-char (point-min)))
- (let* ((errs (js2-errors-and-warnings))
- (continue t)
- (start (point))
- (count (or arg 1))
- (backward (cl-minusp count))
- (sorter (if backward '> '<))
- (stopper (if backward '< '>))
- (count (abs count))
- all-errs err)
- ;; Sort by start position.
- (setq errs (sort errs (lambda (e1 e2)
- (funcall sorter (cl-second e1) (cl-second e2))))
- all-errs errs)
- ;; Find nth error with pos > start.
- (while (and errs continue)
- (when (funcall stopper (cl-cadar errs) start)
- (setq err (car errs))
- (if (zerop (cl-decf count))
- (setq continue nil)))
- (setq errs (cdr errs)))
- ;; Clear for `js2-echo-error'.
- (message nil)
- (if err
- (goto-char (cl-second err))
- ;; Wrap around to first error.
- (goto-char (cl-second (car all-errs)))
- ;; If we were already on it, echo msg again.
- (if (= (point) start)
- (js2-echo-error (point) (point)))))))
-
-(defun js2-down-mouse-3 ()
- "Make right-click move the point to the click location.
-This makes right-click context menu operations a bit more intuitive.
-The point will not move if the region is active, however, to avoid
-destroying the region selection."
- (interactive)
- (when (and js2-move-point-on-right-click
- (not mark-active))
- (let ((e last-input-event))
- (ignore-errors
- (goto-char (cl-cadadr e))))))
-
-(defun js2-mode-create-imenu-index ()
- "Returns an alist for `imenu--index-alist'. Returns nil on first
-scan if buffer size > `imenu-auto-rescan-maxout'."
- (when (and (not js2-mode-ast)
- (<= (buffer-size) imenu-auto-rescan-maxout))
- (js2-reparse))
- (when js2-mode-ast
- ;; if we have an ast but no recorder, they're requesting a rescan
- (unless js2-imenu-recorder
- (js2-reparse 'force))
- (prog1
- (js2-build-imenu-index)
- (setq js2-imenu-recorder nil
- js2-imenu-function-map nil))))
-
-(defun js2-mode-find-tag ()
- "Replacement for `find-tag-default'.
-`find-tag-default' returns a ridiculous answer inside comments."
- (let (beg end)
- (save-excursion
- (if (looking-at "\\_>")
- (setq beg (progn (forward-symbol -1) (point))
- end (progn (forward-symbol 1) (point)))
- (setq beg (progn (forward-symbol 1) (point))
- end (progn (forward-symbol -1) (point))))
- (replace-regexp-in-string
- "[\"']" ""
- (buffer-substring-no-properties beg end)))))
-
-(defun js2-mode-forward-sibling ()
- "Move to the end of the sibling following point in parent.
-Returns non-nil if successful, or nil if there was no following sibling."
- (let* ((node (js2-node-at-point))
- (parent (js2-mode-find-enclosing-fn node))
- sib)
- (when (setq sib (js2-node-find-child-after (point) parent))
- (goto-char (+ (js2-node-abs-pos sib)
- (js2-node-len sib))))))
-
-(defun js2-mode-backward-sibling ()
- "Move to the beginning of the sibling node preceding point in parent.
-Parent is defined as the enclosing script or function."
- (let* ((node (js2-node-at-point))
- (parent (js2-mode-find-enclosing-fn node))
- sib)
- (when (setq sib (js2-node-find-child-before (point) parent))
- (goto-char (js2-node-abs-pos sib)))))
-
-(defun js2-beginning-of-defun (&optional arg)
- "Go to line on which current function starts, and return t on success.
-If we're not in a function or already at the beginning of one, go
-to beginning of previous script-level element.
-With ARG N, do that N times. If N is negative, move forward."
- (setq arg (or arg 1))
- (if (cl-plusp arg)
- (let ((parent (js2-node-parent-script-or-fn (js2-node-at-point))))
- (when (cond
- ((js2-function-node-p parent)
- (goto-char (js2-node-abs-pos parent)))
- (t
- (js2-mode-backward-sibling)))
- (if (> arg 1)
- (js2-beginning-of-defun (1- arg))
- t)))
- (when (js2-end-of-defun)
- (js2-beginning-of-defun (if (>= arg -1) 1 (1+ arg))))))
-
-(defun js2-end-of-defun ()
- "Go to the char after the last position of the current function
-or script-level element."
- (let* ((node (js2-node-at-point))
- (parent (or (and (js2-function-node-p node) node)
- (js2-node-parent-script-or-fn node)))
- script)
- (unless (js2-function-node-p parent)
- ;; Use current script-level node, or, if none, the next one.
- (setq script (or parent node)
- parent (js2-node-find-child-before (point) script))
- (when (or (null parent)
- (>= (point) (+ (js2-node-abs-pos parent)
- (js2-node-len parent))))
- (setq parent (js2-node-find-child-after (point) script))))
- (when parent
- (goto-char (+ (js2-node-abs-pos parent)
- (js2-node-len parent))))))
-
-(defun js2-mark-defun (&optional allow-extend)
- "Put mark at end of this function, point at beginning.
-The function marked is the one that contains point.
-
-Interactively, if this command is repeated,
-or (in Transient Mark mode) if the mark is active,
-it marks the next defun after the ones already marked."
- (interactive "p")
- (let (extended)
- (when (and allow-extend
- (or (and (eq last-command this-command) (mark t))
- (and transient-mark-mode mark-active)))
- (let ((sib (save-excursion
- (goto-char (mark))
- (if (js2-mode-forward-sibling)
- (point)))))
- (if sib
- (progn
- (set-mark sib)
- (setq extended t))
- ;; no more siblings - try extending to enclosing node
- (goto-char (mark t)))))
- (when (not extended)
- (let ((node (js2-node-at-point (point) t)) ; skip comments
- ast fn stmt parent beg end)
- (when (js2-ast-root-p node)
- (setq ast node
- node (or (js2-node-find-child-after (point) node)
- (js2-node-find-child-before (point) node))))
- ;; only mark whole buffer if we can't find any children
- (if (null node)
- (setq node ast))
- (if (js2-function-node-p node)
- (setq parent node)
- (setq fn (js2-mode-find-enclosing-fn node)
- stmt (if (or (null fn)
- (js2-ast-root-p fn))
- (js2-mode-find-first-stmt node))
- parent (or stmt fn)))
- (setq beg (js2-node-abs-pos parent)
- end (+ beg (js2-node-len parent)))
- (push-mark beg)
- (goto-char end)
- (exchange-point-and-mark)))))
-
-(defun js2-narrow-to-defun ()
- "Narrow to the function enclosing point."
- (interactive)
- (let* ((node (js2-node-at-point (point) t)) ; skip comments
- (fn (if (js2-script-node-p node)
- node
- (js2-mode-find-enclosing-fn node)))
- (beg (js2-node-abs-pos fn)))
- (unless (js2-ast-root-p fn)
- (narrow-to-region beg (+ beg (js2-node-len fn))))))
-
-(defun js2-jump-to-definition (&optional arg)
- "Jump to the definition of an object's property, variable or function."
- (interactive "P")
- (if (eval-when-compile (fboundp 'xref-push-marker-stack))
- (xref-push-marker-stack)
- (ring-insert find-tag-marker-ring (point-marker)))
- (js2-reparse)
- (let* ((node (js2-node-at-point))
- (parent (js2-node-parent node))
- (names (if (js2-prop-get-node-p parent)
- (reverse (let ((temp (js2-compute-nested-prop-get parent)))
- (cl-loop for n in temp
- with result = '()
- do (push n result)
- until (equal node n)
- finally return result)))))
- node-init)
- (unless (and (js2-name-node-p node)
- (not (js2-var-init-node-p parent))
- (not (js2-function-node-p parent)))
- (error "Node is not a supported jump node"))
- (push (or (and names (pop names))
- (unless (and (js2-object-prop-node-p parent)
- (eq node (js2-object-prop-node-left parent))
- (not (js2-node-get-prop parent 'SHORTHAND)))
- node)
- (error "Node is not a supported jump node")) names)
- (setq node-init (js2-search-scope node names))
-
- ;; todo: display list of results in buffer
- ;; todo: group found references by buffer
- (unless node-init
- (switch-to-buffer
- (catch 'found
- (unless arg
- (mapc (lambda (b)
- (with-current-buffer b
- (when (derived-mode-p 'js2-mode)
- (setq node-init (js2-search-scope js2-mode-ast names))
- (if node-init
- (throw 'found b)))))
- (buffer-list)))
- nil)))
- (setq node-init (if (listp node-init) (car node-init) node-init))
- (unless node-init
- (pop-tag-mark)
- (error "No jump location found"))
- (goto-char (js2-node-abs-pos node-init))))
-
-(defun js2-search-object (node name-node)
- "Check if object NODE contains element with NAME-NODE."
- (cl-assert (js2-object-node-p node))
- ;; Only support name-node and nodes for the time being
- (cl-loop for elem in (js2-object-node-elems node)
- for left = (js2-object-prop-node-left elem)
- if (or (and (js2-name-node-p left)
- (equal (js2-name-node-name name-node)
- (js2-name-node-name left)))
- (and (js2-string-node-p left)
- (string= (js2-name-node-name name-node)
- (js2-string-node-value left))))
- return elem))
-
-(defun js2-search-object-for-prop (object prop-names)
- "Return node in OBJECT that matches PROP-NAMES or nil.
-PROP-NAMES is a list of values representing a path to a value in OBJECT.
-i.e. (\\='name\\=' \\='value\\=') = {name : { value: 3}}"
- (let (node
- (temp-object object)
- (temp t) ;temporay node
- (names prop-names))
- (while (and temp names (js2-object-node-p temp-object))
- (setq temp (js2-search-object temp-object (pop names)))
- (and (setq node temp)
- (setq temp-object (js2-object-prop-node-right temp))))
- (unless names node)))
-
-(defun js2-search-scope (node names)
- "Searches NODE scope for jump location matching NAMES.
-NAMES is a list of property values to search for. For functions
-and variables NAMES will contain one element."
- (let (node-init
- (val (js2-name-node-name (car names))))
- (setq node-init (js2-get-symbol-declaration node val))
-
- (when (> (length names) 1)
-
- ;; Check var declarations
- (when (and node-init (string= val (js2-name-node-name node-init)))
- (let ((parent (js2-node-parent node-init))
- (temp-names names))
- (pop temp-names) ;; First element is var name
- (setq node-init (when (js2-var-init-node-p parent)
- (js2-search-object-for-prop
- (js2-var-init-node-initializer parent)
- temp-names)))))
-
- ;; Check all assign nodes
- (js2-visit-ast
- js2-mode-ast
- (lambda (node endp)
- (unless endp
- (if (js2-assign-node-p node)
- (let ((left (js2-assign-node-left node))
- (right (js2-assign-node-right node))
- (temp-names names))
- (when (js2-prop-get-node-p left)
- (let* ((prop-list (js2-compute-nested-prop-get left))
- (found (cl-loop for prop in prop-list
- until (not (string=
(js2-name-node-name
- (pop
temp-names))
-
(js2-name-node-name prop)))
- if (not temp-names) return prop))
- (found-node (or found
- (when (js2-object-node-p right)
- (js2-search-object-for-prop right
-
temp-names)))))
- (if found-node (push found-node node-init))))))
- t))))
- node-init))
-
-(defun js2-get-symbol-declaration (node name)
- "Find scope for NAME from NODE."
- (let ((scope (js2-get-defining-scope
- (or (js2-node-get-enclosing-scope node)
- node) name)))
- (if scope (js2-symbol-ast-node (js2-scope-get-symbol scope name)))))
-
-(provide 'js2-mode)
-
-;;; js2-mode.el ends here
diff --git a/packages/js2-mode/js2-old-indent.el
b/packages/js2-mode/js2-old-indent.el
deleted file mode 100644
index 8711d7d..0000000
--- a/packages/js2-mode/js2-old-indent.el
+++ /dev/null
@@ -1,712 +0,0 @@
-;;; js2-old-indent.el --- Indentation code kept for compatibility
-
-;; Copyright (C) 2015 Free Software Foundation, Inc.
-
-;; 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:
-
-;; All features of this indentation code have been ported to Emacs's
-;; built-in `js-mode' by now, so we derive from it. An older
-;; commentary follows.
-
-;; This code is kept for Emacs 24.5 and ealier.
-
-;; This indenter is based on Karl Landström's "javascript.el" indenter.
-;; Karl cleverly deduces that the desired indentation level is often a
-;; function of paren/bracket/brace nesting depth, which can be determined
-;; quickly via the built-in `parse-partial-sexp' function. His indenter
-;; then does some equally clever checks to see if we're in the context of a
-;; substatement of a possibly braceless statement keyword such as if, while,
-;; or finally. This approach yields pretty good results.
-
-;; The indenter is often "wrong", however, and needs to be overridden.
-;; The right long-term solution is probably to emulate (or integrate
-;; with) cc-engine, but it's a nontrivial amount of coding. Even when a
-;; parse tree from `js2-parse' is present, which is not true at the
-;; moment the user is typing, computing indentation is still thousands
-;; of lines of code to handle every possible syntactic edge case.
-
-;; In the meantime, the compromise solution is that we offer a "bounce
-;; indenter", configured with `js2-bounce-indent-p', which cycles the
-;; current line indent among various likely guess points. This approach
-;; is far from perfect, but should at least make it slightly easier to
-;; move the line towards its desired indentation when manually
-;; overriding Karl's heuristic nesting guesser.
-
-;; I've made miscellaneous tweaks to Karl's code to handle some Ecma
-;; extensions such as `let' and Array comprehensions. Major kudos to
-;; Karl for coming up with the initial approach, which packs a lot of
-;; punch for so little code. -- Steve
-
-;;; Code:
-
-(require 'sgml-mode)
-
-(defvar js2-language-version)
-
-(declare-function js2-backward-sws "js2-mode")
-(declare-function js2-forward-sws "js2-mode")
-(declare-function js2-same-line "js2-mode")
-
-(defcustom js2-basic-offset (if (and (boundp 'c-basic-offset)
- (numberp c-basic-offset))
- c-basic-offset
- 4)
- "Number of spaces to indent nested statements.
-Similar to `c-basic-offset'."
- :group 'js2-mode
- :safe 'integerp
- :type 'integer)
-
-(defcustom js2-pretty-multiline-declarations t
- "Non-nil to line up multiline declarations vertically:
-
- var a = 10,
- b = 20,
- c = 30;
-
-If the value is t, and the first assigned value in the
-declaration is a function/array/object literal spanning several
-lines, it won't be indented additionally:
-
- var o = { var bar = 2,
- foo: 3 vs. o = {
- }, foo: 3
- bar = 2; };
-
-If the value is `all', it will always be indented additionally:
-
- var o = {
- foo: 3
- };
-
- var o = {
- foo: 3
- },
- bar = 2;
-
-If the value is `dynamic', it will be indented additionally only
-if the declaration contains more than one variable:
-
- var o = {
- foo: 3
- };
-
- var o = {
- foo: 3
- },
- bar = 2;"
- :group 'js2-mode
- :safe 'symbolp
- :type 'symbol)
-
-(defcustom js2-indent-switch-body nil
- "When nil, case labels are indented on the same level as the
-containing switch statement. Otherwise, all lines inside
-switch statement body are indented one additional level."
- :type 'boolean
- :safe 'booleanp
- :group 'js2-mode)
-
-(defconst js2-possibly-braceless-keywords-re
- (concat "else[ \t]+if\\|for[ \t]+each\\|"
- (regexp-opt '("catch" "do" "else" "finally" "for" "if"
- "try" "while" "with" "let")))
- "Regular expression matching keywords that are optionally
-followed by an opening brace.")
-
-(defconst js2-indent-operator-re
- (concat "[-+*/%<>&^|?:.]\\([^-+*/.]\\|$\\)\\|!?=\\|"
- (regexp-opt '("in" "instanceof") 'symbols))
- "Regular expression matching operators that affect indentation
-of continued expressions.")
-
-(defconst js2-declaration-keyword-re
- (regexp-opt '("var" "let" "const") 'symbols)
- "Regular expression matching variable declaration keywords.")
-
-(defun js2-re-search-forward-inner (regexp &optional bound count)
- "Auxiliary function for `js2-re-search-forward'."
- (let (parse saved-point)
- (while (> count 0)
- (re-search-forward regexp bound)
- (setq parse (if saved-point
- (parse-partial-sexp saved-point (point))
- (syntax-ppss (point))))
- (cond ((nth 3 parse)
- (re-search-forward
- (concat "\\(\\=\\|[^\\]\\|^\\)" (string (nth 3 parse)))
- (save-excursion (end-of-line) (point)) t))
- ((nth 7 parse)
- (forward-line))
- ((or (nth 4 parse)
- (and (eq (char-before) ?\/) (eq (char-after) ?\*)))
- (re-search-forward "\\*/"))
- (t
- (setq count (1- count))))
- (setq saved-point (point))))
- (point))
-
-(defun js2-re-search-forward (regexp &optional bound noerror count)
- "Search forward but ignore strings and comments.
-Invokes `re-search-forward' but treats the buffer as if strings
-and comments have been removed."
- (let ((saved-point (point)))
- (condition-case err
- (cond ((null count)
- (js2-re-search-forward-inner regexp bound 1))
- ((< count 0)
- (js2-re-search-backward-inner regexp bound (- count)))
- ((> count 0)
- (js2-re-search-forward-inner regexp bound count)))
- (search-failed
- (goto-char saved-point)
- (unless noerror
- (error (error-message-string err)))))))
-
-(defun js2-re-search-backward-inner (regexp &optional bound count)
- "Auxiliary function for `js2-re-search-backward'."
- (let (parse)
- (while (> count 0)
- (re-search-backward regexp bound)
- (setq parse (syntax-ppss (point)))
- (cond ((nth 3 parse)
- (re-search-backward
- (concat "\\([^\\]\\|^\\)" (string (nth 3 parse)))
- (line-beginning-position) t))
- ((nth 7 parse)
- (goto-char (nth 8 parse)))
- ((or (nth 4 parse)
- (and (eq (char-before) ?/) (eq (char-after) ?*)))
- (re-search-backward "/\\*"))
- (t
- (setq count (1- count))))))
- (point))
-
-(defun js2-re-search-backward (regexp &optional bound noerror count)
- "Search backward but ignore strings and comments.
-Invokes `re-search-backward' but treats the buffer as if strings
-and comments have been removed."
- (let ((saved-point (point)))
- (condition-case err
- (cond ((null count)
- (js2-re-search-backward-inner regexp bound 1))
- ((< count 0)
- (js2-re-search-forward-inner regexp bound (- count)))
- ((> count 0)
- (js2-re-search-backward-inner regexp bound count)))
- (search-failed
- (goto-char saved-point)
- (unless noerror
- (error (error-message-string err)))))))
-
-(defun js2-looking-at-operator-p ()
- "Return non-nil if text after point is a non-comma operator."
- (defvar js2-mode-identifier-re)
- (and (looking-at js2-indent-operator-re)
- (or (not (eq (char-after) ?:))
- (save-excursion
- (and (js2-re-search-backward "[?:{]\\|\\_<case\\_>" nil t)
- (eq (char-after) ??))))
- (not (and
- (eq (char-after) ?/)
- (save-excursion
- (eq (nth 3 (syntax-ppss)) ?/))))
- (not (and
- (eq (char-after) ?*)
- ;; Generator method (possibly using computed property).
- (looking-at (concat "\\* *\\(?:\\[\\|"
- js2-mode-identifier-re
- " *(\\)"))
- (save-excursion
- (js2-backward-sws)
- ;; We might misindent some expressions that would
- ;; return NaN anyway. Shouldn't be a problem.
- (memq (char-before) '(?, ?} ?{)))))))
-
-(defun js2-continued-expression-p ()
- "Return non-nil if the current line continues an expression."
- (save-excursion
- (back-to-indentation)
- (if (js2-looking-at-operator-p)
- (or (not (memq (char-after) '(?- ?+)))
- (progn
- (forward-comment (- (point)))
- (not (memq (char-before) '(?, ?\[ ?\()))))
- (forward-comment (- (point)))
- (or (bobp) (backward-char))
- (when (js2-looking-at-operator-p)
- (backward-char)
- (not (looking-at "\\*\\|\\+\\+\\|--\\|/[/*]"))))))
-
-(defun js2-end-of-do-while-loop-p ()
- "Return non-nil if word after point is `while' of a do-while
-statement, else returns nil. A braceless do-while statement
-spanning several lines requires that the start of the loop is
-indented to the same column as the current line."
- (interactive)
- (save-excursion
- (when (looking-at "\\s-*\\_<while\\_>")
- (if (save-excursion
- (skip-chars-backward "[ \t\n]*}")
- (looking-at "[ \t\n]*}"))
- (save-excursion
- (backward-list) (backward-word 1) (looking-at "\\_<do\\_>"))
- (js2-re-search-backward "\\_<do\\_>" (point-at-bol) t)
- (or (looking-at "\\_<do\\_>")
- (let ((saved-indent (current-indentation)))
- (while (and (js2-re-search-backward "^[ \t]*\\_<" nil t)
- (/= (current-indentation) saved-indent)))
- (and (looking-at "[ \t]*\\_<do\\_>")
- (not (js2-re-search-forward
- "\\_<while\\_>" (point-at-eol) t))
- (= (current-indentation) saved-indent))))))))
-
-(defun js2-multiline-decl-indentation ()
- "Return the declaration indentation column if the current line belongs
-to a multiline declaration statement. See
`js2-pretty-multiline-declarations'."
- (let (forward-sexp-function ; use Lisp version
- at-opening-bracket)
- (save-excursion
- (back-to-indentation)
- (when (not (looking-at js2-declaration-keyword-re))
- (when (looking-at js2-indent-operator-re)
- (goto-char (match-end 0))) ; continued expressions are ok
- (while (and (not at-opening-bracket)
- (not (bobp))
- (let ((pos (point)))
- (save-excursion
- (js2-backward-sws)
- (or (eq (char-before) ?,)
- (and (not (eq (char-before) ?\;))
- (prog2 (skip-syntax-backward ".")
- (looking-at js2-indent-operator-re)
- (js2-backward-sws))
- (not (eq (char-before) ?\;)))
- (js2-same-line pos)))))
- (condition-case _
- (backward-sexp)
- (scan-error (setq at-opening-bracket t))))
- (when (looking-at js2-declaration-keyword-re)
- (goto-char (match-end 0))
- (1+ (current-column)))))))
-
-(defun js2-ctrl-statement-indentation ()
- "Return the proper indentation of current line if it is a control statement.
-Returns an indentation if this line starts the body of a control
-statement without braces, else returns nil."
- (let (forward-sexp-function)
- (save-excursion
- (back-to-indentation)
- (when (and (not (js2-same-line (point-min)))
- (not (looking-at "{"))
- (js2-re-search-backward "[[:graph:]]" nil t)
- (not (looking-at "[{([]"))
- (progn
- (forward-char)
- (when (= (char-before) ?\))
- ;; scan-sexps sometimes throws an error
- (ignore-errors (backward-sexp))
- (skip-chars-backward " \t" (point-at-bol)))
- (let ((pt (point)))
- (back-to-indentation)
- (when (looking-at "}[ \t]*")
- (goto-char (match-end 0)))
- (and (looking-at js2-possibly-braceless-keywords-re)
- (= (match-end 0) pt)
- (not (js2-end-of-do-while-loop-p))))))
- (+ (current-indentation) js2-basic-offset)))))
-
-(defun js2-indent-in-array-comp (parse-status)
- "Return non-nil if we think we're in an array comprehension.
-In particular, return the buffer position of the first `for' kwd."
- (let ((bracket (nth 1 parse-status))
- (end (point)))
- (when bracket
- (save-excursion
- (goto-char bracket)
- (when (looking-at "\\[")
- (forward-char 1)
- (js2-forward-sws)
- (if (looking-at "[[{]")
- (let (forward-sexp-function) ; use Lisp version
- (forward-sexp) ; skip destructuring form
- (js2-forward-sws)
- (if (and (/= (char-after) ?,) ; regular array
- (looking-at "for"))
- (match-beginning 0)))
- ;; to skip arbitrary expressions we need the parser,
- ;; so we'll just guess at it.
- (if (and (> end (point)) ; not empty literal
- (re-search-forward "[^,]]* \\(for\\) " end t)
- ;; not inside comment or string literal
- (let ((state (parse-partial-sexp bracket (point))))
- (and (= 1 (car state))
- (not (nth 8 state)))))
- (match-beginning 1))))))))
-
-(defun js2-array-comp-indentation (parse-status for-kwd)
- (if (js2-same-line for-kwd)
- ;; first continuation line
- (save-excursion
- (goto-char (nth 1 parse-status))
- (forward-char 1)
- (skip-chars-forward " \t")
- (current-column))
- (save-excursion
- (goto-char for-kwd)
- (current-column))))
-
-(defun js2-maybe-goto-declaration-keyword-end (bracket)
- "Helper function for `js2-proper-indentation'.
-Depending on the value of `js2-pretty-multiline-declarations',
-move point to the end of a variable declaration keyword so that
-indentation is aligned to that column."
- (cond
- ((eq js2-pretty-multiline-declarations 'all)
- (when (looking-at js2-declaration-keyword-re)
- (goto-char (1+ (match-end 0)))))
- ((eq js2-pretty-multiline-declarations 'dynamic)
- (let (declaration-keyword-end
- at-closing-bracket-p
- comma-p)
- (when (looking-at js2-declaration-keyword-re)
- ;; Preserve the match data lest it somehow be overridden.
- (setq declaration-keyword-end (match-end 0))
- (save-excursion
- (goto-char bracket)
- (setq at-closing-bracket-p
- ;; Handle scan errors gracefully.
- (condition-case nil
- (progn
- ;; Use the regular `forward-sexp-function' because the
- ;; normal one for this mode uses the AST.
- (let (forward-sexp-function)
- (forward-sexp))
- t)
- (error nil)))
- (when at-closing-bracket-p
- (js2-forward-sws)
- (setq comma-p (looking-at-p ","))))
- (when comma-p
- (goto-char (1+ declaration-keyword-end))))))))
-
-(cl-defun js2-proper-indentation (parse-status)
- "Return the proper indentation for the current line."
- (save-excursion
- (back-to-indentation)
- (when (nth 4 parse-status)
- (cl-return-from js2-proper-indentation (js2--comment-indent
parse-status)))
- (let* ((at-closing-bracket (looking-at "[]})]"))
- (same-indent-p (or at-closing-bracket
- (looking-at "\\_<case\\_>[^:]")
- (and (looking-at "\\_<default:")
- (save-excursion
- (js2-backward-sws)
- (not (memq (char-before) '(?, ?{)))))))
- (continued-expr-p (js2-continued-expression-p))
- (declaration-indent (and js2-pretty-multiline-declarations
- (js2-multiline-decl-indentation)))
- (bracket (nth 1 parse-status))
- beg indent)
- (cond
- ;; indent array comprehension continuation lines specially
- ((and bracket
- (>= js2-language-version 170)
- (not (js2-same-line bracket))
- (setq beg (js2-indent-in-array-comp parse-status))
- (>= (point) (save-excursion
- (goto-char beg)
- (point-at-bol)))) ; at or after first loop?
- (js2-array-comp-indentation parse-status beg))
-
- ((js2-ctrl-statement-indentation))
-
- ((and declaration-indent continued-expr-p)
- (+ declaration-indent js2-basic-offset))
-
- (declaration-indent)
-
- (bracket
- (goto-char bracket)
- (cond
- ((looking-at "[({[][ \t]*\\(/[/*]\\|$\\)")
- (when (save-excursion (skip-chars-backward " \t\n)")
- (looking-at ")"))
- (backward-list))
- (back-to-indentation)
- (js2-maybe-goto-declaration-keyword-end bracket)
- (setq indent
- (cond (same-indent-p
- (current-column))
- (continued-expr-p
- (+ (current-column) (* 2 js2-basic-offset)))
- (t
- (+ (current-column) js2-basic-offset))))
- (if (and js2-indent-switch-body
- (not at-closing-bracket)
- (looking-at "\\_<switch\\_>"))
- (+ indent js2-basic-offset)
- indent))
- (t
- (unless same-indent-p
- (forward-char)
- (skip-chars-forward " \t"))
- (current-column))))
-
- (continued-expr-p js2-basic-offset)
-
- (t 0)))))
-
-(defun js2--comment-indent (parse-status)
- "Indentation inside a multi-line block comment continuation line."
- (save-excursion
- (goto-char (nth 8 parse-status))
- (if (looking-at "/\\*")
- (+ 1 (current-column))
- 0)))
-
-(defun js2-indent-line (&optional bounce-backwards)
- "Indent the current line as JavaScript source text."
- (interactive)
- (let (parse-status offset
- ;; Don't whine about errors/warnings when we're indenting.
- ;; This has to be set before calling parse-partial-sexp below.
- (inhibit-point-motion-hooks t))
- (setq parse-status (save-excursion
- (syntax-ppss (point-at-bol)))
- offset (- (point) (save-excursion
- (back-to-indentation)
- (point))))
- ;; Don't touch multiline strings.
- (unless (nth 3 parse-status)
- (indent-line-to (js2-proper-indentation parse-status))
- (when (cl-plusp offset)
- (forward-char offset)))))
-
-;;; JSX Indentation
-
-;; The following JSX indentation code is copied basically verbatim from js.el
at
-;; 958da7f, except that the prefixes on the functions/variables are changed.
-
-(defsubst js2--jsx-find-before-tag ()
- "Find where JSX starts.
-
-Assume JSX appears in the following instances:
-- Inside parentheses, when returned or as the first argument
- to a function, and after a newline
-- When assigned to variables or object properties, but only
- on a single line
-- As the N+1th argument to a function
-
-This is an optimized version of (re-search-backward \"[(,]\n\"
-nil t), except set point to the end of the match. This logic
-executes up to the number of lines in the file, so it should be
-really fast to reduce that impact."
- (let (pos)
- (while (and (> (point) (point-min))
- (not (progn
- (end-of-line 0)
- (when (or (eq (char-before) 40) ; (
- (eq (char-before) 44)) ; ,
- (setq pos (1- (point))))))))
- pos))
-
-(defconst js2--jsx-end-tag-re
- (concat "</" sgml-name-re ">\\|/>")
- "Find the end of a JSX element.")
-
-(defconst js2--jsx-after-tag-re "[),]"
- "Find where JSX ends.
-This complements the assumption of where JSX appears from
-`js--jsx-before-tag-re', which see.")
-
-(defun js2--jsx-indented-element-p ()
- "Determine if/how the current line should be indented as JSX.
-
-Return `first' for the first JSXElement on its own line.
-Return `nth' for subsequent lines of the first JSXElement.
-Return `expression' for an embedded JS expression.
-Return `after' for anything after the last JSXElement.
-Return nil for non-JSX lines.
-
-Currently, JSX indentation supports the following styles:
-
-- Single-line elements (indented like normal JS):
-
- var element = <div></div>;
-
-- Multi-line elements (enclosed in parentheses):
-
- function () {
- return (
- <div>
- <div></div>
- </div>
- );
- }
-
-- Function arguments:
-
- React.render(
- <div></div>,
- document.querySelector(\\='.root\\=')
- );"
- (let ((current-pos (point))
- (current-line (line-number-at-pos))
- last-pos
- before-tag-pos before-tag-line
- tag-start-pos tag-start-line
- tag-end-pos tag-end-line
- after-tag-line
- parens paren type)
- (save-excursion
- (and
- ;; Determine if we're inside a jsx element
- (progn
- (end-of-line)
- (while (and (not tag-start-pos)
- (setq last-pos (js2--jsx-find-before-tag)))
- (while (forward-comment 1))
- (when (= (char-after) 60) ; <
- (setq before-tag-pos last-pos
- tag-start-pos (point)))
- (goto-char last-pos))
- tag-start-pos)
- (progn
- (setq before-tag-line (line-number-at-pos before-tag-pos)
- tag-start-line (line-number-at-pos tag-start-pos))
- (and
- ;; A "before" line which also starts an element begins with js, so
- ;; indent it like js
- (> current-line before-tag-line)
- ;; Only indent the jsx lines like jsx
- (>= current-line tag-start-line)))
- (cond
- ;; Analyze bounds if there are any
- ((progn
- (while (and (not tag-end-pos)
- (setq last-pos (re-search-forward js2--jsx-end-tag-re
nil t)))
- (while (forward-comment 1))
- (when (looking-at js2--jsx-after-tag-re)
- (setq tag-end-pos last-pos)))
- tag-end-pos)
- (setq tag-end-line (line-number-at-pos tag-end-pos)
- after-tag-line (line-number-at-pos after-tag-line))
- (or (and
- ;; Ensure we're actually within the bounds of the jsx
- (<= current-line tag-end-line)
- ;; An "after" line which does not end an element begins with
- ;; js, so indent it like js
- (<= current-line after-tag-line))
- (and
- ;; Handle another case where there could be e.g. comments after
- ;; the element
- (> current-line tag-end-line)
- (< current-line after-tag-line)
- (setq type 'after))))
- ;; They may not be any bounds (yet)
- (t))
- ;; Check if we're inside an embedded multi-line js expression
- (cond
- ((not type)
- (goto-char current-pos)
- (end-of-line)
- (setq parens (nth 9 (syntax-ppss)))
- (while (and parens (not type))
- (setq paren (car parens))
- (cond
- ((and (>= paren tag-start-pos)
- ;; Curly bracket indicates the start of an embedded
expression
- (= (char-after paren) 123) ; {
- ;; The first line of the expression is indented like sgml
- (> current-line (line-number-at-pos paren))
- ;; Check if within a closing curly bracket (if any)
- ;; (exclusive, as the closing bracket is indented like sgml)
- (cond
- ((progn
- (goto-char paren)
- (ignore-errors (let (forward-sexp-function)
- (forward-sexp))))
- (< current-line (line-number-at-pos)))
- (t)))
- ;; Indicate this guy will be indented specially
- (setq type 'expression))
- (t (setq parens (cdr parens)))))
- t)
- (t))
- (cond
- (type)
- ;; Indent the first jsx thing like js so we can indent future jsx
things
- ;; like sgml relative to the first thing
- ((= current-line tag-start-line) 'first)
- ('nth))))))
-
-(defmacro js2--as-sgml (&rest body)
- "Execute BODY as if in sgml-mode."
- `(with-syntax-table sgml-mode-syntax-table
- (let (forward-sexp-function
- parse-sexp-lookup-properties)
- ,@body)))
-
-(defun js2--expression-in-sgml-indent-line ()
- "Indent the current line as JavaScript or SGML (whichever is farther)."
- (let* (indent-col
- (savep (point))
- ;; Don't whine about errors/warnings when we're indenting.
- ;; This has to be set before calling parse-partial-sexp below.
- (inhibit-point-motion-hooks t)
- (parse-status (save-excursion
- (syntax-ppss (point-at-bol)))))
- ;; Don't touch multiline strings.
- (unless (nth 3 parse-status)
- (setq indent-col (save-excursion
- (back-to-indentation)
- (if (>= (point) savep) (setq savep nil))
- (js2--as-sgml (sgml-calculate-indent))))
- (if (null indent-col)
- 'noindent
- ;; Use whichever indentation column is greater, such that the sgml
- ;; column is effectively a minimum
- (setq indent-col (max (js2-proper-indentation parse-status)
- (+ indent-col js2-basic-offset)))
- (if savep
- (save-excursion (indent-line-to indent-col))
- (indent-line-to indent-col))))))
-
-(defun js2-jsx-indent-line ()
- "Indent the current line as JSX (with SGML offsets).
-i.e., customize JSX element indentation with `sgml-basic-offset'
-et al."
- (interactive)
- (let ((indentation-type (js2--jsx-indented-element-p)))
- (cond
- ((eq indentation-type 'expression)
- (js2--expression-in-sgml-indent-line))
- ((or (eq indentation-type 'first)
- (eq indentation-type 'after))
- ;; Don't treat this first thing as a continued expression (often a "<" or
- ;; ">" causes this misinterpretation)
- (cl-letf (((symbol-function #'js2-continued-expression-p) 'ignore))
- (js2-indent-line)))
- ((eq indentation-type 'nth)
- (js2--as-sgml (sgml-indent-line)))
- (t (js2-indent-line)))))
-
-(provide 'js2-old-indent)
-
-;;; js2-old-indent.el ends here
diff --git a/packages/js2-mode/tests/consume.el
b/packages/js2-mode/tests/consume.el
deleted file mode 100644
index 8e6ca17..0000000
--- a/packages/js2-mode/tests/consume.el
+++ /dev/null
@@ -1,84 +0,0 @@
-;;; tests/consume.el --- Some tests for js2-mode.
-
-;; Copyright (C) 2016 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'ert-x)
-(require 'js2-mode)
-
-(defun js2-mode--and-parse ()
- (js2-mode)
- (js2-reparse))
-
-;;; Comments
-
-(ert-deftest js2-comments-between ()
- (with-temp-buffer
- (insert "0\n//\n[0,/* */1]")
- (js2-mode--and-parse)
- (let ((comments-list (js2-ast-root-comments js2-mode-ast))
- comments)
- (setq comments (js2-comments-between 1 2 comments-list))
- (should (null comments))
- ;; comment head between region
- (setq comments (js2-comments-between 1 3 comments-list))
- (should (= (length comments) 1))
- ;; comment body between region
- (setq comments (js2-comments-between 4 5 comments-list))
- (should (= (length comments) 1))
- ;; comment tail between region
- (setq comments (js2-comments-between 5 6 comments-list))
- (should (= (length comments) 1))
- (setq comments (js2-comments-between 6 6 comments-list))
- (should (null comments))
- (setq comments (js2-comments-between 10 12 comments-list))
- (should (= (length comments) 1))
- ;; multiple comments between
- (setq comments (js2-comments-between 5 15 comments-list))
- (should (= (length comments) 2))
- ;; pass comments-list when no AST available
- (setq js2-mode-ast nil)
- (setq comments (js2-comments-between 8 9 comments))
- (should (= (length comments) 1))
- )))
-
-;;; Visitors
-
-(ert-deftest js2-visit-import-clause-in-order ()
- (with-temp-buffer
- (insert "import defaultImport, { a, b, c} from 'xyz';")
- (js2-mode--and-parse)
- (let (visit-log)
- (js2-visit-ast js2-mode-ast (lambda (node end-p)
- (when (and (not end-p) (js2-name-node-p
node))
- (let* ((start (js2-node-abs-pos node))
- (end (+ start (js2-node-len
node))))
- (push (buffer-substring-no-properties
start end) visit-log)))
- t))
- (setq visit-log (nreverse visit-log))
- (should (equal visit-log (list "defaultImport" "a" "b" "c"))))))
-
-(ert-deftest js2-node-parent-stmt/arrow-function ()
- (ert-with-test-buffer (:name 'js2-node-parent-stmt/arrow-function)
- (insert "expect(() => ")
- (save-excursion (insert "func(undefined)).toThrow(/undefined/);"))
- (js2-mode--and-parse)
- (let ((parent-stmt (js2-node-parent-stmt (js2-node-at-point))))
- (should (= (js2-node-abs-pos parent-stmt) 1)))))
diff --git a/packages/js2-mode/tests/externs.el
b/packages/js2-mode/tests/externs.el
deleted file mode 100644
index f383e89..0000000
--- a/packages/js2-mode/tests/externs.el
+++ /dev/null
@@ -1,126 +0,0 @@
-;;; tests/externs.el --- Some tests for js2-mode.
-
-;; Copyright (C) 2009, 2011-2014, 2016 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'js2-mode)
-
-(ert-deftest js2-finds-jslint-globals ()
- (with-temp-buffer
- (insert "/*global foo, bar:false, baz: true */")
- (js2-mode)
- (should (equal (js2-get-jslint-globals)
- '("foo" "bar" "baz")))))
-
-(ert-deftest js2-no-jslint-globals-without-keyword ()
- (with-temp-buffer
- (insert "/* foo, bar:false, baz: true */")
- (js2-mode)
- (should (null (js2-get-jslint-globals)))))
-
-(ert-deftest js2-finds-jslint-globals-in-other-comments ()
- (with-temp-buffer
- (insert "/* foo, bar */\n\n\n/*global quux, tee: true, $*/")
- (js2-mode)
- (should (equal (js2-get-jslint-globals)
- '("quux" "tee" "$")))))
-
-(ert-deftest js2-finds-jslint-globals-with-space ()
- (with-temp-buffer
- (insert "/* global foo, bar:false, baz:true")
- (js2-mode)
- (should (equal (js2-get-jslint-globals)
- '("foo" "bar" "baz")))))
-
-(ert-deftest js2-finds-jslint-globals-with-newline ()
- (with-temp-buffer
- (insert "/* global\nfoo, bar")
- (js2-mode)
- (should (equal (js2-get-jslint-globals)
- '("foo" "bar")))))
-
-;;;TODO
-;; ensure that any symbols bound with the import syntax are added to the
extern list
-;; ensure that any symbols bound with the export syntax exist in the file scope
-
-;; Test `/*jslint*/` declarations
-
-(ert-deftest js2-finds-jslint-declaration-externs ()
- (with-temp-buffer
- (insert "/*jslint browser: true, node: true*/")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "navigator" found-externs)
- (member "__filename" found-externs))))))
-
-(ert-deftest js2-finds-jslint-declaration-externs-without-property-value ()
- (with-temp-buffer
- (insert "/*jslint devel, es6: true, couch")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "prompt" found-externs)
- (member "Promise" found-externs)
- (member "require" found-externs))))))
-
-(ert-deftest js2-no-jslint-declaration-externs-without-keyword ()
- (with-temp-buffer
- (insert "/* browser: true, node: true*/")
- (js2-mode)
- (should (null (js2-get-jslint-declaration-externs)))))
-
-(ert-deftest js2-no-jslint-declaration-externs-for-nonexistent-env ()
- (with-temp-buffer
- (insert "/*jslint nonexistent: true*/")
- (js2-mode)
- (should (null (js2-get-jslint-declaration-externs)))))
-
-(ert-deftest js2-finding-jslint-declaration-externs-ignores-nonexistent ()
- (with-temp-buffer
- (insert "/*jslint es6: true, nonexistent: true, couch: true*/")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "Map" found-externs)
- (member "emit" found-externs))))))
-
-(ert-deftest js2-finds-jslint-declaration-externs-in-other-comments ()
- (with-temp-buffer
- (insert "/* foo, bar */\n\n\n/*jslint devel: true, node: true*/")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "Debug" found-externs)
- (member "exports" found-externs))))))
-
-(ert-deftest js2-finds-jslint-declaration-externs-with-space ()
- (with-temp-buffer
- (insert "/* jslint browser: true, couch:true,es6 :true */")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "document" found-externs)
- (member "getRow" found-externs)
- (member "Proxy" found-externs))))))
-
-(ert-deftest js2-finds-jslint-globals-with-newline ()
- (with-temp-buffer
- (insert "/*jslint\nbrowser: true,\nnode:\ntrue\n, devel:\ntrue\n*/")
- (js2-mode)
- (let ((found-externs (js2-get-jslint-declaration-externs)))
- (should (and (member "history" found-externs)
- (member "Buffer" found-externs)
- (member "alert" found-externs))))))
diff --git a/packages/js2-mode/tests/indent.el
b/packages/js2-mode/tests/indent.el
deleted file mode 100644
index 0924691..0000000
--- a/packages/js2-mode/tests/indent.el
+++ /dev/null
@@ -1,291 +0,0 @@
-;;; tests/indent.el --- Some tests for js2-mode.
-
-;; Copyright (C) 2009, 2011-2016 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'js2-mode)
-(require 'cl-lib)
-(require 'js2-old-indent)
-
-(defun js2-test-indent (content keep-indent)
- (let ((s (replace-regexp-in-string "^ *|" "" content)))
- (with-temp-buffer
- (insert
- (if keep-indent
- s
- (replace-regexp-in-string "^ *" "" s)))
- (js2-jsx-mode)
- (js2-reparse) ; solely for js2-jsx-self-closing, for some reason
- (indent-region (point-min) (point-max))
- (should (string= s (buffer-substring-no-properties
- (point-min) (point)))))))
-
-(cl-defmacro js2-deftest-indent (name content &key bind keep-indent)
- `(ert-deftest ,(intern (format "js2-%s" name)) ()
- (let ,(append '(indent-tabs-mode
- (js2-basic-offset 2)
- (js2-pretty-multiline-declarations t)
- (inhibit-point-motion-hooks t))
- bind)
- (js2-test-indent ,content ,keep-indent))))
-
-(put 'js2-deftest-indent 'lisp-indent-function 'defun)
-
-(js2-deftest-indent no-multiline-decl-indent-after-semicolon
- "var foo = 1;
- |bar = 2")
-
-(js2-deftest-indent multiline-decl-indent-after-comma
- "let foo = 1,
- | bar = 2")
-
-(js2-deftest-indent no-multiline-decl-when-disabled
- "let foo = 1,
- |bar = 2"
- :bind ((js2-pretty-multiline-declarations nil)))
-
-(js2-deftest-indent multiline-decl-with-continued-expr
- "var foo = 100500
- | + 1")
-
-(js2-deftest-indent multiline-decl-with-continued-expr-same-line
- "var foo = 100500 /
- | 16;")
-
-(js2-deftest-indent no-multiline-decl-with-operator-inside-string
- "var foo = bar('/protocols/')
- |baz()")
-
-(js2-deftest-indent no-multiline-decl-implicit-semicolon
- "var foo = 100500
- |1")
-
-(js2-deftest-indent multiline-decl-sees-keyword-width
- "const foo = 1,
- | bar = 2;")
-
-(js2-deftest-indent multiline-decl-second-arg-value-parenthesised
- "var foo = 1,
- | bar = [
- | 1, 2,
- | 3, 4
- | ],
- | baz = 5;")
-
-(js2-deftest-indent multiline-decl-first-arg-function-normal
- "var foo = function() {
- | return 7;
- |},
- | bar = 8;")
-
-(js2-deftest-indent multiline-decl-first-arg-function-indent-all
- "var foo = function() {
- | return 7;
- | },
- | bar = 8;"
- :bind ((js2-pretty-multiline-declarations 'all)))
-
-(js2-deftest-indent default-keyword-as-property
- "var foo = {
- | case: 'zzzz',
- | default: 'donkey',
- | tee: 'ornery'
- |};")
-
-(js2-deftest-indent multiline-string-noop
- "`multiline string
- | contents
- | are kept
- | unchanged!`"
- :keep-indent t)
-
-(js2-deftest-indent no-multiline-decl-first-arg-function-dynamic
- "var foo = function() {
- | return 7;
- |};"
- :bind ((js2-pretty-multiline-declarations 'dynamic)))
-
-(js2-deftest-indent multiline-decl-first-arg-function-indent-dynamic
- "var foo = function() {
- | return 7;
- | },
- | bar = 8;"
- :bind ((js2-pretty-multiline-declarations 'dynamic)))
-
-(js2-deftest-indent multiline-decl-first-arg-function-indent-dynamic-comment
- "var foo = function() {
- | return 7;
- | }/* MUAHAHAHA, ah ha! */,
- | bar = 8;"
- :bind ((js2-pretty-multiline-declarations 'dynamic)))
-
-(js2-deftest-indent multiline-decl-first-arg-function-indent-dynamic-scan-error
- "var foo = function() {
- | return 7;
- | ,
- | bar = 8;"
- :bind ((js2-pretty-multiline-declarations 'dynamic)))
-
-(js2-deftest-indent indent-generator-method
- "class A {
- | * x() {
- | return 1
- | * a(2);
- | }
- |}")
-
-(js2-deftest-indent indent-generator-computed-method
- "class A {
- | *[Symbol.iterator]() {
- | yield 'Foo';
- | yield 'Bar';
- | }
- |}")
-
-(js2-deftest-indent case-inside-switch
- "switch(true) {
- |case 'true':
- | return 1;
- |}")
-
-(js2-deftest-indent case-inside-switch-with-extra-indent
- "switch(true) {
- | case 'true':
- | return 1;
- |}"
- :bind ((js2-indent-switch-body t)))
-
-(js2-deftest-indent case-inside-switch-with-extra-indent-curly-after-newline
- "switch(true)
- |{
- | case 'true':
- | return 1;
- |}"
- :bind ((js2-indent-switch-body t)))
-
-(js2-deftest-indent continued-expression-vs-unary-minus
- "var arr = [
- | -1, 2,
- | -3, 4 +
- | -5
- |];")
-
-(js2-deftest-indent spread-inside-array
- "var z = [
- | ...iterableObj,
- | 4,
- | 5
- |]")
-
-(js2-deftest-indent no-continued-expression-after-regexp
- "var re = /some value/
- |str.match(re)")
-
-(js2-deftest-indent jsx-one-line
- "var foo = <div></div>;")
-
-(js2-deftest-indent jsx-children-parentheses
- "return (
- | <div>
- | </div>
- | <div>
- | <div></div>
- | <div>
- | <div></div>
- | </div>
- | </div>
- |);")
-
-(js2-deftest-indent jsx-children-unclosed
- "return (
- | <div>
- | <div>")
-
-(js2-deftest-indent jsx-argument
- "React.render(
- | <div>
- | <div></div>
- | </div>,
- | {
- | a: 1
- | },
- | <div>
- | <div></div>
- | </div>
- |);")
-
-(js2-deftest-indent jsx-leading-comment
- "return (
- | // Sneaky!
- | <div></div>
- |);")
-
-(js2-deftest-indent jsx-trailing-comment
- "return (
- | <div></div>
- | // Sneaky!
- |);")
-
-(js2-deftest-indent jsx-self-closing
- ;; This ensures we know the bounds of a self-closing element
- "React.render(
- | <input
- | />,
- | {
- | a: 1
- | }
- |);"
- :bind ((sgml-attribute-offset 1))) ; Emacs 24.5 -> 25 compat
-
-(js2-deftest-indent jsx-embedded-js-content
- "return (
- | <div>
- | {array.map(function () {
- | return {
- | a: 1
- | };
- | })}
- | </div>
- |);")
-
-(js2-deftest-indent jsx-embedded-js-unclosed
- "return (
- | <div>
- | {array.map(function () {
- | return {
- | a: 1")
-
-(js2-deftest-indent jsx-embedded-js-attribute
- "return (
- | <div attribute={array.map(function () {
- | return {
- | a: 1
- | };
- |
- | return {
- | a: 1
- | };
- |
- | return {
- | a: 1
- | };
- | })}>
- | </div>
- |);")
diff --git a/packages/js2-mode/tests/jsdoc.el b/packages/js2-mode/tests/jsdoc.el
deleted file mode 100644
index 5b5af6e..0000000
--- a/packages/js2-mode/tests/jsdoc.el
+++ /dev/null
@@ -1,113 +0,0 @@
-;;; tests/jsdoc.el --- Tests for js2-mode highlighting of jsdoc comments.
-
-;; Copyright (C) 2009, 2011-2017 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'ert-x)
-(require 'js2-mode)
-
-(defun js2-get-font-lock-face-props (beg end)
- "Return a list of three-tuples (START END FONT-LOCK-FACE).
-BEG and END are the current buffer boundaries to use."
- (unless (get-char-property beg 'font-lock-face)
- (setq beg (next-single-char-property-change beg 'font-lock-face nil end)))
- (let (fontification change)
- (while (< beg end)
- (setq change (next-single-char-property-change beg 'font-lock-face nil
end))
- (push (list beg change (get-char-property beg 'font-lock-face))
fontification)
- (setq beg (if (get-char-property change 'font-lock-face)
- change
- (next-single-char-property-change change 'font-lock-face nil
end))))
- (nreverse fontification)))
-
-(defmacro js2-jsdoc-deftest (name comment-text fontification)
- (declare (indent defun))
- (let ((test-name (intern (format "js2-jsdoc-%s" name))))
- `(ert-deftest ,test-name ()
- (ert-with-test-buffer (:name ',test-name)
- (insert ,comment-text)
- (js2-mode)
- (js2-reparse)
- (should (equal (js2-get-font-lock-face-props (point-min) (point-max))
- ,fontification))))))
-
-(js2-jsdoc-deftest param
- "/**\n * @prop {string} p - The property\n */\n"
- '((1 8 font-lock-doc-face)
- (8 13 js2-jsdoc-tag)
- (13 15 font-lock-doc-face)
- (15 21 js2-jsdoc-type)
- (21 23 font-lock-doc-face)
- (23 24 js2-jsdoc-value)
- (24 43 font-lock-doc-face)))
-
-(js2-jsdoc-deftest typed
- "/**\n * @implements {Interface}\n */\n"
- '((1 8 font-lock-doc-face)
- (8 19 js2-jsdoc-tag)
- (19 21 font-lock-doc-face)
- (21 30 js2-jsdoc-type)
- (30 35 font-lock-doc-face)))
-
-(js2-jsdoc-deftest arg
- "/**\n * @name TheName \n */\n"
- '((1 8 font-lock-doc-face)
- (8 13 js2-jsdoc-tag)
- (13 14 font-lock-doc-face)
- (14 21 js2-jsdoc-value)
- (21 26 font-lock-doc-face)))
-
-(js2-jsdoc-deftest empty
- "/**\n * @class \n */\n"
- '((1 8 font-lock-doc-face)
- (8 14 js2-jsdoc-tag)
- (14 19 font-lock-doc-face)))
-
-(js2-jsdoc-deftest param-same-line
- "/** @prop {string} p - The property */\n"
- '((1 5 font-lock-doc-face)
- (5 10 js2-jsdoc-tag)
- (10 12 font-lock-doc-face)
- (12 18 js2-jsdoc-type)
- (18 20 font-lock-doc-face)
- (20 21 js2-jsdoc-value)
- (21 39 font-lock-doc-face)))
-
-(js2-jsdoc-deftest typed-same-line
- "/** @implements {Interface} */\n"
- '((1 5 font-lock-doc-face)
- (5 16 js2-jsdoc-tag)
- (16 18 font-lock-doc-face)
- (18 27 js2-jsdoc-type)
- (27 31 font-lock-doc-face)))
-
-(js2-jsdoc-deftest arg-same-line
- "/** @name TheName */\n"
- '((1 5 font-lock-doc-face)
- (5 10 js2-jsdoc-tag)
- (10 11 font-lock-doc-face)
- (11 18 js2-jsdoc-value)
- (18 21 font-lock-doc-face)))
-
-(js2-jsdoc-deftest empty-same-line
- "/** @class */\n"
- '((1 5 font-lock-doc-face)
- (5 11 js2-jsdoc-tag)
- (11 14 font-lock-doc-face)))
diff --git a/packages/js2-mode/tests/json-path.el
b/packages/js2-mode/tests/json-path.el
deleted file mode 100644
index 70aecef..0000000
--- a/packages/js2-mode/tests/json-path.el
+++ /dev/null
@@ -1,64 +0,0 @@
-;;; tests/json-path.el --- Test of using js2-mode AST to print JSON path.
-
-;; Copyright (C) 2015 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'js2-mode)
-
-(ert-deftest js2-json-path-with-actual-array-index ()
- (with-temp-buffer
- (insert "var a = { hello: [1, 2, [1,3,3,4, { world: { hell: { yes: [1,2,
'test'] } } }]] };")
- (js2-mode)
- (goto-char 0)
- (search-forward "test")
- (should (string= (js2-print-json-path) "hello[2][4].world.hell.yes[2]"))))
-
-(ert-deftest js2-json-path-pure-arrays ()
- (with-temp-buffer
- (insert "var a = [5, 1, 4, [ 4, [1, 2, [1, 3.9, 4, [1, 2, 'test',3]]]], 9,
9];")
- (js2-mode)
- (goto-char 0)
- (search-forward "test")
- (should (string= (js2-print-json-path) "[3][1][2][3][2]"))))
-
-(ert-deftest js2-json-path-key-is-numeric ()
- (with-temp-buffer
- (insert "var b = {hello: {3 : {world: {2: 'test'}}}};")
- (js2-mode)
- (goto-char 0)
- (search-forward "test")
- (should (string= (js2-print-json-path) "hello.3.world.2"))))
-
-(ert-deftest js2-json-path-not-found ()
- (with-temp-buffer
- (insert "console.log('test');")
- (js2-mode)
- (goto-char 0)
- (search-forward "test")
- (should (eq (js2-print-json-path) nil))))
-
-(ert-deftest js2-json-path-with-array-index-hardcoded ()
- (with-temp-buffer
- (insert "var a = { hello: [1, 2, [1,3,3,4, { world: { hell: { yes: [1,2,
'test'] } } }]] };")
- (js2-mode)
- (goto-char 0)
- (search-forward "test")
- (should (string= (js2-print-json-path 1) "hello[1][1].world.hell.yes[1]"))
- (should (string= (js2-print-json-path 0)
"hello[0][0].world.hell.yes[0]"))))
diff --git a/packages/js2-mode/tests/navigation.el
b/packages/js2-mode/tests/navigation.el
deleted file mode 100644
index 26431da..0000000
--- a/packages/js2-mode/tests/navigation.el
+++ /dev/null
@@ -1,110 +0,0 @@
-;;; tests/navigation.el --- Some tests for js2-mode.
-
-;; Copyright (C) 2009, 2011-2015 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'js2-mode)
-
-(cl-defun js2-navigation-helper (buffer-content &optional expected-point
(point-offset 1) expected-error-msg)
- (with-temp-buffer
- (insert buffer-content)
- (let ((start-point (or (- (point) point-offset)))
- actual-error-msg)
- (js2-mode)
- (goto-char start-point)
- (if expected-error-msg
- (setq actual-error-msg
- (cadr (should-error (js2-jump-to-definition) :type 'error)))
- (js2-jump-to-definition))
- (print (format "%d %d" (point) start-point))
- (should (= (point) (or expected-point start-point)))
- (should (string= actual-error-msg expected-error-msg)))))
-
-(ert-deftest js2-jump-to-var ()
- (js2-navigation-helper "var soup = 2; soup" 5))
-
-(ert-deftest js2-jump-to-function ()
- (js2-navigation-helper "function aFunction() {}; aFunction" 1))
-
-(ert-deftest js2-jump-to-function-parameters ()
- (js2-navigation-helper "var p1 = 4; function aFunction(p1, p2) {p1};" 32 4))
-
-(ert-deftest js2-jump-to-object-property ()
- (js2-navigation-helper "var aObject = {prop1: 3, prop2: \"hello\"};
aObject.prop1" 16))
-
-(ert-deftest js2-no-jump-to-object-property ()
- (js2-navigation-helper "var aObject = {prop1: 3, prop2: \"hello\"};
anotherObject.prop1"
- 61 1 "No jump location found"))
-
-(ert-deftest js2-jump-to-nested-property ()
- (js2-navigation-helper "var aObject = {prop1: {prop2: { prop3: 4}}};
aObject.prop1.prop2.prop3" 33))
-
-(ert-deftest js2-jump-to-object ()
- (js2-navigation-helper "var aObject = {prop1: 3, prop2: \"hello\"};
aObject.prop1" 5 13))
-
-(ert-deftest js2-jump-to-property ()
- (js2-navigation-helper "aObject.func = functon(){};aObject.func" 9))
-
-(ert-deftest js2-jump-to-property-object-property ()
- (js2-navigation-helper "aObject.value = {prop:1};aObject.value.prop" 18))
-
-(ert-deftest js2-jump-to-function-definition-inside-object-value ()
- (js2-navigation-helper
- "function aFunction(p1, p2) {return p1+p2}; module.exports =
{aFunction:aFunction};" 1 6))
-
-(ert-deftest js2-no-jump-to-function-definition-object-property ()
- (js2-navigation-helper
- "function aFunction(p1, p2) {return p1+p2}; module.exports =
{aFunction:aFunction};"
- 67 16 "Node is not a supported jump node"))
-
-(ert-deftest js2-jump-to-function-inside-property-value-syntax ()
- (js2-navigation-helper "function aFunction(p1, p2) {return p1+p2};
module.exports = {aFunction};" 1 6))
-
-
-;; forward-sexp
-
-(defun js2-test-forward-sexp (pre-point skipped after-sexp)
- "Test `js2-mode-forward-sexp'.
-The test buffer's contents are set to the concatenation of
-PRE-POINT, SKIPPED, and AFTER-SEXP. Point is placed after
-PRE-POINT, and `forward-sexp' is called. Then point should be
-after SKIPPED."
- (with-temp-buffer
- (insert pre-point skipped after-sexp)
- (js2-mode)
- (goto-char (1+ (length pre-point)))
- (forward-sexp)
- (should (= (point) (+ 1 (length pre-point) (length skipped))))))
-
-(ert-deftest js2-forward-sexp-skip-semi ()
- "Ensure expr-stmt-nodes' semicolons are skipped over."
- (js2-test-forward-sexp "" "const s = 123;" ""))
-
-(ert-deftest js2-forward-sexp-inside-string ()
- "Test forward sexp inside a string."
- (js2-test-forward-sexp "const s = 'some " "(string contents)" " xyz';"))
-
-(ert-deftest js2-backward-sexp-inside-string ()
- "Test backward sexp inside a string."
- (with-temp-buffer
- (insert "const s = 'some (string contents) ")
- (save-excursion (insert "xyz';"))
- (backward-sexp)
- (should (= (point) 17))))
diff --git a/packages/js2-mode/tests/parser.el
b/packages/js2-mode/tests/parser.el
deleted file mode 100644
index 9137940..0000000
--- a/packages/js2-mode/tests/parser.el
+++ /dev/null
@@ -1,1429 +0,0 @@
-;;; tests/parser.el --- Some tests for js2-mode.
-
-;; Copyright (C) 2009, 2011-2017 Free Software Foundation, Inc.
-
-;; 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/>.
-
-;;; Code:
-
-(require 'ert)
-(require 'ert-x)
-(require 'js2-mode)
-(require 'cl-lib)
-
-(defmacro js2-deftest (name buffer-contents &rest body)
- (declare (indent defun))
- `(ert-deftest ,(intern (format "js2-%s" name)) ()
- (with-temp-buffer
- (save-excursion
- (insert ,buffer-contents))
- (unwind-protect
- (progn
- ,@body)
- (fundamental-mode)))))
-
-(defun js2-mode--and-parse ()
- (js2-mode)
- (js2-reparse))
-
-(defun js2-test-string-to-ast (s)
- (insert s)
- (js2-mode--and-parse)
- (should (null js2-mode-buffer-dirty-p))
- js2-mode-ast)
-
-(cl-defun js2-test-parse-string (code-string &key syntax-error errors-count
- reference warnings-count)
- (ert-with-test-buffer (:name 'origin)
- (let ((ast (js2-test-string-to-ast code-string)))
- (if syntax-error
- (let ((errors (js2-ast-root-errors ast)))
- (should (= (or errors-count 1) (length errors)))
- (cl-destructuring-bind (_ pos len) (car (last errors))
- (should (string= syntax-error (substring code-string
- (1- pos) (+ pos len
-1))))))
- (should (= 0 (length (js2-ast-root-errors ast))))
- (ert-with-test-buffer (:name 'copy)
- (js2-print-tree ast)
- (skip-chars-backward " \t\n")
- (should (string= (or reference code-string)
- (buffer-substring-no-properties
- (point-min) (point)))))
- (when warnings-count
- (should (= warnings-count
- (length (js2-ast-root-warnings ast)))))))))
-
-(cl-defmacro js2-deftest-parse (name code-string &key bind syntax-error
errors-count
- reference warnings-count)
- "Parse CODE-STRING. If SYNTAX-ERROR is nil, print syntax tree
-with `js2-print-tree' and assert the result to be equal to
-REFERENCE, if present, or the original string. If SYNTAX-ERROR
-is passed, expect syntax error highlighting substring equal to
-SYNTAX-ERROR value. BIND defines bindings to apply them around
-the test."
- (declare (indent defun))
- `(ert-deftest ,(intern (format "js2-%s" name)) ()
- (let ,(append bind '((js2-basic-offset 2)))
- (js2-test-parse-string ,code-string
- :syntax-error ,syntax-error
- :errors-count ,errors-count
- :warnings-count ,warnings-count
- :reference ,reference))))
-
-(defun js2-find-node (node predicate)
- "Find the first descendant of NODE meeting PREDICATE."
- (let (target)
- (js2-visit-ast node (lambda (n end-p)
- (unless end-p
- (if (funcall predicate n)
- (progn (setq target n) nil)
- t))))
- target))
-
-(defun js2-node-text (node)
- "Return the part of the buffer corresponding to NODE as a string."
- (let ((beg (js2-node-abs-pos node)))
- (buffer-substring-no-properties beg (+ beg (js2-node-len node)))))
-
-;;; Basics
-
-(js2-deftest-parse variable-assignment
- "a = 1;")
-
-(js2-deftest-parse empty-object-literal
- "b = {};")
-
-(js2-deftest-parse empty-array-literal
- "c = [];")
-
-(js2-deftest-parse array-with-missing-elements
- "var a = [1, 2, ,];")
-
-(js2-deftest-parse comma-after-regexp
- "d = /eee/, 42;")
-
-(js2-deftest-parse return-statement
- "function foo() {\n return 2;\n}")
-
-(js2-deftest-parse function-statement
- "function foo() {\n}")
-
-(js2-deftest-parse trailing-comma-in-function-arguments
- "f(a, b,);"
- :reference "f(a, b);")
-
-(js2-deftest-parse function-statement-inside-block
- "if (true) {\n function foo() {\n }\n}")
-
-(js2-deftest-parse function-expression-statements-are-verboten
- "function() {}" :syntax-error "(")
-
-(js2-deftest-parse member-expr-as-function-name
- "function a.b.c[2](x, y) {\n}"
- :bind ((js2-allow-member-expr-as-function-name t)))
-
-(js2-deftest-parse named-function-expression
- "a = function b() {};")
-
-(js2-deftest-parse parenthesized-expression
- "(1 + 2);")
-
-(js2-deftest-parse for-with-in-operator-in-parens
- "for (var y = (0 in []) in {}) {\n}")
-
-(js2-deftest-parse for-with-in-operator-in-cond
- "for (var y = 1 ? 0 in [] : false in {}) {\n}")
-
-(js2-deftest-parse let-expression
- "(let (x = 42) x);")
-
-(js2-deftest-parse let-expression-statement
- "let (x = 42) x;")
-
-(js2-deftest-parse void
- "void 0;")
-
-;;; Callers of `js2-valid-prop-name-token'
-
-(js2-deftest-parse parse-property-access-when-not-keyword
- "A.foo = 3;")
-
-(js2-deftest-parse parse-property-access-when-keyword
- "A.in = 3;"
- :bind ((js2-allow-keywords-as-property-names t)))
-
-(js2-deftest-parse parse-property-access-when-keyword-no-xml
- "A.in = 3;"
- :bind ((js2-allow-keywords-as-property-names t)
- (js2-compiler-xml-available nil)))
-
-(js2-deftest-parse parse-object-literal-when-not-keyword
- "a = {b: 1};")
-
-(js2-deftest-parse parse-object-literal-when-keyword
- "a = {in: 1};"
- :bind ((js2-allow-keywords-as-property-names t)))
-
-;;; 'of' contextual keyword
-
-(js2-deftest-parse parse-legacy-array-comp-loop-with-of
- "[a for (a of [])];")
-
-(js2-deftest-parse parse-array-comp-loop
- "[for (a of []) a];")
-
-(js2-deftest-parse parse-for-of
- "for (var a of []) {\n}")
-
-(js2-deftest-parse of-can-be-name
- "void of;")
-
-(js2-deftest-parse of-can-be-object-name
- "of.z;")
-
-(js2-deftest-parse of-can-be-var-name
- "var of = 3;")
-
-(js2-deftest-parse of-can-be-function-name
- "function of() {\n}")
-
-;;; Destructuring binding
-
-(js2-deftest-parse destruct-in-declaration
- "var {a, b} = {a: 1, b: 2};"
- :warnings-count 0)
-
-(js2-deftest-parse destruct-in-arguments
- "function f({a: aa, b: bb}) {\n}"
- :warnings-count 0)
-
-(js2-deftest-parse destruct-in-array-comp-loop
- "[a + b for ([a, b] in [[0, 1], [1, 2]])];")
-
-(js2-deftest-parse destruct-in-catch-clause
- "try {\n} catch ({a, b}) {\n a + b;\n}"
- :warnings-count 0)
-
-(js2-deftest-parse destruct-with-initializer-in-object
- "var {a, b = 2, c} = {};\nb;"
- :warnings-count 0)
-
-(js2-deftest-parse destruct-with-initializer-in-array
- "var [a, b = 2, c] = [];\nb;"
- :warnings-count 0)
-
-(js2-deftest-parse destruct-non-name-target-is-error
- "var {1=1} = {};" :syntax-error "1" :errors-count 1)
-
-(js2-deftest-parse destruct-with-initializer-in-function-params
- "function f({a, b = 1, c}, [d, e = 1, f]) {\n}")
-
-(js2-deftest-parse destruct-with-default-in-function-params
- "function f({x = 1, y = 2} = {}, [x, y] = [1, 2]) {\n}")
-
-(js2-deftest-parse destruct-name-conflict-is-error-in-object
- "\"use strict\";\nvar {a=1,a=2} = {};" :syntax-error "a" :errors-count 1)
-
-(js2-deftest destruct-name-conflict-is-warning-in-array "\"use strict\";\nvar
[a=1,a=2] = [];"
- (js2-mode--and-parse)
- (should (equal '("msg.var.redecl" "a")
- (caar js2-parsed-warnings))))
-
-(js2-deftest initializer-outside-destruct-is-error "({a=1});"
- (js2-mode--and-parse)
- (should (equal "msg.init.no.destruct"
- (car (caar js2-parsed-errors)))))
-
-;;; Object literals
-
-(js2-deftest-parse object-literal-shorthand
- "var x = {a: 1, b, c: 1, d};")
-
-(js2-deftest-parse object-literal-shorthard-with-number
- "var a = {1};" :syntax-error "}" :errors-count 2)
-
-(js2-deftest-parse object-literal-method
- "var x = {f(y) { return y;\n}};")
-
-(js2-deftest object-literal-method-own-name-in-scope "({f(){f();}});"
- (js2-mode--and-parse)
- (should (equal '("msg.undeclared.variable" "f")
- (caar js2-parsed-warnings))))
-
-(js2-deftest-parse object-literal-getter-method
- "var x = {get f() { return 42;\n}};")
-
-(js2-deftest-parse object-literal-setter-method
- "var x = {set f(y) { x = y;\n}};")
-
-(js2-deftest-parse object-literal-computed-keys
- "var x = {[Symbol.iterator]: function() {}};")
-
-(js2-deftest-parse object-literal-computed-function-keys
- "var x = {[foo + bar](y) { return y;\n}};")
-
-(js2-deftest-parse object-literal-computed-getter-key
- "var x = {get [foo + bar]() { return 42;\n}};")
-
-(js2-deftest-parse object-literal-generator
- "var x = {*foo() { yield* 42;\n}};")
-
-(js2-deftest-parse object-literal-computed-generator-key
- "var x = {*[foo + bar]() { yield 42;\n}};")
-
-;;; Function definition
-
-(js2-deftest function-redeclaring-var "var gen = 3; function gen() {};"
- (js2-mode--and-parse)
- (should (= (length (js2-ast-root-warnings js2-mode-ast)) 1)))
-
-(js2-deftest function-expression-var-same-name "var gen = function gen() {};"
- (js2-mode--and-parse)
- (should (null (js2-ast-root-warnings js2-mode-ast))))
-
-;;; Function parameters
-
-(js2-deftest-parse function-with-default-parameters
- "function foo(a = 1, b = a + 1) {\n}")
-
-(js2-deftest-parse function-with-no-default-after-default
- "function foo(a = 1, b) {\n}")
-
-(js2-deftest-parse function-with-destruct-after-default
- "function foo(a = 1, {b, c}) {\n}")
-
-(js2-deftest-parse function-with-rest-parameter
- "function foo(a, b, ...rest) {\n}")
-
-(js2-deftest-parse function-with-param-after-rest-parameter
- "function foo(a, ...b, rest) {\n}"
- :syntax-error "rest")
-
-(js2-deftest-parse function-with-destruct-after-rest-parameter
- "function foo(a, ...b, {}) {\n}"
- :syntax-error "{}")
-
-(js2-deftest-parse function-with-rest-after-default-parameter
- "function foo(a = 1, ...rest) {\n}")
-
-(js2-deftest-parse function-with-trailing-comma-in-param-list
- "function foo(a, b,) {\n}"
- :reference "function foo(a, b) {\n}")
-
-;;; Strict mode errors
-
-(js2-deftest-parse function-bad-strict-parameters
- "'use strict';\nfunction foo(eval, {arguments}, bar) {\n}"
- :syntax-error "eval" :errors-count 2)
-
-(js2-deftest-parse function-retroactive-bad-strict-parameters
- "function foo(arguments) {'use strict';}"
- :syntax-error "arguments" :errors-count 1)
-
-(js2-deftest-parse function-duplicate-strict-parameters
- "'use strict';\nfunction foo(a, a) {\n}"
- :syntax-error "a" :errors-count 1)
-
-(js2-deftest-parse function-bad-strict-function-name
- "'use strict';\nfunction eval() {\n}"
- :syntax-error "eval" :errors-count 1)
-
-(js2-deftest-parse function-bad-retroactive-strict-function-name
- "function arguments() {'use strict';}"
- :syntax-error "arguments" :errors-count 1)
-
-(js2-deftest-parse function-bad-strict-catch-name
- "'use strict';\ntry {} catch (eval) {}"
- :syntax-error "eval" :errors-count 1)
-
-(js2-deftest-parse function-bad-strict-variable-name
- "'use strict';\nvar eval = 'kekeke';"
- :syntax-error "eval" :errors-count 1)
-
-(js2-deftest-parse function-bad-strict-assignment
- "'use strict';\narguments = 'fufufu';"
- :syntax-error "arguments" :errors-count 1)
-
-(js2-deftest-parse function-property-strict-assignment
- "'use strict';\narguments.okay = 'alright';")
-
-(js2-deftest-parse function-strict-with
- "'use strict';\nwith ({}) {}"
- :syntax-error "with" :errors-count 1)
-
-(js2-deftest-parse function-strict-octal
- "'use strict';\nvar number = 0644;"
- :syntax-error "0644" :errors-count 1)
-
-(js2-deftest-parse function-strict-octal-allow-0o
- "'use strict';\n0o644;" :reference "'use strict';\n420;")
-
-(js2-deftest-parse function-strict-duplicate-keys
- "'use strict';\nvar object = {a: 1, a: 2, 'a': 3, ['a']: 4, 1: 5, '1': 6, [1
+ 1]: 7};"
- :syntax-error "a" :errors-count 4) ; "a" has 3 dupes, "1" has 1 dupe.
-
-(js2-deftest-parse function-strict-duplicate-getter
- "'use strict';\nvar a = {get x() {}, get x() {}};"
- :syntax-error "x" :errors-count 1)
-
-(js2-deftest-parse function-strict-duplicate-setter
- "'use strict';\nvar a = {set x() {}, set x() {}};"
- :syntax-error "x" :errors-count 1)
-
-;;; Lack of errors in strict mode
-
-(js2-deftest-parse function-strict-const-scope
- "'use strict';\nconst a;\nif (1) {\n const a;\n}")
-
-(js2-deftest-parse function-strict-no-getter-setter-duplicate
- "'use strict';\nvar a = {get x() {}, set x() {}};")
-
-;;; Spread operator
-
-(js2-deftest-parse spread-in-array-literal
- "[1, ...[2, 3], 4, ...[5, 6]];")
-
-(js2-deftest-parse spread-in-function-call
- "f(3, ...[t(2), t(3)], 42, ...[t(4)]);")
-
-(js2-deftest-parse rest-in-array-destructure
- "let [x, y, z, ...w] = [1, ...a, ...b, c];")
-
-(js2-deftest-parse comma-after-rest-in-array
- "let [...x,] = [1, 2, 3];"
- :syntax-error "," :errors-count 1)
-
-(js2-deftest-parse elem-after-rest-in-array
- "let [...x, y] = [1, 2, 3];"
- :syntax-error "," :errors-count 2)
-
-(js2-deftest-parse array-destructure-expr-default
- "let [[x] = [3]] = y;")
-
-(js2-deftest-parse spread-in-object-literal
- "f({x, y, ...z});")
-
-(js2-deftest-parse rest-in-object-literal
- "const {x, y, ...z} = f();")
-
-;;; Arrow functions
-
-(js2-deftest-parse arrow-function-with-empty-args-and-no-curlies
- "() => false;" :reference "() => {false};")
-
-(js2-deftest-parse arrow-function-with-args-and-curlies
- "(a, b = 1, ...c) => { c;\n};")
-
-(js2-deftest-parse arrow-function-with-destructuring
- "([{a}, b]) => { a + b;\n};")
-
-(js2-deftest-parse parenless-arrow-function-prohibits-rest
- "...b => {b + 1;};" :syntax-error "=>")
-
-(js2-deftest-parse parenless-arrow-function-prohibits-destructuring
- "[a, b] => {a + b;};" :syntax-error "]" :errors-count 4)
-
-(js2-deftest-parse arrow-function-recovers-from-error
- "[(,foo) => 1];" :syntax-error "," :errors-count 6)
-
-;;; Automatic semicolon insertion
-
-(js2-deftest-parse no-auto-semi-insertion-after-if
- "if (true) {\n}")
-
-(js2-deftest-parse auto-semi-insertion-after-function
- "a = function() {}" :reference "a = function() {};")
-
-(js2-deftest-parse auto-semi-one-variable-per-line
- "x\ny" :reference "x;\ny;")
-
-;;; Labels
-
-(js2-deftest-parse labeled-stmt-node
- "foo:\nbar:\nx = y + 1;")
-
-(js2-deftest no-label-node-inside-expr "x = y:"
- (let (js2-parse-interruptable-p)
- (js2-mode--and-parse))
- (let ((assignment (js2-expr-stmt-node-expr (car (js2-scope-kids
js2-mode-ast)))))
- (should (js2-name-node-p (js2-assign-node-right assignment)))))
-
-(js2-deftest-parse label-and-loops "for (; ; ) {
- loop:
- for (; ; ) {
- continue loop;
- }
-}")
-
-;;; Generators
-
-(js2-deftest-parse legacy-generator "function foo() {\n yield 1;\n}")
-
-(js2-deftest-parse legacy-generator-cannot-return
- "function foo() {\n yield 1;\n return 2;\n}" :syntax-error "return 2")
-
-(js2-deftest-parse harmony-generator "function* bar() {\n yield 2;\n return
3;\n}")
-
-(js2-deftest-parse harmony-generator-yield-star "(function*(a) { yield*
a;\n});")
-
-(js2-deftest-parse harmony-generator-yield-assign-expr
- "(function*() { return {a: yield a, b: yield b, c: yield c};\n});")
-
-;;; Comprehensions
-
-(js2-deftest-parse parse-legacy-array-comp-loop-with-filter
- "[a for (a in b) if (a == 2)];")
-
-(js2-deftest-parse parse-array-comp-loop-with-filters
- "[for (a in b) if (a == 2) if (b != 10) a];")
-
-(js2-deftest-parse parse-generator-comp-loop-with-filters
- "(for (x of y) if (x != 4) x);")
-
-(js2-deftest-parse parse-array-comp-with-yield-is-ok
- "(function() { return [for (x of []) yield x];\n});")
-
-(js2-deftest-parse parse-generator-comp-with-yield-is-not-ok
- "(function() { return (for (x of []) yield x);\n});"
- :syntax-error "yield")
-
-(js2-deftest-parse parse-generator-comp-with-yield-inside-function-is-ok
- "(for (x of []) function*() { yield x;\n});")
-
-;;; Async
-
-(js2-deftest-parse async-function-statement
- "async function foo() {\n}")
-
-(js2-deftest-parse async-function-statement-inside-block
- "if (true) {\n async function foo() {\n }\n}")
-
-(js2-deftest-parse async-function-expression-statements-are-verboten
- "async function() {}" :syntax-error "(")
-
-(js2-deftest-parse async-named-function-expression
- "a = async function b() {};")
-
-(js2-deftest-parse async-arrow-function-expression
- "a = async (b) => { b;\n};")
-
-(js2-deftest-parse async-arrow-function-without-parens
- "a = async b => 3;" :reference "a = async (b) => {3};")
-
-(js2-deftest-parse async-method-in-object-literal
- "({async f() {}});")
-
-(js2-deftest-parse async-method-kwname-in-object-literal
- "({async delete() {}});")
-
-(js2-deftest-parse async-method-in-class-body
- "class C {\n async foo() {}\n}")
-
-(js2-deftest-parse static-async-method-in-class-body
- "class C {\n static async foo() {}\n}")
-
-(js2-deftest-parse async-method-allow-await
- "({async f() { await x;\n}});")
-
-;;; Await
-
-(js2-deftest-parse await-is-ok "async function foo() {\n await bar();\n}")
-
-(js2-deftest-parse await-inside-assignment-is-ok
- "async function foo() {\n var result = await bar();\n}")
-
-(js2-deftest-parse await-inside-array-is-ok
- "async function foo() {\n var results = [await bar(),
await baz()];\n}")
-
-(js2-deftest-parse await-inside-non-async-function-is-not-ok
- "function foo() {\n await bar();\n}"
- :syntax-error "await")
-
-(js2-deftest-parse await-inside-non-async-arrow-function-is-not-ok
- "a = () => { await bar();\n}"
- :syntax-error "await")
-
-;;; 'async' and 'await' are contextual keywords
-
-(js2-deftest-parse async-can-be-name
- "void async;")
-
-(js2-deftest-parse async-can-be-object-name
- "async.z;")
-
-(js2-deftest-parse async-can-be-var-name
- "var async = 3;")
-
-(js2-deftest-parse async-can-be-function-name
- "function async() {\n}")
-
-(js2-deftest-parse await-can-be-name
- "void await;")
-
-(js2-deftest-parse await-can-be-object-name
- "await.z;")
-
-(js2-deftest-parse await-can-be-var-name
- "var await = 3;")
-
-(js2-deftest-parse await-can-be-function-name
- "function await() {\n}")
-
-;;; Numbers
-
-(js2-deftest-parse decimal-starting-with-zero "081;" :reference "81;")
-
-(js2-deftest-parse huge-hex "0x0123456789abcdefABCDEF;" :reference "-1;")
-
-(js2-deftest-parse octal-without-o "071;" :reference "57;")
-
-(js2-deftest-parse hex-number-okay "0x123;" :reference "291;")
-
-(js2-deftest-parse hex-number-broken "0xz23;"
- :syntax-error "0xz" :errors-count 2)
-
-(js2-deftest-parse binary-number-okay "0b101;" :reference "5;")
-
-(js2-deftest-parse binary-number-broken "0b210;"
- :syntax-error "0b2" :errors-count 2)
-
-(js2-deftest-parse octal-number-okay "0o765;" :reference "501;")
-
-(js2-deftest-parse octal-number-broken "0o812;"
- :syntax-error "0o8" :errors-count 2)
-
-;;; Modules
-
-(js2-deftest parse-export-bindings "{one, two as dos}"
- (js2-init-scanner)
- (should (js2-match-token js2-LC))
- (let ((imports (js2-parse-export-bindings)))
- (should (not (null imports)))
- (should (= 2 (length imports)))
- (let ((first (nth 0 imports))
- (second (nth 1 imports)))
- (should (equal "one" (js2-name-node-name
(js2-export-binding-node-extern-name first))))
- (should (equal "two" (js2-name-node-name
(js2-export-binding-node-extern-name second))))
- (let ((first-name (js2-export-binding-node-local-name first))
- (second-name (js2-export-binding-node-local-name second)))
- (should (equal first (js2-node-parent first-name)))
- (should (equal 3 (js2-node-len first-name)))
- (should (equal "one" (js2-name-node-name first-name)))
- (should (equal second (js2-node-parent second-name)))
- (should (equal 3 (js2-node-len second-name)))
- (should (equal "dos" (js2-name-node-name second-name)))))))
-
-(js2-deftest parse-export-binding-as-default "one as default"
- (js2-init-scanner)
- (let ((binding (js2-maybe-parse-export-binding)))
- (should binding)
- (should (js2-export-binding-node-p binding))
- (let ((name (js2-export-binding-node-local-name binding)))
- (should name)
- (should (equal "default" (js2-name-node-name name))))))
-
-(js2-deftest parse-namespace-import "* as lib;"
- (js2-init-scanner)
- (should (js2-match-token js2-MUL))
- (let ((namespace-import (js2-parse-namespace-import)))
- (should (not (null namespace-import)))
- (should (js2-namespace-import-node-p namespace-import))
- (should (= 1 (js2-node-pos namespace-import)))
- (should (equal 8 (js2-node-len namespace-import)))
- (let ((name-node (js2-namespace-import-node-name namespace-import)))
- (should (equal "lib" (js2-name-node-name name-node)))
- (should (= 5 (js2-node-pos name-node))))))
-
-(js2-deftest-parse parse-namespace-import-error
- "import * lib from 'lib';"
- :syntax-error "import"
- :errors-count 7)
-
-(js2-deftest parse-from-clause "from 'foo/bar';"
- (js2-init-scanner)
- (let ((from (js2-parse-from-clause)))
- (should (not (null from)))
- (should (= 1 (js2-node-pos from)))
- (should (= 14 (js2-node-len from)))
- (should (equal "foo/bar" (js2-from-clause-node-module-id from)))))
-
-(js2-deftest parse-import-module-id-only "import 'src/lib'"
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import (js2-parse-import)))
- (should (not (null import)))
- (should (= 1 (js2-node-pos import)))
- (should (= 16 (js2-node-len import)))
- (should (null (js2-import-node-import import)))
- (should (null (js2-import-node-from import)))))
-
-(js2-deftest parse-imported-default-binding "import theDefault from 'src/lib'"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should (not (null import-node)))
- (should (equal "src/lib" (js2-import-node-module-id import-node)))
- (let ((import (js2-import-node-import import-node)))
- (should (not (null import)))
- (should (null (js2-import-clause-node-namespace-import import)))
- (should (null (js2-import-clause-node-named-imports import)))
- (let ((default (js2-import-clause-node-default-binding import)))
- (should (not (null default)))
- (should (js2-export-binding-node-p default))
- (should (equal "theDefault" (js2-name-node-name
(js2-export-binding-node-extern-name default)))))))
- (should (js2-scope-get-symbol js2-current-scope "theDefault")))
-
-(js2-deftest parse-import-namespace-binding "import * as lib from 'src/lib'"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should (not (null import-node)))
- (should (equal "src/lib" (js2-import-node-module-id import-node)))
- (let ((import (js2-import-node-import import-node)))
- (should (not (null import)))
- (should (null (js2-import-clause-node-default-binding import)))
- (should (null (js2-import-clause-node-named-imports import)))
- (let ((ns-import (js2-import-clause-node-namespace-import import)))
- (should (not (null ns-import)))
- (should (js2-namespace-import-node-p ns-import))
- (should (equal "lib" (js2-name-node-name
(js2-namespace-import-node-name ns-import)))))))
- (should (js2-scope-get-symbol js2-current-scope "lib")))
-
-(js2-deftest parse-import-named-imports "import {foo as bar, baz} from
'src/lib'"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should (not (null import-node)))
- (should (equal "src/lib" (js2-import-node-module-id import-node)))
- (let ((import (js2-import-node-import import-node)))
- (should (not (null import)))
- (should (null (js2-import-clause-node-default-binding import)))
- (should (null (js2-import-clause-node-namespace-import import)))
- (let ((named-imports (js2-import-clause-node-named-imports import)))
- (should (not (null named-imports)))
- (should (listp named-imports))
- (should (= 2 (length named-imports)))
- (let ((first (nth 0 named-imports))
- (second (nth 1 named-imports)))
- (should (equal "bar" (js2-name-node-name
(js2-export-binding-node-local-name first))))
- (should (equal "baz" (js2-name-node-name
(js2-export-binding-node-local-name second))))))))
- (should (js2-scope-get-symbol js2-current-scope "bar"))
- (should (js2-scope-get-symbol js2-current-scope "baz")))
-
-(js2-deftest parse-import-default-and-namespace "import stuff, * as lib from
'src/lib'"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should (not (null import-node)))
- (should (equal "src/lib" (js2-import-node-module-id import-node)))
- (let ((import (js2-import-node-import import-node)))
- (should (not (null import)))
- (should (null (js2-import-clause-node-named-imports import)))
- (let ((default (js2-import-clause-node-default-binding import))
- (ns-import (js2-import-clause-node-namespace-import import)))
- (should (not (null default)))
- (should (equal "stuff" (js2-name-node-name
(js2-export-binding-node-local-name default))))
- (should (not (null ns-import)))
- (should (js2-namespace-import-node-p ns-import))
- (should (equal "lib" (js2-name-node-name
(js2-namespace-import-node-name ns-import)))))))
- (should (js2-scope-get-symbol js2-current-scope "stuff"))
- (should (js2-scope-get-symbol js2-current-scope "lib")))
-
-(js2-deftest parse-import-default-and-named-imports
- "import robert as bob, {cookies, pi as PIE} from 'src/lib'"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should (not (null import-node)))
- (should (equal "src/lib" (js2-import-node-module-id import-node)))
- (let ((import (js2-import-node-import import-node)))
- (should (not (null import)))
- (should (not (null (js2-import-clause-node-named-imports import))))
- (let ((default (js2-import-clause-node-default-binding import))
- (named-imports (js2-import-clause-node-named-imports import)))
- (should (not (null default)))
- (should (equal "bob" (js2-name-node-name
(js2-export-binding-node-local-name default))))
- (should (not (null named-imports)))
- (should (= 2 (length named-imports))))))
- (should (js2-scope-get-symbol js2-current-scope "bob"))
- (should (js2-scope-get-symbol js2-current-scope "cookies"))
- (should (js2-scope-get-symbol js2-current-scope "PIE")))
-
-(js2-deftest parse-this-module-in-from-clause "import {url} from this module;"
- (js2-push-scope (make-js2-scope :pos 0))
- (js2-init-scanner)
- (should (js2-match-token js2-IMPORT))
- (let ((import-node (js2-parse-import)))
- (should import-node)
- (let ((from-clause (js2-import-node-from import-node)))
- (should from-clause)
- (should (equal "this" (js2-from-clause-node-module-id from-clause)))
- (should (js2-from-clause-node-metadata-p from-clause)))))
-
-(js2-deftest-parse import-only-for-side-effects "import 'src/lib';")
-(js2-deftest-parse import-default-only "import theDefault from 'src/lib';")
-(js2-deftest-parse import-named-only "import {one, two} from 'src/lib';")
-(js2-deftest-parse import-default-and-named "import theDefault, {one, two}
from 'src/lib';")
-(js2-deftest-parse import-renaming-default "import * as lib from 'src/mylib';")
-(js2-deftest-parse import-renaming-named "import {one as uno, two as dos} from
'src/lib';")
-(js2-deftest-parse import-default-and-namespace "import robert as bob, * as
lib from 'src/lib';")
-(js2-deftest-parse import-from-this-module "import {url} from this module;")
-
-;; Module Exports
-
-(js2-deftest export-rexport "export * from 'other/lib'"
- (js2-init-scanner)
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-from-clause export-node))))
-
-(js2-deftest export-export-named-list "export {foo, bar as bang};"
- (js2-init-scanner)
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (let ((exports (js2-export-node-exports-list export-node)))
- (should exports)
- (should (= 2 (length exports))))))
-
-(js2-deftest re-export-named-list "export {foo, bar as bang} from 'other/lib'"
- (js2-init-scanner)
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-from-clause export-node))
- (let ((exports (js2-export-node-exports-list export-node)))
- (should exports)
- (should (= 2 (length exports))))))
-
-(js2-deftest export-variable-statement "export var foo = 'bar', baz = 'bang';"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-declaration export-node))))
-
-(js2-deftest export-const-declaration "export const PI = Math.PI;"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-declaration export-node))))
-
-(js2-deftest export-let-declaration "export let foo = [1];"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-var-decl-node-p (js2-export-node-declaration export-node)))))
-
-(js2-deftest export-class-declaration "export class Foo {}"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-class-node-p (js2-export-node-declaration export-node)))))
-
-(js2-deftest export-function-declaration "export default function doStuff() {}"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-default export-node))))
-
-(js2-deftest export-generator-declaration "export default function* one() {}"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-default export-node))))
-
-(js2-deftest export-assignment-expression "export default a = b;"
- (js2-init-scanner)
- (js2-push-scope (make-js2-scope :pos 0))
- (should (js2-match-token js2-EXPORT))
- (let ((export-node (js2-parse-export)))
- (should export-node)
- (should (js2-export-node-default export-node))))
-
-(js2-deftest export-function-no-semicolon "export default function foo() {}"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
-(js2-deftest export-default-function-no-semicolon "export function foo() {}"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
-(js2-deftest export-anything-else-does-require-a-semicolon "export var obj =
{}"
- (js2-mode--and-parse)
- (should (not (null js2-parsed-warnings))))
-
-(js2-deftest export-default-async-function-no-semicolon "export default async
function foo() {}"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
-(js2-deftest export-async-function-no-semicolon "export async function foo()
{}"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
-
-(js2-deftest-parse parse-export-rexport "export * from 'other/lib';")
-(js2-deftest-parse parse-export-export-named-list "export {foo, bar as bang};")
-(js2-deftest-parse parse-re-export-named-list "export {foo, bar as bang} from
'other/lib';")
-(js2-deftest-parse parse-export-const-declaration "export const PI = Math.PI;")
-(js2-deftest-parse parse-export-let-declaration "export let foo = [1];")
-(js2-deftest-parse parse-export-default-function "export default function()
{}")
-(js2-deftest-parse parse-export-default-generator "export default function*()
{}")
-(js2-deftest-parse parse-export-default-class "export default class {\n}")
-(js2-deftest-parse parse-export-assignment-expression "export default a = b;")
-
-(js2-deftest-parse parse-export-function-declaration-no-semi
- "export function f() {\n}")
-
-(js2-deftest-parse parse-export-class-declaration-no-semi
- "export class C {\n}")
-
-(js2-deftest-parse parse-export-async-function-allow-await
- "export async function f() {\n await f();\n}")
-
-(js2-deftest-parse parse-export-default-async-function-allow-await
- "export default async function f() {\n await f();\n}")
-
-;;; Strings
-
-(js2-deftest-parse string-literal
- "var x = 'y';")
-
-(js2-deftest-parse object-get-string-literal
- "var x = {y: 5};\nvar z = x[\"y\"];")
-
-(js2-deftest-parse template-no-substritutions
- "var x = `abc
- def`, y = `\\u0000`;")
-
-(js2-deftest-parse template-with-substitutions
- "var y = `${a + b} ${d + e + f}`;")
-
-(js2-deftest-parse tagged-template
- "foo.args`${++x, \"o\"}k`;")
-
-;;; Classes
-
-(js2-deftest-parse parse-harmony-class-statement
- "class Foo {\n get bar() { return 42;\n}\n set bar(x) { y = x;\n}\n}")
-
-(js2-deftest-parse parse-harmony-class-statement-without-name-is-not-ok
- "class {\n get bar() { return 42;\n}\n}"
- :syntax-error "{")
-
-(js2-deftest-parse parse-harmony-class-expression
- "var Foo1 = class Foo {\n bar() { return 42;\n}\n};")
-
-(js2-deftest-parse parse-harmony-anonymous-class-expression
- "var Foo = class {\n set bar(x) { bar = x;\n}\n};")
-
-(js2-deftest-parse parse-harmony-class-with-extends
- "class Foo extends Bar {\n}")
-
-(js2-deftest-parse parse-harmony-anonymous-class-with-extends
- "foo.Foo = class extends Bar {\n set bar(x) { bar = x;\n}\n};")
-
-(js2-deftest-parse parse-harmony-class-with-complex-extends
- "class Foo extends foo[BAR][2].Baz {\n}")
-
-(js2-deftest-parse parse-harmony-class-missing-extended-class-is-not-ok
- "class Foo extends {\n}"
- :syntax-error "extends")
-
-(js2-deftest-parse parse-harmony-class-static-method
- "class Foo extends Bar {\n static bar() { return 42;\n}\n}")
-
-(js2-deftest-parse parse-unterminated-class-is-not-okay
- "class Foo {\n get bar() { return 42;\n}"
- :syntax-error "}")
-
-(js2-deftest-parse parse-super-keyword
- "class Foo {\n constructor() { super(42);\n}\n foo() {
super.foo();\n}\n}")
-
-(js2-deftest-parse parse-class-keywordlike-method
- "class C {\n delete() {}\n if() {}\n}")
-
-(js2-deftest-parse parse-harmony-class-allow-semicolon-element
- "class Foo {;}" :reference "class Foo {\n}")
-
-(js2-deftest-parse parse-class-public-field-with-init
- "class C {\n x = 42;\n y = 24;\n \"z\" = 1\n 456 = 789\n}"
- :reference "class C {\n x = 42\n y = 24\n \"z\" = 1\n 456 = 789\n}")
-
-(js2-deftest-parse parse-class-public-field-no-init
- "class C {\n x\n y\n \"z\"\n 456\n}")
-
-(js2-deftest-parse parse-class-public-field-computed
- "class C {\n [a + b] = c\n}")
-
-;;; Operators
-
-(js2-deftest-parse exponentiation
- "a **= b ** c ** d * e ** f;")
-
-(js2-deftest-parse exponentiation-prohibits-unary-op
- "var a = -b ** c" :syntax-error "-b")
-
-(js2-deftest unary-void-node-start
- "var c = void 0"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "void 0"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "0"))))
-
-(js2-deftest unary-pos-node-start
- "var a = +1;"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "+1"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "1"))))
-
-(js2-deftest unary-minus-node-start
- "var a = -1;"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "-1"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "1"))))
-
-(js2-deftest unary-await-node-start
- "var f = async () => await p;"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "await p"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "p"))))
-
-(js2-deftest unary-inc-node-start
- "var a = 1; a++;"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "a++"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "a"))))
-
-(js2-deftest unary-delete-node-start
- "var a = {b: 2}; delete a.b;"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "delete a.b"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "a.b"))))
-
-(js2-deftest unary-triple-dot-arg-node-start
- "var b = f(...args)"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "...args"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "args"))))
-
-(js2-deftest unary-triple-dot-array-node-start
- "var a = [1, 2, ...b]"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "...b"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "b"))))
-
-(js2-deftest unary-triple-dot-object-node-start
- "var a = {x: 1, y: 2, ...z}"
- (js2-mode--and-parse)
- (let ((node (js2-find-node js2-mode-ast 'js2-unary-node-p)))
- (should node)
- (should (string= (js2-node-text node) "...z"))
- (should (string= (js2-node-text (js2-unary-node-operand node)) "z"))))
-
-;;; Scopes
-
-(js2-deftest ast-symbol-table-includes-fn-node "function foo() {}"
- (js2-mode--and-parse)
- (let ((entry (js2-scope-get-symbol js2-mode-ast 'foo)))
- (should (= (js2-symbol-decl-type entry) js2-FUNCTION))
- (should (equal (js2-symbol-name entry) "foo"))
- (should (js2-function-node-p (js2-symbol-ast-node entry)))))
-
-(js2-deftest fn-symbol-table-includes-nested-fn "function foo() {
- function bar() {}
- var x;
-}"
- (js2-mode--and-parse)
- (let* ((scope (js2-node-at-point (point-min)))
- (fn-entry (js2-scope-get-symbol scope 'bar))
- (var-entry (js2-scope-get-symbol scope 'x)))
- (should (string= (js2-name-node-name (js2-function-node-name scope))
"foo"))
- (should (= (js2-symbol-decl-type fn-entry) js2-FUNCTION))
- (should (js2-function-node-p (js2-symbol-ast-node fn-entry)))
- (should (= (js2-symbol-decl-type var-entry) js2-VAR))
- (should (js2-name-node-p (js2-symbol-ast-node var-entry)))))
-
-(defun js2-test-scope-of-nth-variable-satisifies-predicate (variable nth
predicate)
- (goto-char (point-min))
- (dotimes (n (1+ nth)) (search-forward variable))
- (forward-char -1)
- (let ((scope (js2-node-get-enclosing-scope (js2-node-at-point))))
- (should (funcall predicate (js2-get-defining-scope scope variable)))))
-
-(js2-deftest for-node-is-declaration-scope "for (let i = 0; i; ++i) {};"
- (js2-mode--and-parse)
- (js2-test-scope-of-nth-variable-satisifies-predicate "i" 0 #'js2-for-node-p))
-
-(js2-deftest const-scope-inside-script "{ const a; } a;"
- (js2-mode--and-parse)
- (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0
#'js2-block-node-p)
- (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'null))
-
-(js2-deftest const-scope-inside-function "function f() { { const a; } a; }"
- (js2-mode--and-parse)
- (js2-test-scope-of-nth-variable-satisifies-predicate "a" 0
#'js2-block-node-p)
- (js2-test-scope-of-nth-variable-satisifies-predicate "a" 1 #'null))
-
-(js2-deftest array-comp-is-result-scope "[x * 2 for (x in y)];"
- (js2-mode--and-parse)
- (js2-test-scope-of-nth-variable-satisifies-predicate "x" 0
#'js2-comp-loop-node-p))
-
-(js2-deftest array-comp-has-parent-scope
- "var a,b=[for (i of [[1,2]]) for (j of i) j * a];"
- (js2-mode--and-parse)
- (search-forward "for")
- (forward-char -3)
- (let ((node (js2-node-at-point)))
- (should (js2-scope-parent-scope node))
- (should (js2-get-defining-scope node "j"))))
-
-;;; Tokenizer
-
-(js2-deftest get-token "(1+1)"
- (js2-init-scanner)
- (should (eq js2-LP (js2-next-token)))
- (should (eq js2-NUMBER (js2-next-token)))
- (should (eq js2-ADD (js2-next-token)))
- (should (eq js2-NUMBER (js2-next-token)))
- (should (eq js2-RP (js2-next-token))))
-
-(js2-deftest unget-token "()"
- (js2-init-scanner)
- (should (eq js2-LP (js2-next-token)))
- (js2-unget-token)
- (should (eq js2-LP (js2-next-token)))
- (should (eq js2-RP (js2-next-token))))
-
-(js2-deftest get-token-or-eol "x\n++;"
- (js2-init-scanner)
- (should (eq js2-NAME (js2-next-token)))
- (should (eq js2-EOL (js2-peek-token-or-eol)))
- (should (eq js2-INC (js2-next-token)))
- (should (eq js2-SEMI (js2-peek-token-or-eol))))
-
-(js2-deftest unget-token-over-eol-and-comment "x\n//abc\ny"
- (js2-init-scanner)
- (should (eq js2-NAME (js2-next-token)))
- (should (eq js2-NAME (js2-next-token)))
- (should (equal "y" (js2-current-token-string)))
- (js2-unget-token)
- (should (eq js2-NAME (js2-current-token-type)))
- (should (equal "x" (js2-current-token-string))))
-
-(js2-deftest ts-seek "(1+2)"
- (js2-init-scanner)
- (should (eq js2-LP (js2-next-token)))
- (should (eq js2-NUMBER (js2-next-token)))
- (js2-unget-token)
- (let ((state (make-js2-ts-state)))
- (should (eq js2-NUMBER (js2-next-token)))
- (should (eq js2-ADD (js2-next-token)))
- (js2-ts-seek state)
- (should (eq 1 js2-ti-lookahead))
- (should (eq js2-NUMBER (js2-next-token)))
- (should (eq 1 (js2-token-number
- (js2-current-token))))))
-
-(js2-deftest get-token-template-literal "`abc ${i} z ${j} def`"
- (js2-init-scanner)
- (should (eq js2-TEMPLATE_HEAD (js2-next-token)))
- (should (equal "abc " (js2-current-token-string)))
- (should (eq js2-NAME (js2-next-token)))
- (should (eq js2-RC (js2-next-token)))
- (should (eq js2-TEMPLATE_HEAD (js2-next-token 'TEMPLATE_TAIL)))
- (should (equal " z " (js2-current-token-string)))
- (should (eq js2-NAME (js2-next-token)))
- (should (eq js2-RC (js2-next-token)))
- (should (eq js2-NO_SUBS_TEMPLATE (js2-next-token 'TEMPLATE_TAIL)))
- (should (equal " def" (js2-current-token-string))))
-
-;;; Error handling
-
-(js2-deftest for-node-with-error-len "for "
- (js2-mode--and-parse)
- (let ((node (js2-node-at-point (point-min))))
- (should (= (js2-node-len (js2-node-parent node)) 4))))
-
-(js2-deftest function-without-parens-error "function b {}"
- ;; Should finish the parse.
- (js2-mode--and-parse))
-
-;;; Comments
-
-(js2-deftest comment-node-length "//"
- (js2-mode--and-parse)
- (let ((node (js2-node-at-point (point-min))))
- (should (= (js2-node-len node) 2))))
-
-(js2-deftest comment-node-length-newline "//\n"
- (js2-mode--and-parse)
- (let ((node (js2-node-at-point (point-min))))
- (should (= (js2-node-len node) 3))))
-
-;;; Variables classification
-
-(defun js2--variables-summary (vars)
- (let (r)
- (setq vars (let (aslist)
- (maphash (lambda (k v) (push (cons k v) aslist)) vars)
- aslist))
- (dolist (v (sort vars (lambda (a b) (< (js2-node-abs-pos
(js2-symbol-ast-node (car a)))
- (js2-node-abs-pos (js2-symbol-ast-node
(car b)))))))
- (let* ((symbol (car v))
- (inition (cadr v))
- (uses (cddr v))
- (symn (js2-symbol-ast-node symbol))
- (namen (js2--get-name-node symn)))
- (push (format "%s@%s:%s"
- (js2-symbol-name symbol)
- (js2-node-abs-pos namen)
- (if (eq inition ?P)
- "P"
- (if uses
- (if inition "I" "N")
- "U"))) r)
- (dolist (u (sort (cddr v) (lambda (a b) (< (js2-node-abs-pos a)
- (js2-node-abs-pos b)))))
- (push (js2-node-abs-pos u) r))))
- (reverse r)))
-
-(defmacro js2-deftest-classify-variables (name buffer-contents summary)
- (declare (indent defun))
- `(ert-deftest ,(intern (format "js2-classify-variables-%s" name)) ()
- (with-temp-buffer
- (save-excursion
- (insert ,buffer-contents))
- (unwind-protect
- (progn
- (js2-mode--and-parse)
- (should (equal ,summary (js2--variables-summary
- (js2--classify-variables)))))
- (fundamental-mode)))))
-
-(js2-deftest-classify-variables incomplete-var-statement
- "var"
- '())
-
-(js2-deftest-classify-variables unused-variable
- "function foo () { var x; return 42; }"
- '("foo@10:U" "x@23:U"))
-
-(js2-deftest-classify-variables unused-variable-declared-twice
- "function foo (a) { var x; function bar () { var x; x=42; }; return a;}"
- '("foo@10:U" "a@15:P" 68 "x@24:U" "bar@36:U" "x@49:U"))
-
-(js2-deftest-classify-variables assigned-variable
- "function foo () { var x; x=42; return x; }"
- '("foo@10:U" "x@23:I" 39))
-
-(js2-deftest-classify-variables assignment-in-nested-function
- "function foo () { var x; function bar () { x=42; }; }"
- '("foo@10:U" "x@23:U" "bar@35:U"))
-
-(js2-deftest-classify-variables unused-nested-function
- "function foo() { var i, j=1; function bar() { var x, y=42, z=i; return y; }
return i; }"
- '("foo@10:U" "i@22:N" 62 84 "j@25:U" "bar@39:U" "x@51:U" "y@54:I" 72
"z@60:U"))
-
-(js2-deftest-classify-variables prop-get-initialized
- "function foo () { var x, y={}; y.a=x; }"
- '("foo@10:U" "x@23:N" 36 "y@26:I" 32))
-
-(js2-deftest-classify-variables prop-get-uninitialized
- "function foo () { var x; if(x.foo) alert('boom'); }"
- '("foo@10:U" "x@23:N" 29))
-
-(js2-deftest-classify-variables prop-get-function-assignment
- "(function(w) { w.f = function() { var a=42, m; return a; }; })(window);"
- '("w@11:P" 16 "a@39:I" 55 "m@45:U"))
-
-(js2-deftest-classify-variables let-declaration
- "function foo () { let x,y=1; return x; }"
- '("foo@10:U" "x@23:N" 37 "y@25:U"))
-
-(js2-deftest-classify-variables external-function-call
- "function foo (m) { console.log(m, arguments); }"
- '("foo@10:U" "m@15:P" 32))
-
-(js2-deftest-classify-variables global-function-call
- "function bar () { return 42; } function foo (a) { return bar(); }"
- '("bar@10:I" 58 "foo@41:U" "a@46:P"))
-
-(js2-deftest-classify-variables let-declaration-for-scope
- "function foo () { for(let x=1,y; x<y; y++) {} }"
- '("foo@10:U" "x@27:I" 34 "y@31:N" 36 39))
-
-(js2-deftest-classify-variables arguments-implicit-var
- "function foo () { var p; for(p in arguments) { return p; } }"
- '("foo@10:U" "p@23:I" 55))
-
-(js2-deftest-classify-variables catch-error-variable
- "function foo () { try { throw 'Foo'; } catch (e) { console.log(e); }"
- '("foo@10:U" "e@47:I" 64))
-
-(js2-deftest-classify-variables prop-get-assignment
- "function foo () { var y,x={y:{z:{}}}; x.y.z=42; }"
- '("foo@10:U" "y@23:U" "x@25:I" 39))
-
-(js2-deftest-classify-variables unused-function-argument
- "function foo (a) { return 42; }"
- '("foo@10:U" "a@15:P"))
-
-(js2-deftest-classify-variables used-function-argument
- "function foo (a) { a=42; return a; }"
- '("foo@10:U" "a@15:P" 33))
-
-(js2-deftest-classify-variables prop-get
- "function foo (a) { a=navigator.x||navigator.y; return a; }"
- '("foo@10:U" "a@15:P" 55))
-
-(js2-deftest-classify-variables for-in-loop
- "function foo () { var d={}; for(var k in d) {var v=d[k]; } }"
- '("foo@10:U" "d@23:I" 42 52 "k@37:I" 54 "v@50:U"))
-
-(js2-deftest-classify-variables array-comprehension-legacy
- "function foo() { var j,a=[for (i of [1,2,3]) i*j]; }"
- '("foo@10:U" "j@22:N" 48 "a@24:U" "i@32:I" 46))
-
-(js2-deftest-classify-variables array-comprehension
- "function foo() { var j,a=[[i,j] for (i of [1,2,3])]; }"
- '("foo@10:U" "j@22:N" 30 "a@24:U" "i@38:I" 28))
-
-(js2-deftest-classify-variables return-named-function
- "function foo() { var a=42; return function bar() { return a; }; }"
- '("foo@10:U" "a@22:I" 59 "bar@44:U"))
-
-(js2-deftest-classify-variables named-wrapper-function
- "function foo() { var a; (function bar() { a=42; })(); return a; }"
- '("foo@10:U" "a@22:I" 62 "bar@35:I" 35))
-
-(js2-deftest-classify-variables destructure-array
- "function foo(x,y) { let [u,v] = [x,y]; }"
- '("foo@10:U" "x@14:P" 34 "y@16:P" 36 "u@26:U" "v@28:U"))
-
-(js2-deftest-classify-variables destructure-object
- "function foo(x,y) { var {p: [, w], q: z} = {p: [x, 2, 3], q: y}; }"
- '("foo@10:U" "x@14:P" 49 "y@16:P" 62 "w@32:U" "z@39:U"))
-
-(js2-deftest-classify-variables destructure-object-shorthand
- "function foo(x,y) { var {p, q} = {p: x, q: y}; }"
- '("foo@10:U" "x@14:P" 38 "y@16:P" 44 "p@26:U" "q@29:U"))
-
-(js2-deftest-classify-variables destructure-object-mixed
- "function foo() { let {a, b, c = 3} = {a: 1, b: 2}; }"
- '("foo@10:U" "a@23:U" "b@26:U" "c@29:U"))
-
-(js2-deftest-classify-variables destructure-object-missing
- "function foo() { let {foo: missing = 10} = {}; }"
- '("foo@10:U" "missing@28:U"))
-
-(js2-deftest-classify-variables import-unused
- "import foo from 'module';"
- '("foo@8:U"))
-
-(js2-deftest-classify-variables named-import-unused
- "import foo as bar from 'module';"
- '("bar@15:U"))
-
-(js2-deftest-classify-variables import-unused-many
- "import {a,b} from 'module';"
- '("a@9:U" "b@11:U"))
-
-(js2-deftest-classify-variables named-import-unused-many
- "import {a as b, c as d} from 'module';"
- '("b@14:U" "d@22:U"))
-
-(js2-deftest-classify-variables import-export
- "import foo from 'module'; export {foo}"
- '("foo@8:I" 35))
-
-(js2-deftest-classify-variables import-namespace-unused
- "import * as foo from 'module';"
- '("foo@13:U"))
-
-(js2-deftest-classify-variables import-namespace-used
- "import * as foo from 'module'; function bar() { return foo.x; }"
- '("foo@13:I" 56 "bar@41:U"))
-
-;; Side effects
-
-(js2-deftest no-side-effects-at-top-level
- "var x; x.foo;"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
-
-(js2-deftest getprop-has-no-side-effects
- "function f() { this.x; }"
- (js2-mode--and-parse)
- (should (equal "msg.no.side.effects"
- (car (caar js2-parsed-warnings)))))
-
-(js2-deftest getprop-has-side-effects-option
- "function f() { this.x; }"
- (let ((js2-getprop-has-side-effects t))
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings))))
-
-(js2-deftest arithmetic-has-no-side-effects
- "function f() { 1 + 2; }"
- (js2-mode--and-parse)
- (should (equal "msg.no.side.effects"
- (car (caar js2-parsed-warnings)))))
-
-(js2-deftest instanceof-has-no-side-effects
- "function f() { this instanceof f; }"
- (js2-mode--and-parse)
- (should (equal "msg.no.side.effects"
- (car (caar js2-parsed-warnings)))))
-
-(js2-deftest instanceof-has-side-effects-option
- "function f() { this instanceof f; }"
- (let ((js2-instanceof-has-side-effects t))
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings))))
-
-(js2-deftest await-has-side-effects
- "const p = new Promise();\nasync function f() { await p; return null; }"
- (js2-mode--and-parse)
- (should (null js2-parsed-warnings)))
diff --git a/packages/math-symbol-lists/.dir-locals.el
b/packages/math-symbol-lists/.dir-locals.el
deleted file mode 100644
index 064a938..0000000
--- a/packages/math-symbol-lists/.dir-locals.el
+++ /dev/null
@@ -1,3 +0,0 @@
-
-((emacs-lisp-mode
- (indent-tabs-mode)))
diff --git a/packages/math-symbol-lists/.gitignore
b/packages/math-symbol-lists/.gitignore
deleted file mode 100644
index 10facf0..0000000
--- a/packages/math-symbol-lists/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# Compiled
-*.elc
-# Packaging
-.cask
-data/
\ No newline at end of file
diff --git a/packages/math-symbol-lists/math-symbol-lists.el
b/packages/math-symbol-lists/math-symbol-lists.el
deleted file mode 100644
index d8fe041..0000000
--- a/packages/math-symbol-lists/math-symbol-lists.el
+++ /dev/null
@@ -1,3700 +0,0 @@
-;;; math-symbol-lists.el --- Lists of Unicode math symbols and latex commands
-*- lexical-binding:t -*-
-;;
-;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
-;; Author: Vitalie Spinu <spinuvit@gmail.com>
-;; URL: https://github.com/vspinu/math-symbol-lists
-;; Keywords: Unicode, symbols, mathematics
-;; Package-Type: simple
-;; Version: 1.2.1
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; This file is 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. If not, see <https://www.gnu.org/licenses/>.
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-;;
-;; This is a "storage" package used by completion engines such as
-;; `company-math.el` and `ac-math.el`.
-;;
-;; Defined (a)lists are:
-;;
-;; `math-symbol-list-basic`
-;; `math-symbol-list-extended`
-;; `math-symbol-list-packages`
-;; `math-symbol-list-latex-commands`
-;; `math-symbol-list-subscripts`
-;; `math-symbol-list-superscripts`
-;;
-;; Sources:
-;;
-;; [1] http://milde.users.sourceforge.net/LUCR/Math/
-;; [2] https://github.com/wspr/unicode-math/blob/master/unicode-math-table.tex
-;; [3] http://milde.users.sourceforge.net/LUCR/Math/data/unimathsymbols.txt
-;; [4] M-x describe-input-method TeX
-;; [5] `LaTeX-math-default' in AucTeX package
-;; [6] LaTeX 2 unicode: https://www.cl.cam.ac.uk/%7Emgk25/ucs/examples/TeX.txt
-;; [7] W3C math WG: https://www.w3.org/2003/entities/2007xml/unicode.xml
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Code:
-
-
-;;; SYMBOLS
-
-(defconst math-symbol-list-latex-commands
- '("address" "addtocounter" "addtolength" "addvspace" "Alph" "alph" "Alph
- example" "alsoname" "and for author" "appendix" "arabic" "arraycolsep"
- "arrayrulewidth" "arraystretch" "baselineskip"
- "baselinestretch" "begin" "bf" "bfseries" "bibitem" "bibliography"
- "bibliographystyle" "bigskip" "bigskipamount" "bmod" "boldmath"
- "bottomfraction" "cal" "caption" "cc" "centering"
- "chapter" "circle" "cite" "cleardoublepage" "clearpage" "cline" "closing"
- "columnsep" "columnseprule" "columnwidth" "contentsline" "copyright"
- "dag" "dashbox" "day" "dblfloatpagefraction"
- "dblfloatsep" "dbltextfloatsep" "dbltopfraction" "ddag" "depth"
- "displaystyle" "documentclass" "dotfill" "doublerulesep" "emph" "encl"
- "enlargethispage" "enumi" "enumii" "enumiii" "enumiv" "evensidemargin"
- "fbox" "fboxrule" "fboxsep" "fill" "floatpagefraction" "floatsep"
- "flushbottom" "fnsymbol" "fontencoding" "fontfamily" "fontseries"
- "fontshape" "fontsize" "footnote" "footnotemark" "footnoterule"
- "footnotesep" "footnotesize" "footnotetext" "footskip" "frame" "framebox"
- "fussy" "gets" "glossary" "glossaryentry"
- "headheight" "headsep" "height" "hfill" "hline" "hrulefill" "hspace"
- "Huge" "huge" "hyphenation" "iff" "include" "includeonly"
- "indent" "index" "indexentry" "input" "intextsep"
- "item" "itemindent" "itemsep" "itshape" "kill"
- "label" "labelenumi" "labelenumii" "labelenumiii" "labelenumiv"
- "labelitemi" "labelitemii" "labelitemiii" "labelitemiv" "labelsep"
- "labelwidth" "land" "LARGE" "Large" "large" "LaTeX" "le" "left" "leadsto"
- "lefteqn" "leftmargin" "leftmargini" "leftmarginii" "leftmarginiii"
- "leftmarginiv" "leftmarginv" "leftmarginvi" "line" "linebreak"
- "linethickness" "linewidth" "listoffigures" "listoftables" "listparindent"
- "lnot" "location" "lor" "lq" "makebox" "makebox " "makeglossary"
- "makeindex" "makelabels" "maketitle" "marginpar" "marginparpush"
- "marginparsep" "marginparwidth" "mathbf" "mathcal" "mathnormal" "mathrm"
- "mathsf" "mathtt" "mathversion" "mbox" "mdseries" "medskip"
- "medskipamount" "month" "multicolumn" "multiput" "name" "newcommand"
- "newcounter" "newenvironment" "newfont" "newlength" "NEWLINE" "newline"
- "newpage" "newsavebox" "newtheorem" "nocite" "nofiles" "noindent"
- "nolinebreak" "nonumber" "nopagebreak" "normalfont" "normalmarginpar"
- "normalsize" "oe" "onecolumn" "opening" "oval" "owns" "P" "pagebreak"
"pagenumbering"
- "pageref" "pagestyle" "paragraph" "parbox" "parindent"
- "parsep" "parskip" "parskip example" "part" "partopsep" "pmod" "poptabs"
- "pounds" "protect" "ps" "pushtabs" "put" "raggedbottom" "raggedleft"
- "raggedright" "raisebox" "ref" "refstepcounter" "renewenvironment"
- "restorecr" "reversemarginpar" "right" "rightmargin" "rm" "rmfamily"
- "roman" "rq" "rule" "savebox" "sbox" "sc" "scriptsize" "scshape"
- "section" "seename" "selectfont" "setcounter" "setlength" "settodepth"
- "settoheight" "settowidth" "sf" "sffamily" "shortstack" "signature" "sl"
- "slshape" "small" "smallint" "smallskip" "smallskipamount" "SPACE" "ss"
- "startbreaks" "stepcounter" "stop" "stopbreaks" "subparagraph"
- "subsection" "subsubsection" "symbol" "TAB"
- "tabbingsep" "tabcolsep" "tableofcontents" "telephone" "TeX" "textbf"
- "textfloatsep" "textfraction" "textheight" "textit" "textmd" "textnormal"
- "textrm" "textsc" "textsf" "textsl" "texttt" "textup" "textwidth"
- "thicklines" "thinlines" "thinspace" "thispagestyle" "tiny" "to" "today"
- "topfraction" "topmargin" "topsep" "topskip" "totalheight" "tt" "ttfamily"
- "twocolumn" "typein" "typeout" "u " "unboldmath"
- "unitlength" "upshape" "usebox" "usecounter" "usefont" "usepackage"
- "value" "vector" "verb" "vert" "vfill" "vline" "vspace"
- "width" "year")
- "List of the latex commands.")
-
-(defconst math-symbol-list-basic
- '(("accent" "\\acute" #X301)
- ("accent" "\\bar" #X304)
- ("accent" "\\breve" #X306)
- ("accent" "\\check" #X30C)
- ("accent" "\\ddot" #X308)
- ("accent" "\\dot" #X307)
- ("accent" "\\grave" #X300)
- ("accent" "\\hat" #X302)
- ("accent" "\\tilde" #X303)
- ("accent" "\\vec" #X20D7)
- ("arrow" "\\Downarrow" #X21D3)
- ("arrow" "\\Leftarrow" #X21D0)
- ("arrow" "\\Leftrightarrow" #X21D4)
- ("arrow" "\\Longleftarrow" #X27F8)
- ("arrow" "\\Longleftrightarrow" #X27FA)
- ("arrow" "\\Longrightarrow" #X27F9)
- ("arrow" "\\Rightarrow" #X21D2)
- ("arrow" "\\Uparrow" #X21D1)
- ("arrow" "\\Updownarrow" #X21D5)
- ("arrow" "\\downarrow" #X2193)
- ("arrow" "\\hookleftarrow" #X21A9)
- ("arrow" "\\hookrightarrow" #X21AA)
- ("arrow" "\\leftarrow" #X2190)
- ("arrow" "\\leftharpoondown" #X21BD)
- ("arrow" "\\leftharpoonup" #X21BC)
- ("arrow" "\\leftrightarrow" #X2194)
- ("arrow" "\\longleftarrow" #X27F5)
- ("arrow" "\\longleftrightarrow" #X27F7)
- ("arrow" "\\longmapsto" #X27FC)
- ("arrow" "\\longrightarrow" #X27F6)
- ("arrow" "\\mapsto" #X21A6)
- ("arrow" "\\nearrow" #X2197)
- ("arrow" "\\nwarrow" #X2196)
- ("arrow" "\\rightarrow" #X2192)
- ("arrow" "\\rightharpoondown" #X21C1)
- ("arrow" "\\rightharpoonup" #X21C0)
- ("arrow" "\\searrow" #X2198)
- ("arrow" "\\swarrow" #X2199)
- ("arrow" "\\uparrow" #X2191)
- ("arrow" "\\updownarrow" #X2195)
- ("bin" "\\amalg" #X2A3F)
- ("bin" "\\ast" #X2217)
- ("bin" "\\bigcirc" #X25CB)
- ("bin" "\\bigtriangledown" #X25BD)
- ("bin" "\\bigtriangleup" #X25B3)
- ("bin" "\\bullet" #X2219)
- ("bin" "\\cap" #X2229)
- ("bin" "\\cdot" #X22C5)
- ("bin" "\\circ" #X2218)
- ("bin" "\\cup" #X222A)
- ("bin" "\\dagger" #X2020)
- ("bin" "\\ddagger" #X2021)
- ("bin" "\\diamond" #X22C4)
- ("bin" "\\div" #XF7)
- ("bin" "\\lhd")
- ("bin" "\\mp" #X2213)
- ("bin" "\\odot" #X2299)
- ("bin" "\\ominus" #X2296)
- ("bin" "\\oplus" #X2295)
- ("bin" "\\oslash" #X2205)
- ("bin" "\\otimes" #X2297)
- ("bin" "\\pm" #XB1)
- ("bin" "\\rhd")
- ("bin" "\\setminus" #X2216)
- ("bin" "\\sqcap" #X2293)
- ("bin" "\\star" #X22C6)
- ("bin" "\\times" #XD7)
- ("bin" "\\triangleleft" #X25C1)
- ("bin" "\\triangleright" #X25B7)
- ("bin" "\\unlhd")
- ("bin" "\\unrhd")
- ("bin" "\\uplus" #X228E)
- ("bin" "\\vee" #X2228)
- ("bin" "\\wedge" #X2227)
- ("bin" "\\wr" #X2240)
- ("constr" "\\frac")
- ("constr" "\\overbrace" #XFE37)
- ("constr" "\\overleftarrow" #X20D6)
- ("constr" "\\overline")
- ("constr" "\\overrightarrow")
- ("constr" "\\sqrt" #X221A)
- ("constr" "\\underbrace" #XFE38)
- ("constr" "\\underline")
- ("constr" "\\widehat" #X302)
- ("constr" "\\widetilde" #X303)
- ("delim" "\\Arrowvert")
- ("delim" "\\arrowvert")
- ("delim" "\\backslash" #X5C)
- ("delim" "\\bracevert")
- ("delim" "\\langle" #X27E8)
- ("delim" "\\lceil" #X2308)
- ("delim" "\\lfloor" #X230A)
- ("delim" "\\lgroup")
- ("delim" "\\lmoustache" #X23B0)
- ("delim" "\\rangle" #X27E9)
- ("delim" "\\rceil" #X2309)
- ("delim" "\\rfloor" #X230B)
- ("delim" "\\rgroup")
- ("delim" "\\rmoustache" #X23B1)
- ("delim" "\\{")
- ("delim" "\\|")
- ("delim" "\\}")
- ("greek" "\\alpha" #X3B1)
- ("greek" "\\beta" #X3B2)
- ("greek" "\\chi" #X3C7)
- ("greek" "\\delta" #X3B4)
- ("greek" "\\epsilon" #X3F5)
- ("greek" "\\eta" #X3B7)
- ("greek" "\\gamma" #X3B3)
- ("greek" "\\iota" #X3B9)
- ("greek" "\\kappa" #X3BA)
- ("greek" "\\lambda" #X3BB)
- ("greek" "\\mu" #X3BC)
- ("greek" "\\nu" #X3BD)
- ("greek" "\\omega" #X3C9)
- ("greek" "\\phi" #X3D5)
- ("greek" "\\pi" #X3C0)
- ("greek" "\\psi" #X3C8)
- ("greek" "\\rho" #X3C1)
- ("greek" "\\sigma" #X3C3)
- ("greek" "\\tau" #X3C4)
- ("greek" "\\theta" #X3B8)
- ("greek" "\\upsilon" #X3C5)
- ("greek" "\\varepsilon" #X3B5)
- ("greek" "\\varphi" #X3C6)
- ("greek" "\\varpi" #X3D6)
- ("greek" "\\varrho" #X3F1)
- ("greek" "\\varsigma" #X3C2)
- ("greek" "\\vartheta" #X3D1)
- ("greek" "\\xi" #X3BE)
- ("greek" "\\zeta" #X3B6)
- ("Greek" "\\Delta" #X394)
- ("Greek" "\\Gamma" #X393)
- ("Greek" "\\Lambda" #X39B)
- ("Greek" "\\Omega" #X3A9)
- ("Greek" "\\Phi" #X3A6)
- ("Greek" "\\Pi" #X3A0)
- ("Greek" "\\Psi" #X3A8)
- ("Greek" "\\Sigma" #X3A3)
- ("Greek" "\\Theta" #X398)
- ("Greek" "\\Upsilon" #X3D2)
- ("Greek" "\\Xi" #X39E)
- ("misc" "\\Im" #X2111)
- ("misc" "\\Re" #X211C)
- ("misc" "\\aleph" #X2135)
- ("misc" "\\angle" #X2220)
- ("misc" "\\bot" #X22A5)
- ("misc" "\\clubsuit" #X2663)
- ("misc" "\\diamondsuit" #X2662)
- ("misc" "\\ell" #X2113)
- ("misc" "\\emptyset" #X2205)
- ("misc" "\\exists" #X2203)
- ("misc" "\\flat" #X266D)
- ("misc" "\\forall" #X2200)
- ("misc" "\\hbar" #X210F)
- ("misc" "\\heartsuit" #X2661)
- ("misc" "\\imath" #X131)
- ("misc" "\\infty" #X221E)
- ("misc" "\\jmath" #X1D6A5)
- ("misc" "\\mho" #X2127)
- ("misc" "\\nabla" #X2207)
- ("misc" "\\natural" #X266E)
- ("misc" "\\neg" #XAC)
- ("misc" "\\not" #X338)
- ("misc" "\\partial" #X2202)
- ("misc" "\\prime" #X2032)
- ("misc" "\\sharp" #X266F)
- ("misc" "\\spadesuit" #X2660)
- ("misc" "\\surd" #X221A)
- ("misc" "\\top" #X22A4)
- ("misc" "\\triangle" #X25B3)
- ("misc" "\\wp" #X2118)
- ("nonsymb" "\\Box")
- ("nonsymb" "\\Diamond")
- ("nonsymb" "\\Pr")
- ("nonsymb" "\\arccos")
- ("nonsymb" "\\arcsin")
- ("nonsymb" "\\arctan")
- ("nonsymb" "\\arg")
- ("nonsymb" "\\cos")
- ("nonsymb" "\\cosh")
- ("nonsymb" "\\cot")
- ("nonsymb" "\\coth")
- ("nonsymb" "\\csc")
- ("nonsymb" "\\deg")
- ("nonsymb" "\\det")
- ("nonsymb" "\\dim")
- ("nonsymb" "\\exp")
- ("nonsymb" "\\gcd")
- ("nonsymb" "\\hom")
- ("nonsymb" "\\inf")
- ("nonsymb" "\\ker")
- ("nonsymb" "\\lg")
- ("nonsymb" "\\lim")
- ("nonsymb" "\\liminf")
- ("nonsymb" "\\limsup")
- ("nonsymb" "\\ln")
- ("nonsymb" "\\log")
- ("nonsymb" "\\max")
- ("nonsymb" "\\min")
- ("nonsymb" "\\sec")
- ("nonsymb" "\\sin")
- ("nonsymb" "\\sinh")
- ("nonsymb" "\\sup")
- ("nonsymb" "\\tan")
- ("nonsymb" "\\tanh")
- ("punct" "\\cdots" #X22EF)
- ("punct" "\\colon" #X3A)
- ("punct" "\\ddots" #X22F1)
- ("punct" "\\ldots" #X2026)
- ("punct" "\\vdots" #X22EE)
- ("rel" "\\Join" #X2A1D)
- ("rel" "\\approx" #X2248)
- ("rel" "\\asymp" #X224D)
- ("rel" "\\bowtie" #X22C8)
- ("rel" "\\cong" #X2245)
- ("rel" "\\dashv" #X22A3)
- ("rel" "\\doteq" #X2250)
- ("rel" "\\equiv" #X2261)
- ("rel" "\\frown" #X2322)
- ("rel" "\\geq" #X2265)
- ("rel" "\\gg" #X226B)
- ("rel" "\\in" #X2208)
- ("rel" "\\leq" #X2264)
- ("rel" "\\ll" #X226A)
- ("rel" "\\mid" #X2223)
- ("rel" "\\models" #X22A7)
- ("rel" "\\neq" #X2260)
- ("rel" "\\ni" #X220B)
- ("rel" "\\parallel" #X2225)
- ("rel" "\\perp" #X27C2)
- ("rel" "\\prec" #X227A)
- ("rel" "\\preceq" #X2AAF)
- ("rel" "\\propto" #X221D)
- ("rel" "\\qed" #X220E)
- ("rel" "\\sim" #X223C)
- ("rel" "\\simeq" #X2243)
- ("rel" "\\smile" #X2323)
- ("rel" "\\sqsubset" #X228F)
- ("rel" "\\sqsubseteq" #X2291)
- ("rel" "\\sqsupset" #X2290)
- ("rel" "\\sqsupseteq" #X2292)
- ("rel" "\\subset" #X2282)
- ("rel" "\\subseteq" #X2286)
- ("rel" "\\succ" #X227B)
- ("rel" "\\succeq" #X2AB0)
- ("rel" "\\supset" #X2283)
- ("rel" "\\supseteq" #X2287)
- ("rel" "\\vdash" #X22A2)
- ("var" "\\bigcap" #X22C2)
- ("var" "\\bigcup" #X22C3)
- ("var" "\\bigodot" #X2A00)
- ("var" "\\bigoplus" #X2A01)
- ("var" "\\bigotimes" #X2A02)
- ("var" "\\bigsqcup" #X2A06)
- ("var" "\\biguplus" #X2A04)
- ("var" "\\bigvee" #X22C1)
- ("var" "\\bigwedge" #X22C0)
- ("var" "\\coprod" #X2210)
- ("var" "\\int" #X222B)
- ("var" "\\oint" #X222E)
- ("var" "\\prod" #X220F)
- ("var" "\\sum" #X2211)
- ;; extra aliases retrieved from LUCR
- ("bin" "\\land" 8743 "∧")
- ("bin" "\\lor" 8744 "∨")
- ("close" "\\rbrace" 125 "}")
- ("fence" "\\vert" 124 "|")
- ("fence" "\\Vert" 8214 "‖")
- ("open" "\\lbrace" 123 "{")
- ("ord" "\\mathdollar" 36 "$")
- ("ord" "\\lnot" 172 "¬")
- ("rel" "\\gets" 8592 "←")
- ("rel" "\\to" 8594 "→")
- ("rel" "\\owns" 8715 "∋")
- ("rel" "\\ne" 8800 "≠")
- ("rel" "\\le" 8804 "≤")
- ("rel" "\\ge" 8805 "≥")
- ;; manually added
- ("misc" "\\P" 182 "¶")
- ("misc" "\\textpilcrow" 182 "¶"))
- "List of basic LaTeX mathematical symbols.
-This list maps standard LaTeX math commands to unicode
-characters. For some symbols in this list the unicode code is
-missing. It is an extension of `LaTeX-math-default' in
-AucTeX/latex.el, but it doesn't include AMS symbols. See also
-`math-symbol-list-extended' and `math-symbol-list-packages'.")
-
-(defconst math-symbol-list-extended
- '(("mathaccent" "\\acute" 769 "́")
- ("mathaccent" "\\annuity" 8423 "⃧")
- ("mathaccent" "\\asteraccent" 8432 "⃰")
- ("mathaccent" "\\bar" 772 "̄")
- ("mathaccent" "\\breve" 774 "̆")
- ("mathaccent" "\\candra" 784 "̐")
- ("mathaccent" "\\check" 780 "̌")
- ("mathaccent" "\\ddddot" 8412 "⃜")
- ("mathaccent" "\\dddot" 8411 "⃛")
- ("mathaccent" "\\ddot" 776 "̈")
- ("mathaccent" "\\dot" 775 "̇")
- ("mathaccent" "\\droang" 794 "̚")
- ("mathaccent" "\\enclosecircle" 8413 "⃝")
- ("mathaccent" "\\enclosediamond" 8415 "⃟")
- ("mathaccent" "\\enclosesquare" 8414 "⃞")
- ("mathaccent" "\\enclosetriangle" 8420 "⃤")
- ("mathaccent" "\\grave" 768 "̀")
- ("mathaccent" "\\hat" 770 "̂")
- ("mathaccent" "\\leftharpoonaccent" 8400 "⃐")
- ("mathaccent" "\\not" 824 "̸")
- ("mathaccent" "\\ocirc" 778 "̊")
- ("mathaccent" "\\ocommatopright" 789 "̕")
- ("mathaccent" "\\oturnedcomma" 786 "̒")
- ("mathaccent" "\\overbar" 773 "̅")
- ("mathaccent" "\\overleftarrow" 8406 "⃖")
- ("mathaccent" "\\overleftrightarrow" 8417 "⃡")
- ("mathaccent" "\\ovhook" 777 "̉")
- ("mathaccent" "\\rightharpoonaccent" 8401 "⃑")
- ("mathaccent" "\\threeunderdot" 8424 "⃨")
- ("mathaccent" "\\tilde" 771 "̃")
- ("mathaccent" "\\underbar" 817 "̱")
- ("mathaccent" "\\underleftarrow" 8430 "⃮")
- ("mathaccent" "\\underleftharpoondown" 8429 "⃭")
- ("mathaccent" "\\underrightarrow" 8431 "⃯")
- ("mathaccent" "\\underrightharpoondown" 8428 "⃬")
- ("mathaccent" "\\vec" 8407 "⃗")
- ("mathaccent" "\\vertoverlay" 8402 "⃒")
- ("mathaccent" "\\widebridgeabove" 8425 "⃩")
- ("mathaccent" "\\wideutilde" 816 "̰")
- ("mathalpha" "\\Angstrom" 8491 "Å")
- ("mathalpha" "\\BbbA" 120120 "𝔸")
- ("mathalpha" "\\BbbB" 120121 "𝔹")
- ("mathalpha" "\\BbbC" 8450 "ℂ")
- ("mathalpha" "\\BbbD" 120123 "𝔻")
- ("mathalpha" "\\BbbE" 120124 "𝔼")
- ("mathalpha" "\\BbbF" 120125 "𝔽")
- ("mathalpha" "\\BbbG" 120126 "𝔾")
- ("mathalpha" "\\BbbGamma" 8510 "ℾ")
- ("mathalpha" "\\BbbH" 8461 "ℍ")
- ("mathalpha" "\\BbbI" 120128 "𝕀")
- ("mathalpha" "\\BbbJ" 120129 "𝕁")
- ("mathalpha" "\\BbbK" 120130 "𝕂")
- ("mathalpha" "\\BbbL" 120131 "𝕃")
- ("mathalpha" "\\BbbM" 120132 "𝕄")
- ("mathalpha" "\\BbbN" 8469 "ℕ")
- ("mathalpha" "\\BbbO" 120134 "𝕆")
- ("mathalpha" "\\BbbP" 8473 "ℙ")
- ("mathalpha" "\\BbbPi" 8511 "ℿ")
- ("mathalpha" "\\BbbQ" 8474 "ℚ")
- ("mathalpha" "\\BbbR" 8477 "ℝ")
- ("mathalpha" "\\BbbS" 120138 "𝕊")
- ("mathalpha" "\\BbbT" 120139 "𝕋")
- ("mathalpha" "\\BbbU" 120140 "𝕌")
- ("mathalpha" "\\BbbV" 120141 "𝕍")
- ("mathalpha" "\\BbbW" 120142 "𝕎")
- ("mathalpha" "\\BbbX" 120143 "𝕏")
- ("mathalpha" "\\BbbY" 120144 "𝕐")
- ("mathalpha" "\\BbbZ" 8484 "ℤ")
- ("mathalpha" "\\Bbba" 120146 "𝕒")
- ("mathalpha" "\\Bbbb" 120147 "𝕓")
- ("mathalpha" "\\Bbbc" 120148 "𝕔")
- ("mathalpha" "\\Bbbd" 120149 "𝕕")
- ("mathalpha" "\\Bbbe" 120150 "𝕖")
- ("mathalpha" "\\Bbbf" 120151 "𝕗")
- ("mathalpha" "\\Bbbg" 120152 "𝕘")
- ("mathalpha" "\\Bbbgamma" 8509 "ℽ")
- ("mathalpha" "\\Bbbh" 120153 "𝕙")
- ("mathalpha" "\\Bbbi" 120154 "𝕚")
- ("mathalpha" "\\Bbbj" 120155 "𝕛")
- ("mathalpha" "\\Bbbk" 120156 "𝕜")
- ("mathalpha" "\\Bbbl" 120157 "𝕝")
- ("mathalpha" "\\Bbbm" 120158 "𝕞")
- ("mathalpha" "\\Bbbn" 120159 "𝕟")
- ("mathalpha" "\\Bbbo" 120160 "𝕠")
- ("mathalpha" "\\Bbbp" 120161 "𝕡")
- ("mathalpha" "\\Bbbq" 120162 "𝕢")
- ("mathalpha" "\\Bbbr" 120163 "𝕣")
- ("mathalpha" "\\Bbbs" 120164 "𝕤")
- ("mathalpha" "\\Bbbt" 120165 "𝕥")
- ("mathalpha" "\\Bbbu" 120166 "𝕦")
- ("mathalpha" "\\Bbbv" 120167 "𝕧")
- ("mathalpha" "\\Bbbw" 120168 "𝕨")
- ("mathalpha" "\\Bbbx" 120169 "𝕩")
- ("mathalpha" "\\Bbby" 120170 "𝕪")
- ("mathalpha" "\\Bbbz" 120171 "𝕫")
- ("mathalpha" "\\Im" 8465 "ℑ")
- ("mathalpha" "\\Re" 8476 "ℜ")
- ("mathalpha" "\\aleph" 8501 "ℵ")
- ("mathalpha" "\\beth" 8502 "ℶ")
- ("mathalpha" "\\daleth" 8504 "ℸ")
- ("mathalpha" "\\ell" 8467 "ℓ")
- ("mathalpha" "\\gimel" 8503 "ℷ")
- ("mathalpha" "\\hslash" 8463 "ℏ")
- ("mathalpha" "\\imath" 120484 "𝚤")
- ("mathalpha" "\\jmath" 120485 "𝚥")
- ("mathalpha" "\\matheth" 240 "ð")
- ("mathalpha" "\\mbfA" 119808 "𝐀")
- ("mathalpha" "\\mbfAlpha" 120488 "𝚨")
- ("mathalpha" "\\mbfB" 119809 "𝐁")
- ("mathalpha" "\\mbfBeta" 120489 "𝚩")
- ("mathalpha" "\\mbfC" 119810 "𝐂")
- ("mathalpha" "\\mbfChi" 120510 "𝚾")
- ("mathalpha" "\\mbfD" 119811 "𝐃")
- ("mathalpha" "\\mbfDelta" 120491 "𝚫")
- ("mathalpha" "\\mbfDigamma" 120778 "𝟊")
- ("mathalpha" "\\mbfE" 119812 "𝐄")
- ("mathalpha" "\\mbfEpsilon" 120492 "𝚬")
- ("mathalpha" "\\mbfEta" 120494 "𝚮")
- ("mathalpha" "\\mbfF" 119813 "𝐅")
- ("mathalpha" "\\mbfG" 119814 "𝐆")
- ("mathalpha" "\\mbfGamma" 120490 "𝚪")
- ("mathalpha" "\\mbfH" 119815 "𝐇")
- ("mathalpha" "\\mbfI" 119816 "𝐈")
- ("mathalpha" "\\mbfIota" 120496 "𝚰")
- ("mathalpha" "\\mbfJ" 119817 "𝐉")
- ("mathalpha" "\\mbfK" 119818 "𝐊")
- ("mathalpha" "\\mbfKappa" 120497 "𝚱")
- ("mathalpha" "\\mbfL" 119819 "𝐋")
- ("mathalpha" "\\mbfLambda" 120498 "𝚲")
- ("mathalpha" "\\mbfM" 119820 "𝐌")
- ("mathalpha" "\\mbfMu" 120499 "𝚳")
- ("mathalpha" "\\mbfN" 119821 "𝐍")
- ("mathalpha" "\\mbfNu" 120500 "𝚴")
- ("mathalpha" "\\mbfO" 119822 "𝐎")
- ("mathalpha" "\\mbfOmega" 120512 "𝛀")
- ("mathalpha" "\\mbfOmicron" 120502 "𝚶")
- ("mathalpha" "\\mbfP" 119823 "𝐏")
- ("mathalpha" "\\mbfPhi" 120509 "𝚽")
- ("mathalpha" "\\mbfPi" 120503 "𝚷")
- ("mathalpha" "\\mbfPsi" 120511 "𝚿")
- ("mathalpha" "\\mbfQ" 119824 "𝐐")
- ("mathalpha" "\\mbfR" 119825 "𝐑")
- ("mathalpha" "\\mbfRho" 120504 "𝚸")
- ("mathalpha" "\\mbfS" 119826 "𝐒")
- ("mathalpha" "\\mbfSigma" 120506 "𝚺")
- ("mathalpha" "\\mbfT" 119827 "𝐓")
- ("mathalpha" "\\mbfTau" 120507 "𝚻")
- ("mathalpha" "\\mbfTheta" 120495 "𝚯")
- ("mathalpha" "\\mbfU" 119828 "𝐔")
- ("mathalpha" "\\mbfUpsilon" 120508 "𝚼")
- ("mathalpha" "\\mbfV" 119829 "𝐕")
- ("mathalpha" "\\mbfW" 119830 "𝐖")
- ("mathalpha" "\\mbfX" 119831 "𝐗")
- ("mathalpha" "\\mbfXi" 120501 "𝚵")
- ("mathalpha" "\\mbfY" 119832 "𝐘")
- ("mathalpha" "\\mbfZ" 119833 "𝐙")
- ("mathalpha" "\\mbfZeta" 120493 "𝚭")
- ("mathalpha" "\\mbfa" 119834 "𝐚")
- ("mathalpha" "\\mbfalpha" 120514 "𝛂")
- ("mathalpha" "\\mbfb" 119835 "𝐛")
- ("mathalpha" "\\mbfbeta" 120515 "𝛃")
- ("mathalpha" "\\mbfc" 119836 "𝐜")
- ("mathalpha" "\\mbfchi" 120536 "𝛘")
- ("mathalpha" "\\mbfd" 119837 "𝐝")
- ("mathalpha" "\\mbfdelta" 120517 "𝛅")
- ("mathalpha" "\\mbfdigamma" 120779 "𝟋")
- ("mathalpha" "\\mbfe" 119838 "𝐞")
- ("mathalpha" "\\mbfepsilon" 120518 "𝛆")
- ("mathalpha" "\\mbfeta" 120520 "𝛈")
- ("mathalpha" "\\mbff" 119839 "𝐟")
- ("mathalpha" "\\mbffrakA" 120172 "𝕬")
- ("mathalpha" "\\mbffrakB" 120173 "𝕭")
- ("mathalpha" "\\mbffrakC" 120174 "𝕮")
- ("mathalpha" "\\mbffrakD" 120175 "𝕯")
- ("mathalpha" "\\mbffrakE" 120176 "𝕰")
- ("mathalpha" "\\mbffrakF" 120177 "𝕱")
- ("mathalpha" "\\mbffrakG" 120178 "𝕲")
- ("mathalpha" "\\mbffrakH" 120179 "𝕳")
- ("mathalpha" "\\mbffrakI" 120180 "𝕴")
- ("mathalpha" "\\mbffrakJ" 120181 "𝕵")
- ("mathalpha" "\\mbffrakK" 120182 "𝕶")
- ("mathalpha" "\\mbffrakL" 120183 "𝕷")
- ("mathalpha" "\\mbffrakM" 120184 "𝕸")
- ("mathalpha" "\\mbffrakN" 120185 "𝕹")
- ("mathalpha" "\\mbffrakO" 120186 "𝕺")
- ("mathalpha" "\\mbffrakP" 120187 "𝕻")
- ("mathalpha" "\\mbffrakQ" 120188 "𝕼")
- ("mathalpha" "\\mbffrakR" 120189 "𝕽")
- ("mathalpha" "\\mbffrakS" 120190 "𝕾")
- ("mathalpha" "\\mbffrakT" 120191 "𝕿")
- ("mathalpha" "\\mbffrakU" 120192 "𝖀")
- ("mathalpha" "\\mbffrakV" 120193 "𝖁")
- ("mathalpha" "\\mbffrakW" 120194 "𝖂")
- ("mathalpha" "\\mbffrakX" 120195 "𝖃")
- ("mathalpha" "\\mbffrakY" 120196 "𝖄")
- ("mathalpha" "\\mbffrakZ" 120197 "𝖅")
- ("mathalpha" "\\mbffraka" 120198 "𝖆")
- ("mathalpha" "\\mbffrakb" 120199 "𝖇")
- ("mathalpha" "\\mbffrakc" 120200 "𝖈")
- ("mathalpha" "\\mbffrakd" 120201 "𝖉")
- ("mathalpha" "\\mbffrake" 120202 "𝖊")
- ("mathalpha" "\\mbffrakf" 120203 "𝖋")
- ("mathalpha" "\\mbffrakg" 120204 "𝖌")
- ("mathalpha" "\\mbffrakh" 120205 "𝖍")
- ("mathalpha" "\\mbffraki" 120206 "𝖎")
- ("mathalpha" "\\mbffrakj" 120207 "𝖏")
- ("mathalpha" "\\mbffrakk" 120208 "𝖐")
- ("mathalpha" "\\mbffrakl" 120209 "𝖑")
- ("mathalpha" "\\mbffrakm" 120210 "𝖒")
- ("mathalpha" "\\mbffrakn" 120211 "𝖓")
- ("mathalpha" "\\mbffrako" 120212 "𝖔")
- ("mathalpha" "\\mbffrakp" 120213 "𝖕")
- ("mathalpha" "\\mbffrakq" 120214 "𝖖")
- ("mathalpha" "\\mbffrakr" 120215 "𝖗")
- ("mathalpha" "\\mbffraks" 120216 "𝖘")
- ("mathalpha" "\\mbffrakt" 120217 "𝖙")
- ("mathalpha" "\\mbffraku" 120218 "𝖚")
- ("mathalpha" "\\mbffrakv" 120219 "𝖛")
- ("mathalpha" "\\mbffrakw" 120220 "𝖜")
- ("mathalpha" "\\mbffrakx" 120221 "𝖝")
- ("mathalpha" "\\mbffraky" 120222 "𝖞")
- ("mathalpha" "\\mbffrakz" 120223 "𝖟")
- ("mathalpha" "\\mbfg" 119840 "𝐠")
- ("mathalpha" "\\mbfgamma" 120516 "𝛄")
- ("mathalpha" "\\mbfh" 119841 "𝐡")
- ("mathalpha" "\\mbfi" 119842 "𝐢")
- ("mathalpha" "\\mbfiota" 120522 "𝛊")
- ("mathalpha" "\\mbfitA" 119912 "𝑨")
- ("mathalpha" "\\mbfitAlpha" 120604 "𝜜")
- ("mathalpha" "\\mbfitB" 119913 "𝑩")
- ("mathalpha" "\\mbfitBeta" 120605 "𝜝")
- ("mathalpha" "\\mbfitC" 119914 "𝑪")
- ("mathalpha" "\\mbfitChi" 120626 "𝜲")
- ("mathalpha" "\\mbfitD" 119915 "𝑫")
- ("mathalpha" "\\mbfitDelta" 120607 "𝜟")
- ("mathalpha" "\\mbfitE" 119916 "𝑬")
- ("mathalpha" "\\mbfitEpsilon" 120608 "𝜠")
- ("mathalpha" "\\mbfitEta" 120610 "𝜢")
- ("mathalpha" "\\mbfitF" 119917 "𝑭")
- ("mathalpha" "\\mbfitG" 119918 "𝑮")
- ("mathalpha" "\\mbfitGamma" 120606 "𝜞")
- ("mathalpha" "\\mbfitH" 119919 "𝑯")
- ("mathalpha" "\\mbfitI" 119920 "𝑰")
- ("mathalpha" "\\mbfitIota" 120612 "𝜤")
- ("mathalpha" "\\mbfitJ" 119921 "𝑱")
- ("mathalpha" "\\mbfitK" 119922 "𝑲")
- ("mathalpha" "\\mbfitKappa" 120613 "𝜥")
- ("mathalpha" "\\mbfitL" 119923 "𝑳")
- ("mathalpha" "\\mbfitLambda" 120614 "𝜦")
- ("mathalpha" "\\mbfitM" 119924 "𝑴")
- ("mathalpha" "\\mbfitMu" 120615 "𝜧")
- ("mathalpha" "\\mbfitN" 119925 "𝑵")
- ("mathalpha" "\\mbfitNu" 120616 "𝜨")
- ("mathalpha" "\\mbfitO" 119926 "𝑶")
- ("mathalpha" "\\mbfitOmega" 120628 "𝜴")
- ("mathalpha" "\\mbfitOmicron" 120618 "𝜪")
- ("mathalpha" "\\mbfitP" 119927 "𝑷")
- ("mathalpha" "\\mbfitPhi" 120625 "𝜱")
- ("mathalpha" "\\mbfitPi" 120619 "𝜫")
- ("mathalpha" "\\mbfitPsi" 120627 "𝜳")
- ("mathalpha" "\\mbfitQ" 119928 "𝑸")
- ("mathalpha" "\\mbfitR" 119929 "𝑹")
- ("mathalpha" "\\mbfitRho" 120620 "𝜬")
- ("mathalpha" "\\mbfitS" 119930 "𝑺")
- ("mathalpha" "\\mbfitSigma" 120622 "𝜮")
- ("mathalpha" "\\mbfitT" 119931 "𝑻")
- ("mathalpha" "\\mbfitTau" 120623 "𝜯")
- ("mathalpha" "\\mbfitTheta" 120611 "𝜣")
- ("mathalpha" "\\mbfitU" 119932 "𝑼")
- ("mathalpha" "\\mbfitUpsilon" 120624 "𝜰")
- ("mathalpha" "\\mbfitV" 119933 "𝑽")
- ("mathalpha" "\\mbfitW" 119934 "𝑾")
- ("mathalpha" "\\mbfitX" 119935 "𝑿")
- ("mathalpha" "\\mbfitXi" 120617 "𝜩")
- ("mathalpha" "\\mbfitY" 119936 "𝒀")
- ("mathalpha" "\\mbfitZ" 119937 "𝒁")
- ("mathalpha" "\\mbfitZeta" 120609 "𝜡")
- ("mathalpha" "\\mbfita" 119938 "𝒂")
- ("mathalpha" "\\mbfitalpha" 120630 "𝜶")
- ("mathalpha" "\\mbfitb" 119939 "𝒃")
- ("mathalpha" "\\mbfitbeta" 120631 "𝜷")
- ("mathalpha" "\\mbfitc" 119940 "𝒄")
- ("mathalpha" "\\mbfitchi" 120652 "𝝌")
- ("mathalpha" "\\mbfitd" 119941 "𝒅")
- ("mathalpha" "\\mbfitdelta" 120633 "𝜹")
- ("mathalpha" "\\mbfite" 119942 "𝒆")
- ("mathalpha" "\\mbfitepsilon" 120634 "𝜺")
- ("mathalpha" "\\mbfiteta" 120636 "𝜼")
- ("mathalpha" "\\mbfitf" 119943 "𝒇")
- ("mathalpha" "\\mbfitg" 119944 "𝒈")
- ("mathalpha" "\\mbfitgamma" 120632 "𝜸")
- ("mathalpha" "\\mbfith" 119945 "𝒉")
- ("mathalpha" "\\mbfiti" 119946 "𝒊")
- ("mathalpha" "\\mbfitiota" 120638 "𝜾")
- ("mathalpha" "\\mbfitj" 119947 "𝒋")
- ("mathalpha" "\\mbfitk" 119948 "𝒌")
- ("mathalpha" "\\mbfitkappa" 120639 "𝜿")
- ("mathalpha" "\\mbfitl" 119949 "𝒍")
- ("mathalpha" "\\mbfitlambda" 120640 "𝝀")
- ("mathalpha" "\\mbfitm" 119950 "𝒎")
- ("mathalpha" "\\mbfitmu" 120641 "𝝁")
- ("mathalpha" "\\mbfitn" 119951 "𝒏")
- ("mathalpha" "\\mbfitnu" 120642 "𝝂")
- ("mathalpha" "\\mbfito" 119952 "𝒐")
- ("mathalpha" "\\mbfitomega" 120654 "𝝎")
- ("mathalpha" "\\mbfitomicron" 120644 "𝝄")
- ("mathalpha" "\\mbfitp" 119953 "𝒑")
- ("mathalpha" "\\mbfitphi" 120651 "𝝋")
- ("mathalpha" "\\mbfitpi" 120645 "𝝅")
- ("mathalpha" "\\mbfitpsi" 120653 "𝝍")
- ("mathalpha" "\\mbfitq" 119954 "𝒒")
- ("mathalpha" "\\mbfitr" 119955 "𝒓")
- ("mathalpha" "\\mbfitrho" 120646 "𝝆")
- ("mathalpha" "\\mbfits" 119956 "𝒔")
- ("mathalpha" "\\mbfitsansA" 120380 "𝘼")
- ("mathalpha" "\\mbfitsansAlpha" 120720 "𝞐")
- ("mathalpha" "\\mbfitsansB" 120381 "𝘽")
- ("mathalpha" "\\mbfitsansBeta" 120721 "𝞑")
- ("mathalpha" "\\mbfitsansC" 120382 "𝘾")
- ("mathalpha" "\\mbfitsansChi" 120742 "𝞦")
- ("mathalpha" "\\mbfitsansD" 120383 "𝘿")
- ("mathalpha" "\\mbfitsansDelta" 120723 "𝞓")
- ("mathalpha" "\\mbfitsansE" 120384 "𝙀")
- ("mathalpha" "\\mbfitsansEpsilon" 120724 "𝞔")
- ("mathalpha" "\\mbfitsansEta" 120726 "𝞖")
- ("mathalpha" "\\mbfitsansF" 120385 "𝙁")
- ("mathalpha" "\\mbfitsansG" 120386 "𝙂")
- ("mathalpha" "\\mbfitsansGamma" 120722 "𝞒")
- ("mathalpha" "\\mbfitsansH" 120387 "𝙃")
- ("mathalpha" "\\mbfitsansI" 120388 "𝙄")
- ("mathalpha" "\\mbfitsansIota" 120728 "𝞘")
- ("mathalpha" "\\mbfitsansJ" 120389 "𝙅")
- ("mathalpha" "\\mbfitsansK" 120390 "𝙆")
- ("mathalpha" "\\mbfitsansKappa" 120729 "𝞙")
- ("mathalpha" "\\mbfitsansL" 120391 "𝙇")
- ("mathalpha" "\\mbfitsansLambda" 120730 "𝞚")
- ("mathalpha" "\\mbfitsansM" 120392 "𝙈")
- ("mathalpha" "\\mbfitsansMu" 120731 "𝞛")
- ("mathalpha" "\\mbfitsansN" 120393 "𝙉")
- ("mathalpha" "\\mbfitsansNu" 120732 "𝞜")
- ("mathalpha" "\\mbfitsansO" 120394 "𝙊")
- ("mathalpha" "\\mbfitsansOmega" 120744 "𝞨")
- ("mathalpha" "\\mbfitsansOmicron" 120734 "𝞞")
- ("mathalpha" "\\mbfitsansP" 120395 "𝙋")
- ("mathalpha" "\\mbfitsansPhi" 120741 "𝞥")
- ("mathalpha" "\\mbfitsansPi" 120735 "𝞟")
- ("mathalpha" "\\mbfitsansPsi" 120743 "𝞧")
- ("mathalpha" "\\mbfitsansQ" 120396 "𝙌")
- ("mathalpha" "\\mbfitsansR" 120397 "𝙍")
- ("mathalpha" "\\mbfitsansRho" 120736 "𝞠")
- ("mathalpha" "\\mbfitsansS" 120398 "𝙎")
- ("mathalpha" "\\mbfitsansSigma" 120738 "𝞢")
- ("mathalpha" "\\mbfitsansT" 120399 "𝙏")
- ("mathalpha" "\\mbfitsansTau" 120739 "𝞣")
- ("mathalpha" "\\mbfitsansTheta" 120727 "𝞗")
- ("mathalpha" "\\mbfitsansU" 120400 "𝙐")
- ("mathalpha" "\\mbfitsansUpsilon" 120740 "𝞤")
- ("mathalpha" "\\mbfitsansV" 120401 "𝙑")
- ("mathalpha" "\\mbfitsansW" 120402 "𝙒")
- ("mathalpha" "\\mbfitsansX" 120403 "𝙓")
- ("mathalpha" "\\mbfitsansXi" 120733 "𝞝")
- ("mathalpha" "\\mbfitsansY" 120404 "𝙔")
- ("mathalpha" "\\mbfitsansZ" 120405 "𝙕")
- ("mathalpha" "\\mbfitsansZeta" 120725 "𝞕")
- ("mathalpha" "\\mbfitsansa" 120406 "𝙖")
- ("mathalpha" "\\mbfitsansalpha" 120746 "𝞪")
- ("mathalpha" "\\mbfitsansb" 120407 "𝙗")
- ("mathalpha" "\\mbfitsansbeta" 120747 "𝞫")
- ("mathalpha" "\\mbfitsansc" 120408 "𝙘")
- ("mathalpha" "\\mbfitsanschi" 120768 "𝟀")
- ("mathalpha" "\\mbfitsansd" 120409 "𝙙")
- ("mathalpha" "\\mbfitsansdelta" 120749 "𝞭")
- ("mathalpha" "\\mbfitsanse" 120410 "𝙚")
- ("mathalpha" "\\mbfitsansepsilon" 120750 "𝞮")
- ("mathalpha" "\\mbfitsanseta" 120752 "𝞰")
- ("mathalpha" "\\mbfitsansf" 120411 "𝙛")
- ("mathalpha" "\\mbfitsansg" 120412 "𝙜")
- ("mathalpha" "\\mbfitsansgamma" 120748 "𝞬")
- ("mathalpha" "\\mbfitsansh" 120413 "𝙝")
- ("mathalpha" "\\mbfitsansi" 120414 "𝙞")
- ("mathalpha" "\\mbfitsansiota" 120754 "𝞲")
- ("mathalpha" "\\mbfitsansj" 120415 "𝙟")
- ("mathalpha" "\\mbfitsansk" 120416 "𝙠")
- ("mathalpha" "\\mbfitsanskappa" 120755 "𝞳")
- ("mathalpha" "\\mbfitsansl" 120417 "𝙡")
- ("mathalpha" "\\mbfitsanslambda" 120756 "𝞴")
- ("mathalpha" "\\mbfitsansm" 120418 "𝙢")
- ("mathalpha" "\\mbfitsansmu" 120757 "𝞵")
- ("mathalpha" "\\mbfitsansn" 120419 "𝙣")
- ("mathalpha" "\\mbfitsansnu" 120758 "𝞶")
- ("mathalpha" "\\mbfitsanso" 120420 "𝙤")
- ("mathalpha" "\\mbfitsansomega" 120770 "𝟂")
- ("mathalpha" "\\mbfitsansomicron" 120760 "𝞸")
- ("mathalpha" "\\mbfitsansp" 120421 "𝙥")
- ("mathalpha" "\\mbfitsansphi" 120767 "𝞿")
- ("mathalpha" "\\mbfitsanspi" 120761 "𝞹")
- ("mathalpha" "\\mbfitsanspsi" 120769 "𝟁")
- ("mathalpha" "\\mbfitsansq" 120422 "𝙦")
- ("mathalpha" "\\mbfitsansr" 120423 "𝙧")
- ("mathalpha" "\\mbfitsansrho" 120762 "𝞺")
- ("mathalpha" "\\mbfitsanss" 120424 "𝙨")
- ("mathalpha" "\\mbfitsanssigma" 120764 "𝞼")
- ("mathalpha" "\\mbfitsanst" 120425 "𝙩")
- ("mathalpha" "\\mbfitsanstau" 120765 "𝞽")
- ("mathalpha" "\\mbfitsanstheta" 120753 "𝞱")
- ("mathalpha" "\\mbfitsansu" 120426 "𝙪")
- ("mathalpha" "\\mbfitsansupsilon" 120766 "𝞾")
- ("mathalpha" "\\mbfitsansv" 120427 "𝙫")
- ("mathalpha" "\\mbfitsansvarTheta" 120737 "𝞡")
- ("mathalpha" "\\mbfitsansvarepsilon" 120772 "𝟄")
- ("mathalpha" "\\mbfitsansvarkappa" 120774 "𝟆")
- ("mathalpha" "\\mbfitsansvarphi" 120775 "𝟇")
- ("mathalpha" "\\mbfitsansvarpi" 120777 "𝟉")
- ("mathalpha" "\\mbfitsansvarrho" 120776 "𝟈")
- ("mathalpha" "\\mbfitsansvarsigma" 120763 "𝞻")
- ("mathalpha" "\\mbfitsansvartheta" 120773 "𝟅")
- ("mathalpha" "\\mbfitsansw" 120428 "𝙬")
- ("mathalpha" "\\mbfitsansx" 120429 "𝙭")
- ("mathalpha" "\\mbfitsansxi" 120759 "𝞷")
- ("mathalpha" "\\mbfitsansy" 120430 "𝙮")
- ("mathalpha" "\\mbfitsansz" 120431 "𝙯")
- ("mathalpha" "\\mbfitsanszeta" 120751 "𝞯")
- ("mathalpha" "\\mbfitsigma" 120648 "𝝈")
- ("mathalpha" "\\mbfitt" 119957 "𝒕")
- ("mathalpha" "\\mbfittau" 120649 "𝝉")
- ("mathalpha" "\\mbfittheta" 120637 "𝜽")
- ("mathalpha" "\\mbfitu" 119958 "𝒖")
- ("mathalpha" "\\mbfitupsilon" 120650 "𝝊")
- ("mathalpha" "\\mbfitv" 119959 "𝒗")
- ("mathalpha" "\\mbfitvarTheta" 120621 "𝜭")
- ("mathalpha" "\\mbfitvarepsilon" 120656 "𝝐")
- ("mathalpha" "\\mbfitvarkappa" 120658 "𝝒")
- ("mathalpha" "\\mbfitvarphi" 120659 "𝝓")
- ("mathalpha" "\\mbfitvarpi" 120661 "𝝕")
- ("mathalpha" "\\mbfitvarrho" 120660 "𝝔")
- ("mathalpha" "\\mbfitvarsigma" 120647 "𝝇")
- ("mathalpha" "\\mbfitvartheta" 120657 "𝝑")
- ("mathalpha" "\\mbfitw" 119960 "𝒘")
- ("mathalpha" "\\mbfitx" 119961 "𝒙")
- ("mathalpha" "\\mbfitxi" 120643 "𝝃")
- ("mathalpha" "\\mbfity" 119962 "𝒚")
- ("mathalpha" "\\mbfitz" 119963 "𝒛")
- ("mathalpha" "\\mbfitzeta" 120635 "𝜻")
- ("mathalpha" "\\mbfj" 119843 "𝐣")
- ("mathalpha" "\\mbfk" 119844 "𝐤")
- ("mathalpha" "\\mbfkappa" 120523 "𝛋")
- ("mathalpha" "\\mbfl" 119845 "𝐥")
- ("mathalpha" "\\mbflambda" 120524 "𝛌")
- ("mathalpha" "\\mbfm" 119846 "𝐦")
- ("mathalpha" "\\mbfmu" 120525 "𝛍")
- ("mathalpha" "\\mbfn" 119847 "𝐧")
- ("mathalpha" "\\mbfnu" 120526 "𝛎")
- ("mathalpha" "\\mbfo" 119848 "𝐨")
- ("mathalpha" "\\mbfomega" 120538 "𝛚")
- ("mathalpha" "\\mbfomicron" 120528 "𝛐")
- ("mathalpha" "\\mbfp" 119849 "𝐩")
- ("mathalpha" "\\mbfphi" 120543 "𝛟")
- ("mathalpha" "\\mbfpi" 120529 "𝛑")
- ("mathalpha" "\\mbfpsi" 120537 "𝛙")
- ("mathalpha" "\\mbfq" 119850 "𝐪")
- ("mathalpha" "\\mbfr" 119851 "𝐫")
- ("mathalpha" "\\mbfrho" 120530 "𝛒")
- ("mathalpha" "\\mbfs" 119852 "𝐬")
- ("mathalpha" "\\mbfsansA" 120276 "𝗔")
- ("mathalpha" "\\mbfsansAlpha" 120662 "𝝖")
- ("mathalpha" "\\mbfsansB" 120277 "𝗕")
- ("mathalpha" "\\mbfsansBeta" 120663 "𝝗")
- ("mathalpha" "\\mbfsansC" 120278 "𝗖")
- ("mathalpha" "\\mbfsansChi" 120684 "𝝬")
- ("mathalpha" "\\mbfsansD" 120279 "𝗗")
- ("mathalpha" "\\mbfsansDelta" 120665 "𝝙")
- ("mathalpha" "\\mbfsansE" 120280 "𝗘")
- ("mathalpha" "\\mbfsansEpsilon" 120666 "𝝚")
- ("mathalpha" "\\mbfsansEta" 120668 "𝝜")
- ("mathalpha" "\\mbfsansF" 120281 "𝗙")
- ("mathalpha" "\\mbfsansG" 120282 "𝗚")
- ("mathalpha" "\\mbfsansGamma" 120664 "𝝘")
- ("mathalpha" "\\mbfsansH" 120283 "𝗛")
- ("mathalpha" "\\mbfsansI" 120284 "𝗜")
- ("mathalpha" "\\mbfsansIota" 120670 "𝝞")
- ("mathalpha" "\\mbfsansJ" 120285 "𝗝")
- ("mathalpha" "\\mbfsansK" 120286 "𝗞")
- ("mathalpha" "\\mbfsansKappa" 120671 "𝝟")
- ("mathalpha" "\\mbfsansL" 120287 "𝗟")
- ("mathalpha" "\\mbfsansLambda" 120672 "𝝠")
- ("mathalpha" "\\mbfsansM" 120288 "𝗠")
- ("mathalpha" "\\mbfsansMu" 120673 "𝝡")
- ("mathalpha" "\\mbfsansN" 120289 "𝗡")
- ("mathalpha" "\\mbfsansNu" 120674 "𝝢")
- ("mathalpha" "\\mbfsansO" 120290 "𝗢")
- ("mathalpha" "\\mbfsansOmega" 120686 "𝝮")
- ("mathalpha" "\\mbfsansOmicron" 120676 "𝝤")
- ("mathalpha" "\\mbfsansP" 120291 "𝗣")
- ("mathalpha" "\\mbfsansPhi" 120683 "𝝫")
- ("mathalpha" "\\mbfsansPi" 120677 "𝝥")
- ("mathalpha" "\\mbfsansPsi" 120685 "𝝭")
- ("mathalpha" "\\mbfsansQ" 120292 "𝗤")
- ("mathalpha" "\\mbfsansR" 120293 "𝗥")
- ("mathalpha" "\\mbfsansRho" 120678 "𝝦")
- ("mathalpha" "\\mbfsansS" 120294 "𝗦")
- ("mathalpha" "\\mbfsansSigma" 120680 "𝝨")
- ("mathalpha" "\\mbfsansT" 120295 "𝗧")
- ("mathalpha" "\\mbfsansTau" 120681 "𝝩")
- ("mathalpha" "\\mbfsansTheta" 120669 "𝝝")
- ("mathalpha" "\\mbfsansU" 120296 "𝗨")
- ("mathalpha" "\\mbfsansUpsilon" 120682 "𝝪")
- ("mathalpha" "\\mbfsansV" 120297 "𝗩")
- ("mathalpha" "\\mbfsansW" 120298 "𝗪")
- ("mathalpha" "\\mbfsansX" 120299 "𝗫")
- ("mathalpha" "\\mbfsansXi" 120675 "𝝣")
- ("mathalpha" "\\mbfsansY" 120300 "𝗬")
- ("mathalpha" "\\mbfsansZ" 120301 "𝗭")
- ("mathalpha" "\\mbfsansZeta" 120667 "𝝛")
- ("mathalpha" "\\mbfsansa" 120302 "𝗮")
- ("mathalpha" "\\mbfsansalpha" 120688 "𝝰")
- ("mathalpha" "\\mbfsansb" 120303 "𝗯")
- ("mathalpha" "\\mbfsansbeta" 120689 "𝝱")
- ("mathalpha" "\\mbfsansc" 120304 "𝗰")
- ("mathalpha" "\\mbfsanschi" 120710 "𝞆")
- ("mathalpha" "\\mbfsansd" 120305 "𝗱")
- ("mathalpha" "\\mbfsansdelta" 120691 "𝝳")
- ("mathalpha" "\\mbfsanse" 120306 "𝗲")
- ("mathalpha" "\\mbfsansepsilon" 120692 "𝝴")
- ("mathalpha" "\\mbfsanseta" 120694 "𝝶")
- ("mathalpha" "\\mbfsansf" 120307 "𝗳")
- ("mathalpha" "\\mbfsansg" 120308 "𝗴")
- ("mathalpha" "\\mbfsansgamma" 120690 "𝝲")
- ("mathalpha" "\\mbfsansh" 120309 "𝗵")
- ("mathalpha" "\\mbfsansi" 120310 "𝗶")
- ("mathalpha" "\\mbfsansiota" 120696 "𝝸")
- ("mathalpha" "\\mbfsansj" 120311 "𝗷")
- ("mathalpha" "\\mbfsansk" 120312 "𝗸")
- ("mathalpha" "\\mbfsanskappa" 120697 "𝝹")
- ("mathalpha" "\\mbfsansl" 120313 "𝗹")
- ("mathalpha" "\\mbfsanslambda" 120698 "𝝺")
- ("mathalpha" "\\mbfsansm" 120314 "𝗺")
- ("mathalpha" "\\mbfsansmu" 120699 "𝝻")
- ("mathalpha" "\\mbfsansn" 120315 "𝗻")
- ("mathalpha" "\\mbfsansnu" 120700 "𝝼")
- ("mathalpha" "\\mbfsanso" 120316 "𝗼")
- ("mathalpha" "\\mbfsansomega" 120712 "𝞈")
- ("mathalpha" "\\mbfsansomicron" 120702 "𝝾")
- ("mathalpha" "\\mbfsansp" 120317 "𝗽")
- ("mathalpha" "\\mbfsansphi" 120709 "𝞅")
- ("mathalpha" "\\mbfsanspi" 120703 "𝝿")
- ("mathalpha" "\\mbfsanspsi" 120711 "𝞇")
- ("mathalpha" "\\mbfsansq" 120318 "𝗾")
- ("mathalpha" "\\mbfsansr" 120319 "𝗿")
- ("mathalpha" "\\mbfsansrho" 120704 "𝞀")
- ("mathalpha" "\\mbfsanss" 120320 "𝘀")
- ("mathalpha" "\\mbfsanssigma" 120706 "𝞂")
- ("mathalpha" "\\mbfsanst" 120321 "𝘁")
- ("mathalpha" "\\mbfsanstau" 120707 "𝞃")
- ("mathalpha" "\\mbfsanstheta" 120695 "𝝷")
- ("mathalpha" "\\mbfsansu" 120322 "𝘂")
- ("mathalpha" "\\mbfsansupsilon" 120708 "𝞄")
- ("mathalpha" "\\mbfsansv" 120323 "𝘃")
- ("mathalpha" "\\mbfsansvarTheta" 120679 "𝝧")
- ("mathalpha" "\\mbfsansvarepsilon" 120714 "𝞊")
- ("mathalpha" "\\mbfsansvarkappa" 120716 "𝞌")
- ("mathalpha" "\\mbfsansvarphi" 120717 "𝞍")
- ("mathalpha" "\\mbfsansvarpi" 120719 "𝞏")
- ("mathalpha" "\\mbfsansvarrho" 120718 "𝞎")
- ("mathalpha" "\\mbfsansvarsigma" 120705 "𝞁")
- ("mathalpha" "\\mbfsansvartheta" 120715 "𝞋")
- ("mathalpha" "\\mbfsansw" 120324 "𝘄")
- ("mathalpha" "\\mbfsansx" 120325 "𝘅")
- ("mathalpha" "\\mbfsansxi" 120701 "𝝽")
- ("mathalpha" "\\mbfsansy" 120326 "𝘆")
- ("mathalpha" "\\mbfsansz" 120327 "𝘇")
- ("mathalpha" "\\mbfsanszeta" 120693 "𝝵")
- ("mathalpha" "\\mbfscrA" 120016 "𝓐")
- ("mathalpha" "\\mbfscrB" 120017 "𝓑")
- ("mathalpha" "\\mbfscrC" 120018 "𝓒")
- ("mathalpha" "\\mbfscrD" 120019 "𝓓")
- ("mathalpha" "\\mbfscrE" 120020 "𝓔")
- ("mathalpha" "\\mbfscrF" 120021 "𝓕")
- ("mathalpha" "\\mbfscrG" 120022 "𝓖")
- ("mathalpha" "\\mbfscrH" 120023 "𝓗")
- ("mathalpha" "\\mbfscrI" 120024 "𝓘")
- ("mathalpha" "\\mbfscrJ" 120025 "𝓙")
- ("mathalpha" "\\mbfscrK" 120026 "𝓚")
- ("mathalpha" "\\mbfscrL" 120027 "𝓛")
- ("mathalpha" "\\mbfscrM" 120028 "𝓜")
- ("mathalpha" "\\mbfscrN" 120029 "𝓝")
- ("mathalpha" "\\mbfscrO" 120030 "𝓞")
- ("mathalpha" "\\mbfscrP" 120031 "𝓟")
- ("mathalpha" "\\mbfscrQ" 120032 "𝓠")
- ("mathalpha" "\\mbfscrR" 120033 "𝓡")
- ("mathalpha" "\\mbfscrS" 120034 "𝓢")
- ("mathalpha" "\\mbfscrT" 120035 "𝓣")
- ("mathalpha" "\\mbfscrU" 120036 "𝓤")
- ("mathalpha" "\\mbfscrV" 120037 "𝓥")
- ("mathalpha" "\\mbfscrW" 120038 "𝓦")
- ("mathalpha" "\\mbfscrX" 120039 "𝓧")
- ("mathalpha" "\\mbfscrY" 120040 "𝓨")
- ("mathalpha" "\\mbfscrZ" 120041 "𝓩")
- ("mathalpha" "\\mbfscra" 120042 "𝓪")
- ("mathalpha" "\\mbfscrb" 120043 "𝓫")
- ("mathalpha" "\\mbfscrc" 120044 "𝓬")
- ("mathalpha" "\\mbfscrd" 120045 "𝓭")
- ("mathalpha" "\\mbfscre" 120046 "𝓮")
- ("mathalpha" "\\mbfscrf" 120047 "𝓯")
- ("mathalpha" "\\mbfscrg" 120048 "𝓰")
- ("mathalpha" "\\mbfscrh" 120049 "𝓱")
- ("mathalpha" "\\mbfscri" 120050 "𝓲")
- ("mathalpha" "\\mbfscrj" 120051 "𝓳")
- ("mathalpha" "\\mbfscrk" 120052 "𝓴")
- ("mathalpha" "\\mbfscrl" 120053 "𝓵")
- ("mathalpha" "\\mbfscrm" 120054 "𝓶")
- ("mathalpha" "\\mbfscrn" 120055 "𝓷")
- ("mathalpha" "\\mbfscro" 120056 "𝓸")
- ("mathalpha" "\\mbfscrp" 120057 "𝓹")
- ("mathalpha" "\\mbfscrq" 120058 "𝓺")
- ("mathalpha" "\\mbfscrr" 120059 "𝓻")
- ("mathalpha" "\\mbfscrs" 120060 "𝓼")
- ("mathalpha" "\\mbfscrt" 120061 "𝓽")
- ("mathalpha" "\\mbfscru" 120062 "𝓾")
- ("mathalpha" "\\mbfscrv" 120063 "𝓿")
- ("mathalpha" "\\mbfscrw" 120064 "𝔀")
- ("mathalpha" "\\mbfscrx" 120065 "𝔁")
- ("mathalpha" "\\mbfscry" 120066 "𝔂")
- ("mathalpha" "\\mbfscrz" 120067 "𝔃")
- ("mathalpha" "\\mbfsigma" 120532 "𝛔")
- ("mathalpha" "\\mbft" 119853 "𝐭")
- ("mathalpha" "\\mbftau" 120533 "𝛕")
- ("mathalpha" "\\mbftheta" 120521 "𝛉")
- ("mathalpha" "\\mbfu" 119854 "𝐮")
- ("mathalpha" "\\mbfupsilon" 120534 "𝛖")
- ("mathalpha" "\\mbfv" 119855 "𝐯")
- ("mathalpha" "\\mbfvarTheta" 120505 "𝚹")
- ("mathalpha" "\\mbfvarepsilon" 120540 "𝛜")
- ("mathalpha" "\\mbfvarkappa" 120542 "𝛞")
- ("mathalpha" "\\mbfvarphi" 120535 "𝛗")
- ("mathalpha" "\\mbfvarpi" 120545 "𝛡")
- ("mathalpha" "\\mbfvarrho" 120544 "𝛠")
- ("mathalpha" "\\mbfvarsigma" 120531 "𝛓")
- ("mathalpha" "\\mbfvartheta" 120541 "𝛝")
- ("mathalpha" "\\mbfw" 119856 "𝐰")
- ("mathalpha" "\\mbfx" 119857 "𝐱")
- ("mathalpha" "\\mbfxi" 120527 "𝛏")
- ("mathalpha" "\\mbfy" 119858 "𝐲")
- ("mathalpha" "\\mbfz" 119859 "𝐳")
- ("mathalpha" "\\mbfzeta" 120519 "𝛇")
- ("mathalpha" "\\mfrakA" 120068 "𝔄")
- ("mathalpha" "\\mfrakB" 120069 "𝔅")
- ("mathalpha" "\\mfrakC" 8493 "ℭ")
- ("mathalpha" "\\mfrakD" 120071 "𝔇")
- ("mathalpha" "\\mfrakE" 120072 "𝔈")
- ("mathalpha" "\\mfrakF" 120073 "𝔉")
- ("mathalpha" "\\mfrakG" 120074 "𝔊")
- ("mathalpha" "\\mfrakH" 8460 "ℌ")
- ("mathalpha" "\\mfrakJ" 120077 "𝔍")
- ("mathalpha" "\\mfrakK" 120078 "𝔎")
- ("mathalpha" "\\mfrakL" 120079 "𝔏")
- ("mathalpha" "\\mfrakM" 120080 "𝔐")
- ("mathalpha" "\\mfrakN" 120081 "𝔑")
- ("mathalpha" "\\mfrakO" 120082 "𝔒")
- ("mathalpha" "\\mfrakP" 120083 "𝔓")
- ("mathalpha" "\\mfrakQ" 120084 "𝔔")
- ("mathalpha" "\\mfrakS" 120086 "𝔖")
- ("mathalpha" "\\mfrakT" 120087 "𝔗")
- ("mathalpha" "\\mfrakU" 120088 "𝔘")
- ("mathalpha" "\\mfrakV" 120089 "𝔙")
- ("mathalpha" "\\mfrakW" 120090 "𝔚")
- ("mathalpha" "\\mfrakX" 120091 "𝔛")
- ("mathalpha" "\\mfrakY" 120092 "𝔜")
- ("mathalpha" "\\mfrakZ" 8488 "ℨ")
- ("mathalpha" "\\mfraka" 120094 "𝔞")
- ("mathalpha" "\\mfrakb" 120095 "𝔟")
- ("mathalpha" "\\mfrakc" 120096 "𝔠")
- ("mathalpha" "\\mfrakd" 120097 "𝔡")
- ("mathalpha" "\\mfrake" 120098 "𝔢")
- ("mathalpha" "\\mfrakf" 120099 "𝔣")
- ("mathalpha" "\\mfrakg" 120100 "𝔤")
- ("mathalpha" "\\mfrakh" 120101 "𝔥")
- ("mathalpha" "\\mfraki" 120102 "𝔦")
- ("mathalpha" "\\mfrakj" 120103 "𝔧")
- ("mathalpha" "\\mfrakk" 120104 "𝔨")
- ("mathalpha" "\\mfrakl" 120105 "𝔩")
- ("mathalpha" "\\mfrakm" 120106 "𝔪")
- ("mathalpha" "\\mfrakn" 120107 "𝔫")
- ("mathalpha" "\\mfrako" 120108 "𝔬")
- ("mathalpha" "\\mfrakp" 120109 "𝔭")
- ("mathalpha" "\\mfrakq" 120110 "𝔮")
- ("mathalpha" "\\mfrakr" 120111 "𝔯")
- ("mathalpha" "\\mfraks" 120112 "𝔰")
- ("mathalpha" "\\mfrakt" 120113 "𝔱")
- ("mathalpha" "\\mfraku" 120114 "𝔲")
- ("mathalpha" "\\mfrakv" 120115 "𝔳")
- ("mathalpha" "\\mfrakw" 120116 "𝔴")
- ("mathalpha" "\\mfrakx" 120117 "𝔵")
- ("mathalpha" "\\mfraky" 120118 "𝔶")
- ("mathalpha" "\\mfrakz" 120119 "𝔷")
- ("mathalpha" "\\mitA" 119860 "𝐴")
- ("mathalpha" "\\mitAlpha" 120546 "𝛢")
- ("mathalpha" "\\mitB" 119861 "𝐵")
- ("mathalpha" "\\mitBeta" 120547 "𝛣")
- ("mathalpha" "\\mitC" 119862 "𝐶")
- ("mathalpha" "\\mitChi" 120568 "𝛸")
- ("mathalpha" "\\mitD" 119863 "𝐷")
- ("mathalpha" "\\mitDelta" 120549 "𝛥")
- ("mathalpha" "\\mitE" 119864 "𝐸")
- ("mathalpha" "\\mitEpsilon" 120550 "𝛦")
- ("mathalpha" "\\mitEta" 120552 "𝛨")
- ("mathalpha" "\\mitF" 119865 "𝐹")
- ("mathalpha" "\\mitG" 119866 "𝐺")
- ("mathalpha" "\\mitGamma" 120548 "𝛤")
- ("mathalpha" "\\mitH" 119867 "𝐻")
- ("mathalpha" "\\mitI" 119868 "𝐼")
- ("mathalpha" "\\mitIota" 120554 "𝛪")
- ("mathalpha" "\\mitJ" 119869 "𝐽")
- ("mathalpha" "\\mitK" 119870 "𝐾")
- ("mathalpha" "\\mitKappa" 120555 "𝛫")
- ("mathalpha" "\\mitL" 119871 "𝐿")
- ("mathalpha" "\\mitLambda" 120556 "𝛬")
- ("mathalpha" "\\mitM" 119872 "𝑀")
- ("mathalpha" "\\mitMu" 120557 "𝛭")
- ("mathalpha" "\\mitN" 119873 "𝑁")
- ("mathalpha" "\\mitNu" 120558 "𝛮")
- ("mathalpha" "\\mitO" 119874 "𝑂")
- ("mathalpha" "\\mitOmega" 120570 "𝛺")
- ("mathalpha" "\\mitOmicron" 120560 "𝛰")
- ("mathalpha" "\\mitP" 119875 "𝑃")
- ("mathalpha" "\\mitPhi" 120567 "𝛷")
- ("mathalpha" "\\mitPi" 120561 "𝛱")
- ("mathalpha" "\\mitPsi" 120569 "𝛹")
- ("mathalpha" "\\mitQ" 119876 "𝑄")
- ("mathalpha" "\\mitR" 119877 "𝑅")
- ("mathalpha" "\\mitRho" 120562 "𝛲")
- ("mathalpha" "\\mitS" 119878 "𝑆")
- ("mathalpha" "\\mitSigma" 120564 "𝛴")
- ("mathalpha" "\\mitT" 119879 "𝑇")
- ("mathalpha" "\\mitTau" 120565 "𝛵")
- ("mathalpha" "\\mitTheta" 120553 "𝛩")
- ("mathalpha" "\\mitU" 119880 "𝑈")
- ("mathalpha" "\\mitUpsilon" 120566 "𝛶")
- ("mathalpha" "\\mitV" 119881 "𝑉")
- ("mathalpha" "\\mitW" 119882 "𝑊")
- ("mathalpha" "\\mitX" 119883 "𝑋")
- ("mathalpha" "\\mitXi" 120559 "𝛯")
- ("mathalpha" "\\mitY" 119884 "𝑌")
- ("mathalpha" "\\mitZ" 119885 "𝑍")
- ("mathalpha" "\\mitZeta" 120551 "𝛧")
- ("mathalpha" "\\mita" 119886 "𝑎")
- ("mathalpha" "\\mitalpha" 120572 "𝛼")
- ("mathalpha" "\\mitb" 119887 "𝑏")
- ("mathalpha" "\\mitbeta" 120573 "𝛽")
- ("mathalpha" "\\mitc" 119888 "𝑐")
- ("mathalpha" "\\mitchi" 120594 "𝜒")
- ("mathalpha" "\\mitd" 119889 "𝑑")
- ("mathalpha" "\\mitdelta" 120575 "𝛿")
- ("mathalpha" "\\mite" 119890 "𝑒")
- ("mathalpha" "\\mitepsilon" 120576 "𝜀")
- ("mathalpha" "\\miteta" 120578 "𝜂")
- ("mathalpha" "\\mitf" 119891 "𝑓")
- ("mathalpha" "\\mitg" 119892 "𝑔")
- ("mathalpha" "\\mitgamma" 120574 "𝛾")
- ("mathalpha" "\\miti" 119894 "𝑖")
- ("mathalpha" "\\mitiota" 120580 "𝜄")
- ("mathalpha" "\\mitj" 119895 "𝑗")
- ("mathalpha" "\\mitk" 119896 "𝑘")
- ("mathalpha" "\\mitkappa" 120581 "𝜅")
- ("mathalpha" "\\mitl" 119897 "𝑙")
- ("mathalpha" "\\mitlambda" 120582 "𝜆")
- ("mathalpha" "\\mitm" 119898 "𝑚")
- ("mathalpha" "\\mitmu" 120583 "𝜇")
- ("mathalpha" "\\mitn" 119899 "𝑛")
- ("mathalpha" "\\mitnu" 120584 "𝜈")
- ("mathalpha" "\\mito" 119900 "𝑜")
- ("mathalpha" "\\mitomega" 120596 "𝜔")
- ("mathalpha" "\\mitomicron" 120586 "𝜊")
- ("mathalpha" "\\mitp" 119901 "𝑝")
- ("mathalpha" "\\mitphi" 120593 "𝜑")
- ("mathalpha" "\\mitpi" 120587 "𝜋")
- ("mathalpha" "\\mitpsi" 120595 "𝜓")
- ("mathalpha" "\\mitq" 119902 "𝑞")
- ("mathalpha" "\\mitr" 119903 "𝑟")
- ("mathalpha" "\\mitrho" 120588 "𝜌")
- ("mathalpha" "\\mits" 119904 "𝑠")
- ("mathalpha" "\\mitsansA" 120328 "𝘈")
- ("mathalpha" "\\mitsansB" 120329 "𝘉")
- ("mathalpha" "\\mitsansC" 120330 "𝘊")
- ("mathalpha" "\\mitsansD" 120331 "𝘋")
- ("mathalpha" "\\mitsansE" 120332 "𝘌")
- ("mathalpha" "\\mitsansF" 120333 "𝘍")
- ("mathalpha" "\\mitsansG" 120334 "𝘎")
- ("mathalpha" "\\mitsansH" 120335 "𝘏")
- ("mathalpha" "\\mitsansI" 120336 "𝘐")
- ("mathalpha" "\\mitsansJ" 120337 "𝘑")
- ("mathalpha" "\\mitsansK" 120338 "𝘒")
- ("mathalpha" "\\mitsansL" 120339 "𝘓")
- ("mathalpha" "\\mitsansM" 120340 "𝘔")
- ("mathalpha" "\\mitsansN" 120341 "𝘕")
- ("mathalpha" "\\mitsansO" 120342 "𝘖")
- ("mathalpha" "\\mitsansP" 120343 "𝘗")
- ("mathalpha" "\\mitsansQ" 120344 "𝘘")
- ("mathalpha" "\\mitsansR" 120345 "𝘙")
- ("mathalpha" "\\mitsansS" 120346 "𝘚")
- ("mathalpha" "\\mitsansT" 120347 "𝘛")
- ("mathalpha" "\\mitsansU" 120348 "𝘜")
- ("mathalpha" "\\mitsansV" 120349 "𝘝")
- ("mathalpha" "\\mitsansW" 120350 "𝘞")
- ("mathalpha" "\\mitsansX" 120351 "𝘟")
- ("mathalpha" "\\mitsansY" 120352 "𝘠")
- ("mathalpha" "\\mitsansZ" 120353 "𝘡")
- ("mathalpha" "\\mitsansa" 120354 "𝘢")
- ("mathalpha" "\\mitsansb" 120355 "𝘣")
- ("mathalpha" "\\mitsansc" 120356 "𝘤")
- ("mathalpha" "\\mitsansd" 120357 "𝘥")
- ("mathalpha" "\\mitsanse" 120358 "𝘦")
- ("mathalpha" "\\mitsansf" 120359 "𝘧")
- ("mathalpha" "\\mitsansg" 120360 "𝘨")
- ("mathalpha" "\\mitsansh" 120361 "𝘩")
- ("mathalpha" "\\mitsansi" 120362 "𝘪")
- ("mathalpha" "\\mitsansj" 120363 "𝘫")
- ("mathalpha" "\\mitsansk" 120364 "𝘬")
- ("mathalpha" "\\mitsansl" 120365 "𝘭")
- ("mathalpha" "\\mitsansm" 120366 "𝘮")
- ("mathalpha" "\\mitsansn" 120367 "𝘯")
- ("mathalpha" "\\mitsanso" 120368 "𝘰")
- ("mathalpha" "\\mitsansp" 120369 "𝘱")
- ("mathalpha" "\\mitsansq" 120370 "𝘲")
- ("mathalpha" "\\mitsansr" 120371 "𝘳")
- ("mathalpha" "\\mitsanss" 120372 "𝘴")
- ("mathalpha" "\\mitsanst" 120373 "𝘵")
- ("mathalpha" "\\mitsansu" 120374 "𝘶")
- ("mathalpha" "\\mitsansv" 120375 "𝘷")
- ("mathalpha" "\\mitsansw" 120376 "𝘸")
- ("mathalpha" "\\mitsansx" 120377 "𝘹")
- ("mathalpha" "\\mitsansy" 120378 "𝘺")
- ("mathalpha" "\\mitsansz" 120379 "𝘻")
- ("mathalpha" "\\mitsigma" 120590 "𝜎")
- ("mathalpha" "\\mitt" 119905 "𝑡")
- ("mathalpha" "\\mittau" 120591 "𝜏")
- ("mathalpha" "\\mittheta" 120579 "𝜃")
- ("mathalpha" "\\mitu" 119906 "𝑢")
- ("mathalpha" "\\mitupsilon" 120592 "𝜐")
- ("mathalpha" "\\mitv" 119907 "𝑣")
- ("mathalpha" "\\mitvarTheta" 120563 "𝛳")
- ("mathalpha" "\\mitvarepsilon" 120598 "𝜖")
- ("mathalpha" "\\mitvarkappa" 120600 "𝜘")
- ("mathalpha" "\\mitvarphi" 120601 "𝜙")
- ("mathalpha" "\\mitvarpi" 120603 "𝜛")
- ("mathalpha" "\\mitvarrho" 120602 "𝜚")
- ("mathalpha" "\\mitvarsigma" 120589 "𝜍")
- ("mathalpha" "\\mitvartheta" 120599 "𝜗")
- ("mathalpha" "\\mitw" 119908 "𝑤")
- ("mathalpha" "\\mitx" 119909 "𝑥")
- ("mathalpha" "\\mitxi" 120585 "𝜉")
- ("mathalpha" "\\mity" 119910 "𝑦")
- ("mathalpha" "\\mitz" 119911 "𝑧")
- ("mathalpha" "\\mitzeta" 120577 "𝜁")
- ("mathalpha" "\\msansA" 120224 "𝖠")
- ("mathalpha" "\\msansB" 120225 "𝖡")
- ("mathalpha" "\\msansC" 120226 "𝖢")
- ("mathalpha" "\\msansD" 120227 "𝖣")
- ("mathalpha" "\\msansE" 120228 "𝖤")
- ("mathalpha" "\\msansF" 120229 "𝖥")
- ("mathalpha" "\\msansG" 120230 "𝖦")
- ("mathalpha" "\\msansH" 120231 "𝖧")
- ("mathalpha" "\\msansI" 120232 "𝖨")
- ("mathalpha" "\\msansJ" 120233 "𝖩")
- ("mathalpha" "\\msansK" 120234 "𝖪")
- ("mathalpha" "\\msansL" 120235 "𝖫")
- ("mathalpha" "\\msansM" 120236 "𝖬")
- ("mathalpha" "\\msansN" 120237 "𝖭")
- ("mathalpha" "\\msansO" 120238 "𝖮")
- ("mathalpha" "\\msansP" 120239 "𝖯")
- ("mathalpha" "\\msansQ" 120240 "𝖰")
- ("mathalpha" "\\msansR" 120241 "𝖱")
- ("mathalpha" "\\msansS" 120242 "𝖲")
- ("mathalpha" "\\msansT" 120243 "𝖳")
- ("mathalpha" "\\msansU" 120244 "𝖴")
- ("mathalpha" "\\msansV" 120245 "𝖵")
- ("mathalpha" "\\msansW" 120246 "𝖶")
- ("mathalpha" "\\msansX" 120247 "𝖷")
- ("mathalpha" "\\msansY" 120248 "𝖸")
- ("mathalpha" "\\msansZ" 120249 "𝖹")
- ("mathalpha" "\\msansa" 120250 "𝖺")
- ("mathalpha" "\\msansb" 120251 "𝖻")
- ("mathalpha" "\\msansc" 120252 "𝖼")
- ("mathalpha" "\\msansd" 120253 "𝖽")
- ("mathalpha" "\\msanse" 120254 "𝖾")
- ("mathalpha" "\\msansf" 120255 "𝖿")
- ("mathalpha" "\\msansg" 120256 "𝗀")
- ("mathalpha" "\\msansh" 120257 "𝗁")
- ("mathalpha" "\\msansi" 120258 "𝗂")
- ("mathalpha" "\\msansj" 120259 "𝗃")
- ("mathalpha" "\\msansk" 120260 "𝗄")
- ("mathalpha" "\\msansl" 120261 "𝗅")
- ("mathalpha" "\\msansm" 120262 "𝗆")
- ("mathalpha" "\\msansn" 120263 "𝗇")
- ("mathalpha" "\\msanso" 120264 "𝗈")
- ("mathalpha" "\\msansp" 120265 "𝗉")
- ("mathalpha" "\\msansq" 120266 "𝗊")
- ("mathalpha" "\\msansr" 120267 "𝗋")
- ("mathalpha" "\\msanss" 120268 "𝗌")
- ("mathalpha" "\\msanst" 120269 "𝗍")
- ("mathalpha" "\\msansu" 120270 "𝗎")
- ("mathalpha" "\\msansv" 120271 "𝗏")
- ("mathalpha" "\\msansw" 120272 "𝗐")
- ("mathalpha" "\\msansx" 120273 "𝗑")
- ("mathalpha" "\\msansy" 120274 "𝗒")
- ("mathalpha" "\\msansz" 120275 "𝗓")
- ("mathalpha" "\\mscrA" 119964 "𝒜")
- ("mathalpha" "\\mscrB" 8492 "ℬ")
- ("mathalpha" "\\mscrC" 119966 "𝒞")
- ("mathalpha" "\\mscrD" 119967 "𝒟")
- ("mathalpha" "\\mscrE" 8496 "ℰ")
- ("mathalpha" "\\mscrF" 8497 "ℱ")
- ("mathalpha" "\\mscrG" 119970 "𝒢")
- ("mathalpha" "\\mscrH" 8459 "ℋ")
- ("mathalpha" "\\mscrI" 8464 "ℐ")
- ("mathalpha" "\\mscrJ" 119973 "𝒥")
- ("mathalpha" "\\mscrK" 119974 "𝒦")
- ("mathalpha" "\\mscrL" 8466 "ℒ")
- ("mathalpha" "\\mscrM" 8499 "ℳ")
- ("mathalpha" "\\mscrN" 119977 "𝒩")
- ("mathalpha" "\\mscrO" 119978 "𝒪")
- ("mathalpha" "\\mscrP" 119979 "𝒫")
- ("mathalpha" "\\mscrQ" 119980 "𝒬")
- ("mathalpha" "\\mscrR" 8475 "ℛ")
- ("mathalpha" "\\mscrS" 119982 "𝒮")
- ("mathalpha" "\\mscrT" 119983 "𝒯")
- ("mathalpha" "\\mscrU" 119984 "𝒰")
- ("mathalpha" "\\mscrV" 119985 "𝒱")
- ("mathalpha" "\\mscrW" 119986 "𝒲")
- ("mathalpha" "\\mscrX" 119987 "𝒳")
- ("mathalpha" "\\mscrY" 119988 "𝒴")
- ("mathalpha" "\\mscrZ" 119989 "𝒵")
- ("mathalpha" "\\mscra" 119990 "𝒶")
- ("mathalpha" "\\mscrb" 119991 "𝒷")
- ("mathalpha" "\\mscrc" 119992 "𝒸")
- ("mathalpha" "\\mscrd" 119993 "𝒹")
- ("mathalpha" "\\mscre" 8495 "ℯ")
- ("mathalpha" "\\mscrf" 119995 "𝒻")
- ("mathalpha" "\\mscrg" 8458 "ℊ")
- ("mathalpha" "\\mscrh" 119997 "𝒽")
- ("mathalpha" "\\mscri" 119998 "𝒾")
- ("mathalpha" "\\mscrj" 119999 "𝒿")
- ("mathalpha" "\\mscrk" 120000 "𝓀")
- ("mathalpha" "\\mscrl" 120001 "𝓁")
- ("mathalpha" "\\mscrm" 120002 "𝓂")
- ("mathalpha" "\\mscrn" 120003 "𝓃")
- ("mathalpha" "\\mscro" 8500 "ℴ")
- ("mathalpha" "\\mscrp" 120005 "𝓅")
- ("mathalpha" "\\mscrq" 120006 "𝓆")
- ("mathalpha" "\\mscrr" 120007 "𝓇")
- ("mathalpha" "\\mscrs" 120008 "𝓈")
- ("mathalpha" "\\mscrt" 120009 "𝓉")
- ("mathalpha" "\\mscru" 120010 "𝓊")
- ("mathalpha" "\\mscrv" 120011 "𝓋")
- ("mathalpha" "\\mscrw" 120012 "𝓌")
- ("mathalpha" "\\mscrx" 120013 "𝓍")
- ("mathalpha" "\\mscry" 120014 "𝓎")
- ("mathalpha" "\\mscrz" 120015 "𝓏")
- ("mathalpha" "\\mttA" 120432 "𝙰")
- ("mathalpha" "\\mttB" 120433 "𝙱")
- ("mathalpha" "\\mttC" 120434 "𝙲")
- ("mathalpha" "\\mttD" 120435 "𝙳")
- ("mathalpha" "\\mttE" 120436 "𝙴")
- ("mathalpha" "\\mttF" 120437 "𝙵")
- ("mathalpha" "\\mttG" 120438 "𝙶")
- ("mathalpha" "\\mttH" 120439 "𝙷")
- ("mathalpha" "\\mttI" 120440 "𝙸")
- ("mathalpha" "\\mttJ" 120441 "𝙹")
- ("mathalpha" "\\mttK" 120442 "𝙺")
- ("mathalpha" "\\mttL" 120443 "𝙻")
- ("mathalpha" "\\mttM" 120444 "𝙼")
- ("mathalpha" "\\mttN" 120445 "𝙽")
- ("mathalpha" "\\mttO" 120446 "𝙾")
- ("mathalpha" "\\mttP" 120447 "𝙿")
- ("mathalpha" "\\mttQ" 120448 "𝚀")
- ("mathalpha" "\\mttR" 120449 "𝚁")
- ("mathalpha" "\\mttS" 120450 "𝚂")
- ("mathalpha" "\\mttT" 120451 "𝚃")
- ("mathalpha" "\\mttU" 120452 "𝚄")
- ("mathalpha" "\\mttV" 120453 "𝚅")
- ("mathalpha" "\\mttW" 120454 "𝚆")
- ("mathalpha" "\\mttX" 120455 "𝚇")
- ("mathalpha" "\\mttY" 120456 "𝚈")
- ("mathalpha" "\\mttZ" 120457 "𝚉")
- ("mathalpha" "\\mtta" 120458 "𝚊")
- ("mathalpha" "\\mttb" 120459 "𝚋")
- ("mathalpha" "\\mttc" 120460 "𝚌")
- ("mathalpha" "\\mttd" 120461 "𝚍")
- ("mathalpha" "\\mtte" 120462 "𝚎")
- ("mathalpha" "\\mttf" 120463 "𝚏")
- ("mathalpha" "\\mttg" 120464 "𝚐")
- ("mathalpha" "\\mtth" 120465 "𝚑")
- ("mathalpha" "\\mtti" 120466 "𝚒")
- ("mathalpha" "\\mttj" 120467 "𝚓")
- ("mathalpha" "\\mttk" 120468 "𝚔")
- ("mathalpha" "\\mttl" 120469 "𝚕")
- ("mathalpha" "\\mttm" 120470 "𝚖")
- ("mathalpha" "\\mttn" 120471 "𝚗")
- ("mathalpha" "\\mtto" 120472 "𝚘")
- ("mathalpha" "\\mttp" 120473 "𝚙")
- ("mathalpha" "\\mttq" 120474 "𝚚")
- ("mathalpha" "\\mttr" 120475 "𝚛")
- ("mathalpha" "\\mtts" 120476 "𝚜")
- ("mathalpha" "\\mttt" 120477 "𝚝")
- ("mathalpha" "\\mttu" 120478 "𝚞")
- ("mathalpha" "\\mttv" 120479 "𝚟")
- ("mathalpha" "\\mttw" 120480 "𝚠")
- ("mathalpha" "\\mttx" 120481 "𝚡")
- ("mathalpha" "\\mtty" 120482 "𝚢")
- ("mathalpha" "\\mttz" 120483 "𝚣")
- ("mathalpha" "\\period" 46 ".")
- ("mathalpha" "\\turnediota" 8489 "℩")
- ("mathalpha" "\\upAlpha" 913 "Α")
- ("mathalpha" "\\upBeta" 914 "Β")
- ("mathalpha" "\\upChi" 935 "Χ")
- ("mathalpha" "\\upDelta" 916 "Δ")
- ("mathalpha" "\\upDigamma" 988 "Ϝ")
- ("mathalpha" "\\upEpsilon" 917 "Ε")
- ("mathalpha" "\\upEta" 919 "Η")
- ("mathalpha" "\\upGamma" 915 "Γ")
- ("mathalpha" "\\upIota" 921 "Ι")
- ("mathalpha" "\\upKappa" 922 "Κ")
- ("mathalpha" "\\upKoppa" 990 "Ϟ")
- ("mathalpha" "\\upLambda" 923 "Λ")
- ("mathalpha" "\\upMu" 924 "Μ")
- ("mathalpha" "\\upNu" 925 "Ν")
- ("mathalpha" "\\upOmega" 937 "Ω")
- ("mathalpha" "\\upOmicron" 927 "Ο")
- ("mathalpha" "\\upPhi" 934 "Φ")
- ("mathalpha" "\\upPi" 928 "Π")
- ("mathalpha" "\\upPsi" 936 "Ψ")
- ("mathalpha" "\\upRho" 929 "Ρ")
- ("mathalpha" "\\upSampi" 992 "Ϡ")
- ("mathalpha" "\\upSigma" 931 "Σ")
- ("mathalpha" "\\upStigma" 986 "Ϛ")
- ("mathalpha" "\\upTau" 932 "Τ")
- ("mathalpha" "\\upTheta" 920 "Θ")
- ("mathalpha" "\\upUpsilon" 933 "Υ")
- ("mathalpha" "\\upUpsilon" 978 "ϒ")
- ("mathalpha" "\\upXi" 926 "Ξ")
- ("mathalpha" "\\upZeta" 918 "Ζ")
- ("mathalpha" "\\upalpha" 945 "α")
- ("mathalpha" "\\upbeta" 946 "β")
- ("mathalpha" "\\upchi" 967 "χ")
- ("mathalpha" "\\updelta" 948 "δ")
- ("mathalpha" "\\updigamma" 989 "ϝ")
- ("mathalpha" "\\upepsilon" 949 "ε")
- ("mathalpha" "\\upeta" 951 "η")
- ("mathalpha" "\\upgamma" 947 "γ")
- ("mathalpha" "\\upiota" 953 "ι")
- ("mathalpha" "\\upkappa" 954 "κ")
- ("mathalpha" "\\upkoppa" 991 "ϟ")
- ("mathalpha" "\\uplambda" 955 "λ")
- ("mathalpha" "\\upmu" 956 "μ")
- ("mathalpha" "\\upnu" 957 "ν")
- ("mathalpha" "\\upomega" 969 "ω")
- ("mathalpha" "\\upomicron" 959 "ο")
- ("mathalpha" "\\upphi" 981 "ϕ")
- ("mathalpha" "\\uppi" 960 "π")
- ("mathalpha" "\\uppsi" 968 "ψ")
- ("mathalpha" "\\uprho" 961 "ρ")
- ("mathalpha" "\\upsampi" 993 "ϡ")
- ("mathalpha" "\\upsigma" 963 "σ")
- ("mathalpha" "\\upstigma" 987 "ϛ")
- ("mathalpha" "\\uptau" 964 "τ")
- ("mathalpha" "\\uptheta" 952 "θ")
- ("mathalpha" "\\upupsilon" 965 "υ")
- ("mathalpha" "\\upvarTheta" 1012 "ϴ")
- ("mathalpha" "\\upvarbeta" 976 "ϐ")
- ("mathalpha" "\\upvarepsilon" 1013 "ϵ")
- ("mathalpha" "\\upvarkappa" 1008 "ϰ")
- ("mathalpha" "\\upvarphi" 966 "φ")
- ("mathalpha" "\\upvarpi" 982 "ϖ")
- ("mathalpha" "\\upvarrho" 1009 "ϱ")
- ("mathalpha" "\\upvarsigma" 962 "ς")
- ("mathalpha" "\\upvartheta" 977 "ϑ")
- ("mathalpha" "\\upxi" 958 "ξ")
- ("mathalpha" "\\upzeta" 950 "ζ")
- ("mathalpha" "\\wp" 8472 "℘")
- ("mathbin" "\\Cap" 8914 "⋒")
- ("mathbin" "\\Cup" 8915 "⋓")
- ("mathbin" "\\Otimes" 10807 "⨷")
- ("mathbin" "\\Sqcap" 10830 "⩎")
- ("mathbin" "\\Sqcup" 10831 "⩏")
- ("mathbin" "\\Vee" 10836 "⩔")
- ("mathbin" "\\Wedge" 10835 "⩓")
- ("mathbin" "\\amalg" 10815 "⨿")
- ("mathbin" "\\ast" 8727 "∗")
- ("mathbin" "\\barcap" 10819 "⩃")
- ("mathbin" "\\barcup" 10818 "⩂")
- ("mathbin" "\\barvee" 8893 "⊽")
- ("mathbin" "\\barwedge" 8892 "⊼")
- ("mathbin" "\\bigslopedvee" 10839 "⩗")
- ("mathbin" "\\bigslopedwedge" 10840 "⩘")
- ("mathbin" "\\bigtriangledown" 9661 "▽")
- ("mathbin" "\\bigtriangleup" 9651 "△")
- ("mathbin" "\\blackhourglass" 10711 "⧗")
- ("mathbin" "\\blacktriangle" 9652 "▴")
- ("mathbin" "\\blacktriangledown" 9662 "▾")
- ("mathbin" "\\blacktriangleleft" 9664 "◀")
- ("mathbin" "\\blacktriangleright" 9654 "▶")
- ("mathbin" "\\boxast" 10694 "⧆")
- ("mathbin" "\\boxbar" 9707 "◫")
- ("mathbin" "\\boxbox" 10696 "⧈")
- ("mathbin" "\\boxbslash" 10693 "⧅")
- ("mathbin" "\\boxcircle" 10695 "⧇")
- ("mathbin" "\\boxdiag" 10692 "⧄")
- ("mathbin" "\\boxdot" 8865 "⊡")
- ("mathbin" "\\boxminus" 8863 "⊟")
- ("mathbin" "\\boxplus" 8862 "⊞")
- ("mathbin" "\\boxtimes" 8864 "⊠")
- ("mathbin" "\\btimes" 10802 "⨲")
- ("mathbin" "\\cap" 8745 "∩")
- ("mathbin" "\\capbarcup" 10825 "⩉")
- ("mathbin" "\\capdot" 10816 "⩀")
- ("mathbin" "\\capovercup" 10823 "⩇")
- ("mathbin" "\\capwedge" 10820 "⩄")
- ("mathbin" "\\cdot" 8901 "⋅")
- ("mathbin" "\\cdotp" 183 "·")
- ("mathbin" "\\circledast" 8859 "⊛")
- ("mathbin" "\\circledcirc" 8858 "⊚")
- ("mathbin" "\\circleddash" 8861 "⊝")
- ("mathbin" "\\circledequal" 8860 "⊜")
- ("mathbin" "\\circledparallel" 10679 "⦷")
- ("mathbin" "\\circledvert" 10678 "⦶")
- ("mathbin" "\\circlehbar" 10677 "⦵")
- ("mathbin" "\\closedvarcap" 10829 "⩍")
- ("mathbin" "\\closedvarcup" 10828 "⩌")
- ("mathbin" "\\closedvarcupsmashprod" 10832 "⩐")
- ("mathbin" "\\commaminus" 10793 "⨩")
- ("mathbin" "\\concavediamond" 10209 "⟡")
- ("mathbin" "\\concavediamondtickleft" 10210 "⟢")
- ("mathbin" "\\concavediamondtickright" 10211 "⟣")
- ("mathbin" "\\cup" 8746 "∪")
- ("mathbin" "\\cupbarcap" 10824 "⩈")
- ("mathbin" "\\cupdot" 8845 "⊍")
- ("mathbin" "\\cupleftarrow" 8844 "⊌")
- ("mathbin" "\\cupovercap" 10822 "⩆")
- ("mathbin" "\\cupvee" 10821 "⩅")
- ("mathbin" "\\curlyvee" 8910 "⋎")
- ("mathbin" "\\curlywedge" 8911 "⋏")
- ("mathbin" "\\dagger" 8224 "†")
- ("mathbin" "\\ddagger" 8225 "‡")
- ("mathbin" "\\div" 247 "÷")
- ("mathbin" "\\divideontimes" 8903 "⋇")
- ("mathbin" "\\divslash" 8725 "∕")
- ("mathbin" "\\dotminus" 8760 "∸")
- ("mathbin" "\\dotplus" 8724 "∔")
- ("mathbin" "\\dottimes" 10800 "⨰")
- ("mathbin" "\\doublebarvee" 10850 "⩢")
- ("mathbin" "\\doublebarwedge" 10846 "⩞")
- ("mathbin" "\\doubleplus" 10746 "⧺")
- ("mathbin" "\\dsol" 10742 "⧶")
- ("mathbin" "\\dsub" 10852 "⩤")
- ("mathbin" "\\eqqplus" 10865 "⩱")
- ("mathbin" "\\fcmp" 10814 "⨾")
- ("mathbin" "\\fracslash" 8260 "⁄")
- ("mathbin" "\\hourglass" 10710 "⧖")
- ("mathbin" "\\intercal" 8890 "⊺")
- ("mathbin" "\\interleave" 10996 "⫴")
- ("mathbin" "\\intprod" 10812 "⨼")
- ("mathbin" "\\intprodr" 10813 "⨽")
- ("mathbin" "\\invlazys" 8766 "∾")
- ("mathbin" "\\leftthreetimes" 8907 "⋋")
- ("mathbin" "\\lozengeminus" 10208 "⟠")
- ("mathbin" "\\ltimes" 8905 "⋉")
- ("mathbin" "\\mdlgblklozenge" 10731 "⧫")
- ("mathbin" "\\mdlgwhtcircle" 9675 "○")
- ("mathbin" "\\midbarvee" 10845 "⩝")
- ("mathbin" "\\midbarwedge" 10844 "⩜")
- ("mathbin" "\\minus" 8722 "−")
- ("mathbin" "\\minusdot" 10794 "⨪")
- ("mathbin" "\\minusfdots" 10795 "⨫")
- ("mathbin" "\\minusrdots" 10796 "⨬")
- ("mathbin" "\\mp" 8723 "∓")
- ("mathbin" "\\nhVvert" 10997 "⫵")
- ("mathbin" "\\obar" 9021 "⌽")
- ("mathbin" "\\obslash" 10680 "⦸")
- ("mathbin" "\\odiv" 10808 "⨸")
- ("mathbin" "\\odot" 8857 "⊙")
- ("mathbin" "\\ogreaterthan" 10689 "⧁")
- ("mathbin" "\\olessthan" 10688 "⧀")
- ("mathbin" "\\ominus" 8854 "⊖")
- ("mathbin" "\\operp" 10681 "⦹")
- ("mathbin" "\\oplus" 8853 "⊕")
- ("mathbin" "\\opluslhrim" 10797 "⨭")
- ("mathbin" "\\oplusrhrim" 10798 "⨮")
- ("mathbin" "\\oslash" 8856 "⊘")
- ("mathbin" "\\otimes" 8855 "⊗")
- ("mathbin" "\\otimeshat" 10806 "⨶")
- ("mathbin" "\\otimeslhrim" 10804 "⨴")
- ("mathbin" "\\otimesrhrim" 10805 "⨵")
- ("mathbin" "\\plus" 43 "+")
- ("mathbin" "\\plusdot" 10789 "⨥")
- ("mathbin" "\\pluseqq" 10866 "⩲")
- ("mathbin" "\\plushat" 10787 "⨣")
- ("mathbin" "\\plussim" 10790 "⨦")
- ("mathbin" "\\plussubtwo" 10791 "⨧")
- ("mathbin" "\\plustrif" 10792 "⨨")
- ("mathbin" "\\pm" 177 "±")
- ("mathbin" "\\rightthreetimes" 8908 "⋌")
- ("mathbin" "\\ringplus" 10786 "⨢")
- ("mathbin" "\\rsolbar" 10743 "⧷")
- ("mathbin" "\\rsub" 10853 "⩥")
- ("mathbin" "\\rtimes" 8906 "⋊")
- ("mathbin" "\\setminus" 10741 "⧵")
- ("mathbin" "\\shuffle" 10722 "⧢")
- ("mathbin" "\\simplus" 10788 "⨤")
- ("mathbin" "\\smallblacktriangleleft" 9666 "◂")
- ("mathbin" "\\smallblacktriangleright" 9656 "▸")
- ("mathbin" "\\smallsetminus" 8726 "∖")
- ("mathbin" "\\smalltriangleleft" 9667 "◃")
- ("mathbin" "\\smalltriangleright" 9657 "▹")
- ("mathbin" "\\smashtimes" 10803 "⨳")
- ("mathbin" "\\smblkcircle" 8226 "•")
- ("mathbin" "\\smwhtdiamond" 8900 "⋄")
- ("mathbin" "\\sqcap" 8851 "⊓")
- ("mathbin" "\\sqcup" 8852 "⊔")
- ("mathbin" "\\sslash" 11005 "⫽")
- ("mathbin" "\\star" 8902 "⋆")
- ("mathbin" "\\talloblong" 11006 "⫾")
- ("mathbin" "\\threedotcolon" 10998 "⫶")
- ("mathbin" "\\tieconcat" 8256 "⁀")
- ("mathbin" "\\times" 215 "×")
- ("mathbin" "\\timesbar" 10801 "⨱")
- ("mathbin" "\\tminus" 10751 "⧿")
- ("mathbin" "\\tplus" 10750 "⧾")
- ("mathbin" "\\triangledown" 9663 "▿")
- ("mathbin" "\\triangleleft" 9665 "◁")
- ("mathbin" "\\triangleminus" 10810 "⨺")
- ("mathbin" "\\triangleplus" 10809 "⨹")
- ("mathbin" "\\triangleright" 9655 "▷")
- ("mathbin" "\\triangleserifs" 10701 "⧍")
- ("mathbin" "\\triangletimes" 10811 "⨻")
- ("mathbin" "\\tripleplus" 10747 "⧻")
- ("mathbin" "\\trslash" 11003 "⫻")
- ("mathbin" "\\twocaps" 10827 "⩋")
- ("mathbin" "\\twocups" 10826 "⩊")
- ("mathbin" "\\typecolon" 10626 "⦂")
- ("mathbin" "\\uminus" 10817 "⩁")
- ("mathbin" "\\upand" 8523 "⅋")
- ("mathbin" "\\uplus" 8846 "⊎")
- ("mathbin" "\\varbarwedge" 8965 "⌅")
- ("mathbin" "\\vardoublebarwedge" 8966 "⌆")
- ("mathbin" "\\vartriangle" 9653 "▵")
- ("mathbin" "\\varveebar" 10849 "⩡")
- ("mathbin" "\\vectimes" 10799 "⨯")
- ("mathbin" "\\vee" 8744 "∨")
- ("mathbin" "\\veebar" 8891 "⊻")
- ("mathbin" "\\veedot" 10183 "⟇")
- ("mathbin" "\\veedoublebar" 10851 "⩣")
- ("mathbin" "\\veemidvert" 10843 "⩛")
- ("mathbin" "\\veeodot" 10834 "⩒")
- ("mathbin" "\\veeonvee" 10838 "⩖")
- ("mathbin" "\\vysmblkcircle" 8729 "∙")
- ("mathbin" "\\vysmwhtcircle" 8728 "∘")
- ("mathbin" "\\wedge" 8743 "∧")
- ("mathbin" "\\wedgebar" 10847 "⩟")
- ("mathbin" "\\wedgedot" 10193 "⟑")
- ("mathbin" "\\wedgedoublebar" 10848 "⩠")
- ("mathbin" "\\wedgemidvert" 10842 "⩚")
- ("mathbin" "\\wedgeodot" 10833 "⩑")
- ("mathbin" "\\wedgeonwedge" 10837 "⩕")
- ("mathbin" "\\whitesquaretickleft" 10212 "⟤")
- ("mathbin" "\\whitesquaretickright" 10213 "⟥")
- ("mathbin" "\\wr" 8768 "≀")
- ("mathclose" "\\Rbrbrak" 10221 "⟭")
- ("mathclose" "\\Rbrbrak" 12313 "〙")
- ("mathclose" "\\Rparenless" 10646 "⦖")
- ("mathclose" "\\Rvzigzag" 10715 "⧛")
- ("mathclose" "\\lrcorner" 8991 "⌟")
- ("mathclose" "\\rAngle" 10219 "⟫")
- ("mathclose" "\\rBrace" 10628 "⦄")
- ("mathclose" "\\rBrack" 10215 "⟧")
- ("mathclose" "\\rParen" 10630 "⦆")
- ("mathclose" "\\rangle" 10217 "⟩")
- ("mathclose" "\\rangledot" 10642 "⦒")
- ("mathclose" "\\rbag" 10182 "⟆")
- ("mathclose" "\\rblkbrbrak" 10648 "⦘")
- ("mathclose" "\\rbrace" 125 "}")
- ("mathclose" "\\rbrack" 93 "]")
- ("mathclose" "\\rbracklrtick" 10638 "⦎")
- ("mathclose" "\\rbrackubar" 10636 "⦌")
- ("mathclose" "\\rbrackurtick" 10640 "⦐")
- ("mathclose" "\\rbrbrak" 10099 "❳")
- ("mathclose" "\\rbrbrak" 12309 "〕")
- ("mathclose" "\\rceil" 8969 "⌉")
- ("mathclose" "\\rcurvyangle" 10749 "⧽")
- ("mathclose" "\\rfloor" 8971 "⌋")
- ("mathclose" "\\rparen" 41 ")")
- ("mathclose" "\\rparengtr" 10644 "⦔")
- ("mathclose" "\\rrangle" 10634 "⦊")
- ("mathclose" "\\rrparenthesis" 10632 "⦈")
- ("mathclose" "\\rvzigzag" 10713 "⧙")
- ("mathclose" "\\urcorner" 8989 "⌝")
- ("mathfence" "\\Vert" 8214 "‖")
- ("mathfence" "\\Vvert" 10624 "⦀")
- ("mathfence" "\\vert" 124 "|")
- ("mathop" "\\Bbbsum" 8512 "⅀")
- ("mathop" "\\Join" 10781 "⨝")
- ("mathop" "\\awint" 10769 "⨑")
- ("mathop" "\\bigbot" 10200 "⟘")
- ("mathop" "\\bigcap" 8898 "⋂")
- ("mathop" "\\bigcup" 8899 "⋃")
- ("mathop" "\\bigcupdot" 10755 "⨃")
- ("mathop" "\\biginterleave" 11004 "⫼")
- ("mathop" "\\bigodot" 10752 "⨀")
- ("mathop" "\\bigoplus" 10753 "⨁")
- ("mathop" "\\bigotimes" 10754 "⨂")
- ("mathop" "\\bigsqcap" 10757 "⨅")
- ("mathop" "\\bigsqcup" 10758 "⨆")
- ("mathop" "\\bigtalloblong" 11007 "⫿")
- ("mathop" "\\bigtimes" 10761 "⨉")
- ("mathop" "\\bigtop" 10201 "⟙")
- ("mathop" "\\bigtriangleleft" 10782 "⨞")
- ("mathop" "\\biguplus" 10756 "⨄")
- ("mathop" "\\bigvee" 8897 "⋁")
- ("mathop" "\\bigwedge" 8896 "⋀")
- ("mathop" "\\cirfnint" 10768 "⨐")
- ("mathop" "\\conjquant" 10759 "⨇")
- ("mathop" "\\coprod" 8720 "∐")
- ("mathop" "\\disjquant" 10760 "⨈")
- ("mathop" "\\fint" 10767 "⨏")
- ("mathop" "\\fullouterjoin" 10199 "⟗")
- ("mathop" "\\iiiint" 10764 "⨌")
- ("mathop" "\\iiint" 8749 "∭")
- ("mathop" "\\iint" 8748 "∬")
- ("mathop" "\\int" 8747 "∫")
- ("mathop" "\\intBar" 10766 "⨎")
- ("mathop" "\\intbar" 10765 "⨍")
- ("mathop" "\\intcap" 10777 "⨙")
- ("mathop" "\\intclockwise" 8753 "∱")
- ("mathop" "\\intcup" 10778 "⨚")
- ("mathop" "\\intlarhk" 10775 "⨗")
- ("mathop" "\\intx" 10776 "⨘")
- ("mathop" "\\leftouterjoin" 10197 "⟕")
- ("mathop" "\\lowint" 10780 "⨜")
- ("mathop" "\\npolint" 10772 "⨔")
- ("mathop" "\\oiiint" 8752 "∰")
- ("mathop" "\\oiint" 8751 "∯")
- ("mathop" "\\oint" 8750 "∮")
- ("mathop" "\\ointctrclockwise" 8755 "∳")
- ("mathop" "\\pointint" 10773 "⨕")
- ("mathop" "\\prod" 8719 "∏")
- ("mathop" "\\rightouterjoin" 10198 "⟖")
- ("mathop" "\\rppolint" 10770 "⨒")
- ("mathop" "\\scpolint" 10771 "⨓")
- ("mathop" "\\sqint" 10774 "⨖")
- ("mathop" "\\sum" 8721 "∑")
- ("mathop" "\\sumint" 10763 "⨋")
- ("mathop" "\\upint" 10779 "⨛")
- ("mathop" "\\varointclockwise" 8754 "∲")
- ("mathop" "\\xbsol" 10745 "⧹")
- ("mathop" "\\xsol" 10744 "⧸")
- ("mathop" "\\zcmp" 10783 "⨟")
- ("mathop" "\\zpipe" 10784 "⨠")
- ("mathop" "\\zproject" 10785 "⨡")
- ("mathopen" "\\Lbrbrak" 10220 "⟬")
- ("mathopen" "\\Lbrbrak" 12312 "〘")
- ("mathopen" "\\Lparengtr" 10645 "⦕")
- ("mathopen" "\\Lvzigzag" 10714 "⧚")
- ("mathopen" "\\lAngle" 10218 "⟪")
- ("mathopen" "\\lBrace" 10627 "⦃")
- ("mathopen" "\\lBrack" 10214 "⟦")
- ("mathopen" "\\lParen" 10629 "⦅")
- ("mathopen" "\\langle" 10216 "⟨")
- ("mathopen" "\\langledot" 10641 "⦑")
- ("mathopen" "\\lbag" 10181 "⟅")
- ("mathopen" "\\lblkbrbrak" 10647 "⦗")
- ("mathopen" "\\lbrace" 123 "{")
- ("mathopen" "\\lbrack" 91 "[")
- ("mathopen" "\\lbracklltick" 10639 "⦏")
- ("mathopen" "\\lbrackubar" 10635 "⦋")
- ("mathopen" "\\lbrackultick" 10637 "⦍")
- ("mathopen" "\\lbrbrak" 10098 "❲")
- ("mathopen" "\\lbrbrak" 12308 "〔")
- ("mathopen" "\\lceil" 8968 "⌈")
- ("mathopen" "\\lcurvyangle" 10748 "⧼")
- ("mathopen" "\\lfloor" 8970 "⌊")
- ("mathopen" "\\llangle" 10633 "⦉")
- ("mathopen" "\\llcorner" 8990 "⌞")
- ("mathopen" "\\llparenthesis" 10631 "⦇")
- ("mathopen" "\\longdivision" 10188 "⟌")
- ("mathopen" "\\lparen" 40 "(")
- ("mathopen" "\\lparenless" 10643 "⦓")
- ("mathopen" "\\lvzigzag" 10712 "⧘")
- ("mathopen" "\\ulcorner" 8988 "⌜")
- ("mathord" "\\APLboxquestion" 9072 "⍰")
- ("mathord" "\\APLboxupcaret" 9043 "⍓")
- ("mathord" "\\APLnotbackslash" 9024 "⍀")
- ("mathord" "\\Bbbeight" 120800 "𝟠")
- ("mathord" "\\Bbbfive" 120797 "𝟝")
- ("mathord" "\\Bbbfour" 120796 "𝟜")
- ("mathord" "\\Bbbnine" 120801 "𝟡")
- ("mathord" "\\Bbbone" 120793 "𝟙")
- ("mathord" "\\Bbbpi" 8508 "ℼ")
- ("mathord" "\\Bbbseven" 120799 "𝟟")
- ("mathord" "\\Bbbsix" 120798 "𝟞")
- ("mathord" "\\Bbbthree" 120795 "𝟛")
- ("mathord" "\\Bbbtwo" 120794 "𝟚")
- ("mathord" "\\Bbbzero" 120792 "𝟘")
- ("mathord" "\\Eulerconst" 8455 "ℇ")
- ("mathord" "\\Exclam" 8252 "‼")
- ("mathord" "\\Finv" 8498 "Ⅎ")
- ("mathord" "\\Game" 8513 "⅁")
- ("mathord" "\\Hermaphrodite" 9893 "⚥")
- ("mathord" "\\Planckconst" 8462 "ℎ")
- ("mathord" "\\PropertyLine" 8522 "⅊")
- ("mathord" "\\QED" 8718 "∎")
- ("mathord" "\\Question" 8263 "⁇")
- ("mathord" "\\Yup" 8516 "⅄")
- ("mathord" "\\Zbar" 437 "Ƶ")
- ("mathord" "\\accurrent" 9190 "⏦")
- ("mathord" "\\acidfree" 9854 "♾")
- ("mathord" "\\acwopencirclearrow" 8634 "↺")
- ("mathord" "\\ampersand" 38 "&")
- ("mathord" "\\angdnr" 10655 "⦟")
- ("mathord" "\\angle" 8736 "∠")
- ("mathord" "\\angles" 10654 "⦞")
- ("mathord" "\\angleubar" 10660 "⦤")
- ("mathord" "\\astrosun" 9737 "☉")
- ("mathord" "\\atsign" 64 "@")
- ("mathord" "\\backdprime" 8246 "‶")
- ("mathord" "\\backprime" 8245 "‵")
- ("mathord" "\\backslash" 92 "\\")
- ("mathord" "\\backtrprime" 8247 "‷")
- ("mathord" "\\barleftarrowrightarrowba" 8633 "↹")
- ("mathord" "\\barovernorthwestarrow" 8632 "↸")
- ("mathord" "\\bbrktbrk" 9142 "⎶")
- ("mathord" "\\bdtriplevdash" 9478 "┆")
- ("mathord" "\\because" 8757 "∵")
- ("mathord" "\\benzenr" 9187 "⏣")
- ("mathord" "\\bigblacktriangledown" 9660 "▼")
- ("mathord" "\\bigblacktriangleup" 9650 "▲")
- ("mathord" "\\bigstar" 9733 "★")
- ("mathord" "\\bigwhitestar" 9734 "☆")
- ("mathord" "\\blackcircledownarrow" 10733 "⧭")
- ("mathord" "\\blackcircledrightdot" 9864 "⚈")
- ("mathord" "\\blackcircledtwodots" 9865 "⚉")
- ("mathord" "\\blackcircleulquadwhite" 9685 "◕")
- ("mathord" "\\blackdiamonddownarrow" 10730 "⧪")
- ("mathord" "\\blackinwhitediamond" 9672 "◈")
- ("mathord" "\\blackinwhitesquare" 9635 "▣")
- ("mathord" "\\blacklefthalfcircle" 9686 "◖")
- ("mathord" "\\blackpointerleft" 9668 "◄")
- ("mathord" "\\blackpointerright" 9658 "►")
- ("mathord" "\\blackrighthalfcircle" 9687 "◗")
- ("mathord" "\\blacksmiley" 9787 "☻")
- ("mathord" "\\blkhorzoval" 11052 "⬬")
- ("mathord" "\\blkvertoval" 11054 "⬮")
- ("mathord" "\\blockfull" 9608 "█")
- ("mathord" "\\blockhalfshaded" 9618 "▒")
- ("mathord" "\\blocklefthalf" 9612 "▌")
- ("mathord" "\\blocklowhalf" 9604 "▄")
- ("mathord" "\\blockqtrshaded" 9617 "░")
- ("mathord" "\\blockrighthalf" 9616 "▐")
- ("mathord" "\\blockthreeqtrshaded" 9619 "▓")
- ("mathord" "\\blockuphalf" 9600 "▀")
- ("mathord" "\\bot" 8869 "⊥")
- ("mathord" "\\botsemicircle" 9697 "◡")
- ("mathord" "\\boxonbox" 10697 "⧉")
- ("mathord" "\\bullseye" 9678 "◎")
- ("mathord" "\\caretinsert" 8248 "‸")
- ("mathord" "\\carriagereturn" 8629 "↵")
- ("mathord" "\\checkmark" 10003 "✓")
- ("mathord" "\\cirE" 10691 "⧃")
- ("mathord" "\\circlebottomhalfblack" 9682 "◒")
- ("mathord" "\\circledbullet" 10687 "⦿")
- ("mathord" "\\circledownarrow" 10732 "⧬")
- ("mathord" "\\circledrightdot" 9862 "⚆")
- ("mathord" "\\circledstar" 10026 "✪")
- ("mathord" "\\circledtwodots" 9863 "⚇")
- ("mathord" "\\circledwhitebullet" 10686 "⦾")
- ("mathord" "\\circlelefthalfblack" 9680 "◐")
- ("mathord" "\\circlellquad" 9717 "◵")
- ("mathord" "\\circlelrquad" 9718 "◶")
- ("mathord" "\\circlerighthalfblack" 9681 "◑")
- ("mathord" "\\circletophalfblack" 9683 "◓")
- ("mathord" "\\circleulquad" 9716 "◴")
- ("mathord" "\\circleurquad" 9719 "◷")
- ("mathord" "\\circleurquadblack" 9684 "◔")
- ("mathord" "\\circlevertfill" 9677 "◍")
- ("mathord" "\\cirscir" 10690 "⧂")
- ("mathord" "\\clubsuit" 9827 "♣")
- ("mathord" "\\complement" 8705 "∁")
- ("mathord" "\\conictaper" 9010 "⌲")
- ("mathord" "\\cwopencirclearrow" 8635 "↻")
- ("mathord" "\\danger" 9761 "☡")
- ("mathord" "\\diameter" 8960 "⌀")
- ("mathord" "\\diamondbotblack" 11033 "⬙")
- ("mathord" "\\diamondcdot" 10192 "⟐")
- ("mathord" "\\diamondleftblack" 11030 "⬖")
- ("mathord" "\\diamondrightblack" 11031 "⬗")
- ("mathord" "\\diamondsuit" 9826 "♢")
- ("mathord" "\\diamondtopblack" 11032 "⬘")
- ("mathord" "\\dicei" 9856 "⚀")
- ("mathord" "\\diceii" 9857 "⚁")
- ("mathord" "\\diceiii" 9858 "⚂")
- ("mathord" "\\diceiv" 9859 "⚃")
- ("mathord" "\\dicev" 9860 "⚄")
- ("mathord" "\\dicevi" 9861 "⚅")
- ("mathord" "\\dingasterisk" 10045 "✽")
- ("mathord" "\\dottedcircle" 9676 "◌")
- ("mathord" "\\dottedsquare" 11034 "⬚")
- ("mathord" "\\downdasharrow" 8675 "⇣")
- ("mathord" "\\downrightcurvedarrow" 10549 "⤵")
- ("mathord" "\\downtriangleleftblack" 10728 "⧨")
- ("mathord" "\\downtrianglerightblack" 10729 "⧩")
- ("mathord" "\\downwhitearrow" 8681 "⇩")
- ("mathord" "\\dprime" 8243 "″")
- ("mathord" "\\draftingarrow" 10139 "➛")
- ("mathord" "\\eighthnote" 9834 "♪")
- ("mathord" "\\elinters" 9191 "⏧")
- ("mathord" "\\emptysetoarr" 10675 "⦳")
- ("mathord" "\\emptysetoarrl" 10676 "⦴")
- ("mathord" "\\emptysetobar" 10673 "⦱")
- ("mathord" "\\emptysetocirc" 10674 "⦲")
- ("mathord" "\\enleadertwodots" 8229 "‥")
- ("mathord" "\\errbarblackcircle" 10739 "⧳")
- ("mathord" "\\errbarblackdiamond" 10737 "⧱")
- ("mathord" "\\errbarblacksquare" 10735 "⧯")
- ("mathord" "\\errbarcircle" 10738 "⧲")
- ("mathord" "\\errbardiamond" 10736 "⧰")
- ("mathord" "\\errbarsquare" 10734 "⧮")
- ("mathord" "\\euro" 8364 "€")
- ("mathord" "\\exists" 8707 "∃")
- ("mathord" "\\fdiagovnearrow" 10543 "⤯")
- ("mathord" "\\fdiagovrdiag" 10540 "⤬")
- ("mathord" "\\female" 9792 "♀")
- ("mathord" "\\fisheye" 9673 "◉")
- ("mathord" "\\flat" 9837 "♭")
- ("mathord" "\\fltns" 9189 "⏥")
- ("mathord" "\\forall" 8704 "∀")
- ("mathord" "\\fourvdots" 10649 "⦙")
- ("mathord" "\\gtlpar" 10656 "⦠")
- ("mathord" "\\harrowextender" 9135 "⎯")
- ("mathord" "\\heartsuit" 9825 "♡")
- ("mathord" "\\hermitmatrix" 8889 "⊹")
- ("mathord" "\\hexagon" 9108 "⎔")
- ("mathord" "\\hexagonblack" 11043 "⬣")
- ("mathord" "\\horizbar" 8213 "―")
- ("mathord" "\\house" 8962 "⌂")
- ("mathord" "\\hrectangle" 9645 "▭")
- ("mathord" "\\hrectangleblack" 9644 "▬")
- ("mathord" "\\hyphenbullet" 8259 "⁃")
- ("mathord" "\\hzigzag" 12336 "〰")
- ("mathord" "\\iinfin" 10716 "⧜")
- ("mathord" "\\increment" 8710 "∆")
- ("mathord" "\\infty" 8734 "∞")
- ("mathord" "\\intbottom" 8993 "⌡")
- ("mathord" "\\intextender" 9134 "⎮")
- ("mathord" "\\inttop" 8992 "⌠")
- ("mathord" "\\inversebullet" 9688 "◘")
- ("mathord" "\\inversewhitecircle" 9689 "◙")
- ("mathord" "\\invnot" 8976 "⌐")
- ("mathord" "\\invwhitelowerhalfcircle" 9691 "◛")
- ("mathord" "\\invwhiteupperhalfcircle" 9690 "◚")
- ("mathord" "\\laplac" 10720 "⧠")
- ("mathord" "\\lbracelend" 9129 "⎩")
- ("mathord" "\\lbracemid" 9128 "⎨")
- ("mathord" "\\lbraceuend" 9127 "⎧")
- ("mathord" "\\lbrackextender" 9122 "⎢")
- ("mathord" "\\lbracklend" 9123 "⎣")
- ("mathord" "\\lbrackuend" 9121 "⎡")
- ("mathord" "\\leftdasharrow" 8672 "⇠")
- ("mathord" "\\leftmoon" 9790 "☾")
- ("mathord" "\\leftwhitearrow" 8678 "⇦")
- ("mathord" "\\lgblkcircle" 11044 "⬤")
- ("mathord" "\\lgblksquare" 11035 "⬛")
- ("mathord" "\\lgwhtcircle" 9711 "◯")
- ("mathord" "\\lgwhtsquare" 11036 "⬜")
- ("mathord" "\\linefeed" 8628 "↴")
- ("mathord" "\\llarc" 9695 "◟")
- ("mathord" "\\llblacktriangle" 9699 "◣")
- ("mathord" "\\lltriangle" 9722 "◺")
- ("mathord" "\\lmoustache" 9136 "⎰")
- ("mathord" "\\lparenextender" 9116 "⎜")
- ("mathord" "\\lparenlend" 9117 "⎝")
- ("mathord" "\\lparenuend" 9115 "⎛")
- ("mathord" "\\lrarc" 9694 "◞")
- ("mathord" "\\lrblacktriangle" 9698 "◢")
- ("mathord" "\\lrtriangle" 9727 "◿")
- ("mathord" "\\lvboxline" 9144 "⎸")
- ("mathord" "\\male" 9794 "♂")
- ("mathord" "\\maltese" 10016 "✠")
- ("mathord" "\\mathdollar" 36 "$")
- ("mathord" "\\mathslash" 47 "/")
- ("mathord" "\\mbfitnabla" 120629 "𝜵")
- ("mathord" "\\mbfitpartial" 120655 "𝝏")
- ("mathord" "\\mbfitsansnabla" 120745 "𝞩")
- ("mathord" "\\mbfitsanspartial" 120771 "𝟃")
- ("mathord" "\\mbfnabla" 120513 "𝛁")
- ("mathord" "\\mbfpartial" 120539 "𝛛")
- ("mathord" "\\mbfsanseight" 120820 "𝟴")
- ("mathord" "\\mbfsansfive" 120817 "𝟱")
- ("mathord" "\\mbfsansfour" 120816 "𝟰")
- ("mathord" "\\mbfsansnabla" 120687 "𝝯")
- ("mathord" "\\mbfsansnine" 120821 "𝟵")
- ("mathord" "\\mbfsansone" 120813 "𝟭")
- ("mathord" "\\mbfsanspartial" 120713 "𝞉")
- ("mathord" "\\mbfsansseven" 120819 "𝟳")
- ("mathord" "\\mbfsanssix" 120818 "𝟲")
- ("mathord" "\\mbfsansthree" 120815 "𝟯")
- ("mathord" "\\mbfsanstwo" 120814 "𝟮")
- ("mathord" "\\mbfsanszero" 120812 "𝟬")
- ("mathord" "\\mdblkcircle" 9899 "⚫")
- ("mathord" "\\mdblkdiamond" 11045 "⬥")
- ("mathord" "\\mdblklozenge" 11047 "⬧")
- ("mathord" "\\mdblksquare" 9724 "◼")
- ("mathord" "\\mdlgblkcircle" 9679 "●")
- ("mathord" "\\mdlgblkdiamond" 9670 "◆")
- ("mathord" "\\mdlgblksquare" 9632 "■")
- ("mathord" "\\mdlgwhtdiamond" 9671 "◇")
- ("mathord" "\\mdlgwhtlozenge" 9674 "◊")
- ("mathord" "\\mdlgwhtsquare" 9633 "□")
- ("mathord" "\\mdsmblkcircle" 10625 "⦁")
- ("mathord" "\\mdsmblksquare" 9726 "◾")
- ("mathord" "\\mdsmwhtcircle" 9900 "⚬")
- ("mathord" "\\mdsmwhtsquare" 9725 "◽")
- ("mathord" "\\mdwhtcircle" 9898 "⚪")
- ("mathord" "\\mdwhtdiamond" 11046 "⬦")
- ("mathord" "\\mdwhtlozenge" 11048 "⬨")
- ("mathord" "\\mdwhtsquare" 9723 "◻")
- ("mathord" "\\measangledltosw" 10671 "⦯")
- ("mathord" "\\measangledrtose" 10670 "⦮")
- ("mathord" "\\measangleldtosw" 10667 "⦫")
- ("mathord" "\\measanglelutonw" 10665 "⦩")
- ("mathord" "\\measanglerdtose" 10666 "⦪")
- ("mathord" "\\measanglerutone" 10664 "⦨")
- ("mathord" "\\measangleultonw" 10669 "⦭")
- ("mathord" "\\measangleurtone" 10668 "⦬")
- ("mathord" "\\measuredangle" 8737 "∡")
- ("mathord" "\\measuredangleleft" 10651 "⦛")
- ("mathord" "\\measuredrightangle" 8894 "⊾")
- ("mathord" "\\medblackstar" 11089 "⭑")
- ("mathord" "\\medwhitestar" 11088 "⭐")
- ("mathord" "\\mho" 8487 "℧")
- ("mathord" "\\mitBbbD" 8517 "ⅅ")
- ("mathord" "\\mitBbbd" 8518 "ⅆ")
- ("mathord" "\\mitBbbe" 8519 "ⅇ")
- ("mathord" "\\mitBbbi" 8520 "ⅈ")
- ("mathord" "\\mitBbbj" 8521 "ⅉ")
- ("mathord" "\\mitnabla" 120571 "𝛻")
- ("mathord" "\\mitpartial" 120597 "𝜕")
- ("mathord" "\\modtwosum" 10762 "⨊")
- ("mathord" "\\msanseight" 120810 "𝟪")
- ("mathord" "\\msansfive" 120807 "𝟧")
- ("mathord" "\\msansfour" 120806 "𝟦")
- ("mathord" "\\msansnine" 120811 "𝟫")
- ("mathord" "\\msansone" 120803 "𝟣")
- ("mathord" "\\msansseven" 120809 "𝟩")
- ("mathord" "\\msanssix" 120808 "𝟨")
- ("mathord" "\\msansthree" 120805 "𝟥")
- ("mathord" "\\msanstwo" 120804 "𝟤")
- ("mathord" "\\msanszero" 120802 "𝟢")
- ("mathord" "\\mtteight" 120830 "𝟾")
- ("mathord" "\\mttfive" 120827 "𝟻")
- ("mathord" "\\mttfour" 120826 "𝟺")
- ("mathord" "\\mttnine" 120831 "𝟿")
- ("mathord" "\\mttone" 120823 "𝟷")
- ("mathord" "\\mttseven" 120829 "𝟽")
- ("mathord" "\\mttsix" 120828 "𝟼")
- ("mathord" "\\mttthree" 120825 "𝟹")
- ("mathord" "\\mtttwo" 120824 "𝟸")
- ("mathord" "\\mttzero" 120822 "𝟶")
- ("mathord" "\\nHdownarrow" 8671 "⇟")
- ("mathord" "\\nHuparrow" 8670 "⇞")
- ("mathord" "\\nabla" 8711 "∇")
- ("mathord" "\\natural" 9838 "♮")
- ("mathord" "\\neg" 172 "¬")
- ("mathord" "\\neovnwarrow" 10545 "⤱")
- ("mathord" "\\neovsearrow" 10542 "⤮")
- ("mathord" "\\neuter" 9906 "⚲")
- ("mathord" "\\nexists" 8708 "∄")
- ("mathord" "\\nvinfty" 10718 "⧞")
- ("mathord" "\\nwovnearrow" 10546 "⤲")
- ("mathord" "\\obot" 10682 "⦺")
- ("mathord" "\\obrbrak" 9184 "⏠")
- ("mathord" "\\octothorpe" 35 "#")
- ("mathord" "\\odotslashdot" 10684 "⦼")
- ("mathord" "\\olcross" 10683 "⦻")
- ("mathord" "\\parallelogram" 9649 "▱")
- ("mathord" "\\parallelogramblack" 9648 "▰")
- ("mathord" "\\partial" 8706 "∂")
- ("mathord" "\\pentagon" 11040 "⬠")
- ("mathord" "\\pentagonblack" 11039 "⬟")
- ("mathord" "\\percent" 37 "%")
- ("mathord" "\\perps" 10977 "⫡")
- ("mathord" "\\postalmark" 12306 "〒")
- ("mathord" "\\prime" 8242 "′")
- ("mathord" "\\profline" 8978 "⌒")
- ("mathord" "\\profsurf" 8979 "⌓")
- ("mathord" "\\qprime" 8279 "⁗")
- ("mathord" "\\quarternote" 9833 "♩")
- ("mathord" "\\question" 63 "?")
- ("mathord" "\\rangledownzigzagarrow" 9084 "⍼")
- ("mathord" "\\rbracelend" 9133 "⎭")
- ("mathord" "\\rbracemid" 9132 "⎬")
- ("mathord" "\\rbraceuend" 9131 "⎫")
- ("mathord" "\\rbrackextender" 9125 "⎥")
- ("mathord" "\\rbracklend" 9126 "⎦")
- ("mathord" "\\rbrackuend" 9124 "⎤")
- ("mathord" "\\rdiagovfdiag" 10539 "⤫")
- ("mathord" "\\rdiagovsearrow" 10544 "⤰")
- ("mathord" "\\revangle" 10659 "⦣")
- ("mathord" "\\revangleubar" 10661 "⦥")
- ("mathord" "\\revemptyset" 10672 "⦰")
- ("mathord" "\\rightangle" 8735 "∟")
- ("mathord" "\\rightanglemdot" 10653 "⦝")
- ("mathord" "\\rightanglesqr" 10652 "⦜")
- ("mathord" "\\rightdasharrow" 8674 "⇢")
- ("mathord" "\\rightmoon" 9789 "☽")
- ("mathord" "\\rightpentagon" 11092 "⭔")
- ("mathord" "\\rightpentagonblack" 11091 "⭓")
- ("mathord" "\\rightwhitearrow" 8680 "⇨")
- ("mathord" "\\rmoustache" 9137 "⎱")
- ("mathord" "\\rparenextender" 9119 "⎟")
- ("mathord" "\\rparenlend" 9120 "⎠")
- ("mathord" "\\rparenuend" 9118 "⎞")
- ("mathord" "\\rvboxline" 9145 "⎹")
- ("mathord" "\\sansLmirrored" 8515 "⅃")
- ("mathord" "\\sansLturned" 8514 "⅂")
- ("mathord" "\\seovnearrow" 10541 "⤭")
- ("mathord" "\\sharp" 9839 "♯")
- ("mathord" "\\sinewave" 8767 "∿")
- ("mathord" "\\smblkdiamond" 11049 "⬩")
- ("mathord" "\\smblklozenge" 11050 "⬪")
- ("mathord" "\\smblksquare" 9642 "▪")
- ("mathord" "\\smwhitestar" 11090 "⭒")
- ("mathord" "\\smwhtcircle" 9702 "◦")
- ("mathord" "\\smwhtlozenge" 11051 "⬫")
- ("mathord" "\\smwhtsquare" 9643 "▫")
- ("mathord" "\\spadesuit" 9824 "♠")
- ("mathord" "\\sphericalangle" 8738 "∢")
- ("mathord" "\\sphericalangleup" 10657 "⦡")
- ("mathord" "\\sqlozenge" 8977 "⌑")
- ("mathord" "\\sqrtbottom" 9143 "⎷")
- ("mathord" "\\squarebotblack" 11027 "⬓")
- ("mathord" "\\squarecrossfill" 9641 "▩")
- ("mathord" "\\squarehfill" 9636 "▤")
- ("mathord" "\\squarehvfill" 9638 "▦")
- ("mathord" "\\squareleftblack" 9703 "◧")
- ("mathord" "\\squarellblack" 11029 "⬕")
- ("mathord" "\\squarellquad" 9713 "◱")
- ("mathord" "\\squarelrblack" 9706 "◪")
- ("mathord" "\\squarelrquad" 9714 "◲")
- ("mathord" "\\squareneswfill" 9640 "▨")
- ("mathord" "\\squarenwsefill" 9639 "▧")
- ("mathord" "\\squarerightblack" 9704 "◨")
- ("mathord" "\\squaretopblack" 11026 "⬒")
- ("mathord" "\\squareulblack" 9705 "◩")
- ("mathord" "\\squareulquad" 9712 "◰")
- ("mathord" "\\squareurblack" 11028 "⬔")
- ("mathord" "\\squareurquad" 9715 "◳")
- ("mathord" "\\squarevfill" 9637 "▥")
- ("mathord" "\\squoval" 9634 "▢")
- ("mathord" "\\sterling" 163 "£")
- ("mathord" "\\strns" 9188 "⏤")
- ("mathord" "\\subsetcirc" 10179 "⟃")
- ("mathord" "\\sumbottom" 9139 "⎳")
- ("mathord" "\\sumtop" 9138 "⎲")
- ("mathord" "\\sun" 9788 "☼")
- ("mathord" "\\supsetcirc" 10180 "⟄")
- ("mathord" "\\therefore" 8756 "∴")
- ("mathord" "\\thermod" 10727 "⧧")
- ("mathord" "\\threedangle" 10176 "⟀")
- ("mathord" "\\tieinfty" 10717 "⧝")
- ("mathord" "\\top" 8868 "⊤")
- ("mathord" "\\topbot" 9014 "⌶")
- ("mathord" "\\topcir" 10993 "⫱")
- ("mathord" "\\topsemicircle" 9696 "◠")
- ("mathord" "\\trapezium" 9186 "⏢")
- ("mathord" "\\trianglecdot" 9708 "◬")
- ("mathord" "\\triangleleftblack" 9709 "◭")
- ("mathord" "\\triangleodot" 10698 "⧊")
- ("mathord" "\\trianglerightblack" 9710 "◮")
- ("mathord" "\\triangles" 10700 "⧌")
- ("mathord" "\\triangleubar" 10699 "⧋")
- ("mathord" "\\trprime" 8244 "‴")
- ("mathord" "\\turnangle" 10658 "⦢")
- ("mathord" "\\turnednot" 8985 "⌙")
- ("mathord" "\\twolowline" 8215 "‗")
- ("mathord" "\\twonotes" 9835 "♫")
- ("mathord" "\\ubrbrak" 9185 "⏡")
- ("mathord" "\\ularc" 9692 "◜")
- ("mathord" "\\ulblacktriangle" 9700 "◤")
- ("mathord" "\\ultriangle" 9720 "◸")
- ("mathord" "\\unicodecdots" 8943 "⋯")
- ("mathord" "\\unicodeellipsis" 8230 "…")
- ("mathord" "\\uparrowoncircle" 10685 "⦽")
- ("mathord" "\\upbackepsilon" 1014 "϶")
- ("mathord" "\\updasharrow" 8673 "⇡")
- ("mathord" "\\updownarrowbar" 8616 "↨")
- ("mathord" "\\upoldKoppa" 984 "Ϙ")
- ("mathord" "\\upoldkoppa" 985 "ϙ")
- ("mathord" "\\uprightcurvearrow" 10548 "⤴")
- ("mathord" "\\upwhitearrow" 8679 "⇧")
- ("mathord" "\\urarc" 9693 "◝")
- ("mathord" "\\urblacktriangle" 9701 "◥")
- ("mathord" "\\urtriangle" 9721 "◹")
- ("mathord" "\\varcarriagereturn" 9166 "⏎")
- ("mathord" "\\varclubsuit" 9831 "♧")
- ("mathord" "\\vardiamondsuit" 9830 "♦")
- ("mathord" "\\varheartsuit" 9829 "♥")
- ("mathord" "\\varhexagon" 11041 "⬡")
- ("mathord" "\\varhexagonblack" 11042 "⬢")
- ("mathord" "\\varhexagonlrbonds" 9004 "⌬")
- ("mathord" "\\varlrtriangle" 8895 "⊿")
- ("mathord" "\\varnothing" 8709 "∅")
- ("mathord" "\\varspadesuit" 9828 "♤")
- ("mathord" "\\varstar" 10038 "✶")
- ("mathord" "\\vbraceextender" 9130 "⎪")
- ("mathord" "\\viewdata" 8983 "⌗")
- ("mathord" "\\vrectangle" 9647 "▯")
- ("mathord" "\\vrectangleblack" 9646 "▮")
- ("mathord" "\\vysmblksquare" 11037 "⬝")
- ("mathord" "\\vysmwhtsquare" 11038 "⬞")
- ("mathord" "\\vzigzag" 10650 "⦚")
- ("mathord" "\\whitearrowupfrombar" 8682 "⇪")
- ("mathord" "\\whiteinwhitetriangle" 10177 "⟁")
- ("mathord" "\\whitepointerleft" 9669 "◅")
- ("mathord" "\\whitepointerright" 9659 "▻")
- ("mathord" "\\whthorzoval" 11053 "⬭")
- ("mathord" "\\whtvertoval" 11055 "⬯")
- ("mathord" "\\wideangledown" 10662 "⦦")
- ("mathord" "\\wideangleup" 10663 "⦧")
- ("mathord" "\\yen" 165 "¥")
- ("mathover" "\\overbrace" 9182 "⏞")
- ("mathover" "\\overbracket" 9140 "⎴")
- ("mathover" "\\overparen" 9180 "⏜")
- ("mathpunct" "\\comma" 44 ",")
- ("mathpunct" "\\exclam" 33 "!")
- ("mathpunct" "\\mathcolon" 58 ":")
- ("mathpunct" "\\semicolon" 59 ";")
- ("mathradical" "\\cuberoot" 8731 "∛")
- ("mathradical" "\\fourthroot" 8732 "∜")
- ("mathradical" "\\sqrt" 8730 "√")
- ("mathrel" "\\APLnotslash" 9023 "⌿")
- ("mathrel" "\\Barv" 10983 "⫧")
- ("mathrel" "\\Bumpeq" 8782 "≎")
- ("mathrel" "\\Colon" 8759 "∷")
- ("mathrel" "\\Coloneq" 10868 "⩴")
- ("mathrel" "\\DDownarrow" 10225 "⟱")
- ("mathrel" "\\DashV" 10981 "⫥")
- ("mathrel" "\\DashVDash" 10202 "⟚")
- ("mathrel" "\\Dashv" 10980 "⫤")
- ("mathrel" "\\Ddownarrow" 10507 "⤋")
- ("mathrel" "\\Doteq" 8785 "≑")
- ("mathrel" "\\Downarrow" 8659 "⇓")
- ("mathrel" "\\Equiv" 8803 "≣")
- ("mathrel" "\\Gt" 10914 "⪢")
- ("mathrel" "\\LLeftarrow" 11077 "⭅")
- ("mathrel" "\\Ldsh" 8626 "↲")
- ("mathrel" "\\Leftarrow" 8656 "⇐")
- ("mathrel" "\\Leftrightarrow" 8660 "⇔")
- ("mathrel" "\\Lleftarrow" 8666 "⇚")
- ("mathrel" "\\Longleftarrow" 10232 "⟸")
- ("mathrel" "\\Longleftrightarrow" 10234 "⟺")
- ("mathrel" "\\Longmapsfrom" 10237 "⟽")
- ("mathrel" "\\Longmapsto" 10238 "⟾")
- ("mathrel" "\\Longrightarrow" 10233 "⟹")
- ("mathrel" "\\Lsh" 8624 "↰")
- ("mathrel" "\\Lt" 10913 "⪡")
- ("mathrel" "\\Mapsfrom" 10502 "⤆")
- ("mathrel" "\\Mapsto" 10503 "⤇")
- ("mathrel" "\\Nearrow" 8663 "⇗")
- ("mathrel" "\\Not" 10988 "⫬")
- ("mathrel" "\\Nwarrow" 8662 "⇖")
- ("mathrel" "\\Prec" 10939 "⪻")
- ("mathrel" "\\RRightarrow" 11078 "⭆")
- ("mathrel" "\\Rdsh" 8627 "↳")
- ("mathrel" "\\Rightarrow" 8658 "⇒")
- ("mathrel" "\\Rrightarrow" 8667 "⇛")
- ("mathrel" "\\Rsh" 8625 "↱")
- ("mathrel" "\\Searrow" 8664 "⇘")
- ("mathrel" "\\Subset" 8912 "⋐")
- ("mathrel" "\\Succ" 10940 "⪼")
- ("mathrel" "\\Supset" 8913 "⋑")
- ("mathrel" "\\Swarrow" 8665 "⇙")
- ("mathrel" "\\UUparrow" 10224 "⟰")
- ("mathrel" "\\Uparrow" 8657 "⇑")
- ("mathrel" "\\Updownarrow" 8661 "⇕")
- ("mathrel" "\\Uuparrow" 10506 "⤊")
- ("mathrel" "\\VDash" 8875 "⊫")
- ("mathrel" "\\Vbar" 10987 "⫫")
- ("mathrel" "\\Vdash" 8873 "⊩")
- ("mathrel" "\\Vvdash" 8874 "⊪")
- ("mathrel" "\\acwcirclearrow" 10560 "⥀")
- ("mathrel" "\\acwgapcirclearrow" 10226 "⟲")
- ("mathrel" "\\acwleftarcarrow" 10553 "⤹")
- ("mathrel" "\\acwoverarcarrow" 10554 "⤺")
- ("mathrel" "\\acwunderarcarrow" 10555 "⤻")
- ("mathrel" "\\adots" 8944 "⋰")
- ("mathrel" "\\approx" 8776 "≈")
- ("mathrel" "\\approxeq" 8778 "≊")
- ("mathrel" "\\approxeqq" 10864 "⩰")
- ("mathrel" "\\approxident" 8779 "≋")
- ("mathrel" "\\arceq" 8792 "≘")
- ("mathrel" "\\assert" 8870 "⊦")
- ("mathrel" "\\asteq" 10862 "⩮")
- ("mathrel" "\\asymp" 8781 "≍")
- ("mathrel" "\\bNot" 10989 "⫭")
- ("mathrel" "\\backcong" 8780 "≌")
- ("mathrel" "\\backsim" 8765 "∽")
- ("mathrel" "\\backsimeq" 8909 "⋍")
- ("mathrel" "\\bagmember" 8959 "⋿")
- ("mathrel" "\\barV" 10986 "⫪")
- ("mathrel" "\\bardownharpoonleft" 10593 "⥡")
- ("mathrel" "\\bardownharpoonright" 10589 "⥝")
- ("mathrel" "\\barleftarrow" 8676 "⇤")
- ("mathrel" "\\barleftharpoondown" 10582 "⥖")
- ("mathrel" "\\barleftharpoonup" 10578 "⥒")
- ("mathrel" "\\barrightarrowdiamond" 10528 "⤠")
- ("mathrel" "\\barrightharpoondown" 10591 "⥟")
- ("mathrel" "\\barrightharpoonup" 10587 "⥛")
- ("mathrel" "\\baruparrow" 10514 "⤒")
- ("mathrel" "\\barupharpoonleft" 10584 "⥘")
- ("mathrel" "\\barupharpoonright" 10580 "⥔")
- ("mathrel" "\\between" 8812 "≬")
- ("mathrel" "\\bowtie" 8904 "⋈")
- ("mathrel" "\\bsimilarleftarrow" 11073 "⭁")
- ("mathrel" "\\bsimilarrightarrow" 11079 "⭇")
- ("mathrel" "\\bsolhsub" 10184 "⟈")
- ("mathrel" "\\bumpeq" 8783 "≏")
- ("mathrel" "\\bumpeqq" 10926 "⪮")
- ("mathrel" "\\ccwundercurvearrow" 10559 "⤿")
- ("mathrel" "\\cirbot" 10207 "⟟")
- ("mathrel" "\\circeq" 8791 "≗")
- ("mathrel" "\\circleonleftarrow" 11056 "⬰")
- ("mathrel" "\\circleonrightarrow" 8692 "⇴")
- ("mathrel" "\\cirmid" 10991 "⫯")
- ("mathrel" "\\closure" 8272 "⁐")
- ("mathrel" "\\coloneq" 8788 "≔")
- ("mathrel" "\\cong" 8773 "≅")
- ("mathrel" "\\congdot" 10861 "⩭")
- ("mathrel" "\\csub" 10959 "⫏")
- ("mathrel" "\\csube" 10961 "⫑")
- ("mathrel" "\\csup" 10960 "⫐")
- ("mathrel" "\\csupe" 10962 "⫒")
- ("mathrel" "\\curlyeqprec" 8926 "⋞")
- ("mathrel" "\\curlyeqsucc" 8927 "⋟")
- ("mathrel" "\\curvearrowleft" 8630 "↶")
- ("mathrel" "\\curvearrowleftplus" 10557 "⤽")
- ("mathrel" "\\curvearrowright" 8631 "↷")
- ("mathrel" "\\curvearrowrightminus" 10556 "⤼")
- ("mathrel" "\\cwcirclearrow" 10561 "⥁")
- ("mathrel" "\\cwgapcirclearrow" 10227 "⟳")
- ("mathrel" "\\cwrightarcarrow" 10552 "⤸")
- ("mathrel" "\\cwundercurvearrow" 10558 "⤾")
- ("mathrel" "\\dashV" 10979 "⫣")
- ("mathrel" "\\dashVdash" 10203 "⟛")
- ("mathrel" "\\dashcolon" 8761 "∹")
- ("mathrel" "\\dashleftharpoondown" 10603 "⥫")
- ("mathrel" "\\dashrightharpoondown" 10605 "⥭")
- ("mathrel" "\\dashv" 8867 "⊣")
- ("mathrel" "\\dbkarow" 10511 "⤏")
- ("mathrel" "\\ddots" 8945 "⋱")
- ("mathrel" "\\ddotseq" 10871 "⩷")
- ("mathrel" "\\diamondleftarrow" 10525 "⤝")
- ("mathrel" "\\diamondleftarrowbar" 10527 "⤟")
- ("mathrel" "\\disin" 8946 "⋲")
- ("mathrel" "\\doteq" 8784 "≐")
- ("mathrel" "\\dotequiv" 10855 "⩧")
- ("mathrel" "\\dotsim" 10858 "⩪")
- ("mathrel" "\\dotsminusdots" 8762 "∺")
- ("mathrel" "\\downarrow" 8595 "↓")
- ("mathrel" "\\downarrowbar" 10515 "⤓")
- ("mathrel" "\\downarrowbarred" 10504 "⤈")
- ("mathrel" "\\downdownarrows" 8650 "⇊")
- ("mathrel" "\\downfishtail" 10623 "⥿")
- ("mathrel" "\\downharpoonleft" 8643 "⇃")
- ("mathrel" "\\downharpoonleftbar" 10585 "⥙")
- ("mathrel" "\\downharpoonright" 8642 "⇂")
- ("mathrel" "\\downharpoonrightbar" 10581 "⥕")
- ("mathrel" "\\downharpoonsleftright" 10597 "⥥")
- ("mathrel" "\\downuparrows" 8693 "⇵")
- ("mathrel" "\\downupharpoonsleftright" 10607 "⥯")
- ("mathrel" "\\downzigzagarrow" 8623 "↯")
- ("mathrel" "\\drbkarow" 10512 "⤐")
- ("mathrel" "\\dualmap" 10719 "⧟")
- ("mathrel" "\\egsdot" 10904 "⪘")
- ("mathrel" "\\elsdot" 10903 "⪗")
- ("mathrel" "\\eparsl" 10723 "⧣")
- ("mathrel" "\\eqcirc" 8790 "≖")
- ("mathrel" "\\eqcolon" 8789 "≕")
- ("mathrel" "\\eqdef" 8797 "≝")
- ("mathrel" "\\eqdot" 10854 "⩦")
- ("mathrel" "\\eqeq" 10869 "⩵")
- ("mathrel" "\\eqeqeq" 10870 "⩶")
- ("mathrel" "\\eqgtr" 8925 "⋝")
- ("mathrel" "\\eqless" 8924 "⋜")
- ("mathrel" "\\eqqgtr" 10906 "⪚")
- ("mathrel" "\\eqqless" 10905 "⪙")
- ("mathrel" "\\eqqsim" 10867 "⩳")
- ("mathrel" "\\eqqslantgtr" 10908 "⪜")
- ("mathrel" "\\eqqslantless" 10907 "⪛")
- ("mathrel" "\\eqsim" 8770 "≂")
- ("mathrel" "\\eqslantgtr" 10902 "⪖")
- ("mathrel" "\\eqslantless" 10901 "⪕")
- ("mathrel" "\\equal" 61 "=")
- ("mathrel" "\\equalleftarrow" 11072 "⭀")
- ("mathrel" "\\equalparallel" 8917 "⋕")
- ("mathrel" "\\equalrightarrow" 10609 "⥱")
- ("mathrel" "\\equiv" 8801 "≡")
- ("mathrel" "\\equivDD" 10872 "⩸")
- ("mathrel" "\\equivVert" 10856 "⩨")
- ("mathrel" "\\equivVvert" 10857 "⩩")
- ("mathrel" "\\eqvparsl" 10725 "⧥")
- ("mathrel" "\\fallingdotseq" 8786 "≒")
- ("mathrel" "\\fbowtie" 10707 "⧓")
- ("mathrel" "\\forks" 10972 "⫝̸")
- ("mathrel" "\\forksnot" 10973 "⫝")
- ("mathrel" "\\forkv" 10969 "⫙")
- ("mathrel" "\\frown" 8994 "⌢")
- ("mathrel" "\\geq" 8805 "≥")
- ("mathrel" "\\geqq" 8807 "≧")
- ("mathrel" "\\geqqslant" 11002 "⫺")
- ("mathrel" "\\geqslant" 10878 "⩾")
- ("mathrel" "\\gescc" 10921 "⪩")
- ("mathrel" "\\gesdot" 10880 "⪀")
- ("mathrel" "\\gesdoto" 10882 "⪂")
- ("mathrel" "\\gesdotol" 10884 "⪄")
- ("mathrel" "\\gesles" 10900 "⪔")
- ("mathrel" "\\gg" 8811 "≫")
- ("mathrel" "\\ggg" 8921 "⋙")
- ("mathrel" "\\gggnest" 11000 "⫸")
- ("mathrel" "\\glE" 10898 "⪒")
- ("mathrel" "\\gla" 10917 "⪥")
- ("mathrel" "\\gleichstark" 10726 "⧦")
- ("mathrel" "\\glj" 10916 "⪤")
- ("mathrel" "\\gnapprox" 10890 "⪊")
- ("mathrel" "\\gneq" 10888 "⪈")
- ("mathrel" "\\gneqq" 8809 "≩")
- ("mathrel" "\\gnsim" 8935 "⋧")
- ("mathrel" "\\greater" 62 ">")
- ("mathrel" "\\gsime" 10894 "⪎")
- ("mathrel" "\\gsiml" 10896 "⪐")
- ("mathrel" "\\gtcc" 10919 "⪧")
- ("mathrel" "\\gtcir" 10874 "⩺")
- ("mathrel" "\\gtquest" 10876 "⩼")
- ("mathrel" "\\gtrapprox" 10886 "⪆")
- ("mathrel" "\\gtrarr" 10616 "⥸")
- ("mathrel" "\\gtrdot" 8919 "⋗")
- ("mathrel" "\\gtreqless" 8923 "⋛")
- ("mathrel" "\\gtreqqless" 10892 "⪌")
- ("mathrel" "\\gtrless" 8823 "≷")
- ("mathrel" "\\gtrsim" 8819 "≳")
- ("mathrel" "\\hatapprox" 10863 "⩯")
- ("mathrel" "\\hknearrow" 10532 "⤤")
- ("mathrel" "\\hknwarrow" 10531 "⤣")
- ("mathrel" "\\hksearow" 10533 "⤥")
- ("mathrel" "\\hkswarow" 10534 "⤦")
- ("mathrel" "\\hookleftarrow" 8617 "↩")
- ("mathrel" "\\hookrightarrow" 8618 "↪")
- ("mathrel" "\\imageof" 8887 "⊷")
- ("mathrel" "\\in" 8712 "∈")
- ("mathrel" "\\isinE" 8953 "⋹")
- ("mathrel" "\\isindot" 8949 "⋵")
- ("mathrel" "\\isinobar" 8951 "⋷")
- ("mathrel" "\\isins" 8948 "⋴")
- ("mathrel" "\\isinvb" 8952 "⋸")
- ("mathrel" "\\kernelcontraction" 8763 "∻")
- ("mathrel" "\\lat" 10923 "⪫")
- ("mathrel" "\\late" 10925 "⪭")
- ("mathrel" "\\leftarrow" 8592 "←")
- ("mathrel" "\\leftarrowapprox" 11082 "⭊")
- ("mathrel" "\\leftarrowbackapprox" 11074 "⭂")
- ("mathrel" "\\leftarrowbsimilar" 11083 "⭋")
- ("mathrel" "\\leftarrowless" 10615 "⥷")
- ("mathrel" "\\leftarrowonoplus" 11058 "⬲")
- ("mathrel" "\\leftarrowplus" 10566 "⥆")
- ("mathrel" "\\leftarrowshortrightarrow" 10563 "⥃")
- ("mathrel" "\\leftarrowsimilar" 10611 "⥳")
- ("mathrel" "\\leftarrowsubset" 10618 "⥺")
- ("mathrel" "\\leftarrowtail" 8610 "↢")
- ("mathrel" "\\leftarrowtriangle" 8701 "⇽")
- ("mathrel" "\\leftarrowx" 11070 "⬾")
- ("mathrel" "\\leftbkarrow" 10508 "⤌")
- ("mathrel" "\\leftcurvedarrow" 11071 "⬿")
- ("mathrel" "\\leftdbkarrow" 10510 "⤎")
- ("mathrel" "\\leftdbltail" 10523 "⤛")
- ("mathrel" "\\leftdotarrow" 11064 "⬸")
- ("mathrel" "\\leftdowncurvedarrow" 10550 "⤶")
- ("mathrel" "\\leftfishtail" 10620 "⥼")
- ("mathrel" "\\leftharpoondown" 8637 "↽")
- ("mathrel" "\\leftharpoondownbar" 10590 "⥞")
- ("mathrel" "\\leftharpoonsupdown" 10594 "⥢")
- ("mathrel" "\\leftharpoonup" 8636 "↼")
- ("mathrel" "\\leftharpoonupbar" 10586 "⥚")
- ("mathrel" "\\leftharpoonupdash" 10602 "⥪")
- ("mathrel" "\\leftleftarrows" 8647 "⇇")
- ("mathrel" "\\leftrightarrow" 8596 "↔")
- ("mathrel" "\\leftrightarrowcircle" 10568 "⥈")
- ("mathrel" "\\leftrightarrows" 8646 "⇆")
- ("mathrel" "\\leftrightarrowtriangle" 8703 "⇿")
- ("mathrel" "\\leftrightharpoondowndown" 10576 "⥐")
- ("mathrel" "\\leftrightharpoondownup" 10571 "⥋")
- ("mathrel" "\\leftrightharpoons" 8651 "⇋")
- ("mathrel" "\\leftrightharpoonsdown" 10599 "⥧")
- ("mathrel" "\\leftrightharpoonsup" 10598 "⥦")
- ("mathrel" "\\leftrightharpoonupdown" 10570 "⥊")
- ("mathrel" "\\leftrightharpoonupup" 10574 "⥎")
- ("mathrel" "\\leftrightsquigarrow" 8621 "↭")
- ("mathrel" "\\leftsquigarrow" 8668 "⇜")
- ("mathrel" "\\lefttail" 10521 "⤙")
- ("mathrel" "\\leftthreearrows" 11057 "⬱")
- ("mathrel" "\\leftwavearrow" 8604 "↜")
- ("mathrel" "\\leq" 8804 "≤")
- ("mathrel" "\\leqq" 8806 "≦")
- ("mathrel" "\\leqqslant" 11001 "⫹")
- ("mathrel" "\\leqslant" 10877 "⩽")
- ("mathrel" "\\lescc" 10920 "⪨")
- ("mathrel" "\\lesdot" 10879 "⩿")
- ("mathrel" "\\lesdoto" 10881 "⪁")
- ("mathrel" "\\lesdotor" 10883 "⪃")
- ("mathrel" "\\lesges" 10899 "⪓")
- ("mathrel" "\\less" 60 "<")
- ("mathrel" "\\lessapprox" 10885 "⪅")
- ("mathrel" "\\lessdot" 8918 "⋖")
- ("mathrel" "\\lesseqgtr" 8922 "⋚")
- ("mathrel" "\\lesseqqgtr" 10891 "⪋")
- ("mathrel" "\\lessgtr" 8822 "≶")
- ("mathrel" "\\lesssim" 8818 "≲")
- ("mathrel" "\\lfbowtie" 10705 "⧑")
- ("mathrel" "\\lftimes" 10708 "⧔")
- ("mathrel" "\\lgE" 10897 "⪑")
- ("mathrel" "\\ll" 8810 "≪")
- ("mathrel" "\\lll" 8920 "⋘")
- ("mathrel" "\\lllnest" 10999 "⫷")
- ("mathrel" "\\lnapprox" 10889 "⪉")
- ("mathrel" "\\lneq" 10887 "⪇")
- ("mathrel" "\\lneqq" 8808 "≨")
- ("mathrel" "\\lnsim" 8934 "⋦")
- ("mathrel" "\\longdashv" 10206 "⟞")
- ("mathrel" "\\longleftarrow" 10229 "⟵")
- ("mathrel" "\\longleftrightarrow" 10231 "⟷")
- ("mathrel" "\\longleftsquigarrow" 11059 "⬳")
- ("mathrel" "\\longmapsfrom" 10235 "⟻")
- ("mathrel" "\\longmapsto" 10236 "⟼")
- ("mathrel" "\\longrightarrow" 10230 "⟶")
- ("mathrel" "\\longrightsquigarrow" 10239 "⟿")
- ("mathrel" "\\looparrowleft" 8619 "↫")
- ("mathrel" "\\looparrowright" 8620 "↬")
- ("mathrel" "\\lrtriangleeq" 10721 "⧡")
- ("mathrel" "\\lsime" 10893 "⪍")
- ("mathrel" "\\lsimg" 10895 "⪏")
- ("mathrel" "\\lsqhook" 10957 "⫍")
- ("mathrel" "\\ltcc" 10918 "⪦")
- ("mathrel" "\\ltcir" 10873 "⩹")
- ("mathrel" "\\ltlarr" 10614 "⥶")
- ("mathrel" "\\ltquest" 10875 "⩻")
- ("mathrel" "\\ltrivb" 10703 "⧏")
- ("mathrel" "\\mapsdown" 8615 "↧")
- ("mathrel" "\\mapsfrom" 8612 "↤")
- ("mathrel" "\\mapsto" 8614 "↦")
- ("mathrel" "\\mapsup" 8613 "↥")
- ("mathrel" "\\mathratio" 8758 "∶")
- ("mathrel" "\\measeq" 8798 "≞")
- ("mathrel" "\\mid" 8739 "∣")
- ("mathrel" "\\midcir" 10992 "⫰")
- ("mathrel" "\\mlcp" 10971 "⫛")
- ("mathrel" "\\models" 8871 "⊧")
- ("mathrel" "\\multimap" 8888 "⊸")
- ("mathrel" "\\multimapinv" 10204 "⟜")
- ("mathrel" "\\nLeftarrow" 8653 "⇍")
- ("mathrel" "\\nLeftrightarrow" 8654 "⇎")
- ("mathrel" "\\nRightarrow" 8655 "⇏")
- ("mathrel" "\\nVDash" 8879 "⊯")
- ("mathrel" "\\nVdash" 8878 "⊮")
- ("mathrel" "\\nVleftarrow" 8698 "⇺")
- ("mathrel" "\\nVleftarrowtail" 11066 "⬺")
- ("mathrel" "\\nVleftrightarrow" 8700 "⇼")
- ("mathrel" "\\nVrightarrow" 8699 "⇻")
- ("mathrel" "\\nVrightarrowtail" 10517 "⤕")
- ("mathrel" "\\nVtwoheadleftarrow" 11061 "⬵")
- ("mathrel" "\\nVtwoheadleftarrowtail" 11069 "⬽")
- ("mathrel" "\\nVtwoheadrightarrow" 10497 "⤁")
- ("mathrel" "\\nVtwoheadrightarrowtail" 10520 "⤘")
- ("mathrel" "\\napprox" 8777 "≉")
- ("mathrel" "\\nasymp" 8813 "≭")
- ("mathrel" "\\ncong" 8775 "≇")
- ("mathrel" "\\ne" 8800 "≠")
- ("mathrel" "\\nearrow" 8599 "↗")
- ("mathrel" "\\nequiv" 8802 "≢")
- ("mathrel" "\\neswarrow" 10530 "⤢")
- ("mathrel" "\\ngeq" 8817 "≱")
- ("mathrel" "\\ngtr" 8815 "≯")
- ("mathrel" "\\ngtrless" 8825 "≹")
- ("mathrel" "\\ngtrsim" 8821 "≵")
- ("mathrel" "\\nhpar" 10994 "⫲")
- ("mathrel" "\\ni" 8715 "∋")
- ("mathrel" "\\niobar" 8958 "⋾")
- ("mathrel" "\\nis" 8956 "⋼")
- ("mathrel" "\\nisd" 8954 "⋺")
- ("mathrel" "\\nleftarrow" 8602 "↚")
- ("mathrel" "\\nleftrightarrow" 8622 "↮")
- ("mathrel" "\\nleq" 8816 "≰")
- ("mathrel" "\\nless" 8814 "≮")
- ("mathrel" "\\nlessgtr" 8824 "≸")
- ("mathrel" "\\nlesssim" 8820 "≴")
- ("mathrel" "\\nmid" 8740 "∤")
- ("mathrel" "\\nni" 8716 "∌")
- ("mathrel" "\\notin" 8713 "∉")
- ("mathrel" "\\nparallel" 8742 "∦")
- ("mathrel" "\\nprec" 8832 "⊀")
- ("mathrel" "\\npreccurlyeq" 8928 "⋠")
- ("mathrel" "\\nrightarrow" 8603 "↛")
- ("mathrel" "\\nsim" 8769 "≁")
- ("mathrel" "\\nsime" 8772 "≄")
- ("mathrel" "\\nsqsubseteq" 8930 "⋢")
- ("mathrel" "\\nsqsupseteq" 8931 "⋣")
- ("mathrel" "\\nsubset" 8836 "⊄")
- ("mathrel" "\\nsubseteq" 8840 "⊈")
- ("mathrel" "\\nsucc" 8833 "⊁")
- ("mathrel" "\\nsucccurlyeq" 8929 "⋡")
- ("mathrel" "\\nsupset" 8837 "⊅")
- ("mathrel" "\\nsupseteq" 8841 "⊉")
- ("mathrel" "\\ntriangleleft" 8938 "⋪")
- ("mathrel" "\\ntrianglelefteq" 8940 "⋬")
- ("mathrel" "\\ntriangleright" 8939 "⋫")
- ("mathrel" "\\ntrianglerighteq" 8941 "⋭")
- ("mathrel" "\\nvDash" 8877 "⊭")
- ("mathrel" "\\nvLeftarrow" 10498 "⤂")
- ("mathrel" "\\nvLeftrightarrow" 10500 "⤄")
- ("mathrel" "\\nvRightarrow" 10499 "⤃")
- ("mathrel" "\\nvdash" 8876 "⊬")
- ("mathrel" "\\nvleftarrow" 8695 "⇷")
- ("mathrel" "\\nvleftarrowtail" 11065 "⬹")
- ("mathrel" "\\nvleftrightarrow" 8697 "⇹")
- ("mathrel" "\\nvrightarrow" 8696 "⇸")
- ("mathrel" "\\nvrightarrowtail" 10516 "⤔")
- ("mathrel" "\\nvtwoheadleftarrow" 11060 "⬴")
- ("mathrel" "\\nvtwoheadleftarrowtail" 11068 "⬼")
- ("mathrel" "\\nvtwoheadrightarrow" 10496 "⤀")
- ("mathrel" "\\nvtwoheadrightarrowtail" 10519 "⤗")
- ("mathrel" "\\nwarrow" 8598 "↖")
- ("mathrel" "\\nwsearrow" 10529 "⤡")
- ("mathrel" "\\origof" 8886 "⊶")
- ("mathrel" "\\parallel" 8741 "∥")
- ("mathrel" "\\parsim" 10995 "⫳")
- ("mathrel" "\\partialmeetcontraction" 10915 "⪣")
- ("mathrel" "\\perp" 10178 "⟂")
- ("mathrel" "\\pitchfork" 8916 "⋔")
- ("mathrel" "\\prec" 8826 "≺")
- ("mathrel" "\\precapprox" 10935 "⪷")
- ("mathrel" "\\preccurlyeq" 8828 "≼")
- ("mathrel" "\\preceq" 10927 "⪯")
- ("mathrel" "\\preceqq" 10931 "⪳")
- ("mathrel" "\\precnapprox" 10937 "⪹")
- ("mathrel" "\\precneq" 10929 "⪱")
- ("mathrel" "\\precneqq" 10933 "⪵")
- ("mathrel" "\\precnsim" 8936 "⋨")
- ("mathrel" "\\precsim" 8830 "≾")
- ("mathrel" "\\propto" 8733 "∝")
- ("mathrel" "\\prurel" 8880 "⊰")
- ("mathrel" "\\pullback" 10195 "⟓")
- ("mathrel" "\\pushout" 10196 "⟔")
- ("mathrel" "\\questeq" 8799 "≟")
- ("mathrel" "\\revnmid" 10990 "⫮")
- ("mathrel" "\\rfbowtie" 10706 "⧒")
- ("mathrel" "\\rftimes" 10709 "⧕")
- ("mathrel" "\\rightarrow" 8594 "→")
- ("mathrel" "\\rightarrowapprox" 10613 "⥵")
- ("mathrel" "\\rightarrowbackapprox" 11080 "⭈")
- ("mathrel" "\\rightarrowbar" 8677 "⇥")
- ("mathrel" "\\rightarrowbsimilar" 11084 "⭌")
- ("mathrel" "\\rightarrowdiamond" 10526 "⤞")
- ("mathrel" "\\rightarrowgtr" 11075 "⭃")
- ("mathrel" "\\rightarrowonoplus" 10228 "⟴")
- ("mathrel" "\\rightarrowplus" 10565 "⥅")
- ("mathrel" "\\rightarrowshortleftarrow" 10562 "⥂")
- ("mathrel" "\\rightarrowsimilar" 10612 "⥴")
- ("mathrel" "\\rightarrowsupset" 11076 "⭄")
- ("mathrel" "\\rightarrowtail" 8611 "↣")
- ("mathrel" "\\rightarrowtriangle" 8702 "⇾")
- ("mathrel" "\\rightarrowx" 10567 "⥇")
- ("mathrel" "\\rightbkarrow" 10509 "⤍")
- ("mathrel" "\\rightcurvedarrow" 10547 "⤳")
- ("mathrel" "\\rightdbltail" 10524 "⤜")
- ("mathrel" "\\rightdotarrow" 10513 "⤑")
- ("mathrel" "\\rightdowncurvedarrow" 10551 "⤷")
- ("mathrel" "\\rightfishtail" 10621 "⥽")
- ("mathrel" "\\rightharpoondown" 8641 "⇁")
- ("mathrel" "\\rightharpoondownbar" 10583 "⥗")
- ("mathrel" "\\rightharpoonsupdown" 10596 "⥤")
- ("mathrel" "\\rightharpoonup" 8640 "⇀")
- ("mathrel" "\\rightharpoonupbar" 10579 "⥓")
- ("mathrel" "\\rightharpoonupdash" 10604 "⥬")
- ("mathrel" "\\rightimply" 10608 "⥰")
- ("mathrel" "\\rightleftarrows" 8644 "⇄")
- ("mathrel" "\\rightleftharpoons" 8652 "⇌")
- ("mathrel" "\\rightleftharpoonsdown" 10601 "⥩")
- ("mathrel" "\\rightleftharpoonsup" 10600 "⥨")
- ("mathrel" "\\rightrightarrows" 8649 "⇉")
- ("mathrel" "\\rightsquigarrow" 8669 "⇝")
- ("mathrel" "\\righttail" 10522 "⤚")
- ("mathrel" "\\rightthreearrows" 8694 "⇶")
- ("mathrel" "\\rightwavearrow" 8605 "↝")
- ("mathrel" "\\risingdotseq" 8787 "≓")
- ("mathrel" "\\rsqhook" 10958 "⫎")
- ("mathrel" "\\rtriltri" 10702 "⧎")
- ("mathrel" "\\ruledelayed" 10740 "⧴")
- ("mathrel" "\\scurel" 8881 "⊱")
- ("mathrel" "\\searrow" 8600 "↘")
- ("mathrel" "\\shortdowntack" 10975 "⫟")
- ("mathrel" "\\shortlefttack" 10974 "⫞")
- ("mathrel" "\\shortrightarrowleftarrow" 10564 "⥄")
- ("mathrel" "\\shortuptack" 10976 "⫠")
- ("mathrel" "\\sim" 8764 "∼")
- ("mathrel" "\\simeq" 8771 "≃")
- ("mathrel" "\\simgE" 10912 "⪠")
- ("mathrel" "\\simgtr" 10910 "⪞")
- ("mathrel" "\\similarleftarrow" 11081 "⭉")
- ("mathrel" "\\similarrightarrow" 10610 "⥲")
- ("mathrel" "\\simlE" 10911 "⪟")
- ("mathrel" "\\simless" 10909 "⪝")
- ("mathrel" "\\simminussim" 10860 "⩬")
- ("mathrel" "\\simneqq" 8774 "≆")
- ("mathrel" "\\simrdots" 10859 "⩫")
- ("mathrel" "\\smallin" 8714 "∊")
- ("mathrel" "\\smallni" 8717 "∍")
- ("mathrel" "\\smeparsl" 10724 "⧤")
- ("mathrel" "\\smile" 8995 "⌣")
- ("mathrel" "\\smt" 10922 "⪪")
- ("mathrel" "\\smte" 10924 "⪬")
- ("mathrel" "\\sqsubset" 8847 "⊏")
- ("mathrel" "\\sqsubseteq" 8849 "⊑")
- ("mathrel" "\\sqsubsetneq" 8932 "⋤")
- ("mathrel" "\\sqsupset" 8848 "⊐")
- ("mathrel" "\\sqsupseteq" 8850 "⊒")
- ("mathrel" "\\sqsupsetneq" 8933 "⋥")
- ("mathrel" "\\stareq" 8795 "≛")
- ("mathrel" "\\subedot" 10947 "⫃")
- ("mathrel" "\\submult" 10945 "⫁")
- ("mathrel" "\\subrarr" 10617 "⥹")
- ("mathrel" "\\subset" 8834 "⊂")
- ("mathrel" "\\subsetapprox" 10953 "⫉")
- ("mathrel" "\\subsetdot" 10941 "⪽")
- ("mathrel" "\\subseteq" 8838 "⊆")
- ("mathrel" "\\subseteqq" 10949 "⫅")
- ("mathrel" "\\subsetneq" 8842 "⊊")
- ("mathrel" "\\subsetneqq" 10955 "⫋")
- ("mathrel" "\\subsetplus" 10943 "⪿")
- ("mathrel" "\\subsim" 10951 "⫇")
- ("mathrel" "\\subsub" 10965 "⫕")
- ("mathrel" "\\subsup" 10963 "⫓")
- ("mathrel" "\\succ" 8827 "≻")
- ("mathrel" "\\succapprox" 10936 "⪸")
- ("mathrel" "\\succcurlyeq" 8829 "≽")
- ("mathrel" "\\succeq" 10928 "⪰")
- ("mathrel" "\\succeqq" 10932 "⪴")
- ("mathrel" "\\succnapprox" 10938 "⪺")
- ("mathrel" "\\succneq" 10930 "⪲")
- ("mathrel" "\\succneqq" 10934 "⪶")
- ("mathrel" "\\succnsim" 8937 "⋩")
- ("mathrel" "\\succsim" 8831 "≿")
- ("mathrel" "\\supdsub" 10968 "⫘")
- ("mathrel" "\\supedot" 10948 "⫄")
- ("mathrel" "\\suphsol" 10185 "⟉")
- ("mathrel" "\\suphsub" 10967 "⫗")
- ("mathrel" "\\suplarr" 10619 "⥻")
- ("mathrel" "\\supmult" 10946 "⫂")
- ("mathrel" "\\supset" 8835 "⊃")
- ("mathrel" "\\supsetapprox" 10954 "⫊")
- ("mathrel" "\\supsetdot" 10942 "⪾")
- ("mathrel" "\\supseteq" 8839 "⊇")
- ("mathrel" "\\supseteqq" 10950 "⫆")
- ("mathrel" "\\supsetneq" 8843 "⊋")
- ("mathrel" "\\supsetneqq" 10956 "⫌")
- ("mathrel" "\\supsetplus" 10944 "⫀")
- ("mathrel" "\\supsim" 10952 "⫈")
- ("mathrel" "\\supsub" 10964 "⫔")
- ("mathrel" "\\supsup" 10966 "⫖")
- ("mathrel" "\\swarrow" 8601 "↙")
- ("mathrel" "\\toea" 10536 "⤨")
- ("mathrel" "\\tona" 10535 "⤧")
- ("mathrel" "\\topfork" 10970 "⫚")
- ("mathrel" "\\tosa" 10537 "⤩")
- ("mathrel" "\\towa" 10538 "⤪")
- ("mathrel" "\\trianglelefteq" 8884 "⊴")
- ("mathrel" "\\triangleq" 8796 "≜")
- ("mathrel" "\\trianglerighteq" 8885 "⊵")
- ("mathrel" "\\twoheaddownarrow" 8609 "↡")
- ("mathrel" "\\twoheadleftarrow" 8606 "↞")
- ("mathrel" "\\twoheadleftarrowtail" 11067 "⬻")
- ("mathrel" "\\twoheadleftdbkarrow" 11063 "⬷")
- ("mathrel" "\\twoheadmapsfrom" 11062 "⬶")
- ("mathrel" "\\twoheadmapsto" 10501 "⤅")
- ("mathrel" "\\twoheadrightarrow" 8608 "↠")
- ("mathrel" "\\twoheadrightarrowtail" 10518 "⤖")
- ("mathrel" "\\twoheaduparrow" 8607 "↟")
- ("mathrel" "\\twoheaduparrowcircle" 10569 "⥉")
- ("mathrel" "\\uparrow" 8593 "↑")
- ("mathrel" "\\uparrowbarred" 10505 "⤉")
- ("mathrel" "\\updownarrow" 8597 "↕")
- ("mathrel" "\\updownarrows" 8645 "⇅")
- ("mathrel" "\\updownharpoonleftleft" 10577 "⥑")
- ("mathrel" "\\updownharpoonleftright" 10573 "⥍")
- ("mathrel" "\\updownharpoonrightleft" 10572 "⥌")
- ("mathrel" "\\updownharpoonrightright" 10575 "⥏")
- ("mathrel" "\\updownharpoonsleftright" 10606 "⥮")
- ("mathrel" "\\upfishtail" 10622 "⥾")
- ("mathrel" "\\upharpoonleft" 8639 "↿")
- ("mathrel" "\\upharpoonleftbar" 10592 "⥠")
- ("mathrel" "\\upharpoonright" 8638 "↾")
- ("mathrel" "\\upharpoonrightbar" 10588 "⥜")
- ("mathrel" "\\upharpoonsleftright" 10595 "⥣")
- ("mathrel" "\\upin" 10194 "⟒")
- ("mathrel" "\\upuparrows" 8648 "⇈")
- ("mathrel" "\\vBar" 10984 "⫨")
- ("mathrel" "\\vBarv" 10985 "⫩")
- ("mathrel" "\\vDash" 8872 "⊨")
- ("mathrel" "\\vDdash" 10978 "⫢")
- ("mathrel" "\\varVdash" 10982 "⫦")
- ("mathrel" "\\varisinobar" 8950 "⋶")
- ("mathrel" "\\varisins" 8947 "⋳")
- ("mathrel" "\\varniobar" 8957 "⋽")
- ("mathrel" "\\varnis" 8955 "⋻")
- ("mathrel" "\\vartriangleleft" 8882 "⊲")
- ("mathrel" "\\vartriangleright" 8883 "⊳")
- ("mathrel" "\\vbrtri" 10704 "⧐")
- ("mathrel" "\\vdash" 8866 "⊢")
- ("mathrel" "\\vdots" 8942 "⋮")
- ("mathrel" "\\veeeq" 8794 "≚")
- ("mathrel" "\\veeonwedge" 10841 "⩙")
- ("mathrel" "\\vlongdash" 10205 "⟝")
- ("mathrel" "\\wedgeq" 8793 "≙")
- ("mathunder" "\\underbrace" 9183 "⏟")
- ("mathunder" "\\underbracket" 9141 "⎵")
- ("mathunder" "\\underparen" 9181 "⏝"))
- ;; FIXME: Describe the expected shape of the contents (i.e. a list of
- ;; 4-tuples, but I'm not sure what those 4 elements mean:
- ;; - why is the first a string rather than a symbol?
- ;; - What's the difference between the 3rd and the 4th (other than: one is
- ;; a char and the other is a single-char string)?
- "Extended list of mathematical symbols.
-Each element is a list of the form (CLASS COMMAND UNICODE SYMBOL)
-where COMMAND is a latex command, UNICODE is the unicode entry
-point and SYMBOL is the Emacs with the actual unicode
-character. The last two are equivalent and provided for
-convenience. This list does not include about 190 of the standard
-LaTeX math commands in `math-symbol-list-basic' because of the
-conflicting names between latex and unicode-math standard.")
-
-(defconst math-symbol-list-packages
- '(("amsfonts" "mathclose" "\\urcorner" 8989 "⌝")
- ("amsfonts" "mathclose" "\\lrcorner" 8991 "⌟")
- ("amsfonts" "mathopen" "\\ulcorner" 8988 "⌜")
- ("amsfonts" "mathopen" "\\llcorner" 8990 "⌞")
- ("amsfonts" "mathord" "\\yen" 165 "¥")
- ("amsfonts" "mathord" "\\circledR" 174 "®")
- ("amsfonts" "mathord" "\\mho" 8487 "℧")
- ("amsfonts" "mathord" "\\dashleftarrow" 8672 "⇠")
- ("amsfonts" "mathord" "\\dashrightarrow" 8674 "⇢")
- ("amsfonts" "mathord" "\\checkmark" 10003 "✓")
- ("amsfonts" "mathord" "\\maltese" 10016 "✠")
- ("amsfonts" "mathrel" "\\sqsubset" 8847 "⊏")
- ("amsfonts" "mathrel" "\\sqsupset" 8848 "⊐")
- ("amsmath" "mathaccent" "\\dddot" 8411 "⃛")
- ("amsmath" "mathaccent" "\\ddddot" 8412 "⃜")
- ("amsmath" "mathaccent" "\\overleftrightarrow" 8417 "⃡")
- ("amsmath" "mathaccent" "\\underleftarrow" 8430 "⃮")
- ("amsmath" "mathaccent" "\\underrightarrow" 8431 "⃯")
- ("amsmath" "mathop" "\\iint" 8748 "∬")
- ("amsmath" "mathop" "\\iiint" 8749 "∭")
- ("amsmath" "mathop" "\\iiiint" 10764 "⨌")
- ("amssymb" "mathaccent" "\\mathring" 778 "̊")
- ("amssymb" "mathalpha" "\\eth" 240 "ð")
- ("amssymb" "mathalpha" "\\Digamma" 988 "Ϝ" t)
- ("amssymb" "mathalpha" "\\hslash" 8463 "ℏ")
- ("amssymb" "mathalpha" "\\wp" 8472 "℘")
- ("amssymb" "mathalpha" "\\beth" 8502 "ℶ")
- ("amssymb" "mathalpha" "\\gimel" 8503 "ℷ")
- ("amssymb" "mathalpha" "\\daleth" 8504 "ℸ")
- ("amssymb" "mathalpha" "\\varkappa" 120600 "𝜘")
- ("amssymb" "mathbin" "\\dotplus" 8724 "∔")
- ("amssymb" "mathbin" "\\smallsetminus" 8726 "∖")
- ("amssymb" "mathbin" "\\wedge" 8743 "∧")
- ("amssymb" "mathbin" "\\wr" 8768 "≀")
- ("amssymb" "mathbin" "\\circledcirc" 8858 "⊚")
- ("amssymb" "mathbin" "\\circledast" 8859 "⊛")
- ("amssymb" "mathbin" "\\circleddash" 8861 "⊝")
- ("amssymb" "mathbin" "\\boxplus" 8862 "⊞")
- ("amssymb" "mathbin" "\\boxminus" 8863 "⊟")
- ("amssymb" "mathbin" "\\boxtimes" 8864 "⊠")
- ("amssymb" "mathbin" "\\boxdot" 8865 "⊡")
- ("amssymb" "mathbin" "\\intercal" 8890 "⊺")
- ("amssymb" "mathbin" "\\veebar" 8891 "⊻")
- ("amssymb" "mathbin" "\\barwedge" 8892 "⊼")
- ("amssymb" "mathbin" "\\divideontimes" 8903 "⋇")
- ("amssymb" "mathbin" "\\ltimes" 8905 "⋉")
- ("amssymb" "mathbin" "\\rtimes" 8906 "⋊")
- ("amssymb" "mathbin" "\\leftthreetimes" 8907 "⋋")
- ("amssymb" "mathbin" "\\rightthreetimes" 8908 "⋌")
- ("amssymb" "mathbin" "\\curlyvee" 8910 "⋎")
- ("amssymb" "mathbin" "\\curlywedge" 8911 "⋏")
- ("amssymb" "mathbin" "\\Cap" 8914 "⋒")
- ("amssymb" "mathbin" "\\Cup" 8915 "⋓")
- ("amssymb" "mathbin" "\\rhd" 9655 "▷")
- ("amssymb" "mathbin" "\\lhd" 9665 "◁")
- ("amssymb" "mathbin" "\\blacklozenge" 10731 "⧫")
- ("amssymb" "mathbin" "\\doublebarwedge" 10846 "⩞")
- ("amssymb" "mathop" "\\Join" 10781 "⨝")
- ("amssymb" "mathord" "\\backepsilon" 1014 "϶")
- ("amssymb" "mathord" "\\backprime" 8245 "‵")
- ("amssymb" "mathord" "\\Finv" 8498 "Ⅎ")
- ("amssymb" "mathord" "\\circlearrowleft" 8634 "↺")
- ("amssymb" "mathord" "\\circlearrowright" 8635 "↻")
- ("amssymb" "mathord" "\\complement" 8705 "∁")
- ("amssymb" "mathord" "\\nexists" 8708 "∄")
- ("amssymb" "mathord" "\\varnothing" 8709 "∅")
- ("amssymb" "mathord" "\\measuredangle" 8737 "∡")
- ("amssymb" "mathord" "\\sphericalangle" 8738 "∢")
- ("amssymb" "mathord" "\\therefore" 8756 "∴")
- ("amssymb" "mathord" "\\because" 8757 "∵")
- ("amssymb" "mathord" "\\Diamond" 9671 "◇")
- ("amssymb" "mathord" "\\lozenge" 9674 "◊")
- ("amssymb" "mathord" "\\square" 9723 "◻")
- ("amssymb" "mathord" "\\blacksquare" 9724 "◼")
- ("amssymb" "mathord" "\\bigstar" 9733 "★")
- ("amssymb" "mathord" "\\blacksquare" 11035 "⬛" t)
- ("amssymb" "mathord" "\\square" 11036 "⬜" t)
- ("amssymb" "mathrel" "\\nwarrow" 8598 "↖")
- ("amssymb" "mathrel" "\\nleftarrow" 8602 "↚")
- ("amssymb" "mathrel" "\\nrightarrow" 8603 "↛")
- ("amssymb" "mathrel" "\\twoheadleftarrow" 8606 "↞")
- ("amssymb" "mathrel" "\\twoheadrightarrow" 8608 "↠")
- ("amssymb" "mathrel" "\\leftarrowtail" 8610 "↢")
- ("amssymb" "mathrel" "\\rightarrowtail" 8611 "↣")
- ("amssymb" "mathrel" "\\looparrowleft" 8619 "↫")
- ("amssymb" "mathrel" "\\looparrowright" 8620 "↬")
- ("amssymb" "mathrel" "\\leftrightsquigarrow" 8621 "↭")
- ("amssymb" "mathrel" "\\nleftrightarrow" 8622 "↮")
- ("amssymb" "mathrel" "\\Lsh" 8624 "↰")
- ("amssymb" "mathrel" "\\Rsh" 8625 "↱")
- ("amssymb" "mathrel" "\\curvearrowleft" 8630 "↶")
- ("amssymb" "mathrel" "\\curvearrowright" 8631 "↷")
- ("amssymb" "mathrel" "\\upharpoonright" 8638 "↾")
- ("amssymb" "mathrel" "\\upharpoonleft" 8639 "↿")
- ("amssymb" "mathrel" "\\downharpoonright" 8642 "⇂")
- ("amssymb" "mathrel" "\\downharpoonleft" 8643 "⇃")
- ("amssymb" "mathrel" "\\rightleftarrows" 8644 "⇄")
- ("amssymb" "mathrel" "\\leftrightarrows" 8646 "⇆")
- ("amssymb" "mathrel" "\\leftleftarrows" 8647 "⇇")
- ("amssymb" "mathrel" "\\upuparrows" 8648 "⇈")
- ("amssymb" "mathrel" "\\rightrightarrows" 8649 "⇉")
- ("amssymb" "mathrel" "\\downdownarrows" 8650 "⇊")
- ("amssymb" "mathrel" "\\leftrightharpoons" 8651 "⇋")
- ("amssymb" "mathrel" "\\nLeftarrow" 8653 "⇍")
- ("amssymb" "mathrel" "\\nLeftrightarrow" 8654 "⇎")
- ("amssymb" "mathrel" "\\nRightarrow" 8655 "⇏")
- ("amssymb" "mathrel" "\\Lleftarrow" 8666 "⇚")
- ("amssymb" "mathrel" "\\Rrightarrow" 8667 "⇛")
- ("amssymb" "mathrel" "\\rightsquigarrow" 8669 "⇝")
- ("amssymb" "mathrel" "\\nmid" 8740 "∤")
- ("amssymb" "mathrel" "\\nparallel" 8742 "∦")
- ("amssymb" "mathrel" "\\backsim" 8765 "∽")
- ("amssymb" "mathrel" "\\nsim" 8769 "≁")
- ("amssymb" "mathrel" "\\eqsim" 8770 "≂")
- ("amssymb" "mathrel" "\\ncong" 8775 "≇")
- ("amssymb" "mathrel" "\\approxeq" 8778 "≊")
- ("amssymb" "mathrel" "\\Bumpeq" 8782 "≎")
- ("amssymb" "mathrel" "\\bumpeq" 8783 "≏")
- ("amssymb" "mathrel" "\\Doteq" 8785 "≑")
- ("amssymb" "mathrel" "\\fallingdotseq" 8786 "≒")
- ("amssymb" "mathrel" "\\risingdotseq" 8787 "≓")
- ("amssymb" "mathrel" "\\eqcirc" 8790 "≖")
- ("amssymb" "mathrel" "\\circeq" 8791 "≗")
- ("amssymb" "mathrel" "\\triangleq" 8796 "≜")
- ("amssymb" "mathrel" "\\leqq" 8806 "≦")
- ("amssymb" "mathrel" "\\geqq" 8807 "≧")
- ("amssymb" "mathrel" "\\lneqq" 8808 "≨")
- ("amssymb" "mathrel" "\\gneqq" 8809 "≩")
- ("amssymb" "mathrel" "\\between" 8812 "≬")
- ("amssymb" "mathrel" "\\nless" 8814 "≮")
- ("amssymb" "mathrel" "\\ngtr" 8815 "≯")
- ("amssymb" "mathrel" "\\nleq" 8816 "≰")
- ("amssymb" "mathrel" "\\ngeq" 8817 "≱")
- ("amssymb" "mathrel" "\\lesssim" 8818 "≲")
- ("amssymb" "mathrel" "\\gtrsim" 8819 "≳")
- ("amssymb" "mathrel" "\\lessgtr" 8822 "≶")
- ("amssymb" "mathrel" "\\gtrless" 8823 "≷")
- ("amssymb" "mathrel" "\\preccurlyeq" 8828 "≼")
- ("amssymb" "mathrel" "\\succcurlyeq" 8829 "≽")
- ("amssymb" "mathrel" "\\precsim" 8830 "≾")
- ("amssymb" "mathrel" "\\succsim" 8831 "≿")
- ("amssymb" "mathrel" "\\nprec" 8832 "⊀")
- ("amssymb" "mathrel" "\\nsucc" 8833 "⊁")
- ("amssymb" "mathrel" "\\nsubseteq" 8840 "⊈")
- ("amssymb" "mathrel" "\\nsupseteq" 8841 "⊉")
- ("amssymb" "mathrel" "\\subsetneq" 8842 "⊊")
- ("amssymb" "mathrel" "\\supsetneq" 8843 "⊋")
- ("amssymb" "mathrel" "\\dashv" 8867 "⊣")
- ("amssymb" "mathrel" "\\vDash" 8872 "⊨")
- ("amssymb" "mathrel" "\\Vdash" 8873 "⊩")
- ("amssymb" "mathrel" "\\Vvdash" 8874 "⊪")
- ("amssymb" "mathrel" "\\nvdash" 8876 "⊬")
- ("amssymb" "mathrel" "\\nvDash" 8877 "⊭")
- ("amssymb" "mathrel" "\\nVdash" 8878 "⊮")
- ("amssymb" "mathrel" "\\nVDash" 8879 "⊯")
- ("amssymb" "mathrel" "\\vartriangleleft" 8882 "⊲")
- ("amssymb" "mathrel" "\\vartriangleright" 8883 "⊳")
- ("amssymb" "mathrel" "\\trianglelefteq" 8884 "⊴")
- ("amssymb" "mathrel" "\\trianglerighteq" 8885 "⊵")
- ("amssymb" "mathrel" "\\multimap" 8888 "⊸")
- ("amssymb" "mathrel" "\\backsimeq" 8909 "⋍")
- ("amssymb" "mathrel" "\\Subset" 8912 "⋐")
- ("amssymb" "mathrel" "\\Supset" 8913 "⋑")
- ("amssymb" "mathrel" "\\pitchfork" 8916 "⋔")
- ("amssymb" "mathrel" "\\lessdot" 8918 "⋖")
- ("amssymb" "mathrel" "\\gtrdot" 8919 "⋗")
- ("amssymb" "mathrel" "\\lll" 8920 "⋘")
- ("amssymb" "mathrel" "\\ggg" 8921 "⋙")
- ("amssymb" "mathrel" "\\lesseqgtr" 8922 "⋚")
- ("amssymb" "mathrel" "\\gtreqless" 8923 "⋛")
- ("amssymb" "mathrel" "\\curlyeqprec" 8926 "⋞")
- ("amssymb" "mathrel" "\\curlyeqsucc" 8927 "⋟")
- ("amssymb" "mathrel" "\\npreceq" 8928 "⋠")
- ("amssymb" "mathrel" "\\nsucceq" 8929 "⋡")
- ("amssymb" "mathrel" "\\lnsim" 8934 "⋦")
- ("amssymb" "mathrel" "\\gnsim" 8935 "⋧")
- ("amssymb" "mathrel" "\\precnsim" 8936 "⋨")
- ("amssymb" "mathrel" "\\succnsim" 8937 "⋩")
- ("amssymb" "mathrel" "\\ntriangleleft" 8938 "⋪")
- ("amssymb" "mathrel" "\\ntriangleright" 8939 "⋫")
- ("amssymb" "mathrel" "\\ntrianglelefteq" 8940 "⋬")
- ("amssymb" "mathrel" "\\ntrianglerighteq" 8941 "⋭")
- ("amssymb" "mathrel" "\\leqslant" 10877 "⩽")
- ("amssymb" "mathrel" "\\geqslant" 10878 "⩾")
- ("amssymb" "mathrel" "\\lessapprox" 10885 "⪅")
- ("amssymb" "mathrel" "\\gtrapprox" 10886 "⪆")
- ("amssymb" "mathrel" "\\lneq" 10887 "⪇")
- ("amssymb" "mathrel" "\\gneq" 10888 "⪈")
- ("amssymb" "mathrel" "\\lnapprox" 10889 "⪉")
- ("amssymb" "mathrel" "\\gnapprox" 10890 "⪊")
- ("amssymb" "mathrel" "\\lesseqqgtr" 10891 "⪋")
- ("amssymb" "mathrel" "\\gtreqqless" 10892 "⪌")
- ("amssymb" "mathrel" "\\eqslantless" 10901 "⪕")
- ("amssymb" "mathrel" "\\eqslantgtr" 10902 "⪖")
- ("amssymb" "mathrel" "\\precapprox" 10935 "⪷")
- ("amssymb" "mathrel" "\\succapprox" 10936 "⪸")
- ("amssymb" "mathrel" "\\precnapprox" 10937 "⪹")
- ("amssymb" "mathrel" "\\succnapprox" 10938 "⪺")
- ("amssymb" "mathrel" "\\subseteqq" 10949 "⫅")
- ("amssymb" "mathrel" "\\supseteqq" 10950 "⫆")
- ("amssymb" "mathrel" "\\subsetneqq" 10955 "⫋")
- ("amssymb" "mathrel" "\\supsetneqq" 10956 "⫌")
- ("amsxtra" "mathord" "\\sptilde" 126 "~")
- ("amsxtra" "mathord" "\\spddot" 168 "¨")
- ("arevmath" "mathalpha" "\\eth" 240 "ð")
- ("arevmath" "mathalpha" "\\varbeta" 976 "ϐ")
- ("arevmath" "mathalpha" "\\Stigma" 986 "Ϛ")
- ("arevmath" "mathalpha" "\\stigma" 987 "ϛ")
- ("arevmath" "mathalpha" "\\digamma" 989 "ϝ")
- ("arevmath" "mathalpha" "\\Koppa" 990 "Ϟ")
- ("arevmath" "mathalpha" "\\koppa" 991 "ϟ")
- ("arevmath" "mathalpha" "\\Sampi" 992 "Ϡ")
- ("arevmath" "mathalpha" "\\sampi" 993 "ϡ")
- ("arevmath" "mathalpha" "\\hslash" 8463 "ℏ")
- ("arevmath" "mathord" "\\Qoppa" 984 "Ϙ")
- ("arevmath" "mathord" "\\qoppa" 985 "ϙ")
- ("arevmath" "mathord" "\\mho" 8487 "℧")
- ("arevmath" "mathord" "\\steaming" 9749 "☕")
- ("arevmath" "mathord" "\\pointright" 9758 "☞")
- ("arevmath" "mathord" "\\skull" 9760 "☠")
- ("arevmath" "mathord" "\\radiation" 9762 "☢")
- ("arevmath" "mathord" "\\biohazard" 9763 "☣")
- ("arevmath" "mathord" "\\yinyang" 9775 "☯")
- ("arevmath" "mathord" "\\quarternote" 9833 "♩")
- ("arevmath" "mathord" "\\eighthnote" 9834 "♪")
- ("arevmath" "mathord" "\\sixteenthnote" 9836 "♬")
- ("arevmath" "mathord" "\\recycle" 9851 "♻")
- ("arevmath" "mathord" "\\anchor" 9875 "⚓")
- ("arevmath" "mathord" "\\swords" 9876 "⚔")
- ("arevmath" "mathord" "\\warning" 9888 "⚠")
- ("arevmath" "mathord" "\\pencil" 9998 "✎")
- ("arevmath" "mathord" "\\ballotx" 10007 "✗")
- ("arevmath" "mathord" "\\arrowbullet" 10146 "➢")
- ("esint" "mathop" "\\iint" 8748 "∬")
- ("esint" "mathop" "\\iiint" 8749 "∭")
- ("esint" "mathop" "\\oiint" 8751 "∯")
- ("esint" "mathop" "\\varointclockwise" 8754 "∲")
- ("esint" "mathop" "\\ointctrclockwise" 8755 "∳")
- ("esint" "mathop" "\\iiiint" 10764 "⨌")
- ("esint" "mathop" "\\fint" 10767 "⨏")
- ("esint" "mathop" "\\sqint" 10774 "⨖")
- ("fourier" "mathalpha" "\\hslash" 8463 "ℏ")
- ("fourier" "mathbin" "\\smallsetminus" 8726 "∖")
- ("fourier" "mathbin" "\\intercal" 8890 "⊺")
- ("fourier" "mathbin" "\\blacktriangleright" 9656 "▸" t)
- ("fourier" "mathbin" "\\blacktriangleleft" 9666 "◂" t)
- ("fourier" "mathclose" "\\rrbracket" 10215 "⟧")
- ("fourier" "mathfence" "\\VERT" 10624 "⦀")
- ("fourier" "mathop" "\\iint" 8748 "∬")
- ("fourier" "mathop" "\\iiint" 8749 "∭")
- ("fourier" "mathop" "\\oiint" 8751 "∯")
- ("fourier" "mathop" "\\oiiint" 8752 "∰")
- ("fourier" "mathopen" "\\llbracket" 10214 "⟦")
- ("fourier" "mathord" "\\pounds" 163 "£" t)
- ("fourier" "mathord" "\\complement" 8705 "∁")
- ("fourier" "mathord" "\\nexists" 8708 "∄")
- ("fourier" "mathord" "\\square" 9723 "◻" t)
- ("fourier" "mathord" "\\blacksquare" 9724 "◼" t)
- ("fourier" "mathord" "\\blacksquare" 11035 "⬛")
- ("fourier" "mathord" "\\square" 11036 "⬜")
- ("fourier" "mathrel" "\\curvearrowleft" 8630 "↶")
- ("fourier" "mathrel" "\\curvearrowright" 8631 "↷")
- ("fourier" "mathrel" "\\leftleftarrows" 8647 "⇇")
- ("fourier" "mathrel" "\\rightrightarrows" 8649 "⇉")
- ("fourier" "mathrel" "\\nparallel" 8742 "∦")
- ("fourier" "mathrel" "\\vDash" 8872 "⊨")
- ("fourier" "mathrel" "\\nvDash" 8877 "⊭")
- ("fourier" "mathrel" "\\leqslant" 10877 "⩽")
- ("fourier" "mathrel" "\\geqslant" 10878 "⩾")
- ("frenchstyle" "mathalpha" "A" 119860 "𝐴" t)
- ("frenchstyle" "mathalpha" "B" 119861 "𝐵" t)
- ("frenchstyle" "mathalpha" "C" 119862 "𝐶" t)
- ("frenchstyle" "mathalpha" "D" 119863 "𝐷" t)
- ("frenchstyle" "mathalpha" "E" 119864 "𝐸" t)
- ("frenchstyle" "mathalpha" "F" 119865 "𝐹" t)
- ("frenchstyle" "mathalpha" "G" 119866 "𝐺" t)
- ("frenchstyle" "mathalpha" "H" 119867 "𝐻" t)
- ("frenchstyle" "mathalpha" "I" 119868 "𝐼" t)
- ("frenchstyle" "mathalpha" "J" 119869 "𝐽" t)
- ("frenchstyle" "mathalpha" "K" 119870 "𝐾" t)
- ("frenchstyle" "mathalpha" "L" 119871 "𝐿" t)
- ("frenchstyle" "mathalpha" "M" 119872 "𝑀" t)
- ("frenchstyle" "mathalpha" "N" 119873 "𝑁" t)
- ("frenchstyle" "mathalpha" "O" 119874 "𝑂" t)
- ("frenchstyle" "mathalpha" "P" 119875 "𝑃" t)
- ("frenchstyle" "mathalpha" "Q" 119876 "𝑄" t)
- ("frenchstyle" "mathalpha" "R" 119877 "𝑅" t)
- ("frenchstyle" "mathalpha" "S" 119878 "𝑆" t)
- ("frenchstyle" "mathalpha" "T" 119879 "𝑇" t)
- ("frenchstyle" "mathalpha" "U" 119880 "𝑈" t)
- ("frenchstyle" "mathalpha" "V" 119881 "𝑉" t)
- ("frenchstyle" "mathalpha" "W" 119882 "𝑊" t)
- ("frenchstyle" "mathalpha" "X" 119883 "𝑋" t)
- ("frenchstyle" "mathalpha" "Y" 119884 "𝑌" t)
- ("frenchstyle" "mathalpha" "Z" 119885 "𝑍" t)
- ("kpfonts" "mathclose" "\\rrbracket" 10215 "⟧")
- ("kpfonts" "mathopen" "\\llbracket" 10214 "⟦")
- ("literal" "mathalpha" "A" 65 "A" t)
- ("literal" "mathalpha" "B" 66 "B" t)
- ("literal" "mathalpha" "C" 67 "C" t)
- ("literal" "mathalpha" "D" 68 "D" t)
- ("literal" "mathalpha" "E" 69 "E" t)
- ("literal" "mathalpha" "F" 70 "F" t)
- ("literal" "mathalpha" "G" 71 "G" t)
- ("literal" "mathalpha" "H" 72 "H" t)
- ("literal" "mathalpha" "I" 73 "I" t)
- ("literal" "mathalpha" "J" 74 "J" t)
- ("literal" "mathalpha" "K" 75 "K" t)
- ("literal" "mathalpha" "L" 76 "L" t)
- ("literal" "mathalpha" "M" 77 "M" t)
- ("literal" "mathalpha" "N" 78 "N" t)
- ("literal" "mathalpha" "O" 79 "O" t)
- ("literal" "mathalpha" "P" 80 "P" t)
- ("literal" "mathalpha" "Q" 81 "Q" t)
- ("literal" "mathalpha" "R" 82 "R" t)
- ("literal" "mathalpha" "S" 83 "S" t)
- ("literal" "mathalpha" "T" 84 "T" t)
- ("literal" "mathalpha" "U" 85 "U" t)
- ("literal" "mathalpha" "V" 86 "V" t)
- ("literal" "mathalpha" "W" 87 "W" t)
- ("literal" "mathalpha" "X" 88 "X" t)
- ("literal" "mathalpha" "Y" 89 "Y" t)
- ("literal" "mathalpha" "Z" 90 "Z" t)
- ("literal" "mathalpha" "a" 97 "a" t)
- ("literal" "mathalpha" "b" 98 "b" t)
- ("literal" "mathalpha" "c" 99 "c" t)
- ("literal" "mathalpha" "d" 100 "d" t)
- ("literal" "mathalpha" "e" 101 "e" t)
- ("literal" "mathalpha" "f" 102 "f" t)
- ("literal" "mathalpha" "g" 103 "g" t)
- ("literal" "mathalpha" "h" 104 "h" t)
- ("literal" "mathalpha" "i" 105 "i" t)
- ("literal" "mathalpha" "j" 106 "j" t)
- ("literal" "mathalpha" "k" 107 "k" t)
- ("literal" "mathalpha" "l" 108 "l" t)
- ("literal" "mathalpha" "m" 109 "m" t)
- ("literal" "mathalpha" "n" 110 "n" t)
- ("literal" "mathalpha" "o" 111 "o" t)
- ("literal" "mathalpha" "p" 112 "p" t)
- ("literal" "mathalpha" "q" 113 "q" t)
- ("literal" "mathalpha" "r" 114 "r" t)
- ("literal" "mathalpha" "s" 115 "s" t)
- ("literal" "mathalpha" "t" 116 "t" t)
- ("literal" "mathalpha" "u" 117 "u" t)
- ("literal" "mathalpha" "v" 118 "v" t)
- ("literal" "mathalpha" "w" 119 "w" t)
- ("literal" "mathalpha" "x" 120 "x" t)
- ("literal" "mathalpha" "y" 121 "y" t)
- ("literal" "mathalpha" "z" 122 "z" t)
- ("literal" "mathalpha" "\\imath" 305 "ı" t)
- ("literal" "mathalpha" "\\jmath" 567 "ȷ" t)
- ("literal" "mathalpha" "\\Gamma" 915 "Γ" t)
- ("literal" "mathalpha" "\\Delta" 916 "Δ" t)
- ("literal" "mathalpha" "\\Theta" 920 "Θ" t)
- ("literal" "mathalpha" "\\Lambda" 923 "Λ" t)
- ("literal" "mathalpha" "\\Xi" 926 "Ξ" t)
- ("literal" "mathalpha" "\\Pi" 928 "Π" t)
- ("literal" "mathalpha" "\\Sigma" 931 "Σ" t)
- ("literal" "mathalpha" "\\Upsilon" 933 "Υ" t)
- ("literal" "mathalpha" "\\Phi" 934 "Φ" t)
- ("literal" "mathalpha" "\\Psi" 936 "Ψ" t)
- ("literal" "mathalpha" "\\Omega" 937 "Ω" t)
- ("literal" "mathalpha" "\\alpha" 945 "α" t)
- ("literal" "mathalpha" "\\beta" 946 "β" t)
- ("literal" "mathalpha" "\\gamma" 947 "γ" t)
- ("literal" "mathalpha" "\\delta" 948 "δ" t)
- ("literal" "mathalpha" "\\varepsilon" 949 "ε" t)
- ("literal" "mathalpha" "\\zeta" 950 "ζ" t)
- ("literal" "mathalpha" "\\eta" 951 "η" t)
- ("literal" "mathalpha" "\\theta" 952 "θ" t)
- ("literal" "mathalpha" "\\iota" 953 "ι" t)
- ("literal" "mathalpha" "\\kappa" 954 "κ" t)
- ("literal" "mathalpha" "\\lambda" 955 "λ" t)
- ("literal" "mathalpha" "\\mu" 956 "μ" t)
- ("literal" "mathalpha" "\\nu" 957 "ν" t)
- ("literal" "mathalpha" "\\xi" 958 "ξ" t)
- ("literal" "mathalpha" "\\pi" 960 "π" t)
- ("literal" "mathalpha" "\\rho" 961 "ρ" t)
- ("literal" "mathalpha" "\\varsigma" 962 "ς" t)
- ("literal" "mathalpha" "\\sigma" 963 "σ" t)
- ("literal" "mathalpha" "\\tau" 964 "τ" t)
- ("literal" "mathalpha" "\\upsilon" 965 "υ" t)
- ("literal" "mathalpha" "\\varphi" 966 "φ" t)
- ("literal" "mathalpha" "\\chi" 967 "χ" t)
- ("literal" "mathalpha" "\\psi" 968 "ψ" t)
- ("literal" "mathalpha" "\\omega" 969 "ω" t)
- ("literal" "mathalpha" "\\vartheta" 977 "ϑ" t)
- ("literal" "mathalpha" "\\phi" 981 "ϕ" t)
- ("literal" "mathalpha" "\\varpi" 982 "ϖ" t)
- ("literal" "mathalpha" "\\varrho" 1009 "ϱ" t)
- ("literal" "mathalpha" "\\epsilon" 1013 "ϵ" t)
- ("literal" "mathord" "\\partial" 8706 "∂" t)
- ("literal" "mathpunct" ":" 58 ":" t)
- ("marvosym" "mathrel" "\\Rightarrow" 8658 "⇒" t)
- ("mathabx" "mathbin" "\\blacktriangleup" 9652 "▴")
- ("mathabx" "mathbin" "\\smalltriangleup" 9653 "▵")
- ("mathabx" "mathbin" "\\blacktriangleright" 9656 "▸")
- ("mathabx" "mathbin" "\\smalltriangleright" 9657 "▹")
- ("mathabx" "mathbin" "\\blacktriangledown" 9662 "▾")
- ("mathabx" "mathbin" "\\smalltriangledown" 9663 "▿")
- ("mathabx" "mathbin" "\\blacktriangleleft" 9666 "◂")
- ("mathabx" "mathbin" "\\smalltriangleleft" 9667 "◃")
- ("mathabx" "mathord" "\\second" 8243 "″")
- ("mathabx" "mathord" "\\third" 8244 "‴")
- ("mathabx" "mathord" "\\fourth" 8279 "⁗")
- ("mathabx" "mathord" "\\diameter" 8960 "⌀")
- ("mathabx" "mathord" "\\Sun" 9737 "☉")
- ("mathabx" "mathord" "\\rightmoon" 9789 "☽")
- ("mathabx" "mathord" "\\leftmoon" 9790 "☾")
- ("mathabx" "mathrel" "\\dlsh" 8626 "↲")
- ("mathabx" "mathrel" "\\drsh" 8627 "↳")
- ("mathabx" "mathrel" "\\updownarrows" 8645 "⇅")
- ("mathabx" "mathrel" "\\leftsquigarrow" 8668 "⇜")
- ("mathabx" "mathrel" "\\downuparrows" 8693 "⇵")
- ("mathabx" "mathrel" "\\eqcolon" 8761 "∹" t)
- ("mathabx" "mathrel" "\\coloneq" 8788 "≔")
- ("mathabx" "mathrel" "\\eqcolon" 8789 "≕")
- ("mathabx" "mathrel" "\\corresponds" 8793 "≙")
- ("mathabx" "mathrel" "\\notasymp" 8813 "≭")
- ("mathabx" "mathrel" "\\VDash" 8875 "⊫")
- ("mathabx" "mathrel" "\\hash" 8917 "⋕")
- ("mathabx" "mathrel" "\\lll" 8920 "⋘" t)
- ("mathabx" "mathrel" "\\ggg" 8921 "⋙" t)
- ("mathabx" "mathrel" "\\barin" 8950 "⋶")
- ("mathabx" "mathrel" "\\leftrightharpoon" 10570 "⥊")
- ("mathabx" "mathrel" "\\rightleftharpoon" 10571 "⥋")
- ("mathabx" "mathrel" "\\leftleftharpoons" 10594 "⥢")
- ("mathabx" "mathrel" "\\upupharpoons" 10595 "⥣")
- ("mathabx" "mathrel" "\\rightrightharpoons" 10596 "⥤")
- ("mathabx" "mathrel" "\\downdownharpoons" 10597 "⥥")
- ("mathabx" "mathrel" "\\leftbarharpoon" 10602 "⥪")
- ("mathabx" "mathrel" "\\barleftharpoon" 10603 "⥫")
- ("mathabx" "mathrel" "\\rightbarharpoon" 10604 "⥬")
- ("mathabx" "mathrel" "\\barrightharpoon" 10605 "⥭")
- ("mathabx" "mathrel" "\\updownharpoons" 10606 "⥮")
- ("mathabx" "mathrel" "\\downupharpoons" 10607 "⥯")
- ("mathabx" "mathrel" "\\llcurly" 10939 "⪻")
- ("mathabx" "mathrel" "\\ggcurly" 10940 "⪼")
- ("mathbbol" "mathclose" "\\Rparen" 10630 "⦆")
- ("mathbbol" "mathopen" "\\Lparen" 10629 "⦅")
- ("mathcomp" "mathalpha" "\\tcohm" 8486 "Ω")
- ("mathdots" "mathrel" "\\iddots" 8944 "⋰")
- ("omlmathit" "mathord" "\\pounds" 163 "£" t)
- ("oz" "mathaccent" "\\dot" 775 "̇" t)
- ("oz" "mathbin" "\\cat" 8256 "⁀")
- ("oz" "mathbin" "\\fcmp" 10814 "⨾")
- ("oz" "mathbin" "\\dsub" 10852 "⩤")
- ("oz" "mathbin" "\\rsub" 10853 "⩥")
- ("oz" "mathclose" "\\rang" 10219 "⟫")
- ("oz" "mathclose" "\\rimg" 10632 "⦈")
- ("oz" "mathclose" "\\rblot" 10634 "⦊")
- ("oz" "mathop" "\\zhide" 10745 "⧹")
- ("oz" "mathop" "\\zcmp" 10783 "⨟")
- ("oz" "mathop" "\\zpipe" 10784 "⨠")
- ("oz" "mathop" "\\zproject" 10785 "⨡")
- ("oz" "mathopen" "\\lang" 10218 "⟪")
- ("oz" "mathopen" "\\limg" 10631 "⦇")
- ("oz" "mathopen" "\\lblot" 10633 "⦉")
- ("oz" "mathord" "\\#" 35 "#" t)
- ("oz" "mathord" "\\spot" 10625 "⦁")
- ("oz" "mathrel" "\\pfun" 8696 "⇸")
- ("oz" "mathrel" "\\ffun" 8699 "⇻")
- ("oz" "mathrel" "\\psur" 10496 "⤀")
- ("oz" "mathrel" "\\pinj" 10516 "⤔")
- ("oz" "mathrel" "\\finj" 10517 "⤕")
- ("oz" "mathrel" "\\bij" 10518 "⤖")
- ("slantedGreek" "mathalpha" "\\Gamma" 120548 "𝛤")
- ("slantedGreek" "mathalpha" "\\Delta" 120549 "𝛥")
- ("slantedGreek" "mathalpha" "\\Theta" 120553 "𝛩")
- ("slantedGreek" "mathalpha" "\\Lambda" 120556 "𝛬")
- ("slantedGreek" "mathalpha" "\\Xi" 120559 "𝛯")
- ("slantedGreek" "mathalpha" "\\Pi" 120561 "𝛱")
- ("slantedGreek" "mathalpha" "\\Sigma" 120564 "𝛴")
- ("slantedGreek" "mathalpha" "\\Upsilon" 120566 "𝛶")
- ("slantedGreek" "mathalpha" "\\Phi" 120567 "𝛷")
- ("slantedGreek" "mathalpha" "\\Psi" 120569 "𝛹")
- ("slantedGreek" "mathalpha" "\\Omega" 120570 "𝛺")
- ("stmaryrd" "mathbin" "\\boxdot" 8865 "⊡")
- ("stmaryrd" "mathbin" "\\bigtriangleup" 9651 "△" t)
- ("stmaryrd" "mathbin" "\\bigtriangledown" 9661 "▽" t)
- ("stmaryrd" "mathbin" "\\boxbar" 9707 "◫")
- ("stmaryrd" "mathbin" "\\boxslash" 10692 "⧄")
- ("stmaryrd" "mathbin" "\\boxbslash" 10693 "⧅")
- ("stmaryrd" "mathbin" "\\boxast" 10694 "⧆")
- ("stmaryrd" "mathbin" "\\boxcircle" 10695 "⧇")
- ("stmaryrd" "mathbin" "\\boxbox" 10696 "⧈")
- ("stmaryrd" "mathbin" "\\interleave" 10996 "⫴")
- ("stmaryrd" "mathbin" "\\sslash" 11005 "⫽")
- ("stmaryrd" "mathbin" "\\talloblong" 11006 "⫾")
- ("stmaryrd" "mathclose" "\\Rbag" 10182 "⟆")
- ("stmaryrd" "mathclose" "\\rrbracket" 10215 "⟧")
- ("stmaryrd" "mathop" "\\biginterleave" 11004 "⫼")
- ("stmaryrd" "mathopen" "\\Lbag" 10181 "⟅")
- ("stmaryrd" "mathopen" "\\llbracket" 10214 "⟦")
- ("stmaryrd" "mathord" "\\Yup" 8516 "⅄")
- ("stmaryrd" "mathrel" "\\mapsfrom" 8612 "↤")
- ("stmaryrd" "mathrel" "\\lightning" 8623 "↯")
- ("stmaryrd" "mathrel" "\\leftarrowtriangle" 8701 "⇽")
- ("stmaryrd" "mathrel" "\\rightarrowtriangle" 8702 "⇾")
- ("stmaryrd" "mathrel" "\\leftrightarrowtriangle" 8703 "⇿")
- ("stmaryrd" "mathrel" "\\longmapsfrom" 10235 "⟻")
- ("stmaryrd" "mathrel" "\\Longmapsfrom" 10237 "⟽")
- ("stmaryrd" "mathrel" "\\Longmapsto" 10238 "⟾")
- ("stmaryrd" "mathrel" "\\Mapsfrom" 10502 "⤆")
- ("stmaryrd" "mathrel" "\\Mapsto" 10503 "⤇")
- ("stmaryrd" "mathrel" "\\leftslice" 10918 "⪦")
- ("stmaryrd" "mathrel" "\\rightslice" 10919 "⪧")
- ("txfonts" "mathbin" "\\invamp" 8523 "⅋")
- ("txfonts" "mathbin" "\\boxbar" 9707 "◫")
- ("txfonts" "mathbin" "\\circledbslash" 10680 "⦸")
- ("txfonts" "mathbin" "\\circledless" 10688 "⧀")
- ("txfonts" "mathbin" "\\circledgtr" 10689 "⧁")
- ("txfonts" "mathbin" "\\boxslash" 10692 "⧄")
- ("txfonts" "mathbin" "\\boxbslash" 10693 "⧅")
- ("txfonts" "mathbin" "\\boxast" 10694 "⧆")
- ("txfonts" "mathclose" "\\Rbag" 10182 "⟆")
- ("txfonts" "mathop" "\\oiiint" 8752 "∰")
- ("txfonts" "mathop" "\\bigsqcap" 10757 "⨅")
- ("txfonts" "mathop" "\\varprod" 10761 "⨉")
- ("txfonts" "mathopen" "\\Lbag" 10181 "⟅")
- ("txfonts" "mathord" "\\Diamondblack" 9670 "◆")
- ("txfonts" "mathord" "\\varspadesuit" 9828 "♤")
- ("txfonts" "mathord" "\\varheartsuit" 9829 "♥")
- ("txfonts" "mathord" "\\vardiamondsuit" 9830 "♦")
- ("txfonts" "mathord" "\\varclubsuit" 9831 "♧")
- ("txfonts" "mathord" "\\medcirc" 9898 "⚪")
- ("txfonts" "mathord" "\\medbullet" 9899 "⚫")
- ("txfonts" "mathord" "\\Diamonddot" 10192 "⟐")
- ("txfonts" "mathrel" "\\Nwarrow" 8662 "⇖")
- ("txfonts" "mathrel" "\\Nearrow" 8663 "⇗")
- ("txfonts" "mathrel" "\\Searrow" 8664 "⇘")
- ("txfonts" "mathrel" "\\Swarrow" 8665 "⇙")
- ("txfonts" "mathrel" "\\leftsquigarrow" 8668 "⇜")
- ("txfonts" "mathrel" "\\eqcolon" 8761 "∹")
- ("txfonts" "mathrel" "\\nsimeq" 8772 "≄")
- ("txfonts" "mathrel" "\\coloneq" 8788 "≔" t)
- ("txfonts" "mathrel" "\\eqcolon" 8789 "≕" t)
- ("txfonts" "mathrel" "\\VDash" 8875 "⊫")
- ("txfonts" "mathrel" "\\multimapdotbothA" 8886 "⊶")
- ("txfonts" "mathrel" "\\multimapdotbothB" 8887 "⊷")
- ("txfonts" "mathrel" "\\multimapinv" 10204 "⟜")
- ("txfonts" "mathrel" "\\leadsto" 10547 "⤳")
- ("txfonts" "mathrel" "\\strictfi" 10620 "⥼")
- ("txfonts" "mathrel" "\\strictif" 10621 "⥽")
- ("txfonts" "mathrel" "\\multimapboth" 10719 "⧟")
- ("txfonts" "mathrel" "\\Coloneqq" 10868 "⩴")
- ("txfonts" "mathrel" "\\preceqq" 10931 "⪳")
- ("txfonts" "mathrel" "\\succeqq" 10932 "⪴")
- ("txfonts" "mathrel" "\\Top" 10986 "⫪")
- ("txfonts" "mathrel" "\\Bot" 10987 "⫫")
- ("undertilde" "mathaccent" "\\utilde" 816 "̰")
- ("uprightstyle" "mathalpha" "a" 119886 "𝑎" t)
- ("uprightstyle" "mathalpha" "b" 119887 "𝑏" t)
- ("uprightstyle" "mathalpha" "c" 119888 "𝑐" t)
- ("uprightstyle" "mathalpha" "d" 119889 "𝑑" t)
- ("uprightstyle" "mathalpha" "e" 119890 "𝑒" t)
- ("uprightstyle" "mathalpha" "f" 119891 "𝑓" t)
- ("uprightstyle" "mathalpha" "g" 119892 "𝑔" t)
- ("uprightstyle" "mathalpha" "i" 119894 "𝑖" t)
- ("uprightstyle" "mathalpha" "j" 119895 "𝑗" t)
- ("uprightstyle" "mathalpha" "k" 119896 "𝑘" t)
- ("uprightstyle" "mathalpha" "l" 119897 "𝑙" t)
- ("uprightstyle" "mathalpha" "m" 119898 "𝑚" t)
- ("uprightstyle" "mathalpha" "n" 119899 "𝑛" t)
- ("uprightstyle" "mathalpha" "o" 119900 "𝑜" t)
- ("uprightstyle" "mathalpha" "p" 119901 "𝑝" t)
- ("uprightstyle" "mathalpha" "q" 119902 "𝑞" t)
- ("uprightstyle" "mathalpha" "r" 119903 "𝑟" t)
- ("uprightstyle" "mathalpha" "s" 119904 "𝑠" t)
- ("uprightstyle" "mathalpha" "t" 119905 "𝑡" t)
- ("uprightstyle" "mathalpha" "u" 119906 "𝑢" t)
- ("uprightstyle" "mathalpha" "v" 119907 "𝑣" t)
- ("uprightstyle" "mathalpha" "w" 119908 "𝑤" t)
- ("uprightstyle" "mathalpha" "x" 119909 "𝑥" t)
- ("uprightstyle" "mathalpha" "y" 119910 "𝑦" t)
- ("uprightstyle" "mathalpha" "z" 119911 "𝑧" t)
- ("wasysym" "mathbin" "\\RHD" 9654 "▶")
- ("wasysym" "mathbin" "\\rhd" 9655 "▷")
- ("wasysym" "mathbin" "\\LHD" 9664 "◀")
- ("wasysym" "mathbin" "\\lhd" 9665 "◁")
- ("wasysym" "mathbin" "\\Circle" 9675 "○")
- ("wasysym" "mathop" "\\iint" 8748 "∬")
- ("wasysym" "mathop" "\\iiint" 8749 "∭")
- ("wasysym" "mathop" "\\oiint" 8751 "∯")
- ("wasysym" "mathord" "\\cent" 162 "¢")
- ("wasysym" "mathord" "\\AC" 8767 "∿")
- ("wasysym" "mathord" "\\invneg" 8976 "⌐")
- ("wasysym" "mathord" "\\wasylozenge" 8977 "⌑")
- ("wasysym" "mathord" "\\APLinv" 9017 "⌹")
- ("wasysym" "mathord" "\\notbackslash" 9024 "⍀")
- ("wasysym" "mathord" "\\APLleftarrowbox" 9031 "⍇")
- ("wasysym" "mathord" "\\APLrightarrowbox" 9032 "⍈")
- ("wasysym" "mathord" "\\APLuparrowbox" 9040 "⍐")
- ("wasysym" "mathord" "\\APLdownarrowbox" 9047 "⍗")
- ("wasysym" "mathord" "\\APLcomment" 9053 "⍝")
- ("wasysym" "mathord" "\\APLinput" 9054 "⍞")
- ("wasysym" "mathord" "\\APLlog" 9055 "⍟")
- ("wasysym" "mathord" "\\CIRCLE" 9679 "●")
- ("wasysym" "mathord" "\\LEFTcircle" 9680 "◐")
- ("wasysym" "mathord" "\\RIGHTcircle" 9681 "◑")
- ("wasysym" "mathord" "\\LEFTCIRCLE" 9686 "◖")
- ("wasysym" "mathord" "\\RIGHTCIRCLE" 9687 "◗")
- ("wasysym" "mathord" "\\Square" 9744 "☐")
- ("wasysym" "mathord" "\\CheckedBox" 9745 "☑")
- ("wasysym" "mathord" "\\XBox" 9746 "☒")
- ("wasysym" "mathord" "\\frownie" 9785 "☹")
- ("wasysym" "mathord" "\\smiley" 9786 "☺")
- ("wasysym" "mathord" "\\blacksmiley" 9787 "☻")
- ("wasysym" "mathord" "\\sun" 9788 "☼")
- ("wasysym" "mathord" "\\rightmoon" 9789 "☽")
- ("wasysym" "mathord" "\\leftmoon" 9790 "☾")
- ("wasysym" "mathord" "\\mercury" 9791 "☿")
- ("wasysym" "mathord" "\\female" 9792 "♀")
- ("wasysym" "mathord" "\\earth" 9793 "♁")
- ("wasysym" "mathord" "\\male" 9794 "♂")
- ("wasysym" "mathord" "\\jupiter" 9795 "♃")
- ("wasysym" "mathord" "\\saturn" 9796 "♄")
- ("wasysym" "mathord" "\\uranus" 9797 "♅")
- ("wasysym" "mathord" "\\neptune" 9798 "♆")
- ("wasysym" "mathord" "\\pluto" 9799 "♇")
- ("wasysym" "mathord" "\\aries" 9800 "♈")
- ("wasysym" "mathord" "\\taurus" 9801 "♉")
- ("wasysym" "mathord" "\\gemini" 9802 "♊")
- ("wasysym" "mathord" "\\cancer" 9803 "♋")
- ("wasysym" "mathord" "\\leo" 9804 "♌")
- ("wasysym" "mathord" "\\virgo" 9805 "♍")
- ("wasysym" "mathord" "\\libra" 9806 "♎")
- ("wasysym" "mathord" "\\scorpio" 9807 "♏")
- ("wasysym" "mathord" "\\sagittarius" 9808 "♐")
- ("wasysym" "mathord" "\\capricornus" 9809 "♑")
- ("wasysym" "mathord" "\\aquarius" 9810 "♒")
- ("wasysym" "mathord" "\\pisces" 9811 "♓")
- ("wasysym" "mathord" "\\quarternote" 9833 "♩")
- ("wasysym" "mathord" "\\twonotes" 9835 "♫")
- ("wasysym" "mathrel" "\\notslash" 9023 "⌿")
- ("wrisym" "mathaccent" "\\lvec" 8400 "⃐")
- ("wrisym" "mathaccent" "\\vec" 8401 "⃑")
- ("wrisym" "mathaccent" "\\LVec" 8406 "⃖")
- ("wrisym" "mathaccent" "\\vec" 8407 "⃗" t)
- ("wrisym" "mathalpha" "\\Micro" 181 "µ")
- ("wrisym" "mathalpha" "\\Stigma" 986 "Ϛ")
- ("wrisym" "mathalpha" "\\stigma" 987 "ϛ")
- ("wrisym" "mathalpha" "\\Digamma" 988 "Ϝ")
- ("wrisym" "mathalpha" "\\digamma" 989 "ϝ")
- ("wrisym" "mathalpha" "\\Sampi" 992 "Ϡ")
- ("wrisym" "mathalpha" "\\Angstroem" 8491 "Å")
- ("wrisym" "mathalpha" "\\beth" 8502 "ℶ")
- ("wrisym" "mathalpha" "\\gimel" 8503 "ℷ")
- ("wrisym" "mathalpha" "\\daleth" 8504 "ℸ")
- ("wrisym" "mathclose" "\\rrbracket" 10215 "⟧")
- ("wrisym" "mathop" "\\fint" 10767 "⨏")
- ("wrisym" "mathopen" "\\llbracket" 10214 "⟦")
- ("wrisym" "mathord" "\\backepsilon" 1014 "϶")
- ("wrisym" "mathord" "\\Euler" 8455 "ℇ")
- ("wrisym" "mathord" "\\CapitalDifferentialD" 8517 "ⅅ")
- ("wrisym" "mathord" "\\DifferentialD" 8518 "ⅆ")
- ("wrisym" "mathord" "\\ExponetialE" 8519 "ⅇ")
- ("wrisym" "mathord" "\\ComplexI" 8520 "ⅈ")
- ("wrisym" "mathord" "\\ComplexJ" 8521 "ⅉ")
- ("wrisym" "mathord" "\\rightangle" 8735 "∟")
- ("wrisym" "mathord" "\\measuredangle" 8737 "∡")
- ("wrisym" "mathord" "\\sphericalangle" 8738 "∢")
- ("wrisym" "mathord" "\\therefore" 8756 "∴")
- ("wrisym" "mathord" "\\because" 8757 "∵")
- ("wrisym" "mathover" "\\overparen" 9180 "⏜")
- ("wrisym" "mathrel" "\\leftrightarrow" 8596 "↔" t)
- ("wrisym" "mathrel" "\\MapsUp" 8613 "↥")
- ("wrisym" "mathrel" "\\MapsDown" 8615 "↧")
- ("wrisym" "mathrel" "\\LeftArrowBar" 8676 "⇤")
- ("wrisym" "mathrel" "\\RightArrowBar" 8677 "⇥")
- ("wrisym" "mathrel" "\\nni" 8716 "∌")
- ("wrisym" "mathrel" "\\Proportion" 8759 "∷")
- ("wrisym" "mathrel" "\\nsim" 8769 "≁")
- ("wrisym" "mathrel" "\\ncong" 8775 "≇")
- ("wrisym" "mathrel" "\\napprox" 8777 "≉")
- ("wrisym" "mathrel" "\\Bumpeq" 8782 "≎")
- ("wrisym" "mathrel" "\\bumpeq" 8783 "≏")
- ("wrisym" "mathrel" "\\nequiv" 8802 "≢")
- ("wrisym" "mathrel" "\\nleq" 8816 "≰")
- ("wrisym" "mathrel" "\\ngeq" 8817 "≱")
- ("wrisym" "mathrel" "\\NotLessTilde" 8820 "≴")
- ("wrisym" "mathrel" "\\NotGreaterTilde" 8821 "≵")
- ("wrisym" "mathrel" "\\NotGreaterLess" 8825 "≹")
- ("wrisym" "mathrel" "\\nprec" 8832 "⊀")
- ("wrisym" "mathrel" "\\nsucc" 8833 "⊁")
- ("wrisym" "mathrel" "\\nsubset" 8836 "⊄")
- ("wrisym" "mathrel" "\\nsupset" 8837 "⊅")
- ("wrisym" "mathrel" "\\nsubseteq" 8840 "⊈")
- ("wrisym" "mathrel" "\\nsupseteq" 8841 "⊉")
- ("wrisym" "mathrel" "\\npreceq" 8928 "⋠")
- ("wrisym" "mathrel" "\\nsucceq" 8929 "⋡")
- ("wrisym" "mathrel" "\\nsqsubseteq" 8930 "⋢")
- ("wrisym" "mathrel" "\\nsqsupseteq" 8931 "⋣")
- ("wrisym" "mathrel" "\\UpArrowBar" 10514 "⤒")
- ("wrisym" "mathrel" "\\DownArrowBar" 10515 "⤓")
- ("wrisym" "mathrel" "\\leftrightharpoonup" 10574 "⥎")
- ("wrisym" "mathrel" "\\rightupdownharpoon" 10575 "⥏")
- ("wrisym" "mathrel" "\\leftrightharpoondown" 10576 "⥐")
- ("wrisym" "mathrel" "\\leftupdownharpoon" 10577 "⥑")
- ("wrisym" "mathrel" "\\LeftVectorBar" 10578 "⥒")
- ("wrisym" "mathrel" "\\RightVectorBar" 10579 "⥓")
- ("wrisym" "mathrel" "\\RightUpVectorBar" 10580 "⥔")
- ("wrisym" "mathrel" "\\RightDownVectorBar" 10581 "⥕")
- ("wrisym" "mathrel" "\\DownLeftVectorBar" 10582 "⥖")
- ("wrisym" "mathrel" "\\DownRightVectorBar" 10583 "⥗")
- ("wrisym" "mathrel" "\\LeftUpVectorBar" 10584 "⥘")
- ("wrisym" "mathrel" "\\LeftDownVectorBar" 10585 "⥙")
- ("wrisym" "mathrel" "\\LeftTeeVector" 10586 "⥚")
- ("wrisym" "mathrel" "\\RightTeeVector" 10587 "⥛")
- ("wrisym" "mathrel" "\\RightUpTeeVector" 10588 "⥜")
- ("wrisym" "mathrel" "\\RightDownTeeVector" 10589 "⥝")
- ("wrisym" "mathrel" "\\DownLeftTeeVector" 10590 "⥞")
- ("wrisym" "mathrel" "\\DownRightTeeVector" 10591 "⥟")
- ("wrisym" "mathrel" "\\LeftUpTeeVector" 10592 "⥠")
- ("wrisym" "mathrel" "\\LeftDownTeeVector" 10593 "⥡")
- ("wrisym" "mathrel" "\\LeftTriangleBar" 10703 "⧏")
- ("wrisym" "mathrel" "\\RightTriangleBar" 10704 "⧐")
- ("wrisym" "mathrel" "\\Equal" 10869 "⩵")
- ("wrisym" "mathrel" "\\Same" 10870 "⩶")
- ("wrisym" "mathrel" "\\NestedLessLess" 10913 "⪡")
- ("wrisym" "mathrel" "\\NestedGreaterGreater" 10914 "⪢")
- ("wrisym" "mathunder" "\\underparen" 9181 "⏝"))
- "Mathematical symbols from various LaTeX packages.
-Each element is of the form
-
- (PACKAGE CLASS COMMAND UNICODE SYMBOL CONFLICT)
-
-Optional CONFLICT is a Boolean that indicates that this command
-conflicts or generates different symbol from math-unicode
-package. Thus the generated LaTeX symbol might be different from
-5th element (symbol) in the list above. See LUCR reference [1]
-for more details. Package 'literal' corresponds to core (La)TeX.
-
- [1] http://milde.users.sourceforge.net/LUCR/Math/")
-
-(defconst math-symbol-list-subscripts
- '(("subscript" "_0" 8320 "₀")
- ("subscript" "_1" 8321 "₁")
- ("subscript" "_2" 8322 "₂")
- ("subscript" "_3" 8323 "₃")
- ("subscript" "_4" 8324 "₄")
- ("subscript" "_5" 8325 "₅")
- ("subscript" "_6" 8326 "₆")
- ("subscript" "_7" 8327 "₇")
- ("subscript" "_8" 8328 "₈")
- ("subscript" "_9" 8329 "₉")
- ("subscript" "_+" 8330 "₊")
- ("subscript" "_-" 8331 "₋")
- ("subscript" "_=" 8332 "₌")
- ("subscript" "_(" 8333 "₍")
- ("subscript" "_)" 8334 "₎")
- ("subscript" "_a" 8336 "ₐ")
- ("subscript" "_e" 8337 "ₑ")
- ("subscript" "_h" 8341 "ₕ")
- ("subscript" "_i" 7522 "ᵢ")
- ("subscript" "_j" 11388 "ⱼ")
- ("subscript" "_k" 8342 "ₖ")
- ("subscript" "_l" 8343 "ₗ")
- ("subscript" "_m" 8344 "ₘ")
- ("subscript" "_n" 8345 "ₙ")
- ("subscript" "_o" 8338 "ₒ")
- ("subscript" "_p" 8346 "ₚ")
- ("subscript" "_r" 7523 "ᵣ")
- ("subscript" "_s" 8347 "ₛ")
- ("subscript" "_t" 8348 "ₜ")
- ("subscript" "_u" 7524 "ᵤ")
- ("subscript" "_v" 7525 "ᵥ")
- ("subscript" "_x" 8339 "ₓ")
- ("subscript" "_beta" 7526 "ᵦ")
- ("subscript" "_gamma" 7527 "ᵧ")
- ("subscript" "_rho" 7528 "ᵨ")
- ("subscript" "_varphi" 7529 "ᵩ")
- ("subscript" "_chi" 7530 "ᵪ"))
- "List of unicode subscripts.
-See `math-symbol-list-extended' for the meaning of the entries.")
-
-(defconst math-symbol-list-superscripts
- '(("superscripts" "^0" 8304 "⁰")
- ("superscripts" "^1" 185 "¹")
- ("superscripts" "^2" 178 "²")
- ("superscripts" "^3" 179 "³")
- ("superscripts" "^4" 8308 "⁴")
- ("superscripts" "^5" 8309 "⁵")
- ("superscripts" "^6" 8310 "⁶")
- ("superscripts" "^7" 8311 "⁷")
- ("superscripts" "^8" 8312 "⁸")
- ("superscripts" "^9" 8313 "⁹")
- ("superscripts" "^+" 8314 "⁺")
- ("superscripts" "^-" 8315 "⁻")
- ("superscripts" "^=" 8316 "⁼")
- ("superscripts" "^(" 8317 "⁽")
- ("superscripts" "^)" 8318 "⁾")
- ("superscripts" "^a" 7491 "ᵃ")
- ("superscripts" "^b" 7495 "ᵇ")
- ("superscripts" "^c" 7580 "ᶜ")
- ("superscripts" "^d" 7496 "ᵈ")
- ("superscripts" "^e" 7497 "ᵉ")
- ("superscripts" "^f" 7584 "ᶠ")
- ("superscripts" "^g" 7501 "ᵍ")
- ("superscripts" "^h" 688 "ʰ")
- ("superscripts" "^i" 8305 "ⁱ")
- ("superscripts" "^j" 690 "ʲ")
- ("superscripts" "^k" 7503 "ᵏ")
- ("superscripts" "^l" 737 "ˡ")
- ("superscripts" "^m" 7504 "ᵐ")
- ("superscripts" "^n" 8319 "ⁿ")
- ("superscripts" "^o" 7506 "ᵒ")
- ("superscripts" "^p" 7510 "ᵖ")
- ("superscripts" "^r" 691 "ʳ")
- ("superscripts" "^s" 738 "ˢ")
- ("superscripts" "^t" 7511 "ᵗ")
- ("superscripts" "^u" 7512 "ᵘ")
- ("superscripts" "^v" 7515 "ᵛ")
- ("superscripts" "^w" 695 "ʷ")
- ("superscripts" "^x" 739 "ˣ")
- ("superscripts" "^y" 696 "ʸ")
- ("superscripts" "^z" 7611 "ᶻ")
- ("superscripts" "^A" 7468 "ᴬ")
- ("superscripts" "^B" 7470 "ᴮ")
- ("superscripts" "^D" 7472 "ᴰ")
- ("superscripts" "^E" 7473 "ᴱ")
- ("superscripts" "^G" 7475 "ᴳ")
- ("superscripts" "^H" 7476 "ᴴ")
- ("superscripts" "^I" 7477 "ᴵ")
- ("superscripts" "^J" 7478 "ᴶ")
- ("superscripts" "^K" 7479 "ᴷ")
- ("superscripts" "^L" 7480 "ᴸ")
- ("superscripts" "^M" 7481 "ᴹ")
- ("superscripts" "^N" 7482 "ᴺ")
- ("superscripts" "^O" 7484 "ᴼ")
- ("superscripts" "^P" 7486 "ᴾ")
- ("superscripts" "^R" 7487 "ᴿ")
- ("superscripts" "^T" 7488 "ᵀ")
- ("superscripts" "^U" 7489 "ᵁ")
- ("superscripts" "^V" 11389 "ⱽ")
- ("superscripts" "^W" 7490 "ᵂ")
- ("superscripts" "^beta" 7517 "ᵝ")
- ("superscripts" "^gamma" 7518 "ᵞ")
- ("superscripts" "^delta" 7519 "ᵟ")
- ("superscripts" "^theta" 7615 "ᶿ")
- ("superscripts" "^iota" 7589 "ᶥ")
- ("superscripts" "^varphi" 7520 "ᵠ")
- ("superscripts" "^chi" 7521 "ᵡ"))
- "List of unicode superscripts.
-See `math-symbol-list-extended' for the meaning of each entry.")
-
-(provide 'math-symbol-lists)
-;;; math-symbol-lists.el ends here
diff --git a/packages/math-symbol-lists/msl-build.el
b/packages/math-symbol-lists/msl-build.el
deleted file mode 100644
index bb9f1b5..0000000
--- a/packages/math-symbol-lists/msl-build.el
+++ /dev/null
@@ -1,168 +0,0 @@
-;;; msl-build.el --- functions to build symbol lists -*- lexical-binding:t -*-
-
-;; Copyright (C) 2019 Free Software Foundation, Inc.
-
-;; Author: Vitalie Spinu <spinuvit@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, 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. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;;
-
-;;; Code:
-
-(require 'cl-lib)
-
-;; IMPORT UTILITIES
-;;
-;; Utilities for reading LUCR list from [1] and optionally PRINT. LUCR list is
a
-;; super-set of unicode-math list [2]. FILE is a local file from [3].
-;;
-;; [1] http://milde.users.sourceforge.net/LUCR/Math/
-;; [2] https://github.com/wspr/unicode-math/blob/master/unicode-math-table.tex
-;; [3] http://milde.users.sourceforge.net/LUCR/Math/data/unimathsymbols.txt
-
-(defun msl--LUCR-parse-alias (str)
- ;; (msl--LUCR-parse-alias "= \\Theta (-slantedGreek)")
- ;; (msl--LUCR-parse-alias "= \\mathrm{\\Theta}")
- (when (and str (msl--no-{}-p str))
- (if (string-match " ?= ?\\(\\\\[^() ]+\\) *$" str)
- (cons (match-string 1 str) "latex")
- (if (string-match " ?= ?\\(\\\\[^() ]+\\) *(\\(.+\\)) *$" str)
- (cons (match-string 1 str) (match-string 2 str))))))
-
-(defun msl--LUCR-parse-line (line)
- (let* ((words (split-string line "\\^"))
- (comment (nth 7 words))
- (aliases (when comment
- (delq nil
- (mapcar #'msl--LUCR-parse-alias
- (split-string comment ", *")))))
- (packages (when (> (length (nth 6 words)) 0)
- (split-string (nth 6 words) " +")))
- (usymb (nth 1 words)))
- (when (> (length usymb) 0)
- (list (nth 0 words) ;; 0: HEX Code
- (when (> (length usymb) 0)
- (substring usymb -1)) ;; 1: Unicode Symbol
- (nth 2 words) ;; 2: La(TeX) command
- (nth 3 words) ;; 3: unicode-math package command
- (nth 4 words) ;; 4: Class
- (nth 5 words) ;; 5: category
- packages ;; 6: packages (prefixed with _
are conflicts)
- aliases)))) ;; 7: aliases (conses of (alias
. package))
-
-(defun msl--no-{}-p (str)
- (not (string-match "[{}]" str)))
-
-(defun msl--LUCR-read-file (file)
- (let ((lines (with-temp-buffer
- (insert-file-contents file)
- (split-string (buffer-string) "\n" t))))
- (delq nil
- (cl-loop for l in lines
- unless (string-match-p "^#" l)
- collect (msl--LUCR-parse-line l)))))
-
-(defun msl--LUCR-to-msl (lucr &optional latex alias no-parse)
- "Convert LUCR list to this package conventions.
-If LATEX is non-nil, give package and latex command instead of
-unicode-math command. If ALIAS is non-nil give package and latex
-command from alias field. "
- (cl-flet ((code (el) (if no-parse (car el) (string-to-number (car el) 16))))
- (let ((sl (delq nil
- (cond
- (latex (mapcan (lambda (el)
- (and (> (length (nth 2 el)) 0)
- (> (length (nth 6 el)) 0)
- (msl--no-{}-p (nth 2 el))
- (mapcar (lambda (pkg)
- (list pkg (nth 5 el) (nth
2 el) (code el) (nth 1 el)))
- (nth 6 el))))
- lucr))
- (alias (mapcan (lambda (el)
- (mapcan (lambda (pkg)
- (and (> (length (car pkg)) 0)
- (msl--no-{}-p (car pkg))
- (mapcar (lambda (pkg2)
- (list pkg2 (nth
5 el) (car pkg) (code el) (nth 1 el)))
- (split-string
(cdr pkg) " +"))))
- (nth 7 el)))
- lucr))
- (t (mapcar (lambda (el)
- (and (string-match-p "\\\\" (nth 3 el))
- (list (nth 5 el) (nth 3 el) (code el)
(nth 1 el))))
- lucr))))))
- (when (or latex alias)
- (setq sl (mapcar (lambda (el)
- (if (not (string-match-p "^-" (car el)))
- el
- (append (list (substring (car el) 1)) (cdr el)
(list t))))
- sl)))
- (cl-sort sl (lambda (a b) (string-lessp (concat (car a) (cadr a))
(concat (car b) (cadr b))))))))
-
-(defun msl--LUCR-filter-LaTeX-aliases (list)
- (delq nil
- (mapcar (lambda (el)
- (when (cl-some (lambda (al)
- (and (string= "latex" (cdr al))
- (msl--no-{}-p (car al))))
- (nth 7 el))
- el))
- list)))
-
-;; this is how you build those
-(defun msl--build-things ()
- (let* ((tt (msl--LUCR-read-file "./data/unimathsymbols.txt"))
- ;; extra aliases for basic symbols
- (tt2 (msl--LUCR-filter-LaTeX-aliases tt)))
- (msl--LUCR-to-msl tt2 nil t)
-
- ;; extended
- (msl--LUCR-to-msl tt)
- ;; packages
- (msl--LUCR-to-msl tt t)
- ;; aliases
- (msl--LUCR-to-msl tt nil t)))
-
-
-;; SUBSCRIPTS and SUPERSCRIPTS
-
-(defvar msl-superscripts
"ⱽª²³¹ºʰʱʲʳʴʵʶʷʸˠˡˢˣᴬᴭᴮᴯᴰᴱᴲᴳᴴᴵᴶᴷᴸᴹᴺᴻᴼᴽᴾᴿᵀᵁᵂᵃᵄᵅᵆᵇᵈᵉᵊᵋᵌᵍᵎᵏᵐᵑᵒᵓᵔᵕᵖᵗᵘᵙᵚᵛᵜᵝᵞᵟᵠᵡᵸᶛᶜᶝᶞᶟᶠᶡᶢᶣᶤᶥᶦᶧᶨᶩᶪᶫᶬᶭᶮᶯᶰᶱᶲᶳᶴᶵᶶᶷᶸᶹᶺᶻᶼᶽᶾᶿ⁰ⁱ⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ")
-
-;; taken from
https://github.com/tpapp/company-unicode-subsuper/blob/master/company-unicode-subsuper.el
-(defconst msl-unicode-name-table
- '((?β . "beta")
- (?γ . "gamma")
- (?δ . "delta")
- (?θ . "theta")
- (?ɩ . "iota")
- (?φ . "varphi") ; varphi instead of phi, as in LaTeX
- (?χ . "chi")
- (?ρ . "rho")
- (?− . "-")) ; replace #x2212 with minus sign
- "table for entering characters outside the ASCII range. Follows conventions
of LaTeX for Greek letters, but without the \\ prefix.")
-
-(defun msl-gen-scripted-alist (char-str type prefix)
- (mapcar (lambda (c)
- (let* ((dec (cdr (get-char-code-property c 'decomposition)))
- (plain (or (cdr (assoc (car dec) msl-unicode-name-table))
dec)))
- (list type (concat prefix plain) c (char-to-string c))))
- char-str))
-
-;; (msl-gen-scripted-alist "₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑₕᵢⱼₖₗₘₙₒₚᵣₛₜᵤᵥₓᵦᵧᵨᵩᵪ" "subscript"
"_")
-;; (msl-gen-scripted-alist
"⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ᵃᵇᶜᵈᵉᶠᵍʰⁱʲᵏˡᵐⁿᵒᵖʳˢᵗᵘᵛʷˣʸᶻᴬᴮᴰᴱᴳᴴᴵᴶᴷᴸᴹᴺᴼᴾᴿᵀᵁⱽᵂᵝᵞᵟᶿᶥᵠᵡ"
"superscripts" "^")
-
-;;; msl-build.el ends here
diff --git a/packages/math-symbol-lists/readme.md
b/packages/math-symbol-lists/readme.md
deleted file mode 100644
index 8c1a72f..0000000
--- a/packages/math-symbol-lists/readme.md
+++ /dev/null
@@ -1,15 +0,0 @@
-This is a "storage" package used by completion engines such as
`company-math.el` and `ac-math.el`.
-
-Defined (a)lists are:
-
- `math-symbol-list-basic`
- `math-symbol-list-extended`
- `math-symbol-list-packages`
- `math-symbol-list-latex-commands`
-
-
-## Known packages that use these lists
-
- - [company-math](https://github.com/vspinu/company-math)
- - [ac-math](https://github.com/vspinu/ac-math)
- - [unicode-math-input](https://github.com/tpapp/unicode-math-input)
diff --git a/packages/names/Other-Packages.org
b/packages/names/Other-Packages.org
deleted file mode 100644
index 910615e..0000000
--- a/packages/names/Other-Packages.org
+++ /dev/null
@@ -1,25 +0,0 @@
-* Other Packages
-*Names* isn't the first package to try patching up namespaces in
-Emacs. Here we link to descriptions and provide short comparisons of
-previous packages attempting similar things.
-** [[https://github.com/Wilfred/with-namespace.el][with-namespace]]
-The closest to *Names* in terms of ideology. It performs simple
-namespacing of symbols inside =defun= forms and alike.
-
-The difference is that *Names* performs intelligent namespacing (it
-understand which symbols are vars, which are functions, and which are
-not fit for namespacing) and applies to any form under the sun.
-** [[https://github.com/sigma/codex][Codex]]
-A robust and somewhat similar option. Notable differences are that
-*Names* does have edebug integration (which greatly facilitates actual
-development) and is generally more focused on being practical (write
-code as you would, just without the prefix).
-** [[https://github.com/skeeto/elisp-fakespace/][Fakespace]]
-Focuses on the global obarray clobbering, not on code clobbering. It
-uninterns defined symbols, while *Names* actually simplifies the code
-that you write.
-** [[https://github.com/chrisbarrett/elisp-namespaces][elisp-namespaces]]
-Possibly the safest and faciest of the bunch. It's a great way to
-avoid clobbering the global obarray if you're willing to use its
-syntax. Like above, the difference it that *Names* actually simplifies
-that you type.
diff --git a/packages/names/Readme.org b/packages/names/Readme.org
deleted file mode 100644
index b1e3405..0000000
--- a/packages/names/Readme.org
+++ /dev/null
@@ -1,123 +0,0 @@
-#+OPTIONS: toc:nil num:nil
-
-* Names
[[https://travis-ci.org/Bruce-Connor/names?branch=master][https://secure.travis-ci.org/Bruce-Connor/names.png?branch=master]]
-
-*Names* is designed as a practical, complete, robust, and debuggable
-tool which writes your namespaces for you.
-
-It is part of Emacs and is available trough
[[https://elpa.gnu.org/packages/names.html][GNU Elpa]], so every
-Emacs user running at least 24.1 has access to it.
-
-[[file:package-example.png]]\\
-/Example usage of Names to namespace an emacs-lisp function./
-*** A Namespace implementation for Emacs-Lisp
-
-The *Names* package aims to provide an implementation of
-namespaces in Emacs with four guiding principles:
-
-- Practical :: Actually useful and easy to grasp.
-- Complete :: Support any macro, function, or special-form available in
- emacs-lisp, /even/ the ones defined by you or a third
- party.
-- Robust :: No-surprises, well-tested, and with clearly stated
- limitations.
-- Debuggable :: Support *edebug* and =eval-defun=, and any other
- package developing tools.
-
-See [[https://github.com/Bruce-Connor/spaces#why-a-namespace-package][Why a
namespace package?]] for a description on why this is
-necessary, and see
[[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/Other-Packages.org][Other-Packages.org]]
for a description and comparison
-of previous packages attempting similar things.
-
-**** Version Compatibility
-Currently, *Names* is being supported on the entire Emacs 24 family
-(24.1--24.4). Any new changes or pull requests are tested on a
-[[https://travis-ci.org/Bruce-Connor/names][Travis-CI machine]]. See the
/“tests”/ subdirectory for our test suite,
-and see .
-
-** Usage
-The
[[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/UsageExample.org][UsageExample]]
file clearly displays and explains how to use *Names*
-in your package. There are few simple measures to take. Go have a look
-if you’re interested, I promise it’s worth it!
-
-If you want deeper descriptions of use-cases, see
[[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]].
-
-** Developer Tools
-*Names* offers a series of tools to make package writing more
-convenient inside a namespace. These developer facilities are on this
-separate file, so the file isn't loaded on the user's computer when
-your package calls =(require 'names)=.
-
-To access them add the following line to your init file.
-#+begin_src emacs-lisp
-(require 'names-dev)
-#+end_src
-
-*** Edebug and eval-defun support
-
-First and foremost, the =edebug-eval-defun= command (bound to =C-u
-C-M-x=) is an essential tool for any package developer. *Names*
-wouldn't be a very useful utility if it prevented you from using this
-asset.
-
-Therefore, it provides the =names-eval-defun= command, which is
-identical to =edebug-eval-defun= except it also works inside
-namespaces. It will automatically be added to your
-=emacs-lisp-mode-map=.
-
-*** Font-locking
-Font-lock for =define-namespace= and =:autoload=.
-
-*** Expansion and comparison functions
-=names-compare-forms= and =names-print= offer information when
-something just doesn't seem to make sense.
-
-** Nomenclature
-
-The name of this package is *Names*, always with a capital “N”.
-Despite the word being plural, refer to it in the singular (e.g.,
-“Names is an amazing achievement”). If possible consider giving it a
-slight emphasis, such as: /Names/.
-When there's a risk of confusion or ambiguity, be it due to context or
-lack of knowledge by the reader, =names.el= is also acceptable.
-
-** Why a namespace package?
-Plain and simple: Emacs doesn't have namespaces, and it needs them.
-
-Nic Ferrier has a
[[http://nic.ferrier.me.uk/blog/2013_06/adding-namespaces-to-elisp][great essay
on the subject]], and you might want to
-read
[[https://lists.gnu.org/archive/html/emacs-devel/2014-12/msg00772.html][an
opposing opinion]] as well. Note that *Names* is very different
-from the solution he proposes, but it does solve the problem he had
-with other alternatives which left the debugger unusable.
-
-Emacs takes the approach of prefixing every symbol name with the name
-of the package. This successfully avoids name clashes between
-packages, but it quickly leads to code that's repetitive and annoying
-to write. Below is an example from =package.el=, the word "/package/"
-is repeated 7 times in a 10-line function.
-
-*Names* doesn't change this overall approach. It adheres to Emacs
-standards and is completely invisible to the end-user. *Names* simply
-gives /you/ (the developer) a convenient way of writing code that
-adheres to this standard.
-
-[[file:package-example.png]]
-/Example usage of Names to namespace an emacs-lisp function./
-
-- At runtime, the right-hand-side will create the same definitions as the
left-hand-side.
-- At compilation, it will create the exact same compiled file (with no
left-over reference to =names.el= functions).
-
-*** Tested On:
-Below are the packages on which I've tested *Names*. If you're
-interested, try using it on one of your packages and
[[https://github.com/Bruce-Connor/names/issues][let me know how
-it goes]].
-**** elnode
-- *Number of ert tests passed:* Same as before namespacing (62).
-- *Reduction in code size:* Approx. 2000 characters.
-**** s.el
-- *Number of ert tests passed:* All.
-- *Reduction in code size:* Approx. 1000 characters (8%).
-1000 characters is a lot when you consider /s.el/ has the second
-shortest namespace possible, =s-=.
-**** dash.el
-- *Number of ert tests passed:* Same as before namespacing (104).
-**** latex-extra
-- *Number of ert tests passed:* ALL.
diff --git a/packages/names/TheNittyGritty.org
b/packages/names/TheNittyGritty.org
deleted file mode 100644
index 84bf6b8..0000000
--- a/packages/names/TheNittyGritty.org
+++ /dev/null
@@ -1,197 +0,0 @@
-* The Nitty Gritty
-In general, =define-namespace= should work as you expect it to. But if you
-need to understand why something is or isn't being namespaced, here's
-the nitty gritty of how it happens.
-
-** Quoted Lists
-Quoted lists (be it with =quote= or =function=) are namespaced *only*
-of the list is a =lambda= form (or a =macro= form). Arbitrary lists
-are returned untouched (they are way too arbitrary to be handled
-sanely). That is:
-#+begin_src emacs-lisp
-(define-namespace foo-
-(defun infinite (y)
- (mapcar
- '(lambda (x) (infinite x))
- '(not a lambda (infinite x))))
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defun foo-infinite (y)
- (mapcar
- '(lambda (x) (foo-infinite x))
- '(not a lambda (infinite x))))
-#+end_src
-
-Note that = '(lambda ...)= is bad practice in Emacs, you should use
-=(lambda ...)= instead (which is also namespaced just fine).
-
-** Symbols Quoted with Quote
-A symbol quoted with =quote= (or = ' =) is never namespaced.
-#+begin_src emacs-lisp
-(define-namespace foo-
-(defvar var nil)
-(defvaralias 'varalias 'var)
-(defun fun nil)
-(defalias 'alias 'fun)
-(defalias 'otheralias 'var)
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defvar foo-var nil)
-(defvaralias 'varalias 'var)
-(defun foo-fun nil)
-(defalias 'alias 'fun)
-;;; foo-var is not a function, so:
-(defalias 'otheralias 'var)
-#+end_src
-
-If you provide the =:assume-var-quote= keyword, quoted symbols will be
-namespaced as variables instead.
-** Symbols Quoted with Function
-A symbol quoted with =function= (or =#' =) is assumed to be the name of a
-function, and will be namespaced as such if possible. You may provide
-the =:dont-assume-function-quote= keyword to disable this behaviour,
-=function= will then be treated like =quote=.
-
-#+begin_src emacs-lisp
-(define-namespace foo-
-(defun fun (x) x)
-(mapcar 'fun somelist)
-(mapcar #'fun somelist)
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defun foo-fun (x) x)
-(mapcar 'fun somelist)
-(mapcar #'foo-fun somelist)
-#+end_src
-
-** Backticks (quasi-quotes)
-Backticks (or =`=) are handled as you would expect. Lists or simbles
-quoted with a backtick are treated the same as those quoted with
-regular quotes ([[#quoted-lists][see above]]), except anything prefixed by a
comma (which
-is effectively not quoted) is namespaced as usual.
-
-** Local Variables Take Precedence
-Local variables take precedence over namespace variables.
-For instance
-#+begin_src emacs-lisp
-(define-namespace foo-
-(defvar bar "2")
-
-(defun funca (bar)
- (string-to-int bar))
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defvar foo-bar "2")
-
-(defun funca (bar)
- (string-to-int bar))
-#+end_src
-
-Note how the last =bar= isn't namespaced. That's because it is local
-to the =funca= function, and takes precedence over the global
-=foo-bar=. The argument list of functions, macros, and lambdas are
-all local definitions.
-
-By default, this does not happen with let bindings, they are
-namespaced as usual (if the variable name in question has a global
-definition). The reason is that let bindings are commonly used to
-temporarily override global bindings.
-
-You can customize this behaviour with the =:no-let-vars= keyword.
-Then:
-#+begin_src emacs-lisp
-(define-namespace foo- :no-let-vars
-(defvar bar "2")
-
-(let ((bar "1"))
- (string-to-int bar))
-)
-#+end_src
-will expand to
-#+begin_src emacs-lisp
-(defvar foo-bar "2")
-
-(let ((bar "1"))
- (string-to-int bar))
-#+end_src
-
-** Macros
-Macros are handled in a very intelligent manner.
-
-*Names* needs to know which parts of a macro's arguments are
-evaluatable forms, and which are just arbitrary symbols. This presents
-a challenge because macro arguments could be absolutely anything.
-Fortunately, (good) macros already provide that information in their
-=debug= declaration.
-
-Thus, *Names* uses the macro's =edebug-spec-list= to find out which
-arguments are evaluatable forms, and namespaces only those. Other
-arguments are left untouched. Usually, this is not something you'll
-need to worry about, it should just do what you expect from it.
-
-This is only relevant if you write your own macros. If you do,
-remember to add a debug declaration in them.
-
-*** The theading macros (~->~ and ~-->~)
-
-The threading macros would require special treatment to namespace
-correctly. However, you can use the ~:functionlike-macros~ keyword to
-tell *Names* to treat them as regular functions.
-
-For example, in the following snippet:
-#+BEGIN_SRC emacs-lisp
-(require 'dash)
-(define-namespace foo-
-:functionlike-macros (-> ->>)
-
-(defvar var nil)
-(defun fun (x &optional y)
- (concat x y))
-
-(-> "some string"
- (fun var)
- fun)
-)
-#+END_SRC
-the ~(fun var)~ part would be namespaced prefectly fine (~fun~ and
-~var~ will be identified as a function and variable respectively),
-because it looks like a regular function call. However, the second use
-of ~fun~ will not be correctly namespaced, because that ~fun~ looks
-like a variable.
-
-In other words, you should use these macros like this instead:
-#+BEGIN_SRC emacs-lisp
-(-> "some string"
- (fun var)
- (fun))
-#+END_SRC
-
-** Accessing Global Symbols
-If one of your definitions shadows a global definition, you can still
-access it by prefixing it with =::=.
-
-#+begin_src emacs-lisp
-(define-namespace foo-
-(defun message ()
- (message)
- (::message "Hi"))
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defun foo-message ()
- (foo-message)
- (message "Hi"))
-#+end_src
-
-When in doubt feel free to use =::=, it will always get removed (as
-long as it's not inside a =quote=). You may also change this prefix to
-something else with the =:prefix= keyword.
diff --git a/packages/names/Todo.org b/packages/names/Todo.org
deleted file mode 100644
index 6face42..0000000
--- a/packages/names/Todo.org
+++ /dev/null
@@ -1,38 +0,0 @@
-* Bugs
-** DONE Outside macros that depend on your macro will throw errors
- CLOSED: [2014-11-09 Sun 18:10]
-This happens because we have to wrap everything in a progn, which the
-compiler/interpreter expands then evaluates. So the outside macro is
-expanded before YOUR macro has been evaluated (and thus defined).
-
-Example:
-#+begin_src emacs-lisp
-(require 'cl-lib)
-
-(defspace name-
-(defmacro cas (string)
- (declare (debug t))
- `(cdr (assoc-string ,string '(("a" . 1) ("b" . 0)))))
-
-(defun incf ()
- "Increment the count of packages in STATUS."
- (cl-incf (cas "a")))
-)
-#+end_src
-
-Not sure how to fix, given it's limited by our use of progn, which I
-don't think we can get around.
-* Not sure how to do:
-** DONE Make eval-defun work inside namespaces.
- CLOSED: [2014-11-09 Sun 18:10]
-** TODO Special treatment for defstruct.
-Right now it's simply being handled as a macro
-* Just do it
-** TODO Add a :use keyword to defspace.
-** TODO Namespace symbols in doc strings.
- Should include =`symbol'=, =\\<symbol>= and =\\{symbol}=.
-** TODO Namespace the
[[https://www.gnu.org/software/emacs/manual/html_node/cl/Argument-Lists.html][initform]]
of cl arglists.
-** DONE Don't call edebug if debug-spec is t or 0.
- CLOSED: [2014-07-17 Thu 19:14]
-** TODO Describe keywords in an info manual, and refer to it instead of the
website.
-* Not sure whether should be done:
diff --git a/packages/names/UsageExample.org b/packages/names/UsageExample.org
deleted file mode 100644
index 1786187..0000000
--- a/packages/names/UsageExample.org
+++ /dev/null
@@ -1,219 +0,0 @@
-* Usage Example
-The following code shows how you can write a package using *Names*.
-The important items are already listed in the Readme:
-
-1. List =names= as a dependency.
-2. Wrap all code that’s to be namespaced inside a =(define-namespace NAME
...)= macro.
-
-
-#+BEGIN_SRC emacs-lisp
-;;; example.el --- Just an example
-
-;;; You have to add this requirement!!
-;; Package-Requires: ((names "Lookup.Latest.Version") (emacs "24"))
-
-;;; Code:
-
-;; `define-namespace' is autoloaded, so there's no need to require
-;; `names'. However, requiring it here means it will also work for
-;; people who don't install through package.el.
-(eval-when-compile (require 'names))
-
-;;;###autoload
-(define-namespace example-
-
-(defvar has-courage nil)
-
-(defmacro with-courage (name &rest body)
- "Evaluate BODY, don't evaluate NAME."
- (declare (debug (sexp body-form))
- (indent defun))
- ;; `example-has-courage' is inside a quoted form, so it needs to be
- ;; written explicitly.
- `(let ((example-has-courage ',name))
- ,@body))
-
-;;; this is how you autoload:
-:autoload
-(defun fight (evil)
- "Fight EVIL!"
- (with-courage evil
- (-fight-internal)))
-
-(defun -fight-internal ()
- "Called by `example-fight'"
- (when has-courage
- ;; `has-courage' here is will be expanded to `example-has-courage'.
- (let ((has-courage nil))
- (message "Victory!"))))
-)
-
-(provide 'example)
-;;; example.el ends here
-
-#+END_SRC
-
-** Expands to this
-To see this expansion yourself.
-1. Replace the =define-namespace= above with a =names-print= (a macro designed
to help developers like you).
-2. Make sure you load the /“names-dev.el”/ file included here.
-3. evaluate the whole thing.
-
-#+BEGIN_SRC emacs-lisp
-(defvar example-has-courage nil)
-
-(defmacro example-with-courage (name &rest body)
- "Evaluate BODY, don't evaluate NAME."
- (declare (debug (sexp body))
- (indent defun))
- `(let ((example-has-courage ',name))
- ,@body))
-
-;;;###autoload
-(defun example-fight (evil)
- "Fight EVIL!"
- (example-with-courage evil
- (example--fight-internal)))
-
-(defun example--fight-internal nil
- "Called by `example-fight'"
- (when example-has-courage
- (let ((has-courage nil))
- (message "Victory!"))))
-#+END_SRC
-
-* Usage Instructions
-
-Follow these steps:
-
-1. Remember to list =names= as a dependency.
-2. Wrap all code that's to be namespaced inside a =(define-namespace NAME
...)= macro.
-3. Pleasantly remove all that redundant repetition from you code!
-4. When quoting function names, use =#' = instead of = ' =.
-5. If you have =;;;###autoload= comments inside your =define-namespace=:
- 1. Replace them with =:autoload= keywords
- 2. Add an =;;;###autoload= tag immediately above your =define-namespace=.
-
-*What you need to know:* There are essentially three rules that are
-applied when namespacing.
-*** 1. Every definition gets namespaced
-Any definitions inside =BODY= will have =NAME= prepended to the
-symbol given:
-#+begin_src emacs-lisp
-;;;###autoload
-(define-namespace foo-
-
-(defvar bar 1 "docs")
-
-:autoload
-(defun free ()
- "DOC"
- (message "hi"))
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defvar foo-bar 1 "docs")
-
-;;;###autoload
-(defun foo-free ()
- "DOC"
- (message "hi"))
-#+end_src
-
-*** 2. Functions and variables are namespaced if defined
-Any function calls (or variable names) get NAME prepended to them if
-the symbol in question is defined as a function (or a variable,
-respectively) inside the current =define-namespace= form. It doesn't
-matter if the function/variable is called before actually being
-defined, *Names* will find it.
-
-In other words, a function call or variable name is /“looked up
-locally”/. If it is not found, it is assumed /“global”/. You can force
-a symbol to be global, by preppending it with =::=.
-
-That is:
-#+begin_src emacs-lisp
-(define-namespace foo-
-
-(defvar var infinite)
-
-(defun infinite (x)
- (infinite x))
-
-(cond
- ((::infinite 2) (message "Global function call"))
- ((something-else t) (message "Global function call"))
- ((infinite var) (message "Local function call."))
- (infinite (message "Variable.")))
-)
-#+end_src
-expands to
-#+begin_src emacs-lisp
-(defvar foo-myvar infinite)
-
-(defun foo-infinite (x)
- (foo-infinite x))
-
-(cond
- ((infinite 2) (message "Global function call"))
- ((something-else t) (message "Global function call"))
- ((foo-infinite foo-var) (message "That was a function call."))
- (infinite (message "That was a variable.")))
-#+end_src
-
-Note how:
-- The =infinite= symbol gets namespaced only as a function name (/not/
- when it's used as a variable), because =define-namespace= knowns
- that =foo-infinite= is not a variable.
-- The symbol inside =(infinite 2)= is not namespaced, because it had
- been protected with =::=.
-- =something-else= is not namespaced, because it is not a locally
- defined function, so it must be global.
-
-*** 3. Forms not meant for evaluation are not namespaced.
-Whenever a form is not meant for evaluation, it is left completely
-untouched. Some examples where this applies are:
-- Lists and symbols quoted with a simple quote (e.g. = 'foo=), these are
regarded as data, not code;
-- Any argument of a macro which doesn't get evaluated, e.g, the =KEYLIST=
arguments of =cl-case=.
-
-Some examples of the opposite:
-- Symbols quoted with a function quote (e.g. =#'foo=) are regarded as
- function names, and are namespaced as explained in
[[#2-functions-and-variables-are-namespaced-if-defined][item 2]]. That's
- why we recommend you always use function quotes for functions.
-- Comma forms inside a backtick form (e.g. =`(nothing ,@(function)
- ,variable)=) *are* meant for evaluation and so *will* be namespaced.
-
-*** Limitations
-
-The main effect of
[[#3-forms-not-meant-for-evaluation-are-not-namespaced][item 3]] is that the
usual way of writing
-=defalias= and =defvaralias= won't be namespaced. That is
-#+begin_src emacs-lisp
-(define-namespace test-
-(defalias 'yell #'message)
-)
-;; simply expands to this
-(defalias 'yell #'message)
-;; instead of this
-(defalias 'test-yell #'message)
-#+end_src
-
-This is not considered a bug. The =SYMBOL= argument of a defalias
-could just as well be an arbitrary form whose value isn't even defined
-until runtime. Therefore, there is no consistent way of handling a
-defalias, and we choose to just treat it as any other function call.
-
-Just remember to add the namespace in your defalias and defvaralias forms.
-
-*** Case-by-case Examples
-In general, =define-namespace= should work as you expect it to. But if you
-need to understand why something is or isn't being namespaced, have a
-look at
[[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]]
-
-
-
-* Keywords - Customizing the behaviour
-Immediately after the name of your space you may add keywords which
-customize the behaviour of =define-namespace=. See the variable
-=names--keyword-list= for a description of each possible keyword, or
-visit
[[https://github.com/Bruce-Connor/emacs-lisp-namespaces/blob/master/TheNittyGritty.org][TheNittyGritty.org]]
for a description with examples.
diff --git a/packages/names/names-dev.el b/packages/names/names-dev.el
deleted file mode 100644
index c139d64..0000000
--- a/packages/names/names-dev.el
+++ /dev/null
@@ -1,254 +0,0 @@
-;;; names-dev.el --- Developer Functions to facilitate use of names.el with
your package.
-
-;; Copyright (C) 2014 Free Software Foundation, Inc.
-
-;; Prefix: names
-;; Separator: -
-
-;;; Commentary:
-;;
-;; This package has some convenient functions for developers working
-;; with names.el.
-;; This package is installed along with names.el, but to use its
-;; features you must require it explicitly:
-;;
-;; (require 'names-dev)
-
-;;; License:
-;;
-;; 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/>.
-
-;;; Code:
-
-(require 'names)
-(require 'elisp-mode nil t)
-(require 'lisp-mode nil t)
-
-
-;;; ---------------------------------------------------------------
-;;; Developer Utility Functions
-(defmacro names-compare-forms (name form-a form-b)
- "Test if (namespace NAME FORM-A) is the same as FORM-B."
- (declare (indent (lambda (&rest x) 0))
- (debug (symbolp sexp form)))
- `(equal
- (macroexpand-all '(define-namespace ,name :global :verbose ,form-a))
- (macroexpand-all ',form-b)))
-
-(defmacro names-compare-forms-assert (name form-a form-b)
- "Assert if (namespace NAME FORM-A) is the same as FORM-B."
- (declare (indent (lambda (&rest x) 0))
- (debug (symbolp sexp form)))
- (cl-assert
- (names-compare-forms name form-a form-b)
- t))
-
-(defmacro names-print (name &rest forms)
- "Return the expanded results of (namespace NAME :global :verbose FORMS).
-Ideal for determining why a specific form isn't being parsed
-correctly. You may need to set `eval-expression-print-level' and
-`eval-expression-print-length' to nil in order to see your full
-expansion."
- (declare (indent (lambda (&rest x) 0)) (debug 0))
- `(define-namespace ,name :global :verbose ,@forms))
-
-(defvar names-font-lock
- '(("^:autoload\\_>" 0 'font-lock-warning-face prepend)
- ("(\\(\\_<define-namespace\\_>\\)[\t \n]+\\([^\t \n]+\\)"
- (1 'font-lock-keyword-face)
- (2 'font-lock-variable-name-face))))
-
-(when (boundp 'lisp-el-font-lock-keywords-2)
- (setq lisp-el-font-lock-keywords-2
- (append names-font-lock
- lisp-el-font-lock-keywords-2)))
-
-
-;;; The backbone
-(defun names--looking-at-namespace ()
- "Non-nil if point is at a `define-namespace' form or an alias to it."
- (when (looking-at "(\\_<")
- (save-excursion
- (forward-char 1)
- (ignore-errors
- (equal (indirect-function (intern (thing-at-point 'symbol)))
- (indirect-function 'define-namespace))))))
-
-(defun names--generate-new-buffer (name &optional form)
- "Generate and return a new buffer.
-NAME is current namespace name.
-If FORM is provided, also try to use it to decide an informative
-buffer name."
- (get-buffer-create
- (concat
- " *names "
- (format "%s %s"
- (or (car-safe form) (random 10000))
- (or (car-safe (cdr-safe form)) (random 10000)))
- "*")))
-
-(defmacro names--wrapped-in-namespace (command form &optional kill &rest body)
- "Call COMMAND, except in a namespace.
-In a namespace, expand FORM in a separate buffer then execute
-BODY. If BODY is nil, call COMMAND instead.
-If KILL is non-nil, kill the temp buffer afterwards."
- (declare (indent defun)
- (debug (sexp form form body)))
- ;; Get the namespace, if we're in one.
- `(let ((evaled-form ,form)
- (invocation
- ',(if (commandp command t)
- `(call-interactively #',command)
- command))
- (entire-namespace
- (save-excursion
- (when (names--top-of-namespace)
- (cdr (read (current-buffer))))))
- b keylist spec name expanded-form)
-
- ;; If we're not in a namespace, call the regular `eval-defun'.
- (if (null entire-namespace)
- (eval invocation)
- ;; If we are, expand the function in a temp buffer
- (setq name (pop entire-namespace))
- (while (setq spec (names--next-keyword entire-namespace))
- (setq keylist (append keylist spec)))
- ;; Prepare the (possibly) temporary buffer.
- (setq b (names--generate-new-buffer name evaled-form))
- (unwind-protect
- (with-current-buffer b
- (cl-letf (((symbol-function #'message) #'ignore))
- (erase-buffer)
- (emacs-lisp-mode)
- ;; Print everything inside the `progn'.
- (mapc
- (lambda (it) (pp it (current-buffer)))
- (cdr
- (setq expanded-form
- (macroexpand
- `(define-namespace ,name :global :clean-output
,@keylist ,evaled-form)))))
- (when (fboundp 'font-lock-ensure)
- (font-lock-ensure)))
- ;; Return value
- ,@(or body '((eval invocation))))
- ;; Kill the buffer if we won't need it.
- (when (and ,kill (buffer-live-p b))
- (kill-buffer b))))))
-
-(defun names--top-of-namespace ()
- "Move to the top of current namespace, and return non-nil.
-If not inside a namespace, return nil and don't move point."
- (let ((top (save-excursion
- (beginning-of-defun)
- (ignore-errors
- (backward-up-list))
- (when (names--looking-at-namespace)
- (point)))))
- (when top
- (goto-char top)
- t)))
-
-(defun names-eval-defun (edebug-it)
- "Identical to `eval-defun', except it works for forms inside namespaces.
-Argument EDEBUG-IT is the same as `eval-defun', causes the form
-to be edebugged."
- (interactive "P")
- (require 'font-lock) ; just in case
- (let ((form
- (save-excursion
- (end-of-defun)
- (beginning-of-defun)
- (read (current-buffer)))))
- (names--wrapped-in-namespace
- eval-defun form (null edebug-it))))
-
-
-;;; eval-last-sexp
-(defalias 'names--preceding-sexp-original
- (if (fboundp 'elisp--preceding-sexp)
- (symbol-function 'elisp--preceding-sexp)
- (symbol-function 'preceding-sexp)))
-
-(defun names--preceding-sexp ()
- "Like `elisp--preceding-sexp', but expand namespaces."
- (names--wrapped-in-namespace
- (names--preceding-sexp-original) (names--preceding-sexp-original) t
- expanded-form))
-
-(defun names-eval-last-sexp (eval-last-sexp-arg-internal)
- "Identical to `eval-last-sexp', except it works for forms inside namespaces.
-Argument EVAL-LAST-SEXP-ARG-INTERNAL is the same as `eval-last-sexp'."
- (interactive "P")
- (cl-letf (((symbol-function 'elisp--preceding-sexp) #'names--preceding-sexp)
- ((symbol-function 'preceding-sexp) #'names--preceding-sexp))
- (eval-last-sexp eval-last-sexp-arg-internal)))
-
-(defun names-eval-print-last-sexp (eval-last-sexp-arg-internal)
- "Identical to `eval-print-last-sexp', except it works for forms inside
namespaces.
-Argument EVAL-LAST-SEXP-ARG-INTERNAL is the same as `eval-print-last-sexp'."
- (interactive "P")
- (cl-letf (((symbol-function 'elisp--preceding-sexp) #'names--preceding-sexp)
- ((symbol-function 'preceding-sexp) #'names--preceding-sexp))
- (eval-print-last-sexp eval-last-sexp-arg-internal)))
-
-;; (pp (symbol-function 'names--preceding-sexp-original) (current-buffer))
-
-(defun names-pprint ()
- "Pretty-print an expansion of the namespace around point."
- (interactive)
- (save-excursion
- (when (names--top-of-namespace)
- (let ((ns (cdr (read (current-buffer)))))
- (pp-macroexpand-expression
- (macroexpand (cons 'names-print ns)))))))
-
-
-;;; Find stuff
-(require 'find-func nil t)
-(defalias 'names--fboundp-original (symbol-function 'fboundp))
-(defalias 'names--boundp-original (symbol-function 'boundp))
-(defalias 'names--find-function-read-original (symbol-function
'find-function-read))
-(defalias 'find-function-read 'names--find-function-read)
-
-(defun names--find-function-read (&optional type)
- "Identical to `find-function-read', except it works inside namespaces."
- (let ((buf (current-buffer)))
- (names--wrapped-in-namespace
- (names--find-function-read-original type) nil t
- (set-buffer buf)
- (let ((names--name name))
- (cl-letf (((symbol-function 'fboundp) #'names--dev-fboundp)
- ((symbol-function 'boundp) #'names--dev-boundp))
- (names--find-function-read-original type))))))
-
-(defun names--dev-fboundp (sym)
- (or (names--fboundp-original sym)
- (names--fboundp-original (names--prepend sym))))
-(defun names--dev-boundp (sym)
- (or (names--boundp-original sym)
- (names--boundp-original (names--prepend sym))))
-
-
-;;; The keys
-(eval-after-load 'lisp-mode
- '(let ((map emacs-lisp-mode-map))
- (define-key map [remap eval-defun] #'names-eval-defun)
- (define-key map [remap eval-last-sexp] #'names-eval-last-sexp)
- (define-key map [remap eval-print-last-sexp]
#'names-eval-print-last-sexp)))
-
-(provide 'names-dev)
-
-;;; names-dev.el ends here
diff --git a/packages/names/names.el b/packages/names/names.el
deleted file mode 100644
index 2bb61a8..0000000
--- a/packages/names/names.el
+++ /dev/null
@@ -1,1322 +0,0 @@
-;;; names.el --- Namespaces for emacs-lisp. Avoid name clobbering without
hiding symbols. -*- lexical-binding:t -*-
-
-;; Copyright (C) 2014-2018 Free Software Foundation, Inc.
-
-;; Author: Artur Malabarba <emacs@endlessparentheses.com>
-;; URL: https://github.com/Malabarba/names
-;; Version: 20151201.0
-;; Package-Requires: ((emacs "24.1") (cl-lib "0.5") (nadvice "0.3"))
-;; Keywords: extensions lisp
-
-;;; Commentary:
-;;
-;; The description is way too large to sanely write here, below is a
-;; summary. For a complete description, please visit the package's
-;; frontpage with `M-x names-view-manual', or see the Readme file on
-;; https://raw.githubusercontent.com/Malabarba/names/master/Readme.org
-
-;;; License:
-;;
-;; 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/>.
-
-;;; News:
-;;; Code:
-
-
-(require 'cl-lib)
-;;; This is a patch because edebug binds under `C-x'.
-;; If `C-x' is not a prefix.
-(unless (consp (key-binding "\C-x"))
- ;; Disable the `C-xC-a' binds.
- (defvar edebug-inhibit-emacs-lisp-mode-bindings)
- (setq edebug-inhibit-emacs-lisp-mode-bindings t)
- ;; And the `C-xX' binds.
- (defvar global-edebug-prefix)
- (when (ignore-errors
- (or (null (boundp 'global-edebug-prefix))
- (eq ?\C-x (elt global-edebug-prefix 0))))
- (setq global-edebug-prefix "")))
-(require 'edebug)
-(require 'bytecomp)
-
-;;; Support
-(declare-function names--autoload-do-load "names" 2)
-(defalias 'names--function-get
- (if (fboundp 'function-get) #'function-get
-
- (defun names--autoload-do-load (def name)
- "Load autoloaded definition DEF from function named NAME."
- (unless (load (cadr def) 'noerror)
- (error "Macro `%s' is autoloaded, but its file (%s) couldn't be loaded"
- name (cadr def)))
- (symbol-function name))
-
- (lambda (f prop &rest _)
- "Return the value of property PROP of function F.
-If F is an autoloaded macro, try to autoload it in the hope that
-it will set PROP."
- (let ((val nil))
- (while (and (symbolp f)
- (null (setq val (get f prop)))
- (fboundp f))
- (let ((fundef (symbol-function f)))
- (if (and (names--autoloadp fundef)
- (not (equal fundef (names--autoload-do-load fundef f))))
- nil ;Re-try `get' on the same `f'.
- (setq f fundef))))
- val))))
-
-(defalias 'names--compat-macrop
- (if (fboundp 'macrop) #'macrop
- (lambda (object)
- "Non-nil if and only if OBJECT is a macro."
- (let ((def (ignore-errors (indirect-function object))))
- (when (consp def)
- (or (eq 'macro (car def))
- (and (names--autoloadp def) (memq (nth 4 def) '(macro t)))))))))
-
-(defalias 'names--autoloadp
- (if (fboundp 'autoloadp) #'autoloadp
- (lambda (object)
- "Non-nil if OBJECT is an autoload."
- (eq 'autoload (car-safe object)))))
-
-(unless (get-edebug-spec 'cl-defun)
- (def-edebug-spec cl-defun defun*))
-(unless (get-edebug-spec 'cl-defmacro)
- (def-edebug-spec cl-defmacro defmacro*))
-(unless (get-edebug-spec 'setq-local)
- (def-edebug-spec setq-local setq))
-(unless (get-edebug-spec 'loop)
- (def-edebug-spec loop
- (&rest &or
- ;; These are usually followed by a symbol, but it can
- ;; actually be any destructuring-bind pattern, which
- ;; would erroneously match `form'.
- [[&or "for" "as" "with" "and"] sexp]
- ;; These are followed by expressions which could
- ;; erroneously match `symbolp'.
- [[&or "from" "upfrom" "downfrom" "to" "upto" "downto"
- "above" "below" "by" "in" "on" "=" "across"
- "repeat" "while" "until" "always" "never"
- "thereis" "collect" "append" "nconc" "sum"
- "count" "maximize" "minimize" "if" "unless"
- "return"] form]
- ;; Simple default, which covers 99% of the cases.
- symbolp form)))
-
-
-;;; ---------------------------------------------------------------
-;;; Variables
-(defconst names-version "20151201.0" "Version of the names.el package.")
-
-(defvar names--name nil
- "Name of the current namespace inside the `define-namespace' macro.")
-(defvar names--regexp nil "Regexp matching `names--name'.")
-
-(defvar names--load-file (and load-file-name (expand-file-name load-file-name))
- "The file where the current version of Names was loaded.
-This is used by `names--check-for-update' to check if a new
-version has been installed.")
-
-(defvar names--bound nil
- "List of variables defined in this namespace.")
-(defvar names--fbound nil
- "List of functions defined in this namespace.")
-(defvar names--macro nil
- "List of macros defined in this namespace.")
-
-(defvar names--keywords nil
- "Keywords that were passed to the current namespace.
-See `names--keyword-list' for a list and description of possible
-keywords.")
-
-(defvar names--local-vars nil
- "Non-global vars that are let/lambda bound at the moment.
-These won't be namespaced, as local takes priority over namespace.")
-
-(defvar names--protection nil
- "Leading chars used to identify protected symbols.
-Don't customise this.
-Instead use the :protection keyword when defining the
-namespace.")
-
-(defvar names--current-run nil
- "Either 1 or 2, depending on which runthrough we're in.")
-
-(defvar names--var-list
- '(names--name names--regexp names--bound
- names--version
- names--package names--group-parent
- names--macro names--current-run
- names--fbound names--keywords
- names--local-vars names--protection)
- "List of variables the user shouldn't touch.")
-
-(defvar names--inside-make-autoload nil
- "Used in `make-autoload' to indicate we're making autoloads.")
-
-(defvar names--package nil
- "Package, name to be used by the :group and :version keywords.
-Is derived from `load-file-name', unless the :package keyword is
-passed to `define-namespace'.")
-
-(defvar names--group-parent nil
- "The name of the parent to be given to `defgroup'.
-Is only non-nil if the :group keyword is passed to `define-namespace'.")
-
-(defvar names--version nil
- "The version number given by :version.
-Used to define a constant and a command.")
-
-(defvar names--functionlike-macros nil
- "Function-like macros, even if their debug-spec says otherwise.
-When expanding the namespace, these macros will be treated
-exactly like functions. This means that their contents will be
-namespaced like regular function arguments.
-
-To add macros to this list, pass the :functionlike-macros keyword
-to your namespace along with a list of macro names (as unquoted
-symbols).
-Example:
-
- (define-namespace foo-
- :functionlike-macros (-> ->> thread-first thread-last)
- ;; Rest of code
- )")
-
-(defconst names--keyword-list
- `((:group
- 1 ,(lambda (x)
- (if (or (symbolp x) (listp x))
- (setq names--group-parent x)
- (names--warn
- "Argument given to :group is not a symbol: %s" x)))
- "Indicate `define-namespace' should make a `defgroup' for you.
-The name of the group is the package name (see :package keyword).
-This keyword should be given one argument, the name of the PARENT
-group as an unquoted symbol.
-
-Alternatively, the argument can be a list, in which case it is a
-list of arguments to be passed to `defgroup' (essentially, a full
-group definition without the leading `defgroup').
-
-If this keyword is provided, besides including a defgroup, Names
-will also include a :group keyword in every `defcustom' (and
-similar forms) that don't already contain one.")
-
- (:version
- 1
- ,(lambda (x)
- (if (stringp x)
- (setq names--version x)
- (names--warn
- "Argument given to :version is not a string: %s" x)))
- "Indicate `define-namespace' should define the version number.
-This keyword should be given one argument, a string describing
-the package's version number.
-
-With this, Names will generate a `defconst' and an interactive
-`defun', each named `PACKAGE-NAME-version'. The function messages
-and returns the version number. See the :package keyword.")
-
- (:package
- 1
- ,(lambda (x)
- (if (symbolp x)
- (setq names--package x)
- (names--warn
- "Argument given to :package is not a symbol: %s" x)))
- "Set the name of this package to the given symbol.
-This keyword should be given one argument, a symbol corresponding
-to the name of this package.
-
-If this keyword isn't used, the package name is taken as the the
-file's basename, but only if its actually needed. This name is
-needed by the :version and :group keywords.")
-
- (:protection
- 1
- ,(lambda (x)
- (let ((val (symbol-name x)))
- (setq names--protection
- (format "\\`%s" (regexp-quote val)))))
- "Change the value of the `names--protection' variable.")
-
- (:functionlike-macros
- 1
- ,(lambda (x) (setq names--functionlike-macros
- (append x names--functionlike-macros)))
- "A list of values to be appended to `names--functionlike-macros'.")
-
- (:no-let-vars
- 0 nil
- "Indicates variables assigned in let-bind are NOT candidates for
namespacing.")
-
- (:verbose
- 0 nil
- "Cause a message to be called on each special form.")
-
- (:global
- 0 nil
- "Accept namespaced names from outside current namespace definition.")
-
- (:assume-var-quote
- 0 nil
- "Indicate symbols quoted with `quote' should be considered variable
names.")
-
- (:dont-assume-function-quote
- 0 nil
- "Indicate symbols quoted with `function' should NOT be considered
function names.")
-
- (:clean-output
- 0 nil
- "Indicate only forms actually inside the namespace should be present in
the output.
-This is for internal use. It is used by `names-eval-defun' to
-prevent `define-namespace' from adding things like `defgroup' or
-`defconst's to the output."))
- "List of keywords used by `define-namespace'.
-Each element is a list containing
- (KEYWORD N DEFINITION DOCUMENTATION)
-where:
-
-- KEYWORD is the keyword's name, a symbol satifying `keywordp'.
-- N is the number of arguments it takes, an integer.
-- DEFINITION is a function (symbol or lambda) that takes N
-arguments and does whatever you need for implementing the
-keyword.
-- DOCUMENTATION is a string explaining the keyword's
-behaviour.")
-
-(defmacro names--prepend (sbl)
- "Return namespace+SBL."
- (declare (debug (symbolp)))
- `(intern (format "%s%s" names--name ,sbl)))
-
-
-(defmacro names--filter-if-bound (var &optional pred)
- "If VAR is bound and is a list, take the car of its elements which satify
PRED."
- (declare (debug (symbolp &optional function-form)))
- `(when (boundp ',var)
- (remove
- nil
- (mapcar (lambda (x) (when (funcall (or ,pred #'identity) (or (car-safe
x) x))
- (or (car-safe x) x)))
- ,var))))
-
-(defmacro names--next-keyword (body)
- "If car of BODY is a known keyword, `pop' it (and its arguments) from body.
-Returns a list (KEYWORD . ARGUMENTLIST)."
- (declare (debug sexp))
- `(let ((kar (car-safe ,body))
- out n)
- (and kar
- (keywordp kar)
- (setq n (assoc kar names--keyword-list))
- (setq n (cadr n))
- (dotimes (_ (1+ n) out)
- (push (pop ,body) out))
- (nreverse out))))
-
-(defvar names--has-reloaded nil
- "Whether `names--reload-if-upgraded' has already been called in this run.")
-
-
-;;; ---------------------------------------------------------------
-;;; The Main Macro and Main Function.
-;;;###autoload
-(defmacro define-namespace (name &rest body)
- "Inside the namespace NAME, execute BODY.
-NAME can be any symbol (not quoted), but it's highly recommended
-to use some form of separator (such as :, /, or -). For a
-complete description of this macro, please visit the frontpage
-with \\[names-view-manual].
-
-In summary, this macro has two main effects:
-
-1. Any definitions inside BODY will have NAME prepended to the
-symbol given. Ex:
-
- (define-namespace foo-
- (defvar bar 1 \"docs\")
- )
-
-expands to
-
- (defvar foo-bar 1 \"docs\")
-
-
-2. Any function calls and variable names get NAME prepended to
-them if such a variable or function exists. Ex:
-
- (define-namespace foo:
- (defun message (x y) nil)
- (message \"%s\" my-var)
- )
-
-expands to
-
- (defun foo:message (x y) nil)
- (foo:message \"%s\" my-var)
-
-Note how `message' is expanded to `foo:message' in the second
-form, because that function exists. Meanwhile, `bar' is left
-untouched because `foo:bar' is not a known variable name.
-
-===============================
-
-AUTOLOAD
-
-In order for `define-namespace' to work with \";;;###autoload\"
-comments must replace all instances of \";;;###autoload\" inside
-your `define-namespace' with `:autoload'.
-Afterwards, add an \";;;###autoload\" comment just above your
-`define-namespace'.
-
-===============================
-
-KEYWORDS
-
-Immediately after NAME you may add keywords which customize the
-behaviour of `define-namespace'. For a list of possible keywords
-and a description of their effects, see the variable
-`names--keyword-list'.
-
-\(fn NAME [KEYWORD ...] BODY)"
- (declare (indent (lambda (&rest x) 0))
- (debug (&define name [&rest keywordp &optional [&or symbolp
(symbolp . symbolp)]] body)))
- (let ((names--has-reloaded names--has-reloaded))
- ;; This was to avoid an infinite recursion, but the bug turned out
- ;; to be somewhere else. Still, I see no reason to erase this.
- (unless names--has-reloaded
- (setq names--has-reloaded t)
- (names--reload-if-upgraded))
- (names--error-if-using-vars)
- (names--define-namespace-implementation name body)))
-
-(defun names--define-namespace-implementation (name body)
- "Namespace BODY using NAME.
-See `define-namespace' for more information."
- (unwind-protect
- (let* ((names--name name)
- (names--regexp
- (concat "\\`" (regexp-quote (symbol-name name))))
- (names--current-run 0)
- ;; Use the :protection keyword to change this.
- (names--protection "\\`::")
- (names--bound
- (names--remove-namespace-from-list
- (names--filter-if-bound byte-compile-bound-variables)
- (names--filter-if-bound byte-compile-variables)))
- (names--fbound
- (names--remove-namespace-from-list
- (names--filter-if-bound byte-compile-macro-environment
'names--compat-macrop)
- (names--filter-if-bound byte-compile-function-environment
'names--compat-macrop)))
- (names--macro
- (names--remove-namespace-from-list
- (names--filter-if-bound byte-compile-macro-environment (lambda
(x) (not (names--compat-macrop x))))
- (names--filter-if-bound byte-compile-function-environment
(lambda (x) (not (names--compat-macrop x))))))
- (names--functionlike-macros names--functionlike-macros)
- names--keywords names--local-vars key-and-args
- names--version names--package names--group-parent)
- ;; Read keywords
- (while (setq key-and-args (names--next-keyword body))
- (names--handle-keyword key-and-args)
- (push key-and-args names--keywords))
-
- ;; First have to populate the bound and fbound lists. So we read
- ;; the entire form (without return it).
- (mapc (if names--inside-make-autoload
- ;; Dependencies haven't been loaded during autoload
- ;; generation, so we better ignore errors here. Ideally we
- ;; would only go through the forms marked for autoloading,
- ;; but then we wouldn't know what symbols are var/function
- ;; names.
- (lambda (form) (ignore-errors (names-convert-form form)))
- #'names-convert-form)
- body)
- (setq names--current-run (1+ names--current-run))
-
- ;; Then we go back and actually namespace the entire form, which
- ;; we'll later return so that it can be evaluated.
- (setq body
- (cons
- 'progn
- (append
- (when (and names--group-parent
- (null (names--keyword :clean-output)))
- (list (names--generate-defgroup)))
- (when (and names--version
- (null (names--keyword :clean-output)))
- ;; `names--generate-version' returns a list.
- (names--generate-version))
- (mapcar #'names-convert-form
- ;; Unless we're in `make-autoload', then just return
autoloads.
- (if names--inside-make-autoload
- (names--extract-autoloads body)
- body)))))
-
- ;; On emacs-version < 24.4, the byte-compiler cannot expand a
- ;; macro if it is being called in the same top-level form as
- ;; it was defined. That's a problem for us, since the entire
- ;; namespace is a single top-level form (we return a `progn').
- ;; The solution is for us to add the macros to
- ;; `byte-compile-macro-environment' ourselves.
- (if (and (boundp 'byte-compile-current-buffer)
- byte-compile-current-buffer
- (null names--inside-make-autoload)
- (version< emacs-version "24.4"))
- (let ((byte-compile-macro-environment
- (when (boundp 'byte-compile-macro-environment)
- byte-compile-macro-environment)))
- (mapc #'names--add-macro-to-environment (cdr body))
- (macroexpand-all body byte-compile-macro-environment))
- body))
-
- ;; Exiting the `unwind-protect'.
- (mapc (lambda (x) (set x nil)) names--var-list)))
-
-(defun names--reload-if-upgraded ()
- "Verify if there's a more recent version of Names in the `load-path'.
-If so, evaluate it."
- (ignore-errors
- (require 'find-func)
- (let ((lp (expand-file-name (find-library-name "names")))
- new-version)
- (when (and lp
- (not (string= lp names--load-file))
- (file-readable-p lp))
- (with-temp-buffer
- (insert-file-contents-literally lp)
- (goto-char (point-min))
- (setq new-version
- (save-excursion
- (when (search-forward-regexp
- "(defconst\\s-+names-version\\s-+\"\\([^\"]+\\)\""
nil t)
- (match-string-no-properties 1))))
- (when (and new-version (version< names-version new-version))
- (eval-buffer nil lp)))))))
-
-(defun names-convert-form (form)
- "Do namespace conversion on FORM.
-FORM is any legal elisp form.
-Namespace name is defined by the global variable `names--name'.
-
-See macro `namespace' for more information."
- (cond
- ((null form) form)
- ;; Function calls
- ((consp form)
- (let ((kar (car form))
- func)
- (cond
- ;; If symbol is protected, clean it.
- ((and (symbolp kar)
- (setq func (names--remove-protection kar)))
- (names--message "Protected: %s" kar)
- ;; And decide what to do with it.
- (names--handle-args func (cdr form)))
-
- ;; If kar is a list, either 1) it's a lambda form, 2) it's a
- ;; macro we don't know about yet, 3) we have a bug.
- ((consp kar)
- (when (and (null (functionp kar))
- (> names--current-run 1))
- (names--warn "Ran into the following strange form.
-Either it's an undefined macro, a macro with a bad debug declaration, or we
have a bug.\n%s" form))
- (mapcar 'names-convert-form form))
-
- ;; Namespaced Functions/Macros
- ((names--fboundp kar)
- (names--message "Namespaced: %s" kar)
- (names--args-of-function-or-macro
- (names--prepend kar) (cdr form) (names--macrop kar)))
-
- ;; General functions/macros/special-forms
- (t (names--handle-args kar (cdr form))))))
- ;; Variables
- ((symbolp form)
- (names--message "Symbol handling: %s" form)
- ;; If symbol is protected, clean it and don't namespace it.
- (or (names--remove-protection form)
- ;; Otherwise, namespace if possible.
- (if (names--boundp form)
- (names--prepend form)
- form)))
- ;; Values
- (t form)))
-
-
-;;; ---------------------------------------------------------------
-;;; Some auxiliary functions
-(defun names-view-manual ()
- "Call `browse-url' to view the manual of the Names package."
- (interactive)
- (browse-url "http://github.com/Malabarba/names"))
-
-(defun names--package-name ()
- "Return the package name as a symbol.
-Decide package name based on several factors. In order:
- 1. The :package keyword,
- 2. The namespace NAME, removing the final char."
- (or names--package
- (let ((package (symbol-name names--name)))
- (prog1 (setq names--package
- (intern (substring package 0 -1)))
- (names--warn "No :package given. Guessing `%s'"
- names--package)))))
-
-(defun names--generate-defgroup ()
- "Return a `defgroup' form for the current namespace."
- (if (listp names--group-parent)
- (cons 'defgroup names--group-parent)
- (list 'defgroup (names--package-name) nil
- (format "Customization group for %s." (names--package-name))
- :prefix (symbol-name names--name)
- :group `',names--group-parent)))
-
-(defun names--generate-version ()
- "Return a `defun' and a `defconst' forms declaring the package version.
-Also adds `version' to `names--fbound' and `names--bound'."
- (add-to-list 'names--fbound 'version)
- (add-to-list 'names--bound 'version)
- (list
- (list 'defconst (names--prepend 'version)
- names--version
- (format "Version of the %s package." (names--package-name)))
- (list 'defun (names--prepend 'version) nil
- (format "Version of the %s package." (names--package-name))
- '(interactive)
- `(message
- ,(format "%s version: %s" (names--package-name) names--version))
- names--version)))
-
-(defun names--add-macro-to-environment (form)
- "If FORM declares a macro, add it to `byte-compile-macro-environment'."
- (let ((expansion form))
- (while (names--compat-macrop (car-safe expansion))
- (setq expansion
- (ignore-errors (macroexpand
- expansion byte-compile-macro-environment))))
- (and expansion
- (car-safe expansion)
- (or (and (memq (car-safe expansion) '(progn prog1 prog2))
- (mapc #'names--add-macro-to-environment (cdr expansion)))
- (and (eq 'defalias (car-safe expansion))
- (let ((def (ignore-errors (eval (nth 2 expansion) t))))
- (and (names--compat-macrop def)
- (push (cons (ignore-errors
- (eval (nth 1 expansion) t))
- (cdr-safe def))
- byte-compile-macro-environment))))))))
-
-;;;###autoload
-(eval-after-load 'find-func
- '(progn
- (advice-add 'find-function-search-for-symbol :around
- #'names--around-find-function-search-for-symbol-advice)
- (defun names--around-find-function-search-for-symbol-advice
- (orig-fun symbol type library)
- "Make sure `find-function-search-for-symbol' understands namespaces."
- (let ((res (funcall orig-fun symbol type library)))
- (ignore-errors
- (if (cdr res)
- res
- (with-current-buffer (car res)
- (search-forward-regexp "^(define-namespace\\_>")
- (skip-chars-forward "\r\n[:blank:]")
- (let* ((names--regexp
- (concat "\\`" (regexp-quote
- (symbol-name (read (current-buffer))))))
- (short-symbol
- ;; We manually implement `names--remove-namespace'
- ;; because it might not be loaded.
- (let ((name (symbol-name symbol)))
- (when (string-match names--regexp name)
- (intern (replace-match "" nil nil name))))))
- (when short-symbol
- (funcall orig-fun short-symbol type library))))))))))
-
-(defun names--extract-autoloads (body)
- "Return a list of the forms in BODY preceded by :autoload."
- (let (acons)
- (when (setq acons (memq :autoload body))
- (cons
- (cadr acons)
- (names--extract-autoloads (cdr (cdr acons)))))))
-
-;;;###autoload
-(eval-after-load 'autoload
- '(progn
- (advice-add 'make-autoload :around #'names--before-make-autoload-advice)
- (defun names--before-make-autoload-advice
- (orig-fun form file &optional expansion)
- "Make sure `make-autoload' understands `define-namespace'.
-Use the `names--inside-make-autoload' variable to indicate to
-`define-namespace' that we're generating autoloads."
- ;; We used to have a letbind here, but this was causing a void
- ;; variable bug on Emacs 24.3.
- (require 'names)
- (if (null (eq (car-safe form) 'define-namespace))
- (funcall orig-fun form file expansion)
- (setq names--inside-make-autoload t)
- (setq form (macroexpand form))
- (setq names--inside-make-autoload nil)
- ;; Up to 24.2 `make-autoload' couldn't handle `progn's.
- (if (version< emacs-version "24.3")
- (cons 'progn
- (mapcar (lambda (x) (names--make-autoload-compat x file))
- (cdr form)))
- (funcall orig-fun form file 'expansion))))))
-
-(defun names--make-autoload-compat (form file)
- (declare-function make-autoload "autoload" (form file &optional expansion))
- (if (eq (car-safe form) 'defalias)
- form
- (make-autoload form file)))
-
-(defvar names--ignored-forms '(declare)
- "The name of functions/macros/special-forms which we return without
reading.")
-
-(defun names--handle-args (func args)
- "Generic handling for the form (FUNC . ARGS), without namespacing FUNC."
- (if (memq func names--ignored-forms)
- (cons func args)
- ;; TODO: Speed this up. Just change it to an alist or a hash-table.
- (let ((handler (intern-soft (format "names--convert-%s" func))))
- ;; Some function-like forms get special handling.
- ;; That's anything with a names--convert-%s function defined.
- (if (fboundp handler)
- (progn (names--message "Special handling: %s" handler)
- (funcall handler (cons func args)))
- ;; If it isn't special, it's either a function or a macro.
- (names--args-of-function-or-macro func args (names--compat-macrop
func))))))
-
-(defun names--message (f &rest rest)
- "If :verbose is on, pass F and REST to `message'."
- (when (names--keyword :verbose)
- (apply #'message (concat "[names] " f) rest)))
-
-(defun names--warn (f &rest rest)
- "Pass F and REST to `message', unless byte-compiling or non-interactive."
- (unless (and (null (names--keyword :verbose))
- (and (boundp 'byte-compile-function-environment)
- byte-compile-function-environment))
- (apply #'message (concat "[names] " f) rest)))
-
-(defun names--error-if-using-vars ()
- "Remind the developer that variables are not customizable."
- (mapcar
- (lambda (x)
- (when (eval x t)
- (error "[names] Global value of variable %s should be nil! %s"
- x "Set it using keywords instead")))
- names--var-list))
-
-(defun names--remove-namespace-from-list (&rest lists)
- "Return a concatenated un-namespaced version of LISTS.
-Symbols in LISTS that aren't namespaced are removed, symbols that
-are namespaced become un-namespaced."
- (delq nil (mapcar 'names--remove-namespace (apply #'append lists))))
-
-(defun names--remove-namespace (symbol)
- "Return SYMBOL with namespace removed, or nil if it wasn't namespaced."
- (names--remove-regexp symbol names--regexp))
-
-(defun names--remove-protection (symbol)
- "Remove the leading :: from SYMBOL if possible, otherwise return nil."
- (names--remove-regexp symbol names--protection))
-
-(defun names--remove-regexp (s r)
- "Return S with regexp R removed, or nil if S didn't match."
- (let ((name (symbol-name s)))
- (when (string-match r name)
- (intern (replace-match "" nil nil name)))))
-
-(defun names--quote-p (sbl)
- "Is SBL a function which quotes its argument?"
- (memq sbl '(quote function)))
-
-(defun names--fboundp (sbl)
- "Is namespace+SBL a fboundp symbol?"
- (or (memq sbl names--fbound)
- (memq sbl names--macro)
- (and (names--keyword :global)
- (fboundp (names--prepend sbl)))))
-
-(defun names--macrop (sbl)
- "Is namespace+SBL a fboundp symbol?"
- (or (memq sbl names--macro)
- (and (names--keyword :global)
- (names--compat-macrop (names--prepend sbl)))))
-
-(defun names--keyword (keyword)
- "Was KEYWORD one of the keywords passed to the `namespace' macro?"
- (assoc keyword names--keywords))
-
-(defun names--boundp (sbl)
- "Is namespace+SBL a boundp symbol?
-If SBL has a let binding, that takes precendence so this also
-returns nil."
- (and (null (memq sbl names--local-vars))
- (or (memq sbl names--bound)
- (and (names--keyword :global)
- (boundp (names--prepend sbl))))))
-
-(defvar names--verbose nil
- "If non-nil, verbose message are printed regardless of the :verbose keyword.
-Use this to easily turn on verbosity during tests.")
-
-(defun names--args-of-function-or-macro (function args macro)
- "Namespace FUNCTION's arguments ARGS, with special treatment if MACRO is
non-nil."
- (if macro
- (let ((it (names--get-edebug-spec function))
- (names--verbose (eq function 'push)))
- (names--message "Edebug-spec of `%s' is %s" function it)
- ;; Macros where we evaluate all arguments are like functions.
- (if (or (equal it t)
- (memq function names--functionlike-macros))
- (names--args-of-function-or-macro function args nil)
- ;; Macros where nothing is evaluated we can just return.
- (if (equal it 0)
- (cons function args)
- ;; Other macros are complicated. Ask edebug for help.
- (names--macro-args-using-edebug (cons function args)))))
- ;; We just convert the arguments of functions.
- (cons function (mapcar 'names-convert-form args))))
-
-(defun names--get-edebug-spec (name)
- "Get 'edebug-form-spec property of symbol NAME."
- ;; Get the spec of symbol resolving all indirection.
- (let ((spec nil)
- (indirect name))
- (while (progn
- (and (symbolp indirect)
- (setq indirect
- (names--function-get
- indirect 'edebug-form-spec 'macro))))
- ;; (edebug-trace "indirection: %s" edebug-form-spec)
- (setq spec indirect))
- spec))
-
-(defvar names--is-inside-macro nil
- "Auxiliary var used in `names--macro-args-using-edebug'.")
-
-(defvar names--gensym-counter 0
- "Counter used to uniquify symbols generated `names--gensym'.")
-
-(defun names--macro-args-using-edebug (form)
- "Namespace the arguments of macro FORM by hacking into edebug.
-This takes advantage of the fact that macros (should) declare a
-`debug' specification which tells us which arguments are actually
-Elisp forms.
-
-Ideally, we would read this specification ourselves and see how
-it matches (cdr FORM), but that would take a lot of work and
-we'd be reimplementing something that edebug already does
-phenomenally. So we hack into edebug instead."
- (require 'edebug)
- (cl-letf
- ((max-lisp-eval-depth 3000)
- (edebug-all-forms t)
- (edebug-all-defs t)
- (names--is-inside-macro form)
- ;; Prevent excessive messaging.
- ;; TODO: Don't do this if `message' is advised.
- ((symbol-function 'message) #'names--edebug-message)
- ;; Older edebugs have poor `get-edebug-spec'.
- ((symbol-function 'get-edebug-spec) #'names--get-edebug-spec)
- ;; Give symbols our own name.
- ((symbol-function 'cl-gensym) #'names--gensym)
- ;; Stop at one level deep.
- ((symbol-function 'edebug-form) #'names--edebug-form)
- ;; Don't actually wrap anything.
- ((symbol-function 'edebug-make-enter-wrapper)
- #'names--edebug-make-enter-wrapper))
- (condition-case er
- (with-temp-buffer
- (pp form 'insert)
- (goto-char (point-min))
- ;; Do the magic!
- (edebug-read-top-level-form))
- (invalid-read-syntax
- (names--warn
- "Couldn't namespace this macro using its (debug ...) declaration: %s"
- form)
- form)
- (error
- (when (equal (car-safe (cdr-safe er))
- "Lisp nesting exceeds `max-lisp-eval-depth'")
- (names--warn
- "Lisp nesting exceeded `max-lisp-eval-depth' at the following form:
%s"
- form))
- form))))
-
-(defvar names--message-backup
- (let ((f (symbol-function 'message)))
- (cond
- ((fboundp 'advice--cd*r) (advice--cd*r f))
- ((fboundp 'ad-is-advised)
- (declare-function ad-get-orig-definition "advice")
- (if (ad-is-advised 'message)
- (ad-get-orig-definition 'message)
- f))
- (t f)))
- "Where names stores `message's definition while overriding it.")
-
-(defun names--edebug-message (&rest args)
- (if (or (names--keyword :verbose) names--verbose)
- (apply names--message-backup args)
- (when args (apply #'format args))))
-
-(defun names--edebug-make-enter-wrapper (forms)
- (setq edebug-def-name
- (or edebug-def-name
- edebug-old-def-name
- (names--gensym "edebug-anon")))
- (cons 'progn forms))
-
-(defun names--gensym (prefix)
- "Generate a new uninterned symbol.
-The name is made by appending a number to PREFIX and preppending \"names\",
default \"G\"."
- (let ((num (prog1 names--gensym-counter
- (setq names--gensym-counter
- (1+ names--gensym-counter)))))
- (make-symbol (format "names-%s%d" (if (stringp prefix) prefix "G") num))))
-
-(defun names--edebug-form (cursor)
- "Parse form given by CURSOR using edebug, and namespace it if necessary."
- (require 'edebug)
- ;; Return the instrumented form for the following form.
- ;; Add the point offsets to the edebug-offset-list for the form.
- (let* ((form (edebug-top-element-required cursor "Expected form"))
- (offset (edebug-top-offset cursor))
- ;; We don't want to convert the entire form that was passed
- ;; to `names--macro-args-using-edebug', since the head of
- ;; that was already converted and it would lead to an
- ;; infinite loop.
- ;; So we check for (equal names--is-inside-macro form)
- ;; Simply incrementing a depth counter didn't work, for a
- ;; reason I can no longer remember.
-
- ;; We DO want to convert the arguments that edebug identifies
- ;; as forms (level-1). And we do that ourselves, don't pass
- ;; them to edebug.
- (func (if (or (eq names--is-inside-macro t)
- (equal names--is-inside-macro form))
- 'identity 'names-convert-form))
- (names--is-inside-macro
- (if (eq func 'names-convert-form)
- t names--is-inside-macro)))
- (names--message " [Edebug] Ran into this: %S" form)
- (names--message " Cursor: %S" cursor)
- (prog1
- (cond
- ((consp form) ;; The first offset for a list form is for the list
form itself.
- (if (eq func 'names-convert-form)
- (names-convert-form form)
- (let* ((head (car form))
- (spec (and (symbolp head) (get-edebug-spec head)))
- (new-cursor (edebug-new-cursor form offset)))
- ;; Find out if this is a defining form from first symbol.
- ;; An indirect spec would not work here, yet.
- (if (and (consp spec) (eq '&define (car spec)))
- (edebug-defining-form
- new-cursor
- (car offset) ;; before the form
- (edebug-after-offset cursor)
- (cons (symbol-name head) (cdr spec)))
- ;; Wrap a regular form.
- (edebug-list-form new-cursor)))))
-
- ((symbolp form)
- (funcall func form))
-
- ;; Anything else is self-evaluating.
- (t form))
- (edebug-move-cursor cursor))))
-
-(defun names--maybe-append-group (form)
- "Append (:group `names--package') to FORM.
-Only if the :group keyword was passed to `define-namespace' and
-if the form doesn't already have a :group."
- (if (or (null names--group-parent) (memq :group form))
- form
- (append form `(:group ',(names--package-name)))))
-
-
-;;; ---------------------------------------------------------------
-;;; Interpreting keywords passed to the main macro.
-(defun names--handle-keyword (body)
- "Call the function that handles the keyword at the car of BODY.
-Such function must be listed in `names--keyword-list'. If it is
-nil, this function just returns.
-
-Regardless of whether a function was called, the keyword is added
-to the variable `names--keywords'.
-
-The car of BODY is the keyword itself and the other elements are
-the keyword arguments, if any."
- (let ((func (nth 2 (assoc (car body) names--keyword-list))))
- (if (functionp func)
- (apply func (cdr body))
- nil)))
-
-
-;;; ---------------------------------------------------------------
-;;; Interpreting the actual forms found in BODY of the main macro.
-;;
-;; This is where the heavy work is done.
-;;
-;; If you'd like to implement support for some special form, simply
-;; define a function called `names--convert-FORM-NAME' along the
-;; lines of the functions defined below. It will be automatically used
-;; whenever that form is found.
-
-;; Defun, defmacro, and defsubst macros are pretty predictable.
-(defun names--convert-defmacro (form)
- "Special treatment for `defmacro' FORM."
- (let* ((name (cadr form))
- (spaced-name (names--prepend name))
- decl)
- (add-to-list 'names--macro name)
- (add-to-list 'names--fbound name)
- ;; Set the macros debug spec if possible. It will be relevant on
- ;; the next run.
- (when (setq decl (ignore-errors (cond
- ((eq (car-safe (nth 3 form)) 'declare)
- (nth 3 form))
- ((and (stringp (nth 3 form))
- (eq (car-safe (nth 4 form))
'declare))
- (nth 4 form))
- (t nil))))
- (setq decl (car (cdr-safe (assoc 'debug (cdr decl)))))
- (when decl (put spaced-name 'edebug-form-spec decl)))
- ;; Then convert the macro as a defalias.
- (cons
- (car form)
- (names--convert-lambda
- (cons spaced-name (cddr form))))))
-(defalias 'names--convert-defmacro* 'names--convert-defmacro)
-
-(defun names--convert-defvaralias (form)
- "Special treatment for `defvaralias' FORM."
- (let ((form (cons (car form)
- (mapcar #'names-convert-form (cdr form))))
- (name))
- (setq name (names--remove-namespace
- (ignore-errors (eval (cadr form) t))))
- (when name
- (add-to-list 'names--bound name))
- form))
-
-(defun names--convert-defalias (form)
- "Special treatment for `defalias' FORM."
- (let ((form (cons (car form)
- (mapcar #'names-convert-form (cdr form))))
- (name))
- (setq name (names--remove-namespace
- (ignore-errors (eval (cadr form) t))))
- (when name
- (add-to-list 'names--fbound name))
- form))
-
-(defun names--convert-defvar (form &optional dont-add)
- "Special treatment for `defvar' FORM.
-If DONT-ADD is nil, the FORM's `cadr' is added to `names--bound'."
- (let ((name (cadr form)))
- (unless dont-add
- (add-to-list 'names--bound name))
- (append
- (list
- (car form)
- (names--prepend name))
- (mapcar 'names-convert-form (cdr (cdr form))))))
-
-(defalias 'names--convert-defconst 'names--convert-defvar
- "Special treatment for `defconst' FORM.")
-
-(defun names--convert-defcustom (form)
- "Special treatment for `defcustom' FORM."
- (names--maybe-append-group
- (names--convert-defvar form)))
-
-(defun names--convert-custom-declare-variable (form)
- "Special treatment for `custom-declare-variable' FORM."
- (let ((name (eval (cadr form) t)) ;;ignore-errors
- (val (car (cddr form))))
- (add-to-list 'names--bound name)
- (append
- (list
- (car form)
- (list 'quote (names--prepend name)) ;cadr
- ;; The DEFAULT argument is explicitly evaluated by
- ;; `custom-declare-variable', so it should be safe to namespace
- ;; even when quoted. Plus, we need to do this because
- ;; defcustom quotes this part.
- (if (names--quote-p (car-safe val))
- (list (car val) (names-convert-form (cadr val)))
- (names-convert-form val))
- (names-convert-form (car (cdr (cdr (cdr form))))))
- (mapcar 'names-convert-form (cdr (cdr (cdr (cdr form))))))))
-
-(defun names--convert-defface (form)
- "Special treatment for `defface' FORM.
-Identical to defvar, just doesn't add the symbol to the boundp
-list. And maybe use a :group."
- (names--maybe-append-group
- (names--convert-defvar form :dont-add)))
-
-(defun names--convert-define-derived-mode (form)
- "Special treatment for `define-derived-mode' FORM."
- (let ((name (cadr form)))
- (add-to-list 'names--fbound name)
- (add-to-list 'names--bound name)
- (add-to-list 'names--bound
- (intern (format "%s-map" name)))
- (add-to-list 'names--bound
- (intern (format "%s-hook" name)))
- (append
- (names--maybe-append-group
- ;; And here we namespace it.
- (list
- (car form)
- (names--prepend name)
- (nth 2 form)
- (names-convert-form (nth 3 form))
- (names-convert-form (nth 4 form))))
- (mapcar #'names-convert-form (cddr (cl-cdddr form))))))
-
-(defun names--convert-define-minor-mode (form)
- "Special treatment for `define-minor-mode' FORM."
- (let ((name (cadr form))
- (keymap (nth 5 form)))
- ;; Register the mode name
- (add-to-list 'names--fbound name)
- (add-to-list 'names--bound name)
- (add-to-list 'names--bound (intern (format "%s-hook" name)))
- ;; Register the keymap
- (if (or (null keymap) (null (symbolp keymap)))
- (add-to-list 'names--bound (intern (format "%s-map" name)))
- (when (setq keymap (names--remove-namespace keymap))
- (add-to-list 'names--bound keymap)))
- (append
- (names--maybe-append-group
- ;; And here we namespace it.
- (list
- (car form)
- (names--prepend name)
- (nth 2 form)
- (names-convert-form (nth 3 form))
- (names-convert-form (nth 4 form))
- (names-convert-form (nth 5 form))
- (names-convert-form (nth 6 form))))
- (mapcar #'names-convert-form (cddr form)))))
-
-(defun names--convert-define-globalized-minor-mode (form)
- "Special treatment for `define-globalized-minor-mode' FORM.
-The NAME of the global mode will NOT be namespaced, despite being
-a definition. It is kept verbatim.
-This is because people tend to name their global modes as
-`global-foo-mode', and namespacing would make this impossible.
-
-The MODE and TURN-ON arguments are converted as function names.
-Everything else is converted as regular forms (which usually
-means no conversion will happen since it's usually keywords and
-quoted symbols)."
- (let ((name (names--remove-namespace (cadr form)))
- (copy (cl-copy-list form)))
- ;; Register the mode name
- (when name
- (add-to-list 'names--fbound name)
- (add-to-list 'names--bound name)
- (add-to-list 'names--bound (intern (format "%s-hook" name))))
- (names--maybe-append-group
- ;; And here we namespace it.
- (append
- (list
- (pop copy)
- (pop copy)
- (names--handle-symbol-as-function (pop copy))
- (names--handle-symbol-as-function (pop copy)))
- (mapcar #'names-convert-form copy)))))
-(defalias 'names--convert-define-global-minor-mode
- #'names--convert-define-globalized-minor-mode)
-(defalias 'names--convert-easy-mmode-define-global-mode
- #'names--convert-define-globalized-minor-mode)
-
-(defun names--convert-quote (form)
- "Special treatment for `quote' FORM.
-When FORM is (quote argument), argument too arbitrary to be
-logically namespaced and is never parsed for namespacing
- (but see :assume-var-quote in `names--keyword-list').
-
-When FORM is (function form), a symbol is namespaced as a
-function name, a list is namespaced as a lambda form."
- (let ((kadr (cadr form))
- (this-name (car form)))
- (if (and (eq this-name 'function)
- (listp kadr))
- (list this-name (names-convert-form kadr))
- (if (symbolp kadr)
- (cond
- ;; A symbol inside a function quote should be a function,
- ;; unless the user disabled that.
- ((and (eq this-name 'function)
- (null (names--keyword :dont-assume-function-quote)))
- (list 'function
- (names--handle-symbol-as-function kadr)))
-
- ;; A symbol inside a regular quote should be a function, if
- ;; the user asked for that.
- ((and (eq this-name 'quote)
- (names--keyword :assume-var-quote))
- (list 'quote
- (or (names--remove-protection kadr)
- (if (names--boundp kadr)
- (names--prepend kadr)
- kadr))))
-
- (t form))
- form))))
-
-(defun names--handle-symbol-as-function (s)
- "Namespace symbol S as a function name."
- (or (names--remove-protection s)
- (if (names--fboundp s) (names--prepend s) s)))
-
-(defalias 'names--convert-function 'names--convert-quote)
-
-(defun names--convert-macro (form)
- "Special treatment for `macro' form.
-Return (macro . (names-convert-form (cdr FORM)))."
- (cons 'macro (names-convert-form (cdr form))))
-
-(defun names--convert-lambda (form)
- "Special treatment for `lambda' FORM."
- (let ((names--local-vars
- (append (names--vars-from-arglist (cadr form))
- names--local-vars))
- (forms (cdr (cdr form))))
- (append
- (list (car form)
- (cadr form))
- (when (stringp (car forms))
- (prog1
- (list (car forms))
- (setq forms (cdr forms))))
- (when (eq 'interactive (car-safe (car forms)))
- (prog1
- (list (list (car (car forms))
- (names-convert-form (cadr (car forms)))))
- (setq forms (cdr forms))))
- (progn
- ;; (message "%S" forms)
- (mapcar 'names-convert-form forms)))))
-
-(defun names--convert-clojure (form)
- "Special treatment for `clojure' FORM."
- (names--warn "Found a `closure'! You should use `lambda's instead")
- (let ((names--local-vars
- (append (names--vars-from-arglist (cadr form))
- names--local-vars)))
- (cons
- (car form)
- (names--convert-lambda (cdr form)))))
-
-(defun names--vars-from-arglist (args)
- "Get a list of local variables from a generalized arglist ARGS."
- (remove
- nil
- (mapcar
- (lambda (x)
- (let ((symb (or (cdr-safe (car-safe x)) (car-safe x) x)))
- (when (and (symbolp symb)
- (null (string-match "^&" (symbol-name symb)))
- (null (eq symb t)))
- symb)))
- args)))
-
-(defun names--convert-defun (form)
- "Special treatment for `defun' FORM."
- (let* ((name (cadr form)))
- (add-to-list 'names--fbound name)
- (cons (car form)
- (names--convert-lambda
- (cons (names--prepend name) (cddr form))))))
-(defalias 'names--convert-defun* 'names--convert-defun)
-(defalias 'names--convert-defsubst 'names--convert-defun)
-(defalias 'names--convert-defsubst* 'names--convert-defun)
-
-(defun names--let-var-convert-then-add (sym add)
- "Try to convert SYM unless :no-let-vars is in use.
-If ADD is non-nil, add resulting symbol to `names--local-vars'."
- (let ((name (if (null (names--keyword :no-let-vars))
- (names-convert-form sym)
- sym)))
- (when add (add-to-list 'names--local-vars name))
- name))
-
-(defun names--convert-let (form &optional star)
- "Special treatment for `let' FORM.
-If STAR is non-nil, parse as a `let*'."
- (let* ((names--local-vars names--local-vars)
- (vars
- (mapcar
- (lambda (x)
- (if (car-safe x)
- (list (names--let-var-convert-then-add (car x) star)
- (names-convert-form (cadr x)))
- (names--let-var-convert-then-add x star)))
- (cadr form))))
- ;; Each var defined in a regular `let' only becomes protected after
- ;; all others have been defined.
- (unless star
- (setq names--local-vars
- (append
- (mapcar (lambda (x) (or (car-safe x) x)) vars)
- names--local-vars)))
- (append
- (list (car form) vars)
- (mapcar 'names-convert-form (cddr form)))))
-
-(defun names--convert-let* (form)
- "Special treatment for `let' FORM."
- (names--convert-let form t))
-
-(defun names--convert-cond (form)
- "Special treatment for `cond' FORM."
- (cons
- (car form)
- (mapcar
- (lambda (x) (mapcar #'names-convert-form x))
- (cdr form))))
-
-(defun names--convert-condition-case (form)
- "Special treatment for `condition-case' FORM."
- (append
- (list
- (car form)
- (cadr form)
- (names-convert-form (cadr (cdr form))))
- (mapcar
- (lambda (x)
- (cons (car x)
- (mapcar 'names-convert-form (cdr x))))
- (cddr (cdr form)))))
-
-(provide 'names)
-;;; names.el ends here
diff --git a/packages/names/package-example.png
b/packages/names/package-example.png
deleted file mode 100644
index 0ffe970..0000000
Binary files a/packages/names/package-example.png and /dev/null differ
diff --git a/packages/on-screen/.gitignore b/packages/on-screen/.gitignore
deleted file mode 100644
index c531d98..0000000
--- a/packages/on-screen/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.elc
diff --git a/packages/on-screen/on-screen.el b/packages/on-screen/on-screen.el
deleted file mode 100644
index 7379b22..0000000
--- a/packages/on-screen/on-screen.el
+++ /dev/null
@@ -1,667 +0,0 @@
-;;; on-screen.el --- guide your eyes while scrolling -*- lexical-binding: t
-*-
-
-;; Copyright (C) 2013-2020 Free Software Foundation, Inc
-
-;; Author: Michael Heerdegen <michael_heerdegen@web.de>
-;; Maintainer: Michael Heerdegen <michael_heerdegen@web.de>
-;; Created: 24 Jan 2013
-;; Keywords: convenience
-;; URL: https://github.com/michael-heerdegen/on-screen.el
-;; Version: 1.3.3
-;; Package-Requires: ((cl-lib "0"))
-
-
-;; This file is not 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:
-
-;; Scrolling can be distracting because your eyes may lose
-;; orientation. This library implements a minor mode that highlights
-;; the previously visible buffer part after each scroll.
-;;
-;; Installation: Put this library somewhere in your load-path, or
-;; install via M-x package-list-packages. Then add to your init-file:
-;;
-;; (require 'on-screen)
-;;
-;; To invoke on-screen globally for all buffers, also add
-;;
-;; (on-screen-global-mode +1)
-;;
-;; Alternatively you can use the buffer local version `on-screen-mode'.
-;; For example, add this line to your init file:
-;;
-;; (add-hook 'Info-mode-hook 'on-screen-mode)
-;;
-;; to enable it in all Info buffers.
-;;
-;; By default, fringe markers are used for highlighting - see
-;; `on-screen-highlight-method' to change that. Type M-x
-;; customize-group RET on-screen RET to see what else can be
-;; configured. If you use a configuration file (.emacs), you may also
-;; want to define mode specific settings by using buffer local
-;; variables. For example, to use non intrusive fringe markers by
-;; default, but transparent overlays in w3m, you would add
-;;
-;; (add-hook
-;; 'w3m-mode-hook
-;; (defun my-w3m-setup-on-screen ()
-;; (setq-local on-screen-highlight-method 'shadow)))
-;;
-;; to your .emacs.
-;;
-;; If you use transparent overlays for highlighting and there is the
-;; library "hexrgb.el" in your `load-path', it will be used to compute
-;; highlighting colors dynamically instead of using constant faces.
-;; I.e. if you use non-default background colors (e.g. from custom
-;; themes), on-screen will try to perform highlighting with a
-;; suitable, slightly different color. See
-;; `on-screen-highlighting-to-background-delta' to control this.
-;;
-;;
-;; Implementation notes (mainly for myself):
-;;
-;; Implementing this functionality is not as straightforward as one
-;; might think. There are commands that scroll other windows than the
-;; current one. Not only scrolling commands can scroll text - also
-;; editing or even redisplay can cause windows to scroll. There is
-;; weird stuff such as folding and narrowing, influencing the visible
-;; buffer part. And although highlighting is realized in the
-;; displayed buffers (with overlays), it must be organized on a
-;; per-window basis, because different buffer parts may be displayed
-;; in different windows, and their highlightings must not interfere.
-;;
-;; That all makes it necessary to observe windows via hacks in
-;; different hooks, and to manage information about buffers, visible
-;; parts and timers in a data structure (`on-screen-data'). It is
-;; realized as an association list whose keys are windows. There are
-;; some pitfalls - e.g. the data can be out of date if the window
-;; configuration has changed and windows display different buffers
-;; now. The data must be updated, but not simply be thrown away,
-;; because the highlightings in the old buffers must be removed
-;; nonetheless.
-;;
-;;
-;; Acknowledgments:
-;;
-;; This library was inspired by a similar feature of the "Conqueror"
-;; web browser.
-;;
-;; Thanks for Drew Adams for testing and contributions.
-
-
-
-
-;;; Code:
-
-;;;; Requirements
-
-(eval-when-compile
- (require 'cl-lib))
-(require 'timer)
-(require 'hexrgb nil t)
-
-(declare-function hexrgb-saturation "hexrgb")
-(declare-function hexrgb-approx-equal "hexrgb")
-(declare-function hexrgb-increment-value "hexrgb")
-(declare-function hexrgb-increment-hue "hexrgb")
-
-
-;;;; Configuration stuff
-
-(defgroup on-screen nil
- "Guide your eyes while scrolling."
- :group 'convenience
- :prefix "on-screen")
-
-(defcustom on-screen-inverse-flag nil
- "What area to highlight.
-When nil, highlight the previously visible screenful. Else
-highlight the previously off-screen parts."
- :type 'boolean)
-
-(defcustom on-screen-highlight-method 'fringe
- "Type of highlighting used by `on-screen-mode'.
-The following values are valid:
-
- fringe - graphical markers in the fringe
- shadow - transparent overlay on the text
- line - transparent overlay on the confining text lines
- narrow-line - narrow horizontal lines
-
-The fringe and the narrow-line methods only work on graphical
-displays. narrow-line only works with Emacs 24 or higher.
-
-`on-screen-inverse-flag' defines which part(s) of the buffers are
-highlighted.
-
-The face used for \"shadow\" and \"line\" may be computed
-dynamically to support different background colors (color themes)
-- see `on-screen-highlighting-to-background-delta'."
- :type '(choice
- (const :tag "Fringe markers" fringe)
- (const :tag "Transparent overlay" shadow)
- (const :tag "Overlay on confining text lines" line)
- (const :tag "Narrow horizontal line" narrow-line)))
-
-(defcustom on-screen-fringe-marker-position t
- "Where to display fringe markers.
-Ignored if highlighting doesn't use the fringe."
- :type '(choice
- (const :tag "Left fringe only" left)
- (const :tag "Right fringe only" right)
- (const :tag "Both sides" t)))
-
-(defface on-screen-shadow
- '((((class color) (min-colors 88) (background light))
- :background "#f2efcb" ; alternative: "#f5f4ff" is a bit less intrusive
- )
- (((class color) (min-colors 88) (background dark))
- :background "#272620")
- (((class color) (min-colors 8) (background light))
- :background "green")
- (((class color) (min-colors 8) (background dark))
- :background "blue"))
- "Face used for displaying a transparent overlay.")
-
-(defface on-screen-hl-line
- '((((background light)) :background "#ffa0a0")
- (((background dark)) :background "#300000"))
- "Face used for displaying the \"line\" style overlay.")
-
-(defcustom on-screen-highlighting-to-background-delta .05
- "How much shadow and line highlighting should differ from background.
-This should be a positive floating point number less than 1.
-Smaller values will lead to a highlighting color being more
-similar to the frame background. A value of nil means to use use
-just face `on-screen-shadow'.
-
-This variable is ignored if the library \"hexrgb\" is not
-available."
- :type '(choice (const :tag "Use standard face" nil)
- (float :tag "Delta")))
-
-(defface on-screen-fringe '((t (:inherit shadow)))
- "Face used for fringe markers.")
-
-(defface on-screen-narrow-line
- '((((background dark)) (:width extra-expanded :underline (:color "gray30"
:style wave)))
- (((background light)) (:width extra-expanded :underline (:color "gray70"
:style wave))))
- "Face used by the narrow-line highlighting method.")
-
-(defcustom on-screen-delay 5
- "How long `on-screen-mode' should display optical aids."
- :type 'number)
-
-(defcustom on-screen-auto-update t
- "Whether to update highlighting for successive scrolls.
-When non-nil, every scroll action will cause a highlighting
-according to the previously visible screenful. When nil, a once
-drawn highlighting will remain fixed relative to the text even
-if you scroll further until `on-screen-delay' is over."
- :type 'boolean)
-
-(defcustom on-screen-remove-when-edit nil
- "Whether to instantly remove highlighting when editing.
-
-In those situations where a single command causes multiple
-changes to a buffer highlighting is always removed to avoid
-confusion."
- :type 'boolean)
-
-(defvar on-screen-treat-cut-lines--default-fraction .3)
-
-(defcustom on-screen-treat-cut-lines nil
- "Whether to care about vertically cut lines.
-If nil, always count lines at the window start or end that are
-only partially visible as part of the visible area. Else, a
-number between 0 and 1, meaning that lines will count as visible
-when the hidden part of them is less than this number. Note that
-a non-nil value may make scrolling stuttering on slow computers."
- :type `(choice (const :tag "Count partially visible lines as visible" nil)
- (const :tag "Count partially visible lines as not visible" t)
- (float
- :tag "Count lines with hidden part less than this as visible"
- :value ,on-screen-treat-cut-lines--default-fraction)))
-
-(defcustom on-screen-drawing-threshold 2
- "If set, highlight only when scrolled at least that many lines."
- :type '(choice (const :tag "Off" nil)
- (integer :value 2)))
-
-(defvar on-screen-inhibit-highlighting nil
- "Disable highlighting if non-nil.
-This variable is checked before highlighting is actually being
-performed, with the according buffer being current.
-
-If a function, it will be called with zero arguments.
-Highlighting will be inhibited if the result is non-nil.")
-
-
-;;;; Other variables
-
-(defvar on-screen-overlay-priority 30 ; > stripe buffer, < ediff, isearch
- "Priority for all on-screen overlays.")
-
-(defvar on-screen-initialized-p nil
- "Whether we have already added stuff to the hooks.")
-
-(defvar on-screen-data nil
- "Association list holding internal data.")
-
-(defvar on-screen-command-counter 0)
-(defvar on-screen-last-change 0)
-
-
-;;;; User Commands
-
-;;;###autoload
-(define-minor-mode on-screen-mode
- "Buffer local minor mode guiding your eyes while scrolling.
-With a prefix argument ARG, enable the mode if ARG is positive,
-and disable it otherwise. If called from Lisp, enable the mode
-if ARG is omitted or nil.
-Type M-x customize-group on-screen RET for configuration."
- :group 'on-screen
- (when on-screen-mode
- (unless on-screen-initialized-p
- (on-screen-initialize))))
-
-;;;###autoload
-(define-minor-mode on-screen-global-mode
- "Global minor mode guiding your eyes while scrolling.
-With a prefix argument ARG, enable the mode if ARG is positive,
-and disable it otherwise. If called from Lisp, enable the mode
-if ARG is omitted or nil.
-
-You can make use of `on-screen-inhibit-highlighting' to prevent
-highlighting on a per-buffer basis.
-
-Type M-x customize-group on-screen RET for configuration."
- :group 'on-screen :global t
- (when on-screen-global-mode
- (unless on-screen-initialized-p
- (on-screen-initialize))))
-
-;;;###autoload
-(defalias 'global-on-screen-mode 'on-screen-global-mode)
-
-
-;;;; Internal functions
-
-(defun on-screen--treat-cut-lines-get-fraction ()
- (if (floatp on-screen-treat-cut-lines)
- on-screen-treat-cut-lines
- on-screen-treat-cut-lines--default-fraction))
-
-(defun on-screen-window-start (&optional window)
- "Like `window-start', but exclude partially visible lines."
- (let* ((start (window-start window))
- (vis (and on-screen-treat-cut-lines (pos-visible-in-window-p start
window t))))
- (if (not (cddr vis))
- start
- (cl-destructuring-bind (_x _y rtop _rbot rowh _vpos) vis
- (if (< (/ (float rtop) (+ rtop rowh))
- (on-screen--treat-cut-lines-get-fraction)) ; count as visible
- start
- (with-current-buffer (window-buffer window)
- (save-excursion
- (goto-char start)
- (on-screen-beginning-of-line +2)
- (point))))))))
-
-(defun on-screen-window-end (&optional window)
- "Like `window-end', but exclude partially visible lines."
- (let* ((end (window-end window))
- (vis (and on-screen-treat-cut-lines (pos-visible-in-window-p (1- end)
window t))))
- (if (not (cddr vis))
- end
- (cl-destructuring-bind (_x _y _rtop rbot rowh _vpos) vis
- (if (< (/ (float rbot) (+ rbot rowh))
- (on-screen--treat-cut-lines-get-fraction)) ; count as visible
- end
- (with-current-buffer (window-buffer window)
- (save-excursion
- (goto-char end)
- (on-screen-beginning-of-line 0)
- (point))))))))
-
-(defun on-screen-beginning-of-line (&optional n)
- (cl-callf or n 1)
- (forward-visible-line (- n 1)))
-
-(defun on-screen-end-of-line (&optional n)
- (cl-callf or n 1)
- (forward-visible-line (- n 1))
- (end-of-visible-line))
-
-(defun on-screen-record-data (win area &optional timer overlays)
- ;; The collected data has the form ((beg end) timer overlays), and
- ;; this is what `on-screen-get-data' returns. Internally, this
- ;; function also remembers the window-buffer of the window, to
- ;; enable the mode to check if remembered data still belongs to the
- ;; same buffer.
- "Store information for window WIN in `on-screen-data'.
-AREA is a list (beg end). TIMER is the currently active timer
-object. OVERLAYS are the on-screen overlays currently visible in
-WIN.
-
-A nil value for AREA, TIMER or OVERLAYS means that the remembered
-values should not be changed. If TIMER is the symbol `finished',
-remember nil for the timer."
- (let* ((entry (assoc win on-screen-data))
- (data (cdr entry))
- (same-buffer-p (eq (car data) (window-buffer win))))
- (setq area (or area (and same-buffer-p (cadr data)))
- timer (cond ((timerp timer) timer)
- (timer nil)
- (t (and same-buffer-p (cl-caddr data))))
- overlays (or overlays (and same-buffer-p (cl-cadddr data)))
- data `(,(window-buffer win) ,area ,timer ,overlays))
- (if entry
- (setcdr entry data)
- (push (cons win data) on-screen-data))))
-
-(defun on-screen-get-data (win)
- "Return stored data for WIN if existent and up-to-date."
- (let ((data (cdr (assoc win on-screen-data))))
- (if (eq (car data) (window-buffer win))
- (cdr data)
- nil)))
-
-(defun on-screen-cleanup-data ()
- "Delete information stored for deleted windows."
- (setq on-screen-data
- (delq nil (mapcar (lambda (entry) (if (window-live-p (car entry))
entry nil))
- on-screen-data))))
-
-(defun on-screen-derive-from-frame-bg
- (win delta-brightness-dark-bg delta-brightness-light-bg delta-hue)
- "Helper calculating a suitable background color for highlighting."
- (let ((frame (window-frame win)))
- (and (display-graphic-p frame) (featurep 'hexrgb)
- (let* ((bg (or (let ((frame-bg (cdr (assq 'background-color
(frame-parameters frame)))))
- (when (member frame-bg '(nil unspecified
"unspecified-bg"))
- (setq frame-bg (if (eq (frame-parameter frame
'background-mode) 'dark)
- "Black"
- "White")))
- (and frame-bg (x-color-defined-p frame-bg)
frame-bg))))
- (sat (condition-case nil (hexrgb-saturation bg) (error nil))))
- (and sat
- (if (hexrgb-approx-equal sat 0.0)
- ;; Grayscale - change bg value slightly.
- (hexrgb-increment-value
- bg (if (eq (frame-parameter frame 'background-mode) 'dark)
- delta-brightness-dark-bg
- delta-brightness-light-bg))
- (hexrgb-increment-hue bg delta-hue)) ; Color - change bg hue
slightly.
- )))))
-
-(defun on-screen-get-shadow-face (win)
- "Return face for the transparent overlay in WIN."
- (if (eq on-screen-highlight-method 'shadow)
- (or (and on-screen-highlighting-to-background-delta
- (let ((bg-col (apply #'on-screen-derive-from-frame-bg win
- (mapcar (lambda (x) (* x
on-screen-highlighting-to-background-delta))
- (list 1 -1 1)))))
- (and bg-col `((t (:background ,bg-col))))))
- 'on-screen-shadow)
- 'on-screen-hl-line))
-
-(defun on-screen-make-fringe-overlays (pos topp &optional inversep)
- "Create and return list of fringe overlays."
- (let (ov1 ov2)
- (unless (eq on-screen-fringe-marker-position 'left)
- (setq ov1 (save-excursion (make-overlay (progn (goto-char pos)
-
(on-screen-beginning-of-line
- (cond ((not inversep)
+1)
- (topp
+2)
- (t
0)))
- (point))
- (1+ (point)))))
- (overlay-put ov1 'before-string (on-screen-fringe-string topp nil
inversep)))
- (unless (eq on-screen-fringe-marker-position 'right)
- (setq ov2 (save-excursion (make-overlay (progn (goto-char pos)
-
(on-screen-beginning-of-line
- (cond ((not inversep)
+1)
- (topp
+2)
- (t
0)))
- (point))
- (1+ (point)))))
- (overlay-put ov2 'before-string (on-screen-fringe-string topp t
inversep)))
- (delq nil (list ov1 ov2))))
-
-(defun on-screen-fringe-string (topp leftp &optional inversep)
- "Return a string suitable for displaying fringe markers."
- (let ((xor (lambda (x y) (if x (not y) y))))
- (propertize (purecopy " ")
- 'display (list (if leftp 'left-fringe 'right-fringe)
- (if (funcall xor topp (not inversep))
- (if leftp 'top-left-angle 'top-right-angle)
- (if leftp 'bottom-left-angle
'bottom-right-angle))
- 'on-screen-fringe))))
-
-(defun on-screen-make-line-overlay (pos)
- "Create an overlay around POS for the line method."
- (save-excursion
- (make-overlay (progn (goto-char pos) (on-screen-beginning-of-line)
(point))
- (progn (goto-char pos) (on-screen-end-of-line) (1+
(point))))))
-
-(defun on-screen-make-narrow-line-overlay (win pos)
- "Create an overlay around POS for the narrow-line method."
- (let ((ov (save-excursion
- (make-overlay (progn (goto-char pos)
(on-screen-beginning-of-line) (point))
- (progn (goto-char pos) (on-screen-end-of-line)
(point))))))
- (overlay-put ov 'face 'on-screen-narrow-line)
- ;; The following is necessary to get a line spanning the entire
- ;; window width, because underlining is only applied to text - a
- ;; problem especially for empty lines. However this hides any
- ;; other highlighting there, e.g. from stripe-buffer or
- ;; hl-line-mode. I think there's nothing I can do about that.
- (overlay-put ov 'after-string (propertize "foo"
- 'face 'on-screen-narrow-line
- 'display `(space :align-to
,(window-width win))
- 'cursor 0))
- ov))
-
-(defun on-screen-get-windows (&optional all-frames)
- "Return a list of all windows.
-With ALL-FRAMES non-nil, include all windows of all frames, else
-only the windows of the selected frame."
- (apply #'nconc
- (mapcar (lambda (frame) (window-list frame))
- (if all-frames (frame-list) (list (selected-frame))))))
-
-(defun on-screen-pre-command ()
- "Remember visible buffer parts in the selected frame."
- ;; This normally goes to `pre-command-hook'.
- (cl-incf on-screen-command-counter)
- (add-hook 'after-change-functions #'on-screen-after-change) ;$$$$ bug#16796
- (condition-case nil
- (mapc (lambda (win) (with-current-buffer (window-buffer win)
- (when (on-screen-enabled-p)
- (on-screen-record-data win (list
(on-screen-window-start win)
- (on-screen-window-end
win))))))
- (on-screen-get-windows))
- ((debug error) nil)))
-
-(defun on-screen-after-scroll (win display-start)
- "DTRT after scrolling.
-This should normally go to `window-scroll-functions'."
- (condition-case nil
- (with-current-buffer (window-buffer win)
- (when (on-screen-enabled-p)
- (let* ((win-data (on-screen-get-data win))
- (area (car win-data))
- (timer (cadr win-data))
- (overlays (cl-caddr win-data))
- (s1 (car area))
- (s2 (cadr area)))
- (when (and
- on-screen-auto-update
- (timerp timer)
- ;; avoid removing highlighting when
`window-scroll-functions' is
- ;; called multiple times in succession (follow-mode does
that)
- (not (eq (car-safe area) (on-screen-window-start win))))
- ;; do what the timer would do, and cancel timer
- (on-screen-remove-highlighting win)
- (cancel-timer timer)
- (on-screen-record-data win area 'finished)
- (setq timer nil))
- (cond
- ((timerp timer)
- (timer-set-time timer (timer-relative-time (current-time)
on-screen-delay)))
- ((or (not area)
- (= display-start s1)
- ;; Deleting a large portion of the buffer caused window
scroll
- (not (<= (point-min) s1 (point-max)))))
- ((and (numberp on-screen-drawing-threshold)
- (< (abs (apply #'count-lines (sort (list display-start s1)
#'<)))
- on-screen-drawing-threshold)))
- (t
- (setq
- overlays
- (let ((method `(,on-screen-highlight-method .
,on-screen-inverse-flag)))
-
- ;; prevent highlighting in certain situations
- ;; note that `window-end' must not be used here!
-
- (when (and s1 s2
- (pos-visible-in-window-p (point-min) win)
- (pos-visible-in-window-p (point-max) win))
- ;; after narrow
- (setq s1 nil s2 nil))
-
- (when (and s1 s2
- (>= s2 (point-max))
- (< s1 (on-screen-window-start win))
- (pos-visible-in-window-p (point-max) win))
- ;;scrolling down near buffer end
- (setq s2 nil))
-
- (cond
- ((equal method '(shadow . nil))
- (if (and s1 s2) (list (make-overlay s1 s2)) ()))
- ((eq (car method) 'shadow)
- (list (and s1 (make-overlay (point-min) s1))
- (and s2 (make-overlay s2 (point-max)))))
- ((eq (car method) 'fringe)
- (append (and s1 (on-screen-make-fringe-overlays s1 nil
(cdr method)))
- (and s2 (on-screen-make-fringe-overlays (1- s2) t
(cdr method)))))
- ((equal method '(line . nil))
- (list (and s1 (on-screen-make-line-overlay s1))
- (and s2 (on-screen-make-line-overlay (1- s2)))))
- ((eq (car method) 'line)
- (list (and s1 (on-screen-make-line-overlay (1- s1)))
- (and s2 (on-screen-make-line-overlay s2))))
- ((eq (car method) 'narrow-line)
- (list (and s1 (on-screen-make-narrow-line-overlay win (1-
s1)))
- (and s2 (on-screen-make-narrow-line-overlay win (1-
s2)))))))
- overlays (delq nil overlays))
- (dolist (ov overlays)
- (overlay-put ov 'window win) ; display only in selected window
- (overlay-put ov 'priority on-screen-overlay-priority))
- (when (memq on-screen-highlight-method '(shadow line))
- (dolist (ov overlays)
- (overlay-put ov 'face (on-screen-get-shadow-face win))))
- (on-screen-record-data
- win nil
- (run-at-time (time-add (current-time) (seconds-to-time
on-screen-delay)) nil
- (lambda (win)
- (condition-case nil
- (progn
- (when (window-live-p win)
- (with-current-buffer (window-buffer win)
- (on-screen-remove-highlighting win)
- (on-screen-record-data
- win (list (on-screen-window-start win)
- (on-screen-window-end win))
- 'finished)))
- (on-screen-cleanup-data))
- ((debug error) nil)))
- win)
- overlays))))))
- ((debug error) nil)))
-
-(defun on-screen-remove-highlighting (win)
- "Delete all on-screen overlays in window WIN.
-This has to be done for a previously buffer if the window-buffer
-had changed."
- (let* ((entry (assoc win on-screen-data))
- (data (cdr entry))
- (buffer (car data)))
- (when (buffer-live-p buffer)
- (with-current-buffer buffer
- (let* ((data (cdr data))
- (timer (cadr data))
- (overlays (cl-caddr data)))
- (dolist (ov overlays) (delete-overlay ov))
- (when (timerp timer) (cancel-timer timer))))
- (setq on-screen-data (delq entry on-screen-data)))))
-
-(defun on-screen-after-change (&rest _)
- "Reset highligting for current buffer after it was changed.
-This has to be done for all its windows. Goes to
-`after-change-functions'."
- (when (or on-screen-remove-when-edit
- (= on-screen-last-change on-screen-command-counter))
- (let ((buf (current-buffer)))
- (when (on-screen-enabled-p buf)
- (dolist (win (on-screen-get-windows t))
- (when (eq (window-buffer win) buf)
- (on-screen-remove-highlighting win))))))
- (setq on-screen-last-change on-screen-command-counter))
-
-(defun on-screen-after-wconf-change ()
- "Clean up after the window configuration has changed.
-I.e., for all windows of the selected frame, remove all
-highlightings and clear all associated data."
- (let ((wins (on-screen-get-windows)))
- (dolist (win wins)
- (on-screen-remove-highlighting win))))
-
-(defun on-screen-enabled-p (&optional buffer)
- "Return non-nil if on-screen is enabled in BUFFER."
- (with-current-buffer (or buffer (current-buffer))
- (and
- (or on-screen-global-mode on-screen-mode)
- (cond
- ((not on-screen-inhibit-highlighting) t)
- ((functionp on-screen-inhibit-highlighting)
- (not (funcall on-screen-inhibit-highlighting)))
- (t nil)))))
-
-(defun on-screen-initialize ()
- "Prepare for using on-screen."
- (add-hook 'pre-command-hook #'on-screen-pre-command)
- (add-hook 'window-scroll-functions #'on-screen-after-scroll)
- (add-hook 'after-change-functions #'on-screen-after-change)
- (add-hook 'window-configuration-change-hook #'on-screen-after-wconf-change)
- (setq on-screen-initialized-p t))
-
-(defun on-screen-unload-function ()
- "Function to run when unloading on-screen."
- (remove-hook 'pre-command-hook #'on-screen-pre-command)
- (remove-hook 'window-scroll-functions #'on-screen-after-scroll)
- (remove-hook 'after-change-functions #'on-screen-after-change)
- (remove-hook 'window-configuration-change-hook
#'on-screen-after-wconf-change)
- nil)
-
-
-(provide 'on-screen)
-
-;;; on-screen.el ends here
diff --git a/packages/vcl-mode/vcl-mode.el b/packages/vcl-mode/vcl-mode.el
deleted file mode 100644
index ed50877..0000000
--- a/packages/vcl-mode/vcl-mode.el
+++ /dev/null
@@ -1,423 +0,0 @@
-;;; vcl-mode.el --- Major mode for Varnish Configuration Language -*-
lexical-binding:t -*-
-
-;; Author: Sergey Poznyakoff <gray@gnu.org.ua>
-;; Version: 1.1
-;; Keywords: Varnish, VCL
-
-;; Copyright (C) 2015-2018 Free Software Foundation, Inc.
-
-;; 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:
-
-;; Emacs support for Varnish's configuration language:
-;; https://varnish-cache.org/docs/trunk/users-guide/vcl.html
-;; This version of vcl-mode supports VCL-4.0.
-
-;; The features provided are auto-indentation (based on CC-mode's
-;; engine), keyword highlighting, and matching of {"..."} multi-line
-;; string delimiters.
-
-;; If you need support for VCL-2.0, you might have more luck with the older
-;; package: https://github.com/ssm/elisp/blob/master/vcl-mode.el
-
-;;; Code:
-
-(require 'cc-mode)
-(require 'cc-langs)
-
-(defvar vcl-mode-map
- (let ((map (make-sparse-keymap)))
- (set-keymap-parent map c-mode-base-map)
- (define-key map "\C-c%" 'vcl-match-paren)
- map)
- "Keymap used in vcl-mode buffers.")
-
-(defvar vcl-mode-syntax-table
- (let ((st (make-syntax-table)))
- (modify-syntax-entry ?\n "> b" st)
- ;; Use comment style `b' to match the style used for \n!
- (modify-syntax-entry ?\# "< b" st)
- (modify-syntax-entry ?/ ". 124b" st)
- (modify-syntax-entry ?* ". 23" st)
- (modify-syntax-entry ?+ "." st)
- (modify-syntax-entry ?- "." st)
- (modify-syntax-entry ?~ "." st)
- (modify-syntax-entry ?= "." st)
- (modify-syntax-entry ?% "." st)
- (modify-syntax-entry ?< "." st)
- (modify-syntax-entry ?> "." st)
- (modify-syntax-entry ?& "." st)
- (modify-syntax-entry ?| "." st)
- (modify-syntax-entry ?_ "_" st)
- (modify-syntax-entry ?\' "." st)
- (modify-syntax-entry ?\" "\"" st)
- st)
- "Syntax table in use in VCL Mode buffers.")
-
-(define-abbrev-table 'vcl-mode-abbrev-table
- '(("else" "else" c-electric-continued-statement :system t))
- "Abbreviation table used in vcl-mode buffers.")
-
-;; Font locking
-(defconst vcl-font-lock-keywords-1
- (eval-when-compile
- (list
- ;; Version declaration
- '("^[ \t]*\\(vcl\\)\\>[ \t]*\\([[:digit:]]+\\.[[:digit:]]+\\)"
- (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
- ;; Built-ins
- (cons
- (concat "\\<"
- (regexp-opt
- '("vcl_init"
- "vcl_recv"
- "vcl_pipe"
- "vcl_pass"
- "vcl_hash"
- "vcl_hit"
- "vcl_miss"
- "vcl_fetch"
- "vcl_deliver"
- "vcl_error"
- "vcl_fini"
- "vcl_synth"
- "vcl_backend_fetch"
- "vcl_backend_response"
- "vcl_backend_error") t)
- "\\>")
- 'font-lock-builtin-face)
- ;; Keywords
- (cons
- (concat "\\<"
- (regexp-opt
- '("sub"
- "import"
- "include"
- "backend"))
- "\\>")
- 'font-lock-keyword-face)
- ))
- "Subdued level highlighting for VCL buffers.")
-
-(defconst vcl-font-lock-keywords-2
- (append vcl-font-lock-keywords-1
- (eval-when-compile
- (list
- ;; Keywords
- (cons
- (concat "\\<"
- (regexp-opt
- '("acl"
- "if"
- "else"
- "return"
- "call"
- "set"
- "remove"
- "unset"
- "director"
- "probe"))
- "\\>")
- 'font-lock-keyword-face)
- ;; Return values
- (cons
- (concat "\\<"
- (regexp-opt
- '("error"
- "fetch"
- "hash"
- "hit_for_pass"
- "lookup"
- "ok"
- "pass"
- "pipe"
- "deliver"
- "restart"
- "true"
- "false"))
- "\\>")
- 'font-lock-constant-face)
- ;; Functions
- (cons
- (concat "\\<"
- (regexp-opt
- '("ban"
- "call"
- "hash_data"
- "new"
- "synth"
- "synthetic"
- "regsub"
- "regsuball"))
- "\\>")
- 'font-lock-function-name-face)
-
- ;; Objects and variables
- ;; See
https://www.varnish-cache.org/docs/4.0/reference/vcl.html#variables
- (list (concat "\\<"
- (regexp-opt
- '("req"
- "resp"
- "bereq"
- "beresp"
- "obj")
- t)
- "\\.\\(http\\)\\(\\.\\([a-zA-Z_-][a-zA-Z_0-9-]*\\)\\)?")
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face)
- '(4 font-lock-string-face nil t))
- (list (concat "\\<\\(bereq\\)\\."
- (regexp-opt
- '("backend"
- "between_bytes_timeout"
- "connect_timeout"
- "first_byte_timeout"
- "method"
- "proto"
- "retries"
- "uncacheable"
- "url"
- "xid")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(beresp\\)\\.\\(backend\\)\\."
- (regexp-opt
- '("name"
- "ip")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face)
- '(3 font-lock-builtin-face))
- (list (concat "\\<\\(beresp\\)\\."
- (regexp-opt
- '("do_esi"
- "do_gunzip"
- "do_gzip"
- "do_stream"
- "grace"
- "keep"
- "proto"
- "reason"
- "status"
- "storage_hint"
- "ttl"
- "uncacheable")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(client\\)\\."
- (regexp-opt
- '("identity"
- "ip")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(obj\\)\\."
- (regexp-opt
- '("grace"
- "hits"
- "keep"
- "proto"
- "reason"
- "status"
- "ttl"
- "uncacheable")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(req\\)\\."
- (regexp-opt
- '("backend_hint"
- "can_gzip"
- "esi"
- "esi_level"
- "hash_always_miss"
- "hash_ignore_busy"
- "method"
- "proto"
- "restarts"
- "ttl"
- "url"
- "xid")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(resp\\)\\."
- (regexp-opt
- '("proto"
- "reason"
- "status")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(server\\)\\."
- (regexp-opt
- '("hostname"
- "identity"
- "ip")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-builtin-face))
- (list (concat "\\<\\(storage\\)\\.\\(\\sw+\\)\\."
- (regexp-opt
- '("free_space"
- "used_space"
- "happy")
- t))
- '(1 font-lock-builtin-face)
- '(2 font-lock-variahle-name-face)
- '(3 font-lock-builtin-face))
-
- (cons
- (concat "\\<"
- (regexp-opt
- '("req"
- "resp"
- "bereq"
- "beresp"
- "client"
- "server"
- "obj"
- "now"))
- "\\>")
- 'font-lock-builtin-face)
-
- ;; Function calls
- '("\\<\\(\\(\\sw+\\)\\.\\)*\\(\\sw+\\)[ \t]*("
- (2 font-lock-variable-name-face nil t)
- (3 font-lock-function-name-face))
-
- ;; Constants
- '("\\<\\([[:digit:]]+\\(\\.[[:digit:]]+\\)?\\)[
\t]*\\(ms\\|[smhdwy]\\)?\\>"
- (1 font-lock-constant-face) (3 font-lock-builtin-face nil t)))))
- "Medium level highlighting for VCL buffers.")
-
-(defconst vcl-font-lock-keywords-3
- (append vcl-font-lock-keywords-2
- (eval-when-compile
- (list
- ;; User function names.
- '("^[ \t]*\\(sub\\)\\>[ \t]*\\(\\sw+\\)?"
- (1 font-lock-keyword-face) (2 font-lock-function-name-face nil
t)))))
- "Gaudy level highlighting for VCL buffers.")
-
-(defvar vcl-font-lock-keywords vcl-font-lock-keywords-3)
-
-(put 'vcl-mode 'c-mode-prefix "vcl-")
-
-(defconst vcl-syntax-propertize-function
- (syntax-propertize-rules
- ("\\({\\)\""
- (1 (when (null (nth 8 (save-excursion
- (syntax-ppss (match-beginning 0)))))
- (string-to-syntax "|"))))
- ("\"\\(}\\)"
- (1 (when (eq t (nth 3 (save-excursion
- (syntax-ppss (match-beginning 0)))))
- (string-to-syntax "|"))))))
-
-(defun vcl-match-paren (&optional arg)
- ;; FIXME: Assuming syntax-propertize works correctly, forward-sexp and
- ;; backward-sexp should do the trick!
- "If point is on a parenthesis (including VCL multi-line string delimiter),
-find the matching one and move point to it.
-With ARG, do it that many times."
- (interactive "p")
- (let ((n (or arg 1))
- (matcher (cond
- ((looking-at "\\s(")
- (cons
- (let ((s (match-string 0)))
- (lambda ()
- (search-forward s)
- (backward-char)))
- (lambda ()
- (forward-list)
- (backward-char))))
- ((looking-at "\\s)")
- (cons
- (let ((s (match-string 0)))
- (lambda ()
- (search-backward s)))
- (lambda ()
- (forward-char)
- (backward-list))))
- ((or (looking-at "{\"")
- (save-excursion
- (backward-char)
- (looking-at "{\"")))
- (cons
- (lambda ()
- (search-forward "{\""))
- (lambda ()
- (search-forward-regexp "\"}")
- (backward-char))))
- ((or (looking-at "\"}")
- (save-excursion
- (backward-char)
- (looking-at "\"}")))
- (cons
- (lambda ()
- (search-backward "\"}"))
- (lambda ()
- (search-backward-regexp "{\"")))))))
- (if (not matcher)
- (message "Point not at parenthesis")
- (condition-case err
- (let ((fx (car matcher))
- (fn (cdr matcher)))
- (catch 'stop
- (while t
- (funcall fn)
- (setq n (1- n))
- (if (= n 0)
- (throw 'stop t)
- (condition-case nil
- (funcall fx)
- (search-failed
- (message "Not enough groups to satisfy the request")
- (throw 'stop t)))))))
-
- (scan-error (goto-char (nth 2 err))
- (message "%s" (nth 1 err)))
- (search-failed (message "Unbalanced %s" (cdr err)))))))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist (cons (purecopy "\\.vcl\\'") 'vcl-mode))
-
-;;;###autoload
-(define-derived-mode vcl-mode prog-mode "VCL"
- "Major mode for editing Varnish Configuration Language code.
-
-Key bindings:
-\\{vcl-mode-map}"
- :abbrev-table vcl-mode-abbrev-table
- (set (make-local-variable 'syntax-propertize-function)
- vcl-syntax-propertize-function)
- (set (make-local-variable 'parse-sexp-lookup-properties) t)
-
- (c-initialize-cc-mode t)
- (c-lang-setvar comment-start "# ")
- (setq c-opt-cpp-prefix nil)
- (setq abbrev-mode t)
- (c-init-language-vars vcl-mode)
- (c-common-init 'vcl-mode)
-
- (run-mode-hooks 'c-mode-common-hook 'vcl-mode-hook)
- (c-update-modeline))
-
-(provide 'vcl-mode)
-;;; vcl-mode.el ends here
diff --git a/packages/web-server/.elpaignore b/packages/web-server/.elpaignore
deleted file mode 100644
index c9833f4..0000000
--- a/packages/web-server/.elpaignore
+++ /dev/null
@@ -1,14 +0,0 @@
-COPYING
-examples
-Makefile
-NOTES
-README
-stuff
-web-server-test.el
-
-## Ignorable documentation files
-doc/dir
-doc/doclicense.texi
-doc/gpl.texi
-doc/Makefile
-doc/web-server.texi
diff --git a/packages/web-server/.github/workflows/test.yml
b/packages/web-server/.github/workflows/test.yml
deleted file mode 100644
index 0b2fe18..0000000
--- a/packages/web-server/.github/workflows/test.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: CI
-
-on: [push, pull_request]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- emacs_version:
- - 24.3
- - 25.3
- - 26.3
- steps:
- - uses: purcell/setup-emacs@master
- with:
- version: ${{ matrix.emacs_version }}
- - uses: actions/checkout@v1
- - name: Run tests
- run: make src check
diff --git a/packages/web-server/.gitignore b/packages/web-server/.gitignore
deleted file mode 100644
index 09b6c67..0000000
--- a/packages/web-server/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.elc
-stuff
-benchmark
-web-server-*
diff --git a/packages/web-server/COPYING b/packages/web-server/COPYING
deleted file mode 100644
index 94a9ed0..0000000
--- a/packages/web-server/COPYING
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 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.
-
- 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 <http://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
-<http://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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/web-server/Makefile b/packages/web-server/Makefile
deleted file mode 100644
index 33c3e4a..0000000
--- a/packages/web-server/Makefile
+++ /dev/null
@@ -1,47 +0,0 @@
-EMACS := emacs
-BATCH=$(EMACS) --batch --execute '(add-to-list (quote load-path) "$(shell
pwd)")'
-
-SRC=$(wildcard *.el)
-ELC=$(SRC:.el=.elc)
-
-.PHONY: src doc check clean
-all: src doc
-
-src: $(SRC)
- $(BATCH) -f batch-byte-compile $^
-
-doc:
- $(MAKE) -C doc/
-
-doc/web-server.info:
- $(MAKE) -C doc/ web-server.info
-
-doc/dir:
- $(MAKE) -C doc/ dir
-
-check: $(SRC)
- $(BATCH) -l cl -l ert -l web-server-test -f ert-run-tests-batch-and-exit
-
-clean:
- rm -rf $(ELC) $(PACKAGE) $(PACKAGE).tar
- $(MAKE) -C doc/ $(MAKECMDGOALS)
-
-# Packaging
-PARSE=grep "$(1):" web-server.el|sed 's/^.*$(1): //'
-NAME=web-server
-VERSION=$(shell $(call PARSE,Version))
-DOC=$(shell head -1 web-server.el|sed 's/^.*--- //')
-REQ=$(shell $(call PARSE,Package-Requires))
-DEFPKG=(define-package "$(NAME)" "$(VERSION)"\n "$(DOC)"\n (quote $(REQ)))
-PACKAGE=$(NAME)-$(VERSION)
-
-$(PACKAGE): $(filter-out web-server-test.el, $(SRC)) doc/web-server.info
doc/dir
- mkdir -p $(PACKAGE)
- cp $^ $(PACKAGE)
- sed -n '/;;; Commentary:/,/;;; Code:/p' web-server.el|tail -n+3|head
-n-2|cut -c4- >$(PACKAGE)/README
- echo -e '$(DEFPKG)' > $(PACKAGE)/$(NAME)-pkg.el
-
-$(PACKAGE).tar: $(PACKAGE)
- tar cf $@ $<
-
-package: $(PACKAGE).tar
diff --git a/packages/web-server/NOTES b/packages/web-server/NOTES
deleted file mode 100644
index 40ecdab..0000000
--- a/packages/web-server/NOTES
+++ /dev/null
@@ -1,325 +0,0 @@
- -*- org -*-
-#+Title: Notes and Tasks
-#+HTML_HEAD: <style>pre{background:#232323; color:#E6E1DC;} table{margin:auto;
width:50%;} @media(min-width:800px){div#content{max-width:800px; padding:2em;
margin:auto;}}</style>
-#+Options: ^:{}
-
-* Notes
-* Tasks [19/22]
-** DONE pass all tests on Windows [2/2]
-Currently two failing tests.
-
-- [X] ws/simple-post returns "you said nil" instead of "you said foo"
-
-- [X] ws/in-directory-p is failing because it assumes "/tmp" which
- doesn't work on windows
-
-** DONE Content and Transfer encodings
-- Content and Transfer encoding values
- http://www.iana.org/assignments/http-parameters/http-parameters.xhtml
-- http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6
-- http://en.wikipedia.org/wiki/Chunked_transfer_encoding
-- http://tools.ietf.org/html/rfc1945#section-7.2
-- http://tools.ietf.org/rfc/rfc1945.txt
-
-Some issue as to whether compression is better done as a "Content
-Encoding" which actually changes the content, or as a "Transfer
-Encoding", which doesn't change the content, just the messages.
-
-The latter seems preferable, but possibly less widely supported. See
-http://stackoverflow.com/questions/11641923/transfer-encoding-gzip-vs-content-encoding-gzip.
-
-- content-coding
- - compress :: Unix =compress= program (rfc2616)
- - deflate :: =zlib= (see http://www.iana.org/go/rfc1950) format with
- =defalte= compression (rfc2616)
- - exi :: W3c efficient XML (see http://www.w3.org/TR/exi/)
- - gzip :: GNU zip (rfc2616)
- - identity :: does nothing
- - pack200-zip :: specific to Java archives (see
- http://www.jcp.org/en/jsr/detail?id=200)
-- transfer-coding
- - chunked :: (rfc2616)
- - compress :: same as above
- - deflate :: same as above
- - gzip :: same as above
-- tail-header
- - Content-MD5 :: Base64 encoded binary MD5 sum of content
-
-Maybe we can set the coding system of the process with
-=define-coding-system=, specifically using the =:pre-write-conversion=
-flag to e.g., gzip or chunkify the contents.
-
-** DONE web sockets
-- http://en.wikipedia.org/wiki/WebSocket
-- http://tools.ietf.org/html/rfc6455
-
-** more examples [4/4]
-*** DONE Org-mode agenda
-Already exists as part of org-ehtml.
-file:examples/011-org-agenda.el
-
-*** DONE display the current buffer
-Idea stolen from elnode.
-file:examples/010-current-buffer.el
-
-*** DONE browse the BBDB
-file:examples/012-search-bbdb.el
-*** DONE org-mode export server
-1. upload a file
-2. supply an export type
-3. return the exported version of the file
-
-** DONE handle large files
-When large files arrive quickly, the filter functions are called while
-they are still running on the previous chunk, this leads to nasty race
-conditions for the state of the request object.
-
-Either introduce some check to wait on new input if input is currently
-being parsed, or wait until all input has arrived before doing any
-parsing.
-
-Now using an =active= field on request objects to avoid race
-conditions when new header text is received while the parsing function
-is still active.
-
-** TODO robustness to bad requests [0/2]
-Low priority, just [[*running%20behind%20a%20proxy][run behind a proxy]].
-
-*** TODO request timeout
-*** TODO maximum request size
-** DONE authentication [2/2]
- - State "HOLD" from "TODO" [2014-02-10 Mon 19:06] \\
- digest may not be worth it, just run Basic over HTTPS
-*** DONE Basic
-http://en.wikipedia.org/wiki/Basic_access_authentication
-
-*** CANCELED Digest
-http://en.wikipedia.org/wiki/Digest_access_authentication
-
-If this is implemented, it would be good to implement some safeguards
-against common attacks.
-
-#+begin_quote
-- Server nonce is allowed to contain timestamps. Therefore the server
- may inspect nonce attributes submitted by clients, to prevent replay
- attacks.
-- Server is also allowed to maintain a list of recently issued or used
- server nonce values to prevent reuse.
-#+end_quote
-
-** incremental handler calls
-not sure if the extra performance is worth the added complexity
-
-Before the header is fully parsed, call any potential handlers.
-Include a field in the request object to indicate that the request
-isn't finished being received so handlers can return and wait to be
-called again.
-
-Also, put a catch in the filter function and allow the =headers=
-function on the request object to throw to said catch aborting the
-handler and waiting for the rest of the input.
-
-** DONE Documentation [6/6]
-- [X] introduction
-- [X] handlers
-- [X] request headers
-- [X] usage examples
-- [X] list of functions
-
-Notes to touch upon
-- [X] how to set content type
-
-** DONE Handle POST requests
-1. read standard for POST data
-2. parse multi-line headers with boundaries
-
-For now keep this all incremental and in ws-filter.
-
-** DONE Makefile
-- byte-compile
-- package
-- test
-- benchmark
-** DONE catch errors and return an error code
-include an easy error handler like the 404 handler
-
-** DONE better parsing of multipart form blocks
-parse more than just the content-type headers.
-
-** DONE non-multipart form data
-e.g., parameter strings
-
-** DONE some more convenience functionality [6/6]
-- [X] strip and parse URL query string
-- [X] parse urlencoded post data
-- [X] think about defaulting to (name . content) for form elements
-- [X] maybe don't require a non-nil return to cancel the connection,
- instead only keep open if =:keep-alive= is returned
-- [X] function to send a file (with mime handling)
-- [X] send a 404 with some default text
-
-** CANCELED Lazy header processing
- - State "CANCELED" from "TODO" [2013-12-25 Wed 12:21] \\
- premature optimization
-Use lazy sequence functions for header a-list to avoid parsing all
-headers. For regexp matchers should stop when matched header is
-encountered (often the first one when :GET), For function matchers
-provide lazy version of assoc.
-
-Also, there is the issue of how a lazy request for more parameters
-should act before all incoming text has been received. Emacs does not
-provide a light-weight mechanism for a function to wait for incoming
-process text without something gross like the =(sit-for 0.1)= used in
-the test suite.
-
-** use gnutls for https
-low priority -- just [[*running%20behind%20an%20https%20proxy][run behind an
https proxy]].
-
-This will be a pain, and will require expanding [[info:emacs-gnutls]] to
-add support for starting server processes, currently only client
-processes are supported.
-** screen cast?
-- http://en.wikipedia.org/wiki/XVidCap
-- https://aur.archlinux.org/packages/xvidcap/
-
-* Tutorials
-The following tutorials walk through common usage scenarios including
-installing the Emacs web-server and running it behind a proxy.
-Install the Emacs web-server and run =(info "web-server")= to browse
-the full manual within Emacs, or view the HTML version at
-[[http://eschulte.github.io/emacs-web-server/][emacs-web-server]].
-
-** Installation and running a server
-Most easily installable through the GNU ELPA, run =M-x
-package-list-packages= select =web-server= and install. Alternately,
-install from the git repository at
-https://github.com/eschulte/emacs-web-server and update your the load.
-
-1. Ensure that you have Emacs version 24 or greater installed.
-
- #+begin_src sh :results scalar
- emacs --version
- #+end_src
-
- : GNU Emacs 24.3.1
- : Copyright (C) 2013 Free Software Foundation, Inc.
- : GNU Emacs comes with ABSOLUTELY NO WARRANTY.
- : You may redistribute copies of Emacs
- : under the terms of the GNU General Public License.
- : For more information about these matters, see the file named COPYING.
-
-2. Download and unpack the zip archive of the Emacs web-server code
- from
[[https://github.com/eschulte/emacs-web-server/archive/master.zip][emacs-web-server-master.zip]]
or clone the source code
- repository with [[http://git-scm.com/][git]].
-
- #+begin_src sh
- git clone https://github.com/eschulte/emacs-web-server.git
- #+end_src
-
-3. Move into the root of the =emacs-web-server/= directory and
- optionally run =make= to compile the web-server code, and run =make
- check= to test your web-server install.
-
- #+begin_src sh
- make
- make check
- #+end_src
-
-4. From the root of the =emacs-web-server/= directory, start an
- instance of Emacs with web-server loaded.
-
- #+begin_src sh
- emacs -Q -L . -l web-server
- #+end_src
-
- Alternately, from an already running Emacs instance, add this
- directory to the load path and load the web server with the
- following.
-
- #+begin_src emacs-lisp
- (add-to-list 'load-path "path/to/emacs-web-server")
- (require 'web-server)
- #+end_src
-
-5. Evaluate the following code in =*scratch*= buffer of this Emacs
- instance.
-
- #+begin_src emacs-lisp
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (process-send-string process "hello world")))
- 9000)
- #+end_src
-
-6. Browse to http://localhost:9000 to see that the web-server is
- running.
-
-7. Read the web-server
[[http://eschulte.github.io/emacs-web-server/index.html#Top][manual]] and work
through other
[[http://eschulte.github.io/emacs-web-server/Usage-Examples.html#Usage-Examples][Usage
Examples]].
-
-** Running behind a proxy
-Public-facing instance of the Emacs web-server should be run behind a
-more established web server such as [[http://httpd.apache.org/][Apache]] or
[[http://wiki.nginx.org][Nginx]] to provide
-additional robustness and security.
-
-The following example Apache configuration may be used to have a
-public facing Apache server listening on port 80 proxy requests to a
-local web-server instance running on port 8888 of the same machine.
-
-#+begin_src conf
- <VirtualHost *:80>
- ServerName yourserver.com
-
- ProxyPass / http://localhost:8888/
- </VirtualHost>
-#+end_src
-
-A similar Nginx configuration is available at
-http://wiki.nginx.org/LoadBalanceExample.
-
-** Running behind an https proxy
-The following example configurations will cause Apache or Nginx to act
-as an HTTPS proxy for an instance of the Emacs web server running on
-the same machine. With this setup Apache speaks HTTPS to the outside
-world, and communicates with the Emacs web server using HTTP. This
-allows use of HTTPS even though the Emacs web server does not
-implement HTTPS itself. This setup is recommended for any setup, but
-should be considered *required* for sites using BASIC HTTP
-Authentication.
-
-*** Apache
-This requires that Apache has =mod_proxy= and =mod_ssl= enabled, and
-that the certificate and key files required for SSL are present. This
-these requirements satisfied, and assuming the Emacs web server is
-listening on port 8888 and is running on the same machine as the
-Apache web server an Apache virtual host configuration such as the
-following.
-
-#+begin_src conf
- <VirtualHost *:443>
- ProxyPreserveHost On
- ServerName yourserver.com
-
- SSLEngine On
- SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
- SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
-
- ProxyPass / http://localhost:8888/
- ProxyPassReverse / http://localhost:8888/
- </VirtualHost>
-#+end_src
-
-*** Nginx
-See the following for instructions configuring Nginx as an HTTPS
-proxy.
-- http://wiki.nginx.org/SSL-Offloader#sslproxy.conf
-- http://www.cyberciti.biz/faq/howto-linux-unix-setup-nginx-ssl-proxy/
-
-** COMMENT documentation for running in a chroot jail
-See https://wiki.archlinux.org/index.php/nginx#Installation_in_a_chroot.
-
-* Bugs [1/1]
-** DONE Sometimes servers don't stop cleanly
-- specifically servers with active client process
-- maybe also implement a =ws-stop-all= function
diff --git a/packages/web-server/README b/packages/web-server/README
deleted file mode 100644
index a888063..0000000
--- a/packages/web-server/README
+++ /dev/null
@@ -1,43 +0,0 @@
- Emacs Web Server
-
-DESCRIPTION
- A web server in Emacs running handlers written in Emacs Lisp.
-
-REQUIREMENTS
- Emacs 24.3 or later.
-
-STATUS
- Supports HTTP GET and POST requests including URL-encoded
- parameters, multipart/form data and file uploads. Supports web
- sockets. Reasonably performant, faster than Elnode [1]. This is
- a new project without much extended use so there are likely bugs
- and potentially security issues. That said it consists of little
- more than HTTP header parsing logic perched atop Emacs' existing
- network process primitives, so it should be fairly robust.
-
- [1] http://eschulte.github.io/emacs-web-server/benchmark/
-
-USAGE
- See the examples/ directory in this repository for examples
- demonstrating usage. The Emacs web-server is also used to run a
- paste server [2], serve editable Org-mode pages [3] and serve
- files for Cask [4].
-
- [2] https://github.com/eschulte/el-sprunge
- [3] https://github.com/eschulte/org-ehtml
- [4] https://github.com/cask/cask
-
- Available from the GNU ELPA [5]. The tutorials page [6] walks
- through usage scenarios including installing the Emacs web-server
- and running it behind a proxy.
-
- [5] http://elpa.gnu.org/
- [6] http://eschulte.github.io/emacs-web-server/tutorials/
-
- Run `make check' to run the included test suite.
-
-DOCUMENTATION
- Run `make doc' to build the texinfo documentation, also available
- online [6].
-
- [6] http://eschulte.github.io/emacs-web-server
diff --git a/packages/web-server/doc/.gitignore
b/packages/web-server/doc/.gitignore
deleted file mode 100644
index 565866c..0000000
--- a/packages/web-server/doc/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-dir
-web-server/
-*.info
-*.html
-*.svg
diff --git a/packages/web-server/doc/Makefile b/packages/web-server/doc/Makefile
deleted file mode 100644
index 3be9207..0000000
--- a/packages/web-server/doc/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-all: web-server web-server.info dir
-
-web-server: web-server.texi
- makeinfo --html $<
-
-web-server.info: web-server.texi
- makeinfo $<
-
-dir: web-server.info
- install-info --info-dir=./ $<
-
-clean:
- rm -f *.info;
- rm -rf web-server/
diff --git a/packages/web-server/doc/doclicense.texi
b/packages/web-server/doc/doclicense.texi
deleted file mode 100644
index 51342e9..0000000
--- a/packages/web-server/doc/doclicense.texi
+++ /dev/null
@@ -1,508 +0,0 @@
-@c -*-texinfo-*-
-@c The GNU Free Documentation License.
-@center Version 1.3, 3 November 2008
-
-@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
-
-@display
-Copyright @copyright{} 2000, 2001, 2002, 2007, 2008, 2009 Free Software
Foundation, Inc.
-@uref{http://fsf.org/}
-
-Everyone is permitted to copy and distribute verbatim copies
-of this license document, but changing it is not allowed.
-@end display
-
-@enumerate 0
-@item
-PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document @dfn{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.
-
-@item
-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
-@sc{ascii} without markup, Texinfo input format, La@TeX{} input
-format, @acronym{SGML} or @acronym{XML} using a publicly available
-@acronym{DTD}, and standard-conforming simple @acronym{HTML},
-PostScript or @acronym{PDF} designed for human modification. Examples
-of transparent image formats include @acronym{PNG}, @acronym{XCF} and
-@acronym{JPG}. Opaque formats include proprietary formats that can be
-read and edited only by proprietary word processors, @acronym{SGML} or
-@acronym{XML} for which the @acronym{DTD} and/or processing tools are
-not generally available, and the machine-generated @acronym{HTML},
-PostScript or @acronym{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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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:
-
-@enumerate A
-@item
-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.
-
-@item
-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.
-
-@item
-State on the Title page the name of the publisher of the
-Modified Version, as the publisher.
-
-@item
-Preserve all the copyright notices of the Document.
-
-@item
-Add an appropriate copyright notice for your modifications
-adjacent to the other copyright notices.
-
-@item
-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.
-
-@item
-Preserve in that license notice the full lists of Invariant Sections
-and required Cover Texts given in the Document's license notice.
-
-@item
-Include an unaltered copy of this License.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-Delete any section Entitled ``Endorsements''. Such a section
-may not be included in the Modified Version.
-
-@item
-Do not retitle any existing section to be Entitled ``Endorsements'' or
-to conflict in title with any Invariant Section.
-
-@item
-Preserve any Warranty Disclaimers.
-@end enumerate
-
-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.
-
-@item
-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.''
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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
-@uref{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.
-
-@item
-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.
-
-@end enumerate
-
-@page
-@heading 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:
-
-@smallexample
-@group
- Copyright (C) @var{year} @var{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''.
-@end group
-@end smallexample
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the ``with@dots{}Texts.'' line with this:
-
-@smallexample
-@group
- with the Invariant Sections being @var{list their titles}, with
- the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
- being @var{list}.
-@end group
-@end smallexample
-
-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.
-
-
-@c Local Variables:
-@c ispell-local-pdict: "ispell-dict"
-@c End:
-
diff --git a/packages/web-server/doc/gpl.texi b/packages/web-server/doc/gpl.texi
deleted file mode 100644
index 1908d1f..0000000
--- a/packages/web-server/doc/gpl.texi
+++ /dev/null
@@ -1,717 +0,0 @@
-@c The GNU General Public License.
-@center Version 3, 29 June 2007
-
-@c This file is intended to be included within another document,
-@c hence no sectioning command or @node.
-
-@display
-Copyright @copyright{} 2007 Free Software Foundation, Inc.
@url{http://fsf.org/}
-
-Everyone is permitted to copy and distribute verbatim copies of this
-license document, but changing it is not allowed.
-@end display
-
-@heading 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.
-
-@heading TERMS AND CONDITIONS
-
-@enumerate 0
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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:
-
-@enumerate a
-@item
-The work must carry prominent notices stating that you modified it,
-and giving a relevant date.
-
-@item
-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''.
-
-@item
-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.
-
-@item
-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.
-@end enumerate
-
-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.
-
-@item 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:
-
-@enumerate a
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@item
-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.
-
-@end enumerate
-
-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.
-
-@item 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:
-
-@enumerate a
-@item
-Disclaiming warranty or limiting liability differently from the terms
-of sections 15 and 16 of this License; or
-
-@item
-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
-
-@item
-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
-
-@item
-Limiting the use for publicity purposes of names of licensors or
-authors of the material; or
-
-@item
-Declining to grant rights under trademark law for use of some trade
-names, trademarks, or service marks; or
-
-@item
-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.
-@end enumerate
-
-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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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.
-
-@item 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 enumerate
-
-@heading END OF TERMS AND CONDITIONS
-
-@heading 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.
-
-@smallexample
-@var{one line to give the program's name and a brief idea of what it does.}
-Copyright (C) @var{year} @var{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 @url{http://www.gnu.org/licenses/}.
-@end smallexample
-
-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:
-
-@smallexample
-@var{program} Copyright (C) @var{year} @var{name of author}
-This program comes with ABSOLUTELY NO WARRANTY; for details type @samp{show w}.
-This is free software, and you are welcome to redistribute it
-under certain conditions; type @samp{show c} for details.
-@end smallexample
-
-The hypothetical commands @samp{show w} and @samp{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
-@url{http://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 @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
diff --git a/packages/web-server/doc/web-server.texi
b/packages/web-server/doc/web-server.texi
deleted file mode 100644
index f4f7392..0000000
--- a/packages/web-server/doc/web-server.texi
+++ /dev/null
@@ -1,601 +0,0 @@
-\input texinfo
-@c @setfilename emacs-web-server.info
-@documentencoding utf-8
-@settitle Emacs Web Server (web-server) User Manual
-
-@copying
-This file documents the Emacs Web Server (web-server)
-
-Copyright (C) 2013 Eric Schulte <schulte.eric@@gmail.com>
-
-@quotation
-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 Section being ``GNU GENERAL PUBLIC LICENSE,''
-A copy of the license is included in the section entitled
-``GNU Free Documentation License.''
-@end quotation
-@end copying
-
-@dircategory Emacs
-@direntry
-* Web Server: (web-server). Web Server for Emacs.
-@end direntry
-
-@titlepage
-@title Emacs Web Server (web-server) User Manual
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@c Output the table of the contents at the beginning.
-@contents
-
-@ifnottex
-@node Top, Introduction, (dir), (dir)
-@top Emacs Web Server User Manual
-
-@insertcopying
-@end ifnottex
-
-@menu
-* Introduction:: Overview of the Emacs Web Server
-* Handlers:: Handlers respond to HTTP requests
-* Requests:: Getting information on HTTP requests
-* Usage Examples:: Examples demonstrating usage
-* Function Index:: List of Functions
-
-Appendices
-
-* Copying:: The GNU General Public License gives
- you permission to redistribute GNU Emacs on
- certain terms; it also explains that there is
- no warranty.
-* GNU Free Documentation License:: The license for this documentation.
-* Index:: Complete index.
-
-
-
-
-@end menu
-
-@node Introduction, Handlers, Top, Top
-@chapter Introduction
-@cindex introduction
-
-The Emacs Web Server is a Web server implemented entirely in Emacs
-Lisp. HTTP requests are matched to handlers (@pxref{Handlers}) which
-are Emacs Lisp functions. Handlers receive as their only argument a
-request object (@pxref{Requests}) which holds information about the
-request and a process holding the HTTP network connection. Handlers
-write their responses directly to the network process.
-
-A number of examples (@pxref{Usage Examples}) demonstrate usage of the
-Emacs Web Server. All public functions of the Emacs Web Server are
-listed (@pxref{Function Index}).
-
-@node Handlers, Requests, Handlers, Top
-@chapter Handlers
-@cindex handlers
-
-The function @code{ws-start} takes takes two arguments @code{handlers}
-and @code{port}. It starts a server listening on @code{port}
-responding to requests with @code{handlers}. @code{Handlers} may be
-either a single function or an association list composed of pairs of
-matchers and handler functions. When @code{handlers} is a single
-function the given function is used to serve every request, when it is
-an association list, the function of the first matcher to match each
-request handles that request.
-
-@section Matchers
-@cindex matchers
-
-Matchers may be a regular expression or a function. Regular
-expression matchers consists of an HTTP header and a regular
-expression. When the regular expression matches the content of the
-given header the matcher succeeds and the associated handler is
-called. For example the following matches any @code{GET} request
-whose path starts with the substring ``foo''.
-
-@example
-(:GET . "^foo")
-@end example
-
-A function matcher is a function which takes the request object
-(@pxref{Requests}) and succeeds when the function returns a non-nil
-value. For example the following matcher matches every request,
-
-@example
-(lambda (_) t)
-@end example
-
-and the following matches only requests in which the supplied
-``number'' parameter is odd.
-
-@example
-(lambda (request)
- (oddp (string-to-number (cdr (assoc "number" request)))))
-@end example
-
-@section Handler Function
-@cindex handler function
-
-Each handler is a function which takes a request object
-(@pxref{Requests}) as its only argument. The function may respond to
-the request by writing to the network process held in the
-@code{process} field of the request object. For example, the
-@code{process-send-string} function may be used to write string data
-to a request as in the following.
-
-@example
- (process-send-string (process request) "hello world")
-@end example
-
-When the handler function exits the connection is terminated unless
-the handler function returns the keyword @code{:keep-alive}.
-
-@node Requests, Usage Examples, Handlers, Top
-@chapter Requests
-@cindex requests
-
-Each HTTP requests is represented using a @code{ws-request} object
-(@pxref{ws-request}). The request object serves two purposes, one
-internal and one external. Internally, request objects are used to
-hold state while HTTP headers are parsed incrementally as the HTTP
-request text is received from the network. Externally, request
-objects are used to decide which handler to call, and are then passed
-as the only argument to the called handler.
-
-In addition to fields used internally, each @code{ws-request} object
-holds the network process in the @code{process} and holds all HTTP
-headers and request GET or POST parameters in the @code{headers}
-alist. HTML Headers are keyed using uppercase keywords (e.g.,
-@code{:GET}), and user supplied parameters are keyed using the string
-name of the parameter.
-
-The @code{process} field may be used by handlers to send data to a
-client as in the following example.
-
-@example
-(process-send-string (process request) "hello world")
-@end example
-
-The @code{headers} field may be used to access request information
-such as the requested path,
-
-@example
-(cdr (assoc :GET (headers request)))
-@end example
-
-or named parameters as from a web form.
-
-@example
-(cdr (assoc "message" (headers request)))
-@end example
-
-@node Usage Examples, Hello World, Requests, Top
-@chapter Usage Examples
-@cindex usage examples
-
-These examples demonstrate usage.
-@menu
-* Hello World:: Serve ``Hello World'' to every request
-* Hello World UTF8:: Serve ``Hello World'' w/UTF8 encoding
-* Hello World HTML:: Serve ``Hello World'' in HTML
-* File Server:: Serve files from a document root
-* URL Parameter Echo:: Echo parameters from a URL query string
-* POST Echo:: Echo POST parameters back
-* Basic Authentication:: BASIC HTTP authentication
-* Org-mode Export:: Export files to HTML and Tex
-* File Upload:: Upload files and return their sha1sum
-* Web Socket:: Web socket echo server
-* Gzipped Transfer Encoding:: Gzip content encoding
-* Chunked Transfer Encoding:: Chunked transfer encoding
-@end menu
-
-@node Hello World, Hello World UTF8, Usage Examples, Usage Examples
-@section Hello World
-
-The simplest possible ``hello world'' example. The handler consists
-of a single (matcher . handler) pair. The function matcher matches
-@emph{every} incoming HTTP request. The handler responds by setting
-the content type to @code{text/plain}, and then sending the string
-``hello world''. When the handler exits the network connection of the
-request is closed.
-
-@verbatiminclude ../examples/000-hello-world.el
-
-@node Hello World UTF8, Hello World HTML, Hello World, Usage Examples
-@section Hello World UTF8
-
-This example only differs from the previous in that the
-``Content-type'' indicates UTF8 encoded data, and the hello world sent
-is selected at random from a list of different languages.
-
-@verbatiminclude ../examples/001-hello-world-utf8.el
-
-@node Hello World HTML, File Server, Hello World UTF8, Usage Examples
-@section Hello World HTML
-@verbatiminclude ../examples/002-hello-world-html.el
-
-This variation of the ``hello world'' example sends a @code{text/html}
-response instead of a simple @code{text/plain} response.
-
-@node File Server, URL Parameter Echo, Hello World HTML, Usage Examples
-@section File Server
-
-The following example implements a file server which will serve files
-from the @code{docroot} document root set to the current working
-directory in this example. Four helper functions are used;
-@code{ws-in-directory-p} is used to check if the requested path is
-within the document root. If not then @code{ws-send-404} is used to
-send a default ``File Not Found''. If so then the file is served with
-@code{ws-send-file} (which appropriately sets the mime-type of the
-response based on the extension of the file) if it is a file or is
-served with @code{ws-send-directory-list} if it is a directory.
-
-@verbatiminclude ../examples/003-file-server.el
-
-@node URL Parameter Echo, POST Echo, File Server, Usage Examples
-@section URL Parameter Echo
-
-This example demonstrates access of URL-encoded parameters in a
-@code{GET} request. For example the following URL
-@url{http://localhost:9005/example?foo=bar&baz=qux} will render as
-the following HTML table.
-
-@multitable @columnfractions .5 .5
-@item foo @tab bar
-@item baz @tab qux
-@end multitable
-
-@verbatiminclude ../examples/004-url-param-echo.el
-
-@node POST Echo, Basic Authentication, URL Parameter Echo, Usage Examples
-@section POST Echo
-
-The following example echos back the content of the ``message'' field
-in a @code{POST} request.
-
-@verbatiminclude ../examples/005-post-echo.el
-
-@node Basic Authentication, Org-mode Export, POST Echo, Usage Examples
-@section Basic Authentication
-
-The following example demonstrates BASIC HTTP authentication. The
-handler prompts an unauthenticated client for authentication by
-sending a ``WWW-Authenticate'' header.
-
-@example
-(ws-response-header process 401
- '("WWW-Authenticate" . "Basic realm=\"example\"")
- '("Content-type" . "text/plain"))
-@end example
-
-The client replies by setting the ``Authorization'' HTTP header which
-is parsed into a list of the form @code{(PROTOCOL USERNAME
-. PASSWORD)}. Currently only BASIC HTTP authentication is supported.
-
-@noindent
-Note: BASIC HTTP authentication passes user credentials in plain text
-between the client and the server and should generally only be used
-with HTTPS network encryption. While the Emacs web server currently
-doesn't support HTTPS network encryption it may be run behind an HTTPS
-proxy server (e.g., Apache or Nginx) with HTTPS support.
-
-@verbatiminclude ../examples/006-basic-authentication.el
-
-@node Org-mode Export, File Upload, Basic Authentication, Usage Examples
-@section Org-mode Export
-
-The following example exports a directory of Org-mode files as either
-text, HTML or LaTeX. The Org-mode export engine is used to export
-files on-demand as they are requested.
-
-@verbatiminclude ../examples/007-org-mode-file-server.el
-
-@node File Upload, Web Socket, Org-mode Export, Usage Examples
-@section File Upload
-
-The following example demonstrates accessing an uploaded file. This
-simple server accesses the file named ``file'' and returns it's
-sha1sum and file name.
-
-@verbatiminclude ../examples/008-file-upload.el
-
-A file may be uploaded from an HTML form, or using the @code{curl}
-program as in the following example.
-
-@example
-$ curl -s -F file=@/usr/share/emacs/24.3/etc/COPYING localhost:9008
-8624bcdae55baeef00cd11d5dfcfa60f68710a02 COPYING
-$ sha1sum /usr/share/emacs/24.3/etc/COPYING
-8624bcdae55baeef00cd11d5dfcfa60f68710a02 /usr/share/emacs/24.3/etc/COPYING
-@end example
-
-@node Web Socket, Chunked Transfer Encoding, File Upload, Usage Examples
-@section Web Socket
-
-Example demonstrating the use of web sockets for full duplex
-communication between clients and the server. Handlers may use the
-@code{ws-web-socket-connect} function (@pxref{ws-web-socket-connect})
-to check for and respond to a web socket upgrade request sent by the
-client (as demonstrated with the @code{new WebSocket} JavaScript code
-in the example). Upon successfully initializing a web socket
-connection the call to @code{ws-web-socket-connect} will return the
-web socket network process. This process may then be used by the
-server to communicate with the client over the web socket using the
-@code{process-send-string} and @code{ws-web-socket-frame} functions.
-All web socket communication must be wrapped in frames using the
-@code{ws-web-socket-frame} function.
-
-The handler must pass a function as the second argument to
-@code{ws-web-socket-connect}. This function will be called on every
-web socket message received from the client.
-
-@noindent
-Note: in order to keep the web socket connection alive the request
-handler from which @code{ws-web-socket-connect} is called must return
-the @code{:keep-alive} keyword, as demonstrated in the example.
-
-@verbatiminclude ../examples/009-web-socket.el
-
-@node Gzipped Transfer Encoding, Chunked Transfer Encoding, Web Socket, Usage
Examples
-@section Gzipped Transfer Encoding
-
-HTTP Responses may be compressed by setting the ``gzip'' (or
-``compress'' or ``deflate'') content- or transfer-encoding HTTP
-headers in @code{ws-response-header}. Any further data sent to the
-process using @code{ws-send} will automatically be appropriately
-compressed.
-
-@verbatiminclude ../examples/016-content-encoding-gzip.el
-
-@node Chunked Transfer Encoding, Function Index, Web Socket, Usage Examples
-@section Chunked Transfer Encoding
-
-Similarly, HTTP Responses may be sent using the ``chunked'' transfer
-encoding by passing the appropriate HTTP header to
-@code{ws-response-header}. Any further data sent to the process using
-@code{ws-send} will automatically be appropriately encoded for chunked
-transfer.
-
-@verbatiminclude ../examples/017-transfer-encoding-chunked.el
-
-@node Function Index, Copying, Usage Examples, Top
-@chapter Function Index
-@cindex function index
-
-The following functions implement the Emacs Web Server public API.
-
-@section Objects
-The following objects represent web servers and requests.
-
-@anchor{ws-server}
-@deftp Class ws-server handlers process port requests
-Every Emacs web server is an instance of the @code{ws-server} class.
-Each instance includes the @code{handlers} association list and
-@code{port} passed to @code{ws-start}, as well as the server network
-@code{process} and a list of all active @code{requests}.
-@end deftp
-
-@anchor{ws-request}
-@deftp Class ws-request process pending context boundary index active headers
-The @code{ws-request} class represents an active web request. The
-@code{process} field holds the network process of the client and may
-be used by handlers to respond to requests. The @code{headers} field
-holds an alist of information on the request for use by handlers. The
-remaining @code{pending}, @code{context}, @code{boundary},
-@code{index} and @code{active} fields are used to maintain header
-parsing information across calls to the @code{ws-filter} function.
-@end deftp
-
-@section Starting and Stopping Servers
-@cindex start and stop
-The following functions start and stop Emacs web servers. The
-@code{ws-servers} list holds all running servers.
-
-@anchor{ws-start}
-@defun ws-start handlers port &optional log-buffer &rest network-args
-@code{ws-start} starts a server listening on @code{port} using
-@code{handlers} (@pxref{Handlers}) to match and respond to requests.
-An instance of the @code{ws-server} class is returned.
-@end defun
-
-@anchor{ws-servers}
-@defvar ws-servers
-The @code{ws-servers} list holds all active Emacs web servers.
-@end defvar
-
-@anchor{ws-stop}
-@defun ws-stop server
-@code{ws-stop} stops @code{server} deletes all related processes, and
-frees the server's port. Evaluate the following to stop all emacs web
-servers.
-@example
-(mapc #'ws-stop ws-servers)
-@end example
-@end defun
-
-@anchor{ws-stop-all}
-@defun ws-stop-all
-@code{ws-stop-all} stops all emacs web servers by mapping
-@code{ws-stop} over @code{ws-servers}.
-@end defun
-
-@section Convenience Functions
-The following convenience functions automate many common tasks
-associated with responding to HTTP requests.
-
-@anchor{ws-response-header}
-@cindex content type
-@defun ws-response-header process code &rest headers
-Send the headers required to start an HTTP response to @code{proc}.
-@code{proc} should be a @code{ws-request} @code{proc} of an active
-request.
-
-For example start a standard 200 ``OK'' HTML response with the
-following.
-
-@example
-(ws-response-header process 200 '("Content-type" . "text/html"))
-@end example
-
-The encoding may optionally be set in the HTTP header. Send a UTF8
-encoded response with the following.
-
-@example
-(ws-response-header process 200
- '("Content-type" . "text/plain; charset=utf-8"))
-@end example
-
-Additionally, when ``Content-Encoding'' or ``Transfer-Encoding''
-headers are supplied any subsequent data written to @code{proc} using
-@code{ws-send} will be encoded appropriately including sending the
-appropriate data upon the end of transmission for chunked transfer
-encoding.
-
-For example with the header @code{("Content-Encoding" . "gzip")}, any
-data subsequently written to @code{proc} using @code{ws-send} will be
-compressed using the command specified in @code{ws-gzip-cmd}. See
-@ref{Gzipped Transfer Encoding} and @ref{Chunked Transfer Encoding}
-for more complete examples.
-
-@end defun
-
-@anchor{ws-send}
-@defun ws-send proc string
-Send @code{string} to process @code{proc}. If any Content or Transfer
-encodings are in use, apply them to @code{string} before sending.
-@end defun
-
-@anchor{ws-send-500}
-@defun ws-send-500 process &rest msg-and-args
-@code{ws-send-500} sends a default 500 ``Internal Server Error''
-response to @code{process}.
-@end defun
-
-@anchor{ws-send-404}
-@defun ws-send-404 process &rest msg-and-args
-@code{ws-send-500} sends a default 404 ``File Not Found'' response to
-@code{process}.
-@end defun
-
-@anchor{ws-send-file}
-@defun ws-send-file process path &optional mime-type
-@code{ws-send-file} sends the file located at @code{path} to
-@code{process}. If the optional @code{mime-type} is not set, then the
-mime-type is determined by calling @code{mm-default-file-encoding} on
-@code{path} or is set to ``application/octet-stream'' if no mime-type
-can be determined.
-@end defun
-
-@anchor{ws-send-directory-list}
-@defun ws-send-directory-list process directory &optional match
-@code{ws-send-directory-list} sends the a listing of the files located
-in @code{directory} to @code{process}. The list is sent as an HTML
-list of links to the files. Optional argument @code{match} may be set
-to a regular expression, in which case only those files that match are
-listed.
-@end defun
-
-@anchor{ws-in-directory-p}
-@defun ws-in-directory-p parent path
-Check if @code{path} is under the @code{parent} directory.
-
-@example
-(ws-in-directory-p "/tmp/" "pics")
- @result{} "/tmp/pics"
-
-(ws-in-directory-p "/tmp/" "..")
- @result{} nil
-
-(ws-in-directory-p "/tmp/" "~/pics")
- @result{} nil
-@end example
-@end defun
-
-@anchor{ws-with-authentication}
-@defun ws-with-authentication handler credentials &optional realm unauth
invalid
-Return a version of @code{handler} which is protected by
-@code{credentials}. Handler should be a normal handler function
-(@pxref{Handlers}) and @code{credentials} should be an association
-list of usernames and passwords.
-
-For example, a server running the following handlers,
-
-@example
-(list (cons '(:GET . ".*") 'view-handler)
- (cons '(:POST . ".*") 'edit-handler))
-@end example
-
-could have authorization added by changing the handlers to the
-following.
-
-@example
-(list (cons '(:GET . ".*") view-handler)
- (cons '(:POST . ".*") (ws-with-authentication
- 'org-ehtml-edit-handler
- '(("admin" . "password")))))
-@end example
-
-@end defun
-
-@anchor{ws-web-socket-connect}
-@defun ws-web-socket-connect request handler
-If @code{request} is a web socket upgrade request (indicated by the
-presence of the @code{:SEC-WEBSOCKET-KEY} header argument) establish a
-web socket connection to the client. Call @code{handler} on web
-socket messages received from the client.
-
-@example
-(ws-web-socket-connect request
- (lambda (proc string)
- (process-send-string proc
- (ws-web-socket-frame (concat "you said: " string)))))
- @result{} #<process ws-server <127.0.0.1:34921>>
-@end example
-@end defun
-
-@section Customization Variables
-The following variables may be changed to control the behavior of the
-web server. Specifically the @code{ws-*-cmd} variables specify the
-command lines used to compress data according to content and or
-transfer encoding HTTP headers passed to @ref{ws-response-header}.
-
-@anchor{ws-compress-cmd}
-@defvar ws-compress-cmd
-Command used for the ``compress'' Content or Transfer coding.
-@end defvar
-
-@anchor{ws-deflate-cmd}
-@defvar ws-deflate-cmd
-Command used for the ``deflate'' Content or Transfer coding.
-@end defvar
-
-@anchor{ws-gzip-cmd}
-@defvar ws-gzip-cmd
-Command used for the ``gzip'' Content or Transfer coding.
-@end defvar
-
-@node Copying, GNU Free Documentation License, Function Index, Top
-@appendix GNU GENERAL PUBLIC LICENSE
-@include gpl.texi
-
-@node GNU Free Documentation License, Index, Copying, Top
-@appendix GNU Free Documentation License
-@include doclicense.texi
-
-@node Index, , GNU Free Documentation License, Top
-@unnumbered Index
-
-@c Combine all index (function variable type and concept) types into a
-@c single index.
-@syncodeindex fn cp
-@syncodeindex vr cp
-@syncodeindex tp cp
-@printindex cp
-
-@bye
diff --git a/packages/web-server/examples/000-hello-world.el
b/packages/web-server/examples/000-hello-world.el
deleted file mode 100644
index 61902b8..0000000
--- a/packages/web-server/examples/000-hello-world.el
+++ /dev/null
@@ -1,9 +0,0 @@
-;;; hello-world.el --- simple hello world server using Emacs Web Server -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (process-send-string process "hello world")))
- 9000)
diff --git a/packages/web-server/examples/001-hello-world-utf8.el
b/packages/web-server/examples/001-hello-world-utf8.el
deleted file mode 100644
index 3013745..0000000
--- a/packages/web-server/examples/001-hello-world-utf8.el
+++ /dev/null
@@ -1,22 +0,0 @@
-;;; hello-world-utf8.el --- utf8 hello world server using Emacs Web Server
-*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((hellos '("こんにちは"
- "안녕하세요"
- "góðan dag"
- "Grüßgott"
- "hyvää päivää"
- "yá'át'ééh"
- "Γεια σας"
- "Вiтаю"
- "გამარჯობა"
- "नमस्ते"
- "你好")))
- (ws-response-header process 200
- '("Content-type" . "text/plain; charset=utf-8"))
- (process-send-string process
- (concat (nth (random (length hellos)) hellos) " world")))))
- 9001)
diff --git a/packages/web-server/examples/002-hello-world-html.el
b/packages/web-server/examples/002-hello-world-html.el
deleted file mode 100644
index 8e17e3d..0000000
--- a/packages/web-server/examples/002-hello-world-html.el
+++ /dev/null
@@ -1,16 +0,0 @@
-;;; hello-world-html.el --- html hello world server using Emacs Web Server
-*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process "<html>
- <head>
- <title>Hello World</title>
- </head>
- <body>
- <b>hello world</b>
- </body>
-</html>")))
- 9002)
diff --git a/packages/web-server/examples/003-file-server.el
b/packages/web-server/examples/003-file-server.el
deleted file mode 100644
index 8be084a..0000000
--- a/packages/web-server/examples/003-file-server.el
+++ /dev/null
@@ -1,15 +0,0 @@
-;;; file-server.el --- serve any files using Emacs Web Server -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(let ((docroot default-directory))
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((path (substring (cdr (assoc :GET headers)) 1)))
- (if (ws-in-directory-p docroot path)
- (if (file-directory-p path)
- (ws-send-directory-list process
- (expand-file-name path docroot) "^[^.]")
- (ws-send-file process (expand-file-name path docroot)))
- (ws-send-404 process)))))
- 9003))
diff --git a/packages/web-server/examples/004-url-param-echo.el
b/packages/web-server/examples/004-url-param-echo.el
deleted file mode 100644
index ac53bee..0000000
--- a/packages/web-server/examples/004-url-param-echo.el
+++ /dev/null
@@ -1,18 +0,0 @@
-;;; url-param-echo.el --- echo back url-paramed message using Emacs Web Server
-*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- `(((:GET . ".*") .
- ,(lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process
- (concat "URL Parameters:</br><table><tr>"
- (mapconcat (lambda (pair)
- (format "<th>%s</th><td>%s</td>"
- (car pair) (cdr pair)))
- (cl-remove-if-not (lambda (el) (stringp (car
el)))
- headers)
- "</tr><tr>")
- "</tr></table>"))))))
- 9004)
diff --git a/packages/web-server/examples/005-post-echo.el
b/packages/web-server/examples/005-post-echo.el
deleted file mode 100644
index a39a3ae..0000000
--- a/packages/web-server/examples/005-post-echo.el
+++ /dev/null
@@ -1,20 +0,0 @@
-;;; post-echo.el --- echo back posted message using Emacs Web Server -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- `(((:POST . ".*") .
- ,(lambda (request)
- (with-slots (process headers) request
- (let ((message (cdr (assoc "message" headers))))
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (process-send-string process
- (if message
- (format "you said %S\n" (cdr (assoc
'content message)))
- "This is a POST request, but it has no
\"message\".\n"))))))
- ((:GET . ".*") .
- ,(lambda (request)
- (with-slots (process) request
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (process-send-string process
- "This is a GET request not a POST
request.\n")))))
- 9005)
diff --git a/packages/web-server/examples/006-basic-authentication.el
b/packages/web-server/examples/006-basic-authentication.el
deleted file mode 100644
index 0d3f354..0000000
--- a/packages/web-server/examples/006-basic-authentication.el
+++ /dev/null
@@ -1,14 +0,0 @@
-;;; basic-authentication.el --- basic authentication -*- lexical-binding: t;
-*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(let ((users '(("foo" . "bar")
- ("baz" . "qux"))))
- (ws-start
- (ws-with-authentication
- (lambda (request)
- (with-slots (process headers) request
- (let ((user (caddr (assoc :AUTHORIZATION headers))))
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (process-send-string process (format "welcome %s" user)))))
- users)
- 9006))
diff --git a/packages/web-server/examples/007-org-mode-file-server.el
b/packages/web-server/examples/007-org-mode-file-server.el
deleted file mode 100644
index 1b3bc9e..0000000
--- a/packages/web-server/examples/007-org-mode-file-server.el
+++ /dev/null
@@ -1,45 +0,0 @@
-;;; org-mode-file-server.el --- serve on-demand exported Org-mode files -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(let ((docroot "/tmp/"))
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((path (ws-in-directory-p ; check if path is in docroot
- docroot (substring (cdr (assoc :GET headers)) 1))))
- (unless path (ws-send-404 process)) ; send 404 if not in docroot
- (if (file-directory-p path)
- (progn ;; send directory listing, convert org files to
html/tex/txt
- (ws-response-header proc 200 (cons "Content-type" "text/html"))
- (process-send-string proc
- (concat "<ul>"
- (mapconcat
- (lambda (f)
- (let* ((full (expand-file-name f path))
- (end (if (file-directory-p full) "/" ""))
- (url (url-encode-url (concat f end))))
- (format "<li><a href=%s>%s</li>" url f)))
- (apply #'append
- (mapcar
- (lambda (f)
- (list (concat f ".txt")
- (concat f ".tex")
- (concat f ".html")))
- (mapcar #'file-name-sans-extension
- (directory-files path nil
- "^[^.].*org\\'"))))
- "\n") "</ul>")))
- ;; Export the file as requested and return the result
- (let* ((base (file-name-sans-extension path))
- (type (case (intern (downcase (file-name-extension path)))
- (html 'html)
- (tex 'latex)
- (txt 'ascii)
- (t (ws-error process "%S export not supported"
- (file-name-extension path)))))
- (orig (concat base ".org")))
- (unless (file-exists-p orig) (ws-send-404 process))
- (save-window-excursion (find-file orig)
- (org-export-to-file type path))
- (ws-send-file process path))))))
- 9007))
diff --git a/packages/web-server/examples/008-file-upload.el
b/packages/web-server/examples/008-file-upload.el
deleted file mode 100644
index 979f520..0000000
--- a/packages/web-server/examples/008-file-upload.el
+++ /dev/null
@@ -1,13 +0,0 @@
-;;; file-upload.el --- use an uploaded file -*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- `(((:POST . ".*") .
- ,(lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200 '("Content-type" . "text/plain"))
- (let ((file (cdr (assoc "file" headers))))
- (process-send-string process
- (concat (sha1 (cdr (assoc 'content file))) " "
- (cdr (assoc 'filename file)) "\n")))))))
- 9008)
diff --git a/packages/web-server/examples/009-web-socket.el
b/packages/web-server/examples/009-web-socket.el
deleted file mode 100644
index d7bbd1a..0000000
--- a/packages/web-server/examples/009-web-socket.el
+++ /dev/null
@@ -1,57 +0,0 @@
-;;; web-sockets.el --- communicate via web-sockets -*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(let* ((web-socket-port 9009)
- (web-socket-page
- (format "<html>
-<head>
-<script type=\"text/javascript\">
-var ws;
-function connect(){
- ws = new WebSocket(\"ws://localhost:%d/\");
-
- ws.onopen = function() { alert(\"connected\"); };
- ws.onmessage = function(msg) { alert(\"server: \" + msg.data); };
- ws.onclose = function() { alert(\"connection closed\"); };
-}
-
-function message(){ ws.send(\"foo\"); }
-
-function close(){ ws.close(); };
-</script>
-</head>
-<body>
-<ol>
-
-<li>Press \"connect\" to initialize the web socket connection to
- the server. The server will complete the web socket
- handshake at which point you'll see an alert with the text
- \"connected\".</li>
-
-<li>Press \"message\" to send the string \"foo\" to the server.
- The server will reply with the text \"you said: foo\" which
- you will see in an alert as \"server: you said: foo\".</li>
-
-<li>Press \"close\" to close the connection. After the server
- responds with a close frame you will see an alert with the
- text \"connection closed\".</li>
-
-</ol>
-<a href=\"javascript:connect()\">connect</a>
-<a href=\"javascript:message()\">message</a>
-<a href=\"javascript:close()\">close</a>
-</body>
-</html>" web-socket-port)))
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- ;; if a web-socket request, then connect and keep open
- (if (ws-web-socket-connect request
- (lambda (proc string)
- (process-send-string proc
- (ws-web-socket-frame (concat "you said: " string)))))
- (prog1 :keep-alive (setq my-connection process))
- ;; otherwise send the index page
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process web-socket-page))))
- web-socket-port))
diff --git a/packages/web-server/examples/010-current-buffer.el
b/packages/web-server/examples/010-current-buffer.el
deleted file mode 100644
index 0233abf..0000000
--- a/packages/web-server/examples/010-current-buffer.el
+++ /dev/null
@@ -1,15 +0,0 @@
-;;; current-buffer.el --- Show the current Emacs buffer -*- lexical-binding:
t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(if t (require 'htmlize)) ;Don't require during compilation.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200
- '("Content-type" . "text/html; charset=utf-8"))
- (process-send-string process
- (let ((html-buffer (htmlize-buffer)))
- (prog1 (with-current-buffer html-buffer (buffer-string))
- (kill-buffer html-buffer))))))
- 9010)
diff --git a/packages/web-server/examples/011-org-agenda.el
b/packages/web-server/examples/011-org-agenda.el
deleted file mode 100644
index 6ec55c3..0000000
--- a/packages/web-server/examples/011-org-agenda.el
+++ /dev/null
@@ -1,18 +0,0 @@
-;;; org-agenda.el --- display the Org-mode agenda -*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(if t (require 'htmlize)) ;Don't require during compilation.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200
- '("Content-type" . "text/html; charset=utf-8"))
- (org-agenda nil "a")
- (process-send-string process
- (save-window-excursion
- (let ((html-buffer (htmlize-buffer)))
- (prog1 (with-current-buffer html-buffer (buffer-string))
- (kill-buffer html-buffer)
- (org-agenda-quit)))))))
- 9011)
diff --git a/packages/web-server/examples/012-search-bbdb.el
b/packages/web-server/examples/012-search-bbdb.el
deleted file mode 100644
index f54cc24..0000000
--- a/packages/web-server/examples/012-search-bbdb.el
+++ /dev/null
@@ -1,23 +0,0 @@
-;;; search-bbdb.el --- search the Big Brother Data Base for a supplied name
-*- lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((name (cdr (assoc "name" headers))))
- (unless name
- (ws-error process "Must specify a name to search."))
- (save-excursion
- (unless (set-buffer (get-buffer "*BBDB*"))
- (ws-error process "no *BBDB* buffer found"))
- (bbdb-search-name name)
- (if (equal (point-min) (point-max))
- (progn
- (ws-response-header process 404
- '("Content-type" . "text/plain"))
- (process-send-string process
- "no matches found"))
- (ws-response-header process 200
- '("Content-type" . "text/plain"))
- (process-send-string process (buffer-string)))))))
- 9012)
diff --git a/packages/web-server/examples/013-org-export-service.el
b/packages/web-server/examples/013-org-export-service.el
deleted file mode 100644
index 67a8a7e..0000000
--- a/packages/web-server/examples/013-org-export-service.el
+++ /dev/null
@@ -1,46 +0,0 @@
-;;; 013-org-export-service.el --- upload and export Org-mode files -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((file (cdr (assoc "file" headers)))
- (type (cdr (assoc 'content (cdr (assoc "type" headers))))))
- (if (not (and file type))
- (progn
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process "
-<html><body><form action=\"\" method=\"post\" enctype=\"multipart/form-data\">
-Export file: <input type=\"file\" name=\"file\"> to type
-<select name=\"type\">
-<option value=\"txt\">Text</option>
-<option value=\"html\">HTML</option>
-<option value=\"tex\">TeX</option>
-</select>
-<input type=\"submit\" value=\"submit\">.
-</form></body></html>"))
- (let* ((orig (cdr (assoc 'filename file)))
- (base (file-name-nondirectory
- (file-name-sans-extension orig)))
- (backend (case (intern (downcase type))
- (html 'html)
- (tex 'latex)
- (txt 'ascii)
- (t (ws-error process "%S export not supported"
- type))))
- (path (concat base "." type)))
- (let ((default-directory temporary-file-directory))
- (when (or (file-exists-p orig) (file-exists-p path))
- (ws-error process
- "File already exists on the server, try a new file."))
- (with-temp-file orig (insert (cdr (assoc 'content file))))
- (save-window-excursion (find-file orig)
- ;; TODO: Steal personal data and
- ;; ideas from uploaded Org-mode
- ;; text. Web services aren't free!
- (org-export-to-file backend path)
- (kill-buffer))
- (ws-send-file process path)
- (delete-file path)
- (delete-file orig)))))))
- 9013)
diff --git a/packages/web-server/examples/014-org-json.el
b/packages/web-server/examples/014-org-json.el
deleted file mode 100644
index f49b823..0000000
--- a/packages/web-server/examples/014-org-json.el
+++ /dev/null
@@ -1,26 +0,0 @@
-;;; org-json.el --- Serve Org-mode pages as json -*- lexical-binding: t; -*-
-;; suggested by nicferrier
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(require 'json)
-(let ((docroot "/tmp/"))
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((path (ws-in-directory-p
- docroot (substring (cdr (assoc :GET headers)) 1))))
- (unless (and path (file-exists-p path))
- (ws-send-404 process))
- (save-window-excursion
- (find-file path)
- (ws-response-header process 200
- '("Content-type" . "application/json"))
- (process-send-string process
- (let ((tree (org-element-parse-buffer)))
- (org-element-map tree
- (append org-element-all-objects org-element-all-elements)
- (lambda (el)
- (org-element-put-property el :parent "none")
- (org-element-put-property el :structure "none")))
- (json-encode tree)))))))
- 9014))
diff --git a/packages/web-server/examples/015-auto-mode-server.el
b/packages/web-server/examples/015-auto-mode-server.el
deleted file mode 100644
index c9ae294..0000000
--- a/packages/web-server/examples/015-auto-mode-server.el
+++ /dev/null
@@ -1,30 +0,0 @@
-;;; auto-mode-server.el --- files with fontification from the
`auto-mode-alist' -*- lexical-binding:t -*-
-;; Copyright (C) 2014, 2016 Free Software Foundation, Inc.
-
-(if t (require 'htmlize)) ;Don't require during compilation.
-
-(let ((docroot default-directory))
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (let ((path (ws-in-directory-p
- docroot (substring (cdr (assoc :GET headers)) 1))))
- (if path
- (if (file-directory-p path)
- (ws-send-directory-list process
- (expand-file-name path docroot) "^[^\.]")
- ;; send htmlize version of file
- (let ((mode (or (cdr (cl-assoc-if (lambda (re) (string-match re
path))
- auto-mode-alist))
- 'fundamental-mode)))
- (ws-response-header process 200
- '("Content-type" . "text/html; charset=utf-8"))
- (process-send-string process
- (with-temp-buffer
- (insert-file-contents-literally path)
- (funcall mode)
- (let ((html (htmlize-buffer)))
- (prog1 (with-current-buffer html (buffer-string))
- (kill-buffer html)))))))
- (ws-send-404 process)))))
- 9015))
diff --git a/packages/web-server/examples/016-content-encoding-gzip.el
b/packages/web-server/examples/016-content-encoding-gzip.el
deleted file mode 100644
index 622e274..0000000
--- a/packages/web-server/examples/016-content-encoding-gzip.el
+++ /dev/null
@@ -1,26 +0,0 @@
-;;; content-encoding-gzip.el -- gzip content encoding -*- lexical-binding: t;
-*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (with-slots (process headers) request
- (ws-response-header process 200
- '("Content-type" . "text/plain; charset=utf-8")
- '("Content-Encoding" . "x-gzip"))
- (let ((s "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
-hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam
-nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis
-natoque penatibus et magnis dis parturient montes, nascetur
-ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique
-diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam
-vestibulum accumsan nisl.
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
-hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam
-nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis
-natoque penatibus et magnis dis parturient montes, nascetur
-ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique
-diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam
-vestibulum accumsan nisl."))
- (ws-send process s))))
- 9016)
diff --git a/packages/web-server/examples/017-transfer-encoding-chunked.el
b/packages/web-server/examples/017-transfer-encoding-chunked.el
deleted file mode 100644
index bf54a98..0000000
--- a/packages/web-server/examples/017-transfer-encoding-chunked.el
+++ /dev/null
@@ -1,31 +0,0 @@
-;;; transfer-encoding-chunked.el -- chunked transfer encoding -*-
lexical-binding: t; -*-
-;; Copyright (C) 2014-2020 Free Software Foundation, Inc.
-
-(ws-start
- (lambda (request)
- (let ((s "
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
-hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam
-nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis
-natoque penatibus et magnis dis parturient montes, nascetur
-ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique
-diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam
-vestibulum accumsan nisl.
-
-Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec
-hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam
-nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis
-natoque penatibus et magnis dis parturient montes, nascetur
-ridiculus mus. Nulla posuere. Donec vitae dolor. Nullam tristique
-diam non turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam
-vestibulum accumsan nisl.
-"))
- (with-slots (process headers) request
- (ws-response-header process 200
- '("Content-type" . "text/plain; charset=utf-8")
- '("Transfer-Encoding" . "chunked"))
- (ws-send process s) (sit-for 0.5)
- (ws-send process s) (sit-for 0.5)
- (ws-send process s) (sit-for 0.5)
- (ws-send process s))))
- 9017)
diff --git a/packages/web-server/examples/018-web-shell.el
b/packages/web-server/examples/018-web-shell.el
deleted file mode 100644
index 37fc702..0000000
--- a/packages/web-server/examples/018-web-shell.el
+++ /dev/null
@@ -1,74 +0,0 @@
-;;; web-shell.el --- interact with a SHELL through a web interface -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2013-2020 Free Software Foundation, Inc.
-
-;; This software 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 software 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:
-
-;; DO NOT RUN THIS EXAMPLE!
-
-;; At least not if anyone has network access to your computer.
-
-;; This example starts a local shell using the `shell' function. The
-;; resulting comint buffer is then exported using web sockets.
-;; Clients can run local shell commands and see their results through
-;; their browser.
-
-;; This example is included because it should be easily generalizable
-;; to build web interfaces to other comint buffers using web sockets.
-
-;;; Code:
-(defvar web-shell-port 9018)
-
-(defun web-shell-f-to-s (f)
- (with-temp-buffer
- (insert-file-contents-literally
- (expand-file-name f
- (file-name-directory
- (or load-file-name buffer-file-name default-directory))))
- (buffer-string)))
-
-(defvar web-shell-js (web-shell-f-to-s "018-web-shell.js"))
-
-(defvar web-shell-html (web-shell-f-to-s "018-web-shell.html"))
-
-(defvar web-shell-socket nil)
-
-(defun web-shell-socket-respond (string)
- (when web-shell-socket
- (process-send-string web-shell-socket (ws-web-socket-frame string))))
-
-(defun web-shell-socket-handler (process string)
- (message "recieved %S" string)
- (with-current-buffer "*shell*"
- (goto-char (process-mark (get-buffer-process (current-buffer))))
- (insert string)
- (comint-send-input)))
-
-(defun web-shell-handler (request)
- (with-slots (process headers) request
- ;; if a web-socket request
- (if (ws-web-socket-connect request 'web-shell-socket-handler)
- ;; then connect and keep open
- (prog1 :keep-alive
- (setq web-shell-socket process)
- (add-hook 'comint-output-filter-functions 'web-shell-socket-respond))
- ;; otherwise send the html and javascript
- (save-window-excursion (shell))
- (ws-response-header process 200 '("Content-type" . "text/html"))
- (process-send-string process
- (format web-shell-html (format web-shell-js web-shell-port))))))
-
-(ws-start #'web-shell-handler 9018)
diff --git a/packages/web-server/examples/018-web-shell.html
b/packages/web-server/examples/018-web-shell.html
deleted file mode 100644
index 56d5ae5..0000000
--- a/packages/web-server/examples/018-web-shell.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
- <head>
- <script type="text/javascript">
-%s
- </script>
- </head>
-<body>
- <pre id="buffer"></pre>
- <div>
- <input type="text" id="mini-buffer" value="" />
- <button onclick="connect();">connect</button>
- <button onclick="ws.close();">close</button>
- </div>
-</body>
-</html>
diff --git a/packages/web-server/examples/018-web-shell.js
b/packages/web-server/examples/018-web-shell.js
deleted file mode 100644
index 295ff7c..0000000
--- a/packages/web-server/examples/018-web-shell.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var ws;
-
-function write(data){
- var before = document.getElementById("buffer").innerHTML;
- document.getElementById("buffer").innerHTML = before + data;
- window.scrollTo(0,document.body.scrollHeight); }
-
-function read(){
- var tmp = document.getElementById("mini-buffer").value;
- document.getElementById("mini-buffer").value = "";
- write(tmp + "\n");
- return tmp; }
-
-function connect(){
- ws = new WebSocket("ws://localhost:%d/");
- ws.onopen = function() { write("<p><i>connected</i></p>"); };
- ws.onmessage = function(msg) { write(msg.data); };
- ws.onclose = function() { write("<p><i>closed</i></p>"); }; }
-
-window.onload = function(){
- document.getElementById("mini-buffer").addEventListener(
- "keyup", function(e){ if(e.keyCode == 13){ ws.send(read()); } }); }
diff --git a/packages/web-server/web-server-status-codes.el
b/packages/web-server/web-server-status-codes.el
deleted file mode 100644
index f3f07fc..0000000
--- a/packages/web-server/web-server-status-codes.el
+++ /dev/null
@@ -1,106 +0,0 @@
-;;; web-server-status-codes.el --- Emacs Web Server HTML status codes
-
-;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
-
-;; This software 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 software 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/>.
-
-;;; Code:
-(defvar ws-status-codes
- '((100 . "Continue")
- (101 . "Switching Protocols")
- (102 . "Processing")
- (200 . "OK")
- (201 . "Created")
- (202 . "Accepted")
- (203 . "Non-Authoritative Information")
- (204 . "No Content")
- (205 . "Reset Content")
- (206 . "Partial Content")
- (207 . "Multi-Status")
- (208 . "Already Reported")
- (226 . "IM Used")
- (300 . "Multiple Choices")
- (301 . "Moved Permanently")
- (302 . "Found")
- (303 . "See Other")
- (304 . "Not Modified")
- (305 . "Use Proxy")
- (306 . "Switch Proxy")
- (307 . "Temporary Redirect")
- (308 . "Permanent Redirect")
- (400 . "Bad Request")
- (401 . "Unauthorized")
- (402 . "Payment Required")
- (403 . "Forbidden")
- (404 . "Not Found")
- (405 . "Method Not Allowed")
- (406 . "Not Acceptable")
- (407 . "Proxy Authentication Required")
- (408 . "Request Timeout")
- (409 . "Conflict")
- (410 . "Gone")
- (411 . "Length Required")
- (412 . "Precondition Failed")
- (413 . "Request Entity Too Large")
- (414 . "Request-URI Too Long")
- (415 . "Unsupported Media Type")
- (416 . "Requested Range Not Satisfiable")
- (417 . "Expectation Failed")
- (418 . "I'm a teapot")
- (419 . "Authentication Timeout")
- (420 . "Method Failure")
- (420 . "Enhance Your Calm")
- (422 . "Unprocessable Entity")
- (423 . "Locked")
- (424 . "Failed Dependency")
- (424 . "Method Failure")
- (425 . "Unordered Collection")
- (426 . "Upgrade Required")
- (428 . "Precondition Required")
- (429 . "Too Many Requests")
- (431 . "Request Header Fields Too Large")
- (440 . "Login Timeout")
- (444 . "No Response")
- (449 . "Retry With")
- (450 . "Blocked by Windows Parental Controls")
- (451 . "Unavailable For Legal Reasons")
- (451 . "Redirect")
- (494 . "Request Header Too Large")
- (495 . "Cert Error")
- (496 . "No Cert")
- (497 . "HTTP to HTTPS")
- (499 . "Client Closed Request")
- (500 . "Internal Server Error")
- (501 . "Not Implemented")
- (502 . "Bad Gateway")
- (503 . "Service Unavailable")
- (504 . "Gateway Timeout")
- (505 . "HTTP Version Not Supported")
- (506 . "Variant Also Negotiates")
- (507 . "Insufficient Storage")
- (508 . "Loop Detected")
- (509 . "Bandwidth Limit Exceeded")
- (510 . "Not Extended")
- (511 . "Network Authentication Required")
- (520 . "Origin Error")
- (522 . "Connection timed out")
- (523 . "Proxy Declined Request")
- (524 . "A timeout occurred")
- (598 . "Network read timeout error")
- (599 . "Network connect timeout error"))
- "Possible HTML status codes with names.
-From http://en.wikipedia.org/wiki/List_of_HTTP_status_codes.")
-
-(provide 'web-server-status-codes)
-;;; web-server-status-codes.el ends here
diff --git a/packages/web-server/web-server-test.el
b/packages/web-server/web-server-test.el
deleted file mode 100644
index 5ec99b3..0000000
--- a/packages/web-server/web-server-test.el
+++ /dev/null
@@ -1,348 +0,0 @@
-;;; web-server-test.el --- Test the Emacs Web Server
-
-;; Copyright (C) 2013-2014 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte <schulte.eric@gmail.com>
-
-;; This software 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 software 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/>.
-
-;;; Code:
-(require 'web-server)
-(require 'cl-lib)
-(eval-when-compile (require 'cl))
-(require 'ert)
-
-(defvar ws-test-port 8999)
-
-(defun ws-test-curl-to-string (url &optional get-params post-params curl-flags)
- "Curl URL with optional parameters."
- (async-shell-command
- (format "curl -s -m 4 %s %s %s localhost:%s/%s"
- (or curl-flags "")
- (if get-params
- (mapconcat (lambda (p) (format "-d \"%s=%s\"" (car p) (cdr p)))
- get-params " ")
- "")
- (if post-params
- (mapconcat (lambda (p) (format "-F \"%s=%s\"" (car p) (cdr p)))
- post-params " ")
- "")
- ws-test-port url))
- (unwind-protect
- (with-current-buffer "*Async Shell Command*"
- (while (get-buffer-process (current-buffer)) (sit-for 0.1))
- (goto-char (point-min))
- (buffer-string))
- (kill-buffer "*Async Shell Command*")))
-
-(defmacro ws-test-with (handler &rest body)
- (declare (indent 1))
- (let ((srv (cl-gensym)))
- `(let* ((,srv (ws-start ,handler ws-test-port)))
- (unwind-protect (progn ,@body) (ws-stop ,srv)))))
-(def-edebug-spec ws-test-with (form body))
-
-(ert-deftest ws/keyword-style-handler ()
- "Ensure that a simple keyword-style handler matches correctly."
- (ws-test-with (mapcar (lambda (letter)
- `((:GET . ,letter) .
- (lambda (request)
- (ws-response-header (ws-process request) 200
- '("Content-type" . "text/plain"))
- (process-send-string (ws-process request)
- (concat "returned:" ,letter)))))
- '("a" "b"))
- (should (string= "returned:a" (ws-test-curl-to-string "a")))
- (should (string= "returned:b" (ws-test-curl-to-string "b")))))
-
-(ert-deftest ws/function-style-handler ()
- "Test that a simple hello-world server responds."
- (ws-test-with
- '(((lambda (_) t) .
- (lambda (request)
- (ws-response-header (ws-process request) 200
- '("Content-type" . "text/plain"))
- (process-send-string (ws-process request) "hello world"))))
- (should (string= (ws-test-curl-to-string "") "hello world"))))
-
-(ert-deftest ws/removed-from-ws-servers-after-stop ()
- (let ((start-length (length ws-servers)))
- (let ((server (ws-start nil ws-test-port)))
- (should (= (length ws-servers) (+ 1 start-length)))
- (ws-stop server)
- (should (= (length ws-servers) start-length)))))
-
-(ert-deftest ws/parse-many-headers ()
- "Test that a number of headers parse successfully."
- (let ((server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request)))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- "GET / HTTP/1.1
-Host: localhost:7777
-User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101
Firefox/26.0
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate
-DNT: 1
-Cookie: __utma=111872281.1462392269.1345929539.1345929539.1345929539.1
-Connection: keep-alive
-
-")
- (ws-parse-request request)
- (let ((headers (cdr (ws-headers request))))
- (should (string= (cdr (assoc :ACCEPT-ENCODING headers))
- "gzip, deflate"))
- (should (string= (cdr (assoc :GET headers)) "/"))
- (should (string= (cdr (assoc :CONNECTION headers)) "keep-alive"))))
- (ws-stop server))))
-
-(ert-deftest ws/parse-post-data ()
- (let ((server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request)))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- "POST / HTTP/1.1
-User-Agent: curl/7.33.0
-Host: localhost:8080
-Accept: */*
-Content-Length: 273
-Expect: 100-continue
-Content-Type: multipart/form-data; boundary=----------------f1270d0deb77af03
-
-------------------f1270d0deb77af03
-Content-Disposition: form-data; name=\"date\"
-
-Wed Dec 18 00:55:39 MST 2013
-
-------------------f1270d0deb77af03
-Content-Disposition: form-data; name=\"name\"
-
-\"schulte\"
-------------------f1270d0deb77af03--
-")
- (ws-parse-request request)
- (let ((headers (cdr (ws-headers request))))
- (should (string= (cdr (assoc 'content (cdr (assoc "name"
headers))))
- "\"schulte\""))
- (should (string= (cdr (assoc 'content (cdr (assoc "date"
headers))))
- "Wed Dec 18 00:55:39 MST 2013\n"))))
- (ws-stop server))))
-
-(ert-deftest ws/parse-another-post-data ()
- "This one from an AJAX request."
- (let ((server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request)))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- "POST /complex.org HTTP/1.1
-Host: localhost:4444
-User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101
Firefox/26.0
-Accept: */*
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate
-DNT: 1
-Content-Type: application/x-www-form-urlencoded; charset=UTF-8
-X-Requested-With: XMLHttpRequest
-Referer: http://localhost:4444/complex.org
-Content-Length: 78
-Cookie: __utma=111872281.1462392269.1345929539.1345929539.1345929539.1
-Connection: keep-alive
-Pragma: no-cache
-Cache-Control: no-cache
-
-org=-+one%0A-+two%0A-+three%0A-+four%0A%0A&beg=646&end=667&path=%2Fcomplex.org")
- (ws-parse-request request)
- (let ((headers (cdr (ws-headers request))))
- (should (string= (cdr (assoc "path" headers)) "/complex.org"))
- (should (string= (cdr (assoc "beg" headers)) "646"))
- (should (string= (cdr (assoc "end" headers)) "667"))
- (should (string= (cdr (assoc "org" headers))
- "- one
-- two
-- three
-- four
-
-"))
- (should (string= (cdr (assoc :CONTENT-TYPE headers))
- "application/x-www-form-urlencoded;
charset=UTF-8"))
- (should (string= (oref request body)
-
"org=-+one%0A-+two%0A-+three%0A-+four%0A%0A&beg=646&end=667&path=%2Fcomplex.org"))))
- (ws-stop server))))
-
-(ert-deftest ws/parse-json-data ()
- "Ensure we can send arbitrary data through to the handler
-
-The handler can then parse it itself."
- (let ((server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request)))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- "POST /complex.org HTTP/1.1
-Host: localhost:4444
-User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:26.0) Gecko/20100101
Firefox/26.0
-Accept: */*
-Accept-Language: en-US,en;q=0.5
-Accept-Encoding: gzip, deflate
-DNT: 1
-Content-Type: application/json
-Referer: http://localhost:4444/complex.org
-Content-Length: 33
-Cookie: __utma=111872281.1462392269.1345929539.1345929539.1345929539.1
-Connection: keep-alive
-Pragma: no-cache
-Cache-Control: no-cache
-
-{\"some example\": \"json data\"}")
- (ws-parse-request request)
- (let ((headers (cdr (ws-headers request))))
- (should (string= (cdr (assoc :CONTENT-TYPE headers))
- "application/json"))
- (should (string= (oref request body)
- "{\"some example\": \"json data\"}")))
- (ws-stop server)))))
-
-(ert-deftest ws/simple-post ()
- "Test a simple POST server."
- (ws-test-with
- '(((:POST . ".*") .
- (lambda (request)
- (with-slots (process headers) request
- (let ((message (cdr (assoc "message" headers))))
- (ws-response-header process 200
- '("Content-type" . "text/plain"))
- (process-send-string process
- (format "you said %S\n" (cdr (assoc 'content message)))))))))
- (should (string= (ws-test-curl-to-string "" nil '(("message" . "foo")))
- "you said \"foo\"\n"))))
-
-(ert-deftest ws/in-directory-p ()
- (mapc (lambda (pair)
- (let ((should-or-not (car pair))
- (dir (cdr pair)))
- (message "dir: %S" dir)
- (should
- (funcall (if should-or-not #'identity #'not)
- (ws-in-directory-p temporary-file-directory dir)))))
- `((nil . "foo/bar/../../../")
- (t . ,(concat
- "foo/bar/../../../"
- (file-name-nondirectory
- (directory-file-name temporary-file-directory))
- "/baz"))
- (t . "./")
- (nil . "/~/pics")
- (nil . "~/pics")
- (nil . "/pics")
- (nil . "../pics")
- (t . "pics")
- (nil . ".."))))
-
-(ert-deftest ws/parse-basic-authorization ()
- "Test that a number of headers parse successfully."
- (let* ((server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request))
- (username "foo") (password "bar"))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- (format "GET / HTTP/1.1
-Authorization: Basic %s
-Connection: keep-alive
-
-" (base64-encode-string (concat username ":" password))))
- (ws-parse-request request)
- (with-slots (headers) request
- (cl-tree-equal (cdr (assoc :AUTHORIZATION headers))
- (cons :BASIC (cons username password)))))
- (ws-stop server))))
-
-(ert-deftest ws/parse-large-file-upload ()
- "Test that `ws-parse-request' can handle at large file upload.
-At least when it comes in a single chunk."
- (let* ((long-string (mapconcat #'int-to-string (number-sequence 0 20000) "
"))
- (server (ws-start nil ws-test-port))
- (request (make-instance 'ws-request)))
- (unwind-protect
- (progn
- (setf (ws-pending request)
- (format "POST / HTTP/1.1
-User-Agent: curl/7.34.0
-Host: localhost:9008
-Accept: */*
-Content-Length: 9086
-Expect: 100-continue
-Content-Type: multipart/form-data; boundary=----------------e458fb665704290b
-
-------------------e458fb665704290b
-Content-Disposition: form-data; name=\"file\"; filename=\"-\"
-Content-Type: application/octet-stream
-
-%s
-------------------e458fb665704290b--
-
-" long-string))
- (ws-parse-request request)
- (should
- (string= long-string
- (cdr (assoc 'content
- (cdr (assoc "file" (ws-headers request))))))))
- (ws-stop server))))
-
-(ert-deftest ws/web-socket-handshake-rfc-example ()
- "Ensure that `ws-web-socket-handshake' conforms to the example in RFC6455."
- (should (string= (ws-web-socket-handshake "dGhlIHNhbXBsZSBub25jZQ==")
- "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")))
-
-(ert-deftest ws/web-socket-frame ()
- "Test WebSocket frame encoding for the different varint payload lengths:
- 0-125, 126-64k, 64k-2^64."
- (should (string= (ws-web-socket-frame "short") "\201short"))
- (should (string= (substring (ws-web-socket-frame (make-string 126 ?a))
- 0 5) "\201~ ~a"))
- (should (string= (substring (ws-web-socket-frame (make-string 65536 ?a))
- 0 11) "\201 a")))
-
-(ert-deftest ws/simple-chunked ()
- "Test a simple server using chunked transfer encoding."
- (ws-test-with
- (lambda (request)
- (with-slots (process) request
- (ws-response-header process 200
- '("Content-type" . "text/plain")
- '("Transfer-Encoding" . "chunked"))
- (ws-send process "I am chunked")))
- (should (string= (ws-test-curl-to-string "") "I am chunked"))))
-
-(ert-deftest ws/simple-gzip ()
- "Test a simple server using gzip content/transfer encoding."
- (cl-macrolet ((gzipper (header)
- `(ws-test-with
- (lambda (request)
- (with-slots (process) request
- (ws-response-header process 200
- '("Content-type" . "text/plain")
- '(,header . "gzip"))
- (ws-send process "I am zipped")))
- (should (string= (ws-test-curl-to-string
- "" nil nil "--compressed")
- "I am zipped")))))
- (gzipper "Content-Encoding")
- (gzipper "Transfer-Encoding")))
-
-(provide 'web-server-test)
diff --git a/packages/web-server/web-server.el
b/packages/web-server/web-server.el
deleted file mode 100644
index f2693fc..0000000
--- a/packages/web-server/web-server.el
+++ /dev/null
@@ -1,744 +0,0 @@
-;;; web-server.el --- Emacs Web Server -*- lexical-binding:t -*-
-
-;; Copyright (C) 2013-2020 Free Software Foundation, Inc.
-
-;; Author: Eric Schulte <schulte.eric@gmail.com>
-;; Maintainer: Eric Schulte <schulte.eric@gmail.com>
-;; Version: 0.1.2
-;; Package-Requires: ((emacs "24.3"))
-;; Keywords: http, server, network
-;; URL: https://github.com/eschulte/emacs-web-server
-
-;; This software 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 software 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:
-
-;; A web server in Emacs running handlers written in Emacs Lisp.
-;;
-;; Full support for GET and POST requests including URL-encoded
-;; parameters and multipart/form data. Supports web sockets.
-;;
-;; See the examples/ directory for examples demonstrating the usage of
-;; the Emacs Web Server. The following launches a simple "hello
-;; world" server.
-;;
-;; (ws-start
-;; '(((lambda (_) t) . ; match every request
-;; (lambda (request) ; reply with "hello world"
-;; (with-slots (process) request
-;; (ws-response-header process 200 '("Content-type" .
"text/plain"))
-;; (process-send-string process "hello world")))))
-;; 9000)
-
-;;; Code:
-(require 'web-server-status-codes)
-(require 'mail-parse) ; to parse multipart data in headers
-(require 'mm-encode) ; to look-up mime types for files
-(require 'url-util) ; to decode url-encoded params
-(require 'eieio)
-(require 'cl-lib)
-
-(defclass ws-server ()
- ((handlers :initarg :handlers :accessor ws-handlers :initform nil)
- (process :initarg :process :accessor ws-process :initform nil)
- (port :initarg :port :accessor ws-port :initform nil)
- (requests :initarg :requests :accessor ws-requests :initform nil)))
-
-(defclass ws-request ()
- ((process :initarg :process :accessor ws-process :initform nil)
- (pending :initarg :pending :accessor ws-pending :initform "")
- (context :initarg :context :accessor ws-context :initform nil)
- (boundary :initarg :boundary :accessor ws-boundary :initform nil)
- (index :initarg :index :accessor ws-index :initform 0)
- (active :initarg :active :accessor ws-active :initform nil)
- (headers :initarg :headers :accessor ws-headers :initform (list nil))
- (body :initarg :body :accessor ws-body :initform "")))
-
-(defvar ws-servers nil
- "List holding all web servers.")
-
-(defvar ws-log-time-format "%Y.%m.%d.%H.%M.%S.%N"
- "Logging time format passed to `format-time-string'.")
-
-(defvar ws-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
- "This GUID is defined in RFC6455.")
-
-;;;###autoload
-(defun ws-start (handlers port &optional log-buffer &rest network-args)
- "Start a server using HANDLERS and return the server object.
-
-HANDLERS may be a single function (which is then called on every
-request) or a list of conses of the form (MATCHER . FUNCTION),
-where the FUNCTION associated with the first successful MATCHER
-is called. Handler functions are called with two arguments, the
-process and the request object.
-
-A MATCHER may be either a function (in which case it is called on
-the request object) or a cons cell of the form (KEYWORD . STRING)
-in which case STRING is matched against the value of the header
-specified by KEYWORD.
-
-Any supplied NETWORK-ARGS are assumed to be keyword arguments for
-`make-network-process' to which they are passed directly.
-
-For example, the following starts a simple hello-world server on
-port 8080.
-
- (ws-start
- (lambda (request)
- (with-slots (process headers) request
- (process-send-string process
- \"HTTP/1.1 200 OK\\r\\nContent-Type: text/plain\\r\\n\\r\\nhello
world\")))
- 8080)
-
-Equivalently, the following starts an identical server using a
-function MATCH and the `ws-response-header' convenience
-function.
-
- (ws-start
- \\='(((lambda (_) t) .
- (lambda (proc request)
- (ws-response-header proc 200 \\='(\"Content-type\" . \"text/plain\"))
- (process-send-string proc \"hello world\")
- t)))
- 8080)
-
-"
- (let ((server (make-instance 'ws-server :handlers handlers :port port))
- (log (when log-buffer (get-buffer-create log-buffer))))
- (setf (ws-process server)
- (apply
- #'make-network-process
- :name "ws-server"
- :service (ws-port server)
- :filter #'ws-filter
- :server t
- :nowait (< emacs-major-version 26)
- :family 'ipv4
- :coding 'no-conversion
- :plist (append (list :server server)
- (when log (list :log-buffer log)))
- :log (when log
- (lambda (proc request message)
- (let ((c (process-contact request))
- (buf (plist-get (process-plist proc) :log-buffer)))
- (with-current-buffer buf
- (goto-char (point-max))
- (insert (format "%s\t%s\t%s\t%s"
- (format-time-string ws-log-time-format)
- (cl-first c) (cl-second c)
message))))))
- network-args))
- (push server ws-servers)
- server))
-
-(defun ws-stop (server)
- "Stop SERVER."
- (setq ws-servers (remove server ws-servers))
- (mapc #'delete-process (append (mapcar #'ws-process (ws-requests server))
- (list (ws-process server)))))
-
-(defun ws-stop-all ()
- "Stop all servers in `ws-servers'."
- (interactive)
- (mapc #'ws-stop ws-servers))
-
-(defvar ws-http-common-methods '(GET HEAD POST PUT DELETE TRACE)
- "HTTP methods from http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.")
-
-(defvar ws-http-method-rx
- (format "^\\(%s\\) \\([^[:space:]]+\\) \\([^[:space:]]+\\)$"
- (mapconcat #'symbol-name ws-http-common-methods "\\|")))
-
-(defun ws-parse-query-string (string)
- "Thin wrapper around `url-parse-query-string'."
- (mapcar (lambda (pair) (cons (cl-first pair) (cl-second pair)))
- (url-parse-query-string string nil 'allow-newlines)))
-
-(defun ws-parse (proc string)
- "Parse HTTP headers in STRING reporting errors to PROC."
- (cl-flet ((to-keyword (s) (intern (concat ":" (upcase s)))))
- (cond
- ;; Method
- ((string-match ws-http-method-rx string)
- (let ((method (to-keyword (match-string 1 string)))
- (url (match-string 2 string)))
- (if (string-match "?" url)
- (cons (cons method (substring url 0 (match-beginning 0)))
- (ws-parse-query-string
- (url-unhex-string (substring url (match-end 0)))))
- (list (cons method url)))))
- ;; Authorization
- ((string-match "^AUTHORIZATION: \\([^[:space:]]+\\) \\(.*\\)$" string)
- (let ((protocol (to-keyword (match-string 1 string)))
- (credentials (match-string 2 string)))
- (list (cons :AUTHORIZATION
- (cons protocol
- (cl-case protocol
- (:BASIC
- (let ((cred (base64-decode-string credentials)))
- (if (string-match ":" cred)
- (cons (substring cred 0 (match-beginning 0))
- (substring cred (match-end 0)))
- (ws-error proc "bad credentials: %S" cred))))
- (t (ws-error proc "un-support protocol: %s"
- protocol))))))))
- ;; All other headers
- ((string-match "^\\([^[:space:]]+\\): \\(.*\\)$" string)
- (list (cons (to-keyword (match-string 1 string))
- (match-string 2 string))))
- (:otherwise (ws-error proc "bad header: %S" string) nil))))
-
-(defun ws-trim (string)
- (while (and (> (length string) 0)
- (or (and (string-match "[\r\n]" (substring string -1))
- (setq string (substring string 0 -1)))
- (and (string-match "[\r\n]" (substring string 0 1))
- (setq string (substring string 1))))))
- string)
-
-(defun ws-parse-multipart/form (proc string)
- ;; ignore empty and non-content blocks
- (when (string-match "Content-Disposition:[[:space:]]*\\(.*\\)\r\n" string)
- (let ((dp (cdr (mail-header-parse-content-disposition
- (match-string 1 string))))
- (last-index (match-end 0))
- index)
- ;; every line up until the double \r\n is a header
- (while (and (setq index (string-match "\r\n" string last-index))
- (not (= index last-index)))
- (setcdr (last dp) (ws-parse proc (substring string last-index index)))
- (setq last-index (+ 2 index)))
- ;; after double \r\n is all content
- (cons (cdr (assoc 'name dp))
- (cons (cons 'content (substring string (+ 2 last-index)))
- dp)))))
-
-(defun ws-filter (proc string)
- (with-slots (handlers requests) (plist-get (process-plist proc) :server)
- (unless (cl-find-if (lambda (c) (equal proc (ws-process c))) requests)
- (push (make-instance 'ws-request :process proc) requests))
- (let ((request (cl-find-if (lambda (c) (equal proc (ws-process c)))
requests)))
- (with-slots (pending) request (setq pending (concat pending string)))
- (unless (ws-active request) ; don't re-start if request is being parsed
- (setf (ws-active request) t)
- (when (not (eq (catch 'close-connection
- (if (ws-parse-request request)
- (ws-call-handler request handlers)
- :keep-alive))
- :keep-alive))
- ;; Properly shut down processes requiring an ending (e.g., chunked)
- (let ((ender (plist-get (process-plist proc) :ender)))
- (when ender (process-send-string proc ender)))
- (setq requests (cl-remove-if (lambda (r) (eql proc (ws-process r)))
requests))
- (delete-process proc))))))
-
-(defun ws-parse-request (request)
- "Parse request STRING from REQUEST with process PROC.
-Return non-nil only when parsing is complete."
- (catch 'finished-parsing-headers
- (with-slots (process pending context boundary headers body index) request
- (let ((delimiter (concat "\r\n" (if boundary (concat "--" boundary) "")))
- ;; Track progress through string, always work with the
- ;; section of string between INDEX and NEXT-INDEX.
- next-index
- body-stored)
- ;; parse headers and append to request
- (while (setq next-index (string-match delimiter pending index))
- (let ((tmp (+ next-index (length delimiter))))
- (if (= index next-index) ; double \r\n ends current run of headers
- (progn
- ;; Store the body
- (unless
- ;; Multipart form data has multiple passes - store on
- ;; first pass only.
- body-stored
- (let ((after-headers (substring pending index)))
- (when (string-prefix-p "\r\n" after-headers)
- (setq body
- ;; Trim off the additional CRLF
- (substring after-headers 2))))
- (setq body-stored t))
- (cl-case context
- ;; Parse URL data.
- ;; http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4
- (application/x-www-form-urlencoded
- (mapc (lambda (pair) (setcdr (last headers) (list pair)))
- (ws-parse-query-string
- (replace-regexp-in-string
- "\\+" " "
- (ws-trim (substring pending index)))))
- (throw 'finished-parsing-headers t))
- ;; Set custom delimiter for multipart form data.
- (multipart/form-data
- (setq delimiter (concat "\r\n--" boundary)))
- ;; No special context so we're done.
- (t (throw 'finished-parsing-headers t))))
- (if (eql context 'multipart/form-data)
- (progn
- (setcdr (last headers)
- (list (ws-parse-multipart/form process
- (substring pending index next-index))))
- ;; Boundary suffixed by "--" indicates end of the headers.
- (when (and (> (length pending) (+ tmp 2))
- (string= (substring pending tmp (+ tmp 2))
"--"))
- (throw 'finished-parsing-headers t)))
- ;; Standard header parsing.
- (let ((header (ws-parse process (substring pending
- index next-index))))
- ;; Content-Type indicates that the next double \r\n
- ;; will be followed by a special type of content which
- ;; will require special parsing. Thus we will note
- ;; the type in the CONTEXT variable for parsing
- ;; dispatch above.
- (when (and (caar header) (eql (caar header) :CONTENT-TYPE))
- (cl-destructuring-bind (type &rest data)
- (mail-header-parse-content-type (cdar header))
- (setq boundary (cdr (assoc 'boundary data)))
- (setq context (intern (downcase type)))))
- ;; All other headers are collected directly.
- (setcdr (last headers) header))))
- (setq index tmp)))))
- (setf (ws-active request) nil)
- nil))
-
-(defun ws-call-handler (request handlers)
- (catch 'matched-handler
- (when (functionp handlers)
- (throw 'matched-handler
- (condition-case e (funcall handlers request)
- (error (ws-error (ws-process request) "Caught Error: %S" e)))))
- (mapc (lambda (handler)
- (let ((match (car handler))
- (function (cdr handler)))
- (when (or (and (consp match)
- (assoc (car match) (ws-headers request))
- (string-match (cdr match)
- (cdr (assoc (car match)
- (ws-headers request)))))
- (and (functionp match) (funcall match request)))
- (throw 'matched-handler
- (condition-case e (funcall function request)
- (error (ws-error (ws-process request)
- "Caught Error: %S" e)))))))
- handlers)
- (ws-error (ws-process request) "no handler matched request: %S"
- (ws-headers request))))
-
-(defun ws-error (proc msg &rest args)
- (let ((buf (plist-get (process-plist proc) :log-buffer))
- (c (process-contact proc)))
- (when buf
- (with-current-buffer buf
- (goto-char (point-max))
- (insert (format "%s\t%s\t%s\tWS-ERROR: %s"
- (format-time-string ws-log-time-format)
- (cl-first c) (cl-second c)
- (apply #'format msg args)))))
- (apply #'ws-send-500 proc msg args)))
-
-
-;;; Web Socket
-;; Implement to conform to http://tools.ietf.org/html/rfc6455.
-
-;; The `ws-message' object is used to hold state across multiple calls
-;; of the process filter on the websocket network process. The fields
-;; play the following roles.
-;; process ------ holds the process itself, used for communication
-;; pending ------ holds text received from the client but not yet parsed
-;; active ------- indicates that parsing is active to avoid re-entry
-;; of the `ws-web-socket-parse-messages' function
-;; new ---------- indicates that new text was received during parsing
-;; and causes `ws-web-socket-parse-messages' to be
-;; called again after it terminates
-;; data --------- holds the data of parsed messages
-;; handler ------ holds the user-supplied function used called on the
-;; data of parsed messages
-(defclass ws-message () ; web socket message object
- ((process :initarg :process :accessor ws-process :initform "")
- (pending :initarg :pending :accessor ws-pending :initform "")
- (active :initarg :active :accessor ws-active :initform nil)
- (new :initarg :new :accessor ws-new :initform nil)
- (data :initarg :data :accessor ws-data :initform "")
- (handler :initarg :handler :accessor ws-handler :initform "")))
-
-(defun ws-web-socket-connect (request handler)
- "Establish a web socket connection with request.
-If the connection is successful this function will throw
-`:keep-alive' to `close-connection' skipping any remaining code
-in the request handler. If no web-socket connection is
-established (e.g., because REQUEST is not attempting to establish
-a connection) then no actions are taken and nil is returned.
-
-Second argument HANDLER should be a function of one argument
-which will be called on all complete messages as they are
-received and parsed from the network."
- (with-slots (process headers) request
- (when (assoc :SEC-WEBSOCKET-KEY headers)
- ;; Accept the connection
- (ws-response-header process 101
- (cons "Upgrade" "websocket")
- (cons "Connection" "upgrade")
- (cons "Sec-WebSocket-Accept"
- (ws-web-socket-handshake
- (cdr (assoc :SEC-WEBSOCKET-KEY headers)))))
- ;; Setup the process filter
- (set-process-coding-system process 'binary)
- (set-process-plist
- process (list :message (make-instance 'ws-message
- :handler handler :process process)))
- (set-process-filter process #'ws-web-socket-filter)
- process)))
-
-(defun ws-web-socket-filter (process string)
- (let ((message (plist-get (process-plist process) :message)))
- (if (ws-active message) ; don't re-start if message is being parsed
- (setf (ws-new message) string)
- (setf (ws-pending message) (concat (ws-pending message) string))
- (setf (ws-active message) t)
- (ws-web-socket-parse-messages message))
- (setf (ws-active message) nil)))
-
-(defun ws-web-socket-mask (masking-key data)
- (let ((masking-data (apply #'concat (make-list (+ 1 (/ (length data) 4))
- masking-key))))
- (apply #'string (cl-mapcar #'logxor masking-data data))))
-
-;; Binary framing protocol
-;; from http://tools.ietf.org/html/rfc6455#section-5.2
-;;
-;; 0 1 2 3
-;; 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-;; +-+-+-+-+-------+-+-------------+-------------------------------+
-;; |F|R|R|R| opcode|M| Payload len | Extended payload length |
-;; |I|S|S|S| (4) |A| (7) | (16/64) |
-;; |N|V|V|V| |S| | (if payload len==126/127) |
-;; | |1|2|3| |K| | |
-;; +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
-;; | Extended payload length continued, if payload len == 127 |
-;; + - - - - - - - - - - - - - - - +-------------------------------+
-;; | |Masking-key, if MASK set to 1 |
-;; +-------------------------------+-------------------------------+
-;; | Masking-key (continued) | Payload Data |
-;; +-------------------------------- - - - - - - - - - - - - - - - +
-;; : Payload Data continued ... :
-;; + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
-;; | Payload Data continued ... |
-;; +---------------------------------------------------------------+
-;;
-(defun ws-web-socket-parse-messages (message)
- "Web socket filter to pass whole frames to the client.
-See RFC6455."
- (with-slots (process active pending data handler new) message
- (let ((index 0))
- (cl-labels ((int-to-bits (int size)
- (let ((result (make-bool-vector size nil)))
- (mapc (lambda (place)
- (let ((val (expt 2 place)))
- (when (>= int val)
- (setq int (- int val))
- (aset result place t))))
- (reverse (number-sequence 0 (- size 1))))
- (reverse (append result nil))))
- (bits-to-int (bits)
- (let ((place 0))
- (apply #'+
- (mapcar (lambda (bit)
- (prog1 (if bit (expt 2 place) 0) (cl-incf
place)))
- (reverse bits)))))
- (bits (length)
- (apply #'append
- (mapcar (lambda (int) (int-to-bits int 8))
- (cl-subseq
- pending index (cl-incf index length))))))
- (let (fin rsvs opcode mask pl mask-key)
- ;; Parse fin bit, rsvs bits and opcode
- (let ((byte (bits 1)))
- (setq fin (car byte)
- rsvs (cl-subseq byte 1 4)
- opcode
- (let ((it (bits-to-int (cl-subseq byte 4))))
- (cl-case it
- (0 :CONTINUATION)
- (1 :TEXT)
- (2 :BINARY)
- ((3 4 5 6 7) :NON-CONTROL)
- (8 :CLOSE)
- (9 :PING)
- (10 :PONG)
- ((11 12 13 14 15) :CONTROL)
- ;; If an unknown opcode is received, the receiving
- ;; endpoint MUST _Fail the WebSocket Connection_.
- (t (ws-error process
- "Web Socket Fail: bad opcode %d" it))))))
- (unless (cl-every #'null rsvs)
- ;; MUST be 0 unless an extension is negotiated that defines
- ;; meanings for non-zero values.
- (ws-error process "Web Socket Fail: non-zero RSV 1 2 or 3"))
- ;; Parse mask and payload length
- (let ((byte (bits 1)))
- (setq mask (car byte)
- pl (bits-to-int (cl-subseq byte 1))))
- (unless (eq mask t)
- ;; All frames sent from client to server have this bit set to 1.
- (ws-error process "Web Socket Fail: client must mask data"))
- (cond
- ((= pl 126) (setq pl (bits-to-int (bits 2))))
- ((= pl 127) (setq pl (bits-to-int (bits 8)))))
- ;; unmask data
- (when mask
- (setq mask-key (cl-subseq pending index (cl-incf index 4))))
- (setq data (concat data
- (ws-web-socket-mask
- mask-key (cl-subseq pending index (+ index
pl)))))
- (if fin
- ;; wipe the message state and call the handler
- (let ((it data))
- (setq data "" active nil pending "" new nil)
- ;; close on a close frame, otherwise call the handler
- (if (not (eql opcode :CLOSE))
- (funcall handler process it)
- (process-send-string process
- (unibyte-string (logior (lsh 1 7) 8) 0))))
- ;; add any remaining un-parsed network data to pending
- (when (< (+ index pl) (length pending))
- (setq pending (substring pending (+ index pl)))))))
- ;; possibly re-parse any pending input
- (when (ws-new message) (ws-web-socket-parse-messages message)))))
-
-(defun ws-web-socket-frame (string &optional opcode)
- "Frame STRING for web socket communication."
- (let* ((fin 1) ;; set to 0 if not final frame
- (len (length string))
- (opcode (cl-ecase (or opcode :TEXT) (:TEXT 1) (:BINARY 2))))
- ;; Does not do any masking which is only required of client communication
- (concat
- (cond
- ((< len 126) (unibyte-string (logior (lsh fin 7) opcode) len))
- ((< len 65536) (unibyte-string (logior (lsh fin 7) opcode) 126
- ;; extended 16-bit length
- (logand (lsh len -8) 255)
- (logand len 255)))
- (t (unibyte-string (logior (lsh fin 7) opcode) 127
- ;; more extended 64-bit length
- (logand (lsh len -56) 255)
- (logand (lsh len -48) 255)
- (logand (lsh len -40) 255)
- (logand (lsh len -32) 255)
- (logand (lsh len -24) 255)
- (logand (lsh len -16) 255)
- (logand (lsh len -8) 255)
- (logand len 255))))
- string)))
-
-
-;;; Content and Transfer encoding support
-(defvar ws-compress-cmd "compress"
- "Command used for the \"compress\" Content or Transfer coding.")
-
-(defvar ws-deflate-cmd "zlib-flate -compress"
- "Command used for the \"deflate\" Content or Transfer coding.")
-
-(defvar ws-gzip-cmd "gzip"
- "Command used for the \"gzip\" Content or Transfer coding.")
-
-(defmacro ws-encoding-cmd-to-fn (cmd)
- "Return a function which applies CMD to strings."
- `(lambda (s)
- (with-temp-buffer
- (insert s)
- (shell-command-on-region (point-min) (point-max) ,cmd nil 'replace)
- (buffer-string))))
-
-(defun ws-chunk (string)
- "Convert STRING to a valid chunk for HTTP chunked Transfer-encoding."
- (format "%x\r\n%s\r\n" (string-bytes string) string))
-
-
-;;; Convenience functions to write responses
-(defun ws-response-header (proc code &rest headers)
- "Send the headers for an HTTP response to PROC.
-CODE should be an HTTP status code, see `ws-status-codes' for a
-list of known codes.
-
-When \"Content-Encoding\" or \"Transfer-Encoding\" headers are
-supplied any subsequent data written to PROC using `ws-send' will
-be encoded appropriately including sending the appropriate data
-upon the end of transmission for chunked transfer encoding.
-
-For example with the header (\"Content-Encoding\" . \"gzip\"),
-any data subsequently written to PROC using `ws-send' will be
-compressed using the command specified in `ws-gzip-cmd'."
- ;; update process to reflect any Content or Transfer encodings
- (let ((content (cdr (assoc "Content-Encoding" headers)))
- (transfer (cdr (assoc "Transfer-Encoding" headers))))
- (when content
- (set-process-plist proc
- (append
- (list :content-encoding
- (cl-ecase (intern content)
- ((compress x-compress) (ws-encoding-cmd-to-fn
ws-compress-cmd))
- ((deflate x-deflate) (ws-encoding-cmd-to-fn ws-deflate-cmd))
- ((gzip x-gzip) (ws-encoding-cmd-to-fn ws-gzip-cmd))
- (identity #'identity)
- ((exi pack200-zip)
- (ws-error proc "`%s' Content-encoding not supported."
- content))))
- (process-plist proc))))
- (when transfer
- (set-process-plist proc
- (append
- (when (string= transfer "chunked") (list :ender "0\r\n\r\n"))
- (list :transfer-encoding
- (cl-ecase (intern transfer)
- (chunked #'ws-chunk)
- ((compress x-compress) (ws-encoding-cmd-to-fn
ws-compress-cmd))
- ((deflate x-deflate) (ws-encoding-cmd-to-fn ws-deflate-cmd))
- ((gzip x-gzip) (ws-encoding-cmd-to-fn ws-gzip-cmd))))
- (process-plist proc)))))
- (let ((headers
- (cons
- (format "HTTP/1.1 %d %s" code (cdr (assoc code ws-status-codes)))
- (mapcar (lambda (h) (format "%s: %s" (car h) (cdr h))) headers))))
- (setcdr (last headers) (list "" ""))
- (process-send-string proc (mapconcat #'identity headers "\r\n"))))
-
-(defun ws-send (proc string)
- "Send STRING to process PROC.
-If any Content or Transfer encodings are in use, apply them to
-STRING before sending."
- (let
- ((cc (or (plist-get (process-plist proc) :content-encoding) #'identity))
- (tc (or (plist-get (process-plist proc) :transfer-encoding)
#'identity)))
- (process-send-string proc (funcall tc (funcall cc string)))))
-
-(defun ws-send-500 (proc &rest msg-and-args)
- "Send 500 \"Internal Server Error\" to PROC with an optional message."
- (ws-response-header proc 500
- '("Content-type" . "text/plain"))
- (process-send-string proc (if msg-and-args
- (apply #'format msg-and-args)
- "500 Internal Server Error"))
- (throw 'close-connection nil))
-
-(defun ws-send-404 (proc &rest msg-and-args)
- "Send 404 \"Not Found\" to PROC with an optional message."
- (ws-response-header proc 404
- '("Content-type" . "text/plain"))
- (process-send-string proc (if msg-and-args
- (apply #'format msg-and-args)
- "404 Not Found"))
- (throw 'close-connection nil))
-
-(defun ws-send-file (proc path &optional mime-type)
- "Send PATH to PROC.
-Optionally explicitly set MIME-TYPE, otherwise it is guessed by
-`mm-default-file-encoding'."
- (let ((mime (or mime-type
- (mm-default-file-encoding path)
- "application/octet-stream")))
- (process-send-string proc
- (with-temp-buffer
- (insert-file-contents-literally path)
- (ws-response-header proc 200
- (cons "Content-type" mime)
- (cons "Content-length" (- (point-max) (point-min))))
- (buffer-string)))))
-
-(defun ws-send-directory-list (proc directory &optional match)
- "Send a listing of files in DIRECTORY to PROC.
-Optional argument MATCH is passed to `directory-files' and may be
-used to limit the files sent."
- (ws-response-header proc 200 (cons "Content-type" "text/html"))
- (process-send-string proc
- (concat "<ul>"
- (mapconcat (lambda (f)
- (let* ((full (expand-file-name f directory))
- (end (if (file-directory-p full) "/" ""))
- (url (url-encode-url (concat f end))))
- (format "<li><a href=%s>%s</li>" url f)))
- (directory-files directory nil match)
- "\n")
- "</ul>")))
-
-(defun ws-in-directory-p (parent path)
- "Check if PATH is under the PARENT directory.
-If so return PATH, if not return nil. Note: the PARENT directory
-must be full expanded as with `expand-file-name' and should not
-contain e.g., \"~\" for a user home directory."
- (if (zerop (length path))
- parent
- (let ((expanded (expand-file-name path parent)))
- (and (>= (length expanded) (length parent))
- (string= parent (substring expanded 0 (length parent)))
- expanded))))
-
-(defun ws-with-authentication (handler credentials
- &optional realm unauth invalid)
- "Return a version of HANDLER protected by CREDENTIALS.
-HANDLER should be a function as passed to `ws-start', and
-CREDENTIALS should be an alist of elements of the form (USERNAME
-. PASSWORD).
-
-Optional argument REALM sets the realm in the authentication
-challenge. Optional arguments UNAUTH and INVALID should be
-functions which are called on the request when no authentication
-information, or invalid authentication information are provided
-respectively."
- (lambda (request)
- (with-slots (process headers) request
- (let ((auth (cddr (assoc :AUTHORIZATION headers))))
- (cond
- ;; no authentication information provided
- ((not auth)
- (if unauth
- (funcall unauth request)
- (ws-response-header process 401
- (cons "WWW-Authenticate"
- (format "Basic realm=%S" (or realm
"restricted")))
- '("Content-type" . "text/plain"))
- (process-send-string process "authentication required")))
- ;; valid authentication information
- ((string= (cdr auth) (cdr (assoc (car auth) credentials)))
- (funcall handler request))
- ;; invalid authentication information
- (t
- (if invalid
- (funcall invalid request)
- (ws-response-header process 403 '("Content-type" . "text/plain"))
- (process-send-string process "invalid credentials"))))))))
-
-(defun ws-web-socket-handshake (key)
- "Perform the handshake defined in RFC6455."
- (base64-encode-string (sha1 (concat (ws-trim key) ws-guid) nil nil 'binary)))
-
-;;; Enable the old accessors without the `ws-' namespace as obsolete.
-;;; Lets plan to remove these within a year of the date they were
-;;; marked obsolete, so that would be roughly 2021-03-12.
-(define-obsolete-function-alias 'active #'ws-active "2020-03-12")
-(define-obsolete-function-alias 'body #'ws-body "2020-03-12")
-(define-obsolete-function-alias 'boundary #'ws-boundary "2020-03-12")
-(define-obsolete-function-alias 'context #'ws-context "2020-03-12")
-(define-obsolete-function-alias 'data #'ws-data "2020-03-12")
-(define-obsolete-function-alias 'handler #'ws-handler "2020-03-12")
-(define-obsolete-function-alias 'handlers #'ws-handlers "2020-03-12")
-(define-obsolete-function-alias 'headers #'ws-headers "2020-03-12")
-(define-obsolete-function-alias 'index #'ws-index "2020-03-12")
-(define-obsolete-function-alias 'new #'ws-new "2020-03-12")
-(define-obsolete-function-alias 'pending #'ws-pending "2020-03-12")
-(define-obsolete-function-alias 'port #'ws-port "2020-03-12")
-(define-obsolete-function-alias 'process #'ws-process "2020-03-12")
-(define-obsolete-function-alias 'requests #'ws-requests "2020-03-12")
-
-(provide 'web-server)
-;;; web-server.el ends here
diff --git a/packages/websocket/COPYING b/packages/websocket/COPYING
deleted file mode 100644
index ecbc059..0000000
--- a/packages/websocket/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) 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
-this service 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 make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. 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.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-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
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the 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 a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE 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.
-
- 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
-convey 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 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.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision 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, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This 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.
\ No newline at end of file
diff --git a/packages/websocket/README.org b/packages/websocket/README.org
deleted file mode 100644
index db5abba..0000000
--- a/packages/websocket/README.org
+++ /dev/null
@@ -1,35 +0,0 @@
-* Description
-This is a elisp library for websocket clients to talk to websocket
-servers, and for websocket servers to accept connections from
-websocket clients. This library is designed to be used by other
-library writers, to write apps that use websockets, and is not useful
-by itself.
-
-An example of how to use the library is in the
-[[https://github.com/ahyatt/emacs-websocket/blob/master/websocket-functional-test.el][websocket-functional-test.el]]
file.
-
-This library is compatible with emacs 23 and 24, although only emacs
-24 support secure websockets.
-
-NOTE: Due to FSF attribution restrictions, ERT tests are only not
-present in the emacs ELPA repository. They can only be found in the
-github repository at https://github.com/ahyatt/emacs-websocket/.
-
-* Version release checklist
-
-Each version that is released should be checked with this checklist:
-
-- [ ] All ert test passing (see note above on ERT tests)
-- [ ] Functional test passing on emacs 23 and 24
-- [ ] websocket.el byte compiling cleanly.
-
-* Existing clients:
-
-- [[https://github.com/tkf/emacs-ipython-notebook][Emacs IPython Notebook]]
-- [[https://github.com/syohex/emacs-realtime-markdown-viewer][Emacs Realtime
Markdown Viewer]]
-- [[https://github.com/jscheid/kite][Kite]]
-
-If you are using this module for your own emacs package, please let me
-know by editing this file, adding your project, and sending a pull
-request to this repository.
-
diff --git a/packages/websocket/testserver.py b/packages/websocket/testserver.py
deleted file mode 100644
index 5cfcb96..0000000
--- a/packages/websocket/testserver.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import logging
-import tornado
-import tornado.web
-from tornado import httpserver
-from tornado import ioloop
-from tornado import websocket
-
-
-class EchoWebSocket(websocket.WebSocketHandler):
-
- def open(self):
- logging.info("OPEN")
-
- def on_message(self, message):
- logging.info(u"ON_MESSAGE: {0}".format(message))
- self.write_message(u"You said: {0}".format(message))
-
- def on_close(self):
- logging.info("ON_CLOSE")
-
- def allow_draft76(self):
- return False
-
-
-if __name__ == "__main__":
- import tornado.options
- tornado.options.parse_command_line()
- application = tornado.web.Application([
- (r"/", EchoWebSocket),
- ])
- server = httpserver.HTTPServer(application)
- server.listen(9999)
- logging.info("STARTED: Server start listening")
- ioloop.IOLoop.instance().start()
diff --git a/packages/websocket/websocket-functional-test.el
b/packages/websocket/websocket-functional-test.el
deleted file mode 100644
index cc9ac70..0000000
--- a/packages/websocket/websocket-functional-test.el
+++ /dev/null
@@ -1,163 +0,0 @@
-;;; websocket-functional-test.el --- Simple functional testing
-
-;; Copyright (c) 2013, 2016 Free Software Foundation, Inc.
-
-;; 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. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; Usage: emacs -batch -Q -L . -l websocket-functional-test.el
-;;
-;; Note: this functional tests requires that you have python with the
-;; Tornado web server. See http://www.tornadoweb.org/en/stable/ for
-;; information on aquiring.
-
-(require 'tls) ;; tests a particular bug we had on emacs 23
-(setq debug-on-error t)
-(require 'websocket)
-(eval-when-compile (require 'cl))
-
-;;;;;;;;;;;;;;;;;;;;;;;
-;; Local server test ;;
-;;;;;;;;;;;;;;;;;;;;;;;
-
-(message "Testing with local server")
-
-(setq websocket-debug t)
-
-(defvar wstest-server-buffer (get-buffer-create "*wstest-server*"))
-(defvar wstest-server-name "wstest-server")
-(defvar wstest-server-proc
- (start-process wstest-server-name wstest-server-buffer
- "python" "testserver.py" "--log_to_stderr" "--logging=debug"))
-(sleep-for 1)
-
-(defvar wstest-msgs nil)
-(defvar wstest-closed nil)
-
-(message "Opening the websocket")
-
-(defvar wstest-ws
- (websocket-open
- "ws://127.0.0.1:9999"
- :on-message (lambda (_websocket frame)
- (push (websocket-frame-text frame) wstest-msgs)
- (message "ws frame: %S" (websocket-frame-text frame))
- (error "Test error (expected)"))
- :on-close (lambda (_websocket) (setq wstest-closed t))))
-
-(defun wstest-pop-to-debug ()
- "Open websocket log buffer. Not used in testing. Just for debugging."
- (interactive)
- (pop-to-buffer (websocket-get-debug-buffer-create wstest-ws)))
-
-(sleep-for 0.1)
-(assert (websocket-openp wstest-ws))
-
-(assert (null wstest-msgs))
-
-(websocket-send-text wstest-ws "你好")
-
-(sleep-for 0.1)
-(assert (equal (car wstest-msgs) "You said: 你好"))
-(setf (websocket-on-error wstest-ws) (lambda (_ws _type _err)))
-(websocket-send-text wstest-ws "Hi after error!")
-(sleep-for 0.1)
-(assert (equal (car wstest-msgs) "You said: Hi after error!"))
-
-(websocket-close wstest-ws)
-(assert (null (websocket-openp wstest-ws)))
-
-(if (not (eq system-type 'windows-nt))
- ; Windows doesn't have support for the SIGSTP signal, so we'll just kill
- ; the process.
- (stop-process wstest-server-proc))
-(kill-process wstest-server-proc)
-
-;; Make sure the processes are closed. This happens asynchronously,
-;; so let's wait for it.
-(sleep-for 1)
-(assert (null (process-list)) t)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Remote server test, with wss ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; echo.websocket.org has an untrusted certificate, for the test to
-;; proceed, we need to disable trust checking.
-(setq tls-checktrust nil)
-
-(when (>= (string-to-number (substring emacs-version 0 2)) 24)
- (message "Testing with wss://echo.websocket.org")
- (when (eq system-type 'windows-nt)
- (message "Windows users must have gnutls DLLs in the emacs bin
directory."))
- (setq wstest-ws
- (websocket-open
- "wss://echo.websocket.org"
- :on-open (lambda (_websocket)
- (message "Websocket opened"))
- :on-message (lambda (_websocket frame)
- (push (websocket-frame-text frame) wstest-msgs)
- (message "ws frame: %S" (websocket-frame-text frame)))
- :on-close (lambda (_websocket)
- (message "Websocket closed")
- (setq wstest-closed t)))
- wstest-msgs nil)
- (sleep-for 0.3)
- (assert (websocket-openp wstest-ws))
- (sleep-for 0.6)
- (assert (eq 'open (websocket-ready-state wstest-ws)))
- (assert (null wstest-msgs))
- (websocket-send-text wstest-ws "Hi!")
- (sleep-for 1)
- (assert (equal (car wstest-msgs) "Hi!"))
- (websocket-close wstest-ws))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Local client and server ;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(message "Testing with emacs websocket server.")
-(message "If this does not pass, make sure your firewall allows the
connection.")
-(setq wstest-closed nil)
-(let ((server-conn (websocket-server
- 9998
- :host 'local
- :on-message (lambda (ws frame)
- (message "Server received text!")
- (websocket-send-text
- ws (websocket-frame-text frame)))
- :on-open (lambda (_websocket) "Client connection opened!")
- :on-close (lambda (_websocket)
- (setq wstest-closed t)))))
- (setq wstest-msgs nil
- wstest-ws
- (websocket-open
- "ws://localhost:9998"
- :on-message (lambda (_websocket frame)
- (message "ws frame: %S" (websocket-frame-text frame))
- (push
- (websocket-frame-text frame) wstest-msgs))))
-
- (assert (websocket-openp wstest-ws))
- (websocket-send-text wstest-ws "你好")
- (sleep-for 0.3)
- (assert (equal (car wstest-msgs) "你好"))
- (websocket-server-close server-conn))
-(assert wstest-closed)
-(websocket-close wstest-ws)
-
-(sleep-for 1)
-(assert (null (process-list)) t)
-(message "\nAll tests passed!\n")
diff --git a/packages/websocket/websocket.el b/packages/websocket/websocket.el
deleted file mode 100644
index 1d69508..0000000
--- a/packages/websocket/websocket.el
+++ /dev/null
@@ -1,1065 +0,0 @@
-;;; websocket.el --- Emacs WebSocket client and server -*- lexical-binding:t
-*-
-
-;; Copyright (c) 2013, 2016-2017 Free Software Foundation, Inc.
-
-;; Author: Andrew Hyatt <ahyatt@gmail.com>
-;; Keywords: Communication, Websocket, Server
-;; Version: 1.12
-;; Package-Requires: ((cl-lib "0.5"))
-;;
-;; 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. If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;; This implements RFC 6455, which can be found at
-;; http://tools.ietf.org/html/rfc6455.
-;;
-;; This library contains code to connect Emacs as a client to a
-;; websocket server, and for Emacs to act as a server for websocket
-;; connections.
-;;
-;; Websockets clients are created by calling `websocket-open', which
-;; returns a `websocket' struct. Users of this library use the
-;; websocket struct, and can call methods `websocket-send-text', which
-;; sends text over the websocket, or `websocket-send', which sends a
-;; `websocket-frame' struct, enabling finer control of what is sent.
-;; A callback is passed to `websocket-open' that will retrieve
-;; websocket frames called from the websocket. Websockets are
-;; eventually closed with `websocket-close'.
-;;
-;; Server functionality is similar. A server is started with
-;; `websocket-server' called with a port and the callbacks to use,
-;; which returns a process. The process can later be closed with
-;; `websocket-server-close'. A `websocket' struct is also created
-;; for every connection, and is exposed through the callbacks.
-
-(require 'bindat)
-(require 'url-parse)
-(require 'url-cookie)
-(require 'seq)
-(eval-when-compile (require 'cl-lib))
-
-;;; Code:
-
-(cl-defstruct (websocket
- (:constructor nil)
- (:constructor websocket-inner-create))
- "A websocket structure.
-This follows the W3C Websocket API, except translated to elisp
-idioms. The API is implemented in both the websocket struct and
-additional methods. Due to how defstruct slots are accessed, all
-API methods are prefixed with \"websocket-\" and take a websocket
-as an argument, so the distrinction between the struct API and
-the additional helper APIs are not visible to the caller.
-
-A websocket struct is created with `websocket-open'.
-
-`ready-state' contains one of `connecting', `open', or
-`closed', depending on the state of the websocket.
-
-The W3C API \"bufferedAmount\" call is not currently implemented,
-since there is no elisp API to get the buffered amount from the
-subprocess. There may, in fact, be output data buffered,
-however, when the `on-message' or `on-close' callbacks are
-called.
-
-`on-open', `on-message', `on-close', and `on-error' are described
-in `websocket-open'.
-
-The `negotiated-extensions' slot lists the extensions accepted by
-both the client and server, and `negotiated-protocols' does the
-same for the protocols."
- ;; API
- (ready-state 'connecting)
- client-data
- on-open
- on-message
- on-close
- on-error
- negotiated-protocols
- negotiated-extensions
- (server-p nil :read-only t)
-
- ;; Other data - clients should not have to access this.
- (url (cl-assert nil) :read-only t)
- (protocols nil :read-only t)
- (extensions nil :read-only t)
- (conn (cl-assert nil) :read-only t)
- ;; Only populated for servers, this is the server connection.
- server-conn
- accept-string
- (inflight-input nil))
-
-(defvar websocket-version "1.12"
- "Version numbers of this version of websocket.el.")
-
-(defvar websocket-debug nil
- "Set to true to output debugging info to a per-websocket buffer.
-The buffer is ` *websocket URL debug*' where URL is the
-URL of the connection.")
-
-(defconst websocket-guid "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
- "The websocket GUID as defined in RFC 6455.
-Do not change unless the RFC changes.")
-
-(defvar websocket-callback-debug-on-error nil
- "If true, when an error happens in a client callback, invoke the debugger.
-Having this on can cause issues with missing frames if the debugger is
-exited by quitting instead of continuing, so it's best to have this set
-to nil unless it is especially needed.")
-
-(defmacro websocket-document-function (function docstring)
- "Document FUNCTION with DOCSTRING. Use this for defstruct accessor etc."
- (declare (indent defun)
- (doc-string 2))
- `(put ',function 'function-documentation ,docstring))
-
-(websocket-document-function websocket-on-open
- "Accessor for websocket on-open callback.
-See `websocket-open' for details.
-
-\(fn WEBSOCKET)")
-
-(websocket-document-function websocket-on-message
- "Accessor for websocket on-message callback.
-See `websocket-open' for details.
-
-\(fn WEBSOCKET)")
-
-(websocket-document-function websocket-on-close
- "Accessor for websocket on-close callback.
-See `websocket-open' for details.
-
-\(fn WEBSOCKET)")
-
-(websocket-document-function websocket-on-error
- "Accessor for websocket on-error callback.
-See `websocket-open' for details.
-
-\(fn WEBSOCKET)")
-
-(defun websocket-genbytes (nbytes)
- "Generate NBYTES random bytes."
- (let ((s (make-string nbytes ?\s)))
- (dotimes (i nbytes)
- (aset s i (random 256)))
- s))
-
-(defun websocket-try-callback (websocket-callback callback-type websocket
- &rest rest)
- "Invoke function WEBSOCKET-CALLBACK with WEBSOCKET and REST args.
-If an error happens, it is handled according to
-`websocket-callback-debug-on-error'."
- ;; This looks like it should be able to done more efficiently, but
- ;; I'm not sure that's the case. We can't do it as a macro, since
- ;; we want it to change whenever websocket-callback-debug-on-error
- ;; changes.
- (let ((args rest)
- (debug-on-error websocket-callback-debug-on-error))
- (push websocket args)
- (if websocket-callback-debug-on-error
- (condition-case err
- (apply (funcall websocket-callback websocket) args)
- ((debug error) (funcall (websocket-on-error websocket)
- websocket callback-type err)))
- (condition-case err
- (apply (funcall websocket-callback websocket) args)
- (error (funcall (websocket-on-error websocket) websocket
- callback-type err))))))
-
-(defun websocket-genkey ()
- "Generate a key suitable for the websocket handshake."
- (base64-encode-string (websocket-genbytes 16)))
-
-(defun websocket-calculate-accept (key)
- "Calculate the expect value of the accept header.
-This is based on the KEY from the Sec-WebSocket-Key header."
- (base64-encode-string
- (sha1 (concat key websocket-guid) nil nil t)))
-
-(defun websocket-get-bytes (s n)
- "From string S, retrieve the value of N bytes.
-Return the value as an unsigned integer. The value N must be a
-power of 2, up to 8.
-
-We support getting frames up to 536870911 bytes (2^29 - 1),
-approximately 537M long."
- (if (= n 8)
- (let* ((32-bit-parts
- (bindat-get-field (bindat-unpack '((:val vec 2 u32)) s) :val))
- (cval
- (logior (lsh (aref 32-bit-parts 0) 32) (aref 32-bit-parts 1))))
- (if (and (= (aref 32-bit-parts 0) 0)
- (= (lsh (aref 32-bit-parts 1) -29) 0))
- cval
- (signal 'websocket-unparseable-frame
- (list "Frame value found too large to parse!"))))
- ;; n is not 8
- (bindat-get-field
- (condition-case _
- (bindat-unpack
- `((:val
- ,(cond ((= n 1) 'u8)
- ((= n 2) 'u16)
- ((= n 4) 'u32)
- ;; This is an error with the library,
- ;; not a user-facing, meaningful error.
- (t (error
- "websocket-get-bytes: Unknown N: %S" n)))))
- s)
- (args-out-of-range (signal 'websocket-unparseable-frame
- (list (format "Frame unexpectedly short: %s"
s)))))
- :val)))
-
-(defun websocket-to-bytes (val nbytes)
- "Encode the integer VAL in NBYTES of data.
-NBYTES much be a power of 2, up to 8.
-
-This supports encoding values up to 536870911 bytes (2^29 - 1),
-approximately 537M long."
- (when (and (< nbytes 8)
- (> val (expt 2 (* 8 nbytes))))
- ;; not a user-facing error, this must be caused from an error in
- ;; this library
- (error "websocket-to-bytes: Value %d could not be expressed in %d bytes"
- val nbytes))
- (if (= nbytes 8)
- (progn
- (let* ((hi-32bits (lsh val -32))
- ;; This is just VAL on systems that don't have >= 32 bits.
- (low-32bits (- val (lsh hi-32bits 32))))
- (when (or (> hi-32bits 0) (> (lsh low-32bits -29) 0))
- (signal 'websocket-frame-too-large (list val)))
- (bindat-pack `((:val vec 2 u32))
- `((:val . [,hi-32bits ,low-32bits])))))
- (bindat-pack
- `((:val ,(cond ((= nbytes 1) 'u8)
- ((= nbytes 2) 'u16)
- ((= nbytes 4) 'u32)
- ;; Library error, not system error
- (t (error "websocket-to-bytes: Unknown NBYTES: %S"
nbytes)))))
- `((:val . ,val)))))
-
-(defun websocket-get-opcode (s)
- "Retrieve the opcode from first byte of string S."
- (websocket-ensure-length s 1)
- (let ((opcode (logand #xf (aref s 0))))
- (cond ((= opcode 0) 'continuation)
- ((= opcode 1) 'text)
- ((= opcode 2) 'binary)
- ((= opcode 8) 'close)
- ((= opcode 9) 'ping)
- ((= opcode 10) 'pong))))
-
-(defun websocket-get-payload-len (s)
- "Parse out the payload length from the string S.
-We start at position 0, and return a cons of the payload length and how
-many bytes were consumed from the string."
- (websocket-ensure-length s 1)
- (let* ((initial-val (logand 127 (aref s 0))))
- (cond ((= initial-val 127)
- (websocket-ensure-length s 9)
- (cons (websocket-get-bytes (substring s 1) 8) 9))
- ((= initial-val 126)
- (websocket-ensure-length s 3)
- (cons (websocket-get-bytes (substring s 1) 2) 3))
- (t (cons initial-val 1)))))
-
-(cl-defstruct websocket-frame opcode payload length completep)
-
-(defun websocket-frame-text (frame)
- "Given FRAME, return the payload as a utf-8 encoded string."
- (cl-assert (websocket-frame-p frame))
- (decode-coding-string (websocket-frame-payload frame) 'utf-8))
-
-(defun websocket-mask (key data)
- "Using string KEY, mask string DATA according to the RFC.
-This is used to both mask and unmask data."
- ;; Returning the string as unibyte is important here. Because we set the
- ;; string byte by byte, this results in a unibyte string.
- (cl-loop
- with result = (make-string (length data) ?x)
- for i from 0 below (length data)
- do (setf (seq-elt result i) (logxor (aref key (mod i 4)) (seq-elt data i)))
- finally return result))
-
-(defun websocket-ensure-length (s n)
- "Ensure the string S has at most N bytes.
-Otherwise we throw the error `websocket-incomplete-frame'."
- (when (< (length s) n)
- (throw 'websocket-incomplete-frame nil)))
-
-(defun websocket-encode-frame (frame should-mask)
- "Encode the FRAME struct to the binary representation.
-We mask the frame or not, depending on SHOULD-MASK."
- (let* ((opcode (websocket-frame-opcode frame))
- (payload (websocket-frame-payload frame))
- (fin (websocket-frame-completep frame))
- (payloadp (and payload
- (memq opcode '(continuation ping pong text binary))))
- (mask-key (when should-mask (websocket-genbytes 4))))
- (apply #'unibyte-string
- (let ((val (append (list
- (logior (pcase opcode
- (`continuation 0)
- (`text 1)
- (`binary 2)
- (`close 8)
- (`ping 9)
- (`pong 10))
- (if fin 128 0)))
- (when payloadp
- (list
- (logior
- (if should-mask 128 0)
- (cond ((< (length payload) 126) (length
payload))
- ((< (length payload) 65536) 126)
- (t 127)))))
- (when (and payloadp (>= (length payload) 126))
- (append (websocket-to-bytes
- (length payload)
- (cond ((< (length payload) 126) 1)
- ((< (length payload) 65536) 2)
- (t 8))) nil))
- (when (and payloadp should-mask)
- (append mask-key nil))
- (when payloadp
- (append (if should-mask (websocket-mask mask-key
payload)
- payload)
- nil)))))
- ;; We have to make sure the non-payload data is a full 32-bit
frame
- (if (= 1 (length val))
- (append val '(0)) val)))))
-
-(defun websocket-read-frame (s)
- "Read from string S a `websocket-frame' struct with the contents.
-This only gets complete frames. Partial frames need to wait until
-the frame finishes. If the frame is not completed, return NIL."
- (catch 'websocket-incomplete-frame
- (websocket-ensure-length s 1)
- (let* ((opcode (websocket-get-opcode s))
- (fin (logand 128 (aref s 0)))
- (payloadp (memq opcode '(continuation text binary ping pong)))
- (payload-len (when payloadp
- (websocket-get-payload-len (substring s 1))))
- (maskp (and
- payloadp
- (= 128 (logand 128 (aref s 1)))))
- (payload-start (when payloadp (+ (if maskp 5 1) (cdr payload-len))))
- (payload-end (when payloadp (+ payload-start (car payload-len))))
- (unmasked-payload (when payloadp
- (websocket-ensure-length s payload-end)
- (substring s payload-start payload-end))))
- (make-websocket-frame
- :opcode opcode
- :payload
- (if maskp
- (let ((masking-key (substring s (+ 1 (cdr payload-len))
- (+ 5 (cdr payload-len)))))
- (websocket-mask masking-key unmasked-payload))
- unmasked-payload)
- :length (if payloadp payload-end 1)
- :completep (> fin 0)))))
-
-(defun websocket-format-error (err)
- "Format an error message like command level does.
-ERR should be a cons of error symbol and error data."
-
- ;; Formatting code adapted from `edebug-report-error'
- (concat (or (get (car err) 'error-message)
- (format "peculiar error (%s)" (car err)))
- (when (cdr err)
- (format ": %s"
- (mapconcat #'prin1-to-string
- (cdr err) ", ")))))
-
-(defun websocket-default-error-handler (_websocket type err)
- "The default error handler used to handle errors in callbacks."
- (display-warning 'websocket
- (format "in callback `%S': %s"
- type
- (websocket-format-error err))
- :error))
-
-;; Error symbols in use by the library
-(put 'websocket-unsupported-protocol 'error-conditions
- '(error websocket-error websocket-unsupported-protocol))
-(put 'websocket-unsupported-protocol 'error-message "Unsupported websocket
protocol")
-(put 'websocket-wss-needs-emacs-24 'error-conditions
- '(error websocket-error websocket-unsupported-protocol
- websocket-wss-needs-emacs-24))
-(put 'websocket-wss-needs-emacs-24 'error-message
- "wss protocol is not supported for Emacs before version 24.")
-(put 'websocket-received-error-http-response 'error-conditions
- '(error websocket-error websocket-received-error-http-response))
-(put 'websocket-received-error-http-response 'error-message
- "Error response received from websocket server")
-(put 'websocket-invalid-header 'error-conditions
- '(error websocket-error websocket-invalid-header))
-(put 'websocket-invalid-header 'error-message
- "Invalid HTTP header sent")
-(put 'websocket-illegal-frame 'error-conditions
- '(error websocket-error websocket-illegal-frame))
-(put 'websocket-illegal-frame 'error-message
- "Cannot send illegal frame to websocket")
-(put 'websocket-closed 'error-conditions
- '(error websocket-error websocket-closed))
-(put 'websocket-closed 'error-message
- "Cannot send message to a closed websocket")
-(put 'websocket-unparseable-frame 'error-conditions
- '(error websocket-error websocket-unparseable-frame))
-(put 'websocket-unparseable-frame 'error-message
- "Received an unparseable frame")
-(put 'websocket-frame-too-large 'error-conditions
- '(error websocket-error websocket-frame-too-large))
-(put 'websocket-frame-too-large 'error-message
- "The frame being sent is too large for this emacs to handle")
-
-(defun websocket-intersect (a b)
- "Simple list intersection, should function like Common Lisp's
`intersection'."
- (let ((result))
- (dolist (elem a (nreverse result))
- (when (member elem b)
- (push elem result)))))
-
-(defun websocket-get-debug-buffer-create (websocket)
- "Get or create the buffer corresponding to WEBSOCKET."
- (let ((buf (get-buffer-create (format "*websocket %s debug*"
- (websocket-url websocket)))))
- (when (= 0 (buffer-size buf))
- (buffer-disable-undo buf))
- buf))
-
-(defun websocket-debug (websocket msg &rest args)
- "In the WEBSOCKET's debug buffer, send MSG, with format ARGS."
- (when websocket-debug
- (let ((buf (websocket-get-debug-buffer-create websocket)))
- (save-excursion
- (with-current-buffer buf
- (goto-char (point-max))
- (insert "[WS] ")
- (insert (apply #'format (append (list msg) args)))
- (insert "\n"))))))
-
-(defun websocket-verify-response-code (output)
- "Verify that OUTPUT contains a valid HTTP response code.
-The only acceptable one to websocket is responce code 101.
-A t value will be returned on success, and an error thrown
-if not."
- (unless (string-match "^HTTP/1.1 \\([[:digit:]]+\\)" output)
- (signal 'websocket-invalid-header (list "Invalid HTTP status line")))
- (unless (equal "101" (match-string 1 output))
- (signal 'websocket-received-error-http-response
- (list (string-to-number (match-string 1 output)))))
- t)
-
-(defun websocket-parse-repeated-field (output field)
- "From header-containing OUTPUT, parse out the list from a
-possibly repeated field."
- (let ((pos 0)
- (extensions))
- (while (and pos
- (string-match (format "\r\n%s: \\(.*\\)\r\n" field)
- output pos))
- (when (setq pos (match-end 1))
- (setq extensions (append extensions (split-string
- (match-string 1 output) ", ?")))))
- extensions))
-
-(defun websocket-process-frame (websocket frame)
- "Using the WEBSOCKET's filter and connection, process the FRAME.
-This returns a lambda that should be executed when all frames have
-been processed. If the frame has a payload, the lambda has the frame
-passed to the filter slot of WEBSOCKET. If the frame is a ping,
-the lambda has a reply with a pong. If the frame is a close, the lambda
-has connection termination."
- (let ((opcode (websocket-frame-opcode frame)))
- (cond ((memq opcode '(continuation text binary))
- (lambda () (websocket-try-callback 'websocket-on-message 'on-message
- websocket frame)))
- ((eq opcode 'ping)
- (lambda () (websocket-send websocket
- (make-websocket-frame
- :opcode 'pong
- :payload (websocket-frame-payload frame)
- :completep t))))
- ((eq opcode 'close)
- (lambda () (delete-process (websocket-conn websocket))))
- (t (lambda ())))))
-
-(defun websocket-process-input-on-open-ws (websocket text)
- "This handles input processing for both the client and server filters."
- (let ((current-frame)
- (processing-queue)
- (start-point 0))
- (while (setq current-frame (websocket-read-frame
- (substring text start-point)))
- (push (websocket-process-frame websocket current-frame) processing-queue)
- (cl-incf start-point (websocket-frame-length current-frame)))
- (when (> (length text) start-point)
- (setf (websocket-inflight-input websocket)
- (substring text start-point)))
- (dolist (to-process (nreverse processing-queue))
- (funcall to-process))))
-
-(defun websocket-send-text (websocket text)
- "To the WEBSOCKET, send TEXT as a complete frame."
- (websocket-send
- websocket
- (make-websocket-frame :opcode 'text
- :payload (encode-coding-string
- text 'raw-text)
- :completep t)))
-
-(defun websocket-check (frame)
- "Check FRAME for correctness, returning true if correct."
- (or
- ;; Text, binary, and continuation frames need payloads
- (and (memq (websocket-frame-opcode frame) '(text binary continuation))
- (websocket-frame-payload frame))
- ;; Pings and pongs may optionally have them
- (memq (websocket-frame-opcode frame) '(ping pong))
- ;; And close shouldn't have any payload, and should always be complete.
- (and (eq (websocket-frame-opcode frame) 'close)
- (not (websocket-frame-payload frame))
- (websocket-frame-completep frame))))
-
-(defun websocket-send (websocket frame)
- "To the WEBSOCKET server, send the FRAME.
-This will raise an error if the frame is illegal.
-
-The error signaled may be of type `websocket-illegal-frame' if
-the frame is malformed in some way, also having the condition
-type of `websocket-error'. The data associated with the signal
-is the frame being sent.
-
-If the websocket is closed a signal `websocket-closed' is sent,
-also with `websocket-error' condition. The data in the signal is
-also the frame.
-
-The frame may be too large for this buid of Emacs, in which case
-`websocket-frame-too-large' is returned, with the data of the
-size of the frame which was too large to process. This also has
-the `websocket-error' condition."
- (unless (websocket-check frame)
- (signal 'websocket-illegal-frame (list frame)))
- (websocket-debug websocket "Sending frame, opcode: %s payload: %s"
- (websocket-frame-opcode frame)
- (websocket-frame-payload frame))
- (websocket-ensure-connected websocket)
- (unless (websocket-openp websocket)
- (signal 'websocket-closed (list frame)))
- (process-send-string (websocket-conn websocket)
- ;; We mask only when we're a client, following the spec.
- (websocket-encode-frame frame (not (websocket-server-p
websocket)))))
-
-(defun websocket-openp (websocket)
- "Check WEBSOCKET and return non-nil if the connection is open."
- (and websocket
- (not (eq 'close (websocket-ready-state websocket)))
- (member (process-status (websocket-conn websocket)) '(open run))))
-
-(defun websocket-close (websocket)
- "Close WEBSOCKET and erase all the old websocket data."
- (websocket-debug websocket "Closing websocket")
- (websocket-try-callback 'websocket-on-close 'on-close websocket)
- (when (websocket-openp websocket)
- (websocket-send websocket
- (make-websocket-frame :opcode 'close
- :completep t))
- (setf (websocket-ready-state websocket) 'closed))
- (delete-process (websocket-conn websocket)))
-
-(defun websocket-ensure-connected (websocket)
- "If the WEBSOCKET connection is closed, open it."
- (unless (and (websocket-conn websocket)
- (cl-ecase (process-status (websocket-conn websocket))
- ((run open listen) t)
- ((stop exit signal closed connect failed nil) nil)))
- (websocket-close websocket)
- (websocket-open (websocket-url websocket)
- :protocols (websocket-protocols websocket)
- :extensions (websocket-extensions websocket)
- :on-open (websocket-on-open websocket)
- :on-message (websocket-on-message websocket)
- :on-close (websocket-on-close websocket)
- :on-error (websocket-on-error websocket))))
-
-;;;;;;;;;;;;;;;;;;;;;;
-;; Websocket client ;;
-;;;;;;;;;;;;;;;;;;;;;;
-
-(cl-defun websocket-open (url &key protocols extensions (on-open 'identity)
- (on-message (lambda (_w _f))) (on-close
'identity)
- (on-error 'websocket-default-error-handler)
- (nowait nil) (custom-header-alist nil))
- "Open a websocket connection to URL, returning the `websocket' struct.
-The PROTOCOL argument is optional, and setting it will declare to
-the server that this client supports the protocols in the list
-given. We will require that the server also has to support that
-protocols.
-
-Similar logic applies to EXTENSIONS, which is a list of conses,
-the car of which is a string naming the extension, and the cdr of
-which is the list of parameter strings to use for that extension.
-The parameter strings are of the form \"key=value\" or \"value\".
-EXTENSIONS can be NIL if none are in use. An example value would
-be (\"deflate-stream\" . (\"mux\" \"max-channels=4\")).
-
-Cookies that are set via `url-cookie-store' will be used during
-communication with the server, and cookies received from the
-server will be stored in the same cookie storage that the
-`url-cookie' package uses.
-
-Optionally you can specify
-ON-OPEN, ON-MESSAGE and ON-CLOSE callbacks as well.
-
-The ON-OPEN callback is called after the connection is
-established with the websocket as the only argument. The return
-value is unused.
-
-The ON-MESSAGE callback is called after receiving a frame, and is
-called with the websocket as the first argument and
-`websocket-frame' struct as the second. The return value is
-unused.
-
-The ON-CLOSE callback is called after the connection is closed, or
-failed to open. It is called with the websocket as the only
-argument, and the return value is unused.
-
-The ON-ERROR callback is called when any of the other callbacks
-have an error. It takes the websocket as the first argument, and
-a symbol as the second argument either `on-open', `on-message',
-or `on-close', and the error as the third argument. Do NOT
-rethrow the error, or else you may miss some websocket messages.
-You similarly must not generate any other errors in this method.
-If you want to debug errors, set
-`websocket-callback-debug-on-error' to t, but this also can be
-dangerous is the debugger is quit out of. If not specified,
-`websocket-default-error-handler' is used.
-
-For each of these event handlers, the client code can store
-arbitrary data in the `client-data' slot in the returned
-websocket.
-
-The following errors might be thrown in this method or in
-websocket processing, all of them having the error-condition
-`websocket-error' in addition to their own symbol:
-
-`websocket-unsupported-protocol': Data in the error signal is the
-protocol that is unsupported. For example, giving a URL starting
-with http by mistake raises this error.
-
-`websocket-wss-needs-emacs-24': Trying to connect wss protocol
-using Emacs < 24 raises this error. You can catch this error
-also by `websocket-unsupported-protocol'.
-
-`websocket-received-error-http-response': Data in the error
-signal is the integer error number.
-
-`websocket-invalid-header': Data in the error is a string
-describing the invalid header received from the server.
-
-`websocket-unparseable-frame': Data in the error is a string
-describing the problem with the frame.
-
-`nowait': If NOWAIT is true, return without waiting for the
-connection to complete.
-
-`custom-headers-alist': An alist of custom headers to pass to the
-server. The car is the header name, the cdr is the header value.
-These are different from the extensions because it is not related
-to the websocket protocol.
-"
- (let* ((name (format "websocket to %s" url))
- (url-struct (url-generic-parse-url url))
- (key (websocket-genkey))
- (coding-system-for-read 'binary)
- (coding-system-for-write 'binary)
- (conn (if (member (url-type url-struct) '("ws" "wss"))
- (let* ((type (if (equal (url-type url-struct) "ws")
- 'plain 'tls))
- (port (if (= 0 (url-port url-struct))
- (if (eq type 'tls) 443 80)
- (url-port url-struct)))
- (host (url-host url-struct)))
- (if (eq type 'plain)
- (make-network-process :name name :buffer nil :host
host
- :service port :nowait nowait)
- (condition-case-unless-debug nil
- (open-network-stream name nil host port :type type
:nowait nowait)
- (wrong-number-of-arguments
- (signal 'websocket-wss-needs-emacs-24 (list
"wss"))))))
- (signal 'websocket-unsupported-protocol (list (url-type
url-struct)))))
- (websocket (websocket-inner-create
- :conn conn
- :url url
- :on-open on-open
- :on-message on-message
- :on-close on-close
- :on-error on-error
- :protocols protocols
- :extensions (mapcar 'car extensions)
- :accept-string
- (websocket-calculate-accept key))))
- (unless conn (error "Could not establish the websocket connection to %s"
url))
- (process-put conn :websocket websocket)
- (set-process-filter conn
- (lambda (process output)
- (let ((websocket (process-get process :websocket)))
- (websocket-outer-filter websocket output))))
- (set-process-sentinel
- conn
- (websocket-sentinel url conn key protocols extensions custom-header-alist
nowait))
- (set-process-query-on-exit-flag conn nil)
- (websocket-ensure-handshake url conn key protocols extensions
custom-header-alist)
- websocket))
-
-(defun websocket-sentinel (url conn key protocols extensions
custom-header-alist nowait)
- #'(lambda (process change)
- (let ((websocket (process-get process :websocket)))
- (websocket-debug websocket "State change to %s" change)
- (let ((status (process-status process)))
- (when (and nowait (eq status 'open))
- (websocket-ensure-handshake url conn key protocols extensions
custom-header-alist))
-
- (when (and (member status '(closed failed exit signal))
- (not (eq 'closed (websocket-ready-state websocket))))
- (websocket-try-callback 'websocket-on-close 'on-close
websocket))))))
-
-(defun websocket-ensure-handshake (url conn key protocols extensions
custom-header-alist)
- (let ((url-struct (url-generic-parse-url url))
- (websocket (process-get conn :websocket)))
- (when (and (eq 'connecting (websocket-ready-state websocket))
- (eq 'open (process-status conn)))
- (process-send-string conn
- (format "GET %s HTTP/1.1\r\n"
- (let ((path (url-filename url-struct)))
- (if (> (length path) 0) path "/"))))
- (websocket-debug websocket "Sending handshake, key: %s, acceptance: %s"
- key (websocket-accept-string websocket))
- (process-send-string conn
- (websocket-create-headers
- url key protocols extensions
custom-header-alist)))))
-
-(defun websocket-process-headers (url headers)
- "On opening URL, process the HEADERS sent from the server."
- (when (string-match "Set-Cookie: \(.*\)\r\n" headers)
- ;; The url-current-object is assumed to be set by
- ;; url-cookie-handle-set-cookie.
- (let ((url-current-object (url-generic-parse-url url)))
- (url-cookie-handle-set-cookie (match-string 1 headers)))))
-
-(defun websocket-outer-filter (websocket output)
- "Filter the WEBSOCKET server's OUTPUT.
-This will parse headers and process frames repeatedly until there
-is no more output or the connection closes. If the websocket
-connection is invalid, the connection will be closed."
- (websocket-debug websocket "Received: %s" output)
- (let ((start-point)
- (text (concat (websocket-inflight-input websocket) output))
- (header-end-pos))
- (setf (websocket-inflight-input websocket) nil)
- ;; If we've received the complete header, check to see if we've
- ;; received the desired handshake.
- (when (and (eq 'connecting (websocket-ready-state websocket)))
- (if (and (setq header-end-pos (string-match "\r\n\r\n" text))
- (setq start-point (+ 4 header-end-pos)))
- (progn
- (condition-case err
- (progn
- (websocket-verify-response-code text)
- (websocket-verify-headers websocket text)
- (websocket-process-headers (websocket-url websocket) text))
- (error
- (websocket-close websocket)
- (funcall (websocket-on-error websocket)
- websocket 'on-open err)))
- (setf (websocket-ready-state websocket) 'open)
- (websocket-try-callback 'websocket-on-open 'on-open websocket))
- (setf (websocket-inflight-input websocket) text)))
- (when (eq 'open (websocket-ready-state websocket))
- (websocket-process-input-on-open-ws
- websocket (substring text (or start-point 0))))))
-
-(defun websocket-verify-headers (websocket output)
- "Based on WEBSOCKET's data, ensure the headers in OUTPUT are valid.
-The output is assumed to have complete headers. This function
-will either return t or call `error'. This has the side-effect
-of populating the list of server extensions to WEBSOCKET."
- (let ((accept-regexp
- (concat "Sec-Web[Ss]ocket-Accept: " (regexp-quote
(websocket-accept-string websocket)))))
- (websocket-debug websocket "Checking for accept header regexp: %s"
accept-regexp)
- (unless (string-match accept-regexp output)
- (signal 'websocket-invalid-header
- (list "Incorrect handshake from websocket: is this really a
websocket connection?"))))
- (let ((case-fold-search t))
- (websocket-debug websocket "Checking for upgrade header")
- (unless (string-match "\r\nUpgrade: websocket\r\n" output)
- (signal 'websocket-invalid-header
- (list "No 'Upgrade: websocket' header found")))
- (websocket-debug websocket "Checking for connection header")
- (unless (string-match "\r\nConnection: upgrade\r\n" output)
- (signal 'websocket-invalid-header
- (list "No 'Connection: upgrade' header found")))
- (when (websocket-protocols websocket)
- (dolist (protocol (websocket-protocols websocket))
- (websocket-debug websocket "Checking for protocol match: %s"
- protocol)
- (let ((protocols
- (if (string-match (format "\r\nSec-Websocket-Protocol: %s\r\n"
- protocol)
- output)
- (list protocol)
- (signal 'websocket-invalid-header
- (list "Incorrect or missing protocol returned by the
server.")))))
- (setf (websocket-negotiated-protocols websocket) protocols))))
- (let* ((extensions (websocket-parse-repeated-field
- output
- "Sec-WebSocket-Extensions"))
- (extra-extensions))
- (dolist (ext extensions)
- (let ((x (cl-first (split-string ext "; ?"))))
- (unless (or (member x (websocket-extensions websocket))
- (member x extra-extensions))
- (push x extra-extensions))))
- (when extra-extensions
- (signal 'websocket-invalid-header
- (list (format "Non-requested extensions returned by server: %S"
- extra-extensions))))
- (setf (websocket-negotiated-extensions websocket) extensions)))
- t)
-
-;;;;;;;;;;;;;;;;;;;;;;
-;; Websocket server ;;
-;;;;;;;;;;;;;;;;;;;;;;
-
-(defvar websocket-server-websockets nil
- "A list of current websockets live on any server.")
-
-(cl-defun websocket-server (port &rest plist)
- "Open a websocket server on PORT.
-If the plist contains a `:host' HOST pair, this value will be
-used to configure the addresses the socket listens on. The symbol
-`local' specifies the local host. If unspecified or nil, the
-socket will listen on all addresses.
-
-This also takes a plist of callbacks: `:on-open', `:on-message',
-`:on-close' and `:on-error', which operate exactly as documented
-in the websocket client function `websocket-open'. Returns the
-connection, which should be kept in order to pass to
-`websocket-server-close'."
- (let* ((conn (make-network-process
- :name (format "websocket server on port %s" port)
- :server t
- :family 'ipv4
- :noquery t
- :filter 'websocket-server-filter
- :log 'websocket-server-accept
- :filter-multibyte nil
- :plist plist
- :host (plist-get plist :host)
- :service port)))
- conn))
-
-(defun websocket-server-close (conn)
- "Closes the websocket, as well as all open websockets for this server."
- (let ((to-delete))
- (dolist (ws websocket-server-websockets)
- (when (eq (websocket-server-conn ws) conn)
- (if (eq (websocket-ready-state ws) 'closed)
- (unless (member ws to-delete)
- (push ws to-delete))
- (websocket-close ws))))
- (dolist (ws to-delete)
- (setq websocket-server-websockets (remove ws
websocket-server-websockets))))
- (delete-process conn))
-
-(defun websocket-server-accept (server client _message)
- "Accept a new websocket connection from a client."
- (let ((ws (websocket-inner-create
- :server-conn server
- :conn client
- :url client
- :server-p t
- :on-open (or (process-get server :on-open) 'identity)
- :on-message (or (process-get server :on-message) (lambda (_ws
_frame)))
- :on-close (let ((user-method
- (or (process-get server :on-close) 'identity)))
- (lambda (ws)
- (setq websocket-server-websockets
- (remove ws websocket-server-websockets))
- (funcall user-method ws)))
- :on-error (or (process-get server :on-error)
- 'websocket-default-error-handler)
- :protocols (process-get server :protocol)
- :extensions (mapcar 'car (process-get server :extensions)))))
- (unless (member ws websocket-server-websockets)
- (push ws websocket-server-websockets))
- (process-put client :websocket ws)
- (set-process-coding-system client 'binary 'binary)
- (set-process-sentinel client
- (lambda (process change)
- (let ((websocket (process-get process :websocket)))
- (websocket-debug websocket "State change to %s"
change)
- (when (and
- (member (process-status process) '(closed
failed exit signal))
- (not (eq 'closed (websocket-ready-state
websocket))))
- (websocket-try-callback 'websocket-on-close
'on-close websocket)))))))
-
-(defun websocket-create-headers (url key protocol extensions
custom-headers-alist)
- "Create connections headers for the given URL, KEY, PROTOCOL, and EXTENSIONS.
-Additionally, the CUSTOM-HEADERS-ALIST is passed from the client.
-All these parameters are defined as in `websocket-open'."
- (let* ((parsed-url (url-generic-parse-url url))
- (host-port (if (url-port-if-non-default parsed-url)
- (format "%s:%s" (url-host parsed-url) (url-port
parsed-url))
- (url-host parsed-url)))
- (cookie-header (url-cookie-generate-header-lines
- host-port (car (url-path-and-query parsed-url))
- (equal (url-type parsed-url) "wss"))))
- (format (concat "Host: %s\r\n"
- "Upgrade: websocket\r\n"
- "Connection: Upgrade\r\n"
- "Sec-WebSocket-Key: %s\r\n"
- "Sec-WebSocket-Version: 13\r\n"
- (when protocol
- (concat
- (mapconcat
- (lambda (protocol)
- (format "Sec-WebSocket-Protocol: %s" protocol))
- protocol "\r\n")
- "\r\n"))
- (when extensions
- (format "Sec-WebSocket-Extensions: %s\r\n"
- (mapconcat
- (lambda (ext)
- (concat
- (car ext)
- (when (cdr ext) "; ")
- (when (cdr ext)
- (mapconcat 'identity (cdr ext) "; "))))
- extensions ", ")))
- (when cookie-header cookie-header)
- (concat (mapconcat (lambda (cons) (format "%s: %s" (car
cons) (cdr cons)))
- custom-headers-alist "\r\n")
- (when custom-headers-alist "\r\n"))
- "\r\n")
- host-port
- key
- protocol)))
-
-(defun websocket-get-server-response (websocket client-protocols
client-extensions)
- "Get the websocket response from client WEBSOCKET."
- (let ((separator "\r\n"))
- (concat "HTTP/1.1 101 Switching Protocols" separator
- "Upgrade: websocket" separator
- "Connection: Upgrade" separator
- "Sec-WebSocket-Accept: "
- (websocket-accept-string websocket) separator
- (let ((protocols
- (websocket-intersect client-protocols
- (websocket-protocols
websocket))))
- (when protocols
- (concat
- (mapconcat
- (lambda (protocol) (format "Sec-WebSocket-Protocol: %s"
- protocol)) protocols separator)
- separator)))
- (let ((extensions (websocket-intersect
- client-extensions
- (websocket-extensions websocket))))
- (when extensions
- (concat
- (mapconcat
- (lambda (extension) (format "Sec-Websocket-Extensions:
%s"
- extension)) extensions separator)
- separator)))
- separator)))
-
-(defun websocket-server-filter (process output)
- "This acts on all OUTPUT from websocket clients PROCESS."
- (let* ((ws (process-get process :websocket))
- (text (concat (websocket-inflight-input ws) output)))
- (setf (websocket-inflight-input ws) nil)
- (cond ((eq (websocket-ready-state ws) 'connecting)
- ;; check for connection string
- (let ((end-of-header-pos
- (let ((pos (string-match "\r\n\r\n" text)))
- (when pos (+ 4 pos)))))
- (if end-of-header-pos
- (progn
- (let ((header-info (websocket-verify-client-headers
text)))
- (if header-info
- (progn (setf (websocket-accept-string ws)
- (websocket-calculate-accept
- (plist-get header-info :key)))
- (process-send-string
- process
- (websocket-get-server-response
- ws (plist-get header-info :protocols)
- (plist-get header-info :extensions)))
- (setf (websocket-ready-state ws) 'open)
- (websocket-try-callback 'websocket-on-open
- 'on-open ws))
- (message "Invalid client headers found in: %s" output)
- (process-send-string process "HTTP/1.1 400 Bad
Request\r\n\r\n")
- (websocket-close ws)))
- (when (> (length text) (+ 1 end-of-header-pos))
- (websocket-server-filter process (substring
- text
-
end-of-header-pos))))
- (setf (websocket-inflight-input ws) text))))
- ((eq (websocket-ready-state ws) 'open)
- (websocket-process-input-on-open-ws ws text))
- ((eq (websocket-ready-state ws) 'closed)
- (message "WARNING: Should not have received further input on closed
websocket")))))
-
-(defun websocket-verify-client-headers (output)
- "Verify the headers from the WEBSOCKET client connection in OUTPUT.
-Unlike `websocket-verify-headers', this is a quieter routine. We
-don't want to error due to a bad client, so we just print out
-messages and a plist containing `:key', the websocket key,
-`:protocols' and `:extensions'."
- (cl-block nil
- (let ((case-fold-search t)
- (plist))
- (unless (string-match "HTTP/1.1" output)
- (message "Websocket client connection: HTTP/1.1 not found")
- (cl-return nil))
- (unless (string-match "^Host: " output)
- (message "Websocket client connection: Host header not found")
- (cl-return nil))
- (unless (string-match "^Upgrade: websocket\r\n" output)
- (message "Websocket client connection: Upgrade: websocket not found")
- (cl-return nil))
- (if (string-match "^Sec-WebSocket-Key: \\([[:graph:]]+\\)\r\n" output)
- (setq plist (plist-put plist :key (match-string 1 output)))
- (message "Websocket client connect: No key sent")
- (cl-return nil))
- (unless (string-match "^Sec-WebSocket-Version: 13" output)
- (message "Websocket client connect: Websocket version 13 not found")
- (cl-return nil))
- (when (string-match "^Sec-WebSocket-Protocol:" output)
- (setq plist (plist-put plist :protocols (websocket-parse-repeated-field
- output
- "Sec-Websocket-Protocol"))))
- (when (string-match "^Sec-WebSocket-Extensions:" output)
- (setq plist (plist-put plist :extensions
(websocket-parse-repeated-field
- output
-
"Sec-Websocket-Extensions"))))
- plist)))
-
-(provide 'websocket)
-
-;;; websocket.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] master f5fd862: * externals-list: Move more :subtrees to :external.,
Stefan Monnier <=