├── screenshot1.png ├── screenshot2.png ├── .gitignore ├── project.clj ├── README.org ├── LICENSE.txt ├── clojure-cheatsheet-tests.el └── clojure-cheatsheet.el /screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clojure-emacs/clojure-cheatsheet/HEAD/screenshot1.png -------------------------------------------------------------------------------- /screenshot2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clojure-emacs/clojure-cheatsheet/HEAD/screenshot2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | /clojure-cheatsheet-autoloads.el 3 | /target 4 | /.nrepl-port 5 | /.lein-repl-history 6 | -------------------------------------------------------------------------------- /project.clj: -------------------------------------------------------------------------------- 1 | (defproject clojure-cheatsheet "0.1.0" 2 | :description "Dependencies for clojure-cheatsheet" 3 | :dependencies [[org.clojure/clojure "1.8.0"] 4 | [org.clojure/data.zip "0.1.2"] 5 | [org.clojure/core.async "0.2.385"]]) 6 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | *This repository is now deprecated*, as the functionality was moved 2 | upstream to [[https://github.com/clojure-emacs/cider][CIDER]] and 3 | [[https://github.com/clojure-emacs/helm-cider][helm-cider]]. 4 | 5 | * Clojure Cheatsheet for Emacs 6 | The incredibly handy [[http://clojure.org/cheatsheet][Clojure Cheatsheet]], updated for Clojure 1.7.0 and 7 | packaged into an easy, fast, searchable, offline form: 8 | 9 | [[screenshot1.png]] 10 | 11 | ** Status 12 | Ready to use. Based on Clojure 1.7.0. 13 | 14 | ** Installation 15 | 16 | If you're hooked up to [[http://melpa.milkbox.net/][MELPA]]: 17 | 18 | #+BEGIN_EXAMPLE 19 | M-x package-refresh-contents 20 | M-x package-install RET clojure-cheatsheet 21 | #+END_EXAMPLE 22 | 23 | Alternatively just grab the single =clojure-cheatsheet.el= file and 24 | install that in your preferred way. 25 | 26 | *** Keybindings 27 | 28 | The cheatsheet doesn't ship with keybindings - people tend to have 29 | strong opinions on them. As a reminder, here's how to define custom 30 | =clojure-mode= keybindings in your own =.emacs= config: 31 | 32 | **** Regular Emacs 33 | #+BEGIN_EXAMPLE 34 | (eval-after-load 'clojure-mode 35 | '(progn 36 | (define-key clojure-mode-map (kbd "C-c C-h") #'clojure-cheatsheet))) 37 | #+END_EXAMPLE 38 | 39 | **** Evil Users 40 | #+BEGIN_EXAMPLE 41 | (evil-define-key 'normal 42 | clojure-mode-map "H" 'clojure-cheatsheet) 43 | #+END_EXAMPLE 44 | 45 | ** Basic Usage 46 | 47 | Call =M-x clojure-cheatsheet= and the cheatsheet will appear. Type 48 | in some terms (space separated) to narrow down the list. For example, 49 | try typing in =sort map= to see some functions that deal with sorting maps. 50 | 51 | *** Keys 52 | 53 | | =C-n= | Next item. | 54 | | =C-p= | Previous item. | 55 | | =C-o= | Next section. | 56 | | =RET= | Jump to the Clojure docs for the current selection. | 57 | | =C-z= | Jump to the Clojure docs for the current selection /without closing the cheatsheet/. | 58 | | =C-e= | Jump to the Clojure src for the current selection. | 59 | | =C-h m= | Full list of keyboard shortcuts. | 60 | 61 | ** Advanced Usage 62 | 63 | This package stands on top of Helm. The variable 64 | =helm-source-clojure-cheatsheet= is available if you want to mix it in 65 | as a Helm source. 66 | 67 | ** See Also 68 | If you like this, and you like org-mode, then you'll probably like 69 | [[https://github.com/emacs-helm/helm-orgcard][helm-orgcard]] too... 70 | 71 | ** Building 72 | 73 | The constant =clojure-cheatsheet-hierarchy= defines the contents of 74 | the cheatsheet. See the docstring of that constant for a full 75 | description of the format. 76 | 77 | There is a test suite in =clojure-cheatsheet-tests.el= 78 | that checks that every symbol defined in the cheatsheet is valid, and 79 | that every symbol defined by Clojure is in the sheet (with a few 80 | explicit exceptions). 81 | 82 | To run the test suite: 83 | 84 | - Clone the project. 85 | - Open =clojure-cheatsheet-tests.el=. 86 | - Call =M-x eval-buffer=. 87 | - Call =M-x cider-jack-in= to start a Clojure REPL. 88 | - Call =M-x ert = to run the test suite. 89 | - Optional: Marvel at Emacs' support for test suites. 90 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Eclipse Public License - v 1.0 2 | 3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC 4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM 5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 6 | 7 | 1. DEFINITIONS 8 | 9 | "Contribution" means: 10 | 11 | a) in the case of the initial Contributor, the initial code and documentation 12 | distributed under this Agreement, and 13 | b) in the case of each subsequent Contributor: 14 | i) changes to the Program, and 15 | ii) additions to the Program; 16 | 17 | where such changes and/or additions to the Program originate from and are 18 | distributed by that particular Contributor. A Contribution 'originates' from 19 | a Contributor if it was added to the Program by such Contributor itself or 20 | anyone acting on such Contributor's behalf. Contributions do not include 21 | additions to the Program which: (i) are separate modules of software 22 | distributed in conjunction with the Program under their own license 23 | agreement, and (ii) are not derivative works of the Program. 24 | 25 | "Contributor" means any person or entity that distributes the Program. 26 | 27 | "Licensed Patents" mean patent claims licensable by a Contributor which are 28 | necessarily infringed by the use or sale of its Contribution alone or when 29 | combined with the Program. 30 | 31 | "Program" means the Contributions distributed in accordance with this Agreement. 32 | 33 | "Recipient" means anyone who receives the Program under this Agreement, 34 | including all Contributors. 35 | 36 | 2. GRANT OF RIGHTS 37 | a) Subject to the terms of this Agreement, each Contributor hereby grants 38 | Recipient a non-exclusive, worldwide, royalty-free copyright license to 39 | reproduce, prepare derivative works of, publicly display, publicly perform, 40 | distribute and sublicense the Contribution of such Contributor, if any, and 41 | such derivative works, in source code and object code form. 42 | b) Subject to the terms of this Agreement, each Contributor hereby grants 43 | Recipient a non-exclusive, worldwide, royalty-free patent license under 44 | Licensed Patents to make, use, sell, offer to sell, import and otherwise 45 | transfer the Contribution of such Contributor, if any, in source code and 46 | object code form. This patent license shall apply to the combination of the 47 | Contribution and the Program if, at the time the Contribution is added by 48 | the Contributor, such addition of the Contribution causes such combination 49 | to be covered by the Licensed Patents. The patent license shall not apply 50 | to any other combinations which include the Contribution. No hardware per 51 | se is licensed hereunder. 52 | c) Recipient understands that although each Contributor grants the licenses to 53 | its Contributions set forth herein, no assurances are provided by any 54 | Contributor that the Program does not infringe the patent or other 55 | intellectual property rights of any other entity. Each Contributor 56 | disclaims any liability to Recipient for claims brought by any other entity 57 | based on infringement of intellectual property rights or otherwise. As a 58 | condition to exercising the rights and licenses granted hereunder, each 59 | Recipient hereby assumes sole responsibility to secure any other 60 | intellectual property rights needed, if any. For example, if a third party 61 | patent license is required to allow Recipient to distribute the Program, it 62 | is Recipient's responsibility to acquire that license before distributing 63 | the Program. 64 | d) Each Contributor represents that to its knowledge it has sufficient 65 | copyright rights in its Contribution, if any, to grant the copyright 66 | license set forth in this Agreement. 67 | 68 | 3. REQUIREMENTS 69 | 70 | A Contributor may choose to distribute the Program in object code form under its 71 | own license agreement, provided that: 72 | 73 | a) it complies with the terms and conditions of this Agreement; and 74 | b) its license agreement: 75 | i) effectively disclaims on behalf of all Contributors all warranties and 76 | conditions, express and implied, including warranties or conditions of 77 | title and non-infringement, and implied warranties or conditions of 78 | merchantability and fitness for a particular purpose; 79 | ii) effectively excludes on behalf of all Contributors all liability for 80 | damages, including direct, indirect, special, incidental and 81 | consequential damages, such as lost profits; 82 | iii) states that any provisions which differ from this Agreement are offered 83 | by that Contributor alone and not by any other party; and 84 | iv) states that source code for the Program is available from such 85 | Contributor, and informs licensees how to obtain it in a reasonable 86 | manner on or through a medium customarily used for software exchange. 87 | 88 | When the Program is made available in source code form: 89 | 90 | a) it must be made available under this Agreement; and 91 | b) a copy of this Agreement must be included with each copy of the Program. 92 | Contributors may not remove or alter any copyright notices contained within 93 | the Program. 94 | 95 | Each Contributor must identify itself as the originator of its Contribution, if 96 | any, in a manner that reasonably allows subsequent Recipients to identify the 97 | originator of the Contribution. 98 | 99 | 4. COMMERCIAL DISTRIBUTION 100 | 101 | Commercial distributors of software may accept certain responsibilities with 102 | respect to end users, business partners and the like. While this license is 103 | intended to facilitate the commercial use of the Program, the Contributor who 104 | includes the Program in a commercial product offering should do so in a manner 105 | which does not create potential liability for other Contributors. Therefore, if 106 | a Contributor includes the Program in a commercial product offering, such 107 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify 108 | every other Contributor ("Indemnified Contributor") against any losses, damages 109 | and costs (collectively "Losses") arising from claims, lawsuits and other legal 110 | actions brought by a third party against the Indemnified Contributor to the 111 | extent caused by the acts or omissions of such Commercial Contributor in 112 | connection with its distribution of the Program in a commercial product 113 | offering. The obligations in this section do not apply to any claims or Losses 114 | relating to any actual or alleged intellectual property infringement. In order 115 | to qualify, an Indemnified Contributor must: a) promptly notify the Commercial 116 | Contributor in writing of such claim, and b) allow the Commercial Contributor to 117 | control, and cooperate with the Commercial Contributor in, the defense and any 118 | related settlement negotiations. The Indemnified Contributor may participate in 119 | any such claim at its own expense. 120 | 121 | For example, a Contributor might include the Program in a commercial product 122 | offering, Product X. That Contributor is then a Commercial Contributor. If that 123 | Commercial Contributor then makes performance claims, or offers warranties 124 | related to Product X, those performance claims and warranties are such 125 | Commercial Contributor's responsibility alone. Under this section, the 126 | Commercial Contributor would have to defend claims against the other 127 | Contributors related to those performance claims and warranties, and if a court 128 | requires any other Contributor to pay any damages as a result, the Commercial 129 | Contributor must pay those damages. 130 | 131 | 5. NO WARRANTY 132 | 133 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN 134 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR 135 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, 136 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each 137 | Recipient is solely responsible for determining the appropriateness of using and 138 | distributing the Program and assumes all risks associated with its exercise of 139 | rights under this Agreement , including but not limited to the risks and costs 140 | of program errors, compliance with applicable laws, damage to or loss of data, 141 | programs or equipment, and unavailability or interruption of operations. 142 | 143 | 6. DISCLAIMER OF LIABILITY 144 | 145 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY 146 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, 147 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST 148 | PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 149 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 150 | OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS 151 | GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 152 | 153 | 7. GENERAL 154 | 155 | If any provision of this Agreement is invalid or unenforceable under applicable 156 | law, it shall not affect the validity or enforceability of the remainder of the 157 | terms of this Agreement, and without further action by the parties hereto, such 158 | provision shall be reformed to the minimum extent necessary to make such 159 | provision valid and enforceable. 160 | 161 | If Recipient institutes patent litigation against any entity (including a 162 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself 163 | (excluding combinations of the Program with other software or hardware) 164 | infringes such Recipient's patent(s), then such Recipient's rights granted under 165 | Section 2(b) shall terminate as of the date such litigation is filed. 166 | 167 | All Recipient's rights under this Agreement shall terminate if it fails to 168 | comply with any of the material terms or conditions of this Agreement and does 169 | not cure such failure in a reasonable period of time after becoming aware of 170 | such noncompliance. If all Recipient's rights under this Agreement terminate, 171 | Recipient agrees to cease use and distribution of the Program as soon as 172 | reasonably practicable. However, Recipient's obligations under this Agreement 173 | and any licenses granted by Recipient relating to the Program shall continue and 174 | survive. 175 | 176 | Everyone is permitted to copy and distribute copies of this Agreement, but in 177 | order to avoid inconsistency the Agreement is copyrighted and may only be 178 | modified in the following manner. The Agreement Steward reserves the right to 179 | publish new versions (including revisions) of this Agreement from time to time. 180 | No one other than the Agreement Steward has the right to modify this Agreement. 181 | The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation 182 | may assign the responsibility to serve as the Agreement Steward to a suitable 183 | separate entity. Each new version of the Agreement will be given a 184 | distinguishing version number. The Program (including Contributions) may always 185 | be distributed subject to the version of the Agreement under which it was 186 | received. In addition, after a new version of the Agreement is published, 187 | Contributor may elect to distribute the Program (including its Contributions) 188 | under the new version. Except as expressly stated in Sections 2(a) and 2(b) 189 | above, Recipient receives no rights or licenses to the intellectual property of 190 | any Contributor under this Agreement, whether expressly, by implication, 191 | estoppel or otherwise. All rights in the Program not expressly granted under 192 | this Agreement are reserved. 193 | 194 | This Agreement is governed by the laws of the State of New York and the 195 | intellectual property laws of the United States of America. No party to this 196 | Agreement will bring a legal action under this Agreement more than one year 197 | after the cause of action arose. Each party waives its rights to a jury trial in 198 | any resulting litigation. 199 | -------------------------------------------------------------------------------- /clojure-cheatsheet-tests.el: -------------------------------------------------------------------------------- 1 | ;;; clojure-cheatsheet-tests.el --- The Clojure Cheatsheet for Emacs tests. 2 | 3 | ;;; Commentary: 4 | ;; 5 | ;; The Clojure Cheatsheet for Emacs tests. Note that to run this test 6 | ;; suite, you'll need to be running a CIDER session, connected to a 7 | ;; Clojure project with all the Cheatsheet's namespaces available. 8 | 9 | (require 'ert) 10 | (require 'cl-lib) 11 | (require 'cider-interaction) 12 | (require 'nrepl-client) 13 | (require 'dash) 14 | (require 'clojure-cheatsheet) 15 | 16 | ;;; Code: 17 | 18 | (defmacro should-propagate-to 19 | (form result) 20 | `(should (equal (clojure-cheatsheet/propagate-headings (quote ,form)) 21 | (quote ,result)))) 22 | 23 | (ert-deftest clojure-cheatsheet/propagate-headings-tests () 24 | (should-propagate-to (kaj +) 25 | (kaj/+)) 26 | (should-propagate-to (clojure.core + -) 27 | (clojure.core/+ clojure.core/-)) 28 | (should-propagate-to ("Level 1" (clojure.core + -)) 29 | (("Level 1" clojure.core/+ clojure.core/-))) 30 | (should-propagate-to ("Level 1" (:special def var)) 31 | (("Level 1" def var))) 32 | (should-propagate-to ("Level 1" 33 | ("Level 2" 34 | (clojure.core + -))) 35 | ((("Level 1 : Level 2" clojure.core/+ clojure.core/-)))) 36 | (should-propagate-to ("Level 1" 37 | (clojure.set union diff) 38 | ("Level 2" 39 | (clojure.core + -))) 40 | (("Level 1" clojure.set/union clojure.set/diff) 41 | (("Level 1 : Level 2" clojure.core/+ clojure.core/-))))) 42 | 43 | (ert-deftest flatten-hierarchy () 44 | (should (equal (clojure-cheatsheet/->> '("Top" 45 | (clojure.core -> ->>) 46 | ("Sub 1" 47 | (:url "Explanation" "http://clojure.org/protocols") 48 | (:special def var) 49 | (clojure.xml data zip) 50 | (clojure.thing this))) 51 | clojure-cheatsheet/propagate-headings 52 | clojure-cheatsheet/flatten 53 | clojure-cheatsheet/group-by-head) 54 | '(("Top" clojure.core/-> clojure.core/->>) 55 | ("Top : Sub 1" 56 | (:url "Explanation" "http://clojure.org/protocols") 57 | def 58 | var 59 | clojure.xml/data clojure.xml/zip clojure.thing/this))))) 60 | 61 | (defun strip-all-but-namespace-lists (node) 62 | (cond ((not (listp node)) node) 63 | ((keywordp (car node)) nil) 64 | ((stringp (car node)) (cdr node)) 65 | (t node))) 66 | 67 | (defun extract-namespaces (node) 68 | (cond ((not (listp node)) node) 69 | ((keywordp (car node)) nil) 70 | ((stringp (car node)) (cdr node)) 71 | ((symbolp (car node)) (list (car node))) 72 | (t node))) 73 | 74 | (defun qualify-all-symbols (node) 75 | (if (and (listp node) 76 | (car node) 77 | (symbolp (car node))) 78 | (mapcar (apply-partially #'clojure-cheatsheet/symbol-qualifier (car node)) 79 | (cdr node)) 80 | node)) 81 | 82 | (defun all-cheatsheet-symbols-qualified () 83 | (clojure-cheatsheet/->> clojure-cheatsheet-hierarchy 84 | (clojure-cheatsheet/treewalk #'strip-all-but-namespace-lists 85 | #'qualify-all-symbols) 86 | clojure-cheatsheet/flatten 87 | (apply #'append))) 88 | 89 | (defun all-namespaces () 90 | (clojure-cheatsheet/->> clojure-cheatsheet-hierarchy 91 | (clojure-cheatsheet/treewalk #'extract-namespaces 92 | #'identity) 93 | clojure-cheatsheet/flatten 94 | (apply #'append) 95 | -uniq)) 96 | 97 | (defun require-namespace 98 | (namespace) 99 | (message "Requiring: %s" namespace) 100 | (let ((result (cider-nrepl-sync-request:eval (format "(require '%s)" namespace)))) 101 | (should (nrepl-dict-get result "status")))) 102 | 103 | (defun check-symbol-bound 104 | (symbol) 105 | (message "Checking: %s" symbol) 106 | (should (nrepl-dict-get (cider-sync-request:info (symbol-name symbol)) 107 | "status"))) 108 | 109 | (ert-deftest test-clojure-function-references () 110 | "Ensure that every function we've defined can actually be found at the REPL." 111 | 112 | (should (cider-current-connection)) 113 | 114 | (mapc #'require-namespace 115 | (all-namespaces)) 116 | 117 | (mapc #'check-symbol-bound 118 | (all-cheatsheet-symbols-qualified))) 119 | 120 | (defun all-cider-symbols-qualified () 121 | (apply 'append 122 | (mapcar (lambda (namespace) 123 | (require-namespace namespace) 124 | (mapcar (lambda (symbol) 125 | (clojure-cheatsheet/symbol-qualifier namespace symbol)) 126 | (cider-sync-request:ns-vars (symbol-name namespace)))) 127 | (all-namespaces)))) 128 | 129 | (ert-deftest test-all-symbols-accounted-for () 130 | "Checks that, for every namespace the cheatsheet covers, it covers every var in that namespace. 131 | eg. If the cheatsheet covers clojure.repl, it should have an entry for everything in clojure.repl." 132 | 133 | (let ((ignorable '(clojure.java.io/IOFactory 134 | clojure.core/*allow-unresolved-vars* 135 | clojure.core/*assert* 136 | clojure.core/*compiler-options* 137 | clojure.core/*suppress-read* 138 | clojure.core/*flush-on-newline* 139 | clojure.core/*fn-loader* 140 | clojure.core/*math-context* 141 | clojure.core/*read-eval* 142 | clojure.core/*source-path* 143 | clojure.core/*use-context-classloader* 144 | clojure.core/*verbose-defrecords* 145 | clojure.core/->ArrayChunk 146 | clojure.core/->Vec 147 | clojure.core/->VecNode 148 | clojure.core/->VecSeq 149 | clojure.core/-cache-protocol-fn 150 | clojure.core/-reset-methods 151 | clojure.core/EMPTY-NODE 152 | clojure.core/accessor 153 | clojure.core/add-classpath 154 | clojure.core/defstruct 155 | clojure.core/agent-errors 156 | clojure.core/clear-agent-errors 157 | clojure.data/diff-similar 158 | clojure.data/equality-partition 159 | clojure.data/Diff 160 | clojure.data/EqualityPartition 161 | clojure.core/chunk 162 | clojure.core/chunk-append 163 | clojure.core/chunk-buffer 164 | clojure.core/chunk-cons 165 | clojure.core/chunk-first 166 | clojure.core/chunk-next 167 | clojure.core/chunk-rest 168 | clojure.core/replicate 169 | clojure.core/destructure 170 | 171 | clojure.core.async/Mix 172 | clojure.core.async/Mult 173 | clojure.core.async/Mux 174 | clojure.core.async/Pub 175 | clojure.core.async/admix* 176 | clojure.core.async/do-alt 177 | clojure.core.async/fn-handler 178 | clojure.core.async/ioc-alts! 179 | clojure.core.async/muxch* 180 | clojure.core.async/solo-mode* 181 | clojure.core.async/sub* 182 | clojure.core.async/tap* 183 | clojure.core.async/toggle* 184 | clojure.core.async/unmix* 185 | clojure.core.async/unmix-all* 186 | clojure.core.async/unsub* 187 | clojure.core.async/unsub-all* 188 | clojure.core.async/untap* 189 | clojure.core.async/untap-all* 190 | 191 | clojure.test/*initial-report-counters* 192 | clojure.test/*load-tests* 193 | clojure.test/*report-counters* 194 | clojure.test/*stack-trace-depth* 195 | clojure.test/*test-out* 196 | clojure.test/*testing-contexts* 197 | clojure.test/*testing-vars* 198 | clojure.test/assert-any 199 | clojure.test/assert-expr 200 | clojure.test/assert-predicate 201 | clojure.test/do-report 202 | clojure.test/file-position 203 | clojure.test/function? 204 | clojure.test/get-possibly-unbound-var 205 | clojure.test/inc-report-counter 206 | clojure.test/report 207 | clojure.test/set-test 208 | clojure.test/successful? 209 | clojure.test/test-all-vars 210 | clojure.test/test-ns 211 | clojure.test/test-var 212 | clojure.test/testing 213 | clojure.test/testing-contexts-str 214 | clojure.test/testing-vars-str 215 | clojure.test/try-expr 216 | clojure.test/with-test 217 | clojure.test/with-test-out)) 218 | 219 | (unfiled '(clojure.core/await1 220 | clojure.repl/set-break-handler! 221 | clojure.core/bound? 222 | 223 | clojure.core/construct-proxy 224 | clojure.core/create-struct 225 | clojure.core/find-protocol-impl 226 | clojure.core/find-protocol-method 227 | clojure.core/get-proxy-class 228 | clojure.core/hash-combine 229 | clojure.core/init-proxy 230 | clojure.core/method-sig 231 | clojure.core/munge 232 | clojure.core/namespace-munge 233 | clojure.core/primitives-classnames 234 | clojure.core/print-ctor 235 | clojure.core/print-dup 236 | clojure.core/print-method 237 | clojure.core/print-simple 238 | clojure.core/proxy 239 | clojure.core/proxy-call-with-super 240 | clojure.core/proxy-mappings 241 | clojure.core/proxy-name 242 | clojure.core/proxy-super 243 | clojure.core/reduced 244 | clojure.core/reset-meta 245 | clojure.core/struct 246 | clojure.core/struct-map 247 | clojure.core/thread-bound? 248 | clojure.core/underive 249 | clojure.core/unquote 250 | clojure.core/unquote-splicing 251 | clojure.core/update-proxy 252 | clojure.core/with-bindings 253 | clojure.core/with-bindings* 254 | clojure.core/with-loading-context 255 | clojure.xml/*current* 256 | clojure.xml/*sb* 257 | clojure.xml/*stack* 258 | clojure.xml/*state* 259 | clojure.xml/attrs 260 | clojure.xml/content 261 | clojure.xml/content-handler 262 | clojure.xml/element 263 | clojure.xml/emit 264 | clojure.xml/emit-element 265 | clojure.xml/startparse-sax 266 | clojure.xml/tag 267 | clojure.pprint/*print-base* 268 | clojure.pprint/*print-miser-width* 269 | clojure.pprint/*print-pprint-dispatch* 270 | clojure.pprint/*print-pretty* 271 | clojure.pprint/*print-radix* 272 | clojure.pprint/*print-suppress-namespaces* 273 | clojure.pprint/code-dispatch 274 | clojure.pprint/formatter 275 | clojure.pprint/formatter-out 276 | clojure.pprint/fresh-line 277 | clojure.pprint/get-pretty-writer 278 | clojure.pprint/pprint-indent 279 | clojure.pprint/pprint-logical-block 280 | clojure.pprint/pprint-newline 281 | clojure.pprint/pprint-tab 282 | clojure.pprint/print-length-loop 283 | clojure.pprint/set-pprint-dispatch 284 | clojure.pprint/simple-dispatch 285 | clojure.pprint/with-pprint-dispatch 286 | clojure.pprint/write 287 | clojure.pprint/write-out 288 | clojure.java.browse/*open-url-script* 289 | clojure.java.shell/*sh-dir* 290 | clojure.java.shell/*sh-env* 291 | clojure.repl/demunge 292 | clojure.repl/root-cause 293 | clojure.repl/set-break-handler 294 | clojure.repl/stack-element-str 295 | clojure.repl/thread-stopper 296 | clojure.java.javadoc/*core-java-api* 297 | clojure.java.javadoc/*feeling-lucky* 298 | clojure.java.javadoc/*feeling-lucky-url* 299 | clojure.java.javadoc/*local-javadocs* 300 | clojure.java.javadoc/*remote-javadocs* 301 | clojure.java.javadoc/add-local-javadoc 302 | clojure.java.javadoc/add-remote-javadoc 303 | clojure.java.io/Coercions 304 | clojure.java.io/default-streams-impl 305 | ))) 306 | (should 307 | (not (cl-set-difference 308 | (cl-set-difference 309 | (all-cider-symbols-qualified) 310 | (all-cheatsheet-symbols-qualified)) 311 | (append ignorable unfiled)))))) 312 | 313 | (provide 'clojure-cheatsheet-tests) 314 | 315 | ;;; clojure-cheatsheet-tests.el ends here 316 | -------------------------------------------------------------------------------- /clojure-cheatsheet.el: -------------------------------------------------------------------------------- 1 | ;;; clojure-cheatsheet.el --- The Clojure Cheatsheet for Emacs 2 | 3 | ;; Copyright 2013-2016 Kris Jenkins 4 | 5 | ;; Author: Kris Jenkins 6 | ;; Maintainer: Kris Jenkins 7 | ;; Keywords: clojure cider cheatsheet helm 8 | ;; URL: https://github.com/clojure-emacs/clojure-cheatsheet 9 | ;; Created: 7th August 2013 10 | ;; Version: 0.4.0 11 | ;; Package-Requires: ((helm "1.7.7") (cider "0.9.0")) ;; TODO Helm core? 12 | 13 | ;; This file is not part of GNU Emacs. 14 | 15 | ;;; Commentary: 16 | 17 | ;; A quick reference system for Clojure. Fast, searchable & available offline. 18 | 19 | ;;; License: 20 | 21 | ;; This program is free software; you can redistribute it and/or 22 | ;; modify it under the terms of the GNU General Public License 23 | ;; as published by the Free Software Foundation; either version 3 24 | ;; of the License, or (at your option) any later version. 25 | ;; 26 | ;; This program is distributed in the hope that it will be useful, 27 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 28 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 | ;; GNU General Public License for more details. 30 | ;; 31 | ;; You should have received a copy of the GNU General Public License 32 | ;; along with GNU Emacs; see the file COPYING. If not, write to the 33 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 34 | ;; Boston, MA 02110-1301, USA. 35 | 36 | ;;; Code: 37 | 38 | (require 'helm) 39 | (require 'helm-multi-match) 40 | (require 'cider-interaction) 41 | (require 'cl-lib) 42 | 43 | (warn "This package is now deprecated as its functionality was fully integrated into CIDER and helm-cider") 44 | 45 | (defconst clojure-cheatsheet-hierarchy 46 | '(("Primitives" 47 | ("Numbers" 48 | ("Arithmetic" 49 | (clojure.core + - * / quot rem mod dec inc max min)) 50 | ("Compare" 51 | (clojure.core = == not= < > <= >= compare)) 52 | ("Bitwise" 53 | (clojure.core bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set bit-shift-left bit-shift-right bit-test bit-xor unsigned-bit-shift-right)) 54 | ("Cast" 55 | (clojure.core byte short long int float double bigdec bigint biginteger num rationalize)) 56 | ("Test" 57 | (clojure.core nil? some? identical? zero? pos? neg? even? odd?)) 58 | ("Random" 59 | (clojure.core rand rand-int)) 60 | ("BigDecimal" 61 | (clojure.core with-precision)) 62 | ("Ratios" 63 | (clojure.core numerator denominator ratio?)) 64 | ("Arbitrary Precision Arithmetic" 65 | (clojure.core +\' -\' *\' inc\' dec\')) 66 | ("Unchecked" 67 | (clojure.core *unchecked-math* 68 | unchecked-add 69 | unchecked-add-int 70 | unchecked-byte 71 | unchecked-char 72 | unchecked-dec 73 | unchecked-dec-int 74 | unchecked-divide-int 75 | unchecked-double 76 | unchecked-float 77 | unchecked-inc 78 | unchecked-inc-int 79 | unchecked-int 80 | unchecked-long 81 | unchecked-multiply 82 | unchecked-multiply-int 83 | unchecked-negate 84 | unchecked-negate-int 85 | unchecked-remainder-int 86 | unchecked-short 87 | unchecked-subtract 88 | unchecked-subtract-int))) 89 | 90 | ("Strings" 91 | ("Create" 92 | (clojure.core str format)) 93 | ("Use" 94 | (clojure.core count get subs compare) 95 | (clojure.string join escape split split-lines replace replace-first reverse re-quote-replacement index-of last-index-of starts-with? ends-with? includes?)) 96 | ("Regex" 97 | (:url "Java's Regex Syntax" "http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html") 98 | (clojure.core re-find re-seq re-matches re-pattern re-matcher re-groups) 99 | (clojure.string replace replace-first re-quote-replacement)) 100 | ("Letters" 101 | (clojure.string capitalize lower-case upper-case)) 102 | ("Trim" 103 | (clojure.string trim trim-newline triml trimr)) 104 | ("Test" 105 | (clojure.core char char? string?) 106 | (clojure.string blank?))) 107 | 108 | ("Other" 109 | ("Characters" 110 | (clojure.core char char-name-string char-escape-string)) 111 | ("Keywords" 112 | (clojure.core keyword keyword? find-keyword)) 113 | ("Symbols" 114 | (clojure.core symbol symbol? gensym)) 115 | ("Data Readers" 116 | (clojure.core *data-readers* default-data-readers *default-data-reader-fn*)))) 117 | 118 | ("Collections" 119 | ("Generic Ops" 120 | (clojure.core count empty not-empty into conj)) 121 | ("Tree Walking" 122 | (clojure.walk walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace keywordize-keys stringify-keys)) 123 | ("Content tests" 124 | (clojure.core distinct? empty? every? not-every? some not-any?)) 125 | ("Capabilities" 126 | (clojure.core sequential? associative? sorted? counted? reversible?)) 127 | ("Type tests" 128 | (clojure.core type class coll? list? vector? set? map? seq? 129 | number? integer? float? decimal? class? rational? ratio? 130 | chunked-seq? reduced? special-symbol? record?)) 131 | ("Lists" 132 | ("Create" 133 | (clojure.core list list*)) 134 | ("Examine" 135 | (clojure.core first nth peek)) 136 | ("'Change'" 137 | (clojure.core cons conj rest pop))) 138 | 139 | ("Vectors" 140 | ("Create" 141 | (clojure.core vec vector vector-of)) 142 | ("Examine" 143 | (clojure.core get peek)) 144 | 145 | ("'Change'" 146 | (clojure.core assoc pop subvec replace conj rseq)) 147 | ("Ops" 148 | (clojure.core mapv filterv reduce-kv))) 149 | 150 | ("Sets" 151 | ("Create" 152 | (clojure.core set hash-set sorted-set sorted-set-by)) 153 | ("Examine" 154 | (clojure.core get contains?)) 155 | ("'Change'" 156 | (clojure.core conj disj)) 157 | ("Relational Algebra" 158 | (clojure.set join select project union difference intersection)) 159 | ("Get map" 160 | (clojure.set index rename-keys rename map-invert)) 161 | ("Test" 162 | (clojure.set subset? superset?))) 163 | 164 | ("Maps" 165 | ("Create" 166 | (clojure.core hash-map array-map zipmap sorted-map sorted-map-by bean frequencies group-by)) 167 | ("Examine" 168 | (clojure.core get get-in contains? find keys vals map-entry?)) 169 | ("'Change'" 170 | (clojure.core assoc assoc-in dissoc merge merge-with select-keys update update-in)) 171 | ("Entry" 172 | (clojure.core key val)) 173 | ("Sorted Maps" 174 | (clojure.core rseq subseq rsubseq))) 175 | 176 | ("Hashes" 177 | (clojure.core hash hash-ordered-coll hash-unordered-coll mix-collection-hash)) 178 | 179 | ("Volatiles" 180 | (clojure.core volatile! volatile? vreset! vswap!))) 181 | 182 | ("Functions" 183 | ("Create" 184 | (clojure.core fn defn defn- definline identity constantly comp complement partial juxt memfn memoize fnil every-pred some-fn trampoline)) 185 | ("Call" 186 | (clojure.core -> ->> some-> some->> as-> cond-> cond->>)) 187 | ("Test" 188 | (clojure.core fn? ifn?))) 189 | 190 | ("Transducers" 191 | ("Create" 192 | (clojure.core cat dedupe distinct drop drop-while filter interpose keep keep-indexed map map-indexed mapcat partition-all partition-by random-sample remove replace take take-nth take-while)) 193 | ("Call" 194 | (clojure.core ->Eduction eduction into sequence transduce completing run!)) 195 | ("Early Termination" 196 | (clojure.core deref reduced reduced? ensure-reduced unreduced))) 197 | 198 | ("Other" 199 | ("XML" 200 | (clojure.core xml-seq) 201 | (clojure.xml parse)) 202 | ("REPL" 203 | (clojure.core *1 *2 *3 *e *print-dup* *print-length* *print-level* *print-meta* *print-readably*)) 204 | ("EDN" 205 | (clojure.edn read read-string)) 206 | ("Compiling Code & Class Generation" 207 | (:url "Documentation" "http://clojure.org/compilation") 208 | (clojure.core *compile-files* *compile-path* *file* *warn-on-reflection* compile gen-class gen-interface loaded-libs test)) 209 | ("Misc" 210 | (clojure.core eval force name *clojure-version* clojure-version *command-line-args*)) 211 | ("Pretty Printing" 212 | (clojure.pprint pprint print-table pp *print-right-margin*)) 213 | ("Browser / Shell" 214 | (clojure.java.browse browse-url) 215 | (clojure.java.shell sh with-sh-dir with-sh-env))) 216 | 217 | ("Vars & Global Environment" 218 | (:url "Documentation" "http://clojure.org/vars") 219 | ("Def Variants" 220 | (:special def) 221 | (clojure.core defn defn- definline defmacro defmethod defmulti defonce defrecord)) 222 | ("Interned Vars" 223 | (:special var) 224 | (clojure.core declare intern binding find-var)) 225 | ("Var Objects" 226 | (clojure.core with-local-vars var-get var-set alter-var-root var?)) 227 | ("Var Validators" 228 | (clojure.core set-validator! get-validator))) 229 | 230 | ("Reader Conditionals" 231 | (clojure.core reader-conditional reader-conditional? tagged-literal tagged-literal?)) 232 | 233 | ("Abstractions" 234 | ("Protocols" 235 | (:url "Documentation" "http://clojure.org/protocols") 236 | (clojure.core defprotocol extend extend-type extend-protocol reify extends? satisfies? extenders)) 237 | ("Records & Types" 238 | (:url "Documentation" "http://clojure.org/datatypes") 239 | (clojure.core defrecord deftype)) 240 | ("Multimethods" 241 | (:url "Documentation" "http://clojure.org/multimethods") 242 | ("Define" 243 | (clojure.core defmulti defmethod)) 244 | ("Dispatch" 245 | (clojure.core get-method methods)) 246 | ("Remove" 247 | (clojure.core remove-method remove-all-methods)) 248 | ("Prefer" 249 | (clojure.core prefer-method prefers)) 250 | ("Relation" 251 | (clojure.core derive isa? parents ancestors descendants make-hierarchy)))) 252 | 253 | ("Macros" 254 | (:url "Documentation" "http://clojure.org/macros") 255 | ("Create" 256 | (clojure.core defmacro definline)) 257 | ("Debug" 258 | (clojure.core macroexpand-1 macroexpand) 259 | (clojure.walk macroexpand-all)) 260 | ("Branch" 261 | (clojure.core and or when when-not when-let when-first if-not if-let cond condp case)) 262 | ("Loop" 263 | (clojure.core for doseq dotimes while)) 264 | ("Arrange" 265 | (clojure.core .. doto ->)) 266 | ("Scope" 267 | (clojure.core binding locking time) 268 | (clojure.core with-in-str with-local-vars with-open with-out-str with-precision with-redefs with-redefs-fn)) 269 | ("Lazy" 270 | (clojure.core lazy-cat lazy-seq delay delay?)) 271 | ("Doc." 272 | (clojure.core assert comment) 273 | (clojure.repl doc dir dir-fn source-fn))) 274 | 275 | ("Java Interop" 276 | (:url "Documentation" "http://clojure.org/java_interop") 277 | ("General" 278 | (:special new set!) 279 | (clojure.core .. doto bean comparator enumeration-seq import iterator-seq memfn definterface supers bases)) 280 | ("Cast" 281 | (clojure.core boolean byte short char int long float double bigdec bigint num cast biginteger)) 282 | ("Java Arrays" 283 | ("Create" 284 | (clojure.core boolean-array byte-array double-array char-array float-array int-array long-array make-array object-array short-array to-array)) 285 | ("Manipulate" 286 | (clojure.core aclone aget aset alength amap areduce aset-int aset-long aset-short aset-boolean aset-byte aset-char aset-double aset-float)) 287 | ("Cast" 288 | (clojure.core booleans bytes chars doubles floats ints longs shorts))) 289 | ("Exceptions" 290 | (:special throw try catch finally) 291 | (clojure.core ex-info ex-data Throwable->map) 292 | (clojure.repl pst))) 293 | 294 | ("Namespaces" 295 | (:url "Documentation" "http://clojure.org/namespaces") 296 | ("Current" 297 | (clojure.core *ns*)) 298 | ("Create Switch" 299 | (clojure.core ns in-ns create-ns)) 300 | ("Add" 301 | (clojure.core alias import intern refer refer-clojure)) 302 | ("Find" 303 | (clojure.core all-ns find-ns)) 304 | ("Examine" 305 | (clojure.core ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers)) 306 | ("From symbol" 307 | (clojure.core resolve namespace ns-resolve the-ns)) 308 | ("Remove" 309 | (clojure.core ns-unalias ns-unmap remove-ns))) 310 | ("Loading" 311 | ("Load libs" 312 | (clojure.core require use import refer)) 313 | ("List Loaded" 314 | (clojure.core loaded-libs)) 315 | ("Load Misc" 316 | (clojure.core load load-file load-reader load-string))) 317 | 318 | ("Concurrency" 319 | (:url "Documentation" "http://clojure.org/atoms") 320 | ("Atoms" 321 | (clojure.core atom swap! reset! compare-and-set!)) 322 | ("Futures" 323 | (clojure.core future future-call future-cancel future-cancelled? future-done? future?)) 324 | ("Threads" 325 | (clojure.core bound-fn bound-fn* get-thread-bindings pop-thread-bindings push-thread-bindings)) 326 | 327 | ("Misc" 328 | (clojure.core locking pcalls pvalues pmap seque promise deliver)) 329 | 330 | ("Refs & Transactions" 331 | (:url "Documentation" "http://clojure.org/refs") 332 | ("Create" 333 | (clojure.core ref)) 334 | ("Examine" 335 | (clojure.core deref)) 336 | ("Transaction" 337 | (clojure.core sync dosync io!)) 338 | ("In Transaction" 339 | (clojure.core ensure ref-set alter commute)) 340 | ("Validators" 341 | (clojure.core get-validator set-validator!)) 342 | ("History" 343 | (clojure.core ref-history-count ref-max-history ref-min-history))) 344 | 345 | ("Agents & Asynchronous Actions" 346 | (:url "Documentation" "http://clojure.org/agents") 347 | ("Create" 348 | (clojure.core agent)) 349 | ("Examine" 350 | (clojure.core agent-error)) 351 | ("Change State" 352 | (clojure.core send send-off restart-agent send-via set-agent-send-executor! set-agent-send-off-executor!)) 353 | ("Block Waiting" 354 | (clojure.core await await-for)) 355 | ("Ref Validators" 356 | (clojure.core get-validator set-validator!)) 357 | ("Watchers" 358 | (clojure.core add-watch remove-watch)) 359 | ("Thread Handling" 360 | (clojure.core shutdown-agents)) 361 | ("Error" 362 | (clojure.core error-handler set-error-handler! error-mode set-error-mode!)) 363 | ("Misc" 364 | (clojure.core *agent* release-pending-sends)))) 365 | 366 | ("Sequences" 367 | ("Creating a Lazy Seq" 368 | ("From Collection" 369 | (clojure.core seq sequence keys vals rseq subseq rsubseq)) 370 | ("From Producer Fn" 371 | (clojure.core lazy-seq repeatedly iterate)) 372 | ("From Constant" 373 | (clojure.core repeat range)) 374 | ("From Other" 375 | (clojure.core file-seq line-seq resultset-seq re-seq tree-seq xml-seq iterator-seq enumeration-seq)) 376 | ("From Seq" 377 | (clojure.core keep keep-indexed))) 378 | 379 | ("Seq in, Seq out" 380 | ("Get shorter" 381 | (clojure.core distinct dedupe filter remove for)) 382 | ("Get longer" 383 | (clojure.core cons conj concat lazy-cat mapcat cycle interleave interpose))) 384 | ("Tail-items" 385 | (clojure.core rest nthrest fnext nnext drop drop-while take-last for)) 386 | ("Head-items" 387 | (clojure.core take take-nth take-while butlast drop-last for)) 388 | ("'Change'" 389 | (clojure.core conj concat distinct flatten group-by partition partition-all partition-by split-at split-with filter remove replace shuffle random-sample)) 390 | ("Rearrange" 391 | (clojure.core reverse sort sort-by compare)) 392 | ("Process items" 393 | (clojure.core map pmap map-indexed mapcat for replace seque)) 394 | 395 | ("Using a Seq" 396 | ("Extract item" 397 | (clojure.core first second last rest next ffirst nfirst fnext nnext nth nthnext rand-nth when-first max-key min-key)) 398 | ("Construct coll" 399 | (clojure.core zipmap into reduce reductions set vec into-array to-array-2d)) 400 | ("Pass to fn" 401 | (clojure.core apply)) 402 | ("Search" 403 | (clojure.core some filter)) 404 | ("Force evaluation" 405 | (clojure.core doseq dorun doall)) 406 | ("Check for forced" 407 | (clojure.core realized?)))) 408 | 409 | ("Zippers" 410 | ("Create" 411 | (clojure.zip zipper seq-zip vector-zip xml-zip)) 412 | ("Get loc" 413 | (clojure.zip up down left right leftmost rightmost)) 414 | ("Get seq" 415 | (clojure.zip lefts rights path children)) 416 | ("'Change'" 417 | (clojure.zip make-node replace edit insert-child insert-left insert-right append-child remove)) 418 | ("Move" 419 | (clojure.zip next prev)) 420 | ("XML" 421 | (clojure.data.zip.xml attr attr= seq-test tag= text text= xml-> xml1->)) 422 | ("Misc" 423 | (clojure.zip root node branch? end?))) 424 | 425 | ("Documentation" 426 | ("REPL" 427 | (clojure.repl doc find-doc apropos source pst) 428 | (clojure.java.javadoc javadoc))) 429 | 430 | ("Transients" 431 | (:url "Documentation" "http://clojure.org/transients") 432 | ("Create") 433 | (clojure.core transient persistent!) 434 | ("Change") 435 | (clojure.core conj! pop! assoc! dissoc! disj!)) 436 | ("Misc" 437 | ("Compare" 438 | (clojure.core = == identical? not= not compare) 439 | (clojure.data diff)) 440 | ("Test" 441 | (clojure.core true? false? nil? instance?))) 442 | 443 | ("IO" 444 | ("To/from ..." 445 | (clojure.core spit slurp)) 446 | ("To *out*" 447 | (clojure.core pr prn print printf println newline) 448 | (clojure.pprint print-table)) 449 | ("To writer" 450 | (clojure.pprint pprint cl-format)) 451 | ("To string" 452 | (clojure.core format with-out-str pr-str prn-str print-str println-str)) 453 | ("From *in*" 454 | (clojure.core read-line read)) 455 | ("From reader" 456 | (clojure.core line-seq read)) 457 | ("From string" 458 | (clojure.core read-string with-in-str)) 459 | ("Open" 460 | (clojure.core with-open) 461 | (clojure.java.io reader writer input-stream output-stream)) 462 | ("Interop" 463 | (clojure.java.io make-writer make-reader make-output-stream make-input-stream)) 464 | ("Misc" 465 | (clojure.core flush file-seq *in* *out* *err*) 466 | (clojure.java.io file copy delete-file resource as-file as-url as-relative-path make-parents))) 467 | 468 | ("Metadata" 469 | (clojure.core meta with-meta alter-meta! reset-meta! vary-meta)) 470 | 471 | ("Special Forms" 472 | (:url "Documentation" "http://clojure.org/special_forms") 473 | (:special def if do quote var recur throw try monitor-enter monitor-exit) 474 | (clojure.core fn loop) 475 | ("Binding / Destructuring" 476 | (clojure.core let fn letfn defn defmacro loop for doseq if-let if-some when-let when-some))) 477 | ("Async" 478 | ("Main" 479 | (clojure.core.async go go-loop ! >!! chan put! take take! close! timeout offer! poll! promise-chan)) 480 | ("Choice" 481 | (clojure.core.async alt! alt!! alts! alts!! do-alts)) 482 | ("Buffering" 483 | (clojure.core.async buffer dropping-buffer sliding-buffer unblocking-buffer?)) 484 | ("Pipelines" 485 | (clojure.core.async pipeline pipeline-async pipeline-blocking)) 486 | ("Threading" 487 | (clojure.core.async thread thread-call)) 488 | 489 | ("Mixing" 490 | (clojure.core.async admix solo-mode mix unmix unmix-all toggle merge pipe unique)) 491 | ("Multiples" 492 | (clojure.core.async mult tap untap untap-all)) 493 | ("Publish/Subscribe" 494 | (clojure.core.async pub sub unsub unsub-all)) 495 | ("Higher Order" 496 | (clojure.core.async filter< filter> map map< map> mapcat< mapcat> partition partition-by reduce remove< remove> split)) 497 | ("Pre-Populate" 498 | (clojure.core.async into onto-chan to-chan))) 499 | ("Unit Tests" 500 | ("Defining" 501 | (clojure.test deftest deftest- testing is are)) 502 | ("Running" 503 | (clojure.test run-tests run-all-tests test-vars)) 504 | ("Fixtures" 505 | (clojure.test use-fixtures join-fixtures compose-fixtures)))) 506 | "A data structure designed for the maintainer's convenience, which we 507 | transform into the format that helm requires. 508 | 509 | It's a tree, where the head of each list determines the context of the rest of the list. 510 | The head may be: 511 | 512 | A string, in which case it's a (sub)heading for the rest of the items. 513 | A symbol, in which case it's the Clojure namespace of the symbols that follow it. 514 | The keyword :special, in which case it's a Clojure special form - a symbol with no 515 | Any other keyword, in which case it's a typed item that will be passed 516 | through and handled in `clojure-cheatsheet/item-to-helm-source'. 517 | 518 | Note that some many Clojure symbols appear in more than once. This is 519 | entirely intentional. For instance, `map` belongs in the sections on 520 | collections and transducers.") 521 | 522 | ;;; We could just make dash.el a dependency, but I'm not sure it's worth it for one utility macro. 523 | (defmacro clojure-cheatsheet/->> (&rest body) 524 | (let ((result (pop body))) 525 | (dolist (form body result) 526 | (setq result (append (if (sequencep form) 527 | form 528 | (list form)) 529 | (list result)))))) 530 | 531 | (defun clojure-cheatsheet/treewalk (before after node) 532 | "Walk a tree. 533 | Invoke BEFORE before the walk, and AFTER after it, on each NODE." 534 | (clojure-cheatsheet/->> node 535 | (funcall before) 536 | ((lambda (new-node) 537 | (if (listp new-node) 538 | (mapcar (lambda (child) 539 | (clojure-cheatsheet/treewalk before after child)) 540 | new-node) 541 | new-node))) 542 | (funcall after))) 543 | 544 | (defun clojure-cheatsheet/symbol-qualifier (namespace symbol) 545 | "Given a (Clojure) NAMESPACE and a SYMBOL, fully-qualify that symbol." 546 | (intern (format "%s/%s" namespace symbol))) 547 | 548 | (defun clojure-cheatsheet/string-qualifier (head subnode) 549 | (cond 550 | ((keywordp (car subnode)) (list head subnode)) 551 | ((symbolp (car subnode)) (cons head subnode)) 552 | ((stringp (car subnode)) (cons (format "%s : %s" head (car subnode)) 553 | (cdr subnode))) 554 | (t (mapcar (apply-partially 'clojure-cheatsheet/string-qualifier head) subnode)))) 555 | 556 | (defun clojure-cheatsheet/propagate-headings (node) 557 | (clojure-cheatsheet/treewalk 558 | #'identity 559 | (lambda (item) 560 | (if (listp item) 561 | (cl-destructuring-bind (head &rest tail) item 562 | (cond ((equal :special head) tail) 563 | ((keywordp head) item) 564 | ((symbolp head) (mapcar (apply-partially #'clojure-cheatsheet/symbol-qualifier head) tail)) 565 | ((stringp head) (mapcar (apply-partially #'clojure-cheatsheet/string-qualifier head) tail)) 566 | (t item))) 567 | item)) 568 | node)) 569 | 570 | (defun clojure-cheatsheet/flatten (node) 571 | "Flatten NODE, which is a tree structure, into a list of its leaves." 572 | (cond 573 | ((not (listp node)) node) 574 | ((keywordp (car node)) node) 575 | ((listp (car node)) (apply 'append (mapcar 'clojure-cheatsheet/flatten node))) 576 | (t (list (mapcar 'clojure-cheatsheet/flatten node))))) 577 | 578 | (defun clojure-cheatsheet/group-by-head (data) 579 | "Group the DATA, which should be a list of lists, by the head of each list." 580 | (let ((result '())) 581 | (dolist (item data result) 582 | (let* ((head (car item)) 583 | (tail (cdr item)) 584 | (current (cdr (assoc head result)))) 585 | (if current 586 | (setf (cdr (assoc head result)) 587 | (append current tail)) 588 | (setq result (append result (list item)))))))) 589 | 590 | (defun clojure-cheatsheet/lookup-doc (symbol) 591 | (if (cider-connected-p) 592 | (cider-doc-lookup symbol) 593 | (user-error "CIDER not connected!"))) 594 | 595 | (defun clojure-cheatsheet/lookup-src (symbol) 596 | (if (cider-connected-p) 597 | (cider-find-var nil symbol) 598 | (user-error "CIDER not connected!"))) 599 | 600 | (defun clojure-cheatsheet/item-to-helm-source (item) 601 | "Turn ITEM, which will be (\"HEADING\" candidates...), into a helm-source." 602 | (cl-destructuring-bind (heading &rest entries) item 603 | `((name . ,heading) 604 | (candidates ,@(mapcar (lambda (item) 605 | (if (and (listp item) 606 | (keywordp (car item))) 607 | (cl-destructuring-bind (kind title value) item 608 | (cons title 609 | (list kind value))) 610 | item)) 611 | entries)) 612 | (match . ((lambda (candidate) 613 | (helm-mm-3-match (format "%s %s" candidate ,heading))))) 614 | (action-transformer (lambda (action-list current-selection) 615 | (if (and (listp current-selection) 616 | (eq (car current-selection) :url)) 617 | '(("Browse" . (lambda (item) 618 | (helm-browse-url (cadr item))))) 619 | '(("Lookup Docs" . clojure-cheatsheet/lookup-doc) 620 | ("Lookup Source" . clojure-cheatsheet/lookup-src)))))))) 621 | 622 | (defvar helm-source-clojure-cheatsheet 623 | (clojure-cheatsheet/->> clojure-cheatsheet-hierarchy 624 | clojure-cheatsheet/propagate-headings 625 | clojure-cheatsheet/flatten 626 | clojure-cheatsheet/group-by-head 627 | (mapcar 'clojure-cheatsheet/item-to-helm-source))) 628 | 629 | ;;;###autoload 630 | (defun clojure-cheatsheet () 631 | "Use helm to show a Clojure cheatsheet." 632 | (interactive) 633 | (helm :sources helm-source-clojure-cheatsheet)) 634 | 635 | (provide 'clojure-cheatsheet) 636 | 637 | ;;; clojure-cheatsheet.el ends here 638 | --------------------------------------------------------------------------------