|
68 | 68 | (run-local-server (clients/client! :nrepl.client))))))
|
69 | 69 |
|
70 | 70 | (behavior ::on-eval.clj
|
| 71 | + :desc "Clojure: Eval editor content" |
71 | 72 | :triggers #{:eval}
|
72 | 73 | :reaction (fn [editor]
|
73 | 74 | (object/raise clj-lang :eval! {:origin editor
|
74 | 75 | :info (assoc (@editor :info)
|
75 | 76 | :print-length (object/raise-reduce editor :clojure.print-length+ nil)
|
76 | 77 | :code (watches/watched-range editor nil nil nil))})))
|
77 | 78 | (behavior ::on-eval.cljs
|
| 79 | + :desc "Clojure: Eval editor content" |
78 | 80 | :triggers #{:eval}
|
79 | 81 | :reaction (fn [editor]
|
80 | 82 | (object/raise clj-lang :eval! {:origin editor
|
|
87 | 89 | "(set! js/COMPILED js/COMPILED-temp)"))})))
|
88 | 90 |
|
89 | 91 | (behavior ::on-eval.one
|
| 92 | + :desc "Clojure: Eval a single form in editor" |
90 | 93 | :triggers #{:eval.one}
|
91 | 94 | :reaction (fn [editor]
|
92 | 95 | (let [code (watches/watched-range editor nil nil nil)
|
|
103 | 106 | :info info}))))
|
104 | 107 |
|
105 | 108 |
|
106 |
| -(defn fill-placeholders [editor exp] |
| 109 | +(defn fill-placeholders |
| 110 | + "Replace editor-selection-flags, that is `__SELECTION*__`, inside `exp` with the currently |
| 111 | + selected code in `editor`." |
| 112 | + [editor exp] |
107 | 113 | (-> exp
|
108 | 114 | (string/replace "__SELECTION*__" (pr-str (ed/selection editor)))
|
109 | 115 | (string/replace "__SELECTION__" (ed/selection editor))))
|
110 | 116 |
|
111 | 117 | (behavior ::on-eval.custom
|
| 118 | + :desc "Clojure: Eval a form that has been wrapped by custom code" |
| 119 | + :doc "Example: |
| 120 | +
|
| 121 | + ``` |
| 122 | + (eval (time form)) ;; instead of (eval form) |
| 123 | + ```" |
112 | 124 | :triggers #{:eval.custom}
|
113 | 125 | :reaction (fn [editor exp opts]
|
114 | 126 | (let [code (fill-placeholders editor exp)
|
|
168 | 180 |
|
169 | 181 | (defn lighttable-ui-project?
|
170 | 182 | "Determine if path is part of a project that evals to LightTable's process
|
171 |
| - e.g. LightTable plugin or LightTable itself" |
| 183 | + (i.e., LightTable plugin or LightTable itself)." |
172 | 184 | [path]
|
173 | 185 | (or (files/walk-up-find path "plugin.edn")
|
174 | 186 | (files/walk-up-find path "plugin.json")
|
175 | 187 | (when-let [project-file (files/walk-up-find path "project.clj")]
|
176 | 188 | (= 'lighttable (second (reader/read-string (:content (files/open-sync project-file))))))))
|
177 | 189 |
|
178 | 190 | (behavior ::eval!
|
| 191 | + :desc "Clojure: Send event information for evaluation." |
| 192 | + :doc "This event information goes to the appropriate nREPL or LightTable-UI client." |
179 | 193 | :triggers #{:eval!}
|
180 | 194 | :reaction (fn [this event]
|
181 | 195 | (let [{:keys [info origin]} event
|
|
263 | 277 | (notifos/done-working)))
|
264 | 278 |
|
265 | 279 | (behavior ::cljs-result
|
| 280 | + :desc "Clojure: Receive a cljs result and dispatch it" |
266 | 281 | :triggers #{:editor.eval.cljs.result}
|
267 | 282 | :reaction (fn [obj res]
|
268 | 283 | (notifos/done-working)
|
|
271 | 286 | (object/raise obj ev res))))
|
272 | 287 |
|
273 | 288 | (behavior ::cljs-result.replace
|
| 289 | + :desc "Clojure: Replace current selection with the result of an evaluation" |
274 | 290 | :triggers #{:editor.eval.cljs.result.replace}
|
275 | 291 | :reaction (fn [obj res]
|
276 | 292 | (if-let [err (or (:stack res) (:ex res))]
|
277 | 293 | (notifos/set-msg! err {:class "error"})
|
278 | 294 | (ed/replace-selection obj (unescape-unicode (or (:result res) ""))))))
|
279 | 295 |
|
280 | 296 | (behavior ::cljs-result.statusbar
|
| 297 | + :desc "Clojure: Show the result of an evaluation on the statusbar" |
281 | 298 | :triggers #{:editor.eval.cljs.result.statusbar}
|
282 | 299 | :reaction (fn [obj res]
|
283 | 300 | (if-let [err (or (:stack res) (:ex res))]
|
284 | 301 | (notifos/set-msg! err {:class "error"})
|
285 | 302 | (notifos/set-msg! (unescape-unicode (or (:result res) "")) {:class "result"}))))
|
286 | 303 |
|
287 | 304 | (behavior ::cljs-result.inline
|
| 305 | + :desc "Clojure: Show the resulting evaluation on inline widget" |
| 306 | + :doc "The resulting evaluation is dispatched either as an exception or an inline-result." |
288 | 307 | :triggers #{:editor.eval.cljs.result.inline}
|
289 | 308 | :reaction (fn [obj res]
|
290 | 309 | (let [meta (:meta res)
|
|
295 | 314 | (object/raise obj :editor.result (unescape-unicode (or (:result res) "")) loc)))))
|
296 | 315 |
|
297 | 316 | (behavior ::cljs-result.inline-at-cursor
|
| 317 | + :desc "Clojure: Show the resulting evaluation inline at cursor location" |
| 318 | + :doc "This is similar to `::cljs-result.inline`, but puts the result as the cursor location." |
298 | 319 | :triggers #{:editor.eval.cljs.result.inline-at-cursor}
|
299 | 320 | :reaction (fn [obj res]
|
300 | 321 | (let [meta (:meta res)
|
|
316 | 337 | :meta meta})))))
|
317 | 338 |
|
318 | 339 | (behavior ::clj-result
|
| 340 | + :desc "Clojure: Receive an eval! result and dispatch it" |
| 341 | + :doc "The dispatch is according to the appropiate result type. Defaults to `:inline`." |
319 | 342 | :triggers #{:editor.eval.clj.result}
|
320 | 343 | :reaction (fn [obj res]
|
321 | 344 | (notifos/done-working)
|
|
324 | 347 | (object/raise obj ev res))))
|
325 | 348 |
|
326 | 349 | (behavior ::clj-result.replace
|
| 350 | + :desc "Clojure: Replace current selection with the result" |
327 | 351 | :triggers #{:editor.eval.clj.result.replace}
|
328 | 352 | :reaction (fn [obj res]
|
329 | 353 | (doseq [result (-> res :results)
|
|
335 | 359 | (ed/replace-selection obj (:result result))))))
|
336 | 360 |
|
337 | 361 | (behavior ::clj-result.statusbar
|
| 362 | + :desc "Clojure: Show evaluation result on the statusbar" |
338 | 363 | :triggers #{:editor.eval.clj.result.statusbar}
|
339 | 364 | :reaction (fn [obj res]
|
340 | 365 | (doseq [result (-> res :results)
|
|
346 | 371 | (notifos/set-msg! (:result result) {:class "result"})))))
|
347 | 372 |
|
348 | 373 | (behavior ::clj-result.inline
|
| 374 | + :desc "Clojure: Display eval result inline" |
| 375 | + :doc "Dispatches as an exception or an inline-result." |
349 | 376 | :triggers #{:editor.eval.clj.result.inline}
|
350 | 377 | :reaction (fn [obj res]
|
351 | 378 | (doseq [result (-> res :results)
|
|
354 | 381 | :start-line (dec (:line meta))}]]
|
355 | 382 | (if (:stack result)
|
356 | 383 | (object/raise obj :editor.eval.clj.exception result :passed)
|
357 |
| - (do |
358 |
| - (object/raise obj :editor.result (:result result) loc)))))) |
| 384 | + (object/raise obj :editor.result (:result result) loc))))) |
359 | 385 |
|
360 | 386 | (behavior ::clj-result.inline-at-cursor
|
| 387 | + :desc "Clojure: Display the eval result inline at cursor location" |
| 388 | + :doc "This is similar to `::clj-result.inline`, but puts the result at the cursor location." |
361 | 389 | :triggers #{:editor.eval.clj.result.inline-at-cursor}
|
362 | 390 | :reaction (fn [obj res]
|
363 | 391 | (doseq [result (-> res :results)
|
|
366 | 394 | :start-line (-> res :meta :start)}]]
|
367 | 395 | (if (:stack result)
|
368 | 396 | (object/raise obj :editor.eval.clj.exception result :passed)
|
369 |
| - (do |
370 |
| - (object/raise obj :editor.result (:result result) loc)))))) |
| 397 | + (object/raise obj :editor.result (:result result) loc))))) |
371 | 398 |
|
372 | 399 | (behavior ::clj-result.return
|
373 | 400 | :triggers #{:editor.eval.clj.result.return}
|
|
382 | 409 | :meta meta})))))
|
383 | 410 |
|
384 | 411 | (behavior ::clj-exception
|
| 412 | + :desc "Clojure: Display stacktrace information and summary in statusbar" |
385 | 413 | :triggers #{:editor.eval.clj.exception}
|
386 | 414 | :reaction (fn [obj res passed?]
|
387 | 415 | (when-not passed?
|
|
390 | 418 | loc {:line (dec (:end-line meta)) :ch (:end-column meta 0)
|
391 | 419 | :start-line (dec (:line meta 1))}]
|
392 | 420 | (notifos/set-msg! (:result res) {:class "error"})
|
393 |
| - (object/raise obj :editor.exception (:stack res) loc)) |
394 |
| - )) |
| 421 | + (object/raise obj :editor.exception (:stack res) loc)))) |
395 | 422 |
|
396 | 423 | (behavior ::cljs-exception
|
| 424 | + :desc "Clojure: Display stacktrace information and summary in statusbar" |
| 425 | + ;; Line below is too long to include, but will be useful after https://github.com/LightTable/LightTable/issues/2197 |
| 426 | + :doc "Take the result of evaling a cljs form, which resulted in an exception, |
| 427 | + and displays a message in the status bar and an exception widget with the stacktrace." |
397 | 428 | :triggers #{:editor.eval.cljs.exception}
|
398 | 429 | :reaction (fn [obj res passed?]
|
399 | 430 | (when-not passed?
|
|
413 | 444 | msg
|
414 | 445 | "Unknown error")]
|
415 | 446 | (notifos/set-msg! msg {:class "error"})
|
416 |
| - (object/raise obj :editor.exception stack loc)) |
417 |
| - )) |
| 447 | + (object/raise obj :editor.exception stack loc)))) |
418 | 448 |
|
419 | 449 | (behavior ::eval-print
|
420 | 450 | :triggers #{:editor.eval.clj.print}
|
|
424 | 454 | :line (when (object/has-tag? this :nrepl.client)
|
425 | 455 | "stdout")
|
426 | 456 | :id (:id str)
|
427 |
| - :content (:out str)} |
428 |
| - )))) |
| 457 | + :content (:out str)})))) |
429 | 458 |
|
430 | 459 | (behavior ::eval-print-err
|
431 | 460 | :triggers #{:editor.eval.clj.print.err}
|
|
517 | 546 | ;; watches
|
518 | 547 | ;;****************************************************
|
519 | 548 |
|
| 549 | +;; For more information on watches check |
| 550 | +;; |
| 551 | +;; Original anouncement: https://groups.google.com/forum/#!msg/light-table-discussion/lyFzPGI2XMs/ec8T1OUPvMsJ |
| 552 | +;; |
| 553 | +;; Blog posts: http://scattered-thoughts.net/blog/2014/01/27/were-not-even-trying/?utm_source=dlvr.it&utm_medium=twitter |
| 554 | +;; https://medium.com/@zindlerb/guide-to-light-table-watches-fad560f698d3#.oqwq991sx |
| 555 | +;; |
| 556 | +;; Rolex watches plugin: https://groups.google.com/forum/#!topic/light-table-discussion/NQWGC0vVHMY |
| 557 | + |
520 | 558 | (behavior ::cljs-watch-src
|
| 559 | + :desc "Clojure: Wraps the watched source code" |
| 560 | + :doc "Wraps watched code to catch its result and send it back to LightTable, |
| 561 | + while continuing normal evaluation of an expression." |
521 | 562 | :triggers #{:watch.src+}
|
522 | 563 | :reaction (fn [editor cur meta src]
|
523 | 564 | (let [meta (assoc meta :ev :editor.eval.cljs.watch)]
|
524 | 565 | (str "(js/lttools.watch " src " (clj->js " (pr-str meta) "))"))))
|
525 | 566 |
|
526 | 567 | (behavior ::clj-watch-src
|
| 568 | + :desc "Clojure: Wraps the watched source code" |
| 569 | + :doc "Wraps watched code to catch its result and send it back to LightTable, |
| 570 | + while continuing normal evaluation of an expression." |
527 | 571 | :triggers #{:watch.src+}
|
528 | 572 | :reaction (fn [editor cur meta src]
|
529 | 573 | (str "(lighttable.nrepl.eval/watch " src " " (pr-str meta) ")")))
|
530 | 574 |
|
531 |
| -(defn fill-watch-placeholders [exp src meta watch] |
| 575 | +(defn fill-watch-placeholders |
| 576 | + "Replace editor-selection-flags (placeholders) for custom watches inside `exp` |
| 577 | + with the src-code to be watched." |
| 578 | + [exp src meta watch] |
532 | 579 | (-> exp
|
533 | 580 | (string/replace "\n" " ")
|
534 | 581 | (string/replace "__SELECTION*__" (pr-str src))
|
|
537 | 584 | (string/replace #"__\|(.*)\|__" watch)))
|
538 | 585 |
|
539 | 586 | (behavior ::cljs-watch-custom-src
|
| 587 | + :desc "Clojure: Prepare expression for watching" |
| 588 | + :doc "The expression is prepared by filling its placeholders and wrapping its watcher-code |
| 589 | + with custom call to `:editor.eval.cljs.watch`." |
540 | 590 | :triggers #{:watch.custom.src+}
|
541 | 591 | :reaction (fn [editor cur meta opts src]
|
542 |
| - (let [watch (str "(js/lttools.raise " (:obj meta) " :editor.eval.cljs.watch {:meta " (pr-str (merge (dissoc opts :exp) meta)) " :result $1})")] |
| 592 | + (let [watch (str "(js/lttools.raise " (:obj meta) |
| 593 | + " :editor.eval.cljs.watch {:meta " (pr-str (merge (dissoc opts :exp) meta)) |
| 594 | + " :result $1})")] |
543 | 595 | (fill-watch-placeholders (:exp opts) src meta watch))))
|
544 | 596 |
|
545 | 597 | (behavior ::clj-watch-custom-src
|
| 598 | + :desc "Clojure: Prepare expression for watching" |
| 599 | + :doc "The exp is prepared by filling its placeholders and wrapping its watcher-code |
| 600 | + with custom call to `:editor.eval.clj.watch`" |
546 | 601 | :triggers #{:watch.custom.src+}
|
547 | 602 | :reaction (fn [editor cur meta opts src]
|
548 | 603 | (let [wrapped (if (:verbatim opts)
|
|
578 | 633 | ;;****************************************************
|
579 | 634 |
|
580 | 635 | (behavior ::clj-doc
|
| 636 | + :desc "Clojure: Request docstring for symbol at cursor from nREPL" |
581 | 637 | :triggers #{:editor.doc}
|
582 | 638 | :reaction (fn [editor]
|
583 | 639 | (let [token (find-symbol-at-cursor editor)
|
|
593 | 649 | :info info
|
594 | 650 | :origin editor
|
595 | 651 | :create try-connect})
|
596 |
| - command info :only editor))) |
597 |
| - )) |
| 652 | + command info :only editor))))) |
598 | 653 |
|
599 | 654 | (behavior ::print-clj-doc
|
600 | 655 | :triggers #{:editor.clj.doc}
|
|
617 | 672 | (assoc token-left :loc loc)))))
|
618 | 673 |
|
619 | 674 | (behavior ::cljs-doc
|
| 675 | + :desc "Clojure: Request docstring for symbol at cursor from nREPL" |
620 | 676 | :triggers #{:editor.doc}
|
621 | 677 | :reaction (fn [editor]
|
622 | 678 | (let [token (find-symbol-at-cursor editor)
|
|
643 | 699 | (object/raise editor :editor.doc.show! result)))))
|
644 | 700 |
|
645 | 701 | (behavior ::clj-doc-search
|
| 702 | + :desc "Clojure: Add trigger for Clojure in language documentation search" |
| 703 | + :doc "Links the 'Search language docs' input-text on the sidebar with a trigger to |
| 704 | + `:docs.clj.search` to retrieve all the documentation on a user-input." |
646 | 705 | :triggers #{:types+}
|
647 | 706 | :reaction (fn [this cur]
|
648 |
| - (conj cur {:label "clj" :trigger :docs.clj.search :file-types #{"Clojure"}}) |
649 |
| - )) |
| 707 | + (conj cur {:label "clj" :trigger :docs.clj.search :file-types #{"Clojure"}}))) |
650 | 708 |
|
651 | 709 | (behavior ::cljs-doc-search
|
| 710 | + :desc "Clojure: Add trigger for ClojureScript in language documentation search" |
| 711 | + :doc "Links the 'Search language docs' input-text on the sidebar with a trigger to |
| 712 | + `:docs.cljs.search` to retrieve all the documentation on a user-input." |
652 | 713 | :triggers #{:types+}
|
653 | 714 | :reaction (fn [this cur]
|
654 |
| - (conj cur {:label "cljs" :trigger :docs.cljs.search :file-types #{"ClojureScript"}}) |
655 |
| - )) |
| 715 | + (conj cur {:label "cljs" :trigger :docs.cljs.search :file-types #{"ClojureScript"}}))) |
656 | 716 |
|
657 | 717 | ;;****************************************************
|
658 | 718 | ;; autocomplete
|
|
0 commit comments