Support Vim, Tmux, Emacs with Stow
After moving off of Meta, Dotfiles has a greater responsibility to manage configs. Vim, Tmux, and Emacs are now within Stow's purview.
This commit is contained in:
parent
8b2fadf477
commit
17ee0e400b
1338 changed files with 330350 additions and 24 deletions
|
@ -1 +0,0 @@
|
||||||
shared/gpg/.gnupg
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
;;; ace-window-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "ace-window" "ace-window.el" (23377 60991 457690
|
||||||
|
;;;;;; 292000))
|
||||||
|
;;; Generated autoloads from ace-window.el
|
||||||
|
|
||||||
|
(autoload 'ace-select-window "ace-window" "\
|
||||||
|
Ace select window.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'ace-delete-window "ace-window" "\
|
||||||
|
Ace delete window.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'ace-swap-window "ace-window" "\
|
||||||
|
Ace swap window.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'ace-delete-other-windows "ace-window" "\
|
||||||
|
Ace delete other windows.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'ace-window "ace-window" "\
|
||||||
|
Select a window.
|
||||||
|
Perform an action based on ARG described below.
|
||||||
|
|
||||||
|
By default, behaves like extended `other-window'.
|
||||||
|
|
||||||
|
Prefixed with one \\[universal-argument], does a swap between the
|
||||||
|
selected window and the current window, so that the selected
|
||||||
|
buffer moves to current window (and current buffer moves to
|
||||||
|
selected window).
|
||||||
|
|
||||||
|
Prefixed with two \\[universal-argument]'s, deletes the selected
|
||||||
|
window.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(defvar ace-window-display-mode nil "\
|
||||||
|
Non-nil if Ace-Window-Display mode is enabled.
|
||||||
|
See the `ace-window-display-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `ace-window-display-mode'.")
|
||||||
|
|
||||||
|
(custom-autoload 'ace-window-display-mode "ace-window" nil)
|
||||||
|
|
||||||
|
(autoload 'ace-window-display-mode "ace-window" "\
|
||||||
|
Minor mode for showing the ace window key in the mode line.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; ace-window-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "ace-window" "20180607.1223" "Quickly switch windows." '((avy "0.2.0")))
|
|
@ -0,0 +1,802 @@
|
||||||
|
;;; ace-window.el --- Quickly switch windows. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2015 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: Oleh Krehel <ohwoeowho@gmail.com>
|
||||||
|
;; Maintainer: Oleh Krehel <ohwoeowho@gmail.com>
|
||||||
|
;; URL: https://github.com/abo-abo/ace-window
|
||||||
|
;; Package-Version: 20180607.1223
|
||||||
|
;; Version: 0.9.0
|
||||||
|
;; Package-Requires: ((avy "0.2.0"))
|
||||||
|
;; Keywords: window, location
|
||||||
|
|
||||||
|
;; This file is part of GNU Emacs.
|
||||||
|
|
||||||
|
;; This file is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation; either version 3, or (at your option)
|
||||||
|
;; any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; For a full copy of the GNU General Public License
|
||||||
|
;; see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; The main function, `ace-window' is meant to replace `other-window'
|
||||||
|
;; by assigning each window a short, unique label. When there are only
|
||||||
|
;; two windows present, `other-window' is called (unless
|
||||||
|
;; aw-dispatch-always is set non-nil). If there are more, each
|
||||||
|
;; window will have its first label character highlighted. Once a
|
||||||
|
;; unique label is typed, ace-window will switch to that window.
|
||||||
|
;;
|
||||||
|
;; To setup this package, just add to your .emacs:
|
||||||
|
;;
|
||||||
|
;; (global-set-key (kbd "M-o") 'ace-window)
|
||||||
|
;;
|
||||||
|
;; replacing "M-o" with an appropriate shortcut.
|
||||||
|
;;
|
||||||
|
;; By default, ace-window uses numbers for window labels so the window
|
||||||
|
;; labeling is intuitively ordered. But if you prefer to type keys on
|
||||||
|
;; your home row for quicker access, use this setting:
|
||||||
|
;;
|
||||||
|
;; (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
|
||||||
|
;;
|
||||||
|
;; Whenever ace-window prompts for a window selection, it grays out
|
||||||
|
;; all the window characters, highlighting window labels in red. To
|
||||||
|
;; disable this behavior, set this:
|
||||||
|
;;
|
||||||
|
;; (setq aw-background nil)
|
||||||
|
;;
|
||||||
|
;; If you want to know the selection characters ahead of time, turn on
|
||||||
|
;; `ace-window-display-mode'.
|
||||||
|
;;
|
||||||
|
;; When prefixed with one `universal-argument', instead of switching
|
||||||
|
;; to the selected window, the selected window is swapped with the
|
||||||
|
;; current one.
|
||||||
|
;;
|
||||||
|
;; When prefixed with two `universal-argument', the selected window is
|
||||||
|
;; deleted instead.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'avy)
|
||||||
|
(require 'ring)
|
||||||
|
(require 'subr-x)
|
||||||
|
|
||||||
|
;;* Customization
|
||||||
|
(defgroup ace-window nil
|
||||||
|
"Quickly switch current window."
|
||||||
|
:group 'convenience
|
||||||
|
:prefix "aw-")
|
||||||
|
|
||||||
|
(defcustom aw-keys '(?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)
|
||||||
|
"Keys for selecting window."
|
||||||
|
:type '(repeat character))
|
||||||
|
|
||||||
|
(defcustom aw-scope 'global
|
||||||
|
"The scope used by `ace-window'."
|
||||||
|
:type '(choice
|
||||||
|
(const :tag "visible frames" visible)
|
||||||
|
(const :tag "global" global)
|
||||||
|
(const :tag "frame" frame)))
|
||||||
|
|
||||||
|
(defcustom aw-minibuffer-flag nil
|
||||||
|
"When non-nil, also display `ace-window-mode' string in the minibuffer when ace-window is active."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-ignored-buffers '("*Calc Trail*" "*LV*")
|
||||||
|
"List of buffers and major-modes to ignore when choosing a window from the window list.
|
||||||
|
Active only when `aw-ignore-on' is non-nil. Windows displaying these
|
||||||
|
buffers can still be chosen by typing their specific labels."
|
||||||
|
:type '(repeat string))
|
||||||
|
|
||||||
|
(defcustom aw-ignore-on t
|
||||||
|
"When t, `ace-window' will ignore buffers and major-modes in `aw-ignored-buffers'.
|
||||||
|
Use M-0 `ace-window' to toggle this value."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-ignore-current nil
|
||||||
|
"When t, `ace-window' will ignore `selected-window'."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-background t
|
||||||
|
"When t, `ace-window' will dim out all buffers temporarily when used."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-leading-char-style 'char
|
||||||
|
"Style of the leading char overlay."
|
||||||
|
:type '(choice
|
||||||
|
(const :tag "single char" 'char)
|
||||||
|
(const :tag "full path" 'path)))
|
||||||
|
|
||||||
|
(defcustom aw-dispatch-always nil
|
||||||
|
"When non-nil, `ace-window' will issue a `read-char' even for one window.
|
||||||
|
This will make `ace-window' act different from `other-window' for
|
||||||
|
one or two windows."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-dispatch-when-more-than 2
|
||||||
|
"If the number of windows is more than this, activate ace-window-ness."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
|
(defcustom aw-reverse-frame-list nil
|
||||||
|
"When non-nil `ace-window' will order frames for selection in
|
||||||
|
the reverse of `frame-list'"
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom aw-frame-offset '(13 . 23)
|
||||||
|
"Increase in pixel offset for new ace-window frames relative to the selected frame.
|
||||||
|
Its value is an (x-offset . y-offset) pair in pixels."
|
||||||
|
:type '(cons integer integer))
|
||||||
|
|
||||||
|
(defcustom aw-frame-size nil
|
||||||
|
"Frame size to make new ace-window frames.
|
||||||
|
Its value is a (width . height) pair in pixels or nil for the default frame size.
|
||||||
|
(0 . 0) is special and means make the frame size the same as the last selected frame size."
|
||||||
|
:type '(cons integer integer))
|
||||||
|
|
||||||
|
(defcustom aw-char-position 'top-left
|
||||||
|
"Window positions of the character overlay.
|
||||||
|
Consider changing this if the overlay tends to overlap with other things."
|
||||||
|
:type '(choice
|
||||||
|
(const :tag "top left corner only" 'top-left)
|
||||||
|
(const :tag "both left corners" 'left)))
|
||||||
|
|
||||||
|
;; Must be defined before `aw-make-frame-char' since its :set function references this.
|
||||||
|
(defvar aw-dispatch-alist
|
||||||
|
'((?x aw-delete-window "Delete Window")
|
||||||
|
(?m aw-swap-window "Swap Windows")
|
||||||
|
(?M aw-move-window "Move Window")
|
||||||
|
(?j aw-switch-buffer-in-window "Select Buffer")
|
||||||
|
(?n aw-flip-window)
|
||||||
|
(?u aw-switch-buffer-other-window "Switch Buffer Other Window")
|
||||||
|
(?c aw-split-window-fair "Split Fair Window")
|
||||||
|
(?v aw-split-window-vert "Split Vert Window")
|
||||||
|
(?b aw-split-window-horz "Split Horz Window")
|
||||||
|
(?o delete-other-windows "Delete Other Windows")
|
||||||
|
(?? aw-show-dispatch-help))
|
||||||
|
"List of actions for `aw-dispatch-default'.
|
||||||
|
Each action is a list of either:
|
||||||
|
(char function description) where function takes a single window argument
|
||||||
|
or
|
||||||
|
(char function) where function takes no argument and the description is omitted.")
|
||||||
|
|
||||||
|
(defun aw-set-make-frame-char (option value)
|
||||||
|
;; Signal an error if `aw-make-frame-char' is ever set to an invalid
|
||||||
|
;; or conflicting value.
|
||||||
|
(when value
|
||||||
|
(cond ((not (characterp value))
|
||||||
|
(user-error "`aw-make-frame-char' must be a character, not `%s'" value))
|
||||||
|
((memq value aw-keys)
|
||||||
|
(user-error "`aw-make-frame-char' is `%c'; this conflicts with the same character in `aw-keys'" value))
|
||||||
|
((assq value aw-dispatch-alist)
|
||||||
|
(user-error "`aw-make-frame-char' is `%c'; this conflicts with the same character in `aw-dispatch-alist'" value))))
|
||||||
|
(set option value))
|
||||||
|
|
||||||
|
(defcustom aw-make-frame-char ?z
|
||||||
|
"Non-existing ace window label character that triggers creation of a new single-window frame for display."
|
||||||
|
:set 'aw-set-make-frame-char
|
||||||
|
:type 'character)
|
||||||
|
|
||||||
|
(defface aw-leading-char-face
|
||||||
|
'((((class color)) (:foreground "red"))
|
||||||
|
(((background dark)) (:foreground "gray100"))
|
||||||
|
(((background light)) (:foreground "gray0"))
|
||||||
|
(t (:foreground "gray100" :underline nil)))
|
||||||
|
"Face for each window's leading char.")
|
||||||
|
|
||||||
|
(defface aw-background-face
|
||||||
|
'((t (:foreground "gray40")))
|
||||||
|
"Face for whole window background during selection.")
|
||||||
|
|
||||||
|
(defface aw-mode-line-face
|
||||||
|
'((t (:inherit mode-line-buffer-id)))
|
||||||
|
"Face used for displaying the ace window key in the mode-line.")
|
||||||
|
|
||||||
|
(defface aw-key-face
|
||||||
|
'((t :inherit font-lock-builtin-face))
|
||||||
|
"Face used by `aw-show-dispatch-help'.")
|
||||||
|
|
||||||
|
;;* Implementation
|
||||||
|
(defun aw-ignored-p (window)
|
||||||
|
"Return t if WINDOW should be ignored when choosing from the window list."
|
||||||
|
(or (and aw-ignore-on
|
||||||
|
;; Ignore major-modes and buffer-names in `aw-ignored-buffers'.
|
||||||
|
(or (memq (buffer-local-value 'major-mode (window-buffer window))
|
||||||
|
aw-ignored-buffers)
|
||||||
|
(member (buffer-name (window-buffer window)) aw-ignored-buffers)))
|
||||||
|
;; Ignore selected window if `aw-ignore-current' is non-nil.
|
||||||
|
(and aw-ignore-current
|
||||||
|
(equal window (selected-window)))
|
||||||
|
;; When `ignore-window-parameters' is nil, ignore windows whose
|
||||||
|
;; `no-other-window’ or `no-delete-other-windows' parameter is non-nil.
|
||||||
|
(unless ignore-window-parameters
|
||||||
|
(cl-case this-command
|
||||||
|
(ace-select-window (window-parameter window 'no-other-window))
|
||||||
|
(ace-delete-window (window-parameter window 'no-delete-other-windows))
|
||||||
|
(ace-delete-other-windows (window-parameter
|
||||||
|
window 'no-delete-other-windows))))))
|
||||||
|
|
||||||
|
(defun aw-window-list ()
|
||||||
|
"Return the list of interesting windows."
|
||||||
|
(sort
|
||||||
|
(cl-remove-if
|
||||||
|
(lambda (w)
|
||||||
|
(let ((f (window-frame w)))
|
||||||
|
(or (not (and (frame-live-p f)
|
||||||
|
(frame-visible-p f)))
|
||||||
|
(string= "initial_terminal" (terminal-name f))
|
||||||
|
(aw-ignored-p w))))
|
||||||
|
(cl-case aw-scope
|
||||||
|
(visible
|
||||||
|
(cl-mapcan #'window-list (visible-frame-list)))
|
||||||
|
(global
|
||||||
|
(cl-mapcan #'window-list (frame-list)))
|
||||||
|
(frame
|
||||||
|
(window-list))
|
||||||
|
(t
|
||||||
|
(error "Invalid `aw-scope': %S" aw-scope))))
|
||||||
|
'aw-window<))
|
||||||
|
|
||||||
|
(defvar aw-overlays-back nil
|
||||||
|
"Hold overlays for when `aw-background' is t.")
|
||||||
|
|
||||||
|
(defvar ace-window-mode nil
|
||||||
|
"Minor mode during the selection process.")
|
||||||
|
|
||||||
|
;; register minor mode
|
||||||
|
(or (assq 'ace-window-mode minor-mode-alist)
|
||||||
|
(nconc minor-mode-alist
|
||||||
|
(list '(ace-window-mode ace-window-mode))))
|
||||||
|
|
||||||
|
(defvar aw-empty-buffers-list nil
|
||||||
|
"Store the read-only empty buffers which had to be modified.
|
||||||
|
Modify them back eventually.")
|
||||||
|
|
||||||
|
(defun aw--done ()
|
||||||
|
"Clean up mode line and overlays."
|
||||||
|
;; mode line
|
||||||
|
(aw-set-mode-line nil)
|
||||||
|
;; background
|
||||||
|
(mapc #'delete-overlay aw-overlays-back)
|
||||||
|
(setq aw-overlays-back nil)
|
||||||
|
(avy--remove-leading-chars)
|
||||||
|
(dolist (b aw-empty-buffers-list)
|
||||||
|
(with-current-buffer b
|
||||||
|
(when (string= (buffer-string) " ")
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(delete-region (point-min) (point-max))))))
|
||||||
|
(setq aw-empty-buffers-list nil))
|
||||||
|
|
||||||
|
(defun aw--overlay-str (wnd pos path)
|
||||||
|
"Return the replacement text for an overlay in WND at POS,
|
||||||
|
accessible by typing PATH."
|
||||||
|
(let ((old-str (or
|
||||||
|
(ignore-errors
|
||||||
|
(with-selected-window wnd
|
||||||
|
(buffer-substring pos (1+ pos))))
|
||||||
|
"")))
|
||||||
|
(concat
|
||||||
|
(cl-case aw-leading-char-style
|
||||||
|
(char
|
||||||
|
(string (avy--key-to-char (car (last path)))))
|
||||||
|
(path
|
||||||
|
(mapconcat
|
||||||
|
(lambda (x) (string (avy--key-to-char x)))
|
||||||
|
(reverse path)
|
||||||
|
""))
|
||||||
|
(t
|
||||||
|
(error "Bad `aw-leading-char-style': %S"
|
||||||
|
aw-leading-char-style)))
|
||||||
|
(cond ((string-equal old-str "\t")
|
||||||
|
(make-string (1- tab-width) ?\ ))
|
||||||
|
((string-equal old-str "\n")
|
||||||
|
"\n")
|
||||||
|
(t
|
||||||
|
(make-string
|
||||||
|
(max 0 (1- (string-width old-str)))
|
||||||
|
?\ ))))))
|
||||||
|
|
||||||
|
(defun aw--lead-overlay (path leaf)
|
||||||
|
"Create an overlay using PATH at LEAF.
|
||||||
|
LEAF is (PT . WND)."
|
||||||
|
(let ((wnd (cdr leaf)))
|
||||||
|
(with-selected-window wnd
|
||||||
|
(when (= 0 (buffer-size))
|
||||||
|
(push (current-buffer) aw-empty-buffers-list)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(insert " ")))
|
||||||
|
|
||||||
|
(let* ((pt (car leaf))
|
||||||
|
(ol (make-overlay pt (1+ pt) (window-buffer wnd))))
|
||||||
|
(overlay-put ol 'display (aw--overlay-str wnd pt path))
|
||||||
|
(overlay-put ol 'face 'aw-leading-char-face)
|
||||||
|
(overlay-put ol 'window wnd)
|
||||||
|
(push ol avy--overlays-lead))
|
||||||
|
|
||||||
|
(when (eq aw-char-position 'left)
|
||||||
|
(let* ((pt
|
||||||
|
(save-excursion
|
||||||
|
;; Move to the start of the last visible line in the buffer.
|
||||||
|
(move-to-window-line -1)
|
||||||
|
(move-beginning-of-line nil)
|
||||||
|
;; If this line is empty, use the previous line so we
|
||||||
|
;; have space for the overlay.
|
||||||
|
(when (equal (point) (point-max))
|
||||||
|
(forward-line -1))
|
||||||
|
(point)))
|
||||||
|
(ol (make-overlay pt (1+ pt) (window-buffer wnd))))
|
||||||
|
(overlay-put ol 'display (aw--overlay-str wnd pt path))
|
||||||
|
(overlay-put ol 'face 'aw-leading-char-face)
|
||||||
|
(overlay-put ol 'window wnd)
|
||||||
|
(push ol avy--overlays-lead))))))
|
||||||
|
|
||||||
|
(defun aw--make-backgrounds (wnd-list)
|
||||||
|
"Create a dim background overlay for each window on WND-LIST."
|
||||||
|
(when aw-background
|
||||||
|
(setq aw-overlays-back
|
||||||
|
(mapcar (lambda (w)
|
||||||
|
(let ((ol (make-overlay
|
||||||
|
(window-start w)
|
||||||
|
(window-end w)
|
||||||
|
(window-buffer w))))
|
||||||
|
(overlay-put ol 'face 'aw-background-face)
|
||||||
|
ol))
|
||||||
|
wnd-list))))
|
||||||
|
|
||||||
|
(define-obsolete-variable-alias
|
||||||
|
'aw-flip-keys 'aw--flip-keys "0.1.0"
|
||||||
|
"Use `aw-dispatch-alist' instead.")
|
||||||
|
|
||||||
|
(defvar aw-dispatch-function 'aw-dispatch-default
|
||||||
|
"Function to call when a character not in `aw-keys' is pressed.")
|
||||||
|
|
||||||
|
(defvar aw-action nil
|
||||||
|
"Function to call at the end of `aw-select'.")
|
||||||
|
|
||||||
|
(defun aw-set-mode-line (str)
|
||||||
|
"Set mode line indicator to STR."
|
||||||
|
(setq ace-window-mode str)
|
||||||
|
(when (and aw-minibuffer-flag ace-window-mode)
|
||||||
|
(message "%s" (string-trim-left str)))
|
||||||
|
(force-mode-line-update))
|
||||||
|
|
||||||
|
(defun aw--dispatch-action (char)
|
||||||
|
"Return item from `aw-dispatch-alist' matching CHAR."
|
||||||
|
(assoc char aw-dispatch-alist))
|
||||||
|
|
||||||
|
(defun aw-make-frame ()
|
||||||
|
"Make a new Emacs frame using the values of `aw-frame-size' and `aw-frame-offset'."
|
||||||
|
(make-frame
|
||||||
|
(delq nil
|
||||||
|
(list
|
||||||
|
;; This first parameter is important because an
|
||||||
|
;; aw-dispatch-alist command may not want to leave this
|
||||||
|
;; frame with input focus. If it is given focus, the
|
||||||
|
;; command may not be able to return focus to a different
|
||||||
|
;; frame since this is done asynchronously by the window
|
||||||
|
;; manager.
|
||||||
|
'(no-focus-on-map . t)
|
||||||
|
(when aw-frame-size
|
||||||
|
(cons 'width
|
||||||
|
(if (zerop (car aw-frame-size))
|
||||||
|
(frame-width)
|
||||||
|
(car aw-frame-size))))
|
||||||
|
(when aw-frame-size
|
||||||
|
(cons 'height
|
||||||
|
(if (zerop (cdr aw-frame-size))
|
||||||
|
(frame-height)
|
||||||
|
(car aw-frame-size))))
|
||||||
|
(cons 'left (+ (car aw-frame-offset)
|
||||||
|
(car (frame-position))))
|
||||||
|
(cons 'top (+ (cdr aw-frame-offset)
|
||||||
|
(cdr (frame-position))))))))
|
||||||
|
|
||||||
|
(defun aw-use-frame (window)
|
||||||
|
"Create a new frame using the contents of WINDOW.
|
||||||
|
|
||||||
|
The new frame is set to the same size as the previous frame, offset by
|
||||||
|
`aw-frame-offset' (x . y) pixels."
|
||||||
|
(aw-switch-to-window window)
|
||||||
|
(aw-make-frame))
|
||||||
|
|
||||||
|
(defun aw-clean-up-avy-current-path ()
|
||||||
|
"Edit `avy-current-path' so only window label characters remain."
|
||||||
|
;; Remove any possible ace-window command char that may
|
||||||
|
;; precede the last specified window label, so
|
||||||
|
;; functions can use `avy-current-path' as the chosen
|
||||||
|
;; window label.
|
||||||
|
(when (and (> (length avy-current-path) 0)
|
||||||
|
(assq (aref avy-current-path 0) aw-dispatch-alist))
|
||||||
|
(setq avy-current-path (substring avy-current-path 1))))
|
||||||
|
|
||||||
|
(defun aw-dispatch-default (char)
|
||||||
|
"Perform an action depending on CHAR."
|
||||||
|
(cond ((and (fboundp 'avy-mouse-event-window)
|
||||||
|
(avy-mouse-event-window char)))
|
||||||
|
((= char (aref (kbd "C-g") 0))
|
||||||
|
(throw 'done 'exit))
|
||||||
|
((= char aw-make-frame-char)
|
||||||
|
;; Make a new frame and perform any action on its window.
|
||||||
|
(let ((start-win (selected-window))
|
||||||
|
(end-win (frame-selected-window (aw-make-frame))))
|
||||||
|
(if aw-action
|
||||||
|
;; Action must be called from the start-win. The action
|
||||||
|
;; determines which window to leave selected.
|
||||||
|
(progn (select-frame-set-input-focus (window-frame start-win))
|
||||||
|
(funcall aw-action end-win))
|
||||||
|
;; Select end-win when no action
|
||||||
|
(aw-switch-to-window end-win)))
|
||||||
|
(throw 'done 'exit))
|
||||||
|
(t
|
||||||
|
(let ((action (aw--dispatch-action char)))
|
||||||
|
(if action
|
||||||
|
(cl-destructuring-bind (_key fn &optional description) action
|
||||||
|
(if (and fn description)
|
||||||
|
(prog1 (setq aw-action fn)
|
||||||
|
(aw-set-mode-line (format " Ace - %s" description)))
|
||||||
|
(funcall fn)
|
||||||
|
(throw 'done 'exit)))
|
||||||
|
(aw-clean-up-avy-current-path)
|
||||||
|
;; Prevent any char from triggering an avy dispatch command.
|
||||||
|
(let ((avy-dispatch-alist))
|
||||||
|
(avy-handler-default char)))))))
|
||||||
|
|
||||||
|
(defun aw-select (mode-line &optional action)
|
||||||
|
"Return a selected other window.
|
||||||
|
Amend MODE-LINE to the mode line for the duration of the selection."
|
||||||
|
(setq aw-action action)
|
||||||
|
(let ((start-window (selected-window))
|
||||||
|
(next-window-scope (cl-case aw-scope
|
||||||
|
('visible 'visible)
|
||||||
|
('global 'visible)
|
||||||
|
('frame 'frame)))
|
||||||
|
(wnd-list (aw-window-list))
|
||||||
|
window)
|
||||||
|
(setq window
|
||||||
|
(cond ((<= (length wnd-list) 1)
|
||||||
|
(when aw-dispatch-always
|
||||||
|
(setq aw-action
|
||||||
|
(unwind-protect
|
||||||
|
(catch 'done
|
||||||
|
(funcall aw-dispatch-function (read-char)))
|
||||||
|
(aw--done)))
|
||||||
|
(when (eq aw-action 'exit)
|
||||||
|
(setq aw-action nil)))
|
||||||
|
(or (car wnd-list) start-window))
|
||||||
|
((and (<= (length wnd-list) aw-dispatch-when-more-than)
|
||||||
|
(not aw-dispatch-always)
|
||||||
|
(not aw-ignore-current))
|
||||||
|
(let ((wnd (next-window nil nil next-window-scope)))
|
||||||
|
(while (and (or (not (memq wnd wnd-list))
|
||||||
|
(aw-ignored-p wnd))
|
||||||
|
(not (equal wnd start-window)))
|
||||||
|
(setq wnd (next-window wnd nil next-window-scope)))
|
||||||
|
wnd))
|
||||||
|
(t
|
||||||
|
(let ((candidate-list
|
||||||
|
(mapcar (lambda (wnd)
|
||||||
|
(cons (aw-offset wnd) wnd))
|
||||||
|
wnd-list)))
|
||||||
|
(aw--make-backgrounds wnd-list)
|
||||||
|
(aw-set-mode-line mode-line)
|
||||||
|
;; turn off helm transient map
|
||||||
|
(remove-hook 'post-command-hook 'helm--maybe-update-keymap)
|
||||||
|
(unwind-protect
|
||||||
|
(let* ((avy-handler-function aw-dispatch-function)
|
||||||
|
(avy-translate-char-function #'identity)
|
||||||
|
(res (avy-read (avy-tree candidate-list aw-keys)
|
||||||
|
#'aw--lead-overlay
|
||||||
|
#'avy--remove-leading-chars)))
|
||||||
|
(if (eq res 'exit)
|
||||||
|
(setq aw-action nil)
|
||||||
|
(or (cdr res)
|
||||||
|
start-window)))
|
||||||
|
(aw--done))))))
|
||||||
|
(if aw-action
|
||||||
|
(funcall aw-action window)
|
||||||
|
window)))
|
||||||
|
|
||||||
|
;;* Interactive
|
||||||
|
;;;###autoload
|
||||||
|
(defun ace-select-window ()
|
||||||
|
"Ace select window."
|
||||||
|
(interactive)
|
||||||
|
(aw-select " Ace - Window"
|
||||||
|
#'aw-switch-to-window))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun ace-delete-window ()
|
||||||
|
"Ace delete window."
|
||||||
|
(interactive)
|
||||||
|
(aw-select " Ace - Delete Window"
|
||||||
|
#'aw-delete-window))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun ace-swap-window ()
|
||||||
|
"Ace swap window."
|
||||||
|
(interactive)
|
||||||
|
(aw-select " Ace - Swap Window"
|
||||||
|
#'aw-swap-window))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun ace-delete-other-windows ()
|
||||||
|
"Ace delete other windows."
|
||||||
|
(interactive)
|
||||||
|
(aw-select " Ace - Delete Other Windows"
|
||||||
|
#'delete-other-windows))
|
||||||
|
|
||||||
|
(define-obsolete-function-alias
|
||||||
|
'ace-maximize-window 'ace-delete-other-windows "0.10.0")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun ace-window (arg)
|
||||||
|
"Select a window.
|
||||||
|
Perform an action based on ARG described below.
|
||||||
|
|
||||||
|
By default, behaves like extended `other-window'.
|
||||||
|
|
||||||
|
Prefixed with one \\[universal-argument], does a swap between the
|
||||||
|
selected window and the current window, so that the selected
|
||||||
|
buffer moves to current window (and current buffer moves to
|
||||||
|
selected window).
|
||||||
|
|
||||||
|
Prefixed with two \\[universal-argument]'s, deletes the selected
|
||||||
|
window."
|
||||||
|
(interactive "p")
|
||||||
|
(cl-case arg
|
||||||
|
(0
|
||||||
|
(setq aw-ignore-on
|
||||||
|
(not aw-ignore-on))
|
||||||
|
(ace-select-window))
|
||||||
|
(4 (ace-swap-window))
|
||||||
|
(16 (ace-delete-window))
|
||||||
|
(t (ace-select-window))))
|
||||||
|
|
||||||
|
;;* Utility
|
||||||
|
(unless (fboundp 'frame-position)
|
||||||
|
(defun frame-position (&optional frame)
|
||||||
|
(cons (frame-parameter frame 'left)
|
||||||
|
(frame-parameter frame 'top))))
|
||||||
|
|
||||||
|
(defun aw-window< (wnd1 wnd2)
|
||||||
|
"Return true if WND1 is less than WND2.
|
||||||
|
This is determined by their respective window coordinates.
|
||||||
|
Windows are numbered top down, left to right."
|
||||||
|
(let ((f1 (window-frame wnd1))
|
||||||
|
(f2 (window-frame wnd2))
|
||||||
|
(e1 (window-edges wnd1))
|
||||||
|
(e2 (window-edges wnd2)))
|
||||||
|
(cond ((< (car (frame-position f1)) (car (frame-position f2)))
|
||||||
|
(not aw-reverse-frame-list))
|
||||||
|
((> (car (frame-position f1)) (car (frame-position f2)))
|
||||||
|
aw-reverse-frame-list)
|
||||||
|
((< (car e1) (car e2))
|
||||||
|
t)
|
||||||
|
((> (car e1) (car e2))
|
||||||
|
nil)
|
||||||
|
((< (cadr e1) (cadr e2))
|
||||||
|
t))))
|
||||||
|
|
||||||
|
(defvar aw--window-ring (make-ring 10)
|
||||||
|
"Hold the window switching history.")
|
||||||
|
|
||||||
|
(defun aw--push-window (window)
|
||||||
|
"Store WINDOW to `aw--window-ring'."
|
||||||
|
(when (or (zerop (ring-length aw--window-ring))
|
||||||
|
(not (equal
|
||||||
|
(ring-ref aw--window-ring 0)
|
||||||
|
window)))
|
||||||
|
(ring-insert aw--window-ring (selected-window))))
|
||||||
|
|
||||||
|
(defun aw--pop-window ()
|
||||||
|
"Return the removed top of `aw--window-ring'."
|
||||||
|
(let (res)
|
||||||
|
(condition-case nil
|
||||||
|
(while (or (not (window-live-p
|
||||||
|
(setq res (ring-remove aw--window-ring 0))))
|
||||||
|
(equal res (selected-window))))
|
||||||
|
(error
|
||||||
|
(if (= (length (aw-window-list)) 2)
|
||||||
|
(progn
|
||||||
|
(other-window 1)
|
||||||
|
(setq res (selected-window)))
|
||||||
|
(error "No previous windows stored"))))
|
||||||
|
res))
|
||||||
|
|
||||||
|
(defun aw-switch-to-window (window)
|
||||||
|
"Switch to the window WINDOW."
|
||||||
|
(let ((frame (window-frame window)))
|
||||||
|
(aw--push-window (selected-window))
|
||||||
|
(when (and (frame-live-p frame)
|
||||||
|
(not (eq frame (selected-frame))))
|
||||||
|
(select-frame-set-input-focus frame))
|
||||||
|
(if (window-live-p window)
|
||||||
|
(select-window window)
|
||||||
|
(error "Got a dead window %S" window))))
|
||||||
|
|
||||||
|
(defun aw-flip-window ()
|
||||||
|
"Switch to the window you were previously in."
|
||||||
|
(interactive)
|
||||||
|
(aw-switch-to-window (aw--pop-window)))
|
||||||
|
|
||||||
|
(defun aw-show-dispatch-help ()
|
||||||
|
"Display action shortucts in echo area."
|
||||||
|
(interactive)
|
||||||
|
(message "%s" (mapconcat
|
||||||
|
(lambda (action)
|
||||||
|
(cl-destructuring-bind (key fn &optional description) action
|
||||||
|
(format "%s: %s"
|
||||||
|
(propertize
|
||||||
|
(char-to-string key)
|
||||||
|
'face 'aw-key-face)
|
||||||
|
(or description fn))))
|
||||||
|
aw-dispatch-alist
|
||||||
|
"\n"))
|
||||||
|
;; Prevent this from replacing any help display
|
||||||
|
;; in the minibuffer.
|
||||||
|
(let (aw-minibuffer-flag)
|
||||||
|
(mapc #'delete-overlay aw-overlays-back)
|
||||||
|
(call-interactively 'ace-window)))
|
||||||
|
|
||||||
|
(defun aw-delete-window (window)
|
||||||
|
"Delete window WINDOW."
|
||||||
|
(let ((frame (window-frame window)))
|
||||||
|
(when (and (frame-live-p frame)
|
||||||
|
(not (eq frame (selected-frame))))
|
||||||
|
(select-frame-set-input-focus (window-frame window)))
|
||||||
|
(if (= 1 (length (window-list)))
|
||||||
|
(delete-frame frame)
|
||||||
|
(if (window-live-p window)
|
||||||
|
(delete-window window)
|
||||||
|
(error "Got a dead window %S" window)))))
|
||||||
|
|
||||||
|
(defun aw-switch-buffer-in-window (window)
|
||||||
|
"Select buffer in WINDOW."
|
||||||
|
(aw-switch-to-window window)
|
||||||
|
(aw--switch-buffer))
|
||||||
|
|
||||||
|
(declare-function ivy-switch-buffer "ext:ivy")
|
||||||
|
|
||||||
|
(defun aw--switch-buffer ()
|
||||||
|
(cond ((bound-and-true-p ivy-mode)
|
||||||
|
(ivy-switch-buffer))
|
||||||
|
((bound-and-true-p ido-mode)
|
||||||
|
(ido-switch-buffer))
|
||||||
|
(t
|
||||||
|
(call-interactively 'switch-to-buffer))))
|
||||||
|
|
||||||
|
(defcustom aw-swap-invert nil
|
||||||
|
"When non-nil, the other of the two swapped windows gets the point."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defun aw-swap-window (window)
|
||||||
|
"Swap buffers of current window and WINDOW."
|
||||||
|
(cl-labels ((swap-windows (window1 window2)
|
||||||
|
"Swap the buffers of WINDOW1 and WINDOW2."
|
||||||
|
(let ((buffer1 (window-buffer window1))
|
||||||
|
(buffer2 (window-buffer window2)))
|
||||||
|
(set-window-buffer window1 buffer2)
|
||||||
|
(set-window-buffer window2 buffer1)
|
||||||
|
(select-window window2))))
|
||||||
|
(let ((frame (window-frame window))
|
||||||
|
(this-window (selected-window)))
|
||||||
|
(when (and (frame-live-p frame)
|
||||||
|
(not (eq frame (selected-frame))))
|
||||||
|
(select-frame-set-input-focus (window-frame window)))
|
||||||
|
(when (and (window-live-p window)
|
||||||
|
(not (eq window this-window)))
|
||||||
|
(aw--push-window this-window)
|
||||||
|
(if aw-swap-invert
|
||||||
|
(swap-windows window this-window)
|
||||||
|
(swap-windows this-window window))))))
|
||||||
|
|
||||||
|
(defun aw-move-window (window)
|
||||||
|
"Move the current buffer to WINDOW.
|
||||||
|
Switch the current window to the previous buffer."
|
||||||
|
(let ((buffer (current-buffer)))
|
||||||
|
(switch-to-buffer (other-buffer))
|
||||||
|
(aw-switch-to-window window)
|
||||||
|
(switch-to-buffer buffer)))
|
||||||
|
|
||||||
|
(defun aw-split-window-vert (window)
|
||||||
|
"Split WINDOW vertically."
|
||||||
|
(select-window window)
|
||||||
|
(split-window-vertically))
|
||||||
|
|
||||||
|
(defun aw-split-window-horz (window)
|
||||||
|
"Split WINDOW horizontally."
|
||||||
|
(select-window window)
|
||||||
|
(split-window-horizontally))
|
||||||
|
|
||||||
|
(defcustom aw-fair-aspect-ratio 2
|
||||||
|
"The aspect ratio to aim for when splitting windows.
|
||||||
|
Sizes are based on the number of characters, not pixels.
|
||||||
|
Increase to prefer wider windows, or decrease for taller windows."
|
||||||
|
:type 'number)
|
||||||
|
|
||||||
|
(defun aw-split-window-fair (window)
|
||||||
|
"Split WINDOW vertically or horizontally, based on its current dimensions.
|
||||||
|
Modify `aw-fair-aspect-ratio' to tweak behavior."
|
||||||
|
(let ((w (window-body-width window))
|
||||||
|
(h (window-body-height window)))
|
||||||
|
(if (< (* h aw-fair-aspect-ratio) w)
|
||||||
|
(aw-split-window-horz window)
|
||||||
|
(aw-split-window-vert window))))
|
||||||
|
|
||||||
|
(defun aw-switch-buffer-other-window (window)
|
||||||
|
"Switch buffer in WINDOW without selecting WINDOW."
|
||||||
|
(aw-switch-to-window window)
|
||||||
|
(aw--switch-buffer)
|
||||||
|
(aw-flip-window))
|
||||||
|
|
||||||
|
(defun aw-offset (window)
|
||||||
|
"Return point in WINDOW that's closest to top left corner.
|
||||||
|
The point is writable, i.e. it's not part of space after newline."
|
||||||
|
(let ((h (window-hscroll window))
|
||||||
|
(beg (window-start window))
|
||||||
|
(end (window-end window))
|
||||||
|
(inhibit-field-text-motion t))
|
||||||
|
(with-current-buffer
|
||||||
|
(window-buffer window)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char beg)
|
||||||
|
(while (and (< (point) end)
|
||||||
|
(< (- (line-end-position)
|
||||||
|
(line-beginning-position))
|
||||||
|
h))
|
||||||
|
(forward-line))
|
||||||
|
(+ (point) h)))))
|
||||||
|
|
||||||
|
;;* Mode line
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode ace-window-display-mode
|
||||||
|
"Minor mode for showing the ace window key in the mode line."
|
||||||
|
:global t
|
||||||
|
(if ace-window-display-mode
|
||||||
|
(progn
|
||||||
|
(aw-update)
|
||||||
|
(set-default
|
||||||
|
'mode-line-format
|
||||||
|
`((ace-window-display-mode
|
||||||
|
(:eval (window-parameter (selected-window) 'ace-window-path)))
|
||||||
|
,@(assq-delete-all
|
||||||
|
'ace-window-display-mode
|
||||||
|
(default-value 'mode-line-format))))
|
||||||
|
(force-mode-line-update t)
|
||||||
|
(add-hook 'window-configuration-change-hook 'aw-update)
|
||||||
|
;; Add at the end so does not precede select-frame call.
|
||||||
|
(add-hook 'after-make-frame-functions (lambda (_) (aw-update)) t))
|
||||||
|
(set-default
|
||||||
|
'mode-line-format
|
||||||
|
(assq-delete-all
|
||||||
|
'ace-window-display-mode
|
||||||
|
(default-value 'mode-line-format)))
|
||||||
|
(remove-hook 'window-configuration-change-hook 'aw-update)
|
||||||
|
(remove-hook 'after-make-frame-functions 'aw-update)))
|
||||||
|
|
||||||
|
(defun aw-update ()
|
||||||
|
"Update ace-window-path window parameter for all windows.
|
||||||
|
|
||||||
|
Ensure all windows are labeled so the user can select a specific
|
||||||
|
one, even from the set of windows typically ignored when making a
|
||||||
|
window list."
|
||||||
|
(let ((aw-ignore-on)
|
||||||
|
(aw-ignore-current)
|
||||||
|
(ignore-window-parameters t))
|
||||||
|
(avy-traverse
|
||||||
|
(avy-tree (aw-window-list) aw-keys)
|
||||||
|
(lambda (path leaf)
|
||||||
|
(set-window-parameter
|
||||||
|
leaf 'ace-window-path
|
||||||
|
(propertize
|
||||||
|
(apply #'string (reverse path))
|
||||||
|
'face 'aw-mode-line-face))))))
|
||||||
|
|
||||||
|
(provide 'ace-window)
|
||||||
|
|
||||||
|
;;; ace-window.el ends here
|
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
;;; add-node-modules-path-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "add-node-modules-path" "add-node-modules-path.el"
|
||||||
|
;;;;;; (23438 54284 226170 718000))
|
||||||
|
;;; Generated autoloads from add-node-modules-path.el
|
||||||
|
|
||||||
|
(defvar add-node-modules-path-debug nil "\
|
||||||
|
Enable verbose output when non nil.")
|
||||||
|
|
||||||
|
(custom-autoload 'add-node-modules-path-debug "add-node-modules-path" t)
|
||||||
|
|
||||||
|
(defvar add-node-modules-max-depth 20 "\
|
||||||
|
Max depth to look for node_modules.")
|
||||||
|
|
||||||
|
(custom-autoload 'add-node-modules-max-depth "add-node-modules-path" t)
|
||||||
|
|
||||||
|
(autoload 'add-node-modules-path "add-node-modules-path" "\
|
||||||
|
Search the current buffer's parent directories for `node_modules/.bin`.
|
||||||
|
Traverse the directory structure up, until reaching the user's home directory,
|
||||||
|
or hitting add-node-modules-max-depth.
|
||||||
|
Any path found is added to the `exec-path'.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; add-node-modules-path-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "add-node-modules-path" "20180710.2342" "Add node_modules to your exec-path" 'nil :commit "f31e69ccb681f882aebb806ce6e9478e3ac39708" :keywords '("javascript" "node" "node_modules" "eslint") :authors '(("Neri Marschik" . "marschik_neri@cyberagent.co.jp")) :maintainer '("Neri Marschik" . "marschik_neri@cyberagent.co.jp") :url "https://github.com/codesuki/add-node-modules-path")
|
|
@ -0,0 +1,79 @@
|
||||||
|
;;; add-node-modules-path.el --- Add node_modules to your exec-path
|
||||||
|
|
||||||
|
;; Copyright (C) 2016 Neri Marschik
|
||||||
|
;; This package uses the MIT License.
|
||||||
|
;; See the LICENSE file.
|
||||||
|
|
||||||
|
;; Author: Neri Marschik <marschik_neri@cyberagent.co.jp>
|
||||||
|
;; Version: 1.0
|
||||||
|
;; Package-Version: 20180710.2342
|
||||||
|
;; Package-Requires: ()
|
||||||
|
;; Keywords: javascript, node, node_modules, eslint
|
||||||
|
;; URL: https://github.com/codesuki/add-node-modules-path
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; This file provides `add-node-modules-path', which searches
|
||||||
|
;; the current files parent directories for the `node_modules/.bin/' directory
|
||||||
|
;; and adds it to the buffer local `exec-path'.
|
||||||
|
;; This allows Emacs to find project based installs of e.g. eslint.
|
||||||
|
;;
|
||||||
|
;; Usage:
|
||||||
|
;; M-x add-node-modules-path
|
||||||
|
;;
|
||||||
|
;; To automatically run it when opening a new buffer:
|
||||||
|
;; (Choose depending on your favorite mode.)
|
||||||
|
;;
|
||||||
|
;; (eval-after-load 'js-mode
|
||||||
|
;; '(add-hook 'js-mode-hook #'add-node-modules-path))
|
||||||
|
;;
|
||||||
|
;; (eval-after-load 'js2-mode
|
||||||
|
;; '(add-hook 'js2-mode-hook #'add-node-modules-path))
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defcustom add-node-modules-path-debug nil
|
||||||
|
"Enable verbose output when non nil."
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defcustom add-node-modules-max-depth 20
|
||||||
|
"Max depth to look for node_modules."
|
||||||
|
:type 'integer)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun add-node-modules-path ()
|
||||||
|
"Search the current buffer's parent directories for `node_modules/.bin`.
|
||||||
|
Traverse the directory structure up, until reaching the user's home directory,
|
||||||
|
or hitting add-node-modules-max-depth.
|
||||||
|
Any path found is added to the `exec-path'."
|
||||||
|
(interactive)
|
||||||
|
(let* ((default-dir (expand-file-name default-directory))
|
||||||
|
(file (or (buffer-file-name) default-dir))
|
||||||
|
(home (expand-file-name "~"))
|
||||||
|
(iterations add-node-modules-max-depth)
|
||||||
|
(root (directory-file-name (or (and (buffer-file-name) (file-name-directory (buffer-file-name))) default-dir)))
|
||||||
|
(roots '()))
|
||||||
|
(while (and root (> iterations 0))
|
||||||
|
(setq iterations (1- iterations))
|
||||||
|
(let ((bindir (expand-file-name "node_modules/.bin/" root)))
|
||||||
|
(when (file-directory-p bindir)
|
||||||
|
(add-to-list 'roots bindir)))
|
||||||
|
(if (string= root home)
|
||||||
|
(setq root nil)
|
||||||
|
(setq root (directory-file-name (file-name-directory root)))))
|
||||||
|
(if roots
|
||||||
|
(progn
|
||||||
|
(make-local-variable 'exec-path)
|
||||||
|
(while roots
|
||||||
|
(add-to-list 'exec-path (car roots))
|
||||||
|
(when add-node-modules-path-debug
|
||||||
|
(message (concat "added " (car roots) " to exec-path")))
|
||||||
|
(setq roots (cdr roots))))
|
||||||
|
(when add-node-modules-path-debug
|
||||||
|
(message (concat "node_modules/.bin not found for " file))))))
|
||||||
|
|
||||||
|
(provide 'add-node-modules-path)
|
||||||
|
|
||||||
|
;;; add-node-modules-path.el ends here
|
Binary file not shown.
|
@ -0,0 +1,94 @@
|
||||||
|
;;; alert-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "alert" "alert.el" (23377 61297 758177 48000))
|
||||||
|
;;; Generated autoloads from alert.el
|
||||||
|
|
||||||
|
(autoload 'alert-add-rule "alert" "\
|
||||||
|
Programmatically add an alert configuration rule.
|
||||||
|
|
||||||
|
Normally, users should custoimze `alert-user-configuration'.
|
||||||
|
This facility is for module writers and users that need to do
|
||||||
|
things the Lisp way.
|
||||||
|
|
||||||
|
Here is a rule the author currently uses with ERC, so that the
|
||||||
|
fringe gets colored whenever people chat on BitlBee:
|
||||||
|
|
||||||
|
\(alert-add-rule :status \\='(buried visible idle)
|
||||||
|
:severity \\='(moderate high urgent)
|
||||||
|
:mode \\='erc-mode
|
||||||
|
:predicate
|
||||||
|
#\\='(lambda (info)
|
||||||
|
(string-match (concat \"\\\\`[^&].*@BitlBee\\\\\\='\")
|
||||||
|
(erc-format-target-and/or-network)))
|
||||||
|
:persistent
|
||||||
|
#\\='(lambda (info)
|
||||||
|
;; If the buffer is buried, or the user has been
|
||||||
|
;; idle for `alert-reveal-idle-time' seconds,
|
||||||
|
;; make this alert persistent. Normally, alerts
|
||||||
|
;; become persistent after
|
||||||
|
;; `alert-persist-idle-time' seconds.
|
||||||
|
(memq (plist-get info :status) \\='(buried idle)))
|
||||||
|
:style \\='fringe
|
||||||
|
:continue t)
|
||||||
|
|
||||||
|
\(fn &key SEVERITY STATUS MODE CATEGORY TITLE MESSAGE PREDICATE ICON (style alert-default-style) PERSISTENT CONTINUE NEVER-PERSIST APPEND)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'alert "alert" "\
|
||||||
|
Alert the user that something has happened.
|
||||||
|
MESSAGE is what the user will see. You may also use keyword
|
||||||
|
arguments to specify additional details. Here is a full example:
|
||||||
|
|
||||||
|
\(alert \"This is a message\"
|
||||||
|
:severity \\='high ;; The default severity is `normal'
|
||||||
|
:title \"Title\" ;; An optional title
|
||||||
|
:category \\='example ;; A symbol to identify the message
|
||||||
|
:mode \\='text-mode ;; Normally determined automatically
|
||||||
|
:buffer (current-buffer) ;; This is the default
|
||||||
|
:data nil ;; Unused by alert.el itself
|
||||||
|
:persistent nil ;; Force the alert to be persistent;
|
||||||
|
;; it is best not to use this
|
||||||
|
:never-persist nil ;; Force this alert to never persist
|
||||||
|
:id \\='my-id) ;; Used to replace previous message of
|
||||||
|
;; the same id in styles that support it
|
||||||
|
:style \\='fringe) ;; Force a given style to be used;
|
||||||
|
;; this is only for debugging!
|
||||||
|
|
||||||
|
If no :title is given, the buffer-name of :buffer is used. If
|
||||||
|
:buffer is nil, it is the current buffer at the point of call.
|
||||||
|
|
||||||
|
:data is an opaque value which modules can pass through to their
|
||||||
|
own styles if they wish.
|
||||||
|
|
||||||
|
Here are some more typical examples of usage:
|
||||||
|
|
||||||
|
;; This is the most basic form usage
|
||||||
|
(alert \"This is an alert\")
|
||||||
|
|
||||||
|
;; You can adjust the severity for more important messages
|
||||||
|
(alert \"This is an alert\" :severity \\='high)
|
||||||
|
|
||||||
|
;; Or decrease it for purely informative ones
|
||||||
|
(alert \"This is an alert\" :severity \\='trivial)
|
||||||
|
|
||||||
|
;; Alerts can have optional titles. Otherwise, the title is the
|
||||||
|
;; buffer-name of the (current-buffer) where the alert originated.
|
||||||
|
(alert \"This is an alert\" :title \"My Alert\")
|
||||||
|
|
||||||
|
;; Further, alerts can have categories. This allows users to
|
||||||
|
;; selectively filter on them.
|
||||||
|
(alert \"This is an alert\" :title \"My Alert\"
|
||||||
|
:category \\='some-category-or-other)
|
||||||
|
|
||||||
|
\(fn MESSAGE &key (severity (quote normal)) TITLE ICON CATEGORY BUFFER MODE DATA STYLE PERSISTENT NEVER-PERSIST ID)" nil nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; alert-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "alert" "20180403.38" "Growl-style notification system for Emacs" '((gntp "0.1") (log4e "0.3.0")))
|
1161
configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el
Normal file
1161
configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.el
Normal file
File diff suppressed because it is too large
Load diff
BIN
configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elc
Normal file
BIN
configs/shared/emacs/.emacs.d/elpa/alert-20180403.38/alert.elc
Normal file
Binary file not shown.
|
@ -0,0 +1,59 @@
|
||||||
|
;;; all-the-icons-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "all-the-icons" "all-the-icons.el" (23377 61284
|
||||||
|
;;;;;; 887385 430000))
|
||||||
|
;;; Generated autoloads from all-the-icons.el
|
||||||
|
|
||||||
|
(autoload 'all-the-icons-icon-for-file "all-the-icons" "\
|
||||||
|
Get the formatted icon for FILE.
|
||||||
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
|
inserting functions.
|
||||||
|
|
||||||
|
\(fn FILE &rest ARG-OVERRIDES)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'all-the-icons-icon-for-mode "all-the-icons" "\
|
||||||
|
Get the formatted icon for MODE.
|
||||||
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
|
inserting functions.
|
||||||
|
|
||||||
|
\(fn MODE &rest ARG-OVERRIDES)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'all-the-icons--icon-info-for-buffer "all-the-icons" "\
|
||||||
|
Get icon info for the current buffer.
|
||||||
|
|
||||||
|
When F is provided, the info function is calculated with the format
|
||||||
|
`all-the-icons-icon-%s-for-file' or `all-the-icons-icon-%s-for-mode'.
|
||||||
|
|
||||||
|
\(fn &optional F)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'all-the-icons-install-fonts "all-the-icons" "\
|
||||||
|
Helper function to download and install the latests fonts based on OS.
|
||||||
|
When PFX is non-nil, ignore the prompt and just install
|
||||||
|
|
||||||
|
\(fn &optional PFX)" t nil)
|
||||||
|
|
||||||
|
(autoload 'all-the-icons-insert "all-the-icons" "\
|
||||||
|
Interactive icon insertion function.
|
||||||
|
When Prefix ARG is non-nil, insert the propertized icon.
|
||||||
|
When FAMILY is non-nil, limit the candidates to the icon set matching it.
|
||||||
|
|
||||||
|
\(fn &optional ARG FAMILY)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil nil ("all-the-icons-faces.el" "all-the-icons-pkg.el")
|
||||||
|
;;;;;; (23377 61284 888696 545000))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; all-the-icons-autoloads.el ends here
|
|
@ -0,0 +1,225 @@
|
||||||
|
;;; all-the-icons-faces.el --- A module of faces for all-the-icons
|
||||||
|
|
||||||
|
;; Copyright (C) 2016 Dominic Charlesworth <dgc336@gmail.com>
|
||||||
|
|
||||||
|
;; Author: Dominic Charlesworth <dgc336@gmail.com>
|
||||||
|
;; Version: 1.0.0
|
||||||
|
;; Package-Requires: ((emacs "24.3"))
|
||||||
|
;; URL: https://github.com/domtronn/all-the-icons.el
|
||||||
|
;; Keywords: convenient, lisp
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or
|
||||||
|
;; modify it under the terms of the GNU General Public License
|
||||||
|
;; as published by the Free Software Foundation; either version 3
|
||||||
|
;; of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This file contains all of the faces used by the package for
|
||||||
|
;; colouring icons
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defgroup all-the-icons-faces nil
|
||||||
|
"Manage how All The Icons icons are coloured and themed."
|
||||||
|
:prefix "all-the-icons-"
|
||||||
|
:group 'tools
|
||||||
|
:group 'all-the-icons)
|
||||||
|
|
||||||
|
|
||||||
|
;; red
|
||||||
|
(defface all-the-icons-red
|
||||||
|
'((((background dark)) :foreground "#AC4142")
|
||||||
|
(((background light)) :foreground "#AC4142"))
|
||||||
|
"Face for red icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lred
|
||||||
|
'((((background dark)) :foreground "#EB595A")
|
||||||
|
(((background light)) :foreground "#EB595A"))
|
||||||
|
"Face for lred icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dred
|
||||||
|
'((((background dark)) :foreground "#843031")
|
||||||
|
(((background light)) :foreground "#843031"))
|
||||||
|
"Face for dred icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-red-alt
|
||||||
|
'((((background dark)) :foreground "#ce5643")
|
||||||
|
(((background light)) :foreground "#843031"))
|
||||||
|
"Face for dred icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; green
|
||||||
|
(defface all-the-icons-green
|
||||||
|
'((((background dark)) :foreground "#90A959")
|
||||||
|
(((background light)) :foreground "#90A959"))
|
||||||
|
"Face for green icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lgreen
|
||||||
|
'((((background dark)) :foreground "#C6E87A")
|
||||||
|
(((background light)) :foreground "#3D6837"))
|
||||||
|
"Face for lgreen icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dgreen
|
||||||
|
'((((background dark)) :foreground "#6D8143")
|
||||||
|
(((background light)) :foreground "#6D8143"))
|
||||||
|
"Face for dgreen icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; yellow
|
||||||
|
(defface all-the-icons-yellow
|
||||||
|
'((((background dark)) :foreground "#FFD446")
|
||||||
|
(((background light)) :foreground "#FFCC0E"))
|
||||||
|
"Face for yellow icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lyellow
|
||||||
|
'((((background dark)) :foreground "#FFC16D")
|
||||||
|
(((background light)) :foreground "#FF9300"))
|
||||||
|
"Face for lyellow icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dyellow
|
||||||
|
'((((background dark)) :foreground "#B48D56")
|
||||||
|
(((background light)) :foreground "#B48D56"))
|
||||||
|
"Face for dyellow icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; blue
|
||||||
|
(defface all-the-icons-blue
|
||||||
|
'((((background dark)) :foreground "#6A9FB5")
|
||||||
|
(((background light)) :foreground "#6A9FB5"))
|
||||||
|
"Face for blue icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-blue-alt
|
||||||
|
'((((background dark)) :foreground "#2188b6")
|
||||||
|
(((background light)) :foreground "#2188b6"))
|
||||||
|
"Face for blue icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lblue
|
||||||
|
'((((background dark)) :foreground "#8FD7F4")
|
||||||
|
(((background light)) :foreground "#677174"))
|
||||||
|
"Face for lblue icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dblue
|
||||||
|
'((((background dark)) :foreground "#446674")
|
||||||
|
(((background light)) :foreground "#446674"))
|
||||||
|
"Face for dblue icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; maroon
|
||||||
|
(defface all-the-icons-maroon
|
||||||
|
'((((background dark)) :foreground "#8F5536")
|
||||||
|
(((background light)) :foreground "#8F5536"))
|
||||||
|
"Face for maroon icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lmaroon
|
||||||
|
'((((background dark)) :foreground "#CE7A4E")
|
||||||
|
(((background light)) :foreground "#CE7A4E"))
|
||||||
|
"Face for lmaroon icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dmaroon
|
||||||
|
'((((background dark)) :foreground "#72584B")
|
||||||
|
(((background light)) :foreground "#72584B"))
|
||||||
|
"Face for dmaroon icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; purple
|
||||||
|
(defface all-the-icons-purple
|
||||||
|
'((((background dark)) :foreground "#AA759F")
|
||||||
|
(((background light)) :foreground "#68295B"))
|
||||||
|
"Face for purple icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lpurple
|
||||||
|
'((((background dark)) :foreground "#E69DD6")
|
||||||
|
(((background light)) :foreground "#E69DD6"))
|
||||||
|
"Face for lpurple icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dpurple
|
||||||
|
'((((background dark)) :foreground "#694863")
|
||||||
|
(((background light)) :foreground "#694863"))
|
||||||
|
"Face for dpurple icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; orange
|
||||||
|
(defface all-the-icons-orange
|
||||||
|
'((((background dark)) :foreground "#D4843E")
|
||||||
|
(((background light)) :foreground "#D4843E"))
|
||||||
|
"Face for orange icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lorange
|
||||||
|
'((((background dark)) :foreground "#FFA500")
|
||||||
|
(((background light)) :foreground "#FFA500"))
|
||||||
|
"Face for lorange icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dorange
|
||||||
|
'((((background dark)) :foreground "#915B2D")
|
||||||
|
(((background light)) :foreground "#915B2D"))
|
||||||
|
"Face for dorange icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; cyan
|
||||||
|
(defface all-the-icons-cyan
|
||||||
|
'((((background dark)) :foreground "#75B5AA")
|
||||||
|
(((background light)) :foreground "#75B5AA"))
|
||||||
|
"Face for cyan icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-cyan-alt
|
||||||
|
'((((background dark)) :foreground "#61dafb")
|
||||||
|
(((background light)) :foreground "#0595bd"))
|
||||||
|
"Face for cyan icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lcyan
|
||||||
|
'((((background dark)) :foreground "#A5FDEC")
|
||||||
|
(((background light)) :foreground "#2C7D6E"))
|
||||||
|
"Face for lcyan icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dcyan
|
||||||
|
'((((background dark)) :foreground "#48746D")
|
||||||
|
(((background light)) :foreground "#48746D"))
|
||||||
|
"Face for dcyan icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; pink
|
||||||
|
(defface all-the-icons-pink
|
||||||
|
'((((background dark)) :foreground "#F2B4B8")
|
||||||
|
(((background light)) :foreground "#FC505B"))
|
||||||
|
"Face for pink icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lpink
|
||||||
|
'((((background dark)) :foreground "#FFBDC1")
|
||||||
|
(((background light)) :foreground "#FF505B"))
|
||||||
|
"Face for lpink icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dpink
|
||||||
|
'((((background dark)) :foreground "#B18286")
|
||||||
|
(((background light)) :foreground "#7E5D5F"))
|
||||||
|
"Face for dpink icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;; silver
|
||||||
|
(defface all-the-icons-silver
|
||||||
|
'((((background dark)) :foreground "#716E68")
|
||||||
|
(((background light)) :foreground "#716E68"))
|
||||||
|
"Face for silver icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-lsilver
|
||||||
|
'((((background dark)) :foreground "#B9B6AA")
|
||||||
|
(((background light)) :foreground "#7F7869"))
|
||||||
|
"Face for lsilver icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
(defface all-the-icons-dsilver
|
||||||
|
'((((background dark)) :foreground "#838484")
|
||||||
|
(((background light)) :foreground "#838484"))
|
||||||
|
"Face for dsilver icons"
|
||||||
|
:group 'all-the-icons-faces)
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'all-the-icons-faces)
|
||||||
|
;;; all-the-icons-faces.el ends here
|
Binary file not shown.
|
@ -0,0 +1,9 @@
|
||||||
|
(define-package "all-the-icons" "20180125.757" "A library for inserting Developer icons"
|
||||||
|
'((emacs "24.3")
|
||||||
|
(memoize "1.0.1"))
|
||||||
|
:keywords
|
||||||
|
'("convenient" "lisp")
|
||||||
|
:url "https://github.com/domtronn/all-the-icons.el")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
|
@ -0,0 +1,832 @@
|
||||||
|
;;; all-the-icons.el --- A library for inserting Developer icons
|
||||||
|
|
||||||
|
;; Copyright (C) 2016 Dominic Charlesworth <dgc336@gmail.com>
|
||||||
|
|
||||||
|
;; Author: Dominic Charlesworth <dgc336@gmail.com>
|
||||||
|
;; Version: 3.1.4
|
||||||
|
;; Package-Requires: ((emacs "24.3") (memoize "1.0.1"))
|
||||||
|
;; URL: https://github.com/domtronn/all-the-icons.el
|
||||||
|
;; Keywords: convenient, lisp
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or
|
||||||
|
;; modify it under the terms of the GNU General Public License
|
||||||
|
;; as published by the Free Software Foundation; either version 3
|
||||||
|
;; of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This package is a utility for using and formatting various Icon
|
||||||
|
;; fonts within Emacs. Icon Fonts allow you to propertize and format
|
||||||
|
;; icons the same way you would normal text. This enables things such
|
||||||
|
;; as better scaling of and anti aliasing of the icons.
|
||||||
|
|
||||||
|
;; This package was inspired by
|
||||||
|
|
||||||
|
;; - `mode-icons' for Emacs, found at https://github.com/ryuslash/mode-icons
|
||||||
|
;; - `file-icons' for Atom, found at https://atom.io/packages/file-icons
|
||||||
|
|
||||||
|
;; Currently, this package provides an interface to the following Icon Fonts
|
||||||
|
|
||||||
|
;; - Atom File Icons, found at https://atom.io/packages/file-icons
|
||||||
|
;; - FontAwesome Icons, found at http://fontawesome.io/
|
||||||
|
;; - GitHub Octicons, found at http://octicons.github.com
|
||||||
|
;; - Material Design Icons, found at http://google.github.io/material-design-icons/
|
||||||
|
;; - Weather Icons, found at https://erikflowers.github.io/weather-icons/
|
||||||
|
;; - AllTheIcons, a custom Icon Font maintained as part of this package
|
||||||
|
|
||||||
|
;; Requests for new icons will be accepted and added to the AllTheIcons Icon Font
|
||||||
|
|
||||||
|
;;; Usage:
|
||||||
|
|
||||||
|
;; The simplest usage for this package is to use the following functions;
|
||||||
|
|
||||||
|
;; `all-the-icons-icon-for-buffer'
|
||||||
|
;; `all-the-icons-icon-for-file'
|
||||||
|
;; `all-the-icons-icon-for-mode'
|
||||||
|
|
||||||
|
;; Which can be used to get a formatted icon for the current buffer, a
|
||||||
|
;; file name or a major mode respectively. e.g.
|
||||||
|
|
||||||
|
;; (insert (all-the-icons-icon-for-file "foo.js"))
|
||||||
|
|
||||||
|
;; Inserts a JavaScript icon formatted like this
|
||||||
|
|
||||||
|
;; #("some-icon" 0 1 (display (raise -0.24)
|
||||||
|
;; face (:family "dev-icons" :height 1.08 :foreground "#FFD446")))
|
||||||
|
|
||||||
|
;; You can also insert icons directly using the individual icon family
|
||||||
|
;; functions
|
||||||
|
|
||||||
|
;; `all-the-icons-alltheicon' // Custom font with fewest icons
|
||||||
|
;; `all-the-icons-devicon' // Developer Icons
|
||||||
|
;; `all-the-icons-faicon' // Font Awesome Icons
|
||||||
|
;; `all-the-icons-fileicon' // File Icons from the Atom File Icons package
|
||||||
|
;; `all-the-icons-octicon' // GitHub Octicons
|
||||||
|
;; `all-the-icons-material' // Material Design Icons
|
||||||
|
;; `all-the-icons-wicon' // Weather Icons
|
||||||
|
|
||||||
|
;; You can call these functions with the icon name you want to insert, e.g.
|
||||||
|
|
||||||
|
;; (all-the-icons-octicon "file-binary") // GitHub Octicon for Binary File
|
||||||
|
;; (all-the-icons-faicon "cogs") // FontAwesome icon for cogs
|
||||||
|
;; (all-the-icons-wicon "tornado") // Weather Icon for tornado
|
||||||
|
|
||||||
|
;; A list of all the icon names for the different font families can be
|
||||||
|
;; found in the data directory, or by inspecting the alist variables.
|
||||||
|
;; All the alist variables are prefixed with `all-the-icons-data/'
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'memoize)
|
||||||
|
(require 'cl-lib)
|
||||||
|
|
||||||
|
(require 'data-alltheicons "./data/data-alltheicons.el")
|
||||||
|
(require 'data-faicons "./data/data-faicons.el")
|
||||||
|
(require 'data-fileicons "./data/data-fileicons.el")
|
||||||
|
(require 'data-octicons "./data/data-octicons.el")
|
||||||
|
(require 'data-weathericons "./data/data-weathericons.el")
|
||||||
|
(require 'data-material "./data/data-material.el")
|
||||||
|
|
||||||
|
(require 'all-the-icons-faces)
|
||||||
|
|
||||||
|
;;; Custom Variables
|
||||||
|
(defgroup all-the-icons nil
|
||||||
|
"Manage how All The Icons formats icons."
|
||||||
|
:prefix "all-the-icons-"
|
||||||
|
:group 'appearance
|
||||||
|
:group 'convenience)
|
||||||
|
|
||||||
|
(defcustom all-the-icons-color-icons t
|
||||||
|
"Whether or not to include a foreground colour when formatting the icon."
|
||||||
|
:group 'all-the-icons
|
||||||
|
:type 'boolean)
|
||||||
|
|
||||||
|
(defcustom all-the-icons-scale-factor 1.2
|
||||||
|
"The base Scale Factor for the `height' face property of an icon."
|
||||||
|
:group 'all-the-icons
|
||||||
|
:type 'number)
|
||||||
|
|
||||||
|
(defcustom all-the-icons-default-adjust -0.2
|
||||||
|
"The default adjustment to be made to the `raise' display property of an icon."
|
||||||
|
:group 'all-the-icons
|
||||||
|
:type 'number)
|
||||||
|
|
||||||
|
(defvar all-the-icons-font-families '() "List of defined icon font families.")
|
||||||
|
(defvar all-the-icons-font-names '() "List of defined font file names this package was built with.")
|
||||||
|
|
||||||
|
(defvar all-the-icons-icon-alist
|
||||||
|
'(
|
||||||
|
;; Meta
|
||||||
|
("\\.tags" all-the-icons-octicon "tag" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("^TAGS$" all-the-icons-octicon "tag" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("\\.log" all-the-icons-octicon "bug" :height 1.0 :v-adjust 0.0 :face all-the-icons-maroon)
|
||||||
|
|
||||||
|
;;
|
||||||
|
("\\.key$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
("\\.pem$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-orange)
|
||||||
|
("\\.p12$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-dorange)
|
||||||
|
("\\.crt$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
("\\.pub$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("\\.gpg$" all-the-icons-octicon "key" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
|
||||||
|
("^TODO$" all-the-icons-octicon "checklist" :v-adjust 0.0 :face all-the-icons-lyellow)
|
||||||
|
("^LICENSE$" all-the-icons-octicon "book" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("^readme" all-the-icons-octicon "book" :height 1.0 :v-adjust 0.0 :face all-the-icons-lcyan)
|
||||||
|
|
||||||
|
("\\.fish" all-the-icons-alltheicon "terminal" :face all-the-icons-lpink)
|
||||||
|
("\\.zsh" all-the-icons-alltheicon "terminal" :face all-the-icons-lcyan)
|
||||||
|
("\\.sh" all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
||||||
|
|
||||||
|
;; Config
|
||||||
|
("\\.node" all-the-icons-alltheicon "nodejs" :height 1.0 :face all-the-icons-green)
|
||||||
|
("\\.babelrc$" all-the-icons-fileicon "babel" :face all-the-icons-yellow)
|
||||||
|
("\\.bashrc$" all-the-icons-alltheicon "script" :height 0.9 :face all-the-icons-dpink)
|
||||||
|
("\\.bowerrc$" all-the-icons-alltheicon "bower" :height 1.0 :v-adjust 0.0 :face all-the-icons-silver)
|
||||||
|
("^bower.json$" all-the-icons-alltheicon "bower" :height 1.0 :v-adjust 0.0 :face all-the-icons-lorange)
|
||||||
|
("\\.ini$" all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.eslintignore" all-the-icons-fileicon "eslint" :height 0.9 :face all-the-icons-purple)
|
||||||
|
("\\.eslint" all-the-icons-fileicon "eslint" :height 0.9 :face all-the-icons-lpurple)
|
||||||
|
("\\.git" all-the-icons-alltheicon "git" :height 1.0 :face all-the-icons-lred)
|
||||||
|
("nginx" all-the-icons-fileicon "nginx" :height 0.9 :face all-the-icons-dgreen)
|
||||||
|
("apache" all-the-icons-alltheicon "apache" :height 0.9 :face all-the-icons-dgreen)
|
||||||
|
("^Makefile$" all-the-icons-fileicon "gnu" :face all-the-icons-dorange)
|
||||||
|
("\\.mk$" all-the-icons-fileicon "gnu" :face all-the-icons-dorange)
|
||||||
|
|
||||||
|
("\\.dockerignore$" all-the-icons-fileicon "dockerfile" :height 1.2 :face all-the-icons-dblue)
|
||||||
|
("^\\.?Dockerfile" all-the-icons-fileicon "dockerfile" :face all-the-icons-blue)
|
||||||
|
("^Brewfile$" all-the-icons-faicon "beer" :face all-the-icons-lsilver)
|
||||||
|
("\\.npmignore" all-the-icons-fileicon "npm" :face all-the-icons-dred)
|
||||||
|
("^package.json$" all-the-icons-fileicon "npm" :face all-the-icons-red)
|
||||||
|
("^package.lock.json$" all-the-icons-fileicon "npm" :face all-the-icons-dred)
|
||||||
|
("^yarn\.lock" all-the-icons-fileicon "yarn" :face all-the-icons-blue-alt)
|
||||||
|
|
||||||
|
("\.xml$" all-the-icons-faicon "file-code-o" :height 0.95 :face all-the-icons-lorange)
|
||||||
|
|
||||||
|
;; ;; AWS
|
||||||
|
("^stack.*.json$" all-the-icons-alltheicon "aws" :face all-the-icons-orange)
|
||||||
|
|
||||||
|
|
||||||
|
("^serverless\\.yml$" all-the-icons-faicon "bolt" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.[jc]son$" all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.ya?ml$" all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-dyellow)
|
||||||
|
|
||||||
|
("\\.pkg$" all-the-icons-octicon "package" :v-adjust 0.0 :face all-the-icons-dsilver)
|
||||||
|
("\\.rpm$" all-the-icons-octicon "package" :v-adjust 0.0 :face all-the-icons-dsilver)
|
||||||
|
|
||||||
|
("\\.elc$" all-the-icons-octicon "file-binary" :v-adjust 0.0 :face all-the-icons-dsilver)
|
||||||
|
|
||||||
|
("\\.gz$" all-the-icons-octicon "file-binary" :v-adjust 0.0 :face all-the-icons-lmaroon)
|
||||||
|
("\\.zip$" all-the-icons-octicon "file-zip" :v-adjust 0.0 :face all-the-icons-lmaroon)
|
||||||
|
("\\.7z$" all-the-icons-octicon "file-zip" :v-adjust 0.0 :face all-the-icons-lmaroon)
|
||||||
|
|
||||||
|
("\\.dat$" all-the-icons-faicon "bar-chart" :face all-the-icons-cyan :height 0.9)
|
||||||
|
;; lock files
|
||||||
|
("~$" all-the-icons-octicon "lock" :v-adjust 0.0 :face all-the-icons-maroon)
|
||||||
|
|
||||||
|
("\\.dmg$" all-the-icons-octicon "tools" :v-adjust 0.0 :face all-the-icons-lsilver)
|
||||||
|
("\\.dll$" all-the-icons-faicon "cogs" :face all-the-icons-silver)
|
||||||
|
("\\.DS_STORE$" all-the-icons-faicon "cogs" :face all-the-icons-silver)
|
||||||
|
|
||||||
|
;; Source Codes
|
||||||
|
("\\.scpt$" all-the-icons-fileicon "apple" :face all-the-icons-pink)
|
||||||
|
("\\.aup$" all-the-icons-fileicon "audacity" :face all-the-icons-yellow)
|
||||||
|
|
||||||
|
("\\.elm" all-the-icons-fileicon "elm" :face all-the-icons-blue)
|
||||||
|
|
||||||
|
("\\.erl$" all-the-icons-alltheicon "erlang" :face all-the-icons-red :v-adjust -0.1 :height 0.9)
|
||||||
|
("\\.hrl$" all-the-icons-alltheicon "erlang" :face all-the-icons-dred :v-adjust -0.1 :height 0.9)
|
||||||
|
|
||||||
|
("\\.eex$" all-the-icons-alltheicon "elixir" :face all-the-icons-lorange :v-adjust -0.1 :height 0.9)
|
||||||
|
("\\.ex$" all-the-icons-alltheicon "elixir" :face all-the-icons-lpurple :v-adjust -0.1 :height 0.9)
|
||||||
|
("\\.exs$" all-the-icons-alltheicon "elixir" :face all-the-icons-lred :v-adjust -0.1 :height 0.9)
|
||||||
|
("^mix.lock$" all-the-icons-alltheicon "elixir" :face all-the-icons-lyellow :v-adjust -0.1 :height 0.9)
|
||||||
|
|
||||||
|
("\\.java$" all-the-icons-alltheicon "java" :height 1.0 :face all-the-icons-purple)
|
||||||
|
|
||||||
|
("\\.go$" all-the-icons-alltheicon "go" :height 1.0 :face all-the-icons-blue)
|
||||||
|
|
||||||
|
("\\.mp3$" all-the-icons-faicon "volume-up" :face all-the-icons-dred)
|
||||||
|
("\\.wav$" all-the-icons-faicon "volume-up" :face all-the-icons-dred)
|
||||||
|
("\\.m4a$" all-the-icons-faicon "volume-up" :face all-the-icons-dred)
|
||||||
|
|
||||||
|
("\\.jl$" all-the-icons-fileicon "julia" :v-adjust 0.0 :face all-the-icons-purple)
|
||||||
|
("\\.matlab$" all-the-icons-fileicon "matlab" :face all-the-icons-orange)
|
||||||
|
|
||||||
|
("\\.p[ml]$" all-the-icons-alltheicon "perl" :face all-the-icons-lorange)
|
||||||
|
("\\.pl6$" all-the-icons-fileicon "perl6" :face all-the-icons-cyan)
|
||||||
|
("\\.pod$" all-the-icons-alltheicon "perldocs" :height 1.2 :face all-the-icons-lgreen)
|
||||||
|
|
||||||
|
("\\.php$" all-the-icons-fileicon "php" :face all-the-icons-lsilver)
|
||||||
|
("\\.pony$" all-the-icons-fileicon "pony" :face all-the-icons-maroon)
|
||||||
|
("\\.prol?o?g?$" all-the-icons-alltheicon "prolog" :height 1.1 :face all-the-icons-lmaroon)
|
||||||
|
("\\.py$" all-the-icons-alltheicon "python" :height 1.0 :face all-the-icons-dblue)
|
||||||
|
|
||||||
|
("\\.rkt$" all-the-icons-fileicon "racket" :height 1.2 :face all-the-icons-red)
|
||||||
|
("\\.gem$" all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
|
("_?test\\.rb$" all-the-icons-fileicon "test-ruby" :height 1.0 :v-adjust 0.0 :face all-the-icons-red)
|
||||||
|
("_?test_helper\\.rb$" all-the-icons-fileicon "test-ruby" :height 1.0 :v-adjust 0.0 :face all-the-icons-dred)
|
||||||
|
("\\.rb$" all-the-icons-octicon "ruby" :v-adjust 0.0 :face all-the-icons-lred)
|
||||||
|
("\\.rs$" all-the-icons-alltheicon "rust" :height 1.2 :face all-the-icons-maroon)
|
||||||
|
("\\.rlib$" all-the-icons-alltheicon "rust" :height 1.2 :face all-the-icons-dmaroon)
|
||||||
|
("\\.r[ds]?x?$" all-the-icons-fileicon "R" :face all-the-icons-lblue)
|
||||||
|
|
||||||
|
("\\.scala$" all-the-icons-alltheicon "scala" :face all-the-icons-red)
|
||||||
|
("\\.scm$" all-the-icons-fileicon "scheme" :height 1.2 :face all-the-icons-red)
|
||||||
|
("\\.swift$" all-the-icons-alltheicon "swift" :height 1.0 :v-adjust -0.1 :face all-the-icons-green)
|
||||||
|
|
||||||
|
("-?spec\\.ts$" all-the-icons-fileicon "test-typescript" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("-?test\\.ts$" all-the-icons-fileicon "test-typescript" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("-?spec\\.js$" all-the-icons-fileicon "test-js" :height 1.0 :v-adjust 0.0 :face all-the-icons-lpurple)
|
||||||
|
("-?test\\.js$" all-the-icons-fileicon "test-js" :height 1.0 :v-adjust 0.0 :face all-the-icons-lpurple)
|
||||||
|
("-?spec\\.jsx$" all-the-icons-fileicon "test-react" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue-alt)
|
||||||
|
("-?test\\.jsx$" all-the-icons-fileicon "test-react" :height 1.0 :v-adjust 0.0 :face all-the-icons-blue-alt)
|
||||||
|
|
||||||
|
("-?spec\\." all-the-icons-fileicon "test-generic" :height 1.0 :v-adjust 0.0 :face all-the-icons-dgreen)
|
||||||
|
("-?test\\." all-the-icons-fileicon "test-generic" :height 1.0 :v-adjust 0.0 :face all-the-icons-dgreen)
|
||||||
|
|
||||||
|
;; There seems to be a a bug with this font icon which does not
|
||||||
|
;; let you propertise it without it reverting to being a lower
|
||||||
|
;; case phi
|
||||||
|
("\\.c$" all-the-icons-alltheicon "c-line" :face all-the-icons-blue)
|
||||||
|
("\\.h$" all-the-icons-alltheicon "c-line" :face all-the-icons-purple)
|
||||||
|
("\\.m$" all-the-icons-fileicon "apple" :v-adjust 0.0 :height 1.0)
|
||||||
|
("\\.mm$" all-the-icons-fileicon "apple" :v-adjust 0.0 :height 1.0)
|
||||||
|
|
||||||
|
("\\.c\\(c\\|pp\\|xx\\)$" all-the-icons-alltheicon "cplusplus-line" :v-adjust -0.2 :face all-the-icons-blue)
|
||||||
|
("\\.h\\(h\\|pp\\|xx\\)$" all-the-icons-alltheicon "cplusplus-line" :v-adjust -0.2 :face all-the-icons-purple)
|
||||||
|
|
||||||
|
("\\.csx?$" all-the-icons-alltheicon "csharp-line" :face all-the-icons-dblue)
|
||||||
|
|
||||||
|
("\\.cljc?$" all-the-icons-alltheicon "clojure-line" :height 1.0 :face all-the-icons-blue :v-adjust 0.0)
|
||||||
|
("\\.cljs$" all-the-icons-fileicon "cljs" :height 1.0 :face all-the-icons-dblue :v-adjust 0.0)
|
||||||
|
|
||||||
|
("\\.coffee$" all-the-icons-alltheicon "coffeescript" :height 1.0 :face all-the-icons-maroon)
|
||||||
|
("\\.iced$" all-the-icons-alltheicon "coffeescript" :height 1.0 :face all-the-icons-lmaroon)
|
||||||
|
|
||||||
|
;; Git
|
||||||
|
("^MERGE_" all-the-icons-octicon "git-merge" :v-adjust 0.0 :face all-the-icons-red)
|
||||||
|
("^COMMIT_EDITMSG" all-the-icons-octicon "git-commit" :v-adjust 0.0 :face all-the-icons-red)
|
||||||
|
|
||||||
|
;; Lisps
|
||||||
|
("\\.cl$" all-the-icons-fileicon "clisp" :face all-the-icons-lorange)
|
||||||
|
("\\.l\\(isp\\)?$" all-the-icons-fileicon "lisp" :face all-the-icons-orange)
|
||||||
|
("\\.el$" all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-purple)
|
||||||
|
|
||||||
|
;; Stylesheeting
|
||||||
|
("\\.css$" all-the-icons-alltheicon "css3" :face all-the-icons-yellow)
|
||||||
|
("\\.scss$" all-the-icons-alltheicon "sass" :face all-the-icons-pink)
|
||||||
|
("\\.sass$" all-the-icons-alltheicon "sass" :face all-the-icons-dpink)
|
||||||
|
("\\.less$" all-the-icons-alltheicon "less" :height 0.8 :face all-the-icons-dyellow)
|
||||||
|
("\\.postcss$" all-the-icons-fileicon "postcss" :face all-the-icons-dred)
|
||||||
|
("\\.sss$" all-the-icons-fileicon "postcss" :face all-the-icons-dred)
|
||||||
|
("\\.styl$" all-the-icons-alltheicon "stylus" :face all-the-icons-lgreen)
|
||||||
|
("stylelint" all-the-icons-fileicon "stylelint" :face all-the-icons-lyellow)
|
||||||
|
("\\.csv$" all-the-icons-octicon "graph" :v-adjust 0.0 :face all-the-icons-dblue)
|
||||||
|
|
||||||
|
("\\.hs$" all-the-icons-alltheicon "haskell" :height 1.0 :face all-the-icons-red)
|
||||||
|
|
||||||
|
;; Web modes
|
||||||
|
("\\.inky-haml$" all-the-icons-fileicon "haml" :face all-the-icons-lyellow)
|
||||||
|
("\\.haml$" all-the-icons-fileicon "haml" :face all-the-icons-lyellow)
|
||||||
|
("\\.html?$" all-the-icons-alltheicon "html5" :face all-the-icons-orange)
|
||||||
|
("\\.inky-erb?$" all-the-icons-alltheicon "html5" :face all-the-icons-lred)
|
||||||
|
("\\.erb$" all-the-icons-alltheicon "html5" :face all-the-icons-lred)
|
||||||
|
("\\.hbs$" all-the-icons-fileicon "moustache" :face all-the-icons-green)
|
||||||
|
("\\.inky-slim$" all-the-icons-octicon "dashboard" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.slim$" all-the-icons-octicon "dashboard" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.jade$" all-the-icons-fileicon "jade" :face all-the-icons-red)
|
||||||
|
("\\.pug$" all-the-icons-fileicon "pug-alt" :face all-the-icons-red)
|
||||||
|
|
||||||
|
;; JavaScript
|
||||||
|
("^gulpfile" all-the-icons-alltheicon "gulp" :height 1.0 :face all-the-icons-lred)
|
||||||
|
("^gruntfile" all-the-icons-alltheicon "grunt" :height 1.0 :v-adjust -0.1 :face all-the-icons-lyellow)
|
||||||
|
("^webpack" all-the-icons-fileicon "webpack" :face all-the-icons-lblue)
|
||||||
|
|
||||||
|
("\\.d3\\.?js" all-the-icons-alltheicon "d3" :height 0.8 :face all-the-icons-lgreen)
|
||||||
|
|
||||||
|
("\\.re$" all-the-icons-fileicon "reason" :height 1.0 :face all-the-icons-red-alt)
|
||||||
|
("\\.rei$" all-the-icons-fileicon "reason" :height 1.0 :face all-the-icons-dred)
|
||||||
|
("\\.ml$" all-the-icons-fileicon "ocaml" :height 1.0 :face all-the-icons-lpink)
|
||||||
|
("\\.mli$" all-the-icons-fileicon "ocaml" :height 1.0 :face all-the-icons-dpink)
|
||||||
|
|
||||||
|
("\\.react" all-the-icons-alltheicon "react" :height 1.1 :face all-the-icons-lblue)
|
||||||
|
("\\.d\\.ts$" all-the-icons-fileicon "typescript" :height 1.0 :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
||||||
|
("\\.ts$" all-the-icons-fileicon "typescript" :height 1.0 :v-adjust -0.1 :face all-the-icons-blue-alt)
|
||||||
|
("\\.js$" all-the-icons-alltheicon "javascript" :height 1.0 :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.es[0-9]$" all-the-icons-alltheicon "javascript" :height 1.0 :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
("\\.jsx$" all-the-icons-fileicon "jsx-2" :height 1.0 :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
||||||
|
("\\.njs$" all-the-icons-alltheicon "nodejs" :height 1.2 :face all-the-icons-lgreen)
|
||||||
|
("\\.vue$" all-the-icons-fileicon "vue" :face all-the-icons-lgreen)
|
||||||
|
|
||||||
|
;; File Types
|
||||||
|
("\\.ico$" all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
("\\.png$" all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-orange)
|
||||||
|
("\\.gif$" all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-green)
|
||||||
|
("\\.jpe?g$" all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-dblue)
|
||||||
|
("\\.svg$" all-the-icons-alltheicon "svg" :height 0.9 :face all-the-icons-lgreen)
|
||||||
|
|
||||||
|
;; Video
|
||||||
|
("\\.mov" all-the-icons-faicon "film" :face all-the-icons-blue)
|
||||||
|
("\\.mp4" all-the-icons-faicon "film" :face all-the-icons-blue)
|
||||||
|
("\\.ogv" all-the-icons-faicon "film" :face all-the-icons-dblue)
|
||||||
|
|
||||||
|
;; Fonts
|
||||||
|
("\\.ttf$" all-the-icons-fileicon "font" :v-adjust 0.0 :face all-the-icons-dcyan)
|
||||||
|
("\\.woff2?$" all-the-icons-fileicon "font" :v-adjust 0.0 :face all-the-icons-cyan)
|
||||||
|
|
||||||
|
;; Doc
|
||||||
|
("\\.pdf" all-the-icons-octicon "file-pdf" :v-adjust 0.0 :face all-the-icons-dred)
|
||||||
|
("\\.te?xt" all-the-icons-octicon "file-text" :v-adjust 0.0 :face all-the-icons-cyan)
|
||||||
|
("\\.doc[xm]?$" all-the-icons-fileicon "word" :face all-the-icons-blue)
|
||||||
|
("\\.texi?$" all-the-icons-fileicon "tex" :face all-the-icons-lred)
|
||||||
|
("\\.md$" all-the-icons-octicon "markdown" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
("\\.bib$" all-the-icons-fileicon "bib" :face all-the-icons-maroon)
|
||||||
|
("\\.org$" all-the-icons-fileicon "org" :face all-the-icons-lgreen)
|
||||||
|
|
||||||
|
("\\.pp[st]$" all-the-icons-fileicon "powerpoint" :face all-the-icons-orange)
|
||||||
|
("\\.pp[st]x$" all-the-icons-fileicon "powerpoint" :face all-the-icons-red)
|
||||||
|
("\\.knt$" all-the-icons-fileicon "powerpoint" :face all-the-icons-cyan)
|
||||||
|
|
||||||
|
("bookmark" all-the-icons-octicon "bookmark" :height 1.1 :v-adjust 0.0 :face all-the-icons-lpink)
|
||||||
|
("\\.cache$" all-the-icons-octicon "database" :height 1.0 :v-adjust 0.0 :face all-the-icons-green)
|
||||||
|
|
||||||
|
("^\\*scratch\\*$" all-the-icons-faicon "sticky-note" :face all-the-icons-lyellow)
|
||||||
|
("^\\*scratch.*" all-the-icons-faicon "sticky-note" :face all-the-icons-yellow)
|
||||||
|
("^\\*new-tab\\*$" all-the-icons-material "star" :face all-the-icons-cyan)
|
||||||
|
|
||||||
|
("^\\." all-the-icons-octicon "gear" :v-adjust 0.0)
|
||||||
|
("." all-the-icons-faicon "file-o" :height 0.8 :v-adjust 0.0 :face all-the-icons-dsilver)))
|
||||||
|
|
||||||
|
(defvar all-the-icons-dir-icon-alist
|
||||||
|
'(
|
||||||
|
("trash" all-the-icons-faicon "trash-o" :height 1.2 :v-adjust -0.1)
|
||||||
|
("dropbox" all-the-icons-faicon "dropbox" :height 1.0 :v-adjust -0.1)
|
||||||
|
("google[ _-]drive" all-the-icons-alltheicon "google-drive" :height 1.3 :v-adjust -0.1)
|
||||||
|
("^atom$" all-the-icons-alltheicon "atom" :height 1.2 :v-adjust -0.1)
|
||||||
|
("documents" all-the-icons-faicon "book" :height 1.0 :v-adjust -0.1)
|
||||||
|
("download" all-the-icons-faicon "cloud-download" :height 0.9 :v-adjust -0.2)
|
||||||
|
("desktop" all-the-icons-octicon "device-desktop" :height 1.0 :v-adjust -0.1)
|
||||||
|
("pictures" all-the-icons-faicon "picture-o" :height 0.9 :v-adjust -0.2)
|
||||||
|
("photos" all-the-icons-faicon "camera-retro" :height 1.0 :v-adjust -0.1)
|
||||||
|
("music" all-the-icons-faicon "music" :height 1.0 :v-adjust -0.1)
|
||||||
|
("movies" all-the-icons-faicon "film" :height 0.9 :v-adjust -0.1)
|
||||||
|
("code" all-the-icons-octicon "code" :height 1.1 :v-adjust -0.1)
|
||||||
|
("workspace" all-the-icons-octicon "code" :height 1.1 :v-adjust -0.1)
|
||||||
|
("test" all-the-icons-fileicon "test-dir" :height 0.9)
|
||||||
|
("\\.git" all-the-icons-alltheicon "git" :height 1.0)
|
||||||
|
("." all-the-icons-octicon "file-directory" :height 1.0 :v-adjust -0.1)
|
||||||
|
))
|
||||||
|
|
||||||
|
(defvar all-the-icons-weather-icon-alist
|
||||||
|
'(
|
||||||
|
("tornado" all-the-icons-wicon "tornado")
|
||||||
|
("hurricane" all-the-icons-wicon "hurricane")
|
||||||
|
("thunderstorms" all-the-icons-wicon "thunderstorm")
|
||||||
|
("sunny" all-the-icons-wicon "day-sunny")
|
||||||
|
("rain.*snow" all-the-icons-wicon "rain-mix")
|
||||||
|
("rain.*hail" all-the-icons-wicon "rain-mix")
|
||||||
|
("sleet" all-the-icons-wicon "sleet")
|
||||||
|
("hail" all-the-icons-wicon "hail")
|
||||||
|
("drizzle" all-the-icons-wicon "sprinkle")
|
||||||
|
("rain" all-the-icons-wicon "showers" :height 1.1 :v-adjust 0.0)
|
||||||
|
("showers" all-the-icons-wicon "showers")
|
||||||
|
("blowing.*snow" all-the-icons-wicon "snow-wind")
|
||||||
|
("snow" all-the-icons-wicon "snow")
|
||||||
|
("dust" all-the-icons-wicon "dust")
|
||||||
|
("fog" all-the-icons-wicon "fog")
|
||||||
|
("haze" all-the-icons-wicon "day-haze")
|
||||||
|
("smoky" all-the-icons-wicon "smoke")
|
||||||
|
("blustery" all-the-icons-wicon "cloudy-windy")
|
||||||
|
("windy" all-the-icons-wicon "cloudy-gusts")
|
||||||
|
("cold" all-the-icons-wicon "snowflake-cold")
|
||||||
|
("partly.*cloudy.*night" all-the-icons-wicon "night-alt-partly-cloudy")
|
||||||
|
("partly.*cloudy" all-the-icons-wicon "day-cloudy-high")
|
||||||
|
("cloudy.*night" all-the-icons-wicon "night-alt-cloudy")
|
||||||
|
("cxloudy.*day" all-the-icons-wicon "day-cloudy")
|
||||||
|
("cloudy" all-the-icons-wicon "cloudy")
|
||||||
|
("clear.*night" all-the-icons-wicon "night-clear")
|
||||||
|
("fair.*night" all-the-icons-wicon "stars")
|
||||||
|
("fair.*day" all-the-icons-wicon "horizon")
|
||||||
|
("hot" all-the-icons-wicon "hot")
|
||||||
|
("not.*available" all-the-icons-wicon "na")
|
||||||
|
))
|
||||||
|
|
||||||
|
(defvar all-the-icons-mode-icon-alist
|
||||||
|
'(
|
||||||
|
(emacs-lisp-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-purple)
|
||||||
|
(inferior-emacs-lisp-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-lblue)
|
||||||
|
(dired-mode all-the-icons-octicon "file-directory" :v-adjust 0.0)
|
||||||
|
(lisp-interaction-mode all-the-icons-fileicon "lisp" :v-adjust -0.1 :face all-the-icons-orange)
|
||||||
|
(org-mode all-the-icons-fileicon "org" :v-adjust 0.0 :face all-the-icons-lgreen)
|
||||||
|
(typescript-mode all-the-icons-fileicon "typescript" :v-adjust -0.1 :face all-the-icons-blue-alt)
|
||||||
|
(js-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
(js-jsx-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
(js2-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
(js3-mode all-the-icons-alltheicon "javascript" :v-adjust -0.1 :face all-the-icons-yellow)
|
||||||
|
(rjsx-mode all-the-icons-fileicon "jsx-2" :v-adjust -0.1 :face all-the-icons-cyan-alt)
|
||||||
|
(term-mode all-the-icons-octicon "terminal" :v-adjust 0.2)
|
||||||
|
(eshell-mode all-the-icons-octicon "terminal" :v-adjust 0.0 :face all-the-icons-purple)
|
||||||
|
(magit-refs-mode all-the-icons-octicon "git-branch" :v-adjust 0.0 :face all-the-icons-red)
|
||||||
|
(magit-process-mode all-the-icons-octicon "mark-github" :v-adjust 0.0)
|
||||||
|
(magit-diff-mode all-the-icons-octicon "git-compare" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
(ediff-mode all-the-icons-octicon "git-compare" :v-adjust 0.0 :Face all-the-icons-red)
|
||||||
|
(comint-mode all-the-icons-faicon "terminal" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
(eww-mode all-the-icons-faicon "firefox" :v-adjust -0.1 :face all-the-icons-red)
|
||||||
|
(org-agenda-mode all-the-icons-octicon "checklist" :v-adjust 0.0 :face all-the-icons-lgreen)
|
||||||
|
(cfw:calendar-mode all-the-icons-octicon "calendar" :v-adjust 0.0)
|
||||||
|
(ibuffer-mode all-the-icons-faicon "files-o" :v-adjust 0.0 :face all-the-icons-dsilver)
|
||||||
|
(messages-buffer-mode all-the-icons-faicon "stack-overflow" :v-adjust -0.1)
|
||||||
|
(help-mode all-the-icons-faicon "info" :v-adjust -0.1 :face all-the-icons-purple)
|
||||||
|
(benchmark-init/tree-mode all-the-icons-octicon "dashboard" :v-adjust 0.0)
|
||||||
|
(jenkins-mode all-the-icons-fileicon "jenkins" :face all-the-icons-blue)
|
||||||
|
(magit-popup-mode all-the-icons-alltheicon "git" :face all-the-icons-red)
|
||||||
|
(magit-status-mode all-the-icons-alltheicon "git" :face all-the-icons-lred)
|
||||||
|
(magit-log-mode all-the-icons-alltheicon "git" :face all-the-icons-green)
|
||||||
|
(Custom-mode all-the-icons-octicon "settings")
|
||||||
|
|
||||||
|
;; Special matcher for Web Mode based on the `web-mode-content-type' of the current buffer
|
||||||
|
(web-mode all-the-icons--web-mode-icon)
|
||||||
|
|
||||||
|
(fundamental-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-dsilver)
|
||||||
|
(special-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-yellow)
|
||||||
|
(text-mode all-the-icons-octicon "file-text" :v-adjust 0.0 :face all-the-icons-cyan)
|
||||||
|
(ruby-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-lred)
|
||||||
|
(inf-ruby-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
|
(projectile-rails-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
|
(rspec-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
|
(rake-compilation-mode all-the-icons-alltheicon "ruby-alt" :face all-the-icons-red)
|
||||||
|
(shell-mode all-the-icons-alltheicon "terminal" :face all-the-icons-purple)
|
||||||
|
(fish-mode all-the-icons-alltheicon "terminal" :face all-the-icons-lpink)
|
||||||
|
(nginx-mode all-the-icons-fileicon "nginx" :height 0.9 :face all-the-icons-dgreen)
|
||||||
|
(apache-mode all-the-icons-alltheicon "apache" :height 0.9 :face all-the-icons-dgreen)
|
||||||
|
(makefile-mode all-the-icons-fileicon "gnu" :face all-the-icons-dorange)
|
||||||
|
(dockerfile-mode all-the-icons-fileicon "dockerfile" :face all-the-icons-blue)
|
||||||
|
(docker-compose-mode all-the-icons-fileicon "dockerfile" :face all-the-icons-lblue)
|
||||||
|
(xml-mode all-the-icons-faicon "file-code-o" :height 0.95 :face all-the-icons-lorange)
|
||||||
|
(json-mode all-the-icons-octicon "settings" :face all-the-icons-yellow)
|
||||||
|
(yaml-mode all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-dyellow)
|
||||||
|
(elisp-byte-code-mode all-the-icons-octicon "file-binary" :v-adjust 0.0 :face all-the-icons-dsilver)
|
||||||
|
(archive-mode all-the-icons-octicon "file-zip" :v-adjust 0.0 :face all-the-icons-lmaroon)
|
||||||
|
(elm-mode all-the-icons-fileicon "elm" :face all-the-icons-blue)
|
||||||
|
(erlang-mode all-the-icons-alltheicon "erlang" :face all-the-icons-red :v-adjust -0.1 :height 0.9)
|
||||||
|
(elixir-mode all-the-icons-alltheicon "elixir" :face all-the-icons-lorange :v-adjust -0.1 :height 0.9)
|
||||||
|
(java-mode all-the-icons-alltheicon "java" :height 1.0 :face all-the-icons-purple)
|
||||||
|
(go-mode all-the-icons-alltheicon "go" :height 1.0 :face all-the-icons-blue)
|
||||||
|
(matlab-mode all-the-icons-fileicon "matlab" :face all-the-icons-orange)
|
||||||
|
(perl-mode all-the-icons-alltheicon "perl" :face all-the-icons-lorange)
|
||||||
|
(cperl-mode all-the-icons-alltheicon "perl" :face all-the-icons-lorange)
|
||||||
|
(php-mode all-the-icons-fileicon "php" :face all-the-icons-lsilver)
|
||||||
|
(prolog-mode all-the-icons-alltheicon "prolog" :height 1.1 :face all-the-icons-lmaroon)
|
||||||
|
(python-mode all-the-icons-alltheicon "python" :height 1.0 :face all-the-icons-dblue)
|
||||||
|
(racket-mode all-the-icons-fileicon "racket" :height 1.2 :face all-the-icons-red)
|
||||||
|
(rust-mode all-the-icons-alltheicon "rust" :height 1.2 :face all-the-icons-maroon)
|
||||||
|
(scala-mode all-the-icons-alltheicon "scala" :face all-the-icons-red)
|
||||||
|
(scheme-mode all-the-icons-fileicon "scheme" :height 1.2 :face all-the-icons-red)
|
||||||
|
(swift-mode all-the-icons-alltheicon "swift" :height 1.0 :v-adjust -0.1 :face all-the-icons-green)
|
||||||
|
(c-mode all-the-icons-alltheicon "c-line" :face all-the-icons-blue)
|
||||||
|
(c++-mode all-the-icons-alltheicon "cplusplus-line" :v-adjust -0.2 :face all-the-icons-blue)
|
||||||
|
(csharp-mode all-the-icons-alltheicon "csharp-line" :face all-the-icons-dblue)
|
||||||
|
(clojure-mode all-the-icons-alltheicon "clojure-line" :height 1.0 :face all-the-icons-blue)
|
||||||
|
(cider-repl-mode all-the-icons-alltheicon "clojure-line" :height 1.0 :face all-the-icons-dblue)
|
||||||
|
(clojurescript-mode all-the-icons-fileicon "cljs" :height 1.0 :face all-the-icons-dblue)
|
||||||
|
(coffee-mode all-the-icons-alltheicon "coffeescript" :height 1.0 :face all-the-icons-maroon)
|
||||||
|
(lisp-mode all-the-icons-fileicon "lisp" :face all-the-icons-orange)
|
||||||
|
(css-mode all-the-icons-alltheicon "css3" :face all-the-icons-yellow)
|
||||||
|
(scss-mode all-the-icons-alltheicon "sass" :face all-the-icons-pink)
|
||||||
|
(sass-mode all-the-icons-alltheicon "sass" :face all-the-icons-dpink)
|
||||||
|
(less-css-mode all-the-icons-alltheicon "less" :height 0.8 :face all-the-icons-dyellow)
|
||||||
|
(stylus-mode all-the-icons-alltheicon "stylus" :face all-the-icons-lgreen)
|
||||||
|
(csv-mode all-the-icons-octicon "graph" :v-adjust 0.0 :face all-the-icons-dblue)
|
||||||
|
(haskell-mode all-the-icons-alltheicon "haskell" :height 1.0 :face all-the-icons-red)
|
||||||
|
(haml-mode all-the-icons-fileicon "haml" :face all-the-icons-lyellow)
|
||||||
|
(html-mode all-the-icons-alltheicon "html5" :face all-the-icons-orange)
|
||||||
|
(rhtml-mode all-the-icons-alltheicon "html5" :face all-the-icons-lred)
|
||||||
|
(mustache-mode all-the-icons-fileicon "moustache" :face all-the-icons-green)
|
||||||
|
(slim-mode all-the-icons-octicon "dashboard" :v-adjust 0.0 :face all-the-icons-yellow)
|
||||||
|
(jade-mode all-the-icons-fileicon "jade" :face all-the-icons-red)
|
||||||
|
(pug-mode all-the-icons-fileicon "pug" :face all-the-icons-red)
|
||||||
|
(react-mode all-the-icons-alltheicon "react" :height 1.1 :face all-the-icons-lblue)
|
||||||
|
(image-mode all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-blue)
|
||||||
|
(texinfo-mode all-the-icons-fileicon "tex" :face all-the-icons-lred)
|
||||||
|
(markdown-mode all-the-icons-octicon "markdown" :v-adjust 0.0 :face all-the-icons-lblue)
|
||||||
|
(bibtex-mode all-the-icons-fileicon "bib" :face all-the-icons-maroon)
|
||||||
|
(org-mode all-the-icons-fileicon "org" :face all-the-icons-lgreen)
|
||||||
|
(compilation-mode all-the-icons-faicon "cogs" :v-adjust 0.0 :height 1.0)
|
||||||
|
(objc-mode all-the-icons-faicon "apple" :v-adjust 0.0 :height 1.0)
|
||||||
|
))
|
||||||
|
|
||||||
|
;; ====================
|
||||||
|
;; Functions Start
|
||||||
|
;; ====================
|
||||||
|
|
||||||
|
(defun all-the-icons-auto-mode-match? (&optional file)
|
||||||
|
"Whether or not FILE's `major-mode' match against its `auto-mode-alist'."
|
||||||
|
(let* ((file (or file (buffer-file-name) (buffer-name)))
|
||||||
|
(auto-mode (all-the-icons-match-to-alist file auto-mode-alist)))
|
||||||
|
(eq major-mode auto-mode)))
|
||||||
|
|
||||||
|
(defun all-the-icons-match-to-alist (file alist)
|
||||||
|
"Match FILE against an entry in ALIST using `string-match'."
|
||||||
|
(cdr (cl-find-if (lambda (it) (string-match (car it) file)) alist)))
|
||||||
|
|
||||||
|
(defun all-the-icons-dir-is-submodule (dir)
|
||||||
|
"Checker whether or not DIR is a git submodule."
|
||||||
|
(let* ((gitmodule-dir (locate-dominating-file dir ".gitmodules"))
|
||||||
|
(modules-file (expand-file-name (format "%s.gitmodules" gitmodule-dir)))
|
||||||
|
(module-search (format "submodule \".*?%s\"" (file-name-base dir))))
|
||||||
|
|
||||||
|
(when (and gitmodule-dir (file-exists-p (format "%s/.git" dir)))
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents modules-file)
|
||||||
|
(search-forward-regexp module-search (point-max) t)))))
|
||||||
|
|
||||||
|
;; Icon functions
|
||||||
|
(defun all-the-icons-icon-for-dir (dir &optional chevron padding)
|
||||||
|
"Format an icon for DIR with CHEVRON similar to tree based directories.
|
||||||
|
|
||||||
|
If PADDING is provided, it will prepend and separate the chevron
|
||||||
|
and directory with PADDING.
|
||||||
|
|
||||||
|
Produces different symbols by inspecting DIR to distinguish
|
||||||
|
symlinks and git repositories which do not depend on the
|
||||||
|
directory contents"
|
||||||
|
(let* ((matcher (all-the-icons-match-to-alist (file-name-base dir) all-the-icons-dir-icon-alist))
|
||||||
|
(path (expand-file-name dir))
|
||||||
|
(chevron (if chevron (all-the-icons-octicon (format "chevron-%s" chevron) :height 0.8 :v-adjust -0.1) ""))
|
||||||
|
(padding (or padding "\t"))
|
||||||
|
(icon (cond
|
||||||
|
((file-symlink-p path)
|
||||||
|
(all-the-icons-octicon "file-symlink-directory" :height 1.0))
|
||||||
|
((all-the-icons-dir-is-submodule path)
|
||||||
|
(all-the-icons-octicon "file-submodule" :height 1.0))
|
||||||
|
((file-exists-p (format "%s/.git" path))
|
||||||
|
(format "%s" (all-the-icons-octicon "repo" :height 1.1)))
|
||||||
|
(t (apply (car matcher) (cdr matcher))))))
|
||||||
|
(format "%s%s%s%s%s" padding chevron padding icon padding)))
|
||||||
|
|
||||||
|
(defun all-the-icons-icon-for-buffer ()
|
||||||
|
"Get the formatted icon for the current buffer.
|
||||||
|
|
||||||
|
This function prioritises the use of the buffers file extension to
|
||||||
|
discern the icon when its `major-mode' matches its auto mode,
|
||||||
|
otherwise it will use the buffers `major-mode' to decide its
|
||||||
|
icon."
|
||||||
|
(all-the-icons--icon-info-for-buffer))
|
||||||
|
|
||||||
|
(defun all-the-icons-icon-family-for-buffer ()
|
||||||
|
"Get the icon font family for the current buffer."
|
||||||
|
(all-the-icons--icon-info-for-buffer "family"))
|
||||||
|
|
||||||
|
(defun all-the-icons--web-mode-icon (&rest arg-overrides) "Get icon for a `web-mode' buffer with ARG-OVERRIDES." (all-the-icons--web-mode nil arg-overrides))
|
||||||
|
(defun all-the-icons--web-mode-icon-family () "Get icon family for a `web-mode' buffer." (all-the-icons--web-mode t))
|
||||||
|
(defun all-the-icons--web-mode (&optional family arg-overrides)
|
||||||
|
"Return icon or FAMILY for `web-mode' based on `web-mode-content-type'.
|
||||||
|
Providing ARG-OVERRIDES will modify the creation of the icon."
|
||||||
|
(let ((non-nil-args (cl-reduce (lambda (acc it) (if it (append acc (list it)) acc)) arg-overrides :initial-value '())))
|
||||||
|
(cond
|
||||||
|
((equal web-mode-content-type "jsx")
|
||||||
|
(if family (all-the-icons-fileicon-family) (apply 'all-the-icons-fileicon (append '("jsx-2") non-nil-args))))
|
||||||
|
((equal web-mode-content-type "javascript")
|
||||||
|
(if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("javascript") non-nil-args))))
|
||||||
|
((equal web-mode-content-type "json")
|
||||||
|
(if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("less") non-nil-args))))
|
||||||
|
((equal web-mode-content-type "xml")
|
||||||
|
(if family (all-the-icons-faicon-family) (apply 'all-the-icons-faicon (append '("file-code-o") non-nil-args))))
|
||||||
|
((equal web-mode-content-type "css")
|
||||||
|
(if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("css3") non-nil-args))))
|
||||||
|
(t
|
||||||
|
(if family (all-the-icons-alltheicon-family) (apply 'all-the-icons-alltheicon (append '("html5") non-nil-args)))))))
|
||||||
|
|
||||||
|
;; Icon Functions
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons-icon-for-file (file &rest arg-overrides)
|
||||||
|
"Get the formatted icon for FILE.
|
||||||
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
|
inserting functions."
|
||||||
|
(let* ((icon (all-the-icons-match-to-alist file all-the-icons-icon-alist))
|
||||||
|
(args (cdr icon)))
|
||||||
|
(when arg-overrides (setq args (append `(,(car args)) arg-overrides (cdr args))))
|
||||||
|
(apply (car icon) args)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons-icon-for-mode (mode &rest arg-overrides)
|
||||||
|
"Get the formatted icon for MODE.
|
||||||
|
ARG-OVERRIDES should be a plist containining `:height',
|
||||||
|
`:v-adjust' or `:face' properties like in the normal icon
|
||||||
|
inserting functions."
|
||||||
|
(let* ((icon (cdr (assoc mode all-the-icons-mode-icon-alist)))
|
||||||
|
(args (cdr icon)))
|
||||||
|
(when arg-overrides (setq args (append `(,(car args)) arg-overrides (cdr args))))
|
||||||
|
(if icon (apply (car icon) args) mode)))
|
||||||
|
|
||||||
|
(memoize 'all-the-icons-icon-for-file)
|
||||||
|
(memoize 'all-the-icons-icon-for-mode)
|
||||||
|
|
||||||
|
;; Family Face Functions
|
||||||
|
(defun all-the-icons-icon-family-for-file (file)
|
||||||
|
"Get the icons font family for FILE."
|
||||||
|
(let ((icon (all-the-icons-match-to-alist file all-the-icons-icon-alist)))
|
||||||
|
(funcall (intern (format "%s-family" (car icon))))))
|
||||||
|
|
||||||
|
(defun all-the-icons-icon-family-for-mode (mode)
|
||||||
|
"Get the icons font family for MODE."
|
||||||
|
(let ((icon (cdr (assoc mode all-the-icons-mode-icon-alist))))
|
||||||
|
(if icon (funcall (intern (format "%s-family" (car icon)))) nil)))
|
||||||
|
|
||||||
|
(defun all-the-icons-icon-family (icon)
|
||||||
|
"Get a propertized ICON family programatically."
|
||||||
|
(plist-get (get-text-property 0 'face icon) :family))
|
||||||
|
|
||||||
|
(memoize 'all-the-icons-icon-family-for-file)
|
||||||
|
(memoize 'all-the-icons-icon-family-for-mode)
|
||||||
|
(memoize 'all-the-icons-icon-family)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons--icon-info-for-buffer (&optional f)
|
||||||
|
"Get icon info for the current buffer.
|
||||||
|
|
||||||
|
When F is provided, the info function is calculated with the format
|
||||||
|
`all-the-icons-icon-%s-for-file' or `all-the-icons-icon-%s-for-mode'."
|
||||||
|
(let* ((base-f (concat "all-the-icons-icon" (when f (format "-%s" f))))
|
||||||
|
(file-f (intern (concat base-f "-for-file")))
|
||||||
|
(mode-f (intern (concat base-f "-for-mode"))))
|
||||||
|
(if (and (buffer-file-name)
|
||||||
|
(all-the-icons-auto-mode-match?))
|
||||||
|
(funcall file-f (file-name-nondirectory (buffer-file-name)))
|
||||||
|
(funcall mode-f major-mode))))
|
||||||
|
|
||||||
|
;; Weather icons
|
||||||
|
(defun all-the-icons-icon-for-weather (weather)
|
||||||
|
"Get an icon for a WEATHER status."
|
||||||
|
(let ((icon (all-the-icons-match-to-alist weather all-the-icons-weather-icon-alist)))
|
||||||
|
(if icon (apply (car icon) (cdr icon)) weather)))
|
||||||
|
|
||||||
|
;; Definitions
|
||||||
|
|
||||||
|
(eval-and-compile
|
||||||
|
(defun all-the-icons--function-name (name)
|
||||||
|
"Get the symbol for an icon function name for icon set NAME."
|
||||||
|
(intern (concat "all-the-icons-" (downcase (symbol-name name)))))
|
||||||
|
|
||||||
|
(defun all-the-icons--family-name (name)
|
||||||
|
"Get the symbol for an icon family function for icon set NAME."
|
||||||
|
(intern (concat "all-the-icons-" (downcase (symbol-name name)) "-family")))
|
||||||
|
|
||||||
|
(defun all-the-icons--data-name (name)
|
||||||
|
"Get the symbol for an icon family function for icon set NAME."
|
||||||
|
(intern (concat "all-the-icons-" (downcase (symbol-name name)) "-data")))
|
||||||
|
|
||||||
|
(defun all-the-icons--insert-function-name (name)
|
||||||
|
"Get the symbol for an icon insert function for icon set NAME."
|
||||||
|
(intern (concat "all-the-icons-insert-" (downcase (symbol-name name))))))
|
||||||
|
|
||||||
|
;; Icon insertion functions
|
||||||
|
|
||||||
|
(defun all-the-icons--read-candidates ()
|
||||||
|
"Helper to build a list of candidates for all families."
|
||||||
|
(cl-reduce 'append (mapcar (lambda (it) (all-the-icons--read-candidates-for-family it t)) all-the-icons-font-families)))
|
||||||
|
|
||||||
|
(defun all-the-icons--read-candidates-for-family (family &optional show-family)
|
||||||
|
"Helper to build read candidates for FAMILY.
|
||||||
|
If SHOW-FAMILY is non-nil, displays the icons family in the candidate string."
|
||||||
|
(let ((data (funcall (all-the-icons--data-name family)))
|
||||||
|
(icon-f (all-the-icons--function-name family)))
|
||||||
|
(mapcar
|
||||||
|
(lambda (it)
|
||||||
|
(let* ((icon-name (car it))
|
||||||
|
(icon-name-head (substring icon-name 0 1))
|
||||||
|
(icon-name-tail (substring icon-name 1))
|
||||||
|
|
||||||
|
(icon-display (propertize icon-name-head 'display (format "%s\t%s" (funcall icon-f icon-name) icon-name-head)))
|
||||||
|
(icon-family (if show-family (format "\t[%s]" family) ""))
|
||||||
|
|
||||||
|
(candidate-name (format "%s%s%s" icon-display icon-name-tail icon-family))
|
||||||
|
(candidate-icon (funcall (all-the-icons--function-name family) icon-name)))
|
||||||
|
|
||||||
|
(cons candidate-name candidate-icon)))
|
||||||
|
data)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons-install-fonts (&optional pfx)
|
||||||
|
"Helper function to download and install the latests fonts based on OS.
|
||||||
|
When PFX is non-nil, ignore the prompt and just install"
|
||||||
|
(interactive "P")
|
||||||
|
(when (or pfx (yes-or-no-p "This will download and install fonts, are you sure you want to do this?"))
|
||||||
|
(let* ((url-format "https://github.com/domtronn/all-the-icons.el/blob/master/fonts/%s?raw=true")
|
||||||
|
(font-dest (cl-case window-system
|
||||||
|
(x (concat (or (getenv "XDG_DATA_HOME") ;; Default Linux install directories
|
||||||
|
(concat (getenv "HOME") "/.local/share"))
|
||||||
|
"/fonts/"))
|
||||||
|
(mac (concat (getenv "HOME") "/Library/Fonts/" ))
|
||||||
|
(ns (concat (getenv "HOME") "/Library/Fonts/" )))) ;; Default MacOS install directory
|
||||||
|
(known-dest? (stringp font-dest))
|
||||||
|
(font-dest (or font-dest (read-directory-name "Font installation directory: " "~/"))))
|
||||||
|
|
||||||
|
(unless (file-directory-p font-dest) (mkdir font-dest t))
|
||||||
|
|
||||||
|
(mapc (lambda (font)
|
||||||
|
(url-copy-file (format url-format font) (expand-file-name font font-dest) t))
|
||||||
|
all-the-icons-font-names)
|
||||||
|
(when known-dest?
|
||||||
|
(message "Fonts downloaded, updating font cache... <fc-cache -f -v> ")
|
||||||
|
(shell-command-to-string (format "fc-cache -f -v")))
|
||||||
|
(message "%s Successfully %s `all-the-icons' fonts to `%s'!"
|
||||||
|
(all-the-icons-wicon "stars" :v-adjust 0.0)
|
||||||
|
(if known-dest? "installed" "downloaded")
|
||||||
|
font-dest))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons-insert (&optional arg family)
|
||||||
|
"Interactive icon insertion function.
|
||||||
|
When Prefix ARG is non-nil, insert the propertized icon.
|
||||||
|
When FAMILY is non-nil, limit the candidates to the icon set matching it."
|
||||||
|
(interactive "P")
|
||||||
|
(let* ((standard-output (current-buffer))
|
||||||
|
(candidates (if family
|
||||||
|
(all-the-icons--read-candidates-for-family family)
|
||||||
|
(all-the-icons--read-candidates)))
|
||||||
|
(prompt (if family
|
||||||
|
(format "%s Icon: " (funcall (all-the-icons--family-name family)))
|
||||||
|
"Icon : "))
|
||||||
|
|
||||||
|
(selection (completing-read prompt candidates nil t))
|
||||||
|
(result (cdr (assoc selection candidates))))
|
||||||
|
|
||||||
|
(if arg (prin1 result) (insert result))))
|
||||||
|
|
||||||
|
;; Debug Helpers
|
||||||
|
|
||||||
|
(defun all-the-icons-insert-icons-for (family &optional height duration)
|
||||||
|
"Insert all of the available icons associated with FAMILY.
|
||||||
|
If a HEIGHT is provided it will render the icons at this height.
|
||||||
|
This is useful both to see the icons more clearly and to test
|
||||||
|
different height rendering. If DURATION is provided, it will
|
||||||
|
pause for DURATION seconds between printing each character."
|
||||||
|
(let* ((data-f (all-the-icons--data-name family))
|
||||||
|
(insert-f (all-the-icons--function-name family))
|
||||||
|
|
||||||
|
(height (or height 2.0))
|
||||||
|
(data (funcall data-f)))
|
||||||
|
(mapc
|
||||||
|
(lambda (it)
|
||||||
|
(insert (format "%s - %s\n" (funcall insert-f (car it) :height height) (car it)))
|
||||||
|
(when duration (sit-for duration 0)))
|
||||||
|
data)))
|
||||||
|
|
||||||
|
(defmacro define-icon (name alist family &optional font-name)
|
||||||
|
"Macro to generate functions for inserting icons for icon set NAME.
|
||||||
|
|
||||||
|
NAME defines is the name of the iconset and will produce a
|
||||||
|
function of the for `all-the-icons-NAME'.
|
||||||
|
|
||||||
|
ALIST is the alist containing maps between icon names and the
|
||||||
|
UniCode for the character. All of these can be found in the data
|
||||||
|
directory of this package.
|
||||||
|
|
||||||
|
FAMILY is the font family to use for the icons.
|
||||||
|
FONT-NAME is the name of the .ttf file providing the font, defaults to FAMILY."
|
||||||
|
`(progn
|
||||||
|
(add-to-list 'all-the-icons-font-families (quote ,name))
|
||||||
|
(add-to-list 'all-the-icons-font-names (quote ,(downcase (format "%s.ttf" (or font-name family)))))
|
||||||
|
|
||||||
|
(defun ,(all-the-icons--family-name name) () ,family)
|
||||||
|
(defun ,(all-the-icons--data-name name) () ,alist)
|
||||||
|
(defun ,(all-the-icons--function-name name) (icon-name &rest args)
|
||||||
|
(let ((icon (cdr (assoc icon-name ,alist)))
|
||||||
|
(other-face (when all-the-icons-color-icons (plist-get args :face)))
|
||||||
|
(height (* all-the-icons-scale-factor (or (plist-get args :height) 1.0)))
|
||||||
|
(v-adjust (* all-the-icons-scale-factor (or (plist-get args :v-adjust) all-the-icons-default-adjust)))
|
||||||
|
(family ,family))
|
||||||
|
(unless icon
|
||||||
|
(error (format "Unable to find icon with name `%s' in icon set `%s'" icon-name (quote ,name))))
|
||||||
|
(propertize icon
|
||||||
|
'face (if other-face
|
||||||
|
`(:family ,family :height ,height :inherit ,other-face)
|
||||||
|
`(:family ,family :height ,height))
|
||||||
|
'display `(raise ,v-adjust)
|
||||||
|
'rear-nonsticky t
|
||||||
|
'font-lock-ignore t)))
|
||||||
|
(defun ,(all-the-icons--insert-function-name name) (&optional arg)
|
||||||
|
,(format "Insert a %s icon at point." family)
|
||||||
|
(interactive "P")
|
||||||
|
(all-the-icons-insert arg (quote ,name)))))
|
||||||
|
|
||||||
|
(define-icon alltheicon all-the-icons-data/alltheicons-alist "all-the-icons")
|
||||||
|
(define-icon fileicon all-the-icons-data/file-icon-alist "file-icons")
|
||||||
|
(define-icon faicon all-the-icons-data/fa-icon-alist "FontAwesome")
|
||||||
|
(define-icon octicon all-the-icons-data/octicons-alist "github-octicons" "octicons")
|
||||||
|
(define-icon wicon all-the-icons-data/weather-icons-alist "Weather Icons" "weathericons")
|
||||||
|
(define-icon material all-the-icons-data/material-icons-alist "Material Icons" "material-design-icons")
|
||||||
|
|
||||||
|
(provide 'all-the-icons)
|
||||||
|
|
||||||
|
;;; all-the-icons.el ends here
|
Binary file not shown.
|
@ -0,0 +1,70 @@
|
||||||
|
(defvar all-the-icons-data/alltheicons-alist
|
||||||
|
'(
|
||||||
|
|
||||||
|
( "apache" . "\xe909" )
|
||||||
|
( "atom" . "\xe917" )
|
||||||
|
( "aws" . "\xe90c" )
|
||||||
|
( "bower" . "\xe918" )
|
||||||
|
( "c" . "\xe915" )
|
||||||
|
( "c-line" . "\xe90f" )
|
||||||
|
( "clojure" . "\xe919" )
|
||||||
|
( "clojure-line" . "\xe91a" )
|
||||||
|
( "coffeescript" . "\xe914" )
|
||||||
|
( "cplusplus" . "\xe913" )
|
||||||
|
( "cplusplus-line" . "\xe910" )
|
||||||
|
( "csharp" . "\xe911" )
|
||||||
|
( "csharp-line" . "\xe912" )
|
||||||
|
( "css3" . "\xe91b" )
|
||||||
|
( "css3-alt" . "\xe91c" )
|
||||||
|
( "d3" . "\xe90e" )
|
||||||
|
( "dlang" . "\xe935" )
|
||||||
|
( "elixir" . "\xe936" )
|
||||||
|
( "erlang" . "\xe934" )
|
||||||
|
( "git" . "\xe907" )
|
||||||
|
( "go" . "\xe91d" )
|
||||||
|
( "google-drive" . "\xe91e" )
|
||||||
|
( "grunt" . "\xe90d" )
|
||||||
|
( "grunt-line" . "\xe91f" )
|
||||||
|
( "gulp" . "\xe920" )
|
||||||
|
( "haskell" . "\xe921" )
|
||||||
|
( "html5" . "\xe932" )
|
||||||
|
( "jasmine" . "\xe904" )
|
||||||
|
( "java" . "\xe922" )
|
||||||
|
( "javascript" . "\xe906" )
|
||||||
|
( "javascript-badge" . "\xe923" )
|
||||||
|
( "javascript-shield" . "\xe924" )
|
||||||
|
( "less" . "\xe90b" )
|
||||||
|
( "nginx" . "\xe933" )
|
||||||
|
( "nodejs" . "\xe925" )
|
||||||
|
( "perl" . "\xe905" )
|
||||||
|
( "perldocs" . "\xe926" )
|
||||||
|
( "postgresql" . "\xe938" )
|
||||||
|
( "prolog" . "\xe927" )
|
||||||
|
( "python" . "\xe928" )
|
||||||
|
( "react" . "\xe929" )
|
||||||
|
( "ruby" . "\xe92a" )
|
||||||
|
( "ruby-alt" . "\xe92b" )
|
||||||
|
( "rust" . "\xe92c" )
|
||||||
|
( "sass" . "\xe92d" )
|
||||||
|
( "scala" . "\xe908" )
|
||||||
|
( "script" . "\xe90a" )
|
||||||
|
( "spring" . "\xe937" )
|
||||||
|
( "stylus" . "\xe92e" )
|
||||||
|
( "svg" . "\xe903" )
|
||||||
|
( "swift" . "\xe92f" )
|
||||||
|
( "terminal" . "\xe930" )
|
||||||
|
( "terminal-alt" . "\xe931" )
|
||||||
|
( "battery-charging" . "\xe939" )
|
||||||
|
|
||||||
|
( "arrow-left" . "\xe93a" )
|
||||||
|
( "arrow-right" . "\xe93b" )
|
||||||
|
( "cup-left" . "\xe93c" )
|
||||||
|
( "cup-right" . "\xe93d" )
|
||||||
|
( "slant-left" . "\xe93e" )
|
||||||
|
( "slant-right" . "\xe93f" )
|
||||||
|
( "wave-left" . "\xe940" )
|
||||||
|
( "wave-right" . "\xe941" )
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(provide 'data-alltheicons)
|
Binary file not shown.
|
@ -0,0 +1,641 @@
|
||||||
|
(defvar all-the-icons-data/fa-icon-alist
|
||||||
|
'(
|
||||||
|
|
||||||
|
("500px" . "\xf26e")
|
||||||
|
("adjust" . "\xf042")
|
||||||
|
("adn" . "\xf170")
|
||||||
|
("align-center" . "\xf037")
|
||||||
|
("align-justify" . "\xf039")
|
||||||
|
("align-left" . "\xf036")
|
||||||
|
("align-right" . "\xf038")
|
||||||
|
("amazon" . "\xf270")
|
||||||
|
("ambulance" . "\xf0f9")
|
||||||
|
("american-sign-language-interpreting" . "\xf2a3")
|
||||||
|
("anchor" . "\xf13d")
|
||||||
|
("android" . "\xf17b")
|
||||||
|
("angellist" . "\xf209")
|
||||||
|
("angle-double-down" . "\xf103")
|
||||||
|
("angle-double-left" . "\xf100")
|
||||||
|
("angle-double-right" . "\xf101")
|
||||||
|
("angle-double-up" . "\xf102")
|
||||||
|
("angle-down" . "\xf107")
|
||||||
|
("angle-left" . "\xf104")
|
||||||
|
("angle-right" . "\xf105")
|
||||||
|
("angle-up" . "\xf106")
|
||||||
|
("apple" . "\xf179")
|
||||||
|
("archive" . "\xf187")
|
||||||
|
("area-chart" . "\xf1fe")
|
||||||
|
("arrow-circle-down" . "\xf0ab")
|
||||||
|
("arrow-circle-left" . "\xf0a8")
|
||||||
|
("arrow-circle-o-down" . "\xf01a")
|
||||||
|
("arrow-circle-o-left" . "\xf190")
|
||||||
|
("arrow-circle-o-right" . "\xf18e")
|
||||||
|
("arrow-circle-o-up" . "\xf01b")
|
||||||
|
("arrow-circle-right" . "\xf0a9")
|
||||||
|
("arrow-circle-up" . "\xf0aa")
|
||||||
|
("arrow-down" . "\xf063")
|
||||||
|
("arrow-left" . "\xf060")
|
||||||
|
("arrow-right" . "\xf061")
|
||||||
|
("arrow-up" . "\xf062")
|
||||||
|
("arrows" . "\xf047")
|
||||||
|
("arrows-alt" . "\xf0b2")
|
||||||
|
("arrows-h" . "\xf07e")
|
||||||
|
("arrows-v" . "\xf07d")
|
||||||
|
("assistive-listening-systems" . "\xf2a2")
|
||||||
|
("asterisk" . "\xf069")
|
||||||
|
("at" . "\xf1fa")
|
||||||
|
("audio-description" . "\xf29e")
|
||||||
|
("backward" . "\xf04a")
|
||||||
|
("balance-scale" . "\xf24e")
|
||||||
|
("ban" . "\xf05e")
|
||||||
|
("bar-chart" . "\xf080")
|
||||||
|
("barcode" . "\xf02a")
|
||||||
|
("bars" . "\xf0c9")
|
||||||
|
("battery-empty" . "\xf244")
|
||||||
|
("battery-full" . "\xf240")
|
||||||
|
("battery-half" . "\xf242")
|
||||||
|
("battery-quarter" . "\xf243")
|
||||||
|
("battery-three-quarters" . "\xf241")
|
||||||
|
("bed" . "\xf236")
|
||||||
|
("beer" . "\xf0fc")
|
||||||
|
("behance" . "\xf1b4")
|
||||||
|
("behance-square" . "\xf1b5")
|
||||||
|
("bell" . "\xf0f3")
|
||||||
|
("bell-o" . "\xf0a2")
|
||||||
|
("bell-slash" . "\xf1f6")
|
||||||
|
("bell-slash-o" . "\xf1f7")
|
||||||
|
("bicycle" . "\xf206")
|
||||||
|
("binoculars" . "\xf1e5")
|
||||||
|
("birthday-cake" . "\xf1fd")
|
||||||
|
("bitbucket" . "\xf171")
|
||||||
|
("bitbucket-square" . "\xf172")
|
||||||
|
("black-tie" . "\xf27e")
|
||||||
|
("blind" . "\xf29d")
|
||||||
|
("bluetooth" . "\xf293")
|
||||||
|
("bluetooth-b" . "\xf294")
|
||||||
|
("bold" . "\xf032")
|
||||||
|
("bolt" . "\xf0e7")
|
||||||
|
("bomb" . "\xf1e2")
|
||||||
|
("book" . "\xf02d")
|
||||||
|
("bookmark" . "\xf02e")
|
||||||
|
("bookmark-o" . "\xf097")
|
||||||
|
("braille" . "\xf2a1")
|
||||||
|
("briefcase" . "\xf0b1")
|
||||||
|
("btc" . "\xf15a")
|
||||||
|
("bug" . "\xf188")
|
||||||
|
("building" . "\xf1ad")
|
||||||
|
("building-o" . "\xf0f7")
|
||||||
|
("bullhorn" . "\xf0a1")
|
||||||
|
("bullseye" . "\xf140")
|
||||||
|
("bus" . "\xf207")
|
||||||
|
("buysellads" . "\xf20d")
|
||||||
|
("calculator" . "\xf1ec")
|
||||||
|
("calendar" . "\xf073")
|
||||||
|
("calendar-check-o" . "\xf274")
|
||||||
|
("calendar-minus-o" . "\xf272")
|
||||||
|
("calendar-o" . "\xf133")
|
||||||
|
("calendar-plus-o" . "\xf271")
|
||||||
|
("calendar-times-o" . "\xf273")
|
||||||
|
("camera" . "\xf030")
|
||||||
|
("camera-retro" . "\xf083")
|
||||||
|
("car" . "\xf1b9")
|
||||||
|
("caret-down" . "\xf0d7")
|
||||||
|
("caret-left" . "\xf0d9")
|
||||||
|
("caret-right" . "\xf0da")
|
||||||
|
("caret-square-o-down" . "\xf150")
|
||||||
|
("caret-square-o-left" . "\xf191")
|
||||||
|
("caret-square-o-right" . "\xf152")
|
||||||
|
("caret-square-o-up" . "\xf151")
|
||||||
|
("caret-up" . "\xf0d8")
|
||||||
|
("cart-arrow-down" . "\xf218")
|
||||||
|
("cart-plus" . "\xf217")
|
||||||
|
("cc" . "\xf20a")
|
||||||
|
("cc-amex" . "\xf1f3")
|
||||||
|
("cc-diners-club" . "\xf24c")
|
||||||
|
("cc-discover" . "\xf1f2")
|
||||||
|
("cc-jcb" . "\xf24b")
|
||||||
|
("cc-mastercard" . "\xf1f1")
|
||||||
|
("cc-paypal" . "\xf1f4")
|
||||||
|
("cc-stripe" . "\xf1f5")
|
||||||
|
("cc-visa" . "\xf1f0")
|
||||||
|
("certificate" . "\xf0a3")
|
||||||
|
("chain-broken" . "\xf127")
|
||||||
|
("check" . "\xf00c")
|
||||||
|
("check-circle" . "\xf058")
|
||||||
|
("check-circle-o" . "\xf05d")
|
||||||
|
("check-square" . "\xf14a")
|
||||||
|
("check-square-o" . "\xf046")
|
||||||
|
("chevron-circle-down" . "\xf13a")
|
||||||
|
("chevron-circle-left" . "\xf137")
|
||||||
|
("chevron-circle-right" . "\xf138")
|
||||||
|
("chevron-circle-up" . "\xf139")
|
||||||
|
("chevron-down" . "\xf078")
|
||||||
|
("chevron-left" . "\xf053")
|
||||||
|
("chevron-right" . "\xf054")
|
||||||
|
("chevron-up" . "\xf077")
|
||||||
|
("child" . "\xf1ae")
|
||||||
|
("chrome" . "\xf268")
|
||||||
|
("circle" . "\xf111")
|
||||||
|
("circle-o" . "\xf10c")
|
||||||
|
("circle-o-notch" . "\xf1ce")
|
||||||
|
("circle-thin" . "\xf1db")
|
||||||
|
("clipboard" . "\xf0ea")
|
||||||
|
("clock-o" . "\xf017")
|
||||||
|
("clone" . "\xf24d")
|
||||||
|
("cloud" . "\xf0c2")
|
||||||
|
("cloud-download" . "\xf0ed")
|
||||||
|
("cloud-upload" . "\xf0ee")
|
||||||
|
("code" . "\xf121")
|
||||||
|
("code-fork" . "\xf126")
|
||||||
|
("codepen" . "\xf1cb")
|
||||||
|
("codiepie" . "\xf284")
|
||||||
|
("coffee" . "\xf0f4")
|
||||||
|
("cog" . "\xf013")
|
||||||
|
("cogs" . "\xf085")
|
||||||
|
("columns" . "\xf0db")
|
||||||
|
("comment" . "\xf075")
|
||||||
|
("comment-o" . "\xf0e5")
|
||||||
|
("commenting" . "\xf27a")
|
||||||
|
("commenting-o" . "\xf27b")
|
||||||
|
("comments" . "\xf086")
|
||||||
|
("comments-o" . "\xf0e6")
|
||||||
|
("compass" . "\xf14e")
|
||||||
|
("compress" . "\xf066")
|
||||||
|
("connectdevelop" . "\xf20e")
|
||||||
|
("contao" . "\xf26d")
|
||||||
|
("copyright" . "\xf1f9")
|
||||||
|
("creative-commons" . "\xf25e")
|
||||||
|
("credit-card" . "\xf09d")
|
||||||
|
("credit-card-alt" . "\xf283")
|
||||||
|
("crop" . "\xf125")
|
||||||
|
("crosshairs" . "\xf05b")
|
||||||
|
("css3" . "\xf13c")
|
||||||
|
("cube" . "\xf1b2")
|
||||||
|
("cubes" . "\xf1b3")
|
||||||
|
("cutlery" . "\xf0f5")
|
||||||
|
("dashcube" . "\xf210")
|
||||||
|
("database" . "\xf1c0")
|
||||||
|
("deaf" . "\xf2a4")
|
||||||
|
("delicious" . "\xf1a5")
|
||||||
|
("desktop" . "\xf108")
|
||||||
|
("deviantart" . "\xf1bd")
|
||||||
|
("diamond" . "\xf219")
|
||||||
|
("digg" . "\xf1a6")
|
||||||
|
("dot-circle-o" . "\xf192")
|
||||||
|
("download" . "\xf019")
|
||||||
|
("dribbble" . "\xf17d")
|
||||||
|
("dropbox" . "\xf16b")
|
||||||
|
("drupal" . "\xf1a9")
|
||||||
|
("edge" . "\xf282")
|
||||||
|
("eject" . "\xf052")
|
||||||
|
("ellipsis-h" . "\xf141")
|
||||||
|
("ellipsis-v" . "\xf142")
|
||||||
|
("empire" . "\xf1d1")
|
||||||
|
("envelope" . "\xf0e0")
|
||||||
|
("envelope-o" . "\xf003")
|
||||||
|
("envelope-square" . "\xf199")
|
||||||
|
("envira" . "\xf299")
|
||||||
|
("eraser" . "\xf12d")
|
||||||
|
("eur" . "\xf153")
|
||||||
|
("exchange" . "\xf0ec")
|
||||||
|
("exclamation" . "\xf12a")
|
||||||
|
("exclamation-circle" . "\xf06a")
|
||||||
|
("exclamation-triangle" . "\xf071")
|
||||||
|
("expand" . "\xf065")
|
||||||
|
("expeditedssl" . "\xf23e")
|
||||||
|
("external-link" . "\xf08e")
|
||||||
|
("external-link-square" . "\xf14c")
|
||||||
|
("eye" . "\xf06e")
|
||||||
|
("eye-slash" . "\xf070")
|
||||||
|
("eyedropper" . "\xf1fb")
|
||||||
|
("facebook" . "\xf09a")
|
||||||
|
("facebook-official" . "\xf230")
|
||||||
|
("facebook-square" . "\xf082")
|
||||||
|
("fast-backward" . "\xf049")
|
||||||
|
("fast-forward" . "\xf050")
|
||||||
|
("fax" . "\xf1ac")
|
||||||
|
("female" . "\xf182")
|
||||||
|
("fighter-jet" . "\xf0fb")
|
||||||
|
("file" . "\xf15b")
|
||||||
|
("file-archive-o" . "\xf1c6")
|
||||||
|
("file-audio-o" . "\xf1c7")
|
||||||
|
("file-code-o" . "\xf1c9")
|
||||||
|
("file-excel-o" . "\xf1c3")
|
||||||
|
("file-image-o" . "\xf1c5")
|
||||||
|
("file-o" . "\xf016")
|
||||||
|
("file-pdf-o" . "\xf1c1")
|
||||||
|
("file-powerpoint-o" . "\xf1c4")
|
||||||
|
("file-text" . "\xf15c")
|
||||||
|
("file-text-o" . "\xf0f6")
|
||||||
|
("file-video-o" . "\xf1c8")
|
||||||
|
("file-word-o" . "\xf1c2")
|
||||||
|
("files-o" . "\xf0c5")
|
||||||
|
("film" . "\xf008")
|
||||||
|
("filter" . "\xf0b0")
|
||||||
|
("fire" . "\xf06d")
|
||||||
|
("fire-extinguisher" . "\xf134")
|
||||||
|
("firefox" . "\xf269")
|
||||||
|
("first-order" . "\xf2b0")
|
||||||
|
("flag" . "\xf024")
|
||||||
|
("flag-checkered" . "\xf11e")
|
||||||
|
("flag-o" . "\xf11d")
|
||||||
|
("flask" . "\xf0c3")
|
||||||
|
("flickr" . "\xf16e")
|
||||||
|
("floppy-o" . "\xf0c7")
|
||||||
|
("folder" . "\xf07b")
|
||||||
|
("folder-o" . "\xf114")
|
||||||
|
("folder-open" . "\xf07c")
|
||||||
|
("folder-open-o" . "\xf115")
|
||||||
|
("font" . "\xf031")
|
||||||
|
("font-awesome" . "\xf2b4")
|
||||||
|
("fonticons" . "\xf280")
|
||||||
|
("fort-awesome" . "\xf286")
|
||||||
|
("forumbee" . "\xf211")
|
||||||
|
("forward" . "\xf04e")
|
||||||
|
("foursquare" . "\xf180")
|
||||||
|
("frown-o" . "\xf119")
|
||||||
|
("futbol-o" . "\xf1e3")
|
||||||
|
("gamepad" . "\xf11b")
|
||||||
|
("gavel" . "\xf0e3")
|
||||||
|
("gbp" . "\xf154")
|
||||||
|
("genderless" . "\xf22d")
|
||||||
|
("get-pocket" . "\xf265")
|
||||||
|
("gg" . "\xf260")
|
||||||
|
("gg-circle" . "\xf261")
|
||||||
|
("gift" . "\xf06b")
|
||||||
|
("git" . "\xf1d3")
|
||||||
|
("git-square" . "\xf1d2")
|
||||||
|
("github" . "\xf09b")
|
||||||
|
("github-alt" . "\xf113")
|
||||||
|
("github-square" . "\xf092")
|
||||||
|
("gitlab" . "\xf296")
|
||||||
|
("glass" . "\xf000")
|
||||||
|
("glide" . "\xf2a5")
|
||||||
|
("glide-g" . "\xf2a6")
|
||||||
|
("globe" . "\xf0ac")
|
||||||
|
("google" . "\xf1a0")
|
||||||
|
("google-plus" . "\xf0d5")
|
||||||
|
("google-plus-official" . "\xf2b3")
|
||||||
|
("google-plus-square" . "\xf0d4")
|
||||||
|
("google-wallet" . "\xf1ee")
|
||||||
|
("graduation-cap" . "\xf19d")
|
||||||
|
("gratipay" . "\xf184")
|
||||||
|
("h-square" . "\xf0fd")
|
||||||
|
("hacker-news" . "\xf1d4")
|
||||||
|
("hand-lizard-o" . "\xf258")
|
||||||
|
("hand-o-down" . "\xf0a7")
|
||||||
|
("hand-o-left" . "\xf0a5")
|
||||||
|
("hand-o-right" . "\xf0a4")
|
||||||
|
("hand-o-up" . "\xf0a6")
|
||||||
|
("hand-paper-o" . "\xf256")
|
||||||
|
("hand-peace-o" . "\xf25b")
|
||||||
|
("hand-pointer-o" . "\xf25a")
|
||||||
|
("hand-rock-o" . "\xf255")
|
||||||
|
("hand-scissors-o" . "\xf257")
|
||||||
|
("hand-spock-o" . "\xf259")
|
||||||
|
("hashtag" . "\xf292")
|
||||||
|
("hdd-o" . "\xf0a0")
|
||||||
|
("header" . "\xf1dc")
|
||||||
|
("headphones" . "\xf025")
|
||||||
|
("heart" . "\xf004")
|
||||||
|
("heart-o" . "\xf08a")
|
||||||
|
("heartbeat" . "\xf21e")
|
||||||
|
("history" . "\xf1da")
|
||||||
|
("home" . "\xf015")
|
||||||
|
("hospital-o" . "\xf0f8")
|
||||||
|
("hourglass" . "\xf254")
|
||||||
|
("hourglass-end" . "\xf253")
|
||||||
|
("hourglass-half" . "\xf252")
|
||||||
|
("hourglass-o" . "\xf250")
|
||||||
|
("hourglass-start" . "\xf251")
|
||||||
|
("houzz" . "\xf27c")
|
||||||
|
("html5" . "\xf13b")
|
||||||
|
("i-cursor" . "\xf246")
|
||||||
|
("ils" . "\xf20b")
|
||||||
|
("inbox" . "\xf01c")
|
||||||
|
("indent" . "\xf03c")
|
||||||
|
("industry" . "\xf275")
|
||||||
|
("info" . "\xf129")
|
||||||
|
("info-circle" . "\xf05a")
|
||||||
|
("inr" . "\xf156")
|
||||||
|
("instagram" . "\xf16d")
|
||||||
|
("internet-explorer" . "\xf26b")
|
||||||
|
("ioxhost" . "\xf208")
|
||||||
|
("italic" . "\xf033")
|
||||||
|
("joomla" . "\xf1aa")
|
||||||
|
("jpy" . "\xf157")
|
||||||
|
("jsfiddle" . "\xf1cc")
|
||||||
|
("key" . "\xf084")
|
||||||
|
("keyboard-o" . "\xf11c")
|
||||||
|
("krw" . "\xf159")
|
||||||
|
("language" . "\xf1ab")
|
||||||
|
("laptop" . "\xf109")
|
||||||
|
("lastfm" . "\xf202")
|
||||||
|
("lastfm-square" . "\xf203")
|
||||||
|
("leaf" . "\xf06c")
|
||||||
|
("leanpub" . "\xf212")
|
||||||
|
("lemon-o" . "\xf094")
|
||||||
|
("level-down" . "\xf149")
|
||||||
|
("level-up" . "\xf148")
|
||||||
|
("life-ring" . "\xf1cd")
|
||||||
|
("lightbulb-o" . "\xf0eb")
|
||||||
|
("line-chart" . "\xf201")
|
||||||
|
("link" . "\xf0c1")
|
||||||
|
("linkedin" . "\xf0e1")
|
||||||
|
("linkedin-square" . "\xf08c")
|
||||||
|
("linux" . "\xf17c")
|
||||||
|
("list" . "\xf03a")
|
||||||
|
("list-alt" . "\xf022")
|
||||||
|
("list-ol" . "\xf0cb")
|
||||||
|
("list-ul" . "\xf0ca")
|
||||||
|
("location-arrow" . "\xf124")
|
||||||
|
("lock" . "\xf023")
|
||||||
|
("long-arrow-down" . "\xf175")
|
||||||
|
("long-arrow-left" . "\xf177")
|
||||||
|
("long-arrow-right" . "\xf178")
|
||||||
|
("long-arrow-up" . "\xf176")
|
||||||
|
("low-vision" . "\xf2a8")
|
||||||
|
("magic" . "\xf0d0")
|
||||||
|
("magnet" . "\xf076")
|
||||||
|
("male" . "\xf183")
|
||||||
|
("map" . "\xf279")
|
||||||
|
("map-marker" . "\xf041")
|
||||||
|
("map-o" . "\xf278")
|
||||||
|
("map-pin" . "\xf276")
|
||||||
|
("map-signs" . "\xf277")
|
||||||
|
("mars" . "\xf222")
|
||||||
|
("mars-double" . "\xf227")
|
||||||
|
("mars-stroke" . "\xf229")
|
||||||
|
("mars-stroke-h" . "\xf22b")
|
||||||
|
("mars-stroke-v" . "\xf22a")
|
||||||
|
("maxcdn" . "\xf136")
|
||||||
|
("meanpath" . "\xf20c")
|
||||||
|
("medium" . "\xf23a")
|
||||||
|
("medkit" . "\xf0fa")
|
||||||
|
("meh-o" . "\xf11a")
|
||||||
|
("mercury" . "\xf223")
|
||||||
|
("microphone" . "\xf130")
|
||||||
|
("microphone-slash" . "\xf131")
|
||||||
|
("minus" . "\xf068")
|
||||||
|
("minus-circle" . "\xf056")
|
||||||
|
("minus-square" . "\xf146")
|
||||||
|
("minus-square-o" . "\xf147")
|
||||||
|
("mixcloud" . "\xf289")
|
||||||
|
("mobile" . "\xf10b")
|
||||||
|
("modx" . "\xf285")
|
||||||
|
("money" . "\xf0d6")
|
||||||
|
("moon-o" . "\xf186")
|
||||||
|
("motorcycle" . "\xf21c")
|
||||||
|
("mouse-pointer" . "\xf245")
|
||||||
|
("music" . "\xf001")
|
||||||
|
("neuter" . "\xf22c")
|
||||||
|
("newspaper-o" . "\xf1ea")
|
||||||
|
("object-group" . "\xf247")
|
||||||
|
("object-ungroup" . "\xf248")
|
||||||
|
("odnoklassniki" . "\xf263")
|
||||||
|
("odnoklassniki-square" . "\xf264")
|
||||||
|
("opencart" . "\xf23d")
|
||||||
|
("openid" . "\xf19b")
|
||||||
|
("opera" . "\xf26a")
|
||||||
|
("optin-monster" . "\xf23c")
|
||||||
|
("outdent" . "\xf03b")
|
||||||
|
("pagelines" . "\xf18c")
|
||||||
|
("paint-brush" . "\xf1fc")
|
||||||
|
("paper-plane" . "\xf1d8")
|
||||||
|
("paper-plane-o" . "\xf1d9")
|
||||||
|
("paperclip" . "\xf0c6")
|
||||||
|
("paragraph" . "\xf1dd")
|
||||||
|
("pause" . "\xf04c")
|
||||||
|
("pause-circle" . "\xf28b")
|
||||||
|
("pause-circle-o" . "\xf28c")
|
||||||
|
("paw" . "\xf1b0")
|
||||||
|
("paypal" . "\xf1ed")
|
||||||
|
("pencil" . "\xf040")
|
||||||
|
("pencil-square" . "\xf14b")
|
||||||
|
("pencil-square-o" . "\xf044")
|
||||||
|
("percent" . "\xf295")
|
||||||
|
("phone" . "\xf095")
|
||||||
|
("phone-square" . "\xf098")
|
||||||
|
("picture-o" . "\xf03e")
|
||||||
|
("pie-chart" . "\xf200")
|
||||||
|
("pied-piper" . "\xf2ae")
|
||||||
|
("pied-piper-alt" . "\xf1a8")
|
||||||
|
("pied-piper-pp" . "\xf1a7")
|
||||||
|
("pinterest" . "\xf0d2")
|
||||||
|
("pinterest-p" . "\xf231")
|
||||||
|
("pinterest-square" . "\xf0d3")
|
||||||
|
("plane" . "\xf072")
|
||||||
|
("play" . "\xf04b")
|
||||||
|
("play-circle" . "\xf144")
|
||||||
|
("play-circle-o" . "\xf01d")
|
||||||
|
("plug" . "\xf1e6")
|
||||||
|
("plus" . "\xf067")
|
||||||
|
("plus-circle" . "\xf055")
|
||||||
|
("plus-square" . "\xf0fe")
|
||||||
|
("plus-square-o" . "\xf196")
|
||||||
|
("power-off" . "\xf011")
|
||||||
|
("print" . "\xf02f")
|
||||||
|
("product-hunt" . "\xf288")
|
||||||
|
("puzzle-piece" . "\xf12e")
|
||||||
|
("qq" . "\xf1d6")
|
||||||
|
("qrcode" . "\xf029")
|
||||||
|
("question" . "\xf128")
|
||||||
|
("question-circle" . "\xf059")
|
||||||
|
("question-circle-o" . "\xf29c")
|
||||||
|
("quote-left" . "\xf10d")
|
||||||
|
("quote-right" . "\xf10e")
|
||||||
|
("random" . "\xf074")
|
||||||
|
("rebel" . "\xf1d0")
|
||||||
|
("recycle" . "\xf1b8")
|
||||||
|
("reddit" . "\xf1a1")
|
||||||
|
("reddit-alien" . "\xf281")
|
||||||
|
("reddit-square" . "\xf1a2")
|
||||||
|
("refresh" . "\xf021")
|
||||||
|
("registered" . "\xf25d")
|
||||||
|
("renren" . "\xf18b")
|
||||||
|
("repeat" . "\xf01e")
|
||||||
|
("reply" . "\xf112")
|
||||||
|
("reply-all" . "\xf122")
|
||||||
|
("retweet" . "\xf079")
|
||||||
|
("road" . "\xf018")
|
||||||
|
("rocket" . "\xf135")
|
||||||
|
("rss" . "\xf09e")
|
||||||
|
("rss-square" . "\xf143")
|
||||||
|
("rub" . "\xf158")
|
||||||
|
("safari" . "\xf267")
|
||||||
|
("scissors" . "\xf0c4")
|
||||||
|
("scribd" . "\xf28a")
|
||||||
|
("search" . "\xf002")
|
||||||
|
("search-minus" . "\xf010")
|
||||||
|
("search-plus" . "\xf00e")
|
||||||
|
("sellsy" . "\xf213")
|
||||||
|
("server" . "\xf233")
|
||||||
|
("share" . "\xf064")
|
||||||
|
("share-alt" . "\xf1e0")
|
||||||
|
("share-alt-square" . "\xf1e1")
|
||||||
|
("share-square" . "\xf14d")
|
||||||
|
("share-square-o" . "\xf045")
|
||||||
|
("shield" . "\xf132")
|
||||||
|
("ship" . "\xf21a")
|
||||||
|
("shirtsinbulk" . "\xf214")
|
||||||
|
("shopping-bag" . "\xf290")
|
||||||
|
("shopping-basket" . "\xf291")
|
||||||
|
("shopping-cart" . "\xf07a")
|
||||||
|
("sign-in" . "\xf090")
|
||||||
|
("sign-language" . "\xf2a7")
|
||||||
|
("sign-out" . "\xf08b")
|
||||||
|
("signal" . "\xf012")
|
||||||
|
("simplybuilt" . "\xf215")
|
||||||
|
("sitemap" . "\xf0e8")
|
||||||
|
("skyatlas" . "\xf216")
|
||||||
|
("skype" . "\xf17e")
|
||||||
|
("slack" . "\xf198")
|
||||||
|
("sliders" . "\xf1de")
|
||||||
|
("slideshare" . "\xf1e7")
|
||||||
|
("smile-o" . "\xf118")
|
||||||
|
("snapchat" . "\xf2ab")
|
||||||
|
("snapchat-ghost" . "\xf2ac")
|
||||||
|
("snapchat-square" . "\xf2ad")
|
||||||
|
("sort" . "\xf0dc")
|
||||||
|
("sort-alpha-asc" . "\xf15d")
|
||||||
|
("sort-alpha-desc" . "\xf15e")
|
||||||
|
("sort-amount-asc" . "\xf160")
|
||||||
|
("sort-amount-desc" . "\xf161")
|
||||||
|
("sort-asc" . "\xf0de")
|
||||||
|
("sort-desc" . "\xf0dd")
|
||||||
|
("sort-numeric-asc" . "\xf162")
|
||||||
|
("sort-numeric-desc" . "\xf163")
|
||||||
|
("soundcloud" . "\xf1be")
|
||||||
|
("space-shuttle" . "\xf197")
|
||||||
|
("spinner" . "\xf110")
|
||||||
|
("spoon" . "\xf1b1")
|
||||||
|
("spotify" . "\xf1bc")
|
||||||
|
("square" . "\xf0c8")
|
||||||
|
("square-o" . "\xf096")
|
||||||
|
("stack-exchange" . "\xf18d")
|
||||||
|
("stack-overflow" . "\xf16c")
|
||||||
|
("star" . "\xf005")
|
||||||
|
("star-half" . "\xf089")
|
||||||
|
("star-half-o" . "\xf123")
|
||||||
|
("star-o" . "\xf006")
|
||||||
|
("steam" . "\xf1b6")
|
||||||
|
("steam-square" . "\xf1b7")
|
||||||
|
("step-backward" . "\xf048")
|
||||||
|
("step-forward" . "\xf051")
|
||||||
|
("stethoscope" . "\xf0f1")
|
||||||
|
("sticky-note" . "\xf249")
|
||||||
|
("sticky-note-o" . "\xf24a")
|
||||||
|
("stop" . "\xf04d")
|
||||||
|
("stop-circle" . "\xf28d")
|
||||||
|
("stop-circle-o" . "\xf28e")
|
||||||
|
("street-view" . "\xf21d")
|
||||||
|
("strikethrough" . "\xf0cc")
|
||||||
|
("stumbleupon" . "\xf1a4")
|
||||||
|
("stumbleupon-circle" . "\xf1a3")
|
||||||
|
("subscript" . "\xf12c")
|
||||||
|
("subway" . "\xf239")
|
||||||
|
("suitcase" . "\xf0f2")
|
||||||
|
("sun-o" . "\xf185")
|
||||||
|
("superscript" . "\xf12b")
|
||||||
|
("table" . "\xf0ce")
|
||||||
|
("tablet" . "\xf10a")
|
||||||
|
("tachometer" . "\xf0e4")
|
||||||
|
("tag" . "\xf02b")
|
||||||
|
("tags" . "\xf02c")
|
||||||
|
("tasks" . "\xf0ae")
|
||||||
|
("taxi" . "\xf1ba")
|
||||||
|
("television" . "\xf26c")
|
||||||
|
("tencent-weibo" . "\xf1d5")
|
||||||
|
("terminal" . "\xf120")
|
||||||
|
("text-height" . "\xf034")
|
||||||
|
("text-width" . "\xf035")
|
||||||
|
("th" . "\xf00a")
|
||||||
|
("th-large" . "\xf009")
|
||||||
|
("th-list" . "\xf00b")
|
||||||
|
("themeisle" . "\xf2b2")
|
||||||
|
("thumb-tack" . "\xf08d")
|
||||||
|
("thumbs-down" . "\xf165")
|
||||||
|
("thumbs-o-down" . "\xf088")
|
||||||
|
("thumbs-o-up" . "\xf087")
|
||||||
|
("thumbs-up" . "\xf164")
|
||||||
|
("ticket" . "\xf145")
|
||||||
|
("times" . "\xf00d")
|
||||||
|
("times-circle" . "\xf057")
|
||||||
|
("times-circle-o" . "\xf05c")
|
||||||
|
("tint" . "\xf043")
|
||||||
|
("toggle-off" . "\xf204")
|
||||||
|
("toggle-on" . "\xf205")
|
||||||
|
("trademark" . "\xf25c")
|
||||||
|
("train" . "\xf238")
|
||||||
|
("transgender" . "\xf224")
|
||||||
|
("transgender-alt" . "\xf225")
|
||||||
|
("trash" . "\xf1f8")
|
||||||
|
("trash-o" . "\xf014")
|
||||||
|
("tree" . "\xf1bb")
|
||||||
|
("trello" . "\xf181")
|
||||||
|
("tripadvisor" . "\xf262")
|
||||||
|
("trophy" . "\xf091")
|
||||||
|
("truck" . "\xf0d1")
|
||||||
|
("try" . "\xf195")
|
||||||
|
("tty" . "\xf1e4")
|
||||||
|
("tumblr" . "\xf173")
|
||||||
|
("tumblr-square" . "\xf174")
|
||||||
|
("twitch" . "\xf1e8")
|
||||||
|
("twitter" . "\xf099")
|
||||||
|
("twitter-square" . "\xf081")
|
||||||
|
("umbrella" . "\xf0e9")
|
||||||
|
("underline" . "\xf0cd")
|
||||||
|
("undo" . "\xf0e2")
|
||||||
|
("universal-access" . "\xf29a")
|
||||||
|
("university" . "\xf19c")
|
||||||
|
("unlock" . "\xf09c")
|
||||||
|
("unlock-alt" . "\xf13e")
|
||||||
|
("upload" . "\xf093")
|
||||||
|
("usb" . "\xf287")
|
||||||
|
("usd" . "\xf155")
|
||||||
|
("user" . "\xf007")
|
||||||
|
("user-md" . "\xf0f0")
|
||||||
|
("user-plus" . "\xf234")
|
||||||
|
("user-secret" . "\xf21b")
|
||||||
|
("user-times" . "\xf235")
|
||||||
|
("users" . "\xf0c0")
|
||||||
|
("venus" . "\xf221")
|
||||||
|
("venus-double" . "\xf226")
|
||||||
|
("venus-mars" . "\xf228")
|
||||||
|
("viacoin" . "\xf237")
|
||||||
|
("viadeo" . "\xf2a9")
|
||||||
|
("viadeo-square" . "\xf2aa")
|
||||||
|
("video-camera" . "\xf03d")
|
||||||
|
("vimeo" . "\xf27d")
|
||||||
|
("vimeo-square" . "\xf194")
|
||||||
|
("vine" . "\xf1ca")
|
||||||
|
("vk" . "\xf189")
|
||||||
|
("volume-control-phone" . "\xf2a0")
|
||||||
|
("volume-down" . "\xf027")
|
||||||
|
("volume-off" . "\xf026")
|
||||||
|
("volume-up" . "\xf028")
|
||||||
|
("weibo" . "\xf18a")
|
||||||
|
("weixin" . "\xf1d7")
|
||||||
|
("whatsapp" . "\xf232")
|
||||||
|
("wheelchair" . "\xf193")
|
||||||
|
("wheelchair-alt" . "\xf29b")
|
||||||
|
("wifi" . "\xf1eb")
|
||||||
|
("wikipedia-w" . "\xf266")
|
||||||
|
("windows" . "\xf17a")
|
||||||
|
("wordpress" . "\xf19a")
|
||||||
|
("wpbeginner" . "\xf297")
|
||||||
|
("wpforms" . "\xf298")
|
||||||
|
("wrench" . "\xf0ad")
|
||||||
|
("xing" . "\xf168")
|
||||||
|
("xing-square" . "\xf169")
|
||||||
|
("y-combinator" . "\xf23b")
|
||||||
|
("yahoo" . "\xf19e")
|
||||||
|
("yelp" . "\xf1e9")
|
||||||
|
("yoast" . "\xf2b1")
|
||||||
|
("youtube" . "\xf167")
|
||||||
|
("youtube-play" . "\xf16a")
|
||||||
|
("youtube-square" . "\xf166")
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(provide 'data-faicons)
|
Binary file not shown.
|
@ -0,0 +1,487 @@
|
||||||
|
(defvar all-the-icons-data/file-icon-alist
|
||||||
|
'(
|
||||||
|
|
||||||
|
( "1c" . "\xa5ea" )
|
||||||
|
( "1c-alt" . "\xea28" )
|
||||||
|
( "MJML" . "\xea6f" )
|
||||||
|
( "R" . "\xe905" )
|
||||||
|
( "abap" . "\xe92b" )
|
||||||
|
( "abif" . "\xea4e" )
|
||||||
|
( "access" . "\xe9ea" )
|
||||||
|
( "actionscript" . "\xe92e" )
|
||||||
|
( "ada" . "\xe90b" )
|
||||||
|
( "ae" . "\xe9f3" )
|
||||||
|
( "ai" . "\xe6b4" )
|
||||||
|
( "akka" . "\xea0e" )
|
||||||
|
( "alex" . "\x29cb" )
|
||||||
|
( "alloy" . "\xe935" )
|
||||||
|
( "alpine-linux" . "\xe9ff" )
|
||||||
|
( "ampl" . "\xe94e" )
|
||||||
|
( "amx" . "\xe99b" )
|
||||||
|
( "angelscript" . "\xea5b" )
|
||||||
|
( "ansible" . "\x24b6" )
|
||||||
|
( "ansible-alt" . "\x61" )
|
||||||
|
( "ant" . "\xe93e" )
|
||||||
|
( "antlr" . "\xe92c" )
|
||||||
|
( "antwar" . "\x2591" )
|
||||||
|
( "api-blueprint" . "\xe92d" )
|
||||||
|
( "apl" . "\x234b" )
|
||||||
|
( "apl-old" . "\xe909" )
|
||||||
|
( "apple" . "\xe925" )
|
||||||
|
( "appveyor" . "\xe923" )
|
||||||
|
( "arc" . "\xe92f" )
|
||||||
|
( "arch-linux" . "\x41" )
|
||||||
|
( "arduino" . "\xe930" )
|
||||||
|
( "arttext" . "\x24d0" )
|
||||||
|
( "asciidoc" . "\xe918" )
|
||||||
|
( "ats" . "\xe934" )
|
||||||
|
( "audacity" . "\xe9f9" )
|
||||||
|
( "augeas" . "\xe931" )
|
||||||
|
( "aurelia" . "\xea48" )
|
||||||
|
( "auto-hotkey" . "\xe932" )
|
||||||
|
( "autoit" . "\xe933" )
|
||||||
|
( "babel" . "\xe91f" )
|
||||||
|
( "bazel" . "\xea5a" )
|
||||||
|
( "bem" . "\xea59" )
|
||||||
|
( "bib" . "\xe601" )
|
||||||
|
( "bintray" . "\xea6e" )
|
||||||
|
( "bithound" . "\xea2a" )
|
||||||
|
( "blender" . "\xe9fa" )
|
||||||
|
( "bluespec" . "\xe93c" )
|
||||||
|
( "boo" . "\xe939" )
|
||||||
|
( "brain" . "\xe93a" )
|
||||||
|
( "brakeman" . "\xe9d6" )
|
||||||
|
( "bro" . "\xe93b" )
|
||||||
|
( "broccoli" . "\xe922" )
|
||||||
|
( "brotli" . "\xea6c" )
|
||||||
|
( "browserslist" . "\xea80" )
|
||||||
|
( "brunch" . "\xea47" )
|
||||||
|
( "buck" . "\xea46" )
|
||||||
|
( "build-boot" . "\xf103" )
|
||||||
|
( "bundler" . "\xea45" )
|
||||||
|
( "byond" . "\xe962" )
|
||||||
|
( "cabal" . "\xe9c2" )
|
||||||
|
( "caddy" . "\xea58" )
|
||||||
|
( "cake" . "\xe9e3" )
|
||||||
|
( "cakefile" . "\xe924" )
|
||||||
|
( "cakephp" . "\xea43" )
|
||||||
|
( "cakephp-old" . "\xe9d3" )
|
||||||
|
( "cc" . "\xe9d5" )
|
||||||
|
( "ceylon" . "\xe94f" )
|
||||||
|
( "chai" . "\x63" )
|
||||||
|
( "chapel" . "\xe950" )
|
||||||
|
( "chartjs" . "\xea0b" )
|
||||||
|
( "chef" . "\xea42" )
|
||||||
|
( "chuck" . "\xe943" )
|
||||||
|
( "circle-ci" . "\xea12" )
|
||||||
|
( "cirru" . "\xe951" )
|
||||||
|
( "ckeditor" . "\xea0c" )
|
||||||
|
( "clarion" . "\xe952" )
|
||||||
|
( "clean" . "\xe95b" )
|
||||||
|
( "click" . "\xe95c" )
|
||||||
|
( "clips" . "\xe940" )
|
||||||
|
( "clj" . "\xf105" )
|
||||||
|
( "cljs" . "\xf104" )
|
||||||
|
( "closure-template" . "\xea82" )
|
||||||
|
( "cmake" . "\xe93f" )
|
||||||
|
( "cobol" . "\xea44" )
|
||||||
|
( "codecov" . "\x2602" )
|
||||||
|
( "codekit" . "\xea41" )
|
||||||
|
( "codemirror" . "\xea0d" )
|
||||||
|
( "codeship" . "\xea6a" )
|
||||||
|
( "cold-fusion" . "\xe929" )
|
||||||
|
( "clisp" . "\xe972" )
|
||||||
|
( "composer" . "\xe683" )
|
||||||
|
( "config" . "\xf07c" )
|
||||||
|
( "coq" . "\xe95f" )
|
||||||
|
( "cordova" . "\xea11" )
|
||||||
|
( "cp" . "\xe942" )
|
||||||
|
( "cpan" . "\xea87" )
|
||||||
|
( "creole" . "\xe95e" )
|
||||||
|
( "crystal" . "\xe902" )
|
||||||
|
( "cs-script" . "\xe9e2" )
|
||||||
|
( "csound" . "\xe9f0" )
|
||||||
|
( "cucumber" . "\xf02b" )
|
||||||
|
( "cython" . "\xe963" )
|
||||||
|
( "d3" . "\xea10" )
|
||||||
|
( "darcs" . "\xe964" )
|
||||||
|
( "dashboard" . "\xf07d" )
|
||||||
|
( "dbase" . "\xe9f1" )
|
||||||
|
( "default" . "\x1f5cc" )
|
||||||
|
( "delphi" . "\xea40" )
|
||||||
|
( "devicetree" . "\xea57" )
|
||||||
|
( "diff" . "\xe960" )
|
||||||
|
( "dockerfile" . "\xf106" )
|
||||||
|
( "doclets" . "\xea3f" )
|
||||||
|
( "doge" . "\xe946" )
|
||||||
|
( "dom" . "\xea71" )
|
||||||
|
( "donejs" . "\x1f3c1" )
|
||||||
|
( "doxygen" . "\xe928" )
|
||||||
|
( "dragula" . "\x1f44c" )
|
||||||
|
( "drone" . "\xea3d" )
|
||||||
|
( "dyalog" . "\xe90c" )
|
||||||
|
( "dylib" . "\xea15" )
|
||||||
|
( "e" . "\x45" )
|
||||||
|
( "eagle" . "\xe965" )
|
||||||
|
( "easybuild" . "\xea85" )
|
||||||
|
( "ec" . "\xe9c9" )
|
||||||
|
( "ecere" . "\xe966" )
|
||||||
|
( "edge" . "\xea78" )
|
||||||
|
( "editorconfig" . "\xea1b" )
|
||||||
|
( "eiffel" . "\xe967" )
|
||||||
|
( "ejs" . "\xea4b" )
|
||||||
|
( "electron" . "\xea27" )
|
||||||
|
( "elm" . "\xf102" )
|
||||||
|
( "emacs" . "\xe926" )
|
||||||
|
( "elisp" . "\xe926" )
|
||||||
|
( "ember" . "\xe61b" )
|
||||||
|
( "emberscript" . "\xe968" )
|
||||||
|
( "eq" . "\xea0a" )
|
||||||
|
( "esdoc" . "\xea5c" )
|
||||||
|
( "eslint" . "\xea0f" )
|
||||||
|
( "eslint-old" . "\xe90e" )
|
||||||
|
( "excel" . "\xe9ee" )
|
||||||
|
( "fabfile" . "\xe94b" )
|
||||||
|
( "factor" . "\xe96a" )
|
||||||
|
( "fancy" . "\xe96b" )
|
||||||
|
( "fantom" . "\xe96f" )
|
||||||
|
( "fbx" . "\xe9fc" )
|
||||||
|
( "ffmpeg" . "\xea22" )
|
||||||
|
( "finder" . "\xe9e9" )
|
||||||
|
( "firebase" . "\xea7f" )
|
||||||
|
( "flow" . "\xe921" )
|
||||||
|
( "flux" . "\xe969" )
|
||||||
|
( "font" . "\xe90f" )
|
||||||
|
( "fontforge" . "\xfb00" )
|
||||||
|
( "fortran" . "\xe90a" )
|
||||||
|
( "franca" . "\xea56" )
|
||||||
|
( "freemarker" . "\xe970" )
|
||||||
|
( "frege" . "\xe96e" )
|
||||||
|
( "fuel-ux" . "\xea09" )
|
||||||
|
( "gams" . "\xe973" )
|
||||||
|
( "gap" . "\xe971" )
|
||||||
|
( "gdb" . "\xea08" )
|
||||||
|
( "genshi" . "\xe976" )
|
||||||
|
( "gentoo" . "\xe96d" )
|
||||||
|
( "gf" . "\xe978" )
|
||||||
|
( "gitlab" . "\xea3c" )
|
||||||
|
( "glade" . "\xe938" )
|
||||||
|
( "glyphs" . "\x47" )
|
||||||
|
( "gn" . "\xea25" )
|
||||||
|
( "gnu" . "\xe679" )
|
||||||
|
( "go" . "\xe624" )
|
||||||
|
( "godot" . "\xe974" )
|
||||||
|
( "golo" . "\xe979" )
|
||||||
|
( "gosu" . "\xe97a" )
|
||||||
|
( "gradle" . "\xe903" )
|
||||||
|
( "graphql" . "\xe97c" )
|
||||||
|
( "graphviz" . "\xe97d" )
|
||||||
|
( "groovy" . "\xe904" )
|
||||||
|
( "grunt" . "\xe611" )
|
||||||
|
( "gulp" . "\xe610" )
|
||||||
|
( "hack" . "\xe9ce" )
|
||||||
|
( "haml" . "\xf15b" )
|
||||||
|
( "harbour" . "\xe97b" )
|
||||||
|
( "hashicorp" . "\xe97e" )
|
||||||
|
( "haxe" . "\xe907" )
|
||||||
|
( "haxedevelop" . "\xea3b" )
|
||||||
|
( "hg" . "\x263f" )
|
||||||
|
( "hoplon" . "\xea4d" )
|
||||||
|
( "hy" . "\xe97f" )
|
||||||
|
( "icu" . "\xea23" )
|
||||||
|
( "id" . "\xe9f4" )
|
||||||
|
( "idl" . "\xe947" )
|
||||||
|
( "idris" . "\xe983" )
|
||||||
|
( "igorpro" . "\xe980" )
|
||||||
|
( "image" . "\xf012" )
|
||||||
|
( "inform7" . "\xe984" )
|
||||||
|
( "inno" . "\xe985" )
|
||||||
|
( "io" . "\xe981" )
|
||||||
|
( "ioke" . "\xe982" )
|
||||||
|
( "ionic-project" . "\xf14b" )
|
||||||
|
( "isabelle" . "\xe945" )
|
||||||
|
( "j" . "\xe937" )
|
||||||
|
( "jade" . "\xe90d" )
|
||||||
|
( "jake" . "\xe948" )
|
||||||
|
( "jasmine" . "\xea3a" )
|
||||||
|
( "jenkins" . "\xe667" )
|
||||||
|
( "jest" . "\xea39" )
|
||||||
|
( "jinja" . "\xe944" )
|
||||||
|
( "jison" . "\xea55" )
|
||||||
|
( "jolie" . "\xea75" )
|
||||||
|
( "jsonld" . "\xe958" )
|
||||||
|
( "jsx" . "\xf100" )
|
||||||
|
( "jsx-2" . "\xf101" )
|
||||||
|
( "jsx2-alt" . "\xe9e6" )
|
||||||
|
( "julia" . "\x26ec" )
|
||||||
|
( "junos" . "\xea81" )
|
||||||
|
( "jupyter" . "\xe987" )
|
||||||
|
( "karma" . "\xe9cd" )
|
||||||
|
( "keynote" . "\xe9e5" )
|
||||||
|
( "khronos" . "\xe9f8" )
|
||||||
|
( "kicad" . "\xea4c" )
|
||||||
|
( "kitchenci" . "\xea38" )
|
||||||
|
( "kivy" . "\xe901" )
|
||||||
|
( "knockout" . "\x4b" )
|
||||||
|
( "kotlin" . "\xe989" )
|
||||||
|
( "krl" . "\xe988" )
|
||||||
|
( "labview" . "\xe98a" )
|
||||||
|
( "lasso" . "\xe98c" )
|
||||||
|
( "leaflet" . "\xea07" )
|
||||||
|
( "lean" . "\x4c" )
|
||||||
|
( "lerna" . "\xea37" )
|
||||||
|
( "lfe" . "\xe94c" )
|
||||||
|
( "libuv" . "\xea21" )
|
||||||
|
( "lightwave" . "\xe9fb" )
|
||||||
|
( "lime" . "\xea36" )
|
||||||
|
( "lisp" . "\xe908" )
|
||||||
|
( "livescript" . "\xe914" )
|
||||||
|
( "llvm" . "\xe91d" )
|
||||||
|
( "logtalk" . "\xe98d" )
|
||||||
|
( "lookml" . "\xe98e" )
|
||||||
|
( "lsl" . "\xe98b" )
|
||||||
|
( "lua" . "\xe91b" )
|
||||||
|
( "mako" . "\xe98f" )
|
||||||
|
( "man-page" . "\xe936" )
|
||||||
|
( "mapbox" . "\xe941" )
|
||||||
|
( "markdownlint" . "\xf0c9" )
|
||||||
|
( "marko" . "\xe920" )
|
||||||
|
( "mathematica" . "\xe990" )
|
||||||
|
( "mathjax" . "\xea06" )
|
||||||
|
( "matlab" . "\xe991" )
|
||||||
|
( "max" . "\xe993" )
|
||||||
|
( "maxscript" . "\xe900" )
|
||||||
|
( "maya" . "\xe9f6" )
|
||||||
|
( "mediawiki" . "\xe954" )
|
||||||
|
( "mercury" . "\xe994" )
|
||||||
|
( "meson" . "\xea54" )
|
||||||
|
( "metal" . "\x4d" )
|
||||||
|
( "meteor" . "\xe6a5" )
|
||||||
|
( "microsoft-infopath" . "\xea35" )
|
||||||
|
( "minecraft" . "\xe9dc" )
|
||||||
|
( "minizinc" . "\xea53" )
|
||||||
|
( "mirah" . "\xe995" )
|
||||||
|
( "miranda" . "\xea52" )
|
||||||
|
( "mocha" . "\x26fe" )
|
||||||
|
( "modula-2" . "\xe996" )
|
||||||
|
( "moment" . "\x1f558" )
|
||||||
|
( "moment-tz" . "\x1f30d" )
|
||||||
|
( "monkey" . "\xe997" )
|
||||||
|
( "moustache" . "\xe60f" )
|
||||||
|
( "mruby" . "\xea18" )
|
||||||
|
( "mupad" . "\xe9ca" )
|
||||||
|
( "nano" . "\xea76" )
|
||||||
|
( "nanoc" . "\xea51" )
|
||||||
|
( "nant" . "\xe9e1" )
|
||||||
|
( "nasm" . "\xea72" )
|
||||||
|
( "neko" . "\xea05" )
|
||||||
|
( "netlogo" . "\xe99c" )
|
||||||
|
( "new-relic" . "\xe9d7" )
|
||||||
|
( "nginx" . "\xf146b" )
|
||||||
|
( "nib" . "\x2712" )
|
||||||
|
( "nimrod" . "\xe998" )
|
||||||
|
( "nit" . "\xe999" )
|
||||||
|
( "nix" . "\xe99a" )
|
||||||
|
( "nmap" . "\xe94d" )
|
||||||
|
( "nodemon" . "\xea26" )
|
||||||
|
( "normalize" . "\xea04" )
|
||||||
|
( "npm" . "\xe91c" )
|
||||||
|
( "npm-old" . "\xf17b" )
|
||||||
|
( "nsis" . "\xea1e" )
|
||||||
|
( "nsis-old" . "\xe992" )
|
||||||
|
( "nuclide" . "\xea34" )
|
||||||
|
( "nuget" . "\xe9d9" )
|
||||||
|
( "numpy" . "\xe99d" )
|
||||||
|
( "nunjucks" . "\xe953" )
|
||||||
|
( "nvidia" . "\xe95d" )
|
||||||
|
( "nxc" . "\xea6b" )
|
||||||
|
( "obj" . "\xe9e8" )
|
||||||
|
( "objective-j" . "\xe99e" )
|
||||||
|
( "ocaml" . "\xe91a" )
|
||||||
|
( "octave" . "\xea33" )
|
||||||
|
( "onenote" . "\xe9eb" )
|
||||||
|
( "ooc" . "\xe9cb" )
|
||||||
|
( "opa" . "\x2601" )
|
||||||
|
( "opencl" . "\xe99f" )
|
||||||
|
( "opengl" . "\xea7a" )
|
||||||
|
( "openoffice" . "\xe9e4" )
|
||||||
|
( "openscad" . "\xe911" )
|
||||||
|
( "org" . "\xe917" )
|
||||||
|
( "owl" . "\xe957" )
|
||||||
|
( "ox" . "\xe9a1" )
|
||||||
|
( "oxygene" . "\xe9bf" )
|
||||||
|
( "oz" . "\xe9be" )
|
||||||
|
( "p4" . "\xea50" )
|
||||||
|
( "pan" . "\xe9bd" )
|
||||||
|
( "papyrus" . "\xe9bc" )
|
||||||
|
( "parrot" . "\xe9bb" )
|
||||||
|
( "pascal" . "\xe92a" )
|
||||||
|
( "patch" . "\xe961" )
|
||||||
|
( "pawn" . "\x265f" )
|
||||||
|
( "pb" . "\xea14" )
|
||||||
|
( "pegjs" . "\xea74" )
|
||||||
|
( "perl6" . "\xe96c" )
|
||||||
|
( "phalcon" . "\xe94a" )
|
||||||
|
( "phoenix" . "\xea5f" )
|
||||||
|
( "php" . "\xf147" )
|
||||||
|
( "phpunit" . "\xea32" )
|
||||||
|
( "pickle" . "\xe9c4" )
|
||||||
|
( "pike" . "\xe9b9" )
|
||||||
|
( "platformio" . "\xea2c" )
|
||||||
|
( "pm2" . "\x2630" )
|
||||||
|
( "pod" . "\xea84" )
|
||||||
|
( "pogo" . "\xe9b8" )
|
||||||
|
( "pointwise" . "\xe977" )
|
||||||
|
( "polymer" . "\xea2b" )
|
||||||
|
( "pony" . "\xe9b7" )
|
||||||
|
( "postcss" . "\xe910" )
|
||||||
|
( "postscript" . "\xe955" )
|
||||||
|
( "povray" . "\x50" )
|
||||||
|
( "powerpoint" . "\xe9ec" )
|
||||||
|
( "powershell" . "\xe9da" )
|
||||||
|
( "precision" . "\x2295" )
|
||||||
|
( "premiere" . "\xe9f5" )
|
||||||
|
( "processing" . "\xe9a0" )
|
||||||
|
( "progress" . "\xe9c0" )
|
||||||
|
( "propeller" . "\xe9b5" )
|
||||||
|
( "proselint" . "\xea6d" )
|
||||||
|
( "protractor" . "\xe9de" )
|
||||||
|
( "ps" . "\xe6b8" )
|
||||||
|
( "pug" . "\xea13" )
|
||||||
|
( "pug-alt" . "\xe9d0" )
|
||||||
|
( "puppet" . "\xf0c3" )
|
||||||
|
( "purebasic" . "\x1b5" )
|
||||||
|
( "purescript" . "\xe9b2" )
|
||||||
|
( "racket" . "\xe9b1" )
|
||||||
|
( "raml" . "\xe913" )
|
||||||
|
( "rascal" . "\xea24" )
|
||||||
|
( "rdoc" . "\xe9b0" )
|
||||||
|
( "realbasic" . "\xe9af" )
|
||||||
|
( "reason" . "\xea1d" )
|
||||||
|
( "rebol" . "\xe9ae" )
|
||||||
|
( "red" . "\xe9ad" )
|
||||||
|
( "redux" . "\xea30" )
|
||||||
|
( "regex" . "\x2a" )
|
||||||
|
( "rexx" . "\xea16" )
|
||||||
|
( "rhino" . "\xea4a" )
|
||||||
|
( "ring" . "\x1f48d" )
|
||||||
|
( "riot" . "\xe919" )
|
||||||
|
( "robot" . "\xe9ac" )
|
||||||
|
( "rollup" . "\xea20" )
|
||||||
|
( "rollup-old" . "\xe9fd" )
|
||||||
|
( "rot" . "\x1f764" )
|
||||||
|
( "rspec" . "\xea31" )
|
||||||
|
( "rst" . "\xe9cc" )
|
||||||
|
( "sage" . "\xe9ab" )
|
||||||
|
( "saltstack" . "\xe915" )
|
||||||
|
( "sas" . "\xe95a" )
|
||||||
|
( "sbt" . "\xe9d2" )
|
||||||
|
( "sc" . "\xe9a2" )
|
||||||
|
( "scheme" . "\x3bb" )
|
||||||
|
( "scilab" . "\xe9a9" )
|
||||||
|
( "scrutinizer" . "\xe9d4" )
|
||||||
|
( "self" . "\xe9a8" )
|
||||||
|
( "sequelize" . "\xea2f" )
|
||||||
|
( "sf" . "\xe9db" )
|
||||||
|
( "shen" . "\xe9a7" )
|
||||||
|
( "shipit" . "\x26f5" )
|
||||||
|
( "shippable" . "\xea2d" )
|
||||||
|
( "shopify" . "\xe9cf" )
|
||||||
|
( "shuriken" . "\x272b" )
|
||||||
|
( "silverstripe" . "\xe800" )
|
||||||
|
( "sinatra" . "\xea03" )
|
||||||
|
( "sketch" . "\xe927" )
|
||||||
|
( "sketchup-layout" . "\xea7c" )
|
||||||
|
( "sketchup-make" . "\xea7e" )
|
||||||
|
( "sketchup-stylebuilder" . "\xea7d" )
|
||||||
|
( "slash" . "\xe9a6" )
|
||||||
|
( "snyk" . "\xea1c" )
|
||||||
|
( "solidity" . "\xea86" )
|
||||||
|
( "sparql" . "\xe959" )
|
||||||
|
( "spray" . "\xea02" )
|
||||||
|
( "sqf" . "\xe9a5" )
|
||||||
|
( "sqlite" . "\xe9dd" )
|
||||||
|
( "squarespace" . "\xea5e" )
|
||||||
|
( "stan" . "\xe9a4" )
|
||||||
|
( "stata" . "\xe9a3" )
|
||||||
|
( "storyist" . "\xe9ef" )
|
||||||
|
( "strings" . "\xe9e0" )
|
||||||
|
( "stylelint" . "\xe93d" )
|
||||||
|
( "stylus" . "\x73" )
|
||||||
|
( "stylus-full" . "\xe9f7" )
|
||||||
|
( "stylus-orb" . "\x53" )
|
||||||
|
( "sublime" . "\xe986" )
|
||||||
|
( "sv" . "\xe9c3" )
|
||||||
|
( "svn" . "\xea17" )
|
||||||
|
( "swagger" . "\xea29" )
|
||||||
|
( "tag" . "\xf015" )
|
||||||
|
( "tcl" . "\xe956" )
|
||||||
|
( "telegram" . "\x2708" )
|
||||||
|
( "terminal" . "\xf0c8" )
|
||||||
|
( "tern" . "\x1f54a" )
|
||||||
|
( "terraform" . "\xe916" )
|
||||||
|
( "test-coffeescript" . "\xea62" )
|
||||||
|
( "test-dir" . "\xea60" )
|
||||||
|
( "test-generic" . "\xea63" )
|
||||||
|
( "test-js" . "\xea64" )
|
||||||
|
( "test-perl" . "\xea65" )
|
||||||
|
( "test-python" . "\xea66" )
|
||||||
|
( "test-react" . "\xea67" )
|
||||||
|
( "test-ruby" . "\xea68" )
|
||||||
|
( "test-typescript" . "\xea69" )
|
||||||
|
( "tex" . "\xe600" )
|
||||||
|
( "textile" . "\x74" )
|
||||||
|
( "textmate" . "\x2122" )
|
||||||
|
( "thor" . "\xe9d8" )
|
||||||
|
( "tinymce" . "\xea01" )
|
||||||
|
( "tsx" . "\xe9d1" )
|
||||||
|
( "tsx-alt" . "\xe9e7" )
|
||||||
|
( "tt" . "\x54" )
|
||||||
|
( "turing" . "\xe9b6" )
|
||||||
|
( "twig" . "\x2e19" )
|
||||||
|
( "twine" . "\xea5d" )
|
||||||
|
( "txl" . "\xe9c1" )
|
||||||
|
( "typedoc" . "\xe9fe" )
|
||||||
|
( "typescript" . "\xe912" )
|
||||||
|
( "typescript-alt" . "\x2a6" )
|
||||||
|
( "typings" . "\xe9df" )
|
||||||
|
( "uno" . "\xe9b3" )
|
||||||
|
( "unreal" . "\x75" )
|
||||||
|
( "urweb" . "\xe9ba" )
|
||||||
|
( "v8" . "\xea1f" )
|
||||||
|
( "vagrant" . "\x56" )
|
||||||
|
( "vcl" . "\xe9b4" )
|
||||||
|
( "verilog" . "\xe949" )
|
||||||
|
( "vertex-shader" . "\xea79" )
|
||||||
|
( "vhdl" . "\xe9aa" )
|
||||||
|
( "video" . "\xf057" )
|
||||||
|
( "virtualbox" . "\xea3e" )
|
||||||
|
( "virtualbox-alt" . "\xea2e" )
|
||||||
|
( "visio" . "\xea83" )
|
||||||
|
( "vmware" . "\xea49" )
|
||||||
|
( "vue" . "\xe906" )
|
||||||
|
( "wasm" . "\xea70" )
|
||||||
|
( "watchman" . "\xea4f" )
|
||||||
|
( "webgl" . "\xea7b" )
|
||||||
|
( "webpack" . "\xea61" )
|
||||||
|
( "webpack-old" . "\xe91e" )
|
||||||
|
( "wercker" . "\xea19" )
|
||||||
|
( "word" . "\xe9ed" )
|
||||||
|
( "x10" . "\x2169" )
|
||||||
|
( "xamarin" . "\xea77" )
|
||||||
|
( "xmos" . "\x58" )
|
||||||
|
( "xpages" . "\xe9c5" )
|
||||||
|
( "xtend" . "\xe9c6" )
|
||||||
|
( "yarn" . "\xea1a" )
|
||||||
|
( "yasm" . "\xea73" )
|
||||||
|
( "yin-yang" . "\x262f" )
|
||||||
|
( "yoyo" . "\xe975" )
|
||||||
|
( "yui" . "\xea00" )
|
||||||
|
( "zbrush" . "\xe9f2" )
|
||||||
|
( "zephir" . "\xe9c7" )
|
||||||
|
( "zimpl" . "\xe9c8" )
|
||||||
|
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
(provide 'data-fileicons)
|
Binary file not shown.
|
@ -0,0 +1,935 @@
|
||||||
|
(defvar all-the-icons-data/material-icons-alist
|
||||||
|
'(("3d_rotation" . "\xe84d")
|
||||||
|
("ac_unit" . "\xeb3b")
|
||||||
|
("access_alarm" . "\xe190")
|
||||||
|
("access_alarms" . "\xe191")
|
||||||
|
("access_time" . "\xe192")
|
||||||
|
("accessibility" . "\xe84e")
|
||||||
|
("accessible" . "\xe914")
|
||||||
|
("account_balance" . "\xe84f")
|
||||||
|
("account_balance_wallet" . "\xe850")
|
||||||
|
("account_box" . "\xe851")
|
||||||
|
("account_circle" . "\xe853")
|
||||||
|
("adb" . "\xe60e")
|
||||||
|
("add" . "\xe145")
|
||||||
|
("add_a_photo" . "\xe439")
|
||||||
|
("add_alarm" . "\xe193")
|
||||||
|
("add_alert" . "\xe003")
|
||||||
|
("add_box" . "\xe146")
|
||||||
|
("add_circle" . "\xe147")
|
||||||
|
("add_circle_outline" . "\xe148")
|
||||||
|
("add_location" . "\xe567")
|
||||||
|
("add_shopping_cart" . "\xe854")
|
||||||
|
("add_to_photos" . "\xe39d")
|
||||||
|
("add_to_queue" . "\xe05c")
|
||||||
|
("adjust" . "\xe39e")
|
||||||
|
("airline_seat_flat" . "\xe630")
|
||||||
|
("airline_seat_flat_angled" . "\xe631")
|
||||||
|
("airline_seat_individual_suite" . "\xe632")
|
||||||
|
("airline_seat_legroom_extra" . "\xe633")
|
||||||
|
("airline_seat_legroom_normal" . "\xe634")
|
||||||
|
("airline_seat_legroom_reduced" . "\xe635")
|
||||||
|
("airline_seat_recline_extra" . "\xe636")
|
||||||
|
("airline_seat_recline_normal" . "\xe637")
|
||||||
|
("airplanemode_active" . "\xe195")
|
||||||
|
("airplanemode_inactive" . "\xe194")
|
||||||
|
("airplay" . "\xe055")
|
||||||
|
("airport_shuttle" . "\xeb3c")
|
||||||
|
("alarm" . "\xe855")
|
||||||
|
("alarm_add" . "\xe856")
|
||||||
|
("alarm_off" . "\xe857")
|
||||||
|
("alarm_on" . "\xe858")
|
||||||
|
("album" . "\xe019")
|
||||||
|
("all_inclusive" . "\xeb3d")
|
||||||
|
("all_out" . "\xe90b")
|
||||||
|
("android" . "\xe859")
|
||||||
|
("announcement" . "\xe85a")
|
||||||
|
("apps" . "\xe5c3")
|
||||||
|
("archive" . "\xe149")
|
||||||
|
("arrow_back" . "\xe5c4")
|
||||||
|
("arrow_downward" . "\xe5db")
|
||||||
|
("arrow_drop_down" . "\xe5c5")
|
||||||
|
("arrow_drop_down_circle" . "\xe5c6")
|
||||||
|
("arrow_drop_up" . "\xe5c7")
|
||||||
|
("arrow_forward" . "\xe5c8")
|
||||||
|
("arrow_upward" . "\xe5d8")
|
||||||
|
("art_track" . "\xe060")
|
||||||
|
("aspect_ratio" . "\xe85b")
|
||||||
|
("assessment" . "\xe85c")
|
||||||
|
("assignment" . "\xe85d")
|
||||||
|
("assignment_ind" . "\xe85e")
|
||||||
|
("assignment_late" . "\xe85f")
|
||||||
|
("assignment_return" . "\xe860")
|
||||||
|
("assignment_returned" . "\xe861")
|
||||||
|
("assignment_turned_in" . "\xe862")
|
||||||
|
("assistant" . "\xe39f")
|
||||||
|
("assistant_photo" . "\xe3a0")
|
||||||
|
("attach_file" . "\xe226")
|
||||||
|
("attach_money" . "\xe227")
|
||||||
|
("attachment" . "\xe2bc")
|
||||||
|
("audiotrack" . "\xe3a1")
|
||||||
|
("autorenew" . "\xe863")
|
||||||
|
("av_timer" . "\xe01b")
|
||||||
|
("backspace" . "\xe14a")
|
||||||
|
("backup" . "\xe864")
|
||||||
|
("battery_alert" . "\xe19c")
|
||||||
|
("battery_charging_full" . "\xe1a3")
|
||||||
|
("battery_full" . "\xe1a4")
|
||||||
|
("battery_std" . "\xe1a5")
|
||||||
|
("battery_unknown" . "\xe1a6")
|
||||||
|
("beach_access" . "\xeb3e")
|
||||||
|
("beenhere" . "\xe52d")
|
||||||
|
("block" . "\xe14b")
|
||||||
|
("bluetooth" . "\xe1a7")
|
||||||
|
("bluetooth_audio" . "\xe60f")
|
||||||
|
("bluetooth_connected" . "\xe1a8")
|
||||||
|
("bluetooth_disabled" . "\xe1a9")
|
||||||
|
("bluetooth_searching" . "\xe1aa")
|
||||||
|
("blur_circular" . "\xe3a2")
|
||||||
|
("blur_linear" . "\xe3a3")
|
||||||
|
("blur_off" . "\xe3a4")
|
||||||
|
("blur_on" . "\xe3a5")
|
||||||
|
("book" . "\xe865")
|
||||||
|
("bookmark" . "\xe866")
|
||||||
|
("bookmark_border" . "\xe867")
|
||||||
|
("border_all" . "\xe228")
|
||||||
|
("border_bottom" . "\xe229")
|
||||||
|
("border_clear" . "\xe22a")
|
||||||
|
("border_color" . "\xe22b")
|
||||||
|
("border_horizontal" . "\xe22c")
|
||||||
|
("border_inner" . "\xe22d")
|
||||||
|
("border_left" . "\xe22e")
|
||||||
|
("border_outer" . "\xe22f")
|
||||||
|
("border_right" . "\xe230")
|
||||||
|
("border_style" . "\xe231")
|
||||||
|
("border_top" . "\xe232")
|
||||||
|
("border_vertical" . "\xe233")
|
||||||
|
("branding_watermark" . "\xe06b")
|
||||||
|
("brightness_1" . "\xe3a6")
|
||||||
|
("brightness_2" . "\xe3a7")
|
||||||
|
("brightness_3" . "\xe3a8")
|
||||||
|
("brightness_4" . "\xe3a9")
|
||||||
|
("brightness_5" . "\xe3aa")
|
||||||
|
("brightness_6" . "\xe3ab")
|
||||||
|
("brightness_7" . "\xe3ac")
|
||||||
|
("brightness_auto" . "\xe1ab")
|
||||||
|
("brightness_high" . "\xe1ac")
|
||||||
|
("brightness_low" . "\xe1ad")
|
||||||
|
("brightness_medium" . "\xe1ae")
|
||||||
|
("broken_image" . "\xe3ad")
|
||||||
|
("brush" . "\xe3ae")
|
||||||
|
("bubble_chart" . "\xe6dd")
|
||||||
|
("bug_report" . "\xe868")
|
||||||
|
("build" . "\xe869")
|
||||||
|
("burst_mode" . "\xe43c")
|
||||||
|
("business" . "\xe0af")
|
||||||
|
("business_center" . "\xeb3f")
|
||||||
|
("cached" . "\xe86a")
|
||||||
|
("cake" . "\xe7e9")
|
||||||
|
("call" . "\xe0b0")
|
||||||
|
("call_end" . "\xe0b1")
|
||||||
|
("call_made" . "\xe0b2")
|
||||||
|
("call_merge" . "\xe0b3")
|
||||||
|
("call_missed" . "\xe0b4")
|
||||||
|
("call_missed_outgoing" . "\xe0e4")
|
||||||
|
("call_received" . "\xe0b5")
|
||||||
|
("call_split" . "\xe0b6")
|
||||||
|
("call_to_action" . "\xe06c")
|
||||||
|
("camera" . "\xe3af")
|
||||||
|
("camera_alt" . "\xe3b0")
|
||||||
|
("camera_enhance" . "\xe8fc")
|
||||||
|
("camera_front" . "\xe3b1")
|
||||||
|
("camera_rear" . "\xe3b2")
|
||||||
|
("camera_roll" . "\xe3b3")
|
||||||
|
("cancel" . "\xe5c9")
|
||||||
|
("card_giftcard" . "\xe8f6")
|
||||||
|
("card_membership" . "\xe8f7")
|
||||||
|
("card_travel" . "\xe8f8")
|
||||||
|
("casino" . "\xeb40")
|
||||||
|
("cast" . "\xe307")
|
||||||
|
("cast_connected" . "\xe308")
|
||||||
|
("center_focus_strong" . "\xe3b4")
|
||||||
|
("center_focus_weak" . "\xe3b5")
|
||||||
|
("change_history" . "\xe86b")
|
||||||
|
("chat" . "\xe0b7")
|
||||||
|
("chat_bubble" . "\xe0ca")
|
||||||
|
("chat_bubble_outline" . "\xe0cb")
|
||||||
|
("check" . "\xe5ca")
|
||||||
|
("check_box" . "\xe834")
|
||||||
|
("check_box_outline_blank" . "\xe835")
|
||||||
|
("check_circle" . "\xe86c")
|
||||||
|
("chevron_left" . "\xe5cb")
|
||||||
|
("chevron_right" . "\xe5cc")
|
||||||
|
("child_care" . "\xeb41")
|
||||||
|
("child_friendly" . "\xeb42")
|
||||||
|
("chrome_reader_mode" . "\xe86d")
|
||||||
|
("class" . "\xe86e")
|
||||||
|
("clear" . "\xe14c")
|
||||||
|
("clear_all" . "\xe0b8")
|
||||||
|
("close" . "\xe5cd")
|
||||||
|
("closed_caption" . "\xe01c")
|
||||||
|
("cloud" . "\xe2bd")
|
||||||
|
("cloud_circle" . "\xe2be")
|
||||||
|
("cloud_done" . "\xe2bf")
|
||||||
|
("cloud_download" . "\xe2c0")
|
||||||
|
("cloud_off" . "\xe2c1")
|
||||||
|
("cloud_queue" . "\xe2c2")
|
||||||
|
("cloud_upload" . "\xe2c3")
|
||||||
|
("code" . "\xe86f")
|
||||||
|
("collections" . "\xe3b6")
|
||||||
|
("collections_bookmark" . "\xe431")
|
||||||
|
("color_lens" . "\xe3b7")
|
||||||
|
("colorize" . "\xe3b8")
|
||||||
|
("comment" . "\xe0b9")
|
||||||
|
("compare" . "\xe3b9")
|
||||||
|
("compare_arrows" . "\xe915")
|
||||||
|
("computer" . "\xe30a")
|
||||||
|
("confirmation_number" . "\xe638")
|
||||||
|
("contact_mail" . "\xe0d0")
|
||||||
|
("contact_phone" . "\xe0cf")
|
||||||
|
("contacts" . "\xe0ba")
|
||||||
|
("content_copy" . "\xe14d")
|
||||||
|
("content_cut" . "\xe14e")
|
||||||
|
("content_paste" . "\xe14f")
|
||||||
|
("control_point" . "\xe3ba")
|
||||||
|
("control_point_duplicate" . "\xe3bb")
|
||||||
|
("copyright" . "\xe90c")
|
||||||
|
("create" . "\xe150")
|
||||||
|
("create_new_folder" . "\xe2cc")
|
||||||
|
("credit_card" . "\xe870")
|
||||||
|
("crop" . "\xe3be")
|
||||||
|
("crop_16_9" . "\xe3bc")
|
||||||
|
("crop_3_2" . "\xe3bd")
|
||||||
|
("crop_5_4" . "\xe3bf")
|
||||||
|
("crop_7_5" . "\xe3c0")
|
||||||
|
("crop_din" . "\xe3c1")
|
||||||
|
("crop_free" . "\xe3c2")
|
||||||
|
("crop_landscape" . "\xe3c3")
|
||||||
|
("crop_original" . "\xe3c4")
|
||||||
|
("crop_portrait" . "\xe3c5")
|
||||||
|
("crop_rotate" . "\xe437")
|
||||||
|
("crop_square" . "\xe3c6")
|
||||||
|
("dashboard" . "\xe871")
|
||||||
|
("data_usage" . "\xe1af")
|
||||||
|
("date_range" . "\xe916")
|
||||||
|
("dehaze" . "\xe3c7")
|
||||||
|
("delete" . "\xe872")
|
||||||
|
("delete_forever" . "\xe92b")
|
||||||
|
("delete_sweep" . "\xe16c")
|
||||||
|
("description" . "\xe873")
|
||||||
|
("desktop_mac" . "\xe30b")
|
||||||
|
("desktop_windows" . "\xe30c")
|
||||||
|
("details" . "\xe3c8")
|
||||||
|
("developer_board" . "\xe30d")
|
||||||
|
("developer_mode" . "\xe1b0")
|
||||||
|
("device_hub" . "\xe335")
|
||||||
|
("devices" . "\xe1b1")
|
||||||
|
("devices_other" . "\xe337")
|
||||||
|
("dialer_sip" . "\xe0bb")
|
||||||
|
("dialpad" . "\xe0bc")
|
||||||
|
("directions" . "\xe52e")
|
||||||
|
("directions_bike" . "\xe52f")
|
||||||
|
("directions_boat" . "\xe532")
|
||||||
|
("directions_bus" . "\xe530")
|
||||||
|
("directions_car" . "\xe531")
|
||||||
|
("directions_railway" . "\xe534")
|
||||||
|
("directions_run" . "\xe566")
|
||||||
|
("directions_subway" . "\xe533")
|
||||||
|
("directions_transit" . "\xe535")
|
||||||
|
("directions_walk" . "\xe536")
|
||||||
|
("disc_full" . "\xe610")
|
||||||
|
("dns" . "\xe875")
|
||||||
|
("do_not_disturb" . "\xe612")
|
||||||
|
("do_not_disturb_alt" . "\xe611")
|
||||||
|
("do_not_disturb_off" . "\xe643")
|
||||||
|
("do_not_disturb_on" . "\xe644")
|
||||||
|
("dock" . "\xe30e")
|
||||||
|
("domain" . "\xe7ee")
|
||||||
|
("done" . "\xe876")
|
||||||
|
("done_all" . "\xe877")
|
||||||
|
("donut_large" . "\xe917")
|
||||||
|
("donut_small" . "\xe918")
|
||||||
|
("drafts" . "\xe151")
|
||||||
|
("drag_handle" . "\xe25d")
|
||||||
|
("drive_eta" . "\xe613")
|
||||||
|
("dvr" . "\xe1b2")
|
||||||
|
("edit" . "\xe3c9")
|
||||||
|
("edit_location" . "\xe568")
|
||||||
|
("eject" . "\xe8fb")
|
||||||
|
("email" . "\xe0be")
|
||||||
|
("enhanced_encryption" . "\xe63f")
|
||||||
|
("equalizer" . "\xe01d")
|
||||||
|
("error" . "\xe000")
|
||||||
|
("error_outline" . "\xe001")
|
||||||
|
("euro_symbol" . "\xe926")
|
||||||
|
("ev_station" . "\xe56d")
|
||||||
|
("event" . "\xe878")
|
||||||
|
("event_available" . "\xe614")
|
||||||
|
("event_busy" . "\xe615")
|
||||||
|
("event_note" . "\xe616")
|
||||||
|
("event_seat" . "\xe903")
|
||||||
|
("exit_to_app" . "\xe879")
|
||||||
|
("expand_less" . "\xe5ce")
|
||||||
|
("expand_more" . "\xe5cf")
|
||||||
|
("explicit" . "\xe01e")
|
||||||
|
("explore" . "\xe87a")
|
||||||
|
("exposure" . "\xe3ca")
|
||||||
|
("exposure_neg_1" . "\xe3cb")
|
||||||
|
("exposure_neg_2" . "\xe3cc")
|
||||||
|
("exposure_plus_1" . "\xe3cd")
|
||||||
|
("exposure_plus_2" . "\xe3ce")
|
||||||
|
("exposure_zero" . "\xe3cf")
|
||||||
|
("extension" . "\xe87b")
|
||||||
|
("face" . "\xe87c")
|
||||||
|
("fast_forward" . "\xe01f")
|
||||||
|
("fast_rewind" . "\xe020")
|
||||||
|
("favorite" . "\xe87d")
|
||||||
|
("favorite_border" . "\xe87e")
|
||||||
|
("featured_play_list" . "\xe06d")
|
||||||
|
("featured_video" . "\xe06e")
|
||||||
|
("feedback" . "\xe87f")
|
||||||
|
("fiber_dvr" . "\xe05d")
|
||||||
|
("fiber_manual_record" . "\xe061")
|
||||||
|
("fiber_new" . "\xe05e")
|
||||||
|
("fiber_pin" . "\xe06a")
|
||||||
|
("fiber_smart_record" . "\xe062")
|
||||||
|
("file_download" . "\xe2c4")
|
||||||
|
("file_upload" . "\xe2c6")
|
||||||
|
("filter" . "\xe3d3")
|
||||||
|
("filter_1" . "\xe3d0")
|
||||||
|
("filter_2" . "\xe3d1")
|
||||||
|
("filter_3" . "\xe3d2")
|
||||||
|
("filter_4" . "\xe3d4")
|
||||||
|
("filter_5" . "\xe3d5")
|
||||||
|
("filter_6" . "\xe3d6")
|
||||||
|
("filter_7" . "\xe3d7")
|
||||||
|
("filter_8" . "\xe3d8")
|
||||||
|
("filter_9" . "\xe3d9")
|
||||||
|
("filter_9_plus" . "\xe3da")
|
||||||
|
("filter_b_and_w" . "\xe3db")
|
||||||
|
("filter_center_focus" . "\xe3dc")
|
||||||
|
("filter_drama" . "\xe3dd")
|
||||||
|
("filter_frames" . "\xe3de")
|
||||||
|
("filter_hdr" . "\xe3df")
|
||||||
|
("filter_list" . "\xe152")
|
||||||
|
("filter_none" . "\xe3e0")
|
||||||
|
("filter_tilt_shift" . "\xe3e2")
|
||||||
|
("filter_vintage" . "\xe3e3")
|
||||||
|
("find_in_page" . "\xe880")
|
||||||
|
("find_replace" . "\xe881")
|
||||||
|
("fingerprint" . "\xe90d")
|
||||||
|
("first_page" . "\xe5dc")
|
||||||
|
("fitness_center" . "\xeb43")
|
||||||
|
("flag" . "\xe153")
|
||||||
|
("flare" . "\xe3e4")
|
||||||
|
("flash_auto" . "\xe3e5")
|
||||||
|
("flash_off" . "\xe3e6")
|
||||||
|
("flash_on" . "\xe3e7")
|
||||||
|
("flight" . "\xe539")
|
||||||
|
("flight_land" . "\xe904")
|
||||||
|
("flight_takeoff" . "\xe905")
|
||||||
|
("flip" . "\xe3e8")
|
||||||
|
("flip_to_back" . "\xe882")
|
||||||
|
("flip_to_front" . "\xe883")
|
||||||
|
("folder" . "\xe2c7")
|
||||||
|
("folder_open" . "\xe2c8")
|
||||||
|
("folder_shared" . "\xe2c9")
|
||||||
|
("folder_special" . "\xe617")
|
||||||
|
("font_download" . "\xe167")
|
||||||
|
("format_align_center" . "\xe234")
|
||||||
|
("format_align_justify" . "\xe235")
|
||||||
|
("format_align_left" . "\xe236")
|
||||||
|
("format_align_right" . "\xe237")
|
||||||
|
("format_bold" . "\xe238")
|
||||||
|
("format_clear" . "\xe239")
|
||||||
|
("format_color_fill" . "\xe23a")
|
||||||
|
("format_color_reset" . "\xe23b")
|
||||||
|
("format_color_text" . "\xe23c")
|
||||||
|
("format_indent_decrease" . "\xe23d")
|
||||||
|
("format_indent_increase" . "\xe23e")
|
||||||
|
("format_italic" . "\xe23f")
|
||||||
|
("format_line_spacing" . "\xe240")
|
||||||
|
("format_list_bulleted" . "\xe241")
|
||||||
|
("format_list_numbered" . "\xe242")
|
||||||
|
("format_paint" . "\xe243")
|
||||||
|
("format_quote" . "\xe244")
|
||||||
|
("format_shapes" . "\xe25e")
|
||||||
|
("format_size" . "\xe245")
|
||||||
|
("format_strikethrough" . "\xe246")
|
||||||
|
("format_textdirection_l_to_r" . "\xe247")
|
||||||
|
("format_textdirection_r_to_l" . "\xe248")
|
||||||
|
("format_underlined" . "\xe249")
|
||||||
|
("forum" . "\xe0bf")
|
||||||
|
("forward" . "\xe154")
|
||||||
|
("forward_10" . "\xe056")
|
||||||
|
("forward_30" . "\xe057")
|
||||||
|
("forward_5" . "\xe058")
|
||||||
|
("free_breakfast" . "\xeb44")
|
||||||
|
("fullscreen" . "\xe5d0")
|
||||||
|
("fullscreen_exit" . "\xe5d1")
|
||||||
|
("functions" . "\xe24a")
|
||||||
|
("g_translate" . "\xe927")
|
||||||
|
("gamepad" . "\xe30f")
|
||||||
|
("games" . "\xe021")
|
||||||
|
("gavel" . "\xe90e")
|
||||||
|
("gesture" . "\xe155")
|
||||||
|
("get_app" . "\xe884")
|
||||||
|
("gif" . "\xe908")
|
||||||
|
("golf_course" . "\xeb45")
|
||||||
|
("gps_fixed" . "\xe1b3")
|
||||||
|
("gps_not_fixed" . "\xe1b4")
|
||||||
|
("gps_off" . "\xe1b5")
|
||||||
|
("grade" . "\xe885")
|
||||||
|
("gradient" . "\xe3e9")
|
||||||
|
("grain" . "\xe3ea")
|
||||||
|
("graphic_eq" . "\xe1b8")
|
||||||
|
("grid_off" . "\xe3eb")
|
||||||
|
("grid_on" . "\xe3ec")
|
||||||
|
("group" . "\xe7ef")
|
||||||
|
("group_add" . "\xe7f0")
|
||||||
|
("group_work" . "\xe886")
|
||||||
|
("hd" . "\xe052")
|
||||||
|
("hdr_off" . "\xe3ed")
|
||||||
|
("hdr_on" . "\xe3ee")
|
||||||
|
("hdr_strong" . "\xe3f1")
|
||||||
|
("hdr_weak" . "\xe3f2")
|
||||||
|
("headset" . "\xe310")
|
||||||
|
("headset_mic" . "\xe311")
|
||||||
|
("healing" . "\xe3f3")
|
||||||
|
("hearing" . "\xe023")
|
||||||
|
("help" . "\xe887")
|
||||||
|
("help_outline" . "\xe8fd")
|
||||||
|
("high_quality" . "\xe024")
|
||||||
|
("highlight" . "\xe25f")
|
||||||
|
("highlight_off" . "\xe888")
|
||||||
|
("history" . "\xe889")
|
||||||
|
("home" . "\xe88a")
|
||||||
|
("hot_tub" . "\xeb46")
|
||||||
|
("hotel" . "\xe53a")
|
||||||
|
("hourglass_empty" . "\xe88b")
|
||||||
|
("hourglass_full" . "\xe88c")
|
||||||
|
("http" . "\xe902")
|
||||||
|
("https" . "\xe88d")
|
||||||
|
("image" . "\xe3f4")
|
||||||
|
("image_aspect_ratio" . "\xe3f5")
|
||||||
|
("import_contacts" . "\xe0e0")
|
||||||
|
("import_export" . "\xe0c3")
|
||||||
|
("important_devices" . "\xe912")
|
||||||
|
("inbox" . "\xe156")
|
||||||
|
("indeterminate_check_box" . "\xe909")
|
||||||
|
("info" . "\xe88e")
|
||||||
|
("info_outline" . "\xe88f")
|
||||||
|
("input" . "\xe890")
|
||||||
|
("insert_chart" . "\xe24b")
|
||||||
|
("insert_comment" . "\xe24c")
|
||||||
|
("insert_drive_file" . "\xe24d")
|
||||||
|
("insert_emoticon" . "\xe24e")
|
||||||
|
("insert_invitation" . "\xe24f")
|
||||||
|
("insert_link" . "\xe250")
|
||||||
|
("insert_photo" . "\xe251")
|
||||||
|
("invert_colors" . "\xe891")
|
||||||
|
("invert_colors_off" . "\xe0c4")
|
||||||
|
("iso" . "\xe3f6")
|
||||||
|
("keyboard" . "\xe312")
|
||||||
|
("keyboard_arrow_down" . "\xe313")
|
||||||
|
("keyboard_arrow_left" . "\xe314")
|
||||||
|
("keyboard_arrow_right" . "\xe315")
|
||||||
|
("keyboard_arrow_up" . "\xe316")
|
||||||
|
("keyboard_backspace" . "\xe317")
|
||||||
|
("keyboard_capslock" . "\xe318")
|
||||||
|
("keyboard_hide" . "\xe31a")
|
||||||
|
("keyboard_return" . "\xe31b")
|
||||||
|
("keyboard_tab" . "\xe31c")
|
||||||
|
("keyboard_voice" . "\xe31d")
|
||||||
|
("kitchen" . "\xeb47")
|
||||||
|
("label" . "\xe892")
|
||||||
|
("label_outline" . "\xe893")
|
||||||
|
("landscape" . "\xe3f7")
|
||||||
|
("language" . "\xe894")
|
||||||
|
("laptop" . "\xe31e")
|
||||||
|
("laptop_chromebook" . "\xe31f")
|
||||||
|
("laptop_mac" . "\xe320")
|
||||||
|
("laptop_windows" . "\xe321")
|
||||||
|
("last_page" . "\xe5dd")
|
||||||
|
("launch" . "\xe895")
|
||||||
|
("layers" . "\xe53b")
|
||||||
|
("layers_clear" . "\xe53c")
|
||||||
|
("leak_add" . "\xe3f8")
|
||||||
|
("leak_remove" . "\xe3f9")
|
||||||
|
("lens" . "\xe3fa")
|
||||||
|
("library_add" . "\xe02e")
|
||||||
|
("library_books" . "\xe02f")
|
||||||
|
("library_music" . "\xe030")
|
||||||
|
("lightbulb_outline" . "\xe90f")
|
||||||
|
("line_style" . "\xe919")
|
||||||
|
("line_weight" . "\xe91a")
|
||||||
|
("linear_scale" . "\xe260")
|
||||||
|
("link" . "\xe157")
|
||||||
|
("linked_camera" . "\xe438")
|
||||||
|
("list" . "\xe896")
|
||||||
|
("live_help" . "\xe0c6")
|
||||||
|
("live_tv" . "\xe639")
|
||||||
|
("local_activity" . "\xe53f")
|
||||||
|
("local_airport" . "\xe53d")
|
||||||
|
("local_atm" . "\xe53e")
|
||||||
|
("local_bar" . "\xe540")
|
||||||
|
("local_cafe" . "\xe541")
|
||||||
|
("local_car_wash" . "\xe542")
|
||||||
|
("local_convenience_store" . "\xe543")
|
||||||
|
("local_dining" . "\xe556")
|
||||||
|
("local_drink" . "\xe544")
|
||||||
|
("local_florist" . "\xe545")
|
||||||
|
("local_gas_station" . "\xe546")
|
||||||
|
("local_grocery_store" . "\xe547")
|
||||||
|
("local_hospital" . "\xe548")
|
||||||
|
("local_hotel" . "\xe549")
|
||||||
|
("local_laundry_service" . "\xe54a")
|
||||||
|
("local_library" . "\xe54b")
|
||||||
|
("local_mall" . "\xe54c")
|
||||||
|
("local_movies" . "\xe54d")
|
||||||
|
("local_offer" . "\xe54e")
|
||||||
|
("local_parking" . "\xe54f")
|
||||||
|
("local_pharmacy" . "\xe550")
|
||||||
|
("local_phone" . "\xe551")
|
||||||
|
("local_pizza" . "\xe552")
|
||||||
|
("local_play" . "\xe553")
|
||||||
|
("local_post_office" . "\xe554")
|
||||||
|
("local_printshop" . "\xe555")
|
||||||
|
("local_see" . "\xe557")
|
||||||
|
("local_shipping" . "\xe558")
|
||||||
|
("local_taxi" . "\xe559")
|
||||||
|
("location_city" . "\xe7f1")
|
||||||
|
("location_disabled" . "\xe1b6")
|
||||||
|
("location_off" . "\xe0c7")
|
||||||
|
("location_on" . "\xe0c8")
|
||||||
|
("location_searching" . "\xe1b7")
|
||||||
|
("lock" . "\xe897")
|
||||||
|
("lock_open" . "\xe898")
|
||||||
|
("lock_outline" . "\xe899")
|
||||||
|
("looks" . "\xe3fc")
|
||||||
|
("looks_3" . "\xe3fb")
|
||||||
|
("looks_4" . "\xe3fd")
|
||||||
|
("looks_5" . "\xe3fe")
|
||||||
|
("looks_6" . "\xe3ff")
|
||||||
|
("looks_one" . "\xe400")
|
||||||
|
("looks_two" . "\xe401")
|
||||||
|
("loop" . "\xe028")
|
||||||
|
("loupe" . "\xe402")
|
||||||
|
("low_priority" . "\xe16d")
|
||||||
|
("loyalty" . "\xe89a")
|
||||||
|
("mail" . "\xe158")
|
||||||
|
("mail_outline" . "\xe0e1")
|
||||||
|
("map" . "\xe55b")
|
||||||
|
("markunread" . "\xe159")
|
||||||
|
("markunread_mailbox" . "\xe89b")
|
||||||
|
("memory" . "\xe322")
|
||||||
|
("menu" . "\xe5d2")
|
||||||
|
("merge_type" . "\xe252")
|
||||||
|
("message" . "\xe0c9")
|
||||||
|
("mic" . "\xe029")
|
||||||
|
("mic_none" . "\xe02a")
|
||||||
|
("mic_off" . "\xe02b")
|
||||||
|
("mms" . "\xe618")
|
||||||
|
("mode_comment" . "\xe253")
|
||||||
|
("mode_edit" . "\xe254")
|
||||||
|
("monetization_on" . "\xe263")
|
||||||
|
("money_off" . "\xe25c")
|
||||||
|
("monochrome_photos" . "\xe403")
|
||||||
|
("mood" . "\xe7f2")
|
||||||
|
("mood_bad" . "\xe7f3")
|
||||||
|
("more" . "\xe619")
|
||||||
|
("more_horiz" . "\xe5d3")
|
||||||
|
("more_vert" . "\xe5d4")
|
||||||
|
("motorcycle" . "\xe91b")
|
||||||
|
("mouse" . "\xe323")
|
||||||
|
("move_to_inbox" . "\xe168")
|
||||||
|
("movie" . "\xe02c")
|
||||||
|
("movie_creation" . "\xe404")
|
||||||
|
("movie_filter" . "\xe43a")
|
||||||
|
("multiline_chart" . "\xe6df")
|
||||||
|
("music_note" . "\xe405")
|
||||||
|
("music_video" . "\xe063")
|
||||||
|
("my_location" . "\xe55c")
|
||||||
|
("nature" . "\xe406")
|
||||||
|
("nature_people" . "\xe407")
|
||||||
|
("navigate_before" . "\xe408")
|
||||||
|
("navigate_next" . "\xe409")
|
||||||
|
("navigation" . "\xe55d")
|
||||||
|
("near_me" . "\xe569")
|
||||||
|
("network_cell" . "\xe1b9")
|
||||||
|
("network_check" . "\xe640")
|
||||||
|
("network_locked" . "\xe61a")
|
||||||
|
("network_wifi" . "\xe1ba")
|
||||||
|
("new_releases" . "\xe031")
|
||||||
|
("next_week" . "\xe16a")
|
||||||
|
("nfc" . "\xe1bb")
|
||||||
|
("no_encryption" . "\xe641")
|
||||||
|
("no_sim" . "\xe0cc")
|
||||||
|
("not_interested" . "\xe033")
|
||||||
|
("note" . "\xe06f")
|
||||||
|
("note_add" . "\xe89c")
|
||||||
|
("notifications" . "\xe7f4")
|
||||||
|
("notifications_active" . "\xe7f7")
|
||||||
|
("notifications_none" . "\xe7f5")
|
||||||
|
("notifications_off" . "\xe7f6")
|
||||||
|
("notifications_paused" . "\xe7f8")
|
||||||
|
("offline_pin" . "\xe90a")
|
||||||
|
("ondemand_video" . "\xe63a")
|
||||||
|
("opacity" . "\xe91c")
|
||||||
|
("open_in_browser" . "\xe89d")
|
||||||
|
("open_in_new" . "\xe89e")
|
||||||
|
("open_with" . "\xe89f")
|
||||||
|
("pages" . "\xe7f9")
|
||||||
|
("pageview" . "\xe8a0")
|
||||||
|
("palette" . "\xe40a")
|
||||||
|
("pan_tool" . "\xe925")
|
||||||
|
("panorama" . "\xe40b")
|
||||||
|
("panorama_fish_eye" . "\xe40c")
|
||||||
|
("panorama_horizontal" . "\xe40d")
|
||||||
|
("panorama_vertical" . "\xe40e")
|
||||||
|
("panorama_wide_angle" . "\xe40f")
|
||||||
|
("party_mode" . "\xe7fa")
|
||||||
|
("pause" . "\xe034")
|
||||||
|
("pause_circle_filled" . "\xe035")
|
||||||
|
("pause_circle_outline" . "\xe036")
|
||||||
|
("payment" . "\xe8a1")
|
||||||
|
("people" . "\xe7fb")
|
||||||
|
("people_outline" . "\xe7fc")
|
||||||
|
("perm_camera_mic" . "\xe8a2")
|
||||||
|
("perm_contact_calendar" . "\xe8a3")
|
||||||
|
("perm_data_setting" . "\xe8a4")
|
||||||
|
("perm_device_information" . "\xe8a5")
|
||||||
|
("perm_identity" . "\xe8a6")
|
||||||
|
("perm_media" . "\xe8a7")
|
||||||
|
("perm_phone_msg" . "\xe8a8")
|
||||||
|
("perm_scan_wifi" . "\xe8a9")
|
||||||
|
("person" . "\xe7fd")
|
||||||
|
("person_add" . "\xe7fe")
|
||||||
|
("person_outline" . "\xe7ff")
|
||||||
|
("person_pin" . "\xe55a")
|
||||||
|
("person_pin_circle" . "\xe56a")
|
||||||
|
("personal_video" . "\xe63b")
|
||||||
|
("pets" . "\xe91d")
|
||||||
|
("phone" . "\xe0cd")
|
||||||
|
("phone_android" . "\xe324")
|
||||||
|
("phone_bluetooth_speaker" . "\xe61b")
|
||||||
|
("phone_forwarded" . "\xe61c")
|
||||||
|
("phone_in_talk" . "\xe61d")
|
||||||
|
("phone_iphone" . "\xe325")
|
||||||
|
("phone_locked" . "\xe61e")
|
||||||
|
("phone_missed" . "\xe61f")
|
||||||
|
("phone_paused" . "\xe620")
|
||||||
|
("phonelink" . "\xe326")
|
||||||
|
("phonelink_erase" . "\xe0db")
|
||||||
|
("phonelink_lock" . "\xe0dc")
|
||||||
|
("phonelink_off" . "\xe327")
|
||||||
|
("phonelink_ring" . "\xe0dd")
|
||||||
|
("phonelink_setup" . "\xe0de")
|
||||||
|
("photo" . "\xe410")
|
||||||
|
("photo_album" . "\xe411")
|
||||||
|
("photo_camera" . "\xe412")
|
||||||
|
("photo_filter" . "\xe43b")
|
||||||
|
("photo_library" . "\xe413")
|
||||||
|
("photo_size_select_actual" . "\xe432")
|
||||||
|
("photo_size_select_large" . "\xe433")
|
||||||
|
("photo_size_select_small" . "\xe434")
|
||||||
|
("picture_as_pdf" . "\xe415")
|
||||||
|
("picture_in_picture" . "\xe8aa")
|
||||||
|
("picture_in_picture_alt" . "\xe911")
|
||||||
|
("pie_chart" . "\xe6c4")
|
||||||
|
("pie_chart_outlined" . "\xe6c5")
|
||||||
|
("pin_drop" . "\xe55e")
|
||||||
|
("place" . "\xe55f")
|
||||||
|
("play_arrow" . "\xe037")
|
||||||
|
("play_circle_filled" . "\xe038")
|
||||||
|
("play_circle_outline" . "\xe039")
|
||||||
|
("play_for_work" . "\xe906")
|
||||||
|
("playlist_add" . "\xe03b")
|
||||||
|
("playlist_add_check" . "\xe065")
|
||||||
|
("playlist_play" . "\xe05f")
|
||||||
|
("plus_one" . "\xe800")
|
||||||
|
("poll" . "\xe801")
|
||||||
|
("polymer" . "\xe8ab")
|
||||||
|
("pool" . "\xeb48")
|
||||||
|
("portable_wifi_off" . "\xe0ce")
|
||||||
|
("portrait" . "\xe416")
|
||||||
|
("power" . "\xe63c")
|
||||||
|
("power_input" . "\xe336")
|
||||||
|
("power_settings_new" . "\xe8ac")
|
||||||
|
("pregnant_woman" . "\xe91e")
|
||||||
|
("present_to_all" . "\xe0df")
|
||||||
|
("print" . "\xe8ad")
|
||||||
|
("priority_high" . "\xe645")
|
||||||
|
("public" . "\xe80b")
|
||||||
|
("publish" . "\xe255")
|
||||||
|
("query_builder" . "\xe8ae")
|
||||||
|
("question_answer" . "\xe8af")
|
||||||
|
("queue" . "\xe03c")
|
||||||
|
("queue_music" . "\xe03d")
|
||||||
|
("queue_play_next" . "\xe066")
|
||||||
|
("radio" . "\xe03e")
|
||||||
|
("radio_button_checked" . "\xe837")
|
||||||
|
("radio_button_unchecked" . "\xe836")
|
||||||
|
("rate_review" . "\xe560")
|
||||||
|
("receipt" . "\xe8b0")
|
||||||
|
("recent_actors" . "\xe03f")
|
||||||
|
("record_voice_over" . "\xe91f")
|
||||||
|
("redeem" . "\xe8b1")
|
||||||
|
("redo" . "\xe15a")
|
||||||
|
("refresh" . "\xe5d5")
|
||||||
|
("remove" . "\xe15b")
|
||||||
|
("remove_circle" . "\xe15c")
|
||||||
|
("remove_circle_outline" . "\xe15d")
|
||||||
|
("remove_from_queue" . "\xe067")
|
||||||
|
("remove_red_eye" . "\xe417")
|
||||||
|
("remove_shopping_cart" . "\xe928")
|
||||||
|
("reorder" . "\xe8fe")
|
||||||
|
("repeat" . "\xe040")
|
||||||
|
("repeat_one" . "\xe041")
|
||||||
|
("replay" . "\xe042")
|
||||||
|
("replay_10" . "\xe059")
|
||||||
|
("replay_30" . "\xe05a")
|
||||||
|
("replay_5" . "\xe05b")
|
||||||
|
("reply" . "\xe15e")
|
||||||
|
("reply_all" . "\xe15f")
|
||||||
|
("report" . "\xe160")
|
||||||
|
("report_problem" . "\xe8b2")
|
||||||
|
("restaurant" . "\xe56c")
|
||||||
|
("restaurant_menu" . "\xe561")
|
||||||
|
("restore" . "\xe8b3")
|
||||||
|
("restore_page" . "\xe929")
|
||||||
|
("ring_volume" . "\xe0d1")
|
||||||
|
("room" . "\xe8b4")
|
||||||
|
("room_service" . "\xeb49")
|
||||||
|
("rotate_90_degrees_ccw" . "\xe418")
|
||||||
|
("rotate_left" . "\xe419")
|
||||||
|
("rotate_right" . "\xe41a")
|
||||||
|
("rounded_corner" . "\xe920")
|
||||||
|
("router" . "\xe328")
|
||||||
|
("rowing" . "\xe921")
|
||||||
|
("rss_feed" . "\xe0e5")
|
||||||
|
("rv_hookup" . "\xe642")
|
||||||
|
("satellite" . "\xe562")
|
||||||
|
("save" . "\xe161")
|
||||||
|
("scanner" . "\xe329")
|
||||||
|
("schedule" . "\xe8b5")
|
||||||
|
("school" . "\xe80c")
|
||||||
|
("screen_lock_landscape" . "\xe1be")
|
||||||
|
("screen_lock_portrait" . "\xe1bf")
|
||||||
|
("screen_lock_rotation" . "\xe1c0")
|
||||||
|
("screen_rotation" . "\xe1c1")
|
||||||
|
("screen_share" . "\xe0e2")
|
||||||
|
("sd_card" . "\xe623")
|
||||||
|
("sd_storage" . "\xe1c2")
|
||||||
|
("search" . "\xe8b6")
|
||||||
|
("security" . "\xe32a")
|
||||||
|
("select_all" . "\xe162")
|
||||||
|
("send" . "\xe163")
|
||||||
|
("sentiment_dissatisfied" . "\xe811")
|
||||||
|
("sentiment_neutral" . "\xe812")
|
||||||
|
("sentiment_satisfied" . "\xe813")
|
||||||
|
("sentiment_very_dissatisfied" . "\xe814")
|
||||||
|
("sentiment_very_satisfied" . "\xe815")
|
||||||
|
("settings" . "\xe8b8")
|
||||||
|
("settings_applications" . "\xe8b9")
|
||||||
|
("settings_backup_restore" . "\xe8ba")
|
||||||
|
("settings_bluetooth" . "\xe8bb")
|
||||||
|
("settings_brightness" . "\xe8bd")
|
||||||
|
("settings_cell" . "\xe8bc")
|
||||||
|
("settings_ethernet" . "\xe8be")
|
||||||
|
("settings_input_antenna" . "\xe8bf")
|
||||||
|
("settings_input_component" . "\xe8c0")
|
||||||
|
("settings_input_composite" . "\xe8c1")
|
||||||
|
("settings_input_hdmi" . "\xe8c2")
|
||||||
|
("settings_input_svideo" . "\xe8c3")
|
||||||
|
("settings_overscan" . "\xe8c4")
|
||||||
|
("settings_phone" . "\xe8c5")
|
||||||
|
("settings_power" . "\xe8c6")
|
||||||
|
("settings_remote" . "\xe8c7")
|
||||||
|
("settings_system_daydream" . "\xe1c3")
|
||||||
|
("settings_voice" . "\xe8c8")
|
||||||
|
("share" . "\xe80d")
|
||||||
|
("shop" . "\xe8c9")
|
||||||
|
("shop_two" . "\xe8ca")
|
||||||
|
("shopping_basket" . "\xe8cb")
|
||||||
|
("shopping_cart" . "\xe8cc")
|
||||||
|
("short_text" . "\xe261")
|
||||||
|
("show_chart" . "\xe6e1")
|
||||||
|
("shuffle" . "\xe043")
|
||||||
|
("signal_cellular_4_bar" . "\xe1c8")
|
||||||
|
("signal_cellular_connected_no_internet_4_bar" . "\xe1cd")
|
||||||
|
("signal_cellular_no_sim" . "\xe1ce")
|
||||||
|
("signal_cellular_null" . "\xe1cf")
|
||||||
|
("signal_cellular_off" . "\xe1d0")
|
||||||
|
("signal_wifi_4_bar" . "\xe1d8")
|
||||||
|
("signal_wifi_4_bar_lock" . "\xe1d9")
|
||||||
|
("signal_wifi_off" . "\xe1da")
|
||||||
|
("sim_card" . "\xe32b")
|
||||||
|
("sim_card_alert" . "\xe624")
|
||||||
|
("skip_next" . "\xe044")
|
||||||
|
("skip_previous" . "\xe045")
|
||||||
|
("slideshow" . "\xe41b")
|
||||||
|
("slow_motion_video" . "\xe068")
|
||||||
|
("smartphone" . "\xe32c")
|
||||||
|
("smoke_free" . "\xeb4a")
|
||||||
|
("smoking_rooms" . "\xeb4b")
|
||||||
|
("sms" . "\xe625")
|
||||||
|
("sms_failed" . "\xe626")
|
||||||
|
("snooze" . "\xe046")
|
||||||
|
("sort" . "\xe164")
|
||||||
|
("sort_by_alpha" . "\xe053")
|
||||||
|
("spa" . "\xeb4c")
|
||||||
|
("space_bar" . "\xe256")
|
||||||
|
("speaker" . "\xe32d")
|
||||||
|
("speaker_group" . "\xe32e")
|
||||||
|
("speaker_notes" . "\xe8cd")
|
||||||
|
("speaker_notes_off" . "\xe92a")
|
||||||
|
("speaker_phone" . "\xe0d2")
|
||||||
|
("spellcheck" . "\xe8ce")
|
||||||
|
("star" . "\xe838")
|
||||||
|
("star_border" . "\xe83a")
|
||||||
|
("star_half" . "\xe839")
|
||||||
|
("stars" . "\xe8d0")
|
||||||
|
("stay_current_landscape" . "\xe0d3")
|
||||||
|
("stay_current_portrait" . "\xe0d4")
|
||||||
|
("stay_primary_landscape" . "\xe0d5")
|
||||||
|
("stay_primary_portrait" . "\xe0d6")
|
||||||
|
("stop" . "\xe047")
|
||||||
|
("stop_screen_share" . "\xe0e3")
|
||||||
|
("storage" . "\xe1db")
|
||||||
|
("store" . "\xe8d1")
|
||||||
|
("store_mall_directory" . "\xe563")
|
||||||
|
("straighten" . "\xe41c")
|
||||||
|
("streetview" . "\xe56e")
|
||||||
|
("strikethrough_s" . "\xe257")
|
||||||
|
("style" . "\xe41d")
|
||||||
|
("subdirectory_arrow_left" . "\xe5d9")
|
||||||
|
("subdirectory_arrow_right" . "\xe5da")
|
||||||
|
("subject" . "\xe8d2")
|
||||||
|
("subscriptions" . "\xe064")
|
||||||
|
("subtitles" . "\xe048")
|
||||||
|
("subway" . "\xe56f")
|
||||||
|
("supervisor_account" . "\xe8d3")
|
||||||
|
("surround_sound" . "\xe049")
|
||||||
|
("swap_calls" . "\xe0d7")
|
||||||
|
("swap_horiz" . "\xe8d4")
|
||||||
|
("swap_vert" . "\xe8d5")
|
||||||
|
("swap_vertical_circle" . "\xe8d6")
|
||||||
|
("switch_camera" . "\xe41e")
|
||||||
|
("switch_video" . "\xe41f")
|
||||||
|
("sync" . "\xe627")
|
||||||
|
("sync_disabled" . "\xe628")
|
||||||
|
("sync_problem" . "\xe629")
|
||||||
|
("system_update" . "\xe62a")
|
||||||
|
("system_update_alt" . "\xe8d7")
|
||||||
|
("tab" . "\xe8d8")
|
||||||
|
("tab_unselected" . "\xe8d9")
|
||||||
|
("tablet" . "\xe32f")
|
||||||
|
("tablet_android" . "\xe330")
|
||||||
|
("tablet_mac" . "\xe331")
|
||||||
|
("tag_faces" . "\xe420")
|
||||||
|
("tap_and_play" . "\xe62b")
|
||||||
|
("terrain" . "\xe564")
|
||||||
|
("text_fields" . "\xe262")
|
||||||
|
("text_format" . "\xe165")
|
||||||
|
("textsms" . "\xe0d8")
|
||||||
|
("texture" . "\xe421")
|
||||||
|
("theaters" . "\xe8da")
|
||||||
|
("thumb_down" . "\xe8db")
|
||||||
|
("thumb_up" . "\xe8dc")
|
||||||
|
("thumbs_up_down" . "\xe8dd")
|
||||||
|
("time_to_leave" . "\xe62c")
|
||||||
|
("timelapse" . "\xe422")
|
||||||
|
("timeline" . "\xe922")
|
||||||
|
("timer" . "\xe425")
|
||||||
|
("timer_10" . "\xe423")
|
||||||
|
("timer_3" . "\xe424")
|
||||||
|
("timer_off" . "\xe426")
|
||||||
|
("title" . "\xe264")
|
||||||
|
("toc" . "\xe8de")
|
||||||
|
("today" . "\xe8df")
|
||||||
|
("toll" . "\xe8e0")
|
||||||
|
("tonality" . "\xe427")
|
||||||
|
("touch_app" . "\xe913")
|
||||||
|
("toys" . "\xe332")
|
||||||
|
("track_changes" . "\xe8e1")
|
||||||
|
("traffic" . "\xe565")
|
||||||
|
("train" . "\xe570")
|
||||||
|
("tram" . "\xe571")
|
||||||
|
("transfer_within_a_station" . "\xe572")
|
||||||
|
("transform" . "\xe428")
|
||||||
|
("translate" . "\xe8e2")
|
||||||
|
("trending_down" . "\xe8e3")
|
||||||
|
("trending_flat" . "\xe8e4")
|
||||||
|
("trending_up" . "\xe8e5")
|
||||||
|
("tune" . "\xe429")
|
||||||
|
("turned_in" . "\xe8e6")
|
||||||
|
("turned_in_not" . "\xe8e7")
|
||||||
|
("tv" . "\xe333")
|
||||||
|
("unarchive" . "\xe169")
|
||||||
|
("undo" . "\xe166")
|
||||||
|
("unfold_less" . "\xe5d6")
|
||||||
|
("unfold_more" . "\xe5d7")
|
||||||
|
("update" . "\xe923")
|
||||||
|
("usb" . "\xe1e0")
|
||||||
|
("verified_user" . "\xe8e8")
|
||||||
|
("vertical_align_bottom" . "\xe258")
|
||||||
|
("vertical_align_center" . "\xe259")
|
||||||
|
("vertical_align_top" . "\xe25a")
|
||||||
|
("vibration" . "\xe62d")
|
||||||
|
("video_call" . "\xe070")
|
||||||
|
("video_label" . "\xe071")
|
||||||
|
("video_library" . "\xe04a")
|
||||||
|
("videocam" . "\xe04b")
|
||||||
|
("videocam_off" . "\xe04c")
|
||||||
|
("videogame_asset" . "\xe338")
|
||||||
|
("view_agenda" . "\xe8e9")
|
||||||
|
("view_array" . "\xe8ea")
|
||||||
|
("view_carousel" . "\xe8eb")
|
||||||
|
("view_column" . "\xe8ec")
|
||||||
|
("view_comfy" . "\xe42a")
|
||||||
|
("view_compact" . "\xe42b")
|
||||||
|
("view_day" . "\xe8ed")
|
||||||
|
("view_headline" . "\xe8ee")
|
||||||
|
("view_list" . "\xe8ef")
|
||||||
|
("view_module" . "\xe8f0")
|
||||||
|
("view_quilt" . "\xe8f1")
|
||||||
|
("view_stream" . "\xe8f2")
|
||||||
|
("view_week" . "\xe8f3")
|
||||||
|
("vignette" . "\xe435")
|
||||||
|
("visibility" . "\xe8f4")
|
||||||
|
("visibility_off" . "\xe8f5")
|
||||||
|
("voice_chat" . "\xe62e")
|
||||||
|
("voicemail" . "\xe0d9")
|
||||||
|
("volume_down" . "\xe04d")
|
||||||
|
("volume_mute" . "\xe04e")
|
||||||
|
("volume_off" . "\xe04f")
|
||||||
|
("volume_up" . "\xe050")
|
||||||
|
("vpn_key" . "\xe0da")
|
||||||
|
("vpn_lock" . "\xe62f")
|
||||||
|
("wallpaper" . "\xe1bc")
|
||||||
|
("warning" . "\xe002")
|
||||||
|
("watch" . "\xe334")
|
||||||
|
("watch_later" . "\xe924")
|
||||||
|
("wb_auto" . "\xe42c")
|
||||||
|
("wb_cloudy" . "\xe42d")
|
||||||
|
("wb_incandescent" . "\xe42e")
|
||||||
|
("wb_iridescent" . "\xe436")
|
||||||
|
("wb_sunny" . "\xe430")
|
||||||
|
("wc" . "\xe63d")
|
||||||
|
("web" . "\xe051")
|
||||||
|
("web_asset" . "\xe069")
|
||||||
|
("weekend" . "\xe16b")
|
||||||
|
("whatshot" . "\xe80e")
|
||||||
|
("widgets" . "\xe1bd")
|
||||||
|
("wifi" . "\xe63e")
|
||||||
|
("wifi_lock" . "\xe1e1")
|
||||||
|
("wifi_tethering" . "\xe1e2")
|
||||||
|
("work" . "\xe8f9")
|
||||||
|
("wrap_text" . "\xe25b")
|
||||||
|
("youtube_searched_for" . "\xe8fa")
|
||||||
|
("zoom_in" . "\xe8ff")
|
||||||
|
("zoom_out" . "\xe900")
|
||||||
|
("zoom_out_map" . "\xe56b")))
|
||||||
|
|
||||||
|
(provide 'data-material)
|
Binary file not shown.
|
@ -0,0 +1,165 @@
|
||||||
|
(defvar all-the-icons-data/octicons-alist
|
||||||
|
'(
|
||||||
|
|
||||||
|
("alert" . "\xf02d")
|
||||||
|
("arrow-down" . "\xf03f")
|
||||||
|
("arrow-left" . "\xf040")
|
||||||
|
("arrow-right" . "\xf03e")
|
||||||
|
("arrow-small-down" . "\xf0a0")
|
||||||
|
("arrow-small-left" . "\xf0a1")
|
||||||
|
("arrow-small-right" . "\xf071")
|
||||||
|
("arrow-small-up" . "\xf09f")
|
||||||
|
("arrow-up" . "\xf03d")
|
||||||
|
("book" . "\xf007")
|
||||||
|
("bookmark" . "\xf07b")
|
||||||
|
("briefcase" . "\xf0d3")
|
||||||
|
("broadcast" . "\xf048")
|
||||||
|
("browser" . "\xf0c5")
|
||||||
|
("bug" . "\xf091")
|
||||||
|
("calendar" . "\xf068")
|
||||||
|
("check" . "\xf03a")
|
||||||
|
("checklist" . "\xf076")
|
||||||
|
("chevron-down" . "\xf0a3")
|
||||||
|
("chevron-left" . "\xf0a4")
|
||||||
|
("chevron-right" . "\xf078")
|
||||||
|
("chevron-up" . "\xf0a2")
|
||||||
|
("circle-slash" . "\xf084")
|
||||||
|
("circuit-board" . "\xf0d6")
|
||||||
|
("clippy" . "\xf035")
|
||||||
|
("clock" . "\xf046")
|
||||||
|
("cloud-download" . "\xf00b")
|
||||||
|
("cloud-upload" . "\xf00c")
|
||||||
|
("code" . "\xf05f")
|
||||||
|
("comment" . "\xf02b")
|
||||||
|
("comment-discussion" . "\xf04f")
|
||||||
|
("credit-card" . "\xf045")
|
||||||
|
("dash" . "\xf0ca")
|
||||||
|
("dashboard" . "\xf07d")
|
||||||
|
("database" . "\xf096")
|
||||||
|
("device-camera" . "\xf056")
|
||||||
|
("device-camera-video" . "\xf057")
|
||||||
|
("device-desktop" . "\xf27c")
|
||||||
|
("device-mobile" . "\xf038")
|
||||||
|
("diff" . "\xf04d")
|
||||||
|
("diff-added" . "\xf06b")
|
||||||
|
("diff-ignored" . "\xf099")
|
||||||
|
("diff-modified" . "\xf06d")
|
||||||
|
("diff-removed" . "\xf06c")
|
||||||
|
("diff-renamed" . "\xf06e")
|
||||||
|
("ellipsis" . "\xf09a")
|
||||||
|
("eye" . "\xf04e")
|
||||||
|
("file-binary" . "\xf094")
|
||||||
|
("file-code" . "\xf010")
|
||||||
|
("file-directory" . "\xf016")
|
||||||
|
("file-media" . "\xf012")
|
||||||
|
("file-pdf" . "\xf014")
|
||||||
|
("file-submodule" . "\xf017")
|
||||||
|
("file-symlink-directory" . "\xf0b1")
|
||||||
|
("file-symlink-file" . "\xf0b0")
|
||||||
|
("file-text" . "\xf011")
|
||||||
|
("file-zip" . "\xf013")
|
||||||
|
("flame" . "\xf0d2")
|
||||||
|
("fold" . "\xf0cc")
|
||||||
|
("gear" . "\xf02f")
|
||||||
|
("gift" . "\xf042")
|
||||||
|
("gist" . "\xf00e")
|
||||||
|
("gist-secret" . "\xf08c")
|
||||||
|
("git-branch" . "\xf020")
|
||||||
|
("git-commit" . "\xf01f")
|
||||||
|
("git-compare" . "\xf0ac")
|
||||||
|
("git-merge" . "\xf023")
|
||||||
|
("git-pull-request" . "\xf009")
|
||||||
|
("globe" . "\xf0b6")
|
||||||
|
("graph" . "\xf043")
|
||||||
|
("beaker" . "\xf0dd")
|
||||||
|
("heart" . "\x2665")
|
||||||
|
("history" . "\xf07e")
|
||||||
|
("home" . "\xf08d")
|
||||||
|
("horizontal-rule" . "\xf070")
|
||||||
|
("hourglass" . "\xf09e")
|
||||||
|
("hubot" . "\xf09d")
|
||||||
|
("inbox" . "\xf0cf")
|
||||||
|
("info" . "\xf059")
|
||||||
|
("issue-closed" . "\xf028")
|
||||||
|
("issue-opened" . "\xf026")
|
||||||
|
("issue-reopened" . "\xf027")
|
||||||
|
("jersey" . "\xf019")
|
||||||
|
("key" . "\xf049")
|
||||||
|
("keyboard" . "\xf00d")
|
||||||
|
("law" . "\xf0d8")
|
||||||
|
("light-bulb" . "\xf000")
|
||||||
|
("link" . "\xf05c")
|
||||||
|
("link-external" . "\xf07f")
|
||||||
|
("list-ordered" . "\xf062")
|
||||||
|
("list-unordered" . "\xf061")
|
||||||
|
("location" . "\xf060")
|
||||||
|
("lock" . "\xf06a")
|
||||||
|
("logo-github" . "\xf092")
|
||||||
|
("mail" . "\xf03b")
|
||||||
|
("mail-read" . "\xf03c")
|
||||||
|
("mail-reply" . "\xf051")
|
||||||
|
("mark-github" . "\xf00a")
|
||||||
|
("markdown" . "\xf0c9")
|
||||||
|
("megaphone" . "\xf077")
|
||||||
|
("mention" . "\xf0be")
|
||||||
|
("milestone" . "\xf075")
|
||||||
|
("mirror" . "\xf024")
|
||||||
|
("mortar-board" . "\xf0d7")
|
||||||
|
("mute" . "\xf080")
|
||||||
|
("no-newline" . "\xf09c")
|
||||||
|
("octoface" . "\xf008")
|
||||||
|
("organization" . "\xf037")
|
||||||
|
("package" . "\xf0c4")
|
||||||
|
("paintcan" . "\xf0d1")
|
||||||
|
("pencil" . "\xf058")
|
||||||
|
("person" . "\xf018")
|
||||||
|
("pin" . "\xf041")
|
||||||
|
("plug" . "\xf0d4")
|
||||||
|
("plus" . "\xf05d")
|
||||||
|
("primitive-dot" . "\xf052")
|
||||||
|
("primitive-square" . "\xf053")
|
||||||
|
("pulse" . "\xf085")
|
||||||
|
("puzzle" . "\xf0c0")
|
||||||
|
("question" . "\xf02c")
|
||||||
|
("quote" . "\xf063")
|
||||||
|
("radio-tower" . "\xf030")
|
||||||
|
("repo" . "\xf001")
|
||||||
|
("repo-clone" . "\xf04c")
|
||||||
|
("repo-force-push" . "\xf04a")
|
||||||
|
("repo-forked" . "\xf002")
|
||||||
|
("repo-pull" . "\xf006")
|
||||||
|
("repo-push" . "\xf005")
|
||||||
|
("rocket" . "\xf033")
|
||||||
|
("rss" . "\xf034")
|
||||||
|
("ruby" . "\xf047")
|
||||||
|
("search" . "\xf02e")
|
||||||
|
("server" . "\xf097")
|
||||||
|
("settings" . "\xf07c")
|
||||||
|
("sign-in" . "\xf036")
|
||||||
|
("sign-out" . "\xf032")
|
||||||
|
("squirrel" . "\xf0b2")
|
||||||
|
("star" . "\xf02a")
|
||||||
|
("steps" . "\xf0c7")
|
||||||
|
("stop" . "\xf08f")
|
||||||
|
("sync" . "\xf087")
|
||||||
|
("tag" . "\xf015")
|
||||||
|
("telescope" . "\xf088")
|
||||||
|
("terminal" . "\xf0c8")
|
||||||
|
("three-bars" . "\xf05e")
|
||||||
|
("thumbsdown" . "\xf0db")
|
||||||
|
("thumbsup" . "\xf0da")
|
||||||
|
("tools" . "\xf031")
|
||||||
|
("trashcan" . "\xf0d0")
|
||||||
|
("triangle-down" . "\xf05b")
|
||||||
|
("triangle-left" . "\xf044")
|
||||||
|
("triangle-right" . "\xf05a")
|
||||||
|
("triangle-up" . "\xf0aa")
|
||||||
|
("unfold" . "\xf039")
|
||||||
|
("unmute" . "\xf0ba")
|
||||||
|
("versions" . "\xf064")
|
||||||
|
("x" . "\xf081")
|
||||||
|
("zap" . "\x26A1")
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(provide 'data-octicons)
|
Binary file not shown.
|
@ -0,0 +1,594 @@
|
||||||
|
(defvar all-the-icons-data/weather-icons-alist
|
||||||
|
'(
|
||||||
|
|
||||||
|
("alien" . "\xf075")
|
||||||
|
("barometer" . "\xf079")
|
||||||
|
("celsius" . "\xf03c")
|
||||||
|
("cloud" . "\xf041")
|
||||||
|
("cloud-down" . "\xf03d")
|
||||||
|
("cloud-refresh" . "\xf03e")
|
||||||
|
("cloud-up" . "\xf040")
|
||||||
|
("cloudy" . "\xf013")
|
||||||
|
("cloudy-gusts" . "\xf011")
|
||||||
|
("cloudy-windy" . "\xf012")
|
||||||
|
("day-cloudy" . "\xf002")
|
||||||
|
("day-cloudy-gusts" . "\xf000")
|
||||||
|
("day-cloudy-high" . "\xf07d")
|
||||||
|
("day-cloudy-windy" . "\xf001")
|
||||||
|
("day-fog" . "\xf003")
|
||||||
|
("day-hail" . "\xf004")
|
||||||
|
("day-haze" . "\xf0b6")
|
||||||
|
("day-light-wind" . "\xf0c4")
|
||||||
|
("day-lightning" . "\xf005")
|
||||||
|
("day-rain" . "\xf008")
|
||||||
|
("day-rain-mix" . "\xf006")
|
||||||
|
("day-rain-wind" . "\xf007")
|
||||||
|
("day-showers" . "\xf009")
|
||||||
|
("day-sleet" . "\xf0b2")
|
||||||
|
("day-sleet-storm" . "\xf068")
|
||||||
|
("day-snow" . "\xf00a")
|
||||||
|
("day-snow-thunderstorm" . "\xf06b")
|
||||||
|
("day-snow-wind" . "\xf065")
|
||||||
|
("day-sprinkle" . "\xf00b")
|
||||||
|
("day-storm-showers" . "\xf00e")
|
||||||
|
("day-sunny" . "\xf00d")
|
||||||
|
("day-sunny-overcast" . "\xf00c")
|
||||||
|
("day-thunderstorm" . "\xf010")
|
||||||
|
("day-windy" . "\xf085")
|
||||||
|
("degrees" . "\xf042")
|
||||||
|
("direction-down" . "\xf044")
|
||||||
|
("direction-down-left" . "\xf043")
|
||||||
|
("direction-down-right" . "\xf088")
|
||||||
|
("direction-left" . "\xf048")
|
||||||
|
("direction-right" . "\xf04d")
|
||||||
|
("direction-up" . "\xf058")
|
||||||
|
("direction-up-left" . "\xf087")
|
||||||
|
("direction-up-right" . "\xf057")
|
||||||
|
("dust" . "\xf063")
|
||||||
|
("earthquake" . "\xf0c6")
|
||||||
|
("fahrenheit" . "\xf045")
|
||||||
|
("fire" . "\xf0c7")
|
||||||
|
("flood" . "\xf07c")
|
||||||
|
("fog" . "\xf014")
|
||||||
|
("forecast-io-clear-day" . "\xf00d")
|
||||||
|
("forecast-io-clear-night" . "\xf02e")
|
||||||
|
("forecast-io-cloudy" . "\xf013")
|
||||||
|
("forecast-io-fog" . "\xf014")
|
||||||
|
("forecast-io-hail" . "\xf015")
|
||||||
|
("forecast-io-partly-cloudy-day" . "\xf002")
|
||||||
|
("forecast-io-partly-cloudy-night" . "\xf031")
|
||||||
|
("forecast-io-rain" . "\xf019")
|
||||||
|
("forecast-io-sleet" . "\xf0b5")
|
||||||
|
("forecast-io-snow" . "\xf01b")
|
||||||
|
("forecast-io-thunderstorm" . "\xf01e")
|
||||||
|
("forecast-io-tornado" . "\xf056")
|
||||||
|
("forecast-io-wind" . "\xf050")
|
||||||
|
("gale-warning" . "\xf0cd")
|
||||||
|
("hail" . "\xf015")
|
||||||
|
("horizon" . "\xf047")
|
||||||
|
("horizon-alt" . "\xf046")
|
||||||
|
("hot" . "\xf072")
|
||||||
|
("humidity" . "\xf07a")
|
||||||
|
("hurricane" . "\xf073")
|
||||||
|
("hurricane-warning" . "\xf0cf")
|
||||||
|
("lightning" . "\xf016")
|
||||||
|
("lunar-eclipse" . "\xf070")
|
||||||
|
("meteor" . "\xf071")
|
||||||
|
("moon-0" . "\xf095")
|
||||||
|
("moon-1" . "\xf096")
|
||||||
|
("moon-10" . "\xf09f")
|
||||||
|
("moon-11" . "\xf0a0")
|
||||||
|
("moon-12" . "\xf0a1")
|
||||||
|
("moon-13" . "\xf0a2")
|
||||||
|
("moon-14" . "\xf0a3")
|
||||||
|
("moon-15" . "\xf0a4")
|
||||||
|
("moon-16" . "\xf0a5")
|
||||||
|
("moon-17" . "\xf0a6")
|
||||||
|
("moon-18" . "\xf0a7")
|
||||||
|
("moon-19" . "\xf0a8")
|
||||||
|
("moon-2" . "\xf097")
|
||||||
|
("moon-20" . "\xf0a9")
|
||||||
|
("moon-21" . "\xf0aa")
|
||||||
|
("moon-22" . "\xf0ab")
|
||||||
|
("moon-23" . "\xf0ac")
|
||||||
|
("moon-24" . "\xf0ad")
|
||||||
|
("moon-25" . "\xf0ae")
|
||||||
|
("moon-26" . "\xf0af")
|
||||||
|
("moon-27" . "\xf0b0")
|
||||||
|
("moon-3" . "\xf098")
|
||||||
|
("moon-4" . "\xf099")
|
||||||
|
("moon-5" . "\xf09a")
|
||||||
|
("moon-6" . "\xf09b")
|
||||||
|
("moon-7" . "\xf09c")
|
||||||
|
("moon-8" . "\xf09d")
|
||||||
|
("moon-9" . "\xf09e")
|
||||||
|
("moon-alt-first-quarter" . "\xf0d6")
|
||||||
|
("moon-alt-full" . "\xf0dd")
|
||||||
|
("moon-alt-new" . "\xf0eb")
|
||||||
|
("moon-alt-third-quarter" . "\xf0e4")
|
||||||
|
("moon-alt-waning-crescent-1" . "\xf0e5")
|
||||||
|
("moon-alt-waning-crescent-2" . "\xf0e6")
|
||||||
|
("moon-alt-waning-crescent-3" . "\xf0e7")
|
||||||
|
("moon-alt-waning-crescent-4" . "\xf0e8")
|
||||||
|
("moon-alt-waning-crescent-5" . "\xf0e9")
|
||||||
|
("moon-alt-waning-crescent-6" . "\xf0ea")
|
||||||
|
("moon-alt-waning-gibbous-1" . "\xf0de")
|
||||||
|
("moon-alt-waning-gibbous-2" . "\xf0df")
|
||||||
|
("moon-alt-waning-gibbous-3" . "\xf0e0")
|
||||||
|
("moon-alt-waning-gibbous-4" . "\xf0e1")
|
||||||
|
("moon-alt-waning-gibbous-5" . "\xf0e2")
|
||||||
|
("moon-alt-waning-gibbous-6" . "\xf0e3")
|
||||||
|
("moon-alt-waxing-crescent-1" . "\xf0d0")
|
||||||
|
("moon-alt-waxing-crescent-2" . "\xf0d1")
|
||||||
|
("moon-alt-waxing-crescent-3" . "\xf0d2")
|
||||||
|
("moon-alt-waxing-crescent-4" . "\xf0d3")
|
||||||
|
("moon-alt-waxing-crescent-5" . "\xf0d4")
|
||||||
|
("moon-alt-waxing-crescent-6" . "\xf0d5")
|
||||||
|
("moon-alt-waxing-gibbous-1" . "\xf0d7")
|
||||||
|
("moon-alt-waxing-gibbous-2" . "\xf0d8")
|
||||||
|
("moon-alt-waxing-gibbous-3" . "\xf0d9")
|
||||||
|
("moon-alt-waxing-gibbous-4" . "\xf0da")
|
||||||
|
("moon-alt-waxing-gibbous-5" . "\xf0db")
|
||||||
|
("moon-alt-waxing-gibbous-6" . "\xf0dc")
|
||||||
|
("moon-first-quarter" . "\xf09c")
|
||||||
|
("moon-full" . "\xf0a3")
|
||||||
|
("moon-new" . "\xf095")
|
||||||
|
("moon-third-quarter" . "\xf0aa")
|
||||||
|
("moon-waning-crescent-1" . "\xf0ab")
|
||||||
|
("moon-waning-crescent-2" . "\xf0ac")
|
||||||
|
("moon-waning-crescent-3" . "\xf0ad")
|
||||||
|
("moon-waning-crescent-4" . "\xf0ae")
|
||||||
|
("moon-waning-crescent-5" . "\xf0af")
|
||||||
|
("moon-waning-crescent-6" . "\xf0b0")
|
||||||
|
("moon-waning-gibbous-1" . "\xf0a4")
|
||||||
|
("moon-waning-gibbous-2" . "\xf0a5")
|
||||||
|
("moon-waning-gibbous-3" . "\xf0a6")
|
||||||
|
("moon-waning-gibbous-4" . "\xf0a7")
|
||||||
|
("moon-waning-gibbous-5" . "\xf0a8")
|
||||||
|
("moon-waning-gibbous-6" . "\xf0a9")
|
||||||
|
("moon-waxing-crescent-1" . "\xf096")
|
||||||
|
("moon-waxing-crescent-2" . "\xf097")
|
||||||
|
("moon-waxing-crescent-3" . "\xf098")
|
||||||
|
("moon-waxing-crescent-4" . "\xf099")
|
||||||
|
("moon-waxing-crescent-5" . "\xf09a")
|
||||||
|
("moon-waxing-crescent-6" . "\xf09b")
|
||||||
|
("moon-waxing-gibbous-1" . "\xf09d")
|
||||||
|
("moon-waxing-gibbous-2" . "\xf09e")
|
||||||
|
("moon-waxing-gibbous-3" . "\xf09f")
|
||||||
|
("moon-waxing-gibbous-4" . "\xf0a0")
|
||||||
|
("moon-waxing-gibbous-5" . "\xf0a1")
|
||||||
|
("moon-waxing-gibbous-6" . "\xf0a2")
|
||||||
|
("moonrise" . "\xf0c9")
|
||||||
|
("moonset" . "\xf0ca")
|
||||||
|
("na" . "\xf07b")
|
||||||
|
("night-alt-cloudy" . "\xf086")
|
||||||
|
("night-alt-cloudy-gusts" . "\xf022")
|
||||||
|
("night-alt-cloudy-high" . "\xf07e")
|
||||||
|
("night-alt-cloudy-windy" . "\xf023")
|
||||||
|
("night-alt-hail" . "\xf024")
|
||||||
|
("night-alt-lightning" . "\xf025")
|
||||||
|
("night-alt-partly-cloudy" . "\xf081")
|
||||||
|
("night-alt-rain" . "\xf028")
|
||||||
|
("night-alt-rain-mix" . "\xf026")
|
||||||
|
("night-alt-rain-wind" . "\xf027")
|
||||||
|
("night-alt-showers" . "\xf029")
|
||||||
|
("night-alt-sleet" . "\xf0b4")
|
||||||
|
("night-alt-sleet-storm" . "\xf06a")
|
||||||
|
("night-alt-snow" . "\xf02a")
|
||||||
|
("night-alt-snow-thunderstorm" . "\xf06d")
|
||||||
|
("night-alt-snow-wind" . "\xf067")
|
||||||
|
("night-alt-sprinkle" . "\xf02b")
|
||||||
|
("night-alt-storm-showers" . "\xf02c")
|
||||||
|
("night-alt-thunderstorm" . "\xf02d")
|
||||||
|
("night-clear" . "\xf02e")
|
||||||
|
("night-cloudy" . "\xf031")
|
||||||
|
("night-cloudy-gusts" . "\xf02f")
|
||||||
|
("night-cloudy-high" . "\xf080")
|
||||||
|
("night-cloudy-windy" . "\xf030")
|
||||||
|
("night-fog" . "\xf04a")
|
||||||
|
("night-hail" . "\xf032")
|
||||||
|
("night-lightning" . "\xf033")
|
||||||
|
("night-partly-cloudy" . "\xf083")
|
||||||
|
("night-rain" . "\xf036")
|
||||||
|
("night-rain-mix" . "\xf034")
|
||||||
|
("night-rain-wind" . "\xf035")
|
||||||
|
("night-showers" . "\xf037")
|
||||||
|
("night-sleet" . "\xf0b3")
|
||||||
|
("night-sleet-storm" . "\xf069")
|
||||||
|
("night-snow" . "\xf038")
|
||||||
|
("night-snow-thunderstorm" . "\xf06c")
|
||||||
|
("night-snow-wind" . "\xf066")
|
||||||
|
("night-sprinkle" . "\xf039")
|
||||||
|
("night-storm-showers" . "\xf03a")
|
||||||
|
("night-thunderstorm" . "\xf03b")
|
||||||
|
("owm-200" . "\xf01e")
|
||||||
|
("owm-201" . "\xf01e")
|
||||||
|
("owm-202" . "\xf01e")
|
||||||
|
("owm-210" . "\xf016")
|
||||||
|
("owm-211" . "\xf016")
|
||||||
|
("owm-212" . "\xf016")
|
||||||
|
("owm-221" . "\xf016")
|
||||||
|
("owm-230" . "\xf01e")
|
||||||
|
("owm-231" . "\xf01e")
|
||||||
|
("owm-232" . "\xf01e")
|
||||||
|
("owm-300" . "\xf01c")
|
||||||
|
("owm-301" . "\xf01c")
|
||||||
|
("owm-302" . "\xf019")
|
||||||
|
("owm-310" . "\xf017")
|
||||||
|
("owm-311" . "\xf019")
|
||||||
|
("owm-312" . "\xf019")
|
||||||
|
("owm-313" . "\xf01a")
|
||||||
|
("owm-314" . "\xf019")
|
||||||
|
("owm-321" . "\xf01c")
|
||||||
|
("owm-500" . "\xf01c")
|
||||||
|
("owm-501" . "\xf019")
|
||||||
|
("owm-502" . "\xf019")
|
||||||
|
("owm-503" . "\xf019")
|
||||||
|
("owm-504" . "\xf019")
|
||||||
|
("owm-511" . "\xf017")
|
||||||
|
("owm-520" . "\xf01a")
|
||||||
|
("owm-521" . "\xf01a")
|
||||||
|
("owm-522" . "\xf01a")
|
||||||
|
("owm-531" . "\xf01d")
|
||||||
|
("owm-600" . "\xf01b")
|
||||||
|
("owm-601" . "\xf01b")
|
||||||
|
("owm-602" . "\xf0b5")
|
||||||
|
("owm-611" . "\xf017")
|
||||||
|
("owm-612" . "\xf017")
|
||||||
|
("owm-615" . "\xf017")
|
||||||
|
("owm-616" . "\xf017")
|
||||||
|
("owm-620" . "\xf017")
|
||||||
|
("owm-621" . "\xf01b")
|
||||||
|
("owm-622" . "\xf01b")
|
||||||
|
("owm-701" . "\xf01a")
|
||||||
|
("owm-711" . "\xf062")
|
||||||
|
("owm-721" . "\xf0b6")
|
||||||
|
("owm-731" . "\xf063")
|
||||||
|
("owm-741" . "\xf014")
|
||||||
|
("owm-761" . "\xf063")
|
||||||
|
("owm-762" . "\xf063")
|
||||||
|
("owm-771" . "\xf011")
|
||||||
|
("owm-781" . "\xf056")
|
||||||
|
("owm-800" . "\xf00d")
|
||||||
|
("owm-801" . "\xf011")
|
||||||
|
("owm-802" . "\xf011")
|
||||||
|
("owm-803" . "\xf012")
|
||||||
|
("owm-804" . "\xf013")
|
||||||
|
("owm-900" . "\xf056")
|
||||||
|
("owm-901" . "\xf01d")
|
||||||
|
("owm-902" . "\xf073")
|
||||||
|
("owm-903" . "\xf076")
|
||||||
|
("owm-904" . "\xf072")
|
||||||
|
("owm-905" . "\xf021")
|
||||||
|
("owm-906" . "\xf015")
|
||||||
|
("owm-957" . "\xf050")
|
||||||
|
("owm-day-200" . "\xf010")
|
||||||
|
("owm-day-201" . "\xf010")
|
||||||
|
("owm-day-202" . "\xf010")
|
||||||
|
("owm-day-210" . "\xf005")
|
||||||
|
("owm-day-211" . "\xf005")
|
||||||
|
("owm-day-212" . "\xf005")
|
||||||
|
("owm-day-221" . "\xf005")
|
||||||
|
("owm-day-230" . "\xf010")
|
||||||
|
("owm-day-231" . "\xf010")
|
||||||
|
("owm-day-232" . "\xf010")
|
||||||
|
("owm-day-300" . "\xf00b")
|
||||||
|
("owm-day-301" . "\xf00b")
|
||||||
|
("owm-day-302" . "\xf008")
|
||||||
|
("owm-day-310" . "\xf008")
|
||||||
|
("owm-day-311" . "\xf008")
|
||||||
|
("owm-day-312" . "\xf008")
|
||||||
|
("owm-day-313" . "\xf008")
|
||||||
|
("owm-day-314" . "\xf008")
|
||||||
|
("owm-day-321" . "\xf00b")
|
||||||
|
("owm-day-500" . "\xf00b")
|
||||||
|
("owm-day-501" . "\xf008")
|
||||||
|
("owm-day-502" . "\xf008")
|
||||||
|
("owm-day-503" . "\xf008")
|
||||||
|
("owm-day-504" . "\xf008")
|
||||||
|
("owm-day-511" . "\xf006")
|
||||||
|
("owm-day-520" . "\xf009")
|
||||||
|
("owm-day-521" . "\xf009")
|
||||||
|
("owm-day-522" . "\xf009")
|
||||||
|
("owm-day-531" . "\xf00e")
|
||||||
|
("owm-day-600" . "\xf00a")
|
||||||
|
("owm-day-601" . "\xf0b2")
|
||||||
|
("owm-day-602" . "\xf00a")
|
||||||
|
("owm-day-611" . "\xf006")
|
||||||
|
("owm-day-612" . "\xf006")
|
||||||
|
("owm-day-615" . "\xf006")
|
||||||
|
("owm-day-616" . "\xf006")
|
||||||
|
("owm-day-620" . "\xf006")
|
||||||
|
("owm-day-621" . "\xf00a")
|
||||||
|
("owm-day-622" . "\xf00a")
|
||||||
|
("owm-day-701" . "\xf009")
|
||||||
|
("owm-day-711" . "\xf062")
|
||||||
|
("owm-day-721" . "\xf0b6")
|
||||||
|
("owm-day-731" . "\xf063")
|
||||||
|
("owm-day-741" . "\xf003")
|
||||||
|
("owm-day-761" . "\xf063")
|
||||||
|
("owm-day-762" . "\xf063")
|
||||||
|
("owm-day-781" . "\xf056")
|
||||||
|
("owm-day-800" . "\xf00d")
|
||||||
|
("owm-day-801" . "\xf000")
|
||||||
|
("owm-day-802" . "\xf000")
|
||||||
|
("owm-day-803" . "\xf000")
|
||||||
|
("owm-day-804" . "\xf00c")
|
||||||
|
("owm-day-900" . "\xf056")
|
||||||
|
("owm-day-902" . "\xf073")
|
||||||
|
("owm-day-903" . "\xf076")
|
||||||
|
("owm-day-904" . "\xf072")
|
||||||
|
("owm-day-906" . "\xf004")
|
||||||
|
("owm-day-957" . "\xf050")
|
||||||
|
("owm-night-200" . "\xf02d")
|
||||||
|
("owm-night-201" . "\xf02d")
|
||||||
|
("owm-night-202" . "\xf02d")
|
||||||
|
("owm-night-210" . "\xf025")
|
||||||
|
("owm-night-211" . "\xf025")
|
||||||
|
("owm-night-212" . "\xf025")
|
||||||
|
("owm-night-221" . "\xf025")
|
||||||
|
("owm-night-230" . "\xf02d")
|
||||||
|
("owm-night-231" . "\xf02d")
|
||||||
|
("owm-night-232" . "\xf02d")
|
||||||
|
("owm-night-300" . "\xf02b")
|
||||||
|
("owm-night-301" . "\xf02b")
|
||||||
|
("owm-night-302" . "\xf028")
|
||||||
|
("owm-night-310" . "\xf028")
|
||||||
|
("owm-night-311" . "\xf028")
|
||||||
|
("owm-night-312" . "\xf028")
|
||||||
|
("owm-night-313" . "\xf028")
|
||||||
|
("owm-night-314" . "\xf028")
|
||||||
|
("owm-night-321" . "\xf02b")
|
||||||
|
("owm-night-500" . "\xf02b")
|
||||||
|
("owm-night-501" . "\xf028")
|
||||||
|
("owm-night-502" . "\xf028")
|
||||||
|
("owm-night-503" . "\xf028")
|
||||||
|
("owm-night-504" . "\xf028")
|
||||||
|
("owm-night-511" . "\xf026")
|
||||||
|
("owm-night-520" . "\xf029")
|
||||||
|
("owm-night-521" . "\xf029")
|
||||||
|
("owm-night-522" . "\xf029")
|
||||||
|
("owm-night-531" . "\xf02c")
|
||||||
|
("owm-night-600" . "\xf02a")
|
||||||
|
("owm-night-601" . "\xf0b4")
|
||||||
|
("owm-night-602" . "\xf02a")
|
||||||
|
("owm-night-611" . "\xf026")
|
||||||
|
("owm-night-612" . "\xf026")
|
||||||
|
("owm-night-615" . "\xf026")
|
||||||
|
("owm-night-616" . "\xf026")
|
||||||
|
("owm-night-620" . "\xf026")
|
||||||
|
("owm-night-621" . "\xf02a")
|
||||||
|
("owm-night-622" . "\xf02a")
|
||||||
|
("owm-night-701" . "\xf029")
|
||||||
|
("owm-night-711" . "\xf062")
|
||||||
|
("owm-night-721" . "\xf0b6")
|
||||||
|
("owm-night-731" . "\xf063")
|
||||||
|
("owm-night-741" . "\xf04a")
|
||||||
|
("owm-night-761" . "\xf063")
|
||||||
|
("owm-night-762" . "\xf063")
|
||||||
|
("owm-night-781" . "\xf056")
|
||||||
|
("owm-night-800" . "\xf02e")
|
||||||
|
("owm-night-801" . "\xf022")
|
||||||
|
("owm-night-802" . "\xf022")
|
||||||
|
("owm-night-803" . "\xf022")
|
||||||
|
("owm-night-804" . "\xf086")
|
||||||
|
("owm-night-900" . "\xf056")
|
||||||
|
("owm-night-902" . "\xf073")
|
||||||
|
("owm-night-903" . "\xf076")
|
||||||
|
("owm-night-904" . "\xf072")
|
||||||
|
("owm-night-906" . "\xf024")
|
||||||
|
("owm-night-957" . "\xf050")
|
||||||
|
("rain" . "\xf019")
|
||||||
|
("rain-mix" . "\xf017")
|
||||||
|
("rain-wind" . "\xf018")
|
||||||
|
("raindrop" . "\xf078")
|
||||||
|
("raindrops" . "\xf04e")
|
||||||
|
("refresh" . "\xf04c")
|
||||||
|
("refresh-alt" . "\xf04b")
|
||||||
|
("sandstorm" . "\xf082")
|
||||||
|
("showers" . "\xf01a")
|
||||||
|
("sleet" . "\xf0b5")
|
||||||
|
("small-craft-advisory" . "\xf0cc")
|
||||||
|
("smog" . "\xf074")
|
||||||
|
("smoke" . "\xf062")
|
||||||
|
("snow" . "\xf01b")
|
||||||
|
("snow" . "\xf01b")
|
||||||
|
("snow-wind" . "\xf064")
|
||||||
|
("snowflake-cold" . "\xf076")
|
||||||
|
("solar-eclipse" . "\xf06e")
|
||||||
|
("sprinkle" . "\xf01c")
|
||||||
|
("stars" . "\xf077")
|
||||||
|
("storm-showers" . "\xf01d")
|
||||||
|
("storm-showers" . "\xf01d")
|
||||||
|
("storm-warning" . "\xf0ce")
|
||||||
|
("strong-wind" . "\xf050")
|
||||||
|
("sunrise" . "\xf051")
|
||||||
|
("sunset" . "\xf052")
|
||||||
|
("thermometer" . "\xf055")
|
||||||
|
("thermometer-exterior" . "\xf053")
|
||||||
|
("thermometer-internal" . "\xf054")
|
||||||
|
("thunderstorm" . "\xf01e")
|
||||||
|
("thunderstorm" . "\xf01e")
|
||||||
|
("time-1" . "\xf08a")
|
||||||
|
("time-10" . "\xf093")
|
||||||
|
("time-11" . "\xf094")
|
||||||
|
("time-12" . "\xf089")
|
||||||
|
("time-2" . "\xf08b")
|
||||||
|
("time-3" . "\xf08c")
|
||||||
|
("time-4" . "\xf08d")
|
||||||
|
("time-5" . "\xf08e")
|
||||||
|
("time-6" . "\xf08f")
|
||||||
|
("time-7" . "\xf090")
|
||||||
|
("time-8" . "\xf091")
|
||||||
|
("time-9" . "\xf092")
|
||||||
|
("tornado" . "\xf056")
|
||||||
|
("train" . "\xf0cb")
|
||||||
|
("tsunami" . "\xf0c5")
|
||||||
|
("umbrella" . "\xf084")
|
||||||
|
("volcano" . "\xf0c8")
|
||||||
|
("wind-beaufort-0" . "\xf0b7")
|
||||||
|
("wind-beaufort-1" . "\xf0b8")
|
||||||
|
("wind-beaufort-10" . "\xf0c1")
|
||||||
|
("wind-beaufort-11" . "\xf0c2")
|
||||||
|
("wind-beaufort-12" . "\xf0c3")
|
||||||
|
("wind-beaufort-2" . "\xf0b9")
|
||||||
|
("wind-beaufort-3" . "\xf0ba")
|
||||||
|
("wind-beaufort-4" . "\xf0bb")
|
||||||
|
("wind-beaufort-5" . "\xf0bc")
|
||||||
|
("wind-beaufort-6" . "\xf0bd")
|
||||||
|
("wind-beaufort-7" . "\xf0be")
|
||||||
|
("wind-beaufort-8" . "\xf0bf")
|
||||||
|
("wind-beaufort-9" . "\xf0c0")
|
||||||
|
("wind-direction" . "\xf0b1")
|
||||||
|
("windy" . "\xf021")
|
||||||
|
("wmo4680-00" . "\xf055")
|
||||||
|
("wmo4680-01" . "\xf013")
|
||||||
|
("wmo4680-02" . "\xf055")
|
||||||
|
("wmo4680-03" . "\xf013")
|
||||||
|
("wmo4680-04" . "\xf014")
|
||||||
|
("wmo4680-05" . "\xf014")
|
||||||
|
("wmo4680-10" . "\xf014")
|
||||||
|
("wmo4680-11" . "\xf014")
|
||||||
|
("wmo4680-12" . "\xf016")
|
||||||
|
("wmo4680-18" . "\xf050")
|
||||||
|
("wmo4680-20" . "\xf014")
|
||||||
|
("wmo4680-21" . "\xf017")
|
||||||
|
("wmo4680-22" . "\xf017")
|
||||||
|
("wmo4680-23" . "\xf019")
|
||||||
|
("wmo4680-24" . "\xf01b")
|
||||||
|
("wmo4680-25" . "\xf015")
|
||||||
|
("wmo4680-26" . "\xf01e")
|
||||||
|
("wmo4680-27" . "\xf063")
|
||||||
|
("wmo4680-28" . "\xf063")
|
||||||
|
("wmo4680-29" . "\xf063")
|
||||||
|
("wmo4680-30" . "\xf014")
|
||||||
|
("wmo4680-31" . "\xf014")
|
||||||
|
("wmo4680-32" . "\xf014")
|
||||||
|
("wmo4680-33" . "\xf014")
|
||||||
|
("wmo4680-34" . "\xf014")
|
||||||
|
("wmo4680-35" . "\xf014")
|
||||||
|
("wmo4680-40" . "\xf017")
|
||||||
|
("wmo4680-41" . "\xf01c")
|
||||||
|
("wmo4680-42" . "\xf019")
|
||||||
|
("wmo4680-43" . "\xf01c")
|
||||||
|
("wmo4680-44" . "\xf019")
|
||||||
|
("wmo4680-45" . "\xf015")
|
||||||
|
("wmo4680-46" . "\xf015")
|
||||||
|
("wmo4680-47" . "\xf01b")
|
||||||
|
("wmo4680-48" . "\xf01b")
|
||||||
|
("wmo4680-50" . "\xf01c")
|
||||||
|
("wmo4680-51" . "\xf01c")
|
||||||
|
("wmo4680-52" . "\xf019")
|
||||||
|
("wmo4680-53" . "\xf019")
|
||||||
|
("wmo4680-54" . "\xf076")
|
||||||
|
("wmo4680-55" . "\xf076")
|
||||||
|
("wmo4680-56" . "\xf076")
|
||||||
|
("wmo4680-57" . "\xf01c")
|
||||||
|
("wmo4680-58" . "\xf019")
|
||||||
|
("wmo4680-60" . "\xf01c")
|
||||||
|
("wmo4680-61" . "\xf01c")
|
||||||
|
("wmo4680-62" . "\xf019")
|
||||||
|
("wmo4680-63" . "\xf019")
|
||||||
|
("wmo4680-64" . "\xf015")
|
||||||
|
("wmo4680-65" . "\xf015")
|
||||||
|
("wmo4680-66" . "\xf015")
|
||||||
|
("wmo4680-67" . "\xf017")
|
||||||
|
("wmo4680-68" . "\xf017")
|
||||||
|
("wmo4680-70" . "\xf01b")
|
||||||
|
("wmo4680-71" . "\xf01b")
|
||||||
|
("wmo4680-72" . "\xf01b")
|
||||||
|
("wmo4680-73" . "\xf01b")
|
||||||
|
("wmo4680-74" . "\xf076")
|
||||||
|
("wmo4680-75" . "\xf076")
|
||||||
|
("wmo4680-76" . "\xf076")
|
||||||
|
("wmo4680-77" . "\xf01b")
|
||||||
|
("wmo4680-78" . "\xf076")
|
||||||
|
("wmo4680-80" . "\xf019")
|
||||||
|
("wmo4680-81" . "\xf01c")
|
||||||
|
("wmo4680-82" . "\xf019")
|
||||||
|
("wmo4680-83" . "\xf019")
|
||||||
|
("wmo4680-84" . "\xf01d")
|
||||||
|
("wmo4680-85" . "\xf017")
|
||||||
|
("wmo4680-86" . "\xf017")
|
||||||
|
("wmo4680-87" . "\xf017")
|
||||||
|
("wmo4680-89" . "\xf015")
|
||||||
|
("wmo4680-90" . "\xf016")
|
||||||
|
("wmo4680-91" . "\xf01d")
|
||||||
|
("wmo4680-92" . "\xf01e")
|
||||||
|
("wmo4680-93" . "\xf01e")
|
||||||
|
("wmo4680-94" . "\xf016")
|
||||||
|
("wmo4680-95" . "\xf01e")
|
||||||
|
("wmo4680-96" . "\xf01e")
|
||||||
|
("wmo4680-99" . "\xf056")
|
||||||
|
("wu-chanceflurries" . "\xf064")
|
||||||
|
("wu-chancerain" . "\xf019")
|
||||||
|
("wu-chancesleat" . "\xf0b5")
|
||||||
|
("wu-chancesnow" . "\xf01b")
|
||||||
|
("wu-chancetstorms" . "\xf01e")
|
||||||
|
("wu-clear" . "\xf00d")
|
||||||
|
("wu-cloudy" . "\xf002")
|
||||||
|
("wu-flurries" . "\xf064")
|
||||||
|
("wu-hazy" . "\xf0b6")
|
||||||
|
("wu-mostlycloudy" . "\xf002")
|
||||||
|
("wu-mostlysunny" . "\xf00d")
|
||||||
|
("wu-partlycloudy" . "\xf002")
|
||||||
|
("wu-partlysunny" . "\xf00d")
|
||||||
|
("wu-rain" . "\xf01a")
|
||||||
|
("wu-sleat" . "\xf0b5")
|
||||||
|
("wu-snow" . "\xf01b")
|
||||||
|
("wu-sunny" . "\xf00d")
|
||||||
|
("wu-tstorms" . "\xf01e")
|
||||||
|
("wu-unknown" . "\xf00d")
|
||||||
|
("yahoo-0" . "\xf056")
|
||||||
|
("yahoo-1" . "\xf00e")
|
||||||
|
("yahoo-10" . "\xf015")
|
||||||
|
("yahoo-11" . "\xf01a")
|
||||||
|
("yahoo-12" . "\xf01a")
|
||||||
|
("yahoo-13" . "\xf01b")
|
||||||
|
("yahoo-14" . "\xf00a")
|
||||||
|
("yahoo-15" . "\xf064")
|
||||||
|
("yahoo-16" . "\xf01b")
|
||||||
|
("yahoo-17" . "\xf015")
|
||||||
|
("yahoo-18" . "\xf017")
|
||||||
|
("yahoo-19" . "\xf063")
|
||||||
|
("yahoo-2" . "\xf073")
|
||||||
|
("yahoo-20" . "\xf014")
|
||||||
|
("yahoo-21" . "\xf021")
|
||||||
|
("yahoo-22" . "\xf062")
|
||||||
|
("yahoo-23" . "\xf050")
|
||||||
|
("yahoo-24" . "\xf050")
|
||||||
|
("yahoo-25" . "\xf076")
|
||||||
|
("yahoo-26" . "\xf013")
|
||||||
|
("yahoo-27" . "\xf031")
|
||||||
|
("yahoo-28" . "\xf002")
|
||||||
|
("yahoo-29" . "\xf031")
|
||||||
|
("yahoo-3" . "\xf01e")
|
||||||
|
("yahoo-30" . "\xf002")
|
||||||
|
("yahoo-31" . "\xf02e")
|
||||||
|
("yahoo-32" . "\xf00d")
|
||||||
|
("yahoo-3200" . "\xf077")
|
||||||
|
("yahoo-33" . "\xf083")
|
||||||
|
("yahoo-34" . "\xf00c")
|
||||||
|
("yahoo-35" . "\xf017")
|
||||||
|
("yahoo-36" . "\xf072")
|
||||||
|
("yahoo-37" . "\xf00e")
|
||||||
|
("yahoo-38" . "\xf00e")
|
||||||
|
("yahoo-39" . "\xf00e")
|
||||||
|
("yahoo-4" . "\xf01e")
|
||||||
|
("yahoo-40" . "\xf01a")
|
||||||
|
("yahoo-41" . "\xf064")
|
||||||
|
("yahoo-42" . "\xf01b")
|
||||||
|
("yahoo-43" . "\xf064")
|
||||||
|
("yahoo-44" . "\xf00c")
|
||||||
|
("yahoo-45" . "\xf00e")
|
||||||
|
("yahoo-46" . "\xf01b")
|
||||||
|
("yahoo-47" . "\xf00e")
|
||||||
|
("yahoo-5" . "\xf017")
|
||||||
|
("yahoo-6" . "\xf017")
|
||||||
|
("yahoo-7" . "\xf017")
|
||||||
|
("yahoo-8" . "\xf015")
|
||||||
|
("yahoo-9" . "\xf01a")
|
||||||
|
|
||||||
|
))
|
||||||
|
|
||||||
|
(provide 'data-weathericons)
|
Binary file not shown.
|
@ -0,0 +1,22 @@
|
||||||
|
;;; all-the-icons-ivy-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "all-the-icons-ivy" "all-the-icons-ivy.el"
|
||||||
|
;;;;;; (23377 61297 57158 640000))
|
||||||
|
;;; Generated autoloads from all-the-icons-ivy.el
|
||||||
|
|
||||||
|
(autoload 'all-the-icons-ivy-setup "all-the-icons-ivy" "\
|
||||||
|
Set ivy's display transformers to show relevant icons next to the candidates.
|
||||||
|
|
||||||
|
\(fn)" nil nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; all-the-icons-ivy-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "all-the-icons-ivy" "20180225.630" "Shows icons while using ivy and counsel" '((emacs "24.4") (all-the-icons "2.4.0") (ivy "0.8.0")))
|
|
@ -0,0 +1,107 @@
|
||||||
|
;;; all-the-icons-ivy.el --- Shows icons while using ivy and counsel -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2017 asok
|
||||||
|
|
||||||
|
;; Author: asok
|
||||||
|
;; Version: 0.2.0
|
||||||
|
;; Package-Version: 20180225.630
|
||||||
|
;; Keywords: faces
|
||||||
|
;; Package-Requires: ((emacs "24.4") (all-the-icons "2.4.0") (ivy "0.8.0"))
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;; To use this package, do
|
||||||
|
;;
|
||||||
|
;; (all-the-icons-ivy-setup)
|
||||||
|
;;
|
||||||
|
;; Or if you prefer to only set transformers
|
||||||
|
;; for a subset of ivy commands:
|
||||||
|
;;
|
||||||
|
;; (require 'all-the-icons-ivy)
|
||||||
|
;; (ivy-set-display-transformer 'ivy-switch-buffer 'all-the-icons-ivy-buffer-transformer)
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'all-the-icons)
|
||||||
|
(require 'ivy)
|
||||||
|
|
||||||
|
(defgroup all-the-icons-ivy nil
|
||||||
|
"Shows icons while using ivy and counsel."
|
||||||
|
:group 'ivy)
|
||||||
|
|
||||||
|
(defcustom all-the-icons-ivy-buffer-commands
|
||||||
|
'(ivy-switch-buffer ivy-switch-buffer-other-window counsel-projectile-switch-to-buffer)
|
||||||
|
"Commands to use with `all-the-icons-ivy-buffer-transformer'."
|
||||||
|
:type '(repeat function)
|
||||||
|
:group 'all-the-icons-ivy)
|
||||||
|
|
||||||
|
|
||||||
|
(defcustom all-the-icons-ivy-file-commands
|
||||||
|
'(counsel-find-file counsel-projectile-find-file counsel-projectile-find-dir)
|
||||||
|
"Commands to use with `all-the-icons-ivy-file-transformer'."
|
||||||
|
:type '(repeat function)
|
||||||
|
:group 'all-the-icons-ivy)
|
||||||
|
|
||||||
|
(defun all-the-icons-ivy--buffer-propertize (b s)
|
||||||
|
"If buffer B is modified apply `ivy-modified-buffer' face on string S."
|
||||||
|
(if (and (buffer-file-name b)
|
||||||
|
(buffer-modified-p b))
|
||||||
|
(propertize s 'face 'ivy-modified-buffer)
|
||||||
|
s))
|
||||||
|
|
||||||
|
(defun all-the-icons-ivy--icon-for-mode (mode)
|
||||||
|
"Apply `all-the-icons-for-mode' on MODE but either return an icon or nil."
|
||||||
|
(let ((icon (all-the-icons-icon-for-mode mode)))
|
||||||
|
(unless (symbolp icon)
|
||||||
|
icon)))
|
||||||
|
|
||||||
|
(defun all-the-icons-ivy--buffer-transformer (b s)
|
||||||
|
"Return a candidate string for buffer B named S preceded by an icon.
|
||||||
|
Try to find the icon for the buffer's B `major-mode'.
|
||||||
|
If that fails look for an icon for the mode that the `major-mode' is derived from."
|
||||||
|
(let ((mode (buffer-local-value 'major-mode b)))
|
||||||
|
(format "%s\t%s"
|
||||||
|
(propertize "\t" 'display (or
|
||||||
|
(all-the-icons-ivy--icon-for-mode mode)
|
||||||
|
(all-the-icons-ivy--icon-for-mode (get mode 'derived-mode-parent))))
|
||||||
|
(all-the-icons-ivy--buffer-propertize b s))))
|
||||||
|
|
||||||
|
(defun all-the-icons-ivy-file-transformer (s)
|
||||||
|
"Return a candidate string for filename S preceded by an icon."
|
||||||
|
(format "%s\t%s"
|
||||||
|
(propertize "\t" 'display (all-the-icons-icon-for-file s))
|
||||||
|
s))
|
||||||
|
|
||||||
|
(defun all-the-icons-ivy-buffer-transformer (s)
|
||||||
|
"Return a candidate string for buffer named S.
|
||||||
|
Assume that sometimes the buffer named S might not exists.
|
||||||
|
That can happen if `ivy-switch-buffer' does not find the buffer and it
|
||||||
|
falls back to `ivy-recentf' and the same transformer is used."
|
||||||
|
(let ((b (get-buffer s)))
|
||||||
|
(if b
|
||||||
|
(all-the-icons-ivy--buffer-transformer b s)
|
||||||
|
(all-the-icons-ivy-file-transformer s))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun all-the-icons-ivy-setup ()
|
||||||
|
"Set ivy's display transformers to show relevant icons next to the candidates."
|
||||||
|
(dolist (cmd all-the-icons-ivy-buffer-commands)
|
||||||
|
(ivy-set-display-transformer cmd 'all-the-icons-ivy-buffer-transformer))
|
||||||
|
(dolist (cmd all-the-icons-ivy-file-commands)
|
||||||
|
(ivy-set-display-transformer cmd 'all-the-icons-ivy-file-transformer)))
|
||||||
|
|
||||||
|
(provide 'all-the-icons-ivy)
|
||||||
|
|
||||||
|
;;; all-the-icons-ivy.el ends here
|
Binary file not shown.
1293
configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents
Normal file
1293
configs/shared/emacs/.emacs.d/elpa/archives/gnu/archive-contents
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1 @@
|
||||||
|
Good signature from 474F05837FBDEF9B GNU ELPA Signing Agent <elpasign@elpa.gnu.org> (trust undefined) created at 2018-07-20T05:10:02-0400 using DSA
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,158 @@
|
||||||
|
;;; async-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "async" "async.el" (23377 61605 799563 818000))
|
||||||
|
;;; Generated autoloads from async.el
|
||||||
|
|
||||||
|
(autoload 'async-start-process "async" "\
|
||||||
|
Start the executable PROGRAM asynchronously. See `async-start'.
|
||||||
|
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
|
||||||
|
process object when done. If FINISH-FUNC is nil, the future
|
||||||
|
object will return the process object when the program is
|
||||||
|
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
|
||||||
|
working directory.
|
||||||
|
|
||||||
|
\(fn NAME PROGRAM FINISH-FUNC &rest PROGRAM-ARGS)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'async-start "async" "\
|
||||||
|
Execute START-FUNC (often a lambda) in a subordinate Emacs process.
|
||||||
|
When done, the return value is passed to FINISH-FUNC. Example:
|
||||||
|
|
||||||
|
(async-start
|
||||||
|
;; What to do in the child process
|
||||||
|
(lambda ()
|
||||||
|
(message \"This is a test\")
|
||||||
|
(sleep-for 3)
|
||||||
|
222)
|
||||||
|
|
||||||
|
;; What to do when it finishes
|
||||||
|
(lambda (result)
|
||||||
|
(message \"Async process done, result should be 222: %s\"
|
||||||
|
result)))
|
||||||
|
|
||||||
|
If FINISH-FUNC is nil or missing, a future is returned that can
|
||||||
|
be inspected using `async-get', blocking until the value is
|
||||||
|
ready. Example:
|
||||||
|
|
||||||
|
(let ((proc (async-start
|
||||||
|
;; What to do in the child process
|
||||||
|
(lambda ()
|
||||||
|
(message \"This is a test\")
|
||||||
|
(sleep-for 3)
|
||||||
|
222))))
|
||||||
|
|
||||||
|
(message \"I'm going to do some work here\") ;; ....
|
||||||
|
|
||||||
|
(message \"Waiting on async process, result should be 222: %s\"
|
||||||
|
(async-get proc)))
|
||||||
|
|
||||||
|
If you don't want to use a callback, and you don't care about any
|
||||||
|
return value from the child process, pass the `ignore' symbol as
|
||||||
|
the second argument (if you don't, and never call `async-get', it
|
||||||
|
will leave *emacs* process buffers hanging around):
|
||||||
|
|
||||||
|
(async-start
|
||||||
|
(lambda ()
|
||||||
|
(delete-file \"a remote file on a slow link\" nil))
|
||||||
|
'ignore)
|
||||||
|
|
||||||
|
Note: Even when FINISH-FUNC is present, a future is still
|
||||||
|
returned except that it yields no value (since the value is
|
||||||
|
passed to FINISH-FUNC). Call `async-get' on such a future always
|
||||||
|
returns nil. It can still be useful, however, as an argument to
|
||||||
|
`async-ready' or `async-wait'.
|
||||||
|
|
||||||
|
\(fn START-FUNC &optional FINISH-FUNC)" nil nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "async-bytecomp" "async-bytecomp.el" (23377
|
||||||
|
;;;;;; 61605 797595 754000))
|
||||||
|
;;; Generated autoloads from async-bytecomp.el
|
||||||
|
|
||||||
|
(autoload 'async-byte-recompile-directory "async-bytecomp" "\
|
||||||
|
Compile all *.el files in DIRECTORY asynchronously.
|
||||||
|
All *.elc files are systematically deleted before proceeding.
|
||||||
|
|
||||||
|
\(fn DIRECTORY &optional QUIET)" nil nil)
|
||||||
|
|
||||||
|
(defvar async-bytecomp-package-mode nil "\
|
||||||
|
Non-nil if Async-Bytecomp-Package mode is enabled.
|
||||||
|
See the `async-bytecomp-package-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `async-bytecomp-package-mode'.")
|
||||||
|
|
||||||
|
(custom-autoload 'async-bytecomp-package-mode "async-bytecomp" nil)
|
||||||
|
|
||||||
|
(autoload 'async-bytecomp-package-mode "async-bytecomp" "\
|
||||||
|
Byte compile asynchronously packages installed with package.el.
|
||||||
|
Async compilation of packages can be controlled by
|
||||||
|
`async-bytecomp-allowed-packages'.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'async-byte-compile-file "async-bytecomp" "\
|
||||||
|
Byte compile Lisp code FILE asynchronously.
|
||||||
|
|
||||||
|
Same as `byte-compile-file' but asynchronous.
|
||||||
|
|
||||||
|
\(fn FILE)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "dired-async" "dired-async.el" (23377 61605
|
||||||
|
;;;;;; 793062 430000))
|
||||||
|
;;; Generated autoloads from dired-async.el
|
||||||
|
|
||||||
|
(defvar dired-async-mode nil "\
|
||||||
|
Non-nil if Dired-Async mode is enabled.
|
||||||
|
See the `dired-async-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `dired-async-mode'.")
|
||||||
|
|
||||||
|
(custom-autoload 'dired-async-mode "dired-async" nil)
|
||||||
|
|
||||||
|
(autoload 'dired-async-mode "dired-async" "\
|
||||||
|
Do dired actions asynchronously.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'dired-async-do-copy "dired-async" "\
|
||||||
|
Run ‘dired-do-copy’ asynchronously.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'dired-async-do-symlink "dired-async" "\
|
||||||
|
Run ‘dired-do-symlink’ asynchronously.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'dired-async-do-hardlink "dired-async" "\
|
||||||
|
Run ‘dired-do-hardlink’ asynchronously.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'dired-async-do-rename "dired-async" "\
|
||||||
|
Run ‘dired-do-rename’ asynchronously.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil nil ("async-pkg.el" "smtpmail-async.el") (23377
|
||||||
|
;;;;;; 61605 801409 281000))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; async-autoloads.el ends here
|
|
@ -0,0 +1,219 @@
|
||||||
|
;;; async-bytecomp.el --- Compile elisp files asynchronously -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2014-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Authors: John Wiegley <jwiegley@gmail.com>
|
||||||
|
;; Thierry Volpiatto <thierry.volpiatto@gmail.com>
|
||||||
|
|
||||||
|
;; Keywords: dired async byte-compile
|
||||||
|
;; X-URL: https://github.com/jwiegley/dired-async
|
||||||
|
|
||||||
|
;; 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, or (at
|
||||||
|
;; your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful, but
|
||||||
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; This package provide the `async-byte-recompile-directory' function
|
||||||
|
;; which allows, as the name says to recompile a directory outside of
|
||||||
|
;; your running emacs.
|
||||||
|
;; The benefit is your files will be compiled in a clean environment without
|
||||||
|
;; the old *.el files loaded.
|
||||||
|
;; Among other things, this fix a bug in package.el which recompile
|
||||||
|
;; the new files in the current environment with the old files loaded, creating
|
||||||
|
;; errors in most packages after upgrades.
|
||||||
|
;;
|
||||||
|
;; NB: This package is advicing the function `package--compile'.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'async)
|
||||||
|
|
||||||
|
(defcustom async-bytecomp-allowed-packages
|
||||||
|
'(async helm helm-core helm-ls-git helm-ls-hg magit)
|
||||||
|
"Packages in this list will be compiled asynchronously by `package--compile'.
|
||||||
|
All the dependencies of these packages will be compiled async too,
|
||||||
|
so no need to add dependencies to this list.
|
||||||
|
The value of this variable can also be a list with a single element,
|
||||||
|
the symbol `all', in this case packages are always compiled asynchronously."
|
||||||
|
:group 'async
|
||||||
|
:type '(repeat (choice symbol)))
|
||||||
|
|
||||||
|
(defvar async-byte-compile-log-file
|
||||||
|
(concat user-emacs-directory "async-bytecomp.log"))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun async-byte-recompile-directory (directory &optional quiet)
|
||||||
|
"Compile all *.el files in DIRECTORY asynchronously.
|
||||||
|
All *.elc files are systematically deleted before proceeding."
|
||||||
|
(cl-loop with dir = (directory-files directory t "\\.elc\\'")
|
||||||
|
unless dir return nil
|
||||||
|
for f in dir
|
||||||
|
when (file-exists-p f) do (delete-file f))
|
||||||
|
;; Ensure async is reloaded when async.elc is deleted.
|
||||||
|
;; This happen when recompiling its own directory.
|
||||||
|
(load "async")
|
||||||
|
(let ((call-back
|
||||||
|
(lambda (&optional _ignore)
|
||||||
|
(if (file-exists-p async-byte-compile-log-file)
|
||||||
|
(let ((buf (get-buffer-create byte-compile-log-buffer))
|
||||||
|
(n 0))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-max))
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(insert-file-contents async-byte-compile-log-file)
|
||||||
|
(compilation-mode))
|
||||||
|
(display-buffer buf)
|
||||||
|
(delete-file async-byte-compile-log-file)
|
||||||
|
(unless quiet
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward "^.*:Error:" nil t)
|
||||||
|
(cl-incf n)))
|
||||||
|
(if (> n 0)
|
||||||
|
(message "Failed to compile %d files in directory `%s'" n directory)
|
||||||
|
(message "Directory `%s' compiled asynchronously with warnings" directory)))))
|
||||||
|
(unless quiet
|
||||||
|
(message "Directory `%s' compiled asynchronously with success" directory))))))
|
||||||
|
(async-start
|
||||||
|
`(lambda ()
|
||||||
|
(require 'bytecomp)
|
||||||
|
,(async-inject-variables "\\`\\(load-path\\)\\|byte\\'")
|
||||||
|
(let ((default-directory (file-name-as-directory ,directory))
|
||||||
|
error-data)
|
||||||
|
(add-to-list 'load-path default-directory)
|
||||||
|
(byte-recompile-directory ,directory 0 t)
|
||||||
|
(when (get-buffer byte-compile-log-buffer)
|
||||||
|
(setq error-data (with-current-buffer byte-compile-log-buffer
|
||||||
|
(buffer-substring-no-properties (point-min) (point-max))))
|
||||||
|
(unless (string= error-data "")
|
||||||
|
(with-temp-file ,async-byte-compile-log-file
|
||||||
|
(erase-buffer)
|
||||||
|
(insert error-data))))))
|
||||||
|
call-back)
|
||||||
|
(unless quiet (message "Started compiling asynchronously directory %s" directory))))
|
||||||
|
|
||||||
|
(defvar package-archive-contents)
|
||||||
|
(defvar package-alist)
|
||||||
|
(declare-function package-desc-reqs "package.el" (cl-x))
|
||||||
|
|
||||||
|
(defun async-bytecomp--get-package-deps (pkg &optional only)
|
||||||
|
;; Same as `package--get-deps' but parse instead `package-archive-contents'
|
||||||
|
;; because PKG is not already installed and not present in `package-alist'.
|
||||||
|
;; However fallback to `package-alist' in case PKG no more present
|
||||||
|
;; in `package-archive-contents' due to modification to `package-archives'.
|
||||||
|
;; See issue #58.
|
||||||
|
(let* ((pkg-desc (cadr (or (assq pkg package-archive-contents)
|
||||||
|
(assq pkg package-alist))))
|
||||||
|
(direct-deps (cl-loop for p in (package-desc-reqs pkg-desc)
|
||||||
|
for name = (car p)
|
||||||
|
when (or (assq name package-archive-contents)
|
||||||
|
(assq name package-alist))
|
||||||
|
collect name))
|
||||||
|
(indirect-deps (unless (eq only 'direct)
|
||||||
|
(delete-dups
|
||||||
|
(cl-loop for p in direct-deps append
|
||||||
|
(async-bytecomp--get-package-deps p))))))
|
||||||
|
(cl-case only
|
||||||
|
(direct direct-deps)
|
||||||
|
(separate (list direct-deps indirect-deps))
|
||||||
|
(indirect indirect-deps)
|
||||||
|
(t (delete-dups (append direct-deps indirect-deps))))))
|
||||||
|
|
||||||
|
(defun async-bytecomp-get-allowed-pkgs ()
|
||||||
|
(when (and async-bytecomp-allowed-packages
|
||||||
|
(listp async-bytecomp-allowed-packages))
|
||||||
|
(if package-archive-contents
|
||||||
|
(cl-loop for p in async-bytecomp-allowed-packages
|
||||||
|
when (assq p package-archive-contents)
|
||||||
|
append (async-bytecomp--get-package-deps p) into reqs
|
||||||
|
finally return
|
||||||
|
(delete-dups
|
||||||
|
(append async-bytecomp-allowed-packages reqs)))
|
||||||
|
async-bytecomp-allowed-packages)))
|
||||||
|
|
||||||
|
(defadvice package--compile (around byte-compile-async)
|
||||||
|
(let ((cur-package (package-desc-name pkg-desc))
|
||||||
|
(pkg-dir (package-desc-dir pkg-desc)))
|
||||||
|
(if (or (equal async-bytecomp-allowed-packages '(all))
|
||||||
|
(memq cur-package (async-bytecomp-get-allowed-pkgs)))
|
||||||
|
(progn
|
||||||
|
(when (eq cur-package 'async)
|
||||||
|
(fmakunbound 'async-byte-recompile-directory))
|
||||||
|
;; Add to `load-path' the latest version of async and
|
||||||
|
;; reload it when reinstalling async.
|
||||||
|
(when (string= cur-package "async")
|
||||||
|
(cl-pushnew pkg-dir load-path)
|
||||||
|
(load "async-bytecomp"))
|
||||||
|
;; `async-byte-recompile-directory' will add directory
|
||||||
|
;; as needed to `load-path'.
|
||||||
|
(async-byte-recompile-directory (package-desc-dir pkg-desc) t))
|
||||||
|
ad-do-it)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode async-bytecomp-package-mode
|
||||||
|
"Byte compile asynchronously packages installed with package.el.
|
||||||
|
Async compilation of packages can be controlled by
|
||||||
|
`async-bytecomp-allowed-packages'."
|
||||||
|
:group 'async
|
||||||
|
:global t
|
||||||
|
(if async-bytecomp-package-mode
|
||||||
|
(ad-activate 'package--compile)
|
||||||
|
(ad-deactivate 'package--compile)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun async-byte-compile-file (file)
|
||||||
|
"Byte compile Lisp code FILE asynchronously.
|
||||||
|
|
||||||
|
Same as `byte-compile-file' but asynchronous."
|
||||||
|
(interactive "fFile: ")
|
||||||
|
(let ((call-back
|
||||||
|
(lambda (&optional _ignore)
|
||||||
|
(let ((bn (file-name-nondirectory file)))
|
||||||
|
(if (file-exists-p async-byte-compile-log-file)
|
||||||
|
(let ((buf (get-buffer-create byte-compile-log-buffer))
|
||||||
|
start)
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (setq start (point-max)))
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(insert-file-contents async-byte-compile-log-file)
|
||||||
|
(compilation-mode))
|
||||||
|
(display-buffer buf)
|
||||||
|
(delete-file async-byte-compile-log-file)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char start)
|
||||||
|
(if (re-search-forward "^.*:Error:" nil t)
|
||||||
|
(message "Failed to compile `%s'" bn)
|
||||||
|
(message "`%s' compiled asynchronously with warnings" bn)))))
|
||||||
|
(message "`%s' compiled asynchronously with success" bn))))))
|
||||||
|
(async-start
|
||||||
|
`(lambda ()
|
||||||
|
(require 'bytecomp)
|
||||||
|
,(async-inject-variables "\\`load-path\\'")
|
||||||
|
(let ((default-directory ,(file-name-directory file)))
|
||||||
|
(add-to-list 'load-path default-directory)
|
||||||
|
(byte-compile-file ,file)
|
||||||
|
(when (get-buffer byte-compile-log-buffer)
|
||||||
|
(setq error-data (with-current-buffer byte-compile-log-buffer
|
||||||
|
(buffer-substring-no-properties (point-min) (point-max))))
|
||||||
|
(unless (string= error-data "")
|
||||||
|
(with-temp-file ,async-byte-compile-log-file
|
||||||
|
(erase-buffer)
|
||||||
|
(insert error-data))))))
|
||||||
|
call-back)))
|
||||||
|
|
||||||
|
(provide 'async-bytecomp)
|
||||||
|
|
||||||
|
;;; async-bytecomp.el ends here
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
||||||
|
(define-package "async" "20180527.1030" "Asynchronous processing in Emacs" 'nil :keywords
|
||||||
|
'("async")
|
||||||
|
:url "https://github.com/jwiegley/emacs-async")
|
||||||
|
;; Local Variables:
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; End:
|
392
configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el
Normal file
392
configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.el
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
;;; async.el --- Asynchronous processing in Emacs -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: John Wiegley <jwiegley@gmail.com>
|
||||||
|
;; Created: 18 Jun 2012
|
||||||
|
;; Version: 1.9.3
|
||||||
|
|
||||||
|
;; Keywords: async
|
||||||
|
;; X-URL: https://github.com/jwiegley/emacs-async
|
||||||
|
|
||||||
|
;; 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, or (at
|
||||||
|
;; your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful, but
|
||||||
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Adds the ability to call asynchronous functions and process with ease. See
|
||||||
|
;; the documentation for `async-start' and `async-start-process'.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(eval-when-compile (require 'cl-lib))
|
||||||
|
|
||||||
|
(defgroup async nil
|
||||||
|
"Simple asynchronous processing in Emacs"
|
||||||
|
:group 'emacs)
|
||||||
|
|
||||||
|
(defcustom async-variables-noprops-function #'async-variables-noprops
|
||||||
|
"Default function to remove text properties in variables."
|
||||||
|
:group 'async
|
||||||
|
:type 'function)
|
||||||
|
|
||||||
|
(defvar async-debug nil)
|
||||||
|
(defvar async-send-over-pipe t)
|
||||||
|
(defvar async-in-child-emacs nil)
|
||||||
|
(defvar async-callback nil)
|
||||||
|
(defvar async-callback-for-process nil)
|
||||||
|
(defvar async-callback-value nil)
|
||||||
|
(defvar async-callback-value-set nil)
|
||||||
|
(defvar async-current-process nil)
|
||||||
|
(defvar async--procvar nil)
|
||||||
|
|
||||||
|
(defun async-variables-noprops (sequence)
|
||||||
|
"Remove text properties in SEQUENCE.
|
||||||
|
|
||||||
|
Argument SEQUENCE may be a list or a string, if anything else it
|
||||||
|
is returned unmodified.
|
||||||
|
|
||||||
|
Note that this is a naive function that doesn't remove text properties
|
||||||
|
in SEQUENCE recursively, only at the first level which suffice in most
|
||||||
|
cases."
|
||||||
|
(cond ((stringp sequence)
|
||||||
|
(substring-no-properties sequence))
|
||||||
|
((listp sequence)
|
||||||
|
(cl-loop for elm in sequence
|
||||||
|
if (stringp elm)
|
||||||
|
collect (substring-no-properties elm)
|
||||||
|
else collect elm))
|
||||||
|
(t sequence)))
|
||||||
|
|
||||||
|
(defun async-inject-variables
|
||||||
|
(include-regexp &optional predicate exclude-regexp noprops)
|
||||||
|
"Return a `setq' form that replicates part of the calling environment.
|
||||||
|
|
||||||
|
It sets the value for every variable matching INCLUDE-REGEXP and
|
||||||
|
also PREDICATE. It will not perform injection for any variable
|
||||||
|
matching EXCLUDE-REGEXP (if present) or representing a syntax-table
|
||||||
|
i.e. ending by \"-syntax-table\".
|
||||||
|
When NOPROPS is non nil it tries to strip out text properties of each
|
||||||
|
variable's value with `async-variables-noprops-function'.
|
||||||
|
|
||||||
|
It is intended to be used as follows:
|
||||||
|
|
||||||
|
(async-start
|
||||||
|
`(lambda ()
|
||||||
|
(require 'smtpmail)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert ,(buffer-substring-no-properties (point-min) (point-max)))
|
||||||
|
;; Pass in the variable environment for smtpmail
|
||||||
|
,(async-inject-variables \"\\`\\(smtpmail\\|\\(user-\\)?mail\\)-\")
|
||||||
|
(smtpmail-send-it)))
|
||||||
|
'ignore)"
|
||||||
|
`(setq
|
||||||
|
,@(let (bindings)
|
||||||
|
(mapatoms
|
||||||
|
(lambda (sym)
|
||||||
|
(let* ((sname (and (boundp sym) (symbol-name sym)))
|
||||||
|
(value (and sname (symbol-value sym))))
|
||||||
|
(when (and sname
|
||||||
|
(or (null include-regexp)
|
||||||
|
(string-match include-regexp sname))
|
||||||
|
(or (null exclude-regexp)
|
||||||
|
(not (string-match exclude-regexp sname)))
|
||||||
|
(not (string-match "-syntax-table\\'" sname)))
|
||||||
|
(unless (or (stringp value)
|
||||||
|
(memq value '(nil t))
|
||||||
|
(numberp value)
|
||||||
|
(vectorp value))
|
||||||
|
(setq value `(quote ,value)))
|
||||||
|
(when noprops
|
||||||
|
(setq value (funcall async-variables-noprops-function
|
||||||
|
value)))
|
||||||
|
(when (or (null predicate)
|
||||||
|
(funcall predicate sym))
|
||||||
|
(setq bindings (cons value bindings)
|
||||||
|
bindings (cons sym bindings)))))))
|
||||||
|
bindings)))
|
||||||
|
|
||||||
|
(defalias 'async-inject-environment 'async-inject-variables)
|
||||||
|
|
||||||
|
(defun async-handle-result (func result buf)
|
||||||
|
(if (null func)
|
||||||
|
(progn
|
||||||
|
(set (make-local-variable 'async-callback-value) result)
|
||||||
|
(set (make-local-variable 'async-callback-value-set) t))
|
||||||
|
(unwind-protect
|
||||||
|
(if (and (listp result)
|
||||||
|
(eq 'async-signal (nth 0 result)))
|
||||||
|
(signal (car (nth 1 result))
|
||||||
|
(cdr (nth 1 result)))
|
||||||
|
(funcall func result))
|
||||||
|
(unless async-debug
|
||||||
|
(kill-buffer buf)))))
|
||||||
|
|
||||||
|
(defun async-when-done (proc &optional _change)
|
||||||
|
"Process sentinel used to retrieve the value from the child process."
|
||||||
|
(when (eq 'exit (process-status proc))
|
||||||
|
(with-current-buffer (process-buffer proc)
|
||||||
|
(let ((async-current-process proc))
|
||||||
|
(if (= 0 (process-exit-status proc))
|
||||||
|
(if async-callback-for-process
|
||||||
|
(if async-callback
|
||||||
|
(prog1
|
||||||
|
(funcall async-callback proc)
|
||||||
|
(unless async-debug
|
||||||
|
(kill-buffer (current-buffer))))
|
||||||
|
(set (make-local-variable 'async-callback-value) proc)
|
||||||
|
(set (make-local-variable 'async-callback-value-set) t))
|
||||||
|
(goto-char (point-max))
|
||||||
|
(backward-sexp)
|
||||||
|
(async-handle-result async-callback (read (current-buffer))
|
||||||
|
(current-buffer)))
|
||||||
|
(set (make-local-variable 'async-callback-value)
|
||||||
|
(list 'error
|
||||||
|
(format "Async process '%s' failed with exit code %d"
|
||||||
|
(process-name proc) (process-exit-status proc))))
|
||||||
|
(set (make-local-variable 'async-callback-value-set) t))))))
|
||||||
|
|
||||||
|
(defun async--receive-sexp (&optional stream)
|
||||||
|
(let ((sexp (decode-coding-string (base64-decode-string
|
||||||
|
(read stream)) 'utf-8-auto))
|
||||||
|
;; Parent expects UTF-8 encoded text.
|
||||||
|
(coding-system-for-write 'utf-8-auto))
|
||||||
|
(if async-debug
|
||||||
|
(message "Received sexp {{{%s}}}" (pp-to-string sexp)))
|
||||||
|
(setq sexp (read sexp))
|
||||||
|
(if async-debug
|
||||||
|
(message "Read sexp {{{%s}}}" (pp-to-string sexp)))
|
||||||
|
(eval sexp)))
|
||||||
|
|
||||||
|
(defun async--insert-sexp (sexp)
|
||||||
|
(let (print-level
|
||||||
|
print-length
|
||||||
|
(print-escape-nonascii t)
|
||||||
|
(print-circle t))
|
||||||
|
(prin1 sexp (current-buffer))
|
||||||
|
;; Just in case the string we're sending might contain EOF
|
||||||
|
(encode-coding-region (point-min) (point-max) 'utf-8-auto)
|
||||||
|
(base64-encode-region (point-min) (point-max) t)
|
||||||
|
(goto-char (point-min)) (insert ?\")
|
||||||
|
(goto-char (point-max)) (insert ?\" ?\n)))
|
||||||
|
|
||||||
|
(defun async--transmit-sexp (process sexp)
|
||||||
|
(with-temp-buffer
|
||||||
|
(if async-debug
|
||||||
|
(message "Transmitting sexp {{{%s}}}" (pp-to-string sexp)))
|
||||||
|
(async--insert-sexp sexp)
|
||||||
|
(process-send-region process (point-min) (point-max))))
|
||||||
|
|
||||||
|
(defun async-batch-invoke ()
|
||||||
|
"Called from the child Emacs process' command-line."
|
||||||
|
;; Make sure 'message' and 'prin1' encode stuff in UTF-8, as parent
|
||||||
|
;; process expects.
|
||||||
|
(let ((coding-system-for-write 'utf-8-auto))
|
||||||
|
(setq async-in-child-emacs t
|
||||||
|
debug-on-error async-debug)
|
||||||
|
(if debug-on-error
|
||||||
|
(prin1 (funcall
|
||||||
|
(async--receive-sexp (unless async-send-over-pipe
|
||||||
|
command-line-args-left))))
|
||||||
|
(condition-case err
|
||||||
|
(prin1 (funcall
|
||||||
|
(async--receive-sexp (unless async-send-over-pipe
|
||||||
|
command-line-args-left))))
|
||||||
|
(error
|
||||||
|
(prin1 (list 'async-signal err)))))))
|
||||||
|
|
||||||
|
(defun async-ready (future)
|
||||||
|
"Query a FUTURE to see if it is ready.
|
||||||
|
|
||||||
|
I.e., if no blocking
|
||||||
|
would result from a call to `async-get' on that FUTURE."
|
||||||
|
(and (memq (process-status future) '(exit signal))
|
||||||
|
(let ((buf (process-buffer future)))
|
||||||
|
(if (buffer-live-p buf)
|
||||||
|
(with-current-buffer buf
|
||||||
|
async-callback-value-set)
|
||||||
|
t))))
|
||||||
|
|
||||||
|
(defun async-wait (future)
|
||||||
|
"Wait for FUTURE to become ready."
|
||||||
|
(while (not (async-ready future))
|
||||||
|
(sleep-for 0.05)))
|
||||||
|
|
||||||
|
(defun async-get (future)
|
||||||
|
"Get the value from process FUTURE when it is ready.
|
||||||
|
FUTURE is returned by `async-start' or `async-start-process' when
|
||||||
|
its FINISH-FUNC is nil."
|
||||||
|
(and future (async-wait future))
|
||||||
|
(let ((buf (process-buffer future)))
|
||||||
|
(when (buffer-live-p buf)
|
||||||
|
(with-current-buffer buf
|
||||||
|
(async-handle-result
|
||||||
|
#'identity async-callback-value (current-buffer))))))
|
||||||
|
|
||||||
|
(defun async-message-p (value)
|
||||||
|
"Return true of VALUE is an async.el message packet."
|
||||||
|
(and (listp value)
|
||||||
|
(plist-get value :async-message)))
|
||||||
|
|
||||||
|
(defun async-send (&rest args)
|
||||||
|
"Send the given messages to the asychronous Emacs PROCESS."
|
||||||
|
(let ((args (append args '(:async-message t))))
|
||||||
|
(if async-in-child-emacs
|
||||||
|
(if async-callback
|
||||||
|
(funcall async-callback args))
|
||||||
|
(async--transmit-sexp (car args) (list 'quote (cdr args))))))
|
||||||
|
|
||||||
|
(defun async-receive ()
|
||||||
|
"Send the given messages to the asychronous Emacs PROCESS."
|
||||||
|
(async--receive-sexp))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun async-start-process (name program finish-func &rest program-args)
|
||||||
|
"Start the executable PROGRAM asynchronously. See `async-start'.
|
||||||
|
PROGRAM is passed PROGRAM-ARGS, calling FINISH-FUNC with the
|
||||||
|
process object when done. If FINISH-FUNC is nil, the future
|
||||||
|
object will return the process object when the program is
|
||||||
|
finished. Set DEFAULT-DIRECTORY to change PROGRAM's current
|
||||||
|
working directory."
|
||||||
|
(let* ((buf (generate-new-buffer (concat "*" name "*")))
|
||||||
|
(proc (let ((process-connection-type nil))
|
||||||
|
(apply #'start-process name buf program program-args))))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(set (make-local-variable 'async-callback) finish-func)
|
||||||
|
(set-process-sentinel proc #'async-when-done)
|
||||||
|
(unless (string= name "emacs")
|
||||||
|
(set (make-local-variable 'async-callback-for-process) t))
|
||||||
|
proc)))
|
||||||
|
|
||||||
|
(defvar async-quiet-switch "-Q"
|
||||||
|
"The Emacs parameter to use to call emacs without config.
|
||||||
|
Can be one of \"-Q\" or \"-q\".
|
||||||
|
Default is \"-Q\" but it is sometimes useful to use \"-q\" to have a
|
||||||
|
enhanced config or some more variables loaded.")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun async-start (start-func &optional finish-func)
|
||||||
|
"Execute START-FUNC (often a lambda) in a subordinate Emacs process.
|
||||||
|
When done, the return value is passed to FINISH-FUNC. Example:
|
||||||
|
|
||||||
|
(async-start
|
||||||
|
;; What to do in the child process
|
||||||
|
(lambda ()
|
||||||
|
(message \"This is a test\")
|
||||||
|
(sleep-for 3)
|
||||||
|
222)
|
||||||
|
|
||||||
|
;; What to do when it finishes
|
||||||
|
(lambda (result)
|
||||||
|
(message \"Async process done, result should be 222: %s\"
|
||||||
|
result)))
|
||||||
|
|
||||||
|
If FINISH-FUNC is nil or missing, a future is returned that can
|
||||||
|
be inspected using `async-get', blocking until the value is
|
||||||
|
ready. Example:
|
||||||
|
|
||||||
|
(let ((proc (async-start
|
||||||
|
;; What to do in the child process
|
||||||
|
(lambda ()
|
||||||
|
(message \"This is a test\")
|
||||||
|
(sleep-for 3)
|
||||||
|
222))))
|
||||||
|
|
||||||
|
(message \"I'm going to do some work here\") ;; ....
|
||||||
|
|
||||||
|
(message \"Waiting on async process, result should be 222: %s\"
|
||||||
|
(async-get proc)))
|
||||||
|
|
||||||
|
If you don't want to use a callback, and you don't care about any
|
||||||
|
return value from the child process, pass the `ignore' symbol as
|
||||||
|
the second argument (if you don't, and never call `async-get', it
|
||||||
|
will leave *emacs* process buffers hanging around):
|
||||||
|
|
||||||
|
(async-start
|
||||||
|
(lambda ()
|
||||||
|
(delete-file \"a remote file on a slow link\" nil))
|
||||||
|
'ignore)
|
||||||
|
|
||||||
|
Note: Even when FINISH-FUNC is present, a future is still
|
||||||
|
returned except that it yields no value (since the value is
|
||||||
|
passed to FINISH-FUNC). Call `async-get' on such a future always
|
||||||
|
returns nil. It can still be useful, however, as an argument to
|
||||||
|
`async-ready' or `async-wait'."
|
||||||
|
(let ((sexp start-func)
|
||||||
|
;; Subordinate Emacs will send text encoded in UTF-8.
|
||||||
|
(coding-system-for-read 'utf-8-auto))
|
||||||
|
(setq async--procvar
|
||||||
|
(async-start-process
|
||||||
|
"emacs" (file-truename
|
||||||
|
(expand-file-name invocation-name
|
||||||
|
invocation-directory))
|
||||||
|
finish-func
|
||||||
|
async-quiet-switch "-l"
|
||||||
|
;; Using `locate-library' ensure we use the right file
|
||||||
|
;; when the .elc have been deleted.
|
||||||
|
(locate-library "async")
|
||||||
|
"-batch" "-f" "async-batch-invoke"
|
||||||
|
(if async-send-over-pipe
|
||||||
|
"<none>"
|
||||||
|
(with-temp-buffer
|
||||||
|
(async--insert-sexp (list 'quote sexp))
|
||||||
|
(buffer-string)))))
|
||||||
|
(if async-send-over-pipe
|
||||||
|
(async--transmit-sexp async--procvar (list 'quote sexp)))
|
||||||
|
async--procvar))
|
||||||
|
|
||||||
|
(defmacro async-sandbox(func)
|
||||||
|
"Evaluate FUNC in a separate Emacs process, synchronously."
|
||||||
|
`(async-get (async-start ,func)))
|
||||||
|
|
||||||
|
(defun async--fold-left (fn forms bindings)
|
||||||
|
(let ((res forms))
|
||||||
|
(dolist (binding bindings)
|
||||||
|
(setq res (funcall fn res
|
||||||
|
(if (listp binding)
|
||||||
|
binding
|
||||||
|
(list binding)))))
|
||||||
|
res))
|
||||||
|
|
||||||
|
(defmacro async-let (bindings &rest forms)
|
||||||
|
"Implements `let', but each binding is established asynchronously.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
(async-let ((x (foo))
|
||||||
|
(y (bar)))
|
||||||
|
(message \"%s %s\" x y))
|
||||||
|
|
||||||
|
expands to ==>
|
||||||
|
|
||||||
|
(async-start (foo)
|
||||||
|
(lambda (x)
|
||||||
|
(async-start (bar)
|
||||||
|
(lambda (y)
|
||||||
|
(message \"%s %s\" x y)))))"
|
||||||
|
(declare (indent 1))
|
||||||
|
(async--fold-left
|
||||||
|
(lambda (acc binding)
|
||||||
|
(let ((fun (pcase (cadr binding)
|
||||||
|
((and (pred functionp) f) f)
|
||||||
|
(f `(lambda () ,f)))))
|
||||||
|
`(async-start ,fun
|
||||||
|
(lambda (,(car binding))
|
||||||
|
,acc))))
|
||||||
|
`(progn ,@forms)
|
||||||
|
(reverse bindings)))
|
||||||
|
|
||||||
|
(provide 'async)
|
||||||
|
|
||||||
|
;;; async.el ends here
|
BIN
configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elc
Normal file
BIN
configs/shared/emacs/.emacs.d/elpa/async-20180527.1030/async.elc
Normal file
Binary file not shown.
|
@ -0,0 +1,405 @@
|
||||||
|
;;; dired-async.el --- Asynchronous dired actions -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Authors: John Wiegley <jwiegley@gmail.com>
|
||||||
|
;; Thierry Volpiatto <thierry.volpiatto@gmail.com>
|
||||||
|
|
||||||
|
;; Keywords: dired async network
|
||||||
|
;; X-URL: https://github.com/jwiegley/dired-async
|
||||||
|
|
||||||
|
;; 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, or (at
|
||||||
|
;; your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful, but
|
||||||
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; This file provide a redefinition of `dired-create-file' function,
|
||||||
|
;; performs copies, moves and all what is handled by `dired-create-file'
|
||||||
|
;; in the background using a slave Emacs process,
|
||||||
|
;; by means of the async.el module.
|
||||||
|
;; To use it, put this in your .emacs:
|
||||||
|
|
||||||
|
;; (dired-async-mode 1)
|
||||||
|
|
||||||
|
;; This will enable async copy/rename etc...
|
||||||
|
;; in dired and helm.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'dired-aux)
|
||||||
|
(require 'async)
|
||||||
|
|
||||||
|
(eval-when-compile
|
||||||
|
(defvar async-callback))
|
||||||
|
|
||||||
|
(defgroup dired-async nil
|
||||||
|
"Copy rename files asynchronously from dired."
|
||||||
|
:group 'dired)
|
||||||
|
|
||||||
|
(defcustom dired-async-env-variables-regexp
|
||||||
|
"\\`\\(tramp-\\(default\\|connection\\|remote\\)\\|ange-ftp\\)-.*"
|
||||||
|
"Variables matching this regexp will be loaded on Child Emacs."
|
||||||
|
:type 'regexp
|
||||||
|
:group 'dired-async)
|
||||||
|
|
||||||
|
(defcustom dired-async-message-function 'dired-async-mode-line-message
|
||||||
|
"Function to use to notify result when operation finish.
|
||||||
|
Should take same args as `message'."
|
||||||
|
:group 'dired-async
|
||||||
|
:type 'function)
|
||||||
|
|
||||||
|
(defcustom dired-async-log-file "/tmp/dired-async.log"
|
||||||
|
"File use to communicate errors from Child Emacs to host Emacs."
|
||||||
|
:group 'dired-async
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
(defcustom dired-async-mode-lighter '(:eval
|
||||||
|
(when (eq major-mode 'dired-mode)
|
||||||
|
" Async"))
|
||||||
|
"Mode line lighter used for `dired-async-mode'."
|
||||||
|
:group 'dired-async
|
||||||
|
:risky t
|
||||||
|
:type 'sexp)
|
||||||
|
|
||||||
|
(defface dired-async-message
|
||||||
|
'((t (:foreground "yellow")))
|
||||||
|
"Face used for mode-line message."
|
||||||
|
:group 'dired-async)
|
||||||
|
|
||||||
|
(defface dired-async-failures
|
||||||
|
'((t (:foreground "red")))
|
||||||
|
"Face used for mode-line message."
|
||||||
|
:group 'dired-async)
|
||||||
|
|
||||||
|
(defface dired-async-mode-message
|
||||||
|
'((t (:foreground "Gold")))
|
||||||
|
"Face used for `dired-async--modeline-mode' lighter."
|
||||||
|
:group 'dired-async)
|
||||||
|
|
||||||
|
(define-minor-mode dired-async--modeline-mode
|
||||||
|
"Notify mode-line that an async process run."
|
||||||
|
:group 'dired-async
|
||||||
|
:global t
|
||||||
|
:lighter (:eval (propertize (format " [%s Async job(s) running]"
|
||||||
|
(length (dired-async-processes)))
|
||||||
|
'face 'dired-async-mode-message))
|
||||||
|
(unless dired-async--modeline-mode
|
||||||
|
(let ((visible-bell t)) (ding))))
|
||||||
|
|
||||||
|
(defun dired-async-mode-line-message (text face &rest args)
|
||||||
|
"Notify end of operation in `mode-line'."
|
||||||
|
(message nil)
|
||||||
|
(let ((mode-line-format (concat
|
||||||
|
" " (propertize
|
||||||
|
(if args
|
||||||
|
(apply #'format text args)
|
||||||
|
text)
|
||||||
|
'face face))))
|
||||||
|
(force-mode-line-update)
|
||||||
|
(sit-for 3)
|
||||||
|
(force-mode-line-update)))
|
||||||
|
|
||||||
|
(defun dired-async-processes ()
|
||||||
|
(cl-loop for p in (process-list)
|
||||||
|
when (cl-loop for c in (process-command p) thereis
|
||||||
|
(string= "async-batch-invoke" c))
|
||||||
|
collect p))
|
||||||
|
|
||||||
|
(defun dired-async-kill-process ()
|
||||||
|
(interactive)
|
||||||
|
(let* ((processes (dired-async-processes))
|
||||||
|
(proc (car (last processes))))
|
||||||
|
(and proc (delete-process proc))
|
||||||
|
(unless (> (length processes) 1)
|
||||||
|
(dired-async--modeline-mode -1))))
|
||||||
|
|
||||||
|
(defun dired-async-after-file-create (total operation failures skipped)
|
||||||
|
"Callback function used for operation handled by `dired-create-file'."
|
||||||
|
(unless (dired-async-processes)
|
||||||
|
;; Turn off mode-line notification
|
||||||
|
;; only when last process end.
|
||||||
|
(dired-async--modeline-mode -1))
|
||||||
|
(when operation
|
||||||
|
(if (file-exists-p dired-async-log-file)
|
||||||
|
(progn
|
||||||
|
(pop-to-buffer (get-buffer-create dired-log-buffer))
|
||||||
|
(goto-char (point-max))
|
||||||
|
(setq inhibit-read-only t)
|
||||||
|
(insert "Error: ")
|
||||||
|
(insert-file-contents dired-async-log-file)
|
||||||
|
(special-mode)
|
||||||
|
(shrink-window-if-larger-than-buffer)
|
||||||
|
(delete-file dired-async-log-file))
|
||||||
|
(run-with-timer
|
||||||
|
0.1 nil
|
||||||
|
(lambda ()
|
||||||
|
;; First send error messages.
|
||||||
|
(cond (failures
|
||||||
|
(funcall dired-async-message-function
|
||||||
|
"%s failed for %d of %d file%s -- See *Dired log* buffer"
|
||||||
|
'dired-async-failures
|
||||||
|
(car operation) (length failures)
|
||||||
|
total (dired-plural-s total)))
|
||||||
|
(skipped
|
||||||
|
(funcall dired-async-message-function
|
||||||
|
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
|
||||||
|
'dired-async-failures
|
||||||
|
(car operation) (length skipped) total
|
||||||
|
(dired-plural-s total))))
|
||||||
|
(when dired-buffers
|
||||||
|
(cl-loop for (_f . b) in dired-buffers
|
||||||
|
when (buffer-live-p b)
|
||||||
|
do (with-current-buffer b (revert-buffer nil t))))
|
||||||
|
;; Finally send the success message.
|
||||||
|
(funcall dired-async-message-function
|
||||||
|
"Asynchronous %s of %s on %s file%s done"
|
||||||
|
'dired-async-message
|
||||||
|
(car operation) (cadr operation)
|
||||||
|
total (dired-plural-s total)))))))
|
||||||
|
|
||||||
|
(defun dired-async-maybe-kill-ftp ()
|
||||||
|
"Return a form to kill ftp process in child emacs."
|
||||||
|
(quote
|
||||||
|
(progn
|
||||||
|
(require 'cl-lib)
|
||||||
|
(let ((buf (cl-loop for b in (buffer-list)
|
||||||
|
thereis (and (string-match
|
||||||
|
"\\`\\*ftp.*"
|
||||||
|
(buffer-name b)) b))))
|
||||||
|
(when buf (kill-buffer buf))))))
|
||||||
|
|
||||||
|
(defvar overwrite-query)
|
||||||
|
(defun dired-async-create-files (file-creator operation fn-list name-constructor
|
||||||
|
&optional _marker-char)
|
||||||
|
"Same as `dired-create-files' but asynchronous.
|
||||||
|
|
||||||
|
See `dired-create-files' for the behavior of arguments."
|
||||||
|
(setq overwrite-query nil)
|
||||||
|
(let ((total (length fn-list))
|
||||||
|
failures async-fn-list skipped callback
|
||||||
|
async-quiet-switch)
|
||||||
|
(let (to)
|
||||||
|
(dolist (from fn-list)
|
||||||
|
(setq to (funcall name-constructor from))
|
||||||
|
(if (and (equal to from)
|
||||||
|
(null (eq file-creator 'backup-file)))
|
||||||
|
(progn
|
||||||
|
(setq to nil)
|
||||||
|
(dired-log "Cannot %s to same file: %s\n"
|
||||||
|
(downcase operation) from)))
|
||||||
|
(if (not to)
|
||||||
|
(setq skipped (cons (dired-make-relative from) skipped))
|
||||||
|
(let* ((overwrite (and (null (eq file-creator 'backup-file))
|
||||||
|
(file-exists-p to)))
|
||||||
|
(dired-overwrite-confirmed ; for dired-handle-overwrite
|
||||||
|
(and overwrite
|
||||||
|
(let ((help-form `(format "\
|
||||||
|
Type SPC or `y' to overwrite file `%s',
|
||||||
|
DEL or `n' to skip to next,
|
||||||
|
ESC or `q' to not overwrite any of the remaining files,
|
||||||
|
`!' to overwrite all remaining files with no more questions." ,to)))
|
||||||
|
(dired-query 'overwrite-query "Overwrite `%s'?" to)))))
|
||||||
|
;; Handle the `dired-copy-file' file-creator specially
|
||||||
|
;; When copying a directory to another directory or
|
||||||
|
;; possibly to itself or one of its subdirectories.
|
||||||
|
;; e.g "~/foo/" => "~/test/"
|
||||||
|
;; or "~/foo/" =>"~/foo/"
|
||||||
|
;; or "~/foo/ => ~/foo/bar/")
|
||||||
|
;; In this case the 'name-constructor' have set the destination
|
||||||
|
;; TO to "~/test/foo" because the old emacs23 behavior
|
||||||
|
;; of `copy-directory' was to not create the subdirectory
|
||||||
|
;; and instead copy the contents.
|
||||||
|
;; With the new behavior of `copy-directory'
|
||||||
|
;; (similar to the `cp' shell command) we don't
|
||||||
|
;; need such a construction of the target directory,
|
||||||
|
;; so modify the destination TO to "~/test/" instead of "~/test/foo/".
|
||||||
|
(let ((destname (file-name-directory to)))
|
||||||
|
(when (and (file-directory-p from)
|
||||||
|
(file-directory-p to)
|
||||||
|
(eq file-creator 'dired-copy-file))
|
||||||
|
(setq to destname))
|
||||||
|
;; If DESTNAME is a subdirectory of FROM, not a symlink,
|
||||||
|
;; and the method in use is copying, signal an error.
|
||||||
|
(and (eq t (car (file-attributes destname)))
|
||||||
|
(eq file-creator 'dired-copy-file)
|
||||||
|
(file-in-directory-p destname from)
|
||||||
|
(error "Cannot copy `%s' into its subdirectory `%s'"
|
||||||
|
from to)))
|
||||||
|
(if overwrite
|
||||||
|
(or (and dired-overwrite-confirmed
|
||||||
|
(push (cons from to) async-fn-list))
|
||||||
|
(progn
|
||||||
|
(push (dired-make-relative from) failures)
|
||||||
|
(dired-log "%s `%s' to `%s' failed\n"
|
||||||
|
operation from to)))
|
||||||
|
(push (cons from to) async-fn-list)))))
|
||||||
|
;; Fix tramp issue #80 with emacs-26, use "-q" only when needed.
|
||||||
|
(setq async-quiet-switch
|
||||||
|
(if (and (boundp 'tramp-cache-read-persistent-data)
|
||||||
|
async-fn-list
|
||||||
|
(cl-loop for (_from . to) in async-fn-list
|
||||||
|
thereis (file-remote-p to)))
|
||||||
|
"-q" "-Q"))
|
||||||
|
;; When failures have been printed to dired log add the date at bob.
|
||||||
|
(when (or failures skipped) (dired-log t))
|
||||||
|
;; When async-fn-list is empty that's mean only one file
|
||||||
|
;; had to be copied and user finally answer NO.
|
||||||
|
;; In this case async process will never start and callback
|
||||||
|
;; will have no chance to run, so notify failures here.
|
||||||
|
(unless async-fn-list
|
||||||
|
(cond (failures
|
||||||
|
(funcall dired-async-message-function
|
||||||
|
"%s failed for %d of %d file%s -- See *Dired log* buffer"
|
||||||
|
'dired-async-failures
|
||||||
|
operation (length failures)
|
||||||
|
total (dired-plural-s total)))
|
||||||
|
(skipped
|
||||||
|
(funcall dired-async-message-function
|
||||||
|
"%s: %d of %d file%s skipped -- See *Dired log* buffer"
|
||||||
|
'dired-async-failures
|
||||||
|
operation (length skipped) total
|
||||||
|
(dired-plural-s total)))))
|
||||||
|
;; Setup callback.
|
||||||
|
(setq callback
|
||||||
|
(lambda (&optional _ignore)
|
||||||
|
(dired-async-after-file-create
|
||||||
|
total (list operation (length async-fn-list)) failures skipped)
|
||||||
|
(when (string= (downcase operation) "rename")
|
||||||
|
(cl-loop for (file . to) in async-fn-list
|
||||||
|
for bf = (get-file-buffer file)
|
||||||
|
for destp = (file-exists-p to)
|
||||||
|
do (and bf destp
|
||||||
|
(with-current-buffer bf
|
||||||
|
(set-visited-file-name to t t))))))))
|
||||||
|
;; Start async process.
|
||||||
|
(when async-fn-list
|
||||||
|
(async-start `(lambda ()
|
||||||
|
(require 'cl-lib) (require 'dired-aux) (require 'dired-x)
|
||||||
|
,(async-inject-variables dired-async-env-variables-regexp)
|
||||||
|
(let ((dired-recursive-copies (quote always))
|
||||||
|
(dired-copy-preserve-time
|
||||||
|
,dired-copy-preserve-time))
|
||||||
|
(setq overwrite-backup-query nil)
|
||||||
|
;; Inline `backup-file' as long as it is not
|
||||||
|
;; available in emacs.
|
||||||
|
(defalias 'backup-file
|
||||||
|
;; Same feature as "cp -f --backup=numbered from to"
|
||||||
|
;; Symlinks are copied as file from source unlike
|
||||||
|
;; `dired-copy-file' which is same as cp -d.
|
||||||
|
;; Directories are omitted.
|
||||||
|
(lambda (from to ok)
|
||||||
|
(cond ((file-directory-p from) (ignore))
|
||||||
|
(t (let ((count 0))
|
||||||
|
(while (let ((attrs (file-attributes to)))
|
||||||
|
(and attrs (null (nth 0 attrs))))
|
||||||
|
(cl-incf count)
|
||||||
|
(setq to (concat (file-name-sans-versions to)
|
||||||
|
(format ".~%s~" count)))))
|
||||||
|
(condition-case err
|
||||||
|
(copy-file from to ok dired-copy-preserve-time)
|
||||||
|
(file-date-error
|
||||||
|
(dired-log "Can't set date on %s:\n%s\n" from err)))))))
|
||||||
|
;; Now run the FILE-CREATOR function on files.
|
||||||
|
(cl-loop with fn = (quote ,file-creator)
|
||||||
|
for (from . dest) in (quote ,async-fn-list)
|
||||||
|
do (condition-case err
|
||||||
|
(funcall fn from dest t)
|
||||||
|
(file-error
|
||||||
|
(dired-log "%s: %s\n" (car err) (cdr err)))
|
||||||
|
nil))
|
||||||
|
(when (get-buffer dired-log-buffer)
|
||||||
|
(dired-log t)
|
||||||
|
(with-current-buffer dired-log-buffer
|
||||||
|
(write-region (point-min) (point-max)
|
||||||
|
,dired-async-log-file))))
|
||||||
|
,(dired-async-maybe-kill-ftp))
|
||||||
|
callback)
|
||||||
|
;; Run mode-line notifications while process running.
|
||||||
|
(dired-async--modeline-mode 1)
|
||||||
|
(message "%s proceeding asynchronously..." operation))))
|
||||||
|
|
||||||
|
(defvar wdired-use-interactive-rename)
|
||||||
|
(defun dired-async-wdired-do-renames (old-fn &rest args)
|
||||||
|
;; Perhaps a better fix would be to ask for renaming BEFORE starting
|
||||||
|
;; OLD-FN when `wdired-use-interactive-rename' is non-nil. For now
|
||||||
|
;; just bind it to nil to ensure no questions will be asked between
|
||||||
|
;; each rename.
|
||||||
|
(let (wdired-use-interactive-rename)
|
||||||
|
(apply old-fn args)))
|
||||||
|
|
||||||
|
(defadvice wdired-do-renames (around wdired-async)
|
||||||
|
(let (wdired-use-interactive-rename)
|
||||||
|
ad-do-it))
|
||||||
|
|
||||||
|
(defadvice dired-create-files (around dired-async)
|
||||||
|
(dired-async-create-files file-creator operation fn-list
|
||||||
|
name-constructor marker-char))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode dired-async-mode
|
||||||
|
"Do dired actions asynchronously."
|
||||||
|
:group 'dired-async
|
||||||
|
:lighter dired-async-mode-lighter
|
||||||
|
:global t
|
||||||
|
(if dired-async-mode
|
||||||
|
(if (fboundp 'advice-add)
|
||||||
|
(progn (advice-add 'dired-create-files :override #'dired-async-create-files)
|
||||||
|
(advice-add 'wdired-do-renames :around #'dired-async-wdired-do-renames))
|
||||||
|
(ad-activate 'dired-create-files)
|
||||||
|
(ad-activate 'wdired-do-renames))
|
||||||
|
(if (fboundp 'advice-remove)
|
||||||
|
(progn (advice-remove 'dired-create-files #'dired-async-create-files)
|
||||||
|
(advice-remove 'wdired-do-renames #'dired-async-wdired-do-renames))
|
||||||
|
(ad-deactivate 'dired-create-files)
|
||||||
|
(ad-deactivate 'wdired-do-renames))))
|
||||||
|
|
||||||
|
(defmacro dired-async--with-async-create-files (&rest body)
|
||||||
|
"Evaluate BODY with ‘dired-create-files’ set to ‘dired-async-create-files’."
|
||||||
|
(declare (indent 0))
|
||||||
|
`(cl-letf (((symbol-function 'dired-create-files) #'dired-async-create-files))
|
||||||
|
,@body))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun dired-async-do-copy (&optional arg)
|
||||||
|
"Run ‘dired-do-copy’ asynchronously."
|
||||||
|
(interactive "P")
|
||||||
|
(dired-async--with-async-create-files
|
||||||
|
(dired-do-copy arg)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun dired-async-do-symlink (&optional arg)
|
||||||
|
"Run ‘dired-do-symlink’ asynchronously."
|
||||||
|
(interactive "P")
|
||||||
|
(dired-async--with-async-create-files
|
||||||
|
(dired-do-symlink arg)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun dired-async-do-hardlink (&optional arg)
|
||||||
|
"Run ‘dired-do-hardlink’ asynchronously."
|
||||||
|
(interactive "P")
|
||||||
|
(dired-async--with-async-create-files
|
||||||
|
(dired-do-hardlink arg)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun dired-async-do-rename (&optional arg)
|
||||||
|
"Run ‘dired-do-rename’ asynchronously."
|
||||||
|
(interactive "P")
|
||||||
|
(dired-async--with-async-create-files
|
||||||
|
(dired-do-rename arg)))
|
||||||
|
|
||||||
|
(provide 'dired-async)
|
||||||
|
|
||||||
|
;;; dired-async.el ends here
|
Binary file not shown.
|
@ -0,0 +1,73 @@
|
||||||
|
;;; smtpmail-async.el --- Send e-mail with smtpmail.el asynchronously -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Author: John Wiegley <jwiegley@gmail.com>
|
||||||
|
;; Created: 18 Jun 2012
|
||||||
|
|
||||||
|
;; Keywords: email async
|
||||||
|
;; X-URL: https://github.com/jwiegley/emacs-async
|
||||||
|
|
||||||
|
;; 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, or (at
|
||||||
|
;; your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful, but
|
||||||
|
;; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
;; General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
||||||
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
;; Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Send e-mail with smtpmail.el asynchronously. To use:
|
||||||
|
;;
|
||||||
|
;; (require 'smtpmail-async)
|
||||||
|
;;
|
||||||
|
;; (setq send-mail-function 'async-smtpmail-send-it
|
||||||
|
;; message-send-mail-function 'async-smtpmail-send-it)
|
||||||
|
;;
|
||||||
|
;; This assumes you already have smtpmail.el working.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defgroup smtpmail-async nil
|
||||||
|
"Send e-mail with smtpmail.el asynchronously"
|
||||||
|
:group 'smptmail)
|
||||||
|
|
||||||
|
(require 'async)
|
||||||
|
(require 'smtpmail)
|
||||||
|
(require 'message)
|
||||||
|
|
||||||
|
(defvar async-smtpmail-before-send-hook nil
|
||||||
|
"Hook running in the child emacs in `async-smtpmail-send-it'.
|
||||||
|
It is called just before calling `smtpmail-send-it'.")
|
||||||
|
|
||||||
|
(defun async-smtpmail-send-it ()
|
||||||
|
(let ((to (message-field-value "To"))
|
||||||
|
(buf-content (buffer-substring-no-properties
|
||||||
|
(point-min) (point-max))))
|
||||||
|
(message "Delivering message to %s..." to)
|
||||||
|
(async-start
|
||||||
|
`(lambda ()
|
||||||
|
(require 'smtpmail)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert ,buf-content)
|
||||||
|
(set-buffer-multibyte nil)
|
||||||
|
;; Pass in the variable environment for smtpmail
|
||||||
|
,(async-inject-variables
|
||||||
|
"\\`\\(smtpmail\\|async-smtpmail\\|\\(user-\\)?mail\\)-\\|auth-sources\\|epg\\|nsm"
|
||||||
|
nil "\\`\\(mail-header-format-function\\|smtpmail-address-buffer\\|mail-mode-abbrev-table\\)")
|
||||||
|
(run-hooks 'async-smtpmail-before-send-hook)
|
||||||
|
(smtpmail-send-it)))
|
||||||
|
(lambda (&optional _ignore)
|
||||||
|
(message "Delivering message to %s...done" to)))))
|
||||||
|
|
||||||
|
(provide 'smtpmail-async)
|
||||||
|
|
||||||
|
;;; smtpmail-async.el ends here
|
Binary file not shown.
|
@ -0,0 +1,253 @@
|
||||||
|
;;; avy-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "avy" "avy.el" (23377 60991 205495 602000))
|
||||||
|
;;; Generated autoloads from avy.el
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char "avy" "\
|
||||||
|
Jump to the currently visible CHAR.
|
||||||
|
The window scope is determined by `avy-all-windows' (ARG negates it).
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char-in-line "avy" "\
|
||||||
|
Jump to the currently visible CHAR in the current line.
|
||||||
|
|
||||||
|
\(fn CHAR)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char-2 "avy" "\
|
||||||
|
Jump to the currently visible CHAR1 followed by CHAR2.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
BEG and END narrow the scope where candidates are searched.
|
||||||
|
|
||||||
|
\(fn CHAR1 CHAR2 &optional ARG BEG END)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char-2-above "avy" "\
|
||||||
|
Jump to the currently visible CHAR1 followed by CHAR2.
|
||||||
|
This is a scoped version of `avy-goto-char-2', where the scope is
|
||||||
|
the visible part of the current buffer up to point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR1 CHAR2 &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char-2-below "avy" "\
|
||||||
|
Jump to the currently visible CHAR1 followed by CHAR2.
|
||||||
|
This is a scoped version of `avy-goto-char-2', where the scope is
|
||||||
|
the visible part of the current buffer following point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR1 CHAR2 &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-isearch "avy" "\
|
||||||
|
Jump to one of the current isearch candidates.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-word-0 "avy" "\
|
||||||
|
Jump to a word start.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
BEG and END narrow the scope where candidates are searched.
|
||||||
|
|
||||||
|
\(fn ARG &optional BEG END)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-word-1 "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a word start.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
BEG and END narrow the scope where candidates are searched.
|
||||||
|
When SYMBOL is non-nil, jump to symbol start instead of word start.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG BEG END SYMBOL)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-word-1-above "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a word start.
|
||||||
|
This is a scoped version of `avy-goto-word-1', where the scope is
|
||||||
|
the visible part of the current buffer up to point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-word-1-below "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a word start.
|
||||||
|
This is a scoped version of `avy-goto-word-1', where the scope is
|
||||||
|
the visible part of the current buffer following point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-symbol-1 "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a symbol start.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-symbol-1-above "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a symbol start.
|
||||||
|
This is a scoped version of `avy-goto-symbol-1', where the scope is
|
||||||
|
the visible part of the current buffer up to point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-symbol-1-below "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a symbol start.
|
||||||
|
This is a scoped version of `avy-goto-symbol-1', where the scope is
|
||||||
|
the visible part of the current buffer following point.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-subword-0 "avy" "\
|
||||||
|
Jump to a word or subword start.
|
||||||
|
The window scope is determined by `avy-all-windows' (ARG negates it).
|
||||||
|
|
||||||
|
When PREDICATE is non-nil it's a function of zero parameters that
|
||||||
|
should return true.
|
||||||
|
|
||||||
|
BEG and END narrow the scope where candidates are searched.
|
||||||
|
|
||||||
|
\(fn &optional ARG PREDICATE BEG END)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-subword-1 "avy" "\
|
||||||
|
Jump to the currently visible CHAR at a subword start.
|
||||||
|
The window scope is determined by `avy-all-windows' (ARG negates it).
|
||||||
|
The case of CHAR is ignored.
|
||||||
|
|
||||||
|
\(fn CHAR &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-word-or-subword-1 "avy" "\
|
||||||
|
Forward to `avy-goto-subword-1' or `avy-goto-word-1'.
|
||||||
|
Which one depends on variable `subword-mode'.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-line "avy" "\
|
||||||
|
Jump to a line start in current buffer.
|
||||||
|
|
||||||
|
When ARG is 1, jump to lines currently visible, with the option
|
||||||
|
to cancel to `goto-line' by entering a number.
|
||||||
|
|
||||||
|
When ARG is 4, negate the window scope determined by
|
||||||
|
`avy-all-windows'.
|
||||||
|
|
||||||
|
Otherwise, forward to `goto-line' with ARG.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-line-above "avy" "\
|
||||||
|
Goto visible line above the cursor.
|
||||||
|
OFFSET changes the distance between the closest key to the cursor and
|
||||||
|
the cursor
|
||||||
|
When BOTTOM-UP is non-nil, display avy candidates from top to bottom
|
||||||
|
|
||||||
|
\(fn &optional OFFSET BOTTOM-UP)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-line-below "avy" "\
|
||||||
|
Goto visible line below the cursor.
|
||||||
|
OFFSET changes the distance between the closest key to the cursor and
|
||||||
|
the cursor
|
||||||
|
When BOTTOM-UP is non-nil, display avy candidates from top to bottom
|
||||||
|
|
||||||
|
\(fn &optional OFFSET BOTTOM-UP)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-copy-line "avy" "\
|
||||||
|
Copy a selected line above the current line.
|
||||||
|
ARG lines can be used.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-move-line "avy" "\
|
||||||
|
Move a selected line above the current line.
|
||||||
|
ARG lines can be used.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-copy-region "avy" "\
|
||||||
|
Select two lines and copy the text between them to point.
|
||||||
|
|
||||||
|
The window scope is determined by `avy-all-windows' or
|
||||||
|
`avy-all-windows-alt' when ARG is non-nil.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-move-region "avy" "\
|
||||||
|
Select two lines and move the text between them above the current line.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-kill-region "avy" "\
|
||||||
|
Select two lines and kill the region between them.
|
||||||
|
|
||||||
|
The window scope is determined by `avy-all-windows' or
|
||||||
|
`avy-all-windows-alt' when ARG is non-nil.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-kill-ring-save-region "avy" "\
|
||||||
|
Select two lines and save the region between them to the kill ring.
|
||||||
|
The window scope is determined by `avy-all-windows'.
|
||||||
|
When ARG is non-nil, do the opposite of `avy-all-windows'.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-kill-whole-line "avy" "\
|
||||||
|
Select line and kill the whole selected line.
|
||||||
|
|
||||||
|
With a numerical prefix ARG, kill ARG line(s) starting from the
|
||||||
|
selected line. If ARG is negative, kill backward.
|
||||||
|
|
||||||
|
If ARG is zero, kill the selected line but exclude the trailing
|
||||||
|
newline.
|
||||||
|
|
||||||
|
\\[universal-argument] 3 \\[avy-kil-whole-line] kill three lines
|
||||||
|
starting from the selected line. \\[universal-argument] -3
|
||||||
|
|
||||||
|
\\[avy-kill-whole-line] kill three lines backward including the
|
||||||
|
selected line.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-kill-ring-save-whole-line "avy" "\
|
||||||
|
Select line and save the whole selected line as if killed, but don’t kill it.
|
||||||
|
|
||||||
|
This command is similar to `avy-kill-whole-line', except that it
|
||||||
|
saves the line(s) as if killed, but does not kill it(them).
|
||||||
|
|
||||||
|
With a numerical prefix ARG, kill ARG line(s) starting from the
|
||||||
|
selected line. If ARG is negative, kill backward.
|
||||||
|
|
||||||
|
If ARG is zero, kill the selected line but exclude the trailing
|
||||||
|
newline.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'avy-setup-default "avy" "\
|
||||||
|
Setup the default shortcuts.
|
||||||
|
|
||||||
|
\(fn)" nil nil)
|
||||||
|
|
||||||
|
(autoload 'avy-goto-char-timer "avy" "\
|
||||||
|
Read one or many consecutive chars and jump to the first one.
|
||||||
|
The window scope is determined by `avy-all-windows' (ARG negates it).
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; avy-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "avy" "20180615.801" "Jump to arbitrary positions in visible text and select text quickly." '((emacs "24.1") (cl-lib "0.5")))
|
2001
configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el
Normal file
2001
configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.el
Normal file
File diff suppressed because it is too large
Load diff
BIN
configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elc
Normal file
BIN
configs/shared/emacs/.emacs.d/elpa/avy-20180615.801/avy.elc
Normal file
Binary file not shown.
|
@ -0,0 +1,79 @@
|
||||||
|
;;; bind-key-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "bind-key" "bind-key.el" (23377 60538 663260
|
||||||
|
;;;;;; 569000))
|
||||||
|
;;; Generated autoloads from bind-key.el
|
||||||
|
|
||||||
|
(autoload 'bind-key "bind-key" "\
|
||||||
|
Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
|
||||||
|
|
||||||
|
KEY-NAME may be a vector, in which case it is passed straight to
|
||||||
|
`define-key'. Or it may be a string to be interpreted as
|
||||||
|
spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
|
||||||
|
`edmacro-mode' for details.
|
||||||
|
|
||||||
|
COMMAND must be an interactive function or lambda form.
|
||||||
|
|
||||||
|
KEYMAP, if present, should be a keymap and not a quoted symbol.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
(bind-key \"M-h\" #'some-interactive-function my-mode-map)
|
||||||
|
|
||||||
|
If PREDICATE is non-nil, it is a form evaluated to determine when
|
||||||
|
a key should be bound. It must return non-nil in such cases.
|
||||||
|
Emacs can evaluate this form at any time that it does redisplay
|
||||||
|
or operates on menu data structures, so you should write it so it
|
||||||
|
can safely be called at any time.
|
||||||
|
|
||||||
|
\(fn KEY-NAME COMMAND &optional KEYMAP PREDICATE)" nil t)
|
||||||
|
|
||||||
|
(autoload 'unbind-key "bind-key" "\
|
||||||
|
Unbind the given KEY-NAME, within the KEYMAP (if specified).
|
||||||
|
See `bind-key' for more details.
|
||||||
|
|
||||||
|
\(fn KEY-NAME &optional KEYMAP)" nil t)
|
||||||
|
|
||||||
|
(autoload 'bind-key* "bind-key" "\
|
||||||
|
Similar to `bind-key', but overrides any mode-specific bindings.
|
||||||
|
|
||||||
|
\(fn KEY-NAME COMMAND &optional PREDICATE)" nil t)
|
||||||
|
|
||||||
|
(autoload 'bind-keys "bind-key" "\
|
||||||
|
Bind multiple keys at once.
|
||||||
|
|
||||||
|
Accepts keyword arguments:
|
||||||
|
:map MAP - a keymap into which the keybindings should be
|
||||||
|
added
|
||||||
|
:prefix KEY - prefix key for these bindings
|
||||||
|
:prefix-map MAP - name of the prefix map that should be created
|
||||||
|
for these bindings
|
||||||
|
:prefix-docstring STR - docstring for the prefix-map variable
|
||||||
|
:menu-name NAME - optional menu string for prefix map
|
||||||
|
:filter FORM - optional form to determine when bindings apply
|
||||||
|
|
||||||
|
The rest of the arguments are conses of keybinding string and a
|
||||||
|
function symbol (unquoted).
|
||||||
|
|
||||||
|
\(fn &rest ARGS)" nil t)
|
||||||
|
|
||||||
|
(autoload 'bind-keys* "bind-key" "\
|
||||||
|
|
||||||
|
|
||||||
|
\(fn &rest ARGS)" nil t)
|
||||||
|
|
||||||
|
(autoload 'describe-personal-keybindings "bind-key" "\
|
||||||
|
Display all the personal keybindings defined by `bind-key'.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; bind-key-autoloads.el ends here
|
|
@ -0,0 +1,2 @@
|
||||||
|
;;; -*- no-byte-compile: t -*-
|
||||||
|
(define-package "bind-key" "20180512.2130" "A simple way to manage personal keybindings" 'nil)
|
|
@ -0,0 +1,455 @@
|
||||||
|
;;; bind-key.el --- A simple way to manage personal keybindings
|
||||||
|
|
||||||
|
;; Copyright (c) 2012-2017 John Wiegley
|
||||||
|
|
||||||
|
;; Author: John Wiegley <johnw@newartisans.com>
|
||||||
|
;; Maintainer: John Wiegley <johnw@newartisans.com>
|
||||||
|
;; Created: 16 Jun 2012
|
||||||
|
;; Modified: 29 Nov 2017
|
||||||
|
;; Version: 2.4
|
||||||
|
;; Package-Version: 20180512.2130
|
||||||
|
;; Keywords: keys keybinding config dotemacs
|
||||||
|
;; URL: https://github.com/jwiegley/use-package
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or
|
||||||
|
;; modify it under the terms of the gnu general public license as
|
||||||
|
;; published by the free software foundation; either version 3, or (at
|
||||||
|
;; your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful, but
|
||||||
|
;; without any warranty; without even the implied warranty of
|
||||||
|
;; merchantability or fitness for a particular purpose. see the gnu
|
||||||
|
;; general public license for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the gnu general public license
|
||||||
|
;; along with gnu emacs; see the file copying. if not, write to the
|
||||||
|
;; free software foundation, inc., 59 temple place - suite 330,
|
||||||
|
;; boston, ma 02111-1307, usa.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; If you have lots of keybindings set in your .emacs file, it can be hard to
|
||||||
|
;; know which ones you haven't set yet, and which may now be overriding some
|
||||||
|
;; new default in a new emacs version. This module aims to solve that
|
||||||
|
;; problem.
|
||||||
|
;;
|
||||||
|
;; Bind keys as follows in your .emacs:
|
||||||
|
;;
|
||||||
|
;; (require 'bind-key)
|
||||||
|
;;
|
||||||
|
;; (bind-key "C-c x" 'my-ctrl-c-x-command)
|
||||||
|
;;
|
||||||
|
;; If the keybinding argument is a vector, it is passed straight to
|
||||||
|
;; `define-key', so remapping a key with `[remap COMMAND]' works as
|
||||||
|
;; expected:
|
||||||
|
;;
|
||||||
|
;; (bind-key [remap original-ctrl-c-x-command] 'my-ctrl-c-x-command)
|
||||||
|
;;
|
||||||
|
;; If you want the keybinding to override all minor modes that may also bind
|
||||||
|
;; the same key, use the `bind-key*' form:
|
||||||
|
;;
|
||||||
|
;; (bind-key* "<C-return>" 'other-window)
|
||||||
|
;;
|
||||||
|
;; If you want to rebind a key only in a particular keymap, use:
|
||||||
|
;;
|
||||||
|
;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map)
|
||||||
|
;;
|
||||||
|
;; To unbind a key within a keymap (for example, to stop your favorite major
|
||||||
|
;; mode from changing a binding that you don't want to override everywhere),
|
||||||
|
;; use `unbind-key':
|
||||||
|
;;
|
||||||
|
;; (unbind-key "C-c x" some-other-mode-map)
|
||||||
|
;;
|
||||||
|
;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro
|
||||||
|
;; is provided. It accepts keyword arguments, please see its documentation
|
||||||
|
;; for a detailed description.
|
||||||
|
;;
|
||||||
|
;; To add keys into a specific map, use :map argument
|
||||||
|
;;
|
||||||
|
;; (bind-keys :map dired-mode-map
|
||||||
|
;; ("o" . dired-omit-mode)
|
||||||
|
;; ("a" . some-custom-dired-function))
|
||||||
|
;;
|
||||||
|
;; To set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are
|
||||||
|
;; required)
|
||||||
|
;;
|
||||||
|
;; (bind-keys :prefix-map my-customize-prefix-map
|
||||||
|
;; :prefix "C-c c"
|
||||||
|
;; ("f" . customize-face)
|
||||||
|
;; ("v" . customize-variable))
|
||||||
|
;;
|
||||||
|
;; You can combine all the keywords together. Additionally,
|
||||||
|
;; `:prefix-docstring' can be specified to set documentation of created
|
||||||
|
;; `:prefix-map' variable.
|
||||||
|
;;
|
||||||
|
;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings
|
||||||
|
;; will not be overridden by other modes), you may use `bind-keys*' macro:
|
||||||
|
;;
|
||||||
|
;; (bind-keys*
|
||||||
|
;; ("C-o" . other-window)
|
||||||
|
;; ("C-M-n" . forward-page)
|
||||||
|
;; ("C-M-p" . backward-page))
|
||||||
|
;;
|
||||||
|
;; After Emacs loads, you can see a summary of all your personal keybindings
|
||||||
|
;; currently in effect with this command:
|
||||||
|
;;
|
||||||
|
;; M-x describe-personal-keybindings
|
||||||
|
;;
|
||||||
|
;; This display will tell you if you've overriden a default keybinding, and
|
||||||
|
;; what the default was. Also, it will tell you if the key was rebound after
|
||||||
|
;; your binding it with `bind-key', and what it was rebound it to.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'easy-mmode)
|
||||||
|
|
||||||
|
(defgroup bind-key nil
|
||||||
|
"A simple way to manage personal keybindings"
|
||||||
|
:group 'emacs)
|
||||||
|
|
||||||
|
(defcustom bind-key-column-widths '(18 . 40)
|
||||||
|
"Width of columns in `describe-personal-keybindings'."
|
||||||
|
:type '(cons integer integer)
|
||||||
|
:group 'bind-key)
|
||||||
|
|
||||||
|
(defcustom bind-key-segregation-regexp
|
||||||
|
"\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)"
|
||||||
|
"Regular expression used to divide key sets in the output from
|
||||||
|
\\[describe-personal-keybindings]."
|
||||||
|
:type 'regexp
|
||||||
|
:group 'bind-key)
|
||||||
|
|
||||||
|
(defcustom bind-key-describe-special-forms nil
|
||||||
|
"If non-nil, extract docstrings from lambdas, closures and keymaps if possible."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'bind-key)
|
||||||
|
|
||||||
|
;; Create override-global-mode to force key remappings
|
||||||
|
|
||||||
|
(defvar override-global-map (make-keymap)
|
||||||
|
"override-global-mode keymap")
|
||||||
|
|
||||||
|
(define-minor-mode override-global-mode
|
||||||
|
"A minor mode so that keymap settings override other modes."
|
||||||
|
t "")
|
||||||
|
|
||||||
|
;; the keymaps in `emulation-mode-map-alists' take precedence over
|
||||||
|
;; `minor-mode-map-alist'
|
||||||
|
(add-to-list 'emulation-mode-map-alists
|
||||||
|
`((override-global-mode . ,override-global-map)))
|
||||||
|
|
||||||
|
(defvar personal-keybindings nil
|
||||||
|
"List of bindings performed by `bind-key'.
|
||||||
|
|
||||||
|
Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro bind-key (key-name command &optional keymap predicate)
|
||||||
|
"Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed).
|
||||||
|
|
||||||
|
KEY-NAME may be a vector, in which case it is passed straight to
|
||||||
|
`define-key'. Or it may be a string to be interpreted as
|
||||||
|
spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of
|
||||||
|
`edmacro-mode' for details.
|
||||||
|
|
||||||
|
COMMAND must be an interactive function or lambda form.
|
||||||
|
|
||||||
|
KEYMAP, if present, should be a keymap and not a quoted symbol.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
(bind-key \"M-h\" #'some-interactive-function my-mode-map)
|
||||||
|
|
||||||
|
If PREDICATE is non-nil, it is a form evaluated to determine when
|
||||||
|
a key should be bound. It must return non-nil in such cases.
|
||||||
|
Emacs can evaluate this form at any time that it does redisplay
|
||||||
|
or operates on menu data structures, so you should write it so it
|
||||||
|
can safely be called at any time."
|
||||||
|
(let ((namevar (make-symbol "name"))
|
||||||
|
(keyvar (make-symbol "key"))
|
||||||
|
(kdescvar (make-symbol "kdesc"))
|
||||||
|
(bindingvar (make-symbol "binding")))
|
||||||
|
`(let* ((,namevar ,key-name)
|
||||||
|
(,keyvar (if (vectorp ,namevar) ,namevar
|
||||||
|
(read-kbd-macro ,namevar)))
|
||||||
|
(,kdescvar (cons (if (stringp ,namevar) ,namevar
|
||||||
|
(key-description ,namevar))
|
||||||
|
(quote ,keymap)))
|
||||||
|
(,bindingvar (lookup-key (or ,keymap global-map) ,keyvar)))
|
||||||
|
(let ((entry (assoc ,kdescvar personal-keybindings))
|
||||||
|
(details (list ,command
|
||||||
|
(unless (numberp ,bindingvar)
|
||||||
|
,bindingvar))))
|
||||||
|
(if entry
|
||||||
|
(setcdr entry details)
|
||||||
|
(add-to-list 'personal-keybindings (cons ,kdescvar details))))
|
||||||
|
,(if predicate
|
||||||
|
`(define-key (or ,keymap global-map) ,keyvar
|
||||||
|
'(menu-item "" nil :filter (lambda (&optional _)
|
||||||
|
(when ,predicate
|
||||||
|
,command))))
|
||||||
|
`(define-key (or ,keymap global-map) ,keyvar ,command)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro unbind-key (key-name &optional keymap)
|
||||||
|
"Unbind the given KEY-NAME, within the KEYMAP (if specified).
|
||||||
|
See `bind-key' for more details."
|
||||||
|
`(progn
|
||||||
|
(bind-key ,key-name nil ,keymap)
|
||||||
|
(setq personal-keybindings
|
||||||
|
(cl-delete-if #'(lambda (k)
|
||||||
|
,(if keymap
|
||||||
|
`(and (consp (car k))
|
||||||
|
(string= (caar k) ,key-name)
|
||||||
|
(eq (cdar k) ',keymap))
|
||||||
|
`(and (stringp (car k))
|
||||||
|
(string= (car k) ,key-name))))
|
||||||
|
personal-keybindings))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro bind-key* (key-name command &optional predicate)
|
||||||
|
"Similar to `bind-key', but overrides any mode-specific bindings."
|
||||||
|
`(bind-key ,key-name ,command override-global-map ,predicate))
|
||||||
|
|
||||||
|
(defun bind-keys-form (args keymap)
|
||||||
|
"Bind multiple keys at once.
|
||||||
|
|
||||||
|
Accepts keyword arguments:
|
||||||
|
:map MAP - a keymap into which the keybindings should be
|
||||||
|
added
|
||||||
|
:prefix KEY - prefix key for these bindings
|
||||||
|
:prefix-map MAP - name of the prefix map that should be created
|
||||||
|
for these bindings
|
||||||
|
:prefix-docstring STR - docstring for the prefix-map variable
|
||||||
|
:menu-name NAME - optional menu string for prefix map
|
||||||
|
:filter FORM - optional form to determine when bindings apply
|
||||||
|
|
||||||
|
The rest of the arguments are conses of keybinding string and a
|
||||||
|
function symbol (unquoted)."
|
||||||
|
(let (map
|
||||||
|
doc
|
||||||
|
prefix-map
|
||||||
|
prefix
|
||||||
|
filter
|
||||||
|
menu-name
|
||||||
|
pkg)
|
||||||
|
|
||||||
|
;; Process any initial keyword arguments
|
||||||
|
(let ((cont t))
|
||||||
|
(while (and cont args)
|
||||||
|
(if (cond ((and (eq :map (car args))
|
||||||
|
(not prefix-map))
|
||||||
|
(setq map (cadr args)))
|
||||||
|
((eq :prefix-docstring (car args))
|
||||||
|
(setq doc (cadr args)))
|
||||||
|
((and (eq :prefix-map (car args))
|
||||||
|
(not (memq map '(global-map
|
||||||
|
override-global-map))))
|
||||||
|
(setq prefix-map (cadr args)))
|
||||||
|
((eq :prefix (car args))
|
||||||
|
(setq prefix (cadr args)))
|
||||||
|
((eq :filter (car args))
|
||||||
|
(setq filter (cadr args)) t)
|
||||||
|
((eq :menu-name (car args))
|
||||||
|
(setq menu-name (cadr args)))
|
||||||
|
((eq :package (car args))
|
||||||
|
(setq pkg (cadr args))))
|
||||||
|
(setq args (cddr args))
|
||||||
|
(setq cont nil))))
|
||||||
|
|
||||||
|
(when (or (and prefix-map (not prefix))
|
||||||
|
(and prefix (not prefix-map)))
|
||||||
|
(error "Both :prefix-map and :prefix must be supplied"))
|
||||||
|
|
||||||
|
(when (and menu-name (not prefix))
|
||||||
|
(error "If :menu-name is supplied, :prefix must be too"))
|
||||||
|
|
||||||
|
(unless map (setq map keymap))
|
||||||
|
|
||||||
|
;; Process key binding arguments
|
||||||
|
(let (first next)
|
||||||
|
(while args
|
||||||
|
(if (keywordp (car args))
|
||||||
|
(progn
|
||||||
|
(setq next args)
|
||||||
|
(setq args nil))
|
||||||
|
(if first
|
||||||
|
(nconc first (list (car args)))
|
||||||
|
(setq first (list (car args))))
|
||||||
|
(setq args (cdr args))))
|
||||||
|
|
||||||
|
(cl-flet
|
||||||
|
((wrap (map bindings)
|
||||||
|
(if (and map pkg (not (memq map '(global-map
|
||||||
|
override-global-map))))
|
||||||
|
`((if (boundp ',map)
|
||||||
|
,(macroexp-progn bindings)
|
||||||
|
(eval-after-load
|
||||||
|
,(if (symbolp pkg) `',pkg pkg)
|
||||||
|
',(macroexp-progn bindings))))
|
||||||
|
bindings)))
|
||||||
|
|
||||||
|
(append
|
||||||
|
(when prefix-map
|
||||||
|
`((defvar ,prefix-map)
|
||||||
|
,@(when doc `((put ',prefix-map 'variable-documentation ,doc)))
|
||||||
|
,@(if menu-name
|
||||||
|
`((define-prefix-command ',prefix-map nil ,menu-name))
|
||||||
|
`((define-prefix-command ',prefix-map)))
|
||||||
|
,@(if (and map (not (eq map 'global-map)))
|
||||||
|
(wrap map `((bind-key ,prefix ',prefix-map ,map ,filter)))
|
||||||
|
`((bind-key ,prefix ',prefix-map nil ,filter)))))
|
||||||
|
(wrap map
|
||||||
|
(cl-mapcan
|
||||||
|
(lambda (form)
|
||||||
|
(let ((fun (and (cdr form) (list 'function (cdr form)))))
|
||||||
|
(if prefix-map
|
||||||
|
`((bind-key ,(car form) ,fun ,prefix-map ,filter))
|
||||||
|
(if (and map (not (eq map 'global-map)))
|
||||||
|
`((bind-key ,(car form) ,fun ,map ,filter))
|
||||||
|
`((bind-key ,(car form) ,fun nil ,filter))))))
|
||||||
|
first))
|
||||||
|
(when next
|
||||||
|
(bind-keys-form (if pkg
|
||||||
|
(cons :package (cons pkg next))
|
||||||
|
next) map)))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro bind-keys (&rest args)
|
||||||
|
"Bind multiple keys at once.
|
||||||
|
|
||||||
|
Accepts keyword arguments:
|
||||||
|
:map MAP - a keymap into which the keybindings should be
|
||||||
|
added
|
||||||
|
:prefix KEY - prefix key for these bindings
|
||||||
|
:prefix-map MAP - name of the prefix map that should be created
|
||||||
|
for these bindings
|
||||||
|
:prefix-docstring STR - docstring for the prefix-map variable
|
||||||
|
:menu-name NAME - optional menu string for prefix map
|
||||||
|
:filter FORM - optional form to determine when bindings apply
|
||||||
|
|
||||||
|
The rest of the arguments are conses of keybinding string and a
|
||||||
|
function symbol (unquoted)."
|
||||||
|
(macroexp-progn (bind-keys-form args nil)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defmacro bind-keys* (&rest args)
|
||||||
|
(macroexp-progn (bind-keys-form args 'override-global-map)))
|
||||||
|
|
||||||
|
(defun get-binding-description (elem)
|
||||||
|
(cond
|
||||||
|
((listp elem)
|
||||||
|
(cond
|
||||||
|
((memq (car elem) '(lambda function))
|
||||||
|
(if (and bind-key-describe-special-forms
|
||||||
|
(stringp (nth 2 elem)))
|
||||||
|
(nth 2 elem)
|
||||||
|
"#<lambda>"))
|
||||||
|
((eq 'closure (car elem))
|
||||||
|
(if (and bind-key-describe-special-forms
|
||||||
|
(stringp (nth 3 elem)))
|
||||||
|
(nth 3 elem)
|
||||||
|
"#<closure>"))
|
||||||
|
((eq 'keymap (car elem))
|
||||||
|
"#<keymap>")
|
||||||
|
(t
|
||||||
|
elem)))
|
||||||
|
;; must be a symbol, non-symbol keymap case covered above
|
||||||
|
((and bind-key-describe-special-forms (keymapp elem))
|
||||||
|
(let ((doc (get elem 'variable-documentation)))
|
||||||
|
(if (stringp doc) doc elem)))
|
||||||
|
((symbolp elem)
|
||||||
|
elem)
|
||||||
|
(t
|
||||||
|
"#<byte-compiled lambda>")))
|
||||||
|
|
||||||
|
(defun compare-keybindings (l r)
|
||||||
|
(let* ((regex bind-key-segregation-regexp)
|
||||||
|
(lgroup (and (string-match regex (caar l))
|
||||||
|
(match-string 0 (caar l))))
|
||||||
|
(rgroup (and (string-match regex (caar r))
|
||||||
|
(match-string 0 (caar r))))
|
||||||
|
(lkeymap (cdar l))
|
||||||
|
(rkeymap (cdar r)))
|
||||||
|
(cond
|
||||||
|
((and (null lkeymap) rkeymap)
|
||||||
|
(cons t t))
|
||||||
|
((and lkeymap (null rkeymap))
|
||||||
|
(cons nil t))
|
||||||
|
((and lkeymap rkeymap
|
||||||
|
(not (string= (symbol-name lkeymap) (symbol-name rkeymap))))
|
||||||
|
(cons (string< (symbol-name lkeymap) (symbol-name rkeymap)) t))
|
||||||
|
((and (null lgroup) rgroup)
|
||||||
|
(cons t t))
|
||||||
|
((and lgroup (null rgroup))
|
||||||
|
(cons nil t))
|
||||||
|
((and lgroup rgroup)
|
||||||
|
(if (string= lgroup rgroup)
|
||||||
|
(cons (string< (caar l) (caar r)) nil)
|
||||||
|
(cons (string< lgroup rgroup) t)))
|
||||||
|
(t
|
||||||
|
(cons (string< (caar l) (caar r)) nil)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun describe-personal-keybindings ()
|
||||||
|
"Display all the personal keybindings defined by `bind-key'."
|
||||||
|
(interactive)
|
||||||
|
(with-output-to-temp-buffer "*Personal Keybindings*"
|
||||||
|
(princ (format (concat "Key name%s Command%s Comments\n%s %s "
|
||||||
|
"---------------------\n")
|
||||||
|
(make-string (- (car bind-key-column-widths) 9) ? )
|
||||||
|
(make-string (- (cdr bind-key-column-widths) 8) ? )
|
||||||
|
(make-string (1- (car bind-key-column-widths)) ?-)
|
||||||
|
(make-string (1- (cdr bind-key-column-widths)) ?-)))
|
||||||
|
(let (last-binding)
|
||||||
|
(dolist (binding
|
||||||
|
(setq personal-keybindings
|
||||||
|
(sort personal-keybindings
|
||||||
|
(lambda (l r)
|
||||||
|
(car (compare-keybindings l r))))))
|
||||||
|
|
||||||
|
(if (not (eq (cdar last-binding) (cdar binding)))
|
||||||
|
(princ (format "\n\n%s: %s\n%s\n\n"
|
||||||
|
(cdar binding) (caar binding)
|
||||||
|
(make-string (+ 21 (car bind-key-column-widths)
|
||||||
|
(cdr bind-key-column-widths)) ?-)))
|
||||||
|
(if (and last-binding
|
||||||
|
(cdr (compare-keybindings last-binding binding)))
|
||||||
|
(princ "\n")))
|
||||||
|
|
||||||
|
(let* ((key-name (caar binding))
|
||||||
|
(at-present (lookup-key (or (symbol-value (cdar binding))
|
||||||
|
(current-global-map))
|
||||||
|
(read-kbd-macro key-name)))
|
||||||
|
(command (nth 1 binding))
|
||||||
|
(was-command (nth 2 binding))
|
||||||
|
(command-desc (get-binding-description command))
|
||||||
|
(was-command-desc (and was-command
|
||||||
|
(get-binding-description was-command)))
|
||||||
|
(at-present-desc (get-binding-description at-present))
|
||||||
|
)
|
||||||
|
(let ((line
|
||||||
|
(format
|
||||||
|
(format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths)
|
||||||
|
(cdr bind-key-column-widths))
|
||||||
|
key-name (format "`%s\'" command-desc)
|
||||||
|
(if (string= command-desc at-present-desc)
|
||||||
|
(if (or (null was-command)
|
||||||
|
(string= command-desc was-command-desc))
|
||||||
|
""
|
||||||
|
(format "was `%s\'" was-command-desc))
|
||||||
|
(format "[now: `%s\']" at-present)))))
|
||||||
|
(princ (if (string-match "[ \t]+\n" line)
|
||||||
|
(replace-match "\n" t t line)
|
||||||
|
line))))
|
||||||
|
|
||||||
|
(setq last-binding binding)))))
|
||||||
|
|
||||||
|
(provide 'bind-key)
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; outline-regexp: ";;;\\(;* [^\s\t\n]\\|###autoload\\)\\|("
|
||||||
|
;; indent-tabs-mode: nil
|
||||||
|
;; End:
|
||||||
|
|
||||||
|
;;; bind-key.el ends here
|
Binary file not shown.
|
@ -0,0 +1,208 @@
|
||||||
|
;;; cider-apropos.el --- Apropos functionality for Clojure -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2014-2018 Jeff Valk, Bozhidar Batsov and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Jeff Valk <jv@jeffvalk.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Apropos functionality for Clojure.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-doc)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-popup)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
|
||||||
|
(require 'clojure-mode)
|
||||||
|
(require 'apropos)
|
||||||
|
(require 'button)
|
||||||
|
|
||||||
|
(defconst cider-apropos-buffer "*cider-apropos*")
|
||||||
|
|
||||||
|
(defcustom cider-apropos-actions '(("display-doc" . cider-doc-lookup)
|
||||||
|
("find-def" . cider--find-var)
|
||||||
|
("lookup-on-grimoire" . cider-grimoire-lookup))
|
||||||
|
"Controls the actions to be applied on the symbol found by an apropos search.
|
||||||
|
The first action key in the list will be selected as default. If the list
|
||||||
|
contains only one action key, the associated action function will be
|
||||||
|
applied automatically. An action function can be any function that receives
|
||||||
|
the symbol found by the apropos search as argument."
|
||||||
|
:type '(alist :key-type string :value-type function)
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.13.0"))
|
||||||
|
|
||||||
|
(define-button-type 'apropos-special-form
|
||||||
|
'apropos-label "Special form"
|
||||||
|
'apropos-short-label "s"
|
||||||
|
'face 'font-lock-keyword-face
|
||||||
|
'help-echo "mouse-2, RET: Display more help on this special form"
|
||||||
|
'follow-link t
|
||||||
|
'action (lambda (button)
|
||||||
|
(describe-function (button-get button 'apropos-symbol))))
|
||||||
|
|
||||||
|
(defun cider-apropos-doc (button)
|
||||||
|
"Display documentation for the symbol represented at BUTTON."
|
||||||
|
(cider-doc-lookup (button-get button 'apropos-symbol)))
|
||||||
|
|
||||||
|
(defun cider-apropos-summary (query ns docs-p include-private-p case-sensitive-p)
|
||||||
|
"Return a short description for the performed apropos search.
|
||||||
|
|
||||||
|
QUERY can be a regular expression list of space-separated words
|
||||||
|
\(e.g take while) which will be converted to a regular expression
|
||||||
|
\(like take.+while) automatically behind the scenes. The search may be
|
||||||
|
limited to the namespace NS, and may optionally search doc strings
|
||||||
|
\(based on DOCS-P), include private vars (based on INCLUDE-PRIVATE-P),
|
||||||
|
and be case-sensitive (based on CASE-SENSITIVE-P)."
|
||||||
|
(concat (if case-sensitive-p "Case-sensitive " "")
|
||||||
|
(if docs-p "Documentation " "")
|
||||||
|
(format "Apropos for %S" query)
|
||||||
|
(if ns (format " in namespace %S" ns) "")
|
||||||
|
(if include-private-p
|
||||||
|
" (public and private symbols)"
|
||||||
|
" (public symbols only)")))
|
||||||
|
|
||||||
|
(defun cider-apropos-highlight (doc query)
|
||||||
|
"Return the DOC string propertized to highlight QUERY matches."
|
||||||
|
(let ((pos 0))
|
||||||
|
(while (string-match query doc pos)
|
||||||
|
(setq pos (match-end 0))
|
||||||
|
(put-text-property (match-beginning 0)
|
||||||
|
(match-end 0)
|
||||||
|
'font-lock-face apropos-match-face doc)))
|
||||||
|
doc)
|
||||||
|
|
||||||
|
(defun cider-apropos-result (result query docs-p)
|
||||||
|
"Emit a RESULT matching QUERY into current buffer, formatted for DOCS-P."
|
||||||
|
(nrepl-dbind-response result (name type doc)
|
||||||
|
(let* ((label (capitalize (if (string= type "variable") "var" type)))
|
||||||
|
(help (concat "Display doc for this " (downcase label))))
|
||||||
|
(cider-propertize-region (list 'apropos-symbol name
|
||||||
|
'action 'cider-apropos-doc
|
||||||
|
'help-echo help)
|
||||||
|
(insert-text-button name 'type 'apropos-symbol)
|
||||||
|
(insert "\n ")
|
||||||
|
(insert-text-button label 'type (intern (concat "apropos-" type)))
|
||||||
|
(insert ": ")
|
||||||
|
(let ((beg (point)))
|
||||||
|
(if docs-p
|
||||||
|
(insert (cider-apropos-highlight doc query) "\n")
|
||||||
|
(insert doc)
|
||||||
|
(fill-region beg (point))))
|
||||||
|
(insert "\n")))))
|
||||||
|
|
||||||
|
(declare-function cider-mode "cider-mode")
|
||||||
|
|
||||||
|
(defun cider-show-apropos (summary results query docs-p)
|
||||||
|
"Show SUMMARY and RESULTS for QUERY in a pop-up buffer, formatted for DOCS-P."
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-apropos-buffer 'select 'apropos-mode 'ancillary)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(if (boundp 'header-line-format)
|
||||||
|
(setq-local header-line-format summary)
|
||||||
|
(insert summary "\n\n"))
|
||||||
|
(dolist (result results)
|
||||||
|
(cider-apropos-result result query docs-p))
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-apropos (query &optional ns docs-p privates-p case-sensitive-p)
|
||||||
|
"Show all symbols whose names match QUERY, a regular expression.
|
||||||
|
QUERY can also be a list of space-separated words (e.g. take while) which
|
||||||
|
will be converted to a regular expression (like take.+while) automatically
|
||||||
|
behind the scenes. The search may be limited to the namespace NS, and may
|
||||||
|
optionally search doc strings (based on DOCS-P), include private vars
|
||||||
|
\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P)."
|
||||||
|
(interactive
|
||||||
|
(cons (read-string "Search for Clojure symbol (a regular expression): ")
|
||||||
|
(when current-prefix-arg
|
||||||
|
(list (let ((ns (completing-read "Namespace (default is all): " (cider-sync-request:ns-list))))
|
||||||
|
(if (string= ns "") nil ns))
|
||||||
|
(y-or-n-p "Search doc strings? ")
|
||||||
|
(y-or-n-p "Include private symbols? ")
|
||||||
|
(y-or-n-p "Case-sensitive? ")))))
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "apropos")
|
||||||
|
(if-let* ((summary (cider-apropos-summary
|
||||||
|
query ns docs-p privates-p case-sensitive-p))
|
||||||
|
(results (cider-sync-request:apropos query ns docs-p privates-p case-sensitive-p)))
|
||||||
|
(cider-show-apropos summary results query docs-p)
|
||||||
|
(message "No apropos matches for %S" query)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-apropos-documentation ()
|
||||||
|
"Shortcut for (cider-apropos <query> nil t)."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "apropos")
|
||||||
|
(cider-apropos (read-string "Search for Clojure documentation (a regular expression): ") nil t))
|
||||||
|
|
||||||
|
(defun cider-apropos-act-on-symbol (symbol)
|
||||||
|
"Apply selected action on SYMBOL."
|
||||||
|
(let* ((first-action-key (car (car cider-apropos-actions)))
|
||||||
|
(action-key (if (= 1 (length cider-apropos-actions))
|
||||||
|
first-action-key
|
||||||
|
(completing-read (format "Choose action to apply to `%s` (default %s): "
|
||||||
|
symbol first-action-key)
|
||||||
|
cider-apropos-actions nil nil nil nil first-action-key)))
|
||||||
|
(action-fn (cdr (assoc action-key cider-apropos-actions))))
|
||||||
|
(if action-fn
|
||||||
|
(funcall action-fn symbol)
|
||||||
|
(user-error "Unknown action `%s`" action-key))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-apropos-select (query &optional ns docs-p privates-p case-sensitive-p)
|
||||||
|
"Similar to `cider-apropos', but presents the results in a completing read.
|
||||||
|
Show all symbols whose names match QUERY, a regular expression.
|
||||||
|
QUERY can also be a list of space-separated words (e.g. take while) which
|
||||||
|
will be converted to a regular expression (like take.+while) automatically
|
||||||
|
behind the scenes. The search may be limited to the namespace NS, and may
|
||||||
|
optionally search doc strings (based on DOCS-P), include private vars
|
||||||
|
\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P)."
|
||||||
|
(interactive
|
||||||
|
(cons (read-string "Search for Clojure symbol (a regular expression): ")
|
||||||
|
(when current-prefix-arg
|
||||||
|
(list (let ((ns (completing-read "Namespace (default is all): " (cider-sync-request:ns-list))))
|
||||||
|
(if (string= ns "") nil ns))
|
||||||
|
(y-or-n-p "Search doc strings? ")
|
||||||
|
(y-or-n-p "Include private symbols? ")
|
||||||
|
(y-or-n-p "Case-sensitive? ")))))
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "apropos")
|
||||||
|
(if-let* ((summary (cider-apropos-summary
|
||||||
|
query ns docs-p privates-p case-sensitive-p))
|
||||||
|
(results (mapcar (lambda (r) (nrepl-dict-get r "name"))
|
||||||
|
(cider-sync-request:apropos query ns docs-p privates-p case-sensitive-p))))
|
||||||
|
(cider-apropos-act-on-symbol (completing-read (concat summary ": ") results))
|
||||||
|
(message "No apropos matches for %S" query)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-apropos-documentation-select ()
|
||||||
|
"Shortcut for (cider-apropos-select <query> nil t)."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "apropos")
|
||||||
|
(cider-apropos-select (read-string "Search for Clojure documentation (a regular expression): ") nil t))
|
||||||
|
|
||||||
|
(provide 'cider-apropos)
|
||||||
|
|
||||||
|
;;; cider-apropos.el ends here
|
Binary file not shown.
|
@ -0,0 +1,607 @@
|
||||||
|
;;; cider-autoloads.el --- automatically extracted autoloads
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(add-to-list 'load-path (directory-file-name (or (file-name-directory #$) (car load-path))))
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider" "cider.el" (23377 61664 804060 975000))
|
||||||
|
;;; Generated autoloads from cider.el
|
||||||
|
|
||||||
|
(autoload 'cider-version "cider" "\
|
||||||
|
Display CIDER's version.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-jack-in-clj "cider" "\
|
||||||
|
Start an nREPL server for the current project and connect to it.
|
||||||
|
PARAMS is a plist optionally containing :project-dir and :jack-in-cmd.
|
||||||
|
With the prefix argument, prompt for all these parameters.
|
||||||
|
|
||||||
|
\(fn PARAMS)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-jack-in-cljs "cider" "\
|
||||||
|
Start an nREPL server for the current project and connect to it.
|
||||||
|
PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
|
||||||
|
:cljs-repl-type (e.g. Node, Figwheel, etc). With the prefix argument,
|
||||||
|
prompt for all these parameters.
|
||||||
|
|
||||||
|
\(fn PARAMS)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-jack-in-clj&cljs "cider" "\
|
||||||
|
Start an nREPL server and connect with clj and cljs REPLs.
|
||||||
|
PARAMS is a plist optionally containing :project-dir, :jack-in-cmd and
|
||||||
|
:cljs-repl-type (e.g. Node, Figwheel, etc). With the prefix argument,
|
||||||
|
prompt for all these parameters. When SOFT-CLJS-START is non-nil, start
|
||||||
|
cljs REPL only when the ClojureScript dependencies are met.
|
||||||
|
|
||||||
|
\(fn &optional PARAMS SOFT-CLJS-START)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-connect-sibling-clj "cider" "\
|
||||||
|
Create a Clojure REPL with the same server as OTHER-REPL.
|
||||||
|
PARAMS is for consistency with other connection commands and is currently
|
||||||
|
ignored. OTHER-REPL defaults to `cider-current-repl' and in programs can
|
||||||
|
also be a server buffer, in which case a new session with a REPL for that
|
||||||
|
server is created.
|
||||||
|
|
||||||
|
\(fn PARAMS &optional OTHER-REPL)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-connect-sibling-cljs "cider" "\
|
||||||
|
Create a ClojureScript REPL with the same server as OTHER-REPL.
|
||||||
|
PARAMS is a plist optionally containing :cljs-repl-type (e.g. Node,
|
||||||
|
Figwheel, etc). All other parameters are inferred from the OTHER-REPL.
|
||||||
|
OTHER-REPL defaults to `cider-current-repl' but in programs can also be a
|
||||||
|
server buffer, in which case a new session for that server is created.
|
||||||
|
|
||||||
|
\(fn PARAMS &optional OTHER-REPL)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-connect-clj "cider" "\
|
||||||
|
Initialize a CLJ connection to an nREPL server.
|
||||||
|
PARAMS is a plist optionally containing :host, :port and :project-dir. On
|
||||||
|
prefix argument, prompt for all the parameters.
|
||||||
|
|
||||||
|
\(fn &optional PARAMS)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-connect-cljs "cider" "\
|
||||||
|
Initialize a CLJS connection to an nREPL server.
|
||||||
|
PARAMS is a plist optionally containing :host, :port, :project-dir and
|
||||||
|
:cljs-repl-type (e.g. Node, Figwheel, etc). On prefix, prompt for all the
|
||||||
|
parameters regardless of their supplied or default values.
|
||||||
|
|
||||||
|
\(fn &optional PARAMS)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-connect-clj&cljs "cider" "\
|
||||||
|
Initialize a CLJ and CLJS connection to an nREPL server..
|
||||||
|
PARAMS is a plist optionally containing :host, :port, :project-dir and
|
||||||
|
:cljs-repl-type (e.g. Node, Figwheel, etc). When SOFT-CLJS-START is
|
||||||
|
non-nil, don't start if ClojureScript requirements are not met.
|
||||||
|
|
||||||
|
\(fn PARAMS &optional SOFT-CLJS-START)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider "cider" "\
|
||||||
|
Start a connection of any type interactively.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(defalias 'cider-jack-in #'cider-jack-in-clj)
|
||||||
|
|
||||||
|
(defalias 'cider-jack-in-clojure #'cider-jack-in-clj)
|
||||||
|
|
||||||
|
(defalias 'cider-jack-in-clojurescript #'cider-jack-in-cljs)
|
||||||
|
|
||||||
|
(defalias 'cider-connect #'cider-connect-clj)
|
||||||
|
|
||||||
|
(defalias 'cider-connect-clojure #'cider-connect-clj)
|
||||||
|
|
||||||
|
(defalias 'cider-connect-clojurescript #'cider-connect-cljs)
|
||||||
|
|
||||||
|
(defalias 'cider-connect-sibling-clojure #'cider-connect-sibling-clj)
|
||||||
|
|
||||||
|
(defalias 'cider-connect-sibling-clojurescript #'cider-connect-sibling-cljs)
|
||||||
|
|
||||||
|
(eval-after-load 'clojure-mode '(progn (define-key clojure-mode-map (kbd "C-c M-x") #'cider) (define-key clojure-mode-map (kbd "C-c M-j") #'cider-jack-in-clj) (define-key clojure-mode-map (kbd "C-c M-J") #'cider-jack-in-cljs) (define-key clojure-mode-map (kbd "C-c M-c") #'cider-connect-clj) (define-key clojure-mode-map (kbd "C-c M-C") #'cider-connect-cljs) (define-key clojure-mode-map (kbd "C-c C-x") 'cider-start-map) (define-key clojure-mode-map (kbd "C-c C-s") 'sesman-map) (require 'sesman) (sesman-install-menu clojure-mode-map) (add-hook 'clojure-mode-hook (lambda nil (setq-local sesman-system 'CIDER)))))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-apropos" "cider-apropos.el" (23377 61664
|
||||||
|
;;;;;; 770864 524000))
|
||||||
|
;;; Generated autoloads from cider-apropos.el
|
||||||
|
|
||||||
|
(autoload 'cider-apropos "cider-apropos" "\
|
||||||
|
Show all symbols whose names match QUERY, a regular expression.
|
||||||
|
QUERY can also be a list of space-separated words (e.g. take while) which
|
||||||
|
will be converted to a regular expression (like take.+while) automatically
|
||||||
|
behind the scenes. The search may be limited to the namespace NS, and may
|
||||||
|
optionally search doc strings (based on DOCS-P), include private vars
|
||||||
|
\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P).
|
||||||
|
|
||||||
|
\(fn QUERY &optional NS DOCS-P PRIVATES-P CASE-SENSITIVE-P)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-apropos-documentation "cider-apropos" "\
|
||||||
|
Shortcut for (cider-apropos <query> nil t).
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-apropos-select "cider-apropos" "\
|
||||||
|
Similar to `cider-apropos', but presents the results in a completing read.
|
||||||
|
Show all symbols whose names match QUERY, a regular expression.
|
||||||
|
QUERY can also be a list of space-separated words (e.g. take while) which
|
||||||
|
will be converted to a regular expression (like take.+while) automatically
|
||||||
|
behind the scenes. The search may be limited to the namespace NS, and may
|
||||||
|
optionally search doc strings (based on DOCS-P), include private vars
|
||||||
|
\(based on PRIVATES-P), and be case-sensitive (based on CASE-SENSITIVE-P).
|
||||||
|
|
||||||
|
\(fn QUERY &optional NS DOCS-P PRIVATES-P CASE-SENSITIVE-P)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-apropos-documentation-select "cider-apropos" "\
|
||||||
|
Shortcut for (cider-apropos-select <query> nil t).
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-browse-ns" "cider-browse-ns.el" (23377
|
||||||
|
;;;;;; 61664 768380 279000))
|
||||||
|
;;; Generated autoloads from cider-browse-ns.el
|
||||||
|
|
||||||
|
(autoload 'cider-browse-ns "cider-browse-ns" "\
|
||||||
|
List all NAMESPACE's vars in BUFFER.
|
||||||
|
|
||||||
|
\(fn NAMESPACE)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-browse-ns-all "cider-browse-ns" "\
|
||||||
|
List all loaded namespaces in BUFFER.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-browse-spec" "cider-browse-spec.el"
|
||||||
|
;;;;;; (23377 61664 797512 30000))
|
||||||
|
;;; Generated autoloads from cider-browse-spec.el
|
||||||
|
|
||||||
|
(autoload 'cider-browse-spec "cider-browse-spec" "\
|
||||||
|
Browse SPEC definition.
|
||||||
|
|
||||||
|
\(fn SPEC)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-browse-spec-all "cider-browse-spec" "\
|
||||||
|
Open list of specs in a popup buffer.
|
||||||
|
|
||||||
|
With a prefix argument ARG, prompts for a regexp to filter specs.
|
||||||
|
No filter applied if the regexp is the empty string.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-cheatsheet" "cider-cheatsheet.el" (23377
|
||||||
|
;;;;;; 61664 799996 355000))
|
||||||
|
;;; Generated autoloads from cider-cheatsheet.el
|
||||||
|
|
||||||
|
(autoload 'cider-cheatsheet "cider-cheatsheet" "\
|
||||||
|
Navigate `cider-cheatsheet-hierarchy' with `completing-read'.
|
||||||
|
|
||||||
|
When you make it to a Clojure var its doc buffer gets displayed.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-classpath" "cider-classpath.el" (23377
|
||||||
|
;;;;;; 61664 806586 783000))
|
||||||
|
;;; Generated autoloads from cider-classpath.el
|
||||||
|
|
||||||
|
(autoload 'cider-classpath "cider-classpath" "\
|
||||||
|
List all classpath entries.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-open-classpath-entry "cider-classpath" "\
|
||||||
|
Open a classpath entry.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-debug" "cider-debug.el" (23377 61664
|
||||||
|
;;;;;; 769634 161000))
|
||||||
|
;;; Generated autoloads from cider-debug.el
|
||||||
|
|
||||||
|
(autoload 'cider-debug-defun-at-point "cider-debug" "\
|
||||||
|
Instrument the \"top-level\" expression at point.
|
||||||
|
If it is a defn, dispatch the instrumented definition. Otherwise,
|
||||||
|
immediately evaluate the instrumented expression.
|
||||||
|
|
||||||
|
While debugged code is being evaluated, the user is taken through the
|
||||||
|
source code and displayed the value of various expressions. At each step,
|
||||||
|
a number of keys will be prompted to the user.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-find" "cider-find.el" (23377 61664 796304
|
||||||
|
;;;;;; 526000))
|
||||||
|
;;; Generated autoloads from cider-find.el
|
||||||
|
|
||||||
|
(autoload 'cider-find-var "cider-find" "\
|
||||||
|
Find definition for VAR at LINE.
|
||||||
|
Prompt according to prefix ARG and `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. The default value is
|
||||||
|
thing at point.
|
||||||
|
|
||||||
|
\(fn &optional ARG VAR LINE)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-find-dwim "cider-find" "\
|
||||||
|
Find and display the SYMBOL-FILE at point.
|
||||||
|
SYMBOL-FILE could be a var or a resource. If thing at point is empty then
|
||||||
|
show dired on project. If var is not found, try to jump to resource of the
|
||||||
|
same name. When called interactively, a prompt is given according to the
|
||||||
|
variable `cider-prompt-for-symbol'. A single or double prefix argument
|
||||||
|
inverts the meaning. A prefix of `-' or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. A default value of thing
|
||||||
|
at point is given when prompted.
|
||||||
|
|
||||||
|
\(fn SYMBOL-FILE)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-find-resource "cider-find" "\
|
||||||
|
Find the resource at PATH.
|
||||||
|
Prompt for input as indicated by the variable `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix argument of `-` or a double prefix
|
||||||
|
argument causes the results to be displayed in other window. The default
|
||||||
|
value is thing at point.
|
||||||
|
|
||||||
|
\(fn PATH)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-find-ns "cider-find" "\
|
||||||
|
Find the file containing NS.
|
||||||
|
A prefix ARG of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window.
|
||||||
|
|
||||||
|
\(fn &optional ARG NS)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-find-keyword "cider-find" "\
|
||||||
|
Find the namespace of the keyword at point and its first occurrence there.
|
||||||
|
|
||||||
|
For instance - if the keyword at point is \":cider.demo/keyword\", this command
|
||||||
|
would find the namespace \"cider.demo\" and afterwards find the first mention
|
||||||
|
of \"::keyword\" there.
|
||||||
|
|
||||||
|
Prompt according to prefix ARG and `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. The default value is
|
||||||
|
thing at point.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-format" "cider-format.el" (23377 61664
|
||||||
|
;;;;;; 755199 681000))
|
||||||
|
;;; Generated autoloads from cider-format.el
|
||||||
|
|
||||||
|
(autoload 'cider-format-region "cider-format" "\
|
||||||
|
Format the Clojure code in the current region.
|
||||||
|
START and END represent the region's boundaries.
|
||||||
|
|
||||||
|
\(fn START END)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-format-defun "cider-format" "\
|
||||||
|
Format the code in the current defun.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-format-buffer "cider-format" "\
|
||||||
|
Format the Clojure code in the current buffer.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-format-edn-buffer "cider-format" "\
|
||||||
|
Format the EDN data in the current buffer.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-format-edn-region "cider-format" "\
|
||||||
|
Format the EDN data in the current region.
|
||||||
|
START and END represent the region's boundaries.
|
||||||
|
|
||||||
|
\(fn START END)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-format-edn-last-sexp "cider-format" "\
|
||||||
|
Format the EDN data of the last sexp.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-grimoire" "cider-grimoire.el" (23377
|
||||||
|
;;;;;; 61664 785871 442000))
|
||||||
|
;;; Generated autoloads from cider-grimoire.el
|
||||||
|
|
||||||
|
(autoload 'cider-grimoire-web "cider-grimoire" "\
|
||||||
|
Open grimoire documentation in the default web browser.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-grimoire "cider-grimoire" "\
|
||||||
|
Open grimoire documentation in a popup buffer.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-inspector" "cider-inspector.el" (23377
|
||||||
|
;;;;;; 61664 783382 910000))
|
||||||
|
;;; Generated autoloads from cider-inspector.el
|
||||||
|
|
||||||
|
(autoload 'cider-inspect-last-sexp "cider-inspector" "\
|
||||||
|
Inspect the result of the the expression preceding point.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-inspect-defun-at-point "cider-inspector" "\
|
||||||
|
Inspect the result of the \"top-level\" expression at point.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-inspect-last-result "cider-inspector" "\
|
||||||
|
Inspect the most recent eval result.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-inspect "cider-inspector" "\
|
||||||
|
Inspect the result of the preceding sexp.
|
||||||
|
|
||||||
|
With a prefix argument ARG it inspects the result of the \"top-level\" form.
|
||||||
|
With a second prefix argument it prompts for an expression to eval and inspect.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-inspect-expr "cider-inspector" "\
|
||||||
|
Evaluate EXPR in NS and inspect its value.
|
||||||
|
Interactively, EXPR is read from the minibuffer, and NS the
|
||||||
|
current buffer's namespace.
|
||||||
|
|
||||||
|
\(fn EXPR NS)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-macroexpansion" "cider-macroexpansion.el"
|
||||||
|
;;;;;; (23377 61664 801273 463000))
|
||||||
|
;;; Generated autoloads from cider-macroexpansion.el
|
||||||
|
|
||||||
|
(autoload 'cider-macroexpand-1 "cider-macroexpansion" "\
|
||||||
|
Invoke \\=`macroexpand-1\\=` on the expression preceding point.
|
||||||
|
If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
|
||||||
|
\\=`macroexpand-1\\=`.
|
||||||
|
|
||||||
|
\(fn &optional PREFIX)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-macroexpand-all "cider-macroexpansion" "\
|
||||||
|
Invoke \\=`macroexpand-all\\=` on the expression preceding point.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-mode" "cider-mode.el" (23377 61664 773443
|
||||||
|
;;;;;; 195000))
|
||||||
|
;;; Generated autoloads from cider-mode.el
|
||||||
|
|
||||||
|
(defvar cider-mode-line '(:eval (format " cider[%s]" (cider--modeline-info))) "\
|
||||||
|
Mode line lighter for cider mode.
|
||||||
|
|
||||||
|
The value of this variable is a mode line template as in
|
||||||
|
`mode-line-format'. See Info Node `(elisp)Mode Line Format' for details
|
||||||
|
about mode line templates.
|
||||||
|
|
||||||
|
Customize this variable to change how cider mode displays its status in the
|
||||||
|
mode line. The default value displays the current connection. Set this
|
||||||
|
variable to nil to disable the mode line entirely.")
|
||||||
|
|
||||||
|
(custom-autoload 'cider-mode-line "cider-mode" t)
|
||||||
|
|
||||||
|
(eval-after-load 'clojure-mode '(easy-menu-define cider-clojure-mode-menu-open clojure-mode-map "Menu for Clojure mode.\n This is displayed in `clojure-mode' buffers, if `cider-mode' is not active." `("CIDER" :visible (not cider-mode) ["Start a Clojure REPL" cider-jack-in :help "Starts an nREPL server (with Leiningen, Boot, or Gradle) and connects a REPL to it."] ["Connect to a Clojure REPL" cider-connect :help "Connects to a REPL that's already running."] ["Connect to a ClojureScript REPL" cider-connect-clojurescript :help "Connects to a ClojureScript REPL that's already running."] ["Start a Clojure REPL, and a ClojureScript REPL" cider-jack-in-cljs :help "Starts an nREPL server, connects a Clojure REPL to it, and then a ClojureScript REPL."] "--" ["View manual online" cider-view-manual])))
|
||||||
|
|
||||||
|
(autoload 'cider-mode "cider-mode" "\
|
||||||
|
Minor mode for REPL interaction from a Clojure buffer.
|
||||||
|
|
||||||
|
\\{cider-mode-map}
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-ns" "cider-ns.el" (23377 61664 775924
|
||||||
|
;;;;;; 562000))
|
||||||
|
;;; Generated autoloads from cider-ns.el
|
||||||
|
|
||||||
|
(autoload 'cider-ns-refresh "cider-ns" "\
|
||||||
|
Reload modified and unloaded namespaces on the classpath.
|
||||||
|
|
||||||
|
With a single prefix argument, or if MODE is `refresh-all', reload all
|
||||||
|
namespaces on the classpath unconditionally.
|
||||||
|
|
||||||
|
With a double prefix argument, or if MODE is `clear', clear the state of
|
||||||
|
the namespace tracker before reloading. This is useful for recovering from
|
||||||
|
some classes of error (for example, those caused by circular dependencies)
|
||||||
|
that a normal reload would not otherwise recover from. The trade-off of
|
||||||
|
clearing is that stale code from any deleted files may not be completely
|
||||||
|
unloaded.
|
||||||
|
|
||||||
|
With a negative prefix argument, or if MODE is `inhibit-fns', prevent any
|
||||||
|
refresh functions (defined in `cider-ns-refresh-before-fn' and
|
||||||
|
`cider-ns-refresh-after-fn') from being invoked.
|
||||||
|
|
||||||
|
\(fn &optional MODE)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-profile" "cider-profile.el" (23377 61664
|
||||||
|
;;;;;; 764574 111000))
|
||||||
|
;;; Generated autoloads from cider-profile.el
|
||||||
|
|
||||||
|
(autoload 'cider-profile-samples "cider-profile" "\
|
||||||
|
Displays current max-sample-count.
|
||||||
|
If optional QUERY is specified, set max-sample-count and display new value.
|
||||||
|
|
||||||
|
\(fn &optional QUERY)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-var-profiled-p "cider-profile" "\
|
||||||
|
Displays the profiling status of var under point.
|
||||||
|
Prompts for var if none under point or QUERY is present.
|
||||||
|
|
||||||
|
\(fn QUERY)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-ns-toggle "cider-profile" "\
|
||||||
|
Toggle profiling for the ns associated with optional QUERY.
|
||||||
|
|
||||||
|
If optional argument QUERY is non-nil, prompt for ns. Otherwise use
|
||||||
|
current ns.
|
||||||
|
|
||||||
|
\(fn &optional QUERY)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-toggle "cider-profile" "\
|
||||||
|
Toggle profiling for the given QUERY.
|
||||||
|
Defaults to the symbol at point.
|
||||||
|
With prefix arg or no symbol at point, prompts for a var.
|
||||||
|
|
||||||
|
\(fn QUERY)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-summary "cider-profile" "\
|
||||||
|
Display a summary of currently collected profile data.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-var-summary "cider-profile" "\
|
||||||
|
Display profile data for var under point QUERY.
|
||||||
|
Defaults to the symbol at point. With prefix arg or no symbol at point,
|
||||||
|
prompts for a var.
|
||||||
|
|
||||||
|
\(fn QUERY)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-profile-clear "cider-profile" "\
|
||||||
|
Clear any collected profile data.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-repl-history" "cider-repl-history.el"
|
||||||
|
;;;;;; (23377 61664 794990 521000))
|
||||||
|
;;; Generated autoloads from cider-repl-history.el
|
||||||
|
|
||||||
|
(autoload 'cider-repl-history "cider-repl-history" "\
|
||||||
|
Display items in the CIDER command history in another buffer.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-scratch" "cider-scratch.el" (23377 61664
|
||||||
|
;;;;;; 778379 441000))
|
||||||
|
;;; Generated autoloads from cider-scratch.el
|
||||||
|
|
||||||
|
(autoload 'cider-scratch "cider-scratch" "\
|
||||||
|
Go to the scratch buffer named `cider-scratch-buffer-name'.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-selector" "cider-selector.el" (23377
|
||||||
|
;;;;;; 61664 805380 173000))
|
||||||
|
;;; Generated autoloads from cider-selector.el
|
||||||
|
|
||||||
|
(autoload 'cider-selector "cider-selector" "\
|
||||||
|
Select a new buffer by type, indicated by a single character.
|
||||||
|
The user is prompted for a single character indicating the method by
|
||||||
|
which to choose a new buffer. The `?' character describes then
|
||||||
|
available methods. OTHER-WINDOW provides an optional target.
|
||||||
|
See `def-cider-selector-method' for defining new methods.
|
||||||
|
|
||||||
|
\(fn &optional OTHER-WINDOW)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-test" "cider-test.el" (23377 61664 798770
|
||||||
|
;;;;;; 508000))
|
||||||
|
;;; Generated autoloads from cider-test.el
|
||||||
|
|
||||||
|
(defvar cider-auto-test-mode nil "\
|
||||||
|
Non-nil if Cider-Auto-Test mode is enabled.
|
||||||
|
See the `cider-auto-test-mode' command
|
||||||
|
for a description of this minor mode.
|
||||||
|
Setting this variable directly does not take effect;
|
||||||
|
either customize it (see the info node `Easy Customization')
|
||||||
|
or call the function `cider-auto-test-mode'.")
|
||||||
|
|
||||||
|
(custom-autoload 'cider-auto-test-mode "cider-test" nil)
|
||||||
|
|
||||||
|
(autoload 'cider-auto-test-mode "cider-test" "\
|
||||||
|
Toggle automatic testing of Clojure files.
|
||||||
|
|
||||||
|
When enabled this reruns tests every time a Clojure file is loaded.
|
||||||
|
Only runs tests corresponding to the loaded file's namespace and does
|
||||||
|
nothing if no tests are defined or if the file failed to load.
|
||||||
|
|
||||||
|
\(fn &optional ARG)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-tracing" "cider-tracing.el" (23377 61664
|
||||||
|
;;;;;; 774719 690000))
|
||||||
|
;;; Generated autoloads from cider-tracing.el
|
||||||
|
|
||||||
|
(autoload 'cider-toggle-trace-var "cider-tracing" "\
|
||||||
|
Toggle var tracing.
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates.
|
||||||
|
|
||||||
|
\(fn ARG)" t nil)
|
||||||
|
|
||||||
|
(autoload 'cider-toggle-trace-ns "cider-tracing" "\
|
||||||
|
Toggle ns tracing.
|
||||||
|
Defaults to the current ns. With prefix arg QUERY, prompts for a ns.
|
||||||
|
|
||||||
|
\(fn QUERY)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil "cider-util" "cider-util.el" (23377 61664 802813
|
||||||
|
;;;;;; 332000))
|
||||||
|
;;; Generated autoloads from cider-util.el
|
||||||
|
|
||||||
|
(autoload 'cider-view-manual "cider-util" "\
|
||||||
|
View the manual in your default browser.
|
||||||
|
|
||||||
|
\(fn)" t nil)
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;;;### (autoloads nil nil ("cider-client.el" "cider-common.el" "cider-compat.el"
|
||||||
|
;;;;;; "cider-completion.el" "cider-connection.el" "cider-doc.el"
|
||||||
|
;;;;;; "cider-eldoc.el" "cider-eval.el" "cider-overlays.el" "cider-pkg.el"
|
||||||
|
;;;;;; "cider-popup.el" "cider-repl.el" "cider-resolve.el" "cider-stacktrace.el"
|
||||||
|
;;;;;; "nrepl-client.el" "nrepl-dict.el") (23377 61664 793689 575000))
|
||||||
|
|
||||||
|
;;;***
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; version-control: never
|
||||||
|
;; no-byte-compile: t
|
||||||
|
;; no-update-autoloads: t
|
||||||
|
;; End:
|
||||||
|
;;; cider-autoloads.el ends here
|
|
@ -0,0 +1,232 @@
|
||||||
|
;;; cider-browse-ns.el --- CIDER namespace browser
|
||||||
|
|
||||||
|
;; Copyright © 2014-2018 John Andrews, Bozhidar Batsov and CIDER contributors
|
||||||
|
|
||||||
|
;; Author: John Andrews <john.m.andrews@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; M-x cider-browse-ns
|
||||||
|
;;
|
||||||
|
;; Display a list of all vars in a namespace.
|
||||||
|
;; Pressing <enter> will take you to the cider-doc buffer for that var.
|
||||||
|
;; Pressing ^ will take you to a list of all namespaces (akin to `dired-mode').
|
||||||
|
|
||||||
|
;; M-x cider-browse-ns-all
|
||||||
|
;;
|
||||||
|
;; Explore Clojure namespaces by browsing a list of all namespaces.
|
||||||
|
;; Pressing <enter> expands into a list of that namespace's vars as if by
|
||||||
|
;; executing the command (cider-browse-ns "my.ns").
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-popup)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'easymenu)
|
||||||
|
(require 'thingatpt)
|
||||||
|
|
||||||
|
(defconst cider-browse-ns-buffer "*cider-ns-browser*")
|
||||||
|
|
||||||
|
(defvar-local cider-browse-ns-current-ns nil)
|
||||||
|
|
||||||
|
;; Mode Definition
|
||||||
|
|
||||||
|
(defvar cider-browse-ns-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map cider-popup-buffer-mode-map)
|
||||||
|
(define-key map "d" #'cider-browse-ns-doc-at-point)
|
||||||
|
(define-key map "s" #'cider-browse-ns-find-at-point)
|
||||||
|
(define-key map (kbd "RET") #'cider-browse-ns-operate-at-point)
|
||||||
|
(define-key map "^" #'cider-browse-ns-all)
|
||||||
|
(define-key map "n" #'next-line)
|
||||||
|
(define-key map "p" #'previous-line)
|
||||||
|
(easy-menu-define cider-browse-ns-mode-menu map
|
||||||
|
"Menu for CIDER's namespace browser"
|
||||||
|
'("Namespace Browser"
|
||||||
|
["Show doc" cider-browse-ns-doc-at-point]
|
||||||
|
["Go to definition" cider-browse-ns-find-at-point]
|
||||||
|
"--"
|
||||||
|
["Browse all namespaces" cider-browse-ns-all]))
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defvar cider-browse-ns-mouse-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map [mouse-1] #'cider-browse-ns-handle-mouse)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(define-derived-mode cider-browse-ns-mode special-mode "browse-ns"
|
||||||
|
"Major mode for browsing Clojure namespaces.
|
||||||
|
|
||||||
|
\\{cider-browse-ns-mode-map}"
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t))
|
||||||
|
(setq-local cider-browse-ns-current-ns nil))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--text-face (var-meta)
|
||||||
|
"Return font-lock-face for a var.
|
||||||
|
VAR-META contains the metadata information used to decide a face.
|
||||||
|
Presence of \"arglists-str\" and \"macro\" indicates a macro form.
|
||||||
|
Only \"arglists-str\" indicates a function. Otherwise, its a variable.
|
||||||
|
If the NAMESPACE is not loaded in the REPL, assume TEXT is a fn."
|
||||||
|
(cond
|
||||||
|
((not var-meta) 'font-lock-function-name-face)
|
||||||
|
((and (nrepl-dict-contains var-meta "arglists")
|
||||||
|
(string= (nrepl-dict-get var-meta "macro") "true"))
|
||||||
|
'font-lock-keyword-face)
|
||||||
|
((nrepl-dict-contains var-meta "arglists") 'font-lock-function-name-face)
|
||||||
|
(t 'font-lock-variable-name-face)))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--properties (var var-meta)
|
||||||
|
"Decorate VAR with a clickable keymap and a face.
|
||||||
|
VAR-META is used to decide a font-lock face."
|
||||||
|
(let ((face (cider-browse-ns--text-face var-meta)))
|
||||||
|
(propertize var
|
||||||
|
'font-lock-face face
|
||||||
|
'mouse-face 'highlight
|
||||||
|
'keymap cider-browse-ns-mouse-map)))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--list (buffer title items &optional ns noerase)
|
||||||
|
"Reset contents of BUFFER.
|
||||||
|
Display TITLE at the top and ITEMS are indented underneath.
|
||||||
|
If NS is non-nil, it is added to each item as the
|
||||||
|
`cider-browse-ns-current-ns' text property. If NOERASE is non-nil, the
|
||||||
|
contents of the buffer are not reset before inserting TITLE and ITEMS."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-browse-ns-mode)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(unless noerase (erase-buffer))
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert (cider-propertize title 'ns) "\n")
|
||||||
|
(dolist (item items)
|
||||||
|
(insert (propertize (concat " " item "\n")
|
||||||
|
'cider-browse-ns-current-ns ns)))
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--first-doc-line (doc)
|
||||||
|
"Return the first line of the given DOC string.
|
||||||
|
If the first line of the DOC string contains multiple sentences, only
|
||||||
|
the first sentence is returned. If the DOC string is nil, a Not documented
|
||||||
|
string is returned."
|
||||||
|
(if doc
|
||||||
|
(let* ((split-newline (split-string doc "\n"))
|
||||||
|
(first-line (car split-newline)))
|
||||||
|
(cond
|
||||||
|
((string-match "\\. " first-line) (substring first-line 0 (match-end 0)))
|
||||||
|
((= 1 (length split-newline)) first-line)
|
||||||
|
(t (concat first-line "..."))))
|
||||||
|
"Not documented."))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--items (namespace)
|
||||||
|
"Return the items to show in the namespace browser of the given NAMESPACE.
|
||||||
|
Each item consists of a ns-var and the first line of its docstring."
|
||||||
|
(let* ((ns-vars-with-meta (cider-sync-request:ns-vars-with-meta namespace))
|
||||||
|
(propertized-ns-vars (nrepl-dict-map #'cider-browse-ns--properties ns-vars-with-meta)))
|
||||||
|
(mapcar (lambda (ns-var)
|
||||||
|
(let* ((doc (nrepl-dict-get-in ns-vars-with-meta (list ns-var "doc")))
|
||||||
|
;; to avoid (read nil)
|
||||||
|
;; it prompts the user for a Lisp expression
|
||||||
|
(doc (when doc (read doc)))
|
||||||
|
(first-doc-line (cider-browse-ns--first-doc-line doc)))
|
||||||
|
(concat ns-var " " (propertize first-doc-line 'font-lock-face 'font-lock-doc-face))))
|
||||||
|
propertized-ns-vars)))
|
||||||
|
|
||||||
|
;; Interactive Functions
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-browse-ns (namespace)
|
||||||
|
"List all NAMESPACE's vars in BUFFER."
|
||||||
|
(interactive (list (completing-read "Browse namespace: " (cider-sync-request:ns-list))))
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-ns-buffer 'select nil 'ancillary)
|
||||||
|
(cider-browse-ns--list (current-buffer)
|
||||||
|
namespace
|
||||||
|
(cider-browse-ns--items namespace))
|
||||||
|
(setq-local cider-browse-ns-current-ns namespace)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-browse-ns-all ()
|
||||||
|
"List all loaded namespaces in BUFFER."
|
||||||
|
(interactive)
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-ns-buffer 'select nil 'ancillary)
|
||||||
|
(let ((names (cider-sync-request:ns-list)))
|
||||||
|
(cider-browse-ns--list (current-buffer)
|
||||||
|
"All loaded namespaces"
|
||||||
|
(mapcar (lambda (name)
|
||||||
|
(cider-browse-ns--properties name nil))
|
||||||
|
names))
|
||||||
|
(setq-local cider-browse-ns-current-ns nil))))
|
||||||
|
|
||||||
|
(defun cider-browse-ns--thing-at-point ()
|
||||||
|
"Get the thing at point.
|
||||||
|
Return a list of the type ('ns or 'var) and the value."
|
||||||
|
(let ((line (car (split-string (string-trim (thing-at-point 'line)) " "))))
|
||||||
|
(if (string-match "\\." line)
|
||||||
|
`(ns ,line)
|
||||||
|
`(var ,(format "%s/%s"
|
||||||
|
(or (get-text-property (point) 'cider-browse-ns-current-ns)
|
||||||
|
cider-browse-ns-current-ns)
|
||||||
|
line)))))
|
||||||
|
|
||||||
|
(defun cider-browse-ns-doc-at-point ()
|
||||||
|
"Show the documentation for the thing at current point."
|
||||||
|
(interactive)
|
||||||
|
(let* ((thing (cider-browse-ns--thing-at-point))
|
||||||
|
(value (cadr thing)))
|
||||||
|
;; value is either some ns or a var
|
||||||
|
(cider-doc-lookup value)))
|
||||||
|
|
||||||
|
(defun cider-browse-ns-operate-at-point ()
|
||||||
|
"Expand browser according to thing at current point.
|
||||||
|
If the thing at point is a ns it will be browsed,
|
||||||
|
and if the thing at point is some var - its documentation will
|
||||||
|
be displayed."
|
||||||
|
(interactive)
|
||||||
|
(let* ((thing (cider-browse-ns--thing-at-point))
|
||||||
|
(type (car thing))
|
||||||
|
(value (cadr thing)))
|
||||||
|
(if (eq type 'ns)
|
||||||
|
(cider-browse-ns value)
|
||||||
|
(cider-doc-lookup value))))
|
||||||
|
|
||||||
|
(declare-function cider-find-ns "cider-find")
|
||||||
|
(declare-function cider-find-var "cider-find")
|
||||||
|
|
||||||
|
(defun cider-browse-ns-find-at-point ()
|
||||||
|
"Find the definition of the thing at point."
|
||||||
|
(interactive)
|
||||||
|
(let* ((thing (cider-browse-ns--thing-at-point))
|
||||||
|
(type (car thing))
|
||||||
|
(value (cadr thing)))
|
||||||
|
(if (eq type 'ns)
|
||||||
|
(cider-find-ns nil value)
|
||||||
|
(cider-find-var current-prefix-arg value))))
|
||||||
|
|
||||||
|
(defun cider-browse-ns-handle-mouse (event)
|
||||||
|
"Handle mouse click EVENT."
|
||||||
|
(interactive "e")
|
||||||
|
(cider-browse-ns-operate-at-point))
|
||||||
|
|
||||||
|
(provide 'cider-browse-ns)
|
||||||
|
|
||||||
|
;;; cider-browse-ns.el ends here
|
Binary file not shown.
|
@ -0,0 +1,357 @@
|
||||||
|
;;; cider-browse-spec.el --- CIDER spec browser
|
||||||
|
|
||||||
|
;; Copyright © 2017 Juan Monetta, Bozhidar Batsov and CIDER contributors
|
||||||
|
|
||||||
|
;; Author: Juan Monetta <jpmonettas@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; M-x cider-browse-spec
|
||||||
|
;;
|
||||||
|
;; Display a spec description you can browse.
|
||||||
|
;; Pressing <enter> over a sub spec will take you to the description of that sub spec.
|
||||||
|
;; Pressing ^ takes you to the list of all specs.
|
||||||
|
|
||||||
|
;; M-x cider-browse-spec-all
|
||||||
|
;;
|
||||||
|
;; Explore clojure.spec registry by browsing a list of all specs.
|
||||||
|
;; Pressing <enter> over a spec display the spec description you can browse.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
(require 'seq)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'help-mode)
|
||||||
|
|
||||||
|
;; The buffer names used by the spec browser
|
||||||
|
(defconst cider-browse-spec-buffer "*cider-spec-browser*")
|
||||||
|
(defconst cider-browse-spec-example-buffer "*cider-spec-example*")
|
||||||
|
|
||||||
|
;; Mode Definition
|
||||||
|
|
||||||
|
(defvar cider-browse-spec-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map (make-composed-keymap button-buffer-map
|
||||||
|
cider-popup-buffer-mode-map))
|
||||||
|
(define-key map (kbd "RET") #'cider-browse-spec--browse-at)
|
||||||
|
(define-key map "n" #'forward-button)
|
||||||
|
(define-key map "p" #'backward-button)
|
||||||
|
map)
|
||||||
|
"Keymap for `cider-browse-spec-mode'.")
|
||||||
|
|
||||||
|
(define-derived-mode cider-browse-spec-mode special-mode "Specs"
|
||||||
|
"Major mode for browsing Clojure specs.
|
||||||
|
|
||||||
|
\\{cider-browse-spec-mode-map}"
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t)))
|
||||||
|
|
||||||
|
(defvar cider-browse-spec--current-spec nil)
|
||||||
|
|
||||||
|
(defvar cider-browse-spec-view-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map help-mode-map)
|
||||||
|
(define-key map (kbd "RET") #'cider-browse-spec--browse-at)
|
||||||
|
(define-key map "^" #'cider-browse-spec-all)
|
||||||
|
(define-key map "e" #'cider-browse-spec--print-curr-spec-example)
|
||||||
|
(define-key map "n" #'forward-button)
|
||||||
|
(define-key map "p" #'backward-button)
|
||||||
|
map)
|
||||||
|
"Keymap for `cider-browse-spec-view-mode'.")
|
||||||
|
|
||||||
|
(define-derived-mode cider-browse-spec-view-mode help-mode "Spec"
|
||||||
|
"Major mode for displaying CIDER spec.
|
||||||
|
|
||||||
|
\\{cider-browse-spec-view-mode-map}"
|
||||||
|
(setq-local cider-browse-spec--current-spec nil)
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t)))
|
||||||
|
|
||||||
|
(defvar cider-browse-spec-example-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map cider-popup-buffer-mode-map)
|
||||||
|
(define-key map "^" #'cider-browse-spec-all)
|
||||||
|
(define-key map "e" #'cider-browse-spec--print-curr-spec-example)
|
||||||
|
(define-key map "g" #'revert-buffer)
|
||||||
|
map)
|
||||||
|
"Keymap for `cider-browse-spec-example-mode'.")
|
||||||
|
|
||||||
|
(define-derived-mode cider-browse-spec-example-mode special-mode "Example"
|
||||||
|
"Major mode for Clojure spec examples.
|
||||||
|
|
||||||
|
\\{cider-browse-spec-example-mode-map}"
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local revert-buffer-function #'cider-browse-spec--example-revert-buffer-function)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t)))
|
||||||
|
|
||||||
|
;; Non interactive functions
|
||||||
|
|
||||||
|
(define-button-type 'cider-browse-spec--spec
|
||||||
|
'action #'cider-browse-spec--browse-at
|
||||||
|
'face nil
|
||||||
|
'follow-link t
|
||||||
|
'help-echo "View spec")
|
||||||
|
|
||||||
|
(defun cider-browse-spec--draw-list-buffer (buffer title specs)
|
||||||
|
"Reset contents of BUFFER.
|
||||||
|
Display TITLE at the top and SPECS are indented underneath."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-browse-spec-mode)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(erase-buffer)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert (cider-propertize title 'emph) "\n")
|
||||||
|
(dolist (spec-name specs)
|
||||||
|
(insert (propertize " " 'spec-name spec-name))
|
||||||
|
(thread-first (cider-font-lock-as-clojure spec-name)
|
||||||
|
(insert-text-button 'type 'cider-browse-spec--spec)
|
||||||
|
(button-put 'spec-name spec-name))
|
||||||
|
(insert (propertize "\n" 'spec-name spec-name)))
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
(defun cider--qualified-keyword-p (str)
|
||||||
|
"Return non nil if STR is a namespaced keyword."
|
||||||
|
(string-match-p "^:.+/.+$" str))
|
||||||
|
|
||||||
|
(defun cider--spec-fn-p (value fn-name)
|
||||||
|
"Return non nil if VALUE is clojure.spec.[alpha]/FN-NAME."
|
||||||
|
(string-match-p (concat "^\\(clojure.spec\\|clojure.spec.alpha\\)/" fn-name "$") value))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--pprint (form)
|
||||||
|
"Given a spec FORM builds a multi line string with a pretty render of that FORM."
|
||||||
|
(cond ((stringp form)
|
||||||
|
(if (cider--qualified-keyword-p form)
|
||||||
|
(with-temp-buffer
|
||||||
|
(thread-first form
|
||||||
|
(insert-text-button 'type 'cider-browse-spec--spec)
|
||||||
|
(button-put 'spec-name form))
|
||||||
|
(buffer-string))
|
||||||
|
;; to make it easier to read replace all clojure.spec ns with s/
|
||||||
|
;; and remove all clojure.core ns
|
||||||
|
(thread-last form
|
||||||
|
(replace-regexp-in-string "^\\(clojure.spec\\|clojure.spec.alpha\\)/" "s/")
|
||||||
|
(replace-regexp-in-string "^\\(clojure.core\\)/" ""))))
|
||||||
|
|
||||||
|
((and (listp form) (stringp (cl-first form)))
|
||||||
|
(let ((form-tag (cl-first form)))
|
||||||
|
(cond
|
||||||
|
;; prettier fns #()
|
||||||
|
((string-equal form-tag "clojure.core/fn")
|
||||||
|
(if (equal (cl-second form) '("%"))
|
||||||
|
(format "#%s" (cl-reduce #'concat (mapcar #'cider-browse-spec--pprint (cl-rest (cl-rest form)))))
|
||||||
|
(format "(fn [%%] %s)" (cl-reduce #'concat (mapcar #'cider-browse-spec--pprint (cl-rest (cl-rest form)))))))
|
||||||
|
;; prettier (s/and )
|
||||||
|
((cider--spec-fn-p form-tag "and")
|
||||||
|
(format "(s/and\n%s)" (string-join (thread-last (cl-rest form)
|
||||||
|
(mapcar #'cider-browse-spec--pprint)
|
||||||
|
(mapcar (lambda (x) (format "%s" x))))
|
||||||
|
"\n")))
|
||||||
|
;; prettier (s/or )
|
||||||
|
((cider--spec-fn-p form-tag "or")
|
||||||
|
(let ((name-spec-pair (seq-partition (cl-rest form) 2)))
|
||||||
|
(format "(s/or\n%s)" (string-join
|
||||||
|
(thread-last name-spec-pair
|
||||||
|
(mapcar (lambda (s) (format "%s %s" (cl-first s) (cider-browse-spec--pprint (cl-second s))))))
|
||||||
|
"\n"))))
|
||||||
|
;; prettier (s/merge )
|
||||||
|
((cider--spec-fn-p form-tag "merge")
|
||||||
|
(format "(s/merge\n%s)" (string-join (thread-last (cl-rest form)
|
||||||
|
(mapcar #'cider-browse-spec--pprint)
|
||||||
|
(mapcar (lambda (x) (format "%s" x))))
|
||||||
|
"\n")))
|
||||||
|
;; prettier (s/keys )
|
||||||
|
((cider--spec-fn-p form-tag "keys")
|
||||||
|
(let ((keys-args (seq-partition (cl-rest form) 2)))
|
||||||
|
(format "(s/keys%s)" (thread-last
|
||||||
|
keys-args
|
||||||
|
(mapcar (lambda (s)
|
||||||
|
(let ((key-type (cl-first s))
|
||||||
|
(specs-vec (cl-second s)))
|
||||||
|
(concat "\n" key-type
|
||||||
|
" ["
|
||||||
|
(string-join (thread-last specs-vec
|
||||||
|
(mapcar #'cider-browse-spec--pprint)
|
||||||
|
(mapcar (lambda (x) (format "%s" x))))
|
||||||
|
"\n")
|
||||||
|
"]"))))
|
||||||
|
(cl-reduce #'concat)))))
|
||||||
|
;; prettier (s/multi-spec)
|
||||||
|
((cider--spec-fn-p form-tag "multi-spec")
|
||||||
|
(let ((multi-method (cl-second form))
|
||||||
|
(retag (cl-third form))
|
||||||
|
(sub-specs (cl-rest (cl-rest (cl-rest form)))))
|
||||||
|
(format "(s/multi-spec %s %s\n%s)"
|
||||||
|
multi-method
|
||||||
|
retag
|
||||||
|
(string-join
|
||||||
|
(thread-last sub-specs
|
||||||
|
(mapcar (lambda (s)
|
||||||
|
(concat "\n\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s))))))
|
||||||
|
"\n"))))
|
||||||
|
;; prettier (s/cat )
|
||||||
|
((cider--spec-fn-p form-tag "cat")
|
||||||
|
(let ((name-spec-pairs (seq-partition (cl-rest form) 2)))
|
||||||
|
(format "(s/cat %s)"
|
||||||
|
(thread-last name-spec-pairs
|
||||||
|
(mapcar (lambda (s)
|
||||||
|
(concat "\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s)))))
|
||||||
|
(cl-reduce #'concat)))))
|
||||||
|
;; prettier (s/alt )
|
||||||
|
((cider--spec-fn-p form-tag "alt")
|
||||||
|
(let ((name-spec-pairs (seq-partition (cl-rest form) 2)))
|
||||||
|
(format "(s/alt %s)"
|
||||||
|
(thread-last name-spec-pairs
|
||||||
|
(mapcar (lambda (s)
|
||||||
|
(concat "\n" (cl-first s) " " (cider-browse-spec--pprint (cl-second s)))))
|
||||||
|
(cl-reduce #'concat)))))
|
||||||
|
;; prettier (s/fspec )
|
||||||
|
((cider--spec-fn-p form-tag "fspec")
|
||||||
|
(thread-last (seq-partition (cl-rest form) 2)
|
||||||
|
(cl-remove-if (lambda (s) (and (stringp (cl-second s))
|
||||||
|
(string-empty-p (cl-second s)))))
|
||||||
|
(mapcar (lambda (s)
|
||||||
|
(format "\n%-11s: %s" (pcase (cl-first s)
|
||||||
|
(":args" "arguments")
|
||||||
|
(":ret" "returns")
|
||||||
|
(":fn" "invariants"))
|
||||||
|
(cider-browse-spec--pprint (cl-second s)))))
|
||||||
|
(cl-reduce #'concat)
|
||||||
|
(format "%s")))
|
||||||
|
;; every other with no special management
|
||||||
|
(t (format "(%s %s)"
|
||||||
|
(cider-browse-spec--pprint form-tag)
|
||||||
|
(string-join (mapcar #'cider-browse-spec--pprint (cl-rest form)) " "))))))
|
||||||
|
(t (format "%s" form))))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--pprint-indented (spec-form)
|
||||||
|
"Indent (pretty-print) and font-lock SPEC-FORM.
|
||||||
|
Return the result as a string."
|
||||||
|
(with-temp-buffer
|
||||||
|
(clojure-mode)
|
||||||
|
(insert (cider-browse-spec--pprint spec-form))
|
||||||
|
(indent-region (point-min) (point-max))
|
||||||
|
(cider--font-lock-ensure)
|
||||||
|
(buffer-string)))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--draw-spec-buffer (buffer spec spec-form)
|
||||||
|
"Reset contents of BUFFER and draws everything needed to browse the SPEC-FORM.
|
||||||
|
Display SPEC as a title and uses `cider-browse-spec--pprint' to display
|
||||||
|
a more user friendly representation of SPEC-FORM."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(cider--help-setup-xref (list #'cider-browse-spec spec) nil buffer)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert (cider-font-lock-as-clojure spec) "\n\n")
|
||||||
|
(insert (cider-browse-spec--pprint-indented spec-form))
|
||||||
|
(cider--make-back-forward-xrefs)
|
||||||
|
(current-buffer))))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--browse (spec)
|
||||||
|
"Browse SPEC."
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "spec-form")
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-spec-buffer 'select #'cider-browse-spec-view-mode 'ancillary)
|
||||||
|
(setq-local cider-browse-spec--current-spec spec)
|
||||||
|
(cider-browse-spec--draw-spec-buffer (current-buffer)
|
||||||
|
spec
|
||||||
|
(cider-sync-request:spec-form spec))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(current-buffer)))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--browse-at (&optional pos)
|
||||||
|
"View the definition of a spec.
|
||||||
|
|
||||||
|
Optional argument POS is the position of a spec, defaulting to point. POS
|
||||||
|
may also be a button, so this function can be used a the button's `action'
|
||||||
|
property."
|
||||||
|
(interactive)
|
||||||
|
(let ((pos (or pos (point))))
|
||||||
|
(when-let* ((spec (button-get pos 'spec-name)))
|
||||||
|
(cider-browse-spec--browse spec))))
|
||||||
|
|
||||||
|
;; Interactive Functions
|
||||||
|
|
||||||
|
(defun cider-browse-spec--print-curr-spec-example ()
|
||||||
|
"Generate and print an example of the current spec."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "spec-example")
|
||||||
|
(if-let* ((spec cider-browse-spec--current-spec))
|
||||||
|
(if-let* ((example (cider-sync-request:spec-example spec)))
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-spec-example-buffer 'select #'cider-browse-spec-example-mode 'ancillary)
|
||||||
|
(setq-local cider-browse-spec--current-spec spec)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(insert "Example of " (cider-font-lock-as-clojure spec))
|
||||||
|
(insert "\n\n")
|
||||||
|
(insert (cider-font-lock-as-clojure example))
|
||||||
|
(goto-char (point-min))))
|
||||||
|
(error (format "No example for spec %s" spec)))
|
||||||
|
(error "No current spec")))
|
||||||
|
|
||||||
|
(defun cider-browse-spec--example-revert-buffer-function (&rest _)
|
||||||
|
"`revert-buffer' function for `cider-browse-spec-example-mode'.
|
||||||
|
|
||||||
|
Generates a new example for the current spec."
|
||||||
|
(cider-browse-spec--print-curr-spec-example))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-browse-spec (spec)
|
||||||
|
"Browse SPEC definition."
|
||||||
|
(interactive (list (completing-read "Browse spec: "
|
||||||
|
(cider-sync-request:spec-list)
|
||||||
|
nil nil
|
||||||
|
(cider-symbol-at-point))))
|
||||||
|
(cider-browse-spec--browse spec))
|
||||||
|
|
||||||
|
(defun cider-browse-spec-regex (regex)
|
||||||
|
"Open the list of specs that matches REGEX in a popup buffer.
|
||||||
|
Displays all specs when REGEX is nil."
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "spec-list")
|
||||||
|
(let ((filter-regex (or regex "")))
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-spec-buffer 'select nil 'ancillary)
|
||||||
|
(let ((specs (cider-sync-request:spec-list filter-regex)))
|
||||||
|
(cider-browse-spec--draw-list-buffer (current-buffer)
|
||||||
|
(if (string-empty-p filter-regex)
|
||||||
|
"All specs in registry"
|
||||||
|
(format "All specs matching regex `%s' in registry" filter-regex))
|
||||||
|
specs)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-browse-spec-all (&optional arg)
|
||||||
|
"Open list of specs in a popup buffer.
|
||||||
|
|
||||||
|
With a prefix argument ARG, prompts for a regexp to filter specs.
|
||||||
|
No filter applied if the regexp is the empty string."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-browse-spec-regex (if arg (read-string "Filter regex: ") "")))
|
||||||
|
|
||||||
|
(provide 'cider-browse-spec)
|
||||||
|
|
||||||
|
;;; cider-browse-spec.el ends here
|
Binary file not shown.
|
@ -0,0 +1,577 @@
|
||||||
|
;;; cider-cheatsheet.el --- Quick reference for Clojure -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2018 Kris Jenkins, Bozhidar Batsov and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Kris Jenkins <krisajenkins@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; A quick reference system for Clojure. Fast, searchable & available offline.
|
||||||
|
|
||||||
|
;; Mostly taken from Kris Jenkins' `clojure-cheatsheet'
|
||||||
|
;; See: https://github.com/clojure-emacs/clojure-cheatsheet
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-doc)
|
||||||
|
(require 'seq)
|
||||||
|
|
||||||
|
(defconst cider-cheatsheet-hierarchy
|
||||||
|
'(("Primitives"
|
||||||
|
("Numbers"
|
||||||
|
("Arithmetic"
|
||||||
|
(clojure.core + - * / quot rem mod dec inc max min))
|
||||||
|
("Compare"
|
||||||
|
(clojure.core = == not= < > <= >= compare))
|
||||||
|
("Bitwise"
|
||||||
|
(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))
|
||||||
|
("Cast"
|
||||||
|
(clojure.core byte short long int float double bigdec bigint biginteger num rationalize))
|
||||||
|
("Test"
|
||||||
|
(clojure.core nil? some? identical? zero? pos? neg? even? odd?))
|
||||||
|
("Random"
|
||||||
|
(clojure.core rand rand-int))
|
||||||
|
("BigDecimal"
|
||||||
|
(clojure.core with-precision))
|
||||||
|
("Ratios"
|
||||||
|
(clojure.core numerator denominator ratio?))
|
||||||
|
("Arbitrary Precision Arithmetic"
|
||||||
|
(clojure.core +\' -\' *\' inc\' dec\'))
|
||||||
|
("Unchecked"
|
||||||
|
(clojure.core *unchecked-math*
|
||||||
|
unchecked-add
|
||||||
|
unchecked-add-int
|
||||||
|
unchecked-byte
|
||||||
|
unchecked-char
|
||||||
|
unchecked-dec
|
||||||
|
unchecked-dec-int
|
||||||
|
unchecked-divide-int
|
||||||
|
unchecked-double
|
||||||
|
unchecked-float
|
||||||
|
unchecked-inc
|
||||||
|
unchecked-inc-int
|
||||||
|
unchecked-int
|
||||||
|
unchecked-long
|
||||||
|
unchecked-multiply
|
||||||
|
unchecked-multiply-int
|
||||||
|
unchecked-negate
|
||||||
|
unchecked-negate-int
|
||||||
|
unchecked-remainder-int
|
||||||
|
unchecked-short
|
||||||
|
unchecked-subtract
|
||||||
|
unchecked-subtract-int)))
|
||||||
|
|
||||||
|
("Strings"
|
||||||
|
("Create"
|
||||||
|
(clojure.core str format))
|
||||||
|
("Use"
|
||||||
|
(clojure.core count get subs compare)
|
||||||
|
(clojure.string join escape split split-lines replace replace-first reverse re-quote-replacement index-of last-index-of starts-with? ends-with? includes?))
|
||||||
|
("Regex"
|
||||||
|
(clojure.core re-find re-seq re-matches re-pattern re-matcher re-groups)
|
||||||
|
(clojure.string replace replace-first re-quote-replacement))
|
||||||
|
("Letters"
|
||||||
|
(clojure.string capitalize lower-case upper-case))
|
||||||
|
("Trim"
|
||||||
|
(clojure.string trim trim-newline triml trimr))
|
||||||
|
("Test"
|
||||||
|
(clojure.core char char? string?)
|
||||||
|
(clojure.string blank?)))
|
||||||
|
|
||||||
|
("Other"
|
||||||
|
("Characters"
|
||||||
|
(clojure.core char char-name-string char-escape-string))
|
||||||
|
("Keywords"
|
||||||
|
(clojure.core keyword keyword? find-keyword))
|
||||||
|
("Symbols"
|
||||||
|
(clojure.core symbol symbol? gensym))
|
||||||
|
("Data Readers"
|
||||||
|
(clojure.core *data-readers* default-data-readers *default-data-reader-fn*))))
|
||||||
|
|
||||||
|
("Collections"
|
||||||
|
("Generic Ops"
|
||||||
|
(clojure.core count bounded-count empty not-empty into conj))
|
||||||
|
("Tree Walking"
|
||||||
|
(clojure.walk walk prewalk prewalk-demo prewalk-replace postwalk postwalk-demo postwalk-replace keywordize-keys stringify-keys))
|
||||||
|
("Content tests"
|
||||||
|
(clojure.core distinct? empty? every? not-every? some not-any?))
|
||||||
|
("Capabilities"
|
||||||
|
(clojure.core sequential? associative? sorted? counted? reversible?))
|
||||||
|
("Type tests"
|
||||||
|
(clojure.core type class coll? list? vector? set? map? seq?
|
||||||
|
number? integer? float? decimal? class? rational? ratio?
|
||||||
|
chunked-seq? reduced? special-symbol? record?))
|
||||||
|
("Lists"
|
||||||
|
("Create"
|
||||||
|
(clojure.core list list*))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core first nth peek))
|
||||||
|
("Change"
|
||||||
|
(clojure.core cons conj rest pop)))
|
||||||
|
|
||||||
|
("Vectors"
|
||||||
|
("Create"
|
||||||
|
(clojure.core vec vector vector-of))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core get peek))
|
||||||
|
|
||||||
|
("Change"
|
||||||
|
(clojure.core assoc pop subvec replace conj rseq))
|
||||||
|
("Ops"
|
||||||
|
(clojure.core mapv filterv reduce-kv)))
|
||||||
|
|
||||||
|
("Sets"
|
||||||
|
("Create"
|
||||||
|
(clojure.core set hash-set sorted-set sorted-set-by))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core get contains?))
|
||||||
|
("Change"
|
||||||
|
(clojure.core conj disj))
|
||||||
|
("Relational Algebra"
|
||||||
|
(clojure.set join select project union difference intersection))
|
||||||
|
("Get map"
|
||||||
|
(clojure.set index rename-keys rename map-invert))
|
||||||
|
("Test"
|
||||||
|
(clojure.set subset? superset?))
|
||||||
|
("Sorted Sets"
|
||||||
|
(clojure.core rseq subseq rsubseq)))
|
||||||
|
|
||||||
|
("Maps"
|
||||||
|
("Create"
|
||||||
|
(clojure.core hash-map array-map zipmap sorted-map sorted-map-by bean frequencies group-by))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core get get-in contains? find keys vals map-entry?))
|
||||||
|
("Change"
|
||||||
|
(clojure.core assoc assoc-in dissoc merge merge-with select-keys update update-in))
|
||||||
|
("Entry"
|
||||||
|
(clojure.core key val))
|
||||||
|
("Sorted Maps"
|
||||||
|
(clojure.core rseq subseq rsubseq)))
|
||||||
|
|
||||||
|
("Hashes"
|
||||||
|
(clojure.core hash hash-ordered-coll hash-unordered-coll mix-collection-hash))
|
||||||
|
|
||||||
|
("Volatiles"
|
||||||
|
(clojure.core volatile! volatile? vreset! vswap!)))
|
||||||
|
|
||||||
|
("Functions"
|
||||||
|
("Create"
|
||||||
|
(clojure.core fn defn defn- definline identity constantly comp complement partial juxt memfn memoize fnil every-pred some-fn trampoline))
|
||||||
|
("Call"
|
||||||
|
(clojure.core -> ->> some-> some->> as-> cond-> cond->>))
|
||||||
|
("Test"
|
||||||
|
(clojure.core fn? ifn?)))
|
||||||
|
|
||||||
|
("Transducers"
|
||||||
|
("Create"
|
||||||
|
(clojure.core cat dedupe distinct drop drop-while filter halt-when interpose keep keep-indexed map map-indexed mapcat partition-all partition-by random-sample remove replace take take-nth take-while))
|
||||||
|
("Call"
|
||||||
|
(clojure.core ->Eduction eduction into sequence transduce completing run!))
|
||||||
|
("Early Termination"
|
||||||
|
(clojure.core deref reduced reduced? ensure-reduced unreduced)))
|
||||||
|
|
||||||
|
("Spec"
|
||||||
|
("Operations"
|
||||||
|
(clojure.spec.alpha valid? conform unform explain explain-data explain-str explain-out form describe assert check-asserts check-asserts?))
|
||||||
|
("Generator Ops"
|
||||||
|
(clojure.spec.alpha gen exercise exercise-fn))
|
||||||
|
("Defn & Registry"
|
||||||
|
(clojure.spec.alpha def fdef registry get-spec spec? spec with-gen))
|
||||||
|
("Logical"
|
||||||
|
(clojure.spec.alpha and or))
|
||||||
|
("Collection"
|
||||||
|
(clojure.spec.alpha coll-of map-of every every-kv keys merge))
|
||||||
|
("Regex "
|
||||||
|
(clojure.spec.alpha cat alt * + \? & keys*))
|
||||||
|
("Range"
|
||||||
|
(clojure.spec.alpha int-in inst-in double-in int-in-range? inst-in-range?))
|
||||||
|
("Custom Explain"
|
||||||
|
(clojure.spec.alpha explain-printer *explain-out*))
|
||||||
|
("Other"
|
||||||
|
(clojure.spec.alpha nilable multi-spec fspec conformer))
|
||||||
|
|
||||||
|
("Predicates with test.check generators"
|
||||||
|
("Numbers"
|
||||||
|
(clojure.core number? rational? integer? ratio? decimal? float? zero? double? int? nat-int? neg-int? pos-int?))
|
||||||
|
("Symbols & Keywords"
|
||||||
|
(clojure.core keyword? symbol? ident? qualified-ident? qualified-keyword? qualified-symbol? simple-ident? simple-keyword? simple-symbol?))
|
||||||
|
("Scalars"
|
||||||
|
(clojure.core string? true? false? nil? some? boolean? bytes? inst? uri? uuid?))
|
||||||
|
("Collections"
|
||||||
|
(clojure.core list? map? set? vector? associative? coll? sequential? seq? empty? indexed? seqable?))
|
||||||
|
("Other"
|
||||||
|
(clojure.core any?))))
|
||||||
|
|
||||||
|
("Other"
|
||||||
|
("XML"
|
||||||
|
(clojure.core xml-seq)
|
||||||
|
(clojure.xml parse))
|
||||||
|
("REPL"
|
||||||
|
(clojure.core *1 *2 *3 *e *print-dup* *print-length* *print-level* *print-meta* *print-readably*))
|
||||||
|
("EDN"
|
||||||
|
(clojure.edn read read-string))
|
||||||
|
("Compiling Code & Class Generation"
|
||||||
|
(clojure.core *compile-files* *compile-path* *file* *warn-on-reflection* compile gen-class gen-interface loaded-libs test))
|
||||||
|
("Misc"
|
||||||
|
(clojure.core eval force name *clojure-version* clojure-version *command-line-args*))
|
||||||
|
("Pretty Printing"
|
||||||
|
(clojure.pprint pprint print-table pp *print-right-margin*))
|
||||||
|
("Browser / Shell"
|
||||||
|
(clojure.java.browse browse-url)
|
||||||
|
(clojure.java.shell sh with-sh-dir with-sh-env)))
|
||||||
|
|
||||||
|
("Vars & Global Environment"
|
||||||
|
("Def Variants"
|
||||||
|
(:special def)
|
||||||
|
(clojure.core defn defn- definline defmacro defmethod defmulti defonce defrecord))
|
||||||
|
("Interned Vars"
|
||||||
|
(:special var)
|
||||||
|
(clojure.core declare intern binding find-var))
|
||||||
|
("Var Objects"
|
||||||
|
(clojure.core with-local-vars var-get var-set alter-var-root var?))
|
||||||
|
("Var Validators"
|
||||||
|
(clojure.core set-validator! get-validator)))
|
||||||
|
|
||||||
|
("Reader Conditionals"
|
||||||
|
(clojure.core reader-conditional reader-conditional? tagged-literal tagged-literal?))
|
||||||
|
|
||||||
|
("Abstractions"
|
||||||
|
("Protocols"
|
||||||
|
(clojure.core defprotocol extend extend-type extend-protocol reify extends? satisfies? extenders))
|
||||||
|
("Records & Types"
|
||||||
|
(clojure.core defrecord deftype))
|
||||||
|
("Multimethods"
|
||||||
|
("Define"
|
||||||
|
(clojure.core defmulti defmethod))
|
||||||
|
("Dispatch"
|
||||||
|
(clojure.core get-method methods))
|
||||||
|
("Remove"
|
||||||
|
(clojure.core remove-method remove-all-methods))
|
||||||
|
("Prefer"
|
||||||
|
(clojure.core prefer-method prefers))
|
||||||
|
("Relation"
|
||||||
|
(clojure.core derive isa? parents ancestors descendants make-hierarchy))))
|
||||||
|
|
||||||
|
("Macros"
|
||||||
|
("Create"
|
||||||
|
(clojure.core defmacro definline))
|
||||||
|
("Debug"
|
||||||
|
(clojure.core macroexpand-1 macroexpand)
|
||||||
|
(clojure.walk macroexpand-all))
|
||||||
|
("Branch"
|
||||||
|
(clojure.core and or when when-not when-let when-first if-not if-let cond condp case))
|
||||||
|
("Loop"
|
||||||
|
(clojure.core for doseq dotimes while))
|
||||||
|
("Arrange"
|
||||||
|
(clojure.core .. doto ->))
|
||||||
|
("Scope"
|
||||||
|
(clojure.core binding locking time)
|
||||||
|
(clojure.core with-in-str with-local-vars with-open with-out-str with-precision with-redefs with-redefs-fn))
|
||||||
|
("Lazy"
|
||||||
|
(clojure.core lazy-cat lazy-seq delay delay?))
|
||||||
|
("Doc"
|
||||||
|
(clojure.core assert comment)
|
||||||
|
(clojure.repl doc dir dir-fn source-fn)))
|
||||||
|
|
||||||
|
("Java Interop"
|
||||||
|
("General"
|
||||||
|
(:special new set!)
|
||||||
|
(clojure.core .. doto bean comparator enumeration-seq import iterator-seq memfn definterface supers bases))
|
||||||
|
("Cast"
|
||||||
|
(clojure.core boolean byte short char int long float double bigdec bigint num cast biginteger))
|
||||||
|
("Exceptions"
|
||||||
|
(:special throw try catch finally)
|
||||||
|
(clojure.core ex-info ex-data Throwable->map StackTraceElement->vec)
|
||||||
|
(clojure.repl pst))
|
||||||
|
("Arrays"
|
||||||
|
("Create"
|
||||||
|
(clojure.core boolean-array byte-array double-array char-array float-array int-array long-array make-array object-array short-array to-array))
|
||||||
|
("Manipulate"
|
||||||
|
(clojure.core aclone aget aset alength amap areduce aset-int aset-long aset-short aset-boolean aset-byte aset-char aset-double aset-float))
|
||||||
|
("Cast"
|
||||||
|
(clojure.core booleans bytes chars doubles floats ints longs shorts)))
|
||||||
|
("Proxy"
|
||||||
|
("Create"
|
||||||
|
(clojure.core proxy get-proxy-class construct-proxy init-proxy))
|
||||||
|
("Misc"
|
||||||
|
(clojure.core proxy-mappings proxy-super update-proxy))))
|
||||||
|
|
||||||
|
("Namespaces"
|
||||||
|
("Current"
|
||||||
|
(clojure.core *ns*))
|
||||||
|
("Create Switch"
|
||||||
|
(clojure.core ns in-ns create-ns))
|
||||||
|
("Add"
|
||||||
|
(clojure.core alias import intern refer refer-clojure))
|
||||||
|
("Find"
|
||||||
|
(clojure.core all-ns find-ns))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core ns-aliases ns-imports ns-interns ns-map ns-name ns-publics ns-refers))
|
||||||
|
("From symbol"
|
||||||
|
(clojure.core resolve namespace ns-resolve the-ns))
|
||||||
|
("Remove"
|
||||||
|
(clojure.core ns-unalias ns-unmap remove-ns)))
|
||||||
|
("Loading"
|
||||||
|
("Load libs"
|
||||||
|
(clojure.core require use import refer))
|
||||||
|
("List Loaded"
|
||||||
|
(clojure.core loaded-libs))
|
||||||
|
("Load Misc"
|
||||||
|
(clojure.core load load-file load-reader load-string)))
|
||||||
|
|
||||||
|
("Concurrency"
|
||||||
|
("Atoms"
|
||||||
|
(clojure.core atom swap! swap-vals! reset! reset-vals! compare-and-set!))
|
||||||
|
("Futures"
|
||||||
|
(clojure.core future future-call future-cancel future-cancelled? future-done? future?))
|
||||||
|
("Threads"
|
||||||
|
(clojure.core bound-fn bound-fn* get-thread-bindings pop-thread-bindings push-thread-bindings))
|
||||||
|
|
||||||
|
("Misc"
|
||||||
|
(clojure.core locking pcalls pvalues pmap seque promise deliver))
|
||||||
|
|
||||||
|
("Refs & Transactions"
|
||||||
|
("Create"
|
||||||
|
(clojure.core ref))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core deref))
|
||||||
|
("Transaction"
|
||||||
|
(clojure.core sync dosync io!))
|
||||||
|
("In Transaction"
|
||||||
|
(clojure.core ensure ref-set alter commute))
|
||||||
|
("Validators"
|
||||||
|
(clojure.core get-validator set-validator!))
|
||||||
|
("History"
|
||||||
|
(clojure.core ref-history-count ref-max-history ref-min-history)))
|
||||||
|
|
||||||
|
("Agents & Asynchronous Actions"
|
||||||
|
("Create"
|
||||||
|
(clojure.core agent))
|
||||||
|
("Examine"
|
||||||
|
(clojure.core agent-error))
|
||||||
|
("Change State"
|
||||||
|
(clojure.core send send-off restart-agent send-via set-agent-send-executor! set-agent-send-off-executor!))
|
||||||
|
("Block Waiting"
|
||||||
|
(clojure.core await await-for))
|
||||||
|
("Ref Validators"
|
||||||
|
(clojure.core get-validator set-validator!))
|
||||||
|
("Watchers"
|
||||||
|
(clojure.core add-watch remove-watch))
|
||||||
|
("Thread Handling"
|
||||||
|
(clojure.core shutdown-agents))
|
||||||
|
("Error"
|
||||||
|
(clojure.core error-handler set-error-handler! error-mode set-error-mode!))
|
||||||
|
("Misc"
|
||||||
|
(clojure.core *agent* release-pending-sends))))
|
||||||
|
|
||||||
|
("Sequences"
|
||||||
|
("Creating a Lazy Seq"
|
||||||
|
("From Collection"
|
||||||
|
(clojure.core seq sequence keys vals rseq subseq rsubseq))
|
||||||
|
("From Producer Fn"
|
||||||
|
(clojure.core lazy-seq repeatedly iterate))
|
||||||
|
("From Constant"
|
||||||
|
(clojure.core repeat range))
|
||||||
|
("From Other"
|
||||||
|
(clojure.core file-seq line-seq resultset-seq re-seq tree-seq xml-seq iterator-seq enumeration-seq))
|
||||||
|
("From Seq"
|
||||||
|
(clojure.core keep keep-indexed)))
|
||||||
|
|
||||||
|
("Seq in, Seq out"
|
||||||
|
("Get shorter"
|
||||||
|
(clojure.core distinct dedupe filter remove for))
|
||||||
|
("Get longer"
|
||||||
|
(clojure.core cons conj concat lazy-cat mapcat cycle interleave interpose)))
|
||||||
|
("Tail-items"
|
||||||
|
(clojure.core rest nthrest fnext nnext drop drop-while take-last for))
|
||||||
|
("Head-items"
|
||||||
|
(clojure.core take take-nth take-while butlast drop-last for))
|
||||||
|
("Change"
|
||||||
|
(clojure.core conj concat distinct flatten group-by partition partition-all partition-by split-at split-with filter remove replace shuffle random-sample))
|
||||||
|
("Rearrange"
|
||||||
|
(clojure.core reverse sort sort-by compare))
|
||||||
|
("Process items"
|
||||||
|
(clojure.core map pmap map-indexed mapcat for replace seque))
|
||||||
|
|
||||||
|
("Using a Seq"
|
||||||
|
("Extract item"
|
||||||
|
(clojure.core first second last rest next ffirst nfirst fnext nnext nth nthnext rand-nth when-first max-key min-key))
|
||||||
|
("Construct coll"
|
||||||
|
(clojure.core zipmap into reduce reductions set vec into-array to-array-2d))
|
||||||
|
("Pass to fn"
|
||||||
|
(clojure.core apply))
|
||||||
|
("Search"
|
||||||
|
(clojure.core some filter))
|
||||||
|
("Force evaluation"
|
||||||
|
(clojure.core doseq dorun doall))
|
||||||
|
("Check for forced"
|
||||||
|
(clojure.core realized?))))
|
||||||
|
|
||||||
|
("Zippers"
|
||||||
|
("Create"
|
||||||
|
(clojure.zip zipper seq-zip vector-zip xml-zip))
|
||||||
|
("Get loc"
|
||||||
|
(clojure.zip up down left right leftmost rightmost))
|
||||||
|
("Get seq"
|
||||||
|
(clojure.zip lefts rights path children))
|
||||||
|
("Change"
|
||||||
|
(clojure.zip make-node replace edit insert-child insert-left insert-right append-child remove))
|
||||||
|
("Move"
|
||||||
|
(clojure.zip next prev))
|
||||||
|
("XML"
|
||||||
|
(clojure.data.zip.xml attr attr= seq-test tag= text text= xml-> xml1->))
|
||||||
|
("Misc"
|
||||||
|
(clojure.zip root node branch? end?)))
|
||||||
|
|
||||||
|
("Documentation"
|
||||||
|
("REPL"
|
||||||
|
(clojure.repl doc find-doc apropos source pst)
|
||||||
|
(clojure.java.javadoc javadoc)))
|
||||||
|
|
||||||
|
("Transients"
|
||||||
|
("Create"
|
||||||
|
(clojure.core transient persistent!))
|
||||||
|
("Change"
|
||||||
|
(clojure.core conj! pop! assoc! dissoc! disj!)))
|
||||||
|
("Misc"
|
||||||
|
("Compare"
|
||||||
|
(clojure.core = == identical? not= not compare)
|
||||||
|
(clojure.data diff))
|
||||||
|
("Test"
|
||||||
|
(clojure.core true? false? nil? instance?)))
|
||||||
|
|
||||||
|
("IO"
|
||||||
|
("To/from ..."
|
||||||
|
(clojure.core spit slurp))
|
||||||
|
("To *out*"
|
||||||
|
(clojure.core pr prn print printf println newline)
|
||||||
|
(clojure.pprint print-table))
|
||||||
|
("To writer"
|
||||||
|
(clojure.pprint pprint cl-format))
|
||||||
|
("To string"
|
||||||
|
(clojure.core format with-out-str pr-str prn-str print-str println-str))
|
||||||
|
("From *in*"
|
||||||
|
(clojure.core read-line read))
|
||||||
|
("From reader"
|
||||||
|
(clojure.core line-seq read))
|
||||||
|
("From string"
|
||||||
|
(clojure.core read-string with-in-str))
|
||||||
|
("Open"
|
||||||
|
(clojure.core with-open)
|
||||||
|
(clojure.java.io reader writer input-stream output-stream))
|
||||||
|
("Interop"
|
||||||
|
(clojure.java.io make-writer make-reader make-output-stream make-input-stream))
|
||||||
|
("Misc"
|
||||||
|
(clojure.core flush file-seq *in* *out* *err*)
|
||||||
|
(clojure.java.io file copy delete-file resource as-file as-url as-relative-path make-parents)))
|
||||||
|
|
||||||
|
("Metadata"
|
||||||
|
(clojure.core meta with-meta alter-meta! reset-meta! vary-meta))
|
||||||
|
|
||||||
|
("Special Forms"
|
||||||
|
(:special def if do quote var recur throw try monitor-enter monitor-exit)
|
||||||
|
(clojure.core fn loop)
|
||||||
|
("Binding / Destructuring"
|
||||||
|
(clojure.core let fn letfn defn defmacro loop for doseq if-let if-some when-let when-some)))
|
||||||
|
|
||||||
|
("Async"
|
||||||
|
("Main"
|
||||||
|
(clojure.core.async go go-loop <! <!! >! >!! chan put! take take! close! timeout offer! poll! promise-chan))
|
||||||
|
("Choice"
|
||||||
|
(clojure.core.async alt! alt!! alts! alts!! do-alts))
|
||||||
|
("Buffering"
|
||||||
|
(clojure.core.async buffer dropping-buffer sliding-buffer unblocking-buffer?))
|
||||||
|
("Pipelines"
|
||||||
|
(clojure.core.async pipeline pipeline-async pipeline-blocking))
|
||||||
|
("Threading"
|
||||||
|
(clojure.core.async thread thread-call))
|
||||||
|
("Mixing"
|
||||||
|
(clojure.core.async admix solo-mode mix unmix unmix-all toggle merge pipe unique))
|
||||||
|
("Multiples"
|
||||||
|
(clojure.core.async mult tap untap untap-all))
|
||||||
|
("Publish/Subscribe"
|
||||||
|
(clojure.core.async pub sub unsub unsub-all))
|
||||||
|
("Higher Order"
|
||||||
|
(clojure.core.async filter< filter> map map< map> mapcat< mapcat> partition partition-by reduce remove< remove> split))
|
||||||
|
("Pre-Populate"
|
||||||
|
(clojure.core.async into onto-chan to-chan)))
|
||||||
|
("Unit Tests"
|
||||||
|
("Defining"
|
||||||
|
(clojure.test deftest deftest- testing is are))
|
||||||
|
("Running"
|
||||||
|
(clojure.test run-tests run-all-tests test-vars))
|
||||||
|
("Fixtures"
|
||||||
|
(clojure.test use-fixtures join-fixtures compose-fixtures))))
|
||||||
|
"A data structure for Clojure cheatsheet information.
|
||||||
|
|
||||||
|
It's a tree, where the head of each list determines the context of the rest
|
||||||
|
of the list. The head may be:
|
||||||
|
|
||||||
|
- A string, in which case it's a (sub)heading for the rest of the items.
|
||||||
|
|
||||||
|
- A symbol, in which case it's the Clojure namespace of the symbols that
|
||||||
|
follow it.
|
||||||
|
|
||||||
|
- The keyword :special, in which case it's a Clojure special form
|
||||||
|
|
||||||
|
- Any other keyword, in which case it's a typed item that will be passed
|
||||||
|
through.
|
||||||
|
|
||||||
|
Note that some Clojure symbols appear in more than once. This is entirely
|
||||||
|
intentional. For instance, `map` belongs in the sections on collections
|
||||||
|
and transducers.")
|
||||||
|
|
||||||
|
(defun cider-cheatsheet--expand-vars (list)
|
||||||
|
"Expand the symbols in LIST to fully-qualified var names.
|
||||||
|
|
||||||
|
This list is supposed to have the following format:
|
||||||
|
|
||||||
|
(my-ns var1 var2 var3)"
|
||||||
|
(let ((ns (car list))
|
||||||
|
(vars (cdr list)))
|
||||||
|
(if (eq ns :special)
|
||||||
|
(mapcar #'symbol-name vars)
|
||||||
|
(mapcar (lambda (var) (format "%s/%s" ns var)) vars))))
|
||||||
|
|
||||||
|
(defun cider-cheatsheet--select-var (var-list)
|
||||||
|
"Expand the symbols in VAR-LIST to fully-qualified var names.
|
||||||
|
|
||||||
|
The list can hold one or more lists inside - one per each namespace."
|
||||||
|
(let ((namespaced-vars (seq-mapcat #'cider-cheatsheet--expand-vars
|
||||||
|
(seq-remove (lambda (list)
|
||||||
|
(eq (car list) :url))
|
||||||
|
var-list))))
|
||||||
|
(cider-doc-lookup (completing-read "Select var: " namespaced-vars))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-cheatsheet ()
|
||||||
|
"Navigate `cider-cheatsheet-hierarchy' with `completing-read'.
|
||||||
|
|
||||||
|
When you make it to a Clojure var its doc buffer gets displayed."
|
||||||
|
(interactive)
|
||||||
|
(let ((cheatsheet-data cider-cheatsheet-hierarchy))
|
||||||
|
(while (stringp (caar cheatsheet-data))
|
||||||
|
(let* ((sections (mapcar #'car cheatsheet-data))
|
||||||
|
(sel-section (completing-read "Select cheatsheet section: " sections))
|
||||||
|
(section-data (seq-find (lambda (elem) (equal (car elem) sel-section)) cheatsheet-data)))
|
||||||
|
(setq cheatsheet-data (cdr section-data))))
|
||||||
|
(cider-cheatsheet--select-var cheatsheet-data)))
|
||||||
|
|
||||||
|
(provide 'cider-cheatsheet)
|
||||||
|
|
||||||
|
;;; cider-cheatsheet.el ends here
|
Binary file not shown.
|
@ -0,0 +1,112 @@
|
||||||
|
;;; cider-classpath.el --- Basic Java classpath browser
|
||||||
|
|
||||||
|
;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
|
||||||
|
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Basic Java classpath browser for CIDER.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-popup)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
|
||||||
|
(defvar cider-classpath-buffer "*cider-classpath*")
|
||||||
|
|
||||||
|
(defvar cider-classpath-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map cider-popup-buffer-mode-map)
|
||||||
|
(define-key map (kbd "RET") #'cider-classpath-operate-on-point)
|
||||||
|
(define-key map "n" #'next-line)
|
||||||
|
(define-key map "p" #'previous-line)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defvar cider-classpath-mouse-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map [mouse-1] #'cider-classpath-handle-mouse)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(define-derived-mode cider-classpath-mode special-mode "classpath"
|
||||||
|
"Major mode for browsing the entries in Java's classpath.
|
||||||
|
|
||||||
|
\\{cider-classpath-mode-map}"
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t)))
|
||||||
|
|
||||||
|
(defun cider-classpath-list (buffer items)
|
||||||
|
"Populate BUFFER with ITEMS."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-classpath-mode)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(erase-buffer)
|
||||||
|
(dolist (item items)
|
||||||
|
(insert item "\n"))
|
||||||
|
(goto-char (point-min)))))
|
||||||
|
|
||||||
|
(defun cider-classpath-properties (text)
|
||||||
|
"Decorate TEXT with a clickable keymap and function face."
|
||||||
|
(let ((face (cond
|
||||||
|
((not (file-exists-p text)) 'font-lock-warning-face)
|
||||||
|
((file-directory-p text) 'dired-directory)
|
||||||
|
(t 'default))))
|
||||||
|
(propertize text
|
||||||
|
'font-lock-face face
|
||||||
|
'mouse-face 'highlight
|
||||||
|
'keymap cider-classpath-mouse-map)))
|
||||||
|
|
||||||
|
(defun cider-classpath-operate-on-point ()
|
||||||
|
"Expand browser according to thing at current point."
|
||||||
|
(interactive)
|
||||||
|
(let* ((bol (line-beginning-position))
|
||||||
|
(eol (line-end-position))
|
||||||
|
(line (buffer-substring-no-properties bol eol)))
|
||||||
|
(find-file-other-window line)))
|
||||||
|
|
||||||
|
(defun cider-classpath-handle-mouse (event)
|
||||||
|
"Handle mouse click EVENT."
|
||||||
|
(interactive "e")
|
||||||
|
(cider-classpath-operate-on-point))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-classpath ()
|
||||||
|
"List all classpath entries."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "classpath")
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-classpath-buffer 'select nil 'ancillary)
|
||||||
|
(cider-classpath-list (current-buffer)
|
||||||
|
(mapcar (lambda (name)
|
||||||
|
(cider-classpath-properties name))
|
||||||
|
(cider-sync-request:classpath)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-open-classpath-entry ()
|
||||||
|
"Open a classpath entry."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "classpath")
|
||||||
|
(when-let* ((entry (completing-read "Classpath entries: " (cider-sync-request:classpath))))
|
||||||
|
(find-file-other-window entry)))
|
||||||
|
|
||||||
|
(provide 'cider-classpath)
|
||||||
|
|
||||||
|
;;; cider-classpath.el ends here
|
Binary file not shown.
|
@ -0,0 +1,577 @@
|
||||||
|
;;; cider-client.el --- A layer of abstraction above low-level nREPL client code. -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov
|
||||||
|
;;
|
||||||
|
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; A layer of abstraction above the low-level nREPL client code.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'spinner)
|
||||||
|
(require 'nrepl-client)
|
||||||
|
(require 'cider-connection)
|
||||||
|
(require 'cider-common)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'clojure-mode)
|
||||||
|
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'seq)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Eval spinner
|
||||||
|
(defcustom cider-eval-spinner-type 'progress-bar
|
||||||
|
"Appearance of the evaluation spinner.
|
||||||
|
|
||||||
|
Value is a symbol. The possible values are the symbols in the
|
||||||
|
`spinner-types' variable."
|
||||||
|
:type 'symbol
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-show-eval-spinner t
|
||||||
|
"When true, show the evaluation spinner in the mode line."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-eval-spinner-delay 1
|
||||||
|
"Amount of time, in seconds, after which the evaluation spinner will be shown."
|
||||||
|
:type 'integer
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defun cider-spinner-start (buffer)
|
||||||
|
"Start the evaluation spinner in BUFFER.
|
||||||
|
Do nothing if `cider-show-eval-spinner' is nil."
|
||||||
|
(when cider-show-eval-spinner
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(spinner-start cider-eval-spinner-type nil
|
||||||
|
cider-eval-spinner-delay))))
|
||||||
|
|
||||||
|
(defun cider-eval-spinner-handler (eval-buffer original-callback)
|
||||||
|
"Return a response handler to stop the spinner and call ORIGINAL-CALLBACK.
|
||||||
|
EVAL-BUFFER is the buffer where the spinner was started."
|
||||||
|
(lambda (response)
|
||||||
|
;; buffer still exists and
|
||||||
|
;; we've got status "done" from nrepl
|
||||||
|
;; stop the spinner
|
||||||
|
(when (and (buffer-live-p eval-buffer)
|
||||||
|
(let ((status (nrepl-dict-get response "status")))
|
||||||
|
(or (member "done" status)
|
||||||
|
(member "eval-error" status)
|
||||||
|
(member "error" status))))
|
||||||
|
(with-current-buffer eval-buffer
|
||||||
|
(when spinner-current (spinner-stop))))
|
||||||
|
(funcall original-callback response)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Evaluation helpers
|
||||||
|
(defun cider-ns-form-p (form)
|
||||||
|
"Check if FORM is an ns form."
|
||||||
|
(string-match-p "^[[:space:]]*\(ns\\([[:space:]]*$\\|[[:space:]]+\\)" form))
|
||||||
|
|
||||||
|
(defun cider-ns-from-form (ns-form)
|
||||||
|
"Get ns substring from NS-FORM."
|
||||||
|
(when (string-match "^[ \t\n]*\(ns[ \t\n]+\\([^][ \t\n(){}]+\\)" ns-form)
|
||||||
|
(match-string-no-properties 1 ns-form)))
|
||||||
|
|
||||||
|
(defvar-local cider-buffer-ns nil
|
||||||
|
"Current Clojure namespace of some buffer.
|
||||||
|
Useful for special buffers (e.g. REPL, doc buffers) that have to keep track
|
||||||
|
of a namespace. This should never be set in Clojure buffers, as there the
|
||||||
|
namespace should be extracted from the buffer's ns form.")
|
||||||
|
|
||||||
|
(defun cider-current-ns (&optional no-default)
|
||||||
|
"Return the current ns.
|
||||||
|
The ns is extracted from the ns form for Clojure buffers and from
|
||||||
|
`cider-buffer-ns' for all other buffers. If it's missing, use the current
|
||||||
|
REPL's ns, otherwise fall back to \"user\". When NO-DEFAULT is non-nil, it
|
||||||
|
will return nil instead of \"user\"."
|
||||||
|
(or cider-buffer-ns
|
||||||
|
(clojure-find-ns)
|
||||||
|
(when-let* ((repl (cider-current-repl)))
|
||||||
|
(buffer-local-value 'cider-buffer-ns repl))
|
||||||
|
(if no-default nil "user")))
|
||||||
|
|
||||||
|
(defun cider-expected-ns (&optional path)
|
||||||
|
"Return the namespace string matching PATH, or nil if not found.
|
||||||
|
PATH is expected to be an absolute file path. If PATH is nil, use the path
|
||||||
|
to the file backing the current buffer. The command falls back to
|
||||||
|
`clojure-expected-ns' in the absence of an active nREPL connection."
|
||||||
|
(if (cider-connected-p)
|
||||||
|
(let* ((path (or path (file-truename (buffer-file-name))))
|
||||||
|
(relpath (thread-last (cider-sync-request:classpath)
|
||||||
|
(seq-map
|
||||||
|
(lambda (cp)
|
||||||
|
(when (string-prefix-p cp path)
|
||||||
|
(substring path (length cp)))))
|
||||||
|
(seq-filter #'identity)
|
||||||
|
(seq-sort (lambda (a b)
|
||||||
|
(< (length a) (length b))))
|
||||||
|
(car))))
|
||||||
|
(if relpath
|
||||||
|
(thread-last (substring relpath 1) ; remove leading /
|
||||||
|
(file-name-sans-extension)
|
||||||
|
(replace-regexp-in-string "/" ".")
|
||||||
|
(replace-regexp-in-string "_" "-"))
|
||||||
|
(clojure-expected-ns path)))
|
||||||
|
(clojure-expected-ns path)))
|
||||||
|
|
||||||
|
(defun cider-nrepl-op-supported-p (op &optional connection)
|
||||||
|
"Check whether the CONNECTION supports the nREPL middleware OP."
|
||||||
|
(nrepl-op-supported-p op (or connection (cider-current-repl))))
|
||||||
|
|
||||||
|
(defvar cider-version)
|
||||||
|
(defun cider-ensure-op-supported (op)
|
||||||
|
"Check for support of middleware op OP.
|
||||||
|
Signal an error if it is not supported."
|
||||||
|
(unless (cider-nrepl-op-supported-p op)
|
||||||
|
(user-error "`%s' requires the nREPL op \"%s\". Please, install (or update) cider-nrepl %s and restart CIDER" this-command op (upcase cider-version))))
|
||||||
|
|
||||||
|
(defun cider-nrepl-send-request (request callback &optional connection)
|
||||||
|
"Send REQUEST and register response handler CALLBACK.
|
||||||
|
REQUEST is a pair list of the form (\"op\" \"operation\" \"par1-name\"
|
||||||
|
\"par1\" ... ).
|
||||||
|
If CONNECTION is provided dispatch to that connection instead of
|
||||||
|
the current connection. Return the id of the sent message."
|
||||||
|
(nrepl-send-request request callback (or connection (cider-current-repl))))
|
||||||
|
|
||||||
|
(defun cider-nrepl-send-sync-request (request &optional connection abort-on-input)
|
||||||
|
"Send REQUEST to the nREPL server synchronously using CONNECTION.
|
||||||
|
Hold till final \"done\" message has arrived and join all response messages
|
||||||
|
of the same \"op\" that came along and return the accumulated response.
|
||||||
|
If ABORT-ON-INPUT is non-nil, the function will return nil
|
||||||
|
at the first sign of user input, so as not to hang the
|
||||||
|
interface."
|
||||||
|
(nrepl-send-sync-request request
|
||||||
|
(or connection (cider-current-repl))
|
||||||
|
abort-on-input))
|
||||||
|
|
||||||
|
(defun cider-nrepl-send-unhandled-request (request &optional connection)
|
||||||
|
"Send REQUEST to the nREPL CONNECTION and ignore any responses.
|
||||||
|
Immediately mark the REQUEST as done. Return the id of the sent message."
|
||||||
|
(let* ((conn (or connection (cider-current-repl)))
|
||||||
|
(id (nrepl-send-request request #'ignore conn)))
|
||||||
|
(with-current-buffer conn
|
||||||
|
(nrepl--mark-id-completed id))
|
||||||
|
id))
|
||||||
|
|
||||||
|
(defun cider-nrepl-request:eval (input callback &optional ns line column additional-params connection)
|
||||||
|
"Send the request INPUT and register the CALLBACK as the response handler.
|
||||||
|
If NS is non-nil, include it in the request. LINE and COLUMN, if non-nil,
|
||||||
|
define the position of INPUT in its buffer. ADDITIONAL-PARAMS is a plist
|
||||||
|
to be appended to the request message. CONNECTION is the connection
|
||||||
|
buffer, defaults to (cider-current-repl)."
|
||||||
|
(let ((connection (or connection (cider-current-repl))))
|
||||||
|
(nrepl-request:eval input
|
||||||
|
(if cider-show-eval-spinner
|
||||||
|
(cider-eval-spinner-handler connection callback)
|
||||||
|
callback)
|
||||||
|
connection
|
||||||
|
ns line column additional-params)
|
||||||
|
(cider-spinner-start connection)))
|
||||||
|
|
||||||
|
(defun cider-nrepl-sync-request:eval (input &optional connection ns)
|
||||||
|
"Send the INPUT to the nREPL CONNECTION synchronously.
|
||||||
|
If NS is non-nil, include it in the eval request."
|
||||||
|
(nrepl-sync-request:eval input (or connection (cider-current-repl)) ns))
|
||||||
|
|
||||||
|
(defcustom cider-pprint-fn 'pprint
|
||||||
|
"Sets the function to use when pretty-printing evaluation results.
|
||||||
|
|
||||||
|
The value must be one of the following symbols:
|
||||||
|
|
||||||
|
`pprint' - to use \\=`clojure.pprint/pprint\\=`
|
||||||
|
|
||||||
|
`fipp' - to use the Fast Idiomatic Pretty Printer, approximately 5-10x
|
||||||
|
faster than \\=`clojure.core/pprint\\=` (this is the default)
|
||||||
|
|
||||||
|
`puget' - to use Puget, which provides canonical serialization of data on
|
||||||
|
top of fipp, but at a slight performance cost
|
||||||
|
|
||||||
|
Alternatively, can be the namespace-qualified name of a Clojure function of
|
||||||
|
one argument. If the function cannot be resolved, an exception will be
|
||||||
|
thrown.
|
||||||
|
|
||||||
|
The function is assumed to respect the contract of \\=`clojure.pprint/pprint\\=`
|
||||||
|
with respect to the bound values of \\=`*print-length*\\=`, \\=`*print-level*\\=`,
|
||||||
|
\\=`*print-meta*\\=`, and \\=`clojure.pprint/*print-right-margin*\\=`."
|
||||||
|
:type '(choice (const pprint)
|
||||||
|
(const fipp)
|
||||||
|
(const puget)
|
||||||
|
string)
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.11.0"))
|
||||||
|
|
||||||
|
(defun cider--pprint-fn ()
|
||||||
|
"Return the value to send in the pprint-fn slot of messages."
|
||||||
|
(pcase cider-pprint-fn
|
||||||
|
(`pprint "clojure.pprint/pprint")
|
||||||
|
(`fipp "cider.nrepl.middleware.pprint/fipp-pprint")
|
||||||
|
(`puget "cider.nrepl.middleware.pprint/puget-pprint")
|
||||||
|
(_ cider-pprint-fn)))
|
||||||
|
|
||||||
|
(defun cider--nrepl-pprint-request-plist (right-margin &optional pprint-fn)
|
||||||
|
"Plist to be appended to an eval request to make it use pprint.
|
||||||
|
PPRINT-FN is the name of the Clojure function to use.
|
||||||
|
RIGHT-MARGIN specifies the maximum column-width of the pretty-printed
|
||||||
|
result, and is included in the request if non-nil."
|
||||||
|
(nconc `("pprint" "true"
|
||||||
|
"pprint-fn" ,(or pprint-fn (cider--pprint-fn)))
|
||||||
|
(and right-margin `("print-right-margin" ,right-margin))))
|
||||||
|
|
||||||
|
(defun cider--nrepl-content-type-plist ()
|
||||||
|
"Plist to be appended to an eval request to make it use content-types."
|
||||||
|
'("content-type" "true"))
|
||||||
|
|
||||||
|
(defun cider-tooling-eval (input callback &optional ns connection)
|
||||||
|
"Send the request INPUT to CONNECTION and register the CALLBACK.
|
||||||
|
NS specifies the namespace in which to evaluate the request. Requests
|
||||||
|
evaluated in the tooling nREPL session don't affect the thread-local
|
||||||
|
bindings of the primary eval nREPL session (e.g. this is not going to
|
||||||
|
clobber *1/2/3)."
|
||||||
|
;; namespace forms are always evaluated in the "user" namespace
|
||||||
|
(nrepl-request:eval input
|
||||||
|
callback
|
||||||
|
(or connection (cider-current-repl))
|
||||||
|
ns nil nil nil 'tooling))
|
||||||
|
|
||||||
|
(defun cider-sync-tooling-eval (input &optional ns connection)
|
||||||
|
"Send the request INPUT to CONNECTION and evaluate in synchronously.
|
||||||
|
NS specifies the namespace in which to evaluate the request. Requests
|
||||||
|
evaluated in the tooling nREPL session don't affect the thread-local
|
||||||
|
bindings of the primary eval nREPL session (e.g. this is not going to
|
||||||
|
clobber *1/2/3)."
|
||||||
|
;; namespace forms are always evaluated in the "user" namespace
|
||||||
|
(nrepl-sync-request:eval input
|
||||||
|
(or connection (cider-current-repl))
|
||||||
|
ns
|
||||||
|
'tooling))
|
||||||
|
|
||||||
|
;; TODO: Add some unit tests and pretty those two functions up.
|
||||||
|
;; FIXME: Currently that's broken for group-id with multiple segments (e.g. org.clojure/clojure)
|
||||||
|
(defun cider-classpath-libs ()
|
||||||
|
"Return a list of all libs on the classpath."
|
||||||
|
(let ((libs (seq-filter (lambda (cp-entry)
|
||||||
|
(string-suffix-p ".jar" cp-entry))
|
||||||
|
(cider-sync-request:classpath)))
|
||||||
|
(dir-sep (if (string-equal system-type "windows-nt") "\\\\" "/")))
|
||||||
|
(thread-last libs
|
||||||
|
(seq-map (lambda (s) (split-string s dir-sep)))
|
||||||
|
(seq-map #'reverse)
|
||||||
|
(seq-map (lambda (l) (reverse (seq-take l 4)))))))
|
||||||
|
|
||||||
|
(defun cider-library-present-p (lib)
|
||||||
|
"Check whether LIB is present on the classpath.
|
||||||
|
The library is a string of the format \"group-id/artifact-id\"."
|
||||||
|
(let* ((lib (split-string lib "/"))
|
||||||
|
(group-id (car lib))
|
||||||
|
(artifact-id (cadr lib)))
|
||||||
|
(seq-find (lambda (lib)
|
||||||
|
(let ((g (car lib))
|
||||||
|
(a (cadr lib)))
|
||||||
|
(and (equal group-id g) (equal artifact-id a))))
|
||||||
|
(cider-classpath-libs))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Interrupt evaluation
|
||||||
|
|
||||||
|
(defun cider-interrupt-handler (buffer)
|
||||||
|
"Create an interrupt response handler for BUFFER."
|
||||||
|
(nrepl-make-response-handler buffer nil nil nil nil))
|
||||||
|
|
||||||
|
(defun cider-interrupt ()
|
||||||
|
"Interrupt any pending evaluations."
|
||||||
|
(interactive)
|
||||||
|
;; FIXME: does this work correctly in cljc files?
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
(let ((pending-request-ids (cider-util--hash-keys nrepl-pending-requests)))
|
||||||
|
(dolist (request-id pending-request-ids)
|
||||||
|
(nrepl-request:interrupt
|
||||||
|
request-id
|
||||||
|
(cider-interrupt-handler (current-buffer))
|
||||||
|
(cider-current-repl))))))
|
||||||
|
|
||||||
|
(defun cider-nrepl-eval-session ()
|
||||||
|
"Return the eval nREPL session id of the current connection."
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
nrepl-session))
|
||||||
|
|
||||||
|
(defun cider-nrepl-tooling-session ()
|
||||||
|
"Return the tooling nREPL session id of the current connection."
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
nrepl-tooling-session))
|
||||||
|
|
||||||
|
(defun cider--var-choice (var-info)
|
||||||
|
"Prompt to choose from among multiple VAR-INFO candidates, if required.
|
||||||
|
This is needed only when the symbol queried is an unqualified host platform
|
||||||
|
method, and multiple classes have a so-named member. If VAR-INFO does not
|
||||||
|
contain a `candidates' key, it is returned as is."
|
||||||
|
(let ((candidates (nrepl-dict-get var-info "candidates")))
|
||||||
|
(if candidates
|
||||||
|
(let* ((classes (nrepl-dict-keys candidates))
|
||||||
|
(choice (completing-read "Member in class: " classes nil t))
|
||||||
|
(info (nrepl-dict-get candidates choice)))
|
||||||
|
info)
|
||||||
|
var-info)))
|
||||||
|
|
||||||
|
(defun cider-var-info (var &optional all)
|
||||||
|
"Return VAR's info as an alist with list cdrs.
|
||||||
|
When multiple matching vars are returned you'll be prompted to select one,
|
||||||
|
unless ALL is truthy."
|
||||||
|
(when (and var (not (string= var "")))
|
||||||
|
(let ((var-info (cider-sync-request:info var)))
|
||||||
|
(if all var-info (cider--var-choice var-info)))))
|
||||||
|
|
||||||
|
(defun cider-member-info (class member)
|
||||||
|
"Return the CLASS MEMBER's info as an alist with list cdrs."
|
||||||
|
(when (and class member)
|
||||||
|
(cider-sync-request:info nil class member)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Requests
|
||||||
|
|
||||||
|
(declare-function cider-load-file-handler "cider-eval")
|
||||||
|
(defun cider-request:load-file (file-contents file-path file-name &optional connection callback)
|
||||||
|
"Perform the nREPL \"load-file\" op.
|
||||||
|
FILE-CONTENTS, FILE-PATH and FILE-NAME are details of the file to be
|
||||||
|
loaded. If CONNECTION is nil, use `cider-current-repl'. If CALLBACK
|
||||||
|
is nil, use `cider-load-file-handler'."
|
||||||
|
(cider-nrepl-send-request `("op" "load-file"
|
||||||
|
"file" ,file-contents
|
||||||
|
"file-path" ,file-path
|
||||||
|
"file-name" ,file-name)
|
||||||
|
(or callback
|
||||||
|
(cider-load-file-handler (current-buffer)))
|
||||||
|
connection))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Sync Requests
|
||||||
|
|
||||||
|
(defcustom cider-filtered-namespaces-regexps
|
||||||
|
'("^cider.nrepl" "^refactor-nrepl" "^clojure.tools.nrepl")
|
||||||
|
"List of regexps used to filter out some vars/symbols/namespaces.
|
||||||
|
When nil, nothing is filtered out. Otherwise, all namespaces matching any
|
||||||
|
regexp from this list are dropped out of the \"ns-list\" op. Also,
|
||||||
|
\"apropos\" won't include vars from such namespaces. This list is passed
|
||||||
|
on to the nREPL middleware without any pre-processing. So the regexps have
|
||||||
|
to be in Clojure format (with twice the number of backslashes) and not
|
||||||
|
Emacs Lisp."
|
||||||
|
:type '(repeat string)
|
||||||
|
:safe #'listp
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.13.0"))
|
||||||
|
|
||||||
|
(defun cider-sync-request:apropos (query &optional search-ns docs-p privates-p case-sensitive-p)
|
||||||
|
"Send \"apropos\" request for regexp QUERY.
|
||||||
|
|
||||||
|
Optional arguments include SEARCH-NS, DOCS-P, PRIVATES-P, CASE-SENSITIVE-P."
|
||||||
|
(let* ((query (replace-regexp-in-string "[ \t]+" ".+" query))
|
||||||
|
(response (cider-nrepl-send-sync-request
|
||||||
|
`("op" "apropos"
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
"query" ,query
|
||||||
|
,@(when search-ns `("search-ns" ,search-ns))
|
||||||
|
,@(when docs-p '("docs?" "t"))
|
||||||
|
,@(when privates-p '("privates?" "t"))
|
||||||
|
,@(when case-sensitive-p '("case-sensitive?" "t"))
|
||||||
|
"filter-regexps" ,cider-filtered-namespaces-regexps))))
|
||||||
|
(if (member "apropos-regexp-error" (nrepl-dict-get response "status"))
|
||||||
|
(user-error "Invalid regexp: %s" (nrepl-dict-get response "error-msg"))
|
||||||
|
(nrepl-dict-get response "apropos-matches"))))
|
||||||
|
|
||||||
|
(defun cider-sync-request:classpath ()
|
||||||
|
"Return a list of classpath entries."
|
||||||
|
(cider-ensure-op-supported "classpath")
|
||||||
|
(thread-first '("op" "classpath")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "classpath")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:complete (str context)
|
||||||
|
"Return a list of completions for STR using nREPL's \"complete\" op.
|
||||||
|
CONTEXT represents a completion context for compliment."
|
||||||
|
(when-let* ((dict (thread-first `("op" "complete"
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
"symbol" ,str
|
||||||
|
"context" ,context)
|
||||||
|
(cider-nrepl-send-sync-request nil 'abort-on-input))))
|
||||||
|
(nrepl-dict-get dict "completions")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:complete-flush-caches ()
|
||||||
|
"Send \"complete-flush-caches\" op to flush Compliment's caches."
|
||||||
|
(cider-nrepl-send-sync-request (list "op" "complete-flush-caches"
|
||||||
|
"session" (cider-nrepl-eval-session))
|
||||||
|
'abort-on-input))
|
||||||
|
|
||||||
|
(defun cider-sync-request:info (symbol &optional class member)
|
||||||
|
"Send \"info\" op with parameters SYMBOL or CLASS and MEMBER."
|
||||||
|
(let ((var-info (thread-first `("op" "info"
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
,@(when symbol `("symbol" ,symbol))
|
||||||
|
,@(when class `("class" ,class))
|
||||||
|
,@(when member `("member" ,member)))
|
||||||
|
(cider-nrepl-send-sync-request))))
|
||||||
|
(if (member "no-info" (nrepl-dict-get var-info "status"))
|
||||||
|
nil
|
||||||
|
var-info)))
|
||||||
|
|
||||||
|
(defun cider-sync-request:eldoc (symbol &optional class member)
|
||||||
|
"Send \"eldoc\" op with parameters SYMBOL or CLASS and MEMBER."
|
||||||
|
(when-let* ((eldoc (thread-first `("op" "eldoc"
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
,@(when symbol `("symbol" ,symbol))
|
||||||
|
,@(when class `("class" ,class))
|
||||||
|
,@(when member `("member" ,member)))
|
||||||
|
(cider-nrepl-send-sync-request nil 'abort-on-input))))
|
||||||
|
(if (member "no-eldoc" (nrepl-dict-get eldoc "status"))
|
||||||
|
nil
|
||||||
|
eldoc)))
|
||||||
|
|
||||||
|
(defun cider-sync-request:eldoc-datomic-query (symbol)
|
||||||
|
"Send \"eldoc-datomic-query\" op with parameter SYMBOL."
|
||||||
|
(when-let* ((eldoc (thread-first `("op" "eldoc-datomic-query"
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
,@(when symbol `("symbol" ,symbol)))
|
||||||
|
(cider-nrepl-send-sync-request nil 'abort-on-input))))
|
||||||
|
(if (member "no-eldoc" (nrepl-dict-get eldoc "status"))
|
||||||
|
nil
|
||||||
|
eldoc)))
|
||||||
|
|
||||||
|
(defun cider-sync-request:spec-list (&optional filter-regex)
|
||||||
|
"Get a list of the available specs in the registry.
|
||||||
|
Optional argument FILTER-REGEX filters specs. By default, all specs are
|
||||||
|
returned."
|
||||||
|
(setq filter-regex (or filter-regex ""))
|
||||||
|
(thread-first `("op" "spec-list"
|
||||||
|
"filter-regex" ,filter-regex)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "spec-list")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:spec-form (spec)
|
||||||
|
"Get SPEC's form from registry."
|
||||||
|
(thread-first `("op" "spec-form"
|
||||||
|
"spec-name" ,spec)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "spec-form")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:spec-example (spec)
|
||||||
|
"Get an example for SPEC."
|
||||||
|
(thread-first `("op" "spec-example"
|
||||||
|
"spec-name" ,spec)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "spec-example")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:ns-list ()
|
||||||
|
"Get a list of the available namespaces."
|
||||||
|
(thread-first `("op" "ns-list"
|
||||||
|
"filter-regexps" ,cider-filtered-namespaces-regexps)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "ns-list")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:ns-vars (ns)
|
||||||
|
"Get a list of the vars in NS."
|
||||||
|
(thread-first `("op" "ns-vars"
|
||||||
|
"ns" ,ns)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "ns-vars")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:ns-path (ns)
|
||||||
|
"Get the path to the file containing NS."
|
||||||
|
(thread-first `("op" "ns-path"
|
||||||
|
"ns" ,ns)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "path")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:ns-vars-with-meta (ns)
|
||||||
|
"Get a map of the vars in NS to its metadata information."
|
||||||
|
(thread-first `("op" "ns-vars-with-meta"
|
||||||
|
"ns" ,ns)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "ns-vars-with-meta")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:ns-load-all ()
|
||||||
|
"Load all project namespaces."
|
||||||
|
(thread-first '("op" "ns-load-all")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "loaded-ns")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:resource (name)
|
||||||
|
"Perform nREPL \"resource\" op with resource name NAME."
|
||||||
|
(thread-first `("op" "resource"
|
||||||
|
"name" ,name)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "resource-path")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:resources-list ()
|
||||||
|
"Return a list of all resources on the classpath.
|
||||||
|
The result entries are relative to the classpath."
|
||||||
|
(when-let* ((resources (thread-first '("op" "resources-list")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "resources-list"))))
|
||||||
|
(seq-map (lambda (resource) (nrepl-dict-get resource "relpath")) resources)))
|
||||||
|
|
||||||
|
(defun cider-sync-request:format-code (code)
|
||||||
|
"Perform nREPL \"format-code\" op with CODE."
|
||||||
|
(thread-first `("op" "format-code"
|
||||||
|
"code" ,code)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "formatted-code")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:format-edn (edn right-margin)
|
||||||
|
"Perform \"format-edn\" op with EDN and RIGHT-MARGIN."
|
||||||
|
(let* ((response (thread-first `("op" "format-edn"
|
||||||
|
"edn" ,edn)
|
||||||
|
(append (cider--nrepl-pprint-request-plist right-margin))
|
||||||
|
(cider-nrepl-send-sync-request)))
|
||||||
|
(err (nrepl-dict-get response "err")))
|
||||||
|
(when err
|
||||||
|
;; err will be a stacktrace with a first line that looks like:
|
||||||
|
;; "clojure.lang.ExceptionInfo: Unmatched delimiter ]"
|
||||||
|
(error (car (split-string err "\n"))))
|
||||||
|
(nrepl-dict-get response "formatted-edn")))
|
||||||
|
|
||||||
|
;;; Dealing with input
|
||||||
|
;; TODO: Replace this with some nil handler.
|
||||||
|
(defun cider-stdin-handler (&optional _buffer)
|
||||||
|
"Make a stdin response handler for _BUFFER."
|
||||||
|
(nrepl-make-response-handler (current-buffer)
|
||||||
|
(lambda (_buffer _value))
|
||||||
|
(lambda (_buffer _out))
|
||||||
|
(lambda (_buffer _err))
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defun cider-need-input (buffer)
|
||||||
|
"Handle an need-input request from BUFFER."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map minibuffer-local-map)
|
||||||
|
(define-key map (kbd "C-c C-c") 'abort-recursive-edit)
|
||||||
|
(let ((stdin (condition-case nil
|
||||||
|
(concat (read-from-minibuffer "Stdin: " nil map) "\n")
|
||||||
|
(quit nil))))
|
||||||
|
(nrepl-request:stdin stdin
|
||||||
|
(cider-stdin-handler buffer)
|
||||||
|
(cider-current-repl))))))
|
||||||
|
|
||||||
|
(provide 'cider-client)
|
||||||
|
|
||||||
|
;;; cider-client.el ends here
|
Binary file not shown.
|
@ -0,0 +1,375 @@
|
||||||
|
;;; cider-common.el --- Common use functions -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright © 2015-2018 Artur Malabarba
|
||||||
|
|
||||||
|
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Common functions that are useful in both Clojure buffers and REPL
|
||||||
|
;; buffers.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'etags) ; for find-tags-marker-ring
|
||||||
|
(require 'tramp)
|
||||||
|
|
||||||
|
(defcustom cider-prompt-for-symbol t
|
||||||
|
"Controls when to prompt for symbol when a command requires one.
|
||||||
|
|
||||||
|
When non-nil, always prompt, and use the symbol at point as the default
|
||||||
|
value at the prompt.
|
||||||
|
|
||||||
|
When nil, attempt to use the symbol at point for the command, and only
|
||||||
|
prompt if that throws an error."
|
||||||
|
:type '(choice (const :tag "always" t)
|
||||||
|
(const :tag "dwim" nil))
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defcustom cider-special-mode-truncate-lines t
|
||||||
|
"If non-nil, contents of CIDER's special buffers will be line-truncated.
|
||||||
|
Should be set before loading CIDER."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.15.0"))
|
||||||
|
|
||||||
|
(defun cider--should-prompt-for-symbol (&optional invert)
|
||||||
|
"Return the value of the variable `cider-prompt-for-symbol'.
|
||||||
|
Optionally invert the value, if INVERT is truthy."
|
||||||
|
(if invert (not cider-prompt-for-symbol) cider-prompt-for-symbol))
|
||||||
|
|
||||||
|
(defun cider-prompt-for-symbol-function (&optional invert)
|
||||||
|
"Prompt for symbol if funcall `cider--should-prompt-for-symbol' is truthy.
|
||||||
|
Otherwise attempt to use the symbol at point for the command, and only
|
||||||
|
prompt if that throws an error.
|
||||||
|
|
||||||
|
INVERT is used to invert the semantics of the function `cider--should-prompt-for-symbol'."
|
||||||
|
(if (cider--should-prompt-for-symbol invert)
|
||||||
|
#'cider-read-symbol-name
|
||||||
|
#'cider-try-symbol-at-point))
|
||||||
|
|
||||||
|
(defun cider--kw-to-symbol (kw)
|
||||||
|
"Convert the keyword KW to a symbol."
|
||||||
|
(when kw
|
||||||
|
(replace-regexp-in-string "\\`:+" "" kw)))
|
||||||
|
|
||||||
|
;;; Minibuffer
|
||||||
|
(defvar cider-minibuffer-history '()
|
||||||
|
"History list of expressions read from the minibuffer.")
|
||||||
|
|
||||||
|
(defvar cider-minibuffer-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map minibuffer-local-map)
|
||||||
|
(define-key map (kbd "TAB") #'complete-symbol)
|
||||||
|
(define-key map (kbd "M-TAB") #'complete-symbol)
|
||||||
|
map)
|
||||||
|
"Minibuffer keymap used for reading Clojure expressions.")
|
||||||
|
|
||||||
|
(declare-function cider-complete-at-point "cider-completion")
|
||||||
|
(declare-function cider-eldoc "cider-eldoc")
|
||||||
|
(defun cider-read-from-minibuffer (prompt &optional value)
|
||||||
|
"Read a string from the minibuffer, prompting with PROMPT.
|
||||||
|
If VALUE is non-nil, it is inserted into the minibuffer as initial-input.
|
||||||
|
PROMPT need not end with \": \". If it doesn't, VALUE is displayed on the
|
||||||
|
prompt as a default value (used if the user doesn't type anything) and is
|
||||||
|
not used as initial input (input is left empty)."
|
||||||
|
(minibuffer-with-setup-hook
|
||||||
|
(lambda ()
|
||||||
|
(set-syntax-table clojure-mode-syntax-table)
|
||||||
|
(add-hook 'completion-at-point-functions
|
||||||
|
#'cider-complete-at-point nil t)
|
||||||
|
(setq-local eldoc-documentation-function #'cider-eldoc)
|
||||||
|
(run-hooks 'eval-expression-minibuffer-setup-hook))
|
||||||
|
(let* ((has-colon (string-match ": \\'" prompt))
|
||||||
|
(input (read-from-minibuffer (cond
|
||||||
|
(has-colon prompt)
|
||||||
|
(value (format "%s (default %s): " prompt value))
|
||||||
|
(t (format "%s: " prompt)))
|
||||||
|
(when has-colon value) ; initial-input
|
||||||
|
cider-minibuffer-map nil
|
||||||
|
'cider-minibuffer-history
|
||||||
|
(unless has-colon value)))) ; default-value
|
||||||
|
(if (and (equal input "") value (not has-colon))
|
||||||
|
value
|
||||||
|
input))))
|
||||||
|
|
||||||
|
(defun cider-read-symbol-name (prompt callback)
|
||||||
|
"Read a symbol name using PROMPT with a default of the one at point.
|
||||||
|
Use CALLBACK as the completing read var callback."
|
||||||
|
(funcall callback (cider-read-from-minibuffer
|
||||||
|
prompt
|
||||||
|
;; if the thing at point is a keyword we treat it as symbol
|
||||||
|
(cider--kw-to-symbol (cider-symbol-at-point 'look-back)))))
|
||||||
|
|
||||||
|
(defun cider-try-symbol-at-point (prompt callback)
|
||||||
|
"Call CALLBACK with symbol at point.
|
||||||
|
On failure, read a symbol name using PROMPT and call CALLBACK with that."
|
||||||
|
(condition-case nil (funcall callback (cider--kw-to-symbol (cider-symbol-at-point 'look-back)))
|
||||||
|
('error (funcall callback (cider-read-from-minibuffer prompt)))))
|
||||||
|
|
||||||
|
(declare-function cider-mode "cider-mode")
|
||||||
|
|
||||||
|
(defun cider-jump-to (buffer &optional pos other-window)
|
||||||
|
"Push current point onto marker ring, and jump to BUFFER and POS.
|
||||||
|
POS can be either a number, a cons, or a symbol.
|
||||||
|
If a number, it is the character position (the point).
|
||||||
|
If a cons, it specifies the position as (LINE . COLUMN). COLUMN can be nil.
|
||||||
|
If a symbol, `cider-jump-to' searches for something that looks like the
|
||||||
|
symbol's definition in the file.
|
||||||
|
If OTHER-WINDOW is non-nil don't reuse current window."
|
||||||
|
(with-no-warnings
|
||||||
|
(ring-insert find-tag-marker-ring (point-marker)))
|
||||||
|
(if other-window
|
||||||
|
(pop-to-buffer buffer)
|
||||||
|
;; like switch-to-buffer, but reuse existing window if BUFFER is visible
|
||||||
|
(pop-to-buffer buffer '((display-buffer-reuse-window display-buffer-same-window))))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(widen)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(cider-mode +1)
|
||||||
|
(cond
|
||||||
|
;; Line-column specification.
|
||||||
|
((consp pos)
|
||||||
|
(forward-line (1- (or (car pos) 1)))
|
||||||
|
(if (cdr pos)
|
||||||
|
(move-to-column (cdr pos))
|
||||||
|
(back-to-indentation)))
|
||||||
|
;; Point specification.
|
||||||
|
((numberp pos)
|
||||||
|
(goto-char pos))
|
||||||
|
;; Symbol or string.
|
||||||
|
(pos
|
||||||
|
;; Try to find (def full-name ...).
|
||||||
|
(if (or (save-excursion
|
||||||
|
(search-forward-regexp (format "(def.*\\s-\\(%s\\)" (regexp-quote pos))
|
||||||
|
nil 'noerror))
|
||||||
|
(let ((name (replace-regexp-in-string ".*/" "" pos)))
|
||||||
|
;; Try to find (def name ...).
|
||||||
|
(or (save-excursion
|
||||||
|
(search-forward-regexp (format "(def.*\\s-\\(%s\\)" (regexp-quote name))
|
||||||
|
nil 'noerror))
|
||||||
|
;; Last resort, just find the first occurrence of `name'.
|
||||||
|
(save-excursion
|
||||||
|
(search-forward name nil 'noerror)))))
|
||||||
|
(goto-char (match-beginning 0))
|
||||||
|
(message "Can't find %s in %s" pos (buffer-file-name))))
|
||||||
|
(t nil))))
|
||||||
|
|
||||||
|
(defun cider--find-buffer-for-file (file)
|
||||||
|
"Return a buffer visiting FILE.
|
||||||
|
If FILE is a temp buffer name, return that buffer."
|
||||||
|
(if (string-prefix-p "*" file)
|
||||||
|
file
|
||||||
|
(and file
|
||||||
|
(not (cider--tooling-file-p file))
|
||||||
|
(cider-find-file file))))
|
||||||
|
|
||||||
|
(defun cider--jump-to-loc-from-info (info &optional other-window)
|
||||||
|
"Jump to location give by INFO.
|
||||||
|
INFO object is returned by `cider-var-info' or `cider-member-info'.
|
||||||
|
OTHER-WINDOW is passed to `cider-jump-to'."
|
||||||
|
(let* ((line (nrepl-dict-get info "line"))
|
||||||
|
(file (nrepl-dict-get info "file"))
|
||||||
|
(name (nrepl-dict-get info "name"))
|
||||||
|
;; the filename might actually be a REPL buffer name
|
||||||
|
(buffer (cider--find-buffer-for-file file)))
|
||||||
|
(if buffer
|
||||||
|
(cider-jump-to buffer (if line (cons line nil) name) other-window)
|
||||||
|
(error "No source location"))))
|
||||||
|
|
||||||
|
(declare-function url-filename "url-parse" (cl-x) t)
|
||||||
|
|
||||||
|
(defun cider--url-to-file (url)
|
||||||
|
"Return the filename from the resource URL.
|
||||||
|
Uses `url-generic-parse-url' to parse the url. The filename is extracted and
|
||||||
|
then url decoded. If the decoded filename has a Windows device letter followed
|
||||||
|
by a colon immediately after the leading '/' then the leading '/' is dropped to
|
||||||
|
create a valid path."
|
||||||
|
(let ((filename (url-unhex-string (url-filename (url-generic-parse-url url)))))
|
||||||
|
(if (string-match "^/\\([a-zA-Z]:/.*\\)" filename)
|
||||||
|
(match-string 1 filename)
|
||||||
|
filename)))
|
||||||
|
|
||||||
|
(defun cider-make-tramp-prefix (method user host)
|
||||||
|
"Constructs a Tramp file prefix from METHOD, USER, HOST.
|
||||||
|
It originated from Tramp's `tramp-make-tramp-file-name'. The original be
|
||||||
|
forced to make full file name with `with-parsed-tramp-file-name', not providing
|
||||||
|
prefix only option."
|
||||||
|
(concat tramp-prefix-format
|
||||||
|
(unless (zerop (length method))
|
||||||
|
(concat method tramp-postfix-method-format))
|
||||||
|
(unless (zerop (length user))
|
||||||
|
(concat user tramp-postfix-user-format))
|
||||||
|
(when host
|
||||||
|
(if (string-match tramp-ipv6-regexp host)
|
||||||
|
(concat tramp-prefix-ipv6-format host tramp-postfix-ipv6-format)
|
||||||
|
host))
|
||||||
|
tramp-postfix-host-format))
|
||||||
|
|
||||||
|
(defun cider-tramp-prefix (&optional buffer)
|
||||||
|
"Use the filename for BUFFER to determine a tramp prefix.
|
||||||
|
Defaults to the current buffer. Return the tramp prefix, or nil
|
||||||
|
if BUFFER is local."
|
||||||
|
(let* ((buffer (or buffer (current-buffer)))
|
||||||
|
(name (or (buffer-file-name buffer)
|
||||||
|
(with-current-buffer buffer
|
||||||
|
default-directory))))
|
||||||
|
(when (tramp-tramp-file-p name)
|
||||||
|
(with-parsed-tramp-file-name name v
|
||||||
|
(with-no-warnings
|
||||||
|
(cider-make-tramp-prefix v-method v-user v-host))))))
|
||||||
|
|
||||||
|
(defun cider--client-tramp-filename (name &optional buffer)
|
||||||
|
"Return the tramp filename for path NAME relative to BUFFER.
|
||||||
|
If BUFFER has a tramp prefix, it will be added as a prefix to NAME.
|
||||||
|
If the resulting path is an existing tramp file, it returns the path,
|
||||||
|
otherwise, nil."
|
||||||
|
(let* ((buffer (or buffer (current-buffer)))
|
||||||
|
(name (replace-regexp-in-string "^file:" "" name))
|
||||||
|
(name (concat (cider-tramp-prefix buffer) name)))
|
||||||
|
(if (tramp-handle-file-exists-p name)
|
||||||
|
name)))
|
||||||
|
|
||||||
|
(defun cider--server-filename (name)
|
||||||
|
"Return the nREPL server-relative filename for NAME."
|
||||||
|
(if (tramp-tramp-file-p name)
|
||||||
|
(with-parsed-tramp-file-name name nil
|
||||||
|
localname)
|
||||||
|
name))
|
||||||
|
|
||||||
|
(defvar cider-from-nrepl-filename-function
|
||||||
|
(with-no-warnings
|
||||||
|
(if (eq system-type 'cygwin)
|
||||||
|
#'cygwin-convert-file-name-from-windows
|
||||||
|
#'identity))
|
||||||
|
"Function to translate nREPL namestrings to Emacs filenames.")
|
||||||
|
|
||||||
|
(defcustom cider-prefer-local-resources nil
|
||||||
|
"Prefer local resources to remote (tramp) ones when both are available."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider)
|
||||||
|
|
||||||
|
(defun cider--file-path (path)
|
||||||
|
"Return PATH's local or tramp path using `cider-prefer-local-resources'.
|
||||||
|
If no local or remote file exists, return nil."
|
||||||
|
(let* ((local-path (funcall cider-from-nrepl-filename-function path))
|
||||||
|
(tramp-path (and local-path (cider--client-tramp-filename local-path))))
|
||||||
|
(cond ((equal local-path "") "")
|
||||||
|
((and cider-prefer-local-resources (file-exists-p local-path))
|
||||||
|
local-path)
|
||||||
|
((and tramp-path (file-exists-p tramp-path))
|
||||||
|
tramp-path)
|
||||||
|
((and local-path (file-exists-p local-path))
|
||||||
|
local-path))))
|
||||||
|
|
||||||
|
(declare-function archive-extract "arc-mode")
|
||||||
|
(declare-function archive-zip-extract "arc-mode")
|
||||||
|
|
||||||
|
(defun cider-find-file (url)
|
||||||
|
"Return a buffer visiting the file URL if it exists, or nil otherwise.
|
||||||
|
If URL has a scheme prefix, it must represent a fully-qualified file path
|
||||||
|
or an entry within a zip/jar archive. If URL doesn't contain a scheme
|
||||||
|
prefix and is an absolute path, it is treated as such. Finally, if URL is
|
||||||
|
relative, it is expanded within each of the open Clojure buffers till an
|
||||||
|
existing file ending with URL has been found."
|
||||||
|
(require 'arc-mode)
|
||||||
|
(cond ((string-match "^file:\\(.+\\)" url)
|
||||||
|
(when-let* ((file (cider--url-to-file (match-string 1 url)))
|
||||||
|
(path (cider--file-path file)))
|
||||||
|
(find-file-noselect path)))
|
||||||
|
((string-match "^\\(jar\\|zip\\):\\(file:.+\\)!/\\(.+\\)" url)
|
||||||
|
(when-let* ((entry (match-string 3 url))
|
||||||
|
(file (cider--url-to-file (match-string 2 url)))
|
||||||
|
(path (cider--file-path file))
|
||||||
|
;; It is used for targeting useless intermediate buffer.
|
||||||
|
;; That buffer is made by (find-file path) below.
|
||||||
|
;; It has the name which is the last part of the path.
|
||||||
|
(trash (replace-regexp-in-string "^/.+/" "" path))
|
||||||
|
(name (format "%s:%s" path entry)))
|
||||||
|
(or (find-buffer-visiting name)
|
||||||
|
(if (tramp-tramp-file-p path)
|
||||||
|
(progn
|
||||||
|
;; Use emacs built in archiving.
|
||||||
|
;; This makes a list of files in archived Zip or Jar.
|
||||||
|
;; That list buffer is useless after jumping to the
|
||||||
|
;; buffer which has the real definition.
|
||||||
|
;; It'll be removed by (kill-buffer trash) below.
|
||||||
|
(find-file path)
|
||||||
|
(goto-char (point-min))
|
||||||
|
;; Make sure the file path is followed by a newline to
|
||||||
|
;; prevent eg. clj matching cljs.
|
||||||
|
(search-forward (concat entry "\n"))
|
||||||
|
;; moves up to matching line
|
||||||
|
(forward-line -1)
|
||||||
|
(archive-extract)
|
||||||
|
;; Remove useless buffer made by (find-file path) above.
|
||||||
|
(kill-buffer trash)
|
||||||
|
(current-buffer))
|
||||||
|
;; Use external zip program to just extract the single file
|
||||||
|
(with-current-buffer (generate-new-buffer
|
||||||
|
(file-name-nondirectory entry))
|
||||||
|
(archive-zip-extract path entry)
|
||||||
|
(set-visited-file-name name)
|
||||||
|
(setq-local default-directory (file-name-directory path))
|
||||||
|
(setq-local buffer-read-only t)
|
||||||
|
(set-buffer-modified-p nil)
|
||||||
|
(set-auto-mode)
|
||||||
|
(current-buffer))))))
|
||||||
|
(t (if-let* ((path (cider--file-path url)))
|
||||||
|
(find-file-noselect path)
|
||||||
|
(unless (file-name-absolute-p url)
|
||||||
|
(let ((cider-buffers (cider-util--clojure-buffers))
|
||||||
|
(url (file-name-nondirectory url)))
|
||||||
|
(or (cl-loop for bf in cider-buffers
|
||||||
|
for path = (with-current-buffer bf
|
||||||
|
(expand-file-name url))
|
||||||
|
if (and path (file-exists-p path))
|
||||||
|
return (find-file-noselect path))
|
||||||
|
(cl-loop for bf in cider-buffers
|
||||||
|
if (string= (buffer-name bf) url)
|
||||||
|
return bf))))))))
|
||||||
|
|
||||||
|
(defun cider--open-other-window-p (arg)
|
||||||
|
"Test prefix value ARG to see if it indicates displaying results in other window."
|
||||||
|
(let ((narg (prefix-numeric-value arg)))
|
||||||
|
(pcase narg
|
||||||
|
(-1 t) ; -
|
||||||
|
(16 t) ; empty empty
|
||||||
|
(_ nil))))
|
||||||
|
|
||||||
|
(defun cider-abbreviate-ns (namespace)
|
||||||
|
"Return a string that abbreviates NAMESPACE."
|
||||||
|
(when namespace
|
||||||
|
(let* ((names (reverse (split-string namespace "\\.")))
|
||||||
|
(lastname (car names)))
|
||||||
|
(concat (mapconcat (lambda (s) (concat (substring s 0 1) "."))
|
||||||
|
(reverse (cdr names))
|
||||||
|
"")
|
||||||
|
lastname))))
|
||||||
|
|
||||||
|
(defun cider-last-ns-segment (namespace)
|
||||||
|
"Return the last segment of NAMESPACE."
|
||||||
|
(when namespace
|
||||||
|
(car (reverse (split-string namespace "\\.")))))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'cider-common)
|
||||||
|
;;; cider-common.el ends here
|
Binary file not shown.
|
@ -0,0 +1,54 @@
|
||||||
|
;;; cider-compat.el --- Functions from newer Emacs versions for compatibility -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
|
||||||
|
;; 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/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Everything here was copied from subr-x for compatibility with
|
||||||
|
;; Emacs 25.1.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(eval-and-compile
|
||||||
|
|
||||||
|
(unless (fboundp 'if-let*)
|
||||||
|
(defmacro if-let* (bindings then &rest else)
|
||||||
|
"Process BINDINGS and if all values are non-nil eval THEN, else ELSE.
|
||||||
|
Argument BINDINGS is a list of tuples whose car is a symbol to be
|
||||||
|
bound and (optionally) used in THEN, and its cadr is a sexp to be
|
||||||
|
evalled to set symbol's value."
|
||||||
|
(declare (indent 2)
|
||||||
|
(debug ([&or (&rest (symbolp form)) (symbolp form)] form body)))
|
||||||
|
`(let* ,(internal--build-bindings bindings)
|
||||||
|
(if ,(car (internal--listify (car (last bindings))))
|
||||||
|
,then
|
||||||
|
,@else))))
|
||||||
|
|
||||||
|
(unless (fboundp 'when-let*)
|
||||||
|
(defmacro when-let* (bindings &rest body)
|
||||||
|
"Process BINDINGS and if all values are non-nil eval BODY.
|
||||||
|
Argument BINDINGS is a list of tuples whose car is a symbol to be
|
||||||
|
bound and (optionally) used in BODY, and its cadr is a sexp to be
|
||||||
|
evalled to set symbol's value."
|
||||||
|
(declare (indent 1) (debug if-let*))
|
||||||
|
`(if-let* ,bindings ,(macroexp-progn body)))))
|
||||||
|
|
||||||
|
(provide 'cider-compat)
|
||||||
|
;;; cider-compat.el ends here
|
Binary file not shown.
|
@ -0,0 +1,253 @@
|
||||||
|
;;; cider-completion.el --- Smart REPL-powered code completion -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Smart REPL-powered code completion and integration with company-mode.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'thingatpt)
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-common)
|
||||||
|
(require 'cider-eldoc)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
|
||||||
|
(defcustom cider-completion-use-context t
|
||||||
|
"When true, uses context at point to improve completion suggestions."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
(defcustom cider-annotate-completion-candidates t
|
||||||
|
"When true, annotate completion candidates with some extra information."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.8.0"))
|
||||||
|
|
||||||
|
(defcustom cider-annotate-completion-function
|
||||||
|
#'cider-default-annotate-completion-function
|
||||||
|
"Controls how the annotations for completion candidates are formatted.
|
||||||
|
Must be a function that takes two arguments: the abbreviation of the
|
||||||
|
candidate type according to `cider-completion-annotations-alist' and the
|
||||||
|
candidate's namespace."
|
||||||
|
:type 'function
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defcustom cider-completion-annotations-alist
|
||||||
|
'(("class" "c")
|
||||||
|
("field" "fi")
|
||||||
|
("function" "f")
|
||||||
|
("import" "i")
|
||||||
|
("keyword" "k")
|
||||||
|
("local" "l")
|
||||||
|
("macro" "m")
|
||||||
|
("method" "me")
|
||||||
|
("namespace" "n")
|
||||||
|
("protocol" "p")
|
||||||
|
("protocol-function" "pf")
|
||||||
|
("record" "r")
|
||||||
|
("special-form" "s")
|
||||||
|
("static-field" "sf")
|
||||||
|
("static-method" "sm")
|
||||||
|
("type" "t")
|
||||||
|
("var" "v"))
|
||||||
|
"Controls the abbreviations used when annotating completion candidates.
|
||||||
|
|
||||||
|
Must be a list of elements with the form (TYPE . ABBREVIATION), where TYPE
|
||||||
|
is a possible value of the candidate's type returned from the completion
|
||||||
|
backend, and ABBREVIATION is a short form of that type."
|
||||||
|
:type '(alist :key-type string :value-type string)
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defcustom cider-completion-annotations-include-ns 'unqualified
|
||||||
|
"Controls passing of namespaces to `cider-annotate-completion-function'.
|
||||||
|
|
||||||
|
When set to 'always, the candidate's namespace will always be passed if it
|
||||||
|
is available. When set to 'unqualified, the namespace will only be passed
|
||||||
|
if the candidate is not namespace-qualified."
|
||||||
|
:type '(choice (const always)
|
||||||
|
(const unqualified)
|
||||||
|
(const :tag "never" nil))
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defvar cider-completion-last-context nil)
|
||||||
|
|
||||||
|
(defun cider-completion-symbol-start-pos ()
|
||||||
|
"Find the starting position of the symbol at point, unless inside a string."
|
||||||
|
(let ((sap (symbol-at-point)))
|
||||||
|
(when (and sap (not (nth 3 (syntax-ppss))))
|
||||||
|
(car (bounds-of-thing-at-point 'symbol)))))
|
||||||
|
|
||||||
|
(defun cider-completion-get-context-at-point ()
|
||||||
|
"Extract the context at point.
|
||||||
|
If point is not inside the list, returns nil; otherwise return \"top-level\"
|
||||||
|
form, with symbol at point replaced by __prefix__."
|
||||||
|
(when (save-excursion
|
||||||
|
(condition-case _
|
||||||
|
(progn
|
||||||
|
(up-list)
|
||||||
|
(check-parens)
|
||||||
|
t)
|
||||||
|
(scan-error nil)
|
||||||
|
(user-error nil)))
|
||||||
|
(save-excursion
|
||||||
|
(let* ((pref-end (point))
|
||||||
|
(pref-start (cider-completion-symbol-start-pos))
|
||||||
|
(context (cider-defun-at-point))
|
||||||
|
(_ (beginning-of-defun))
|
||||||
|
(expr-start (point)))
|
||||||
|
(concat (when pref-start (substring context 0 (- pref-start expr-start)))
|
||||||
|
"__prefix__"
|
||||||
|
(substring context (- pref-end expr-start)))))))
|
||||||
|
|
||||||
|
(defun cider-completion-get-context ()
|
||||||
|
"Extract context depending on `cider-completion-use-context' and major mode."
|
||||||
|
(let ((context (if (and cider-completion-use-context
|
||||||
|
;; Important because `beginning-of-defun' and
|
||||||
|
;; `ending-of-defun' work incorrectly in the REPL
|
||||||
|
;; buffer, so context extraction fails there.
|
||||||
|
(derived-mode-p 'clojure-mode))
|
||||||
|
(or (cider-completion-get-context-at-point)
|
||||||
|
"nil")
|
||||||
|
"nil")))
|
||||||
|
(if (string= cider-completion-last-context context)
|
||||||
|
":same"
|
||||||
|
(setq cider-completion-last-context context)
|
||||||
|
context)))
|
||||||
|
|
||||||
|
(defun cider-completion--parse-candidate-map (candidate-map)
|
||||||
|
"Get \"candidate\" from CANDIDATE-MAP.
|
||||||
|
Put type and ns properties on the candidate"
|
||||||
|
(let ((candidate (nrepl-dict-get candidate-map "candidate"))
|
||||||
|
(type (nrepl-dict-get candidate-map "type"))
|
||||||
|
(ns (nrepl-dict-get candidate-map "ns")))
|
||||||
|
(put-text-property 0 1 'type type candidate)
|
||||||
|
(put-text-property 0 1 'ns ns candidate)
|
||||||
|
candidate))
|
||||||
|
|
||||||
|
(defun cider-complete (str)
|
||||||
|
"Complete STR with context at point."
|
||||||
|
(let* ((context (cider-completion-get-context))
|
||||||
|
(candidates (cider-sync-request:complete str context)))
|
||||||
|
(mapcar #'cider-completion--parse-candidate-map candidates)))
|
||||||
|
|
||||||
|
(defun cider-completion--get-candidate-type (symbol)
|
||||||
|
"Get candidate type for SYMBOL."
|
||||||
|
(let ((type (get-text-property 0 'type symbol)))
|
||||||
|
(or (cadr (assoc type cider-completion-annotations-alist))
|
||||||
|
type)))
|
||||||
|
|
||||||
|
(defun cider-completion--get-candidate-ns (symbol)
|
||||||
|
"Get candidate ns for SYMBOL."
|
||||||
|
(when (or (eq 'always cider-completion-annotations-include-ns)
|
||||||
|
(and (eq 'unqualified cider-completion-annotations-include-ns)
|
||||||
|
(not (cider-namespace-qualified-p symbol))))
|
||||||
|
(get-text-property 0 'ns symbol)))
|
||||||
|
|
||||||
|
(defun cider-default-annotate-completion-function (type ns)
|
||||||
|
"Get completion function based on TYPE and NS."
|
||||||
|
(concat (when ns (format " (%s)" ns))
|
||||||
|
(when type (format " <%s>" type))))
|
||||||
|
|
||||||
|
(defun cider-annotate-symbol (symbol)
|
||||||
|
"Return a string suitable for annotating SYMBOL.
|
||||||
|
If SYMBOL has a text property `type` whose value is recognised, its
|
||||||
|
abbreviation according to `cider-completion-annotations-alist' will be
|
||||||
|
used. If `type` is present but not recognised, its value will be used
|
||||||
|
unaltered. If SYMBOL has a text property `ns`, then its value will be used
|
||||||
|
according to `cider-completion-annotations-include-ns'. The formatting is
|
||||||
|
performed by `cider-annotate-completion-function'."
|
||||||
|
(when cider-annotate-completion-candidates
|
||||||
|
(let* ((type (cider-completion--get-candidate-type symbol))
|
||||||
|
(ns (cider-completion--get-candidate-ns symbol)))
|
||||||
|
(funcall cider-annotate-completion-function type ns))))
|
||||||
|
|
||||||
|
(defun cider-complete-at-point ()
|
||||||
|
"Complete the symbol at point."
|
||||||
|
(when-let* ((bounds (bounds-of-thing-at-point 'symbol)))
|
||||||
|
(when (and (cider-connected-p)
|
||||||
|
(not (or (cider-in-string-p) (cider-in-comment-p))))
|
||||||
|
(list (car bounds) (cdr bounds)
|
||||||
|
(completion-table-dynamic #'cider-complete)
|
||||||
|
:annotation-function #'cider-annotate-symbol
|
||||||
|
:company-doc-buffer #'cider-create-doc-buffer
|
||||||
|
:company-location #'cider-company-location
|
||||||
|
:company-docsig #'cider-company-docsig))))
|
||||||
|
|
||||||
|
(defun cider-completion-flush-caches ()
|
||||||
|
"Force Compliment to refill its caches.
|
||||||
|
This command should be used if Compliment fails to pick up new classnames
|
||||||
|
and methods from dependencies that were loaded dynamically after the REPL
|
||||||
|
has started."
|
||||||
|
(interactive)
|
||||||
|
(cider-sync-request:complete-flush-caches))
|
||||||
|
|
||||||
|
(defun cider-company-location (var)
|
||||||
|
"Open VAR's definition in a buffer.
|
||||||
|
Returns the cons of the buffer itself and the location of VAR's definition
|
||||||
|
in the buffer."
|
||||||
|
(when-let* ((info (cider-var-info var))
|
||||||
|
(file (nrepl-dict-get info "file"))
|
||||||
|
(line (nrepl-dict-get info "line"))
|
||||||
|
(buffer (cider-find-file file)))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line (1- line))
|
||||||
|
(cons buffer (point))))))
|
||||||
|
|
||||||
|
(defun cider-company-docsig (thing)
|
||||||
|
"Return signature for THING."
|
||||||
|
(let* ((eldoc-info (cider-eldoc-info thing))
|
||||||
|
(ns (lax-plist-get eldoc-info "ns"))
|
||||||
|
(symbol (lax-plist-get eldoc-info "symbol"))
|
||||||
|
(arglists (lax-plist-get eldoc-info "arglists")))
|
||||||
|
(when eldoc-info
|
||||||
|
(format "%s: %s"
|
||||||
|
(cider-eldoc-format-thing ns symbol thing
|
||||||
|
(cider-eldoc-thing-type eldoc-info))
|
||||||
|
(cider-eldoc-format-arglist arglists 0)))))
|
||||||
|
|
||||||
|
;; Fuzzy completion for company-mode
|
||||||
|
|
||||||
|
(defun cider-company-unfiltered-candidates (string &rest _)
|
||||||
|
"Return CIDER completion candidates for STRING as is, unfiltered."
|
||||||
|
(cider-complete string))
|
||||||
|
|
||||||
|
(add-to-list 'completion-styles-alist
|
||||||
|
'(cider
|
||||||
|
cider-company-unfiltered-candidates
|
||||||
|
cider-company-unfiltered-candidates
|
||||||
|
"CIDER backend-driven completion style."))
|
||||||
|
|
||||||
|
(defun cider-company-enable-fuzzy-completion ()
|
||||||
|
"Enable backend-driven fuzzy completion in the current buffer."
|
||||||
|
(setq-local completion-styles '(cider)))
|
||||||
|
|
||||||
|
(provide 'cider-completion)
|
||||||
|
;;; cider-completion.el ends here
|
Binary file not shown.
|
@ -0,0 +1,646 @@
|
||||||
|
;;; cider-connection.el --- Connection and session life-cycle management for CIDER -*- lexical-binding: t -*-
|
||||||
|
;;
|
||||||
|
;; Copyright © 2018 Artur Malabarba, Bozhidar Batsov, Vitalie Spinu and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
;; Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Vitalie Spinu <spinuvit@gmail.com>
|
||||||
|
;;
|
||||||
|
;; Keywords: languages, clojure, cider
|
||||||
|
;;
|
||||||
|
;; 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/>.
|
||||||
|
;;
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'nrepl-client)
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'sesman)
|
||||||
|
|
||||||
|
(defcustom cider-connection-message-fn #'cider-random-words-of-inspiration
|
||||||
|
"The function to use to generate the message displayed on connect.
|
||||||
|
When set to nil no additional message will be displayed. A good
|
||||||
|
alternative to the default is `cider-random-tip'."
|
||||||
|
:type 'function
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.11.0"))
|
||||||
|
|
||||||
|
(defcustom cider-redirect-server-output-to-repl t
|
||||||
|
"Controls whether nREPL server output would be redirected to the REPL.
|
||||||
|
When non-nil the output would end up in both the nrepl-server buffer (when
|
||||||
|
available) and the matching REPL buffer."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:safe #'booleanp
|
||||||
|
:package-version '(cider . "0.17.0"))
|
||||||
|
|
||||||
|
(defcustom cider-auto-mode t
|
||||||
|
"When non-nil, automatically enable cider mode for all Clojure buffers."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:safe #'booleanp
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defconst cider-required-nrepl-version "0.2.12"
|
||||||
|
"The minimum nREPL version that's known to work properly with CIDER.")
|
||||||
|
|
||||||
|
|
||||||
|
;;; Connect
|
||||||
|
|
||||||
|
(defun cider-nrepl-connect (params)
|
||||||
|
"Start nrepl client and create the REPL.
|
||||||
|
PARAMS is a plist containing :host, :port, :server and other parameters for
|
||||||
|
`cider-repl-create'."
|
||||||
|
(process-buffer
|
||||||
|
(nrepl-start-client-process
|
||||||
|
(plist-get params :host)
|
||||||
|
(plist-get params :port)
|
||||||
|
(plist-get params :server)
|
||||||
|
(lambda (_)
|
||||||
|
(cider-repl-create params)))))
|
||||||
|
|
||||||
|
(defun cider-connected-p ()
|
||||||
|
"Return t if CIDER is currently connected, nil otherwise."
|
||||||
|
(process-live-p (get-buffer-process (cider-current-repl))))
|
||||||
|
|
||||||
|
(defun cider-ensure-connected ()
|
||||||
|
"Ensure there is a linked CIDER session."
|
||||||
|
(sesman-ensure-session 'CIDER))
|
||||||
|
|
||||||
|
(defun cider--gather-connect-params (params proc-buffer)
|
||||||
|
"Gather all relevant connection parameters into PARAMS plist.
|
||||||
|
PROC-BUFFER is either server or client buffer."
|
||||||
|
(with-current-buffer proc-buffer
|
||||||
|
(unless nrepl-endpoint
|
||||||
|
(error "This is not a REPL or SERVER buffer; is there an active REPL?"))
|
||||||
|
(let ((server-buf (if (nrepl-server-p proc-buffer)
|
||||||
|
proc-buffer
|
||||||
|
nrepl-server-buffer)))
|
||||||
|
(cl-loop for l on nrepl-endpoint by #'cddr
|
||||||
|
do (setq params (plist-put params (car l) (cadr l))))
|
||||||
|
(setq params (thread-first params
|
||||||
|
(plist-put :project-dir nrepl-project-dir)))
|
||||||
|
(when (buffer-live-p server-buf)
|
||||||
|
(setq params (thread-first params
|
||||||
|
(plist-put :server (get-buffer-process server-buf))
|
||||||
|
(plist-put :server-command nrepl-server-command))))
|
||||||
|
;; repl-specific parameters (do not pollute server params!)
|
||||||
|
(when (nrepl-server-p proc-buffer)
|
||||||
|
(setq params (thread-first params
|
||||||
|
(plist-put :repl-type cider-repl-type)
|
||||||
|
(plist-put :repl-init-function cider-repl-init-function))))
|
||||||
|
params)))
|
||||||
|
|
||||||
|
(defun cider--close-buffer (buffer)
|
||||||
|
"Close the BUFFER and kill its associated process (if any)."
|
||||||
|
(when (buffer-live-p buffer)
|
||||||
|
(when-let* ((proc (get-buffer-process buffer)))
|
||||||
|
(when (process-live-p proc)
|
||||||
|
(delete-process proc)))
|
||||||
|
(kill-buffer buffer)))
|
||||||
|
|
||||||
|
(declare-function cider-repl-emit-interactive-stderr "cider-repl")
|
||||||
|
(defun cider--close-connection (repl &optional no-kill)
|
||||||
|
"Close connection associated with REPL.
|
||||||
|
When NO-KILL is non-nil stop the connection but don't kill the REPL
|
||||||
|
buffer."
|
||||||
|
(when (buffer-live-p repl)
|
||||||
|
(with-current-buffer repl
|
||||||
|
(when spinner-current (spinner-stop))
|
||||||
|
(when nrepl-tunnel-buffer
|
||||||
|
(cider--close-buffer nrepl-tunnel-buffer))
|
||||||
|
(when no-kill
|
||||||
|
;; inform sentinel not to kill the server, if any
|
||||||
|
(thread-first (get-buffer-process repl)
|
||||||
|
(process-plist)
|
||||||
|
(plist-put :no-server-kill t))))
|
||||||
|
(let ((proc (get-buffer-process repl)))
|
||||||
|
(when (and (process-live-p proc)
|
||||||
|
(or (not nrepl-server-buffer)
|
||||||
|
;; Sync request will hang if the server is dead.
|
||||||
|
(process-live-p (get-buffer-process nrepl-server-buffer))))
|
||||||
|
(nrepl-sync-request:close repl)
|
||||||
|
(delete-process proc)))
|
||||||
|
(when-let* ((messages-buffer (and nrepl-log-messages
|
||||||
|
(nrepl-messages-buffer repl))))
|
||||||
|
(kill-buffer messages-buffer))
|
||||||
|
(if no-kill
|
||||||
|
(with-current-buffer repl
|
||||||
|
(goto-char (point-max))
|
||||||
|
(cider-repl-emit-interactive-stderr
|
||||||
|
(format "*** Closed on %s ***\n" (current-time-string))))
|
||||||
|
(kill-buffer repl)))
|
||||||
|
(when repl
|
||||||
|
(sesman-remove-object 'CIDER nil repl (not no-kill) t)))
|
||||||
|
|
||||||
|
(defun cider-emit-manual-warning (section-id format &rest args)
|
||||||
|
"Emit a warning to the REPL and link to the online manual.
|
||||||
|
SECTION-ID is the section to link to. The link is added on the last line.
|
||||||
|
FORMAT is a format string to compile with ARGS and display on the REPL."
|
||||||
|
(let ((message (apply #'format format args)))
|
||||||
|
(cider-repl-emit-interactive-stderr
|
||||||
|
(concat "WARNING: " message "\n "
|
||||||
|
(cider--manual-button "More information" section-id)
|
||||||
|
"."))))
|
||||||
|
|
||||||
|
(defvar cider-version)
|
||||||
|
(defun cider--check-required-nrepl-version ()
|
||||||
|
"Check whether we're using a compatible nREPL version."
|
||||||
|
(if-let* ((nrepl-version (cider--nrepl-version)))
|
||||||
|
(when (version< nrepl-version cider-required-nrepl-version)
|
||||||
|
(cider-emit-manual-warning "troubleshooting/#warning-saying-you-have-to-use-nrepl-0212"
|
||||||
|
"CIDER requires nREPL %s (or newer) to work properly"
|
||||||
|
cider-required-nrepl-version))
|
||||||
|
(cider-emit-manual-warning "troubleshooting/#warning-saying-you-have-to-use-nrepl-0212"
|
||||||
|
"Can't determine nREPL's version.\nPlease, update nREPL to %s."
|
||||||
|
cider-required-nrepl-version)))
|
||||||
|
|
||||||
|
(defvar cider-minimum-clojure-version)
|
||||||
|
(defun cider--check-clojure-version-supported ()
|
||||||
|
"Ensure that we are meeting the minimum supported version of Clojure."
|
||||||
|
(if-let* ((clojure-version (cider--clojure-version)))
|
||||||
|
(when (version< clojure-version cider-minimum-clojure-version)
|
||||||
|
(cider-emit-manual-warning "installation/#prerequisites"
|
||||||
|
"Clojure version (%s) is not supported (minimum %s). CIDER will not work."
|
||||||
|
clojure-version cider-minimum-clojure-version))
|
||||||
|
(cider-emit-manual-warning "installation/#prerequisites"
|
||||||
|
"Can't determine Clojure's version. CIDER requires Clojure %s (or newer)."
|
||||||
|
cider-minimum-clojure-version)))
|
||||||
|
|
||||||
|
(defun cider--check-middleware-compatibility ()
|
||||||
|
"CIDER frontend/backend compatibility check.
|
||||||
|
Retrieve the underlying connection's CIDER-nREPL version and checks if the
|
||||||
|
middleware used is compatible with CIDER. If not, will display a warning
|
||||||
|
message in the REPL area."
|
||||||
|
(let* ((version-dict (nrepl-aux-info "cider-version" (cider-current-repl)))
|
||||||
|
(middleware-version (nrepl-dict-get version-dict "version-string" "not installed")))
|
||||||
|
(unless (equal cider-version middleware-version)
|
||||||
|
(cider-emit-manual-warning "troubleshooting/#cider-complains-of-the-cider-nrepl-version"
|
||||||
|
"CIDER's version (%s) does not match cider-nrepl's version (%s). Things will break!"
|
||||||
|
cider-version middleware-version))))
|
||||||
|
|
||||||
|
(declare-function cider-interactive-eval-handler "cider-eval")
|
||||||
|
;; TODO: Use some null handler here
|
||||||
|
(defun cider--subscribe-repl-to-server-out ()
|
||||||
|
"Subscribe to the nREPL server's *out*."
|
||||||
|
(cider-nrepl-send-request '("op" "out-subscribe")
|
||||||
|
(cider-interactive-eval-handler (current-buffer))))
|
||||||
|
|
||||||
|
(declare-function cider-mode "cider-mode")
|
||||||
|
(defun cider-enable-on-existing-clojure-buffers ()
|
||||||
|
"Enable CIDER's minor mode on existing Clojure buffers.
|
||||||
|
See command `cider-mode'."
|
||||||
|
(interactive)
|
||||||
|
(add-hook 'clojure-mode-hook #'cider-mode)
|
||||||
|
(dolist (buffer (cider-util--clojure-buffers))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-mode +1))))
|
||||||
|
|
||||||
|
(defun cider-disable-on-existing-clojure-buffers ()
|
||||||
|
"Disable command `cider-mode' on existing Clojure buffers."
|
||||||
|
(interactive)
|
||||||
|
(dolist (buffer (cider-util--clojure-buffers))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-mode -1))))
|
||||||
|
|
||||||
|
(defun cider-possibly-disable-on-existing-clojure-buffers ()
|
||||||
|
"If not connected, disable command `cider-mode' on existing Clojure buffers."
|
||||||
|
(unless (cider-connected-p)
|
||||||
|
(cider-disable-on-existing-clojure-buffers)))
|
||||||
|
|
||||||
|
(declare-function cider--debug-init-connection "cider-debug")
|
||||||
|
(declare-function cider-repl-init "cider-repl")
|
||||||
|
(defun cider--connected-handler ()
|
||||||
|
"Handle CIDER initialization after nREPL connection has been established.
|
||||||
|
This function is appended to `nrepl-connected-hook' in the client process
|
||||||
|
buffer."
|
||||||
|
;; `nrepl-connected-hook' is run in the connection buffer
|
||||||
|
;; `cider-enlighten-mode' changes eval to include the debugger, so we inhibit
|
||||||
|
;; it here as the debugger isn't necessarily initialized yet
|
||||||
|
(let ((cider-enlighten-mode nil))
|
||||||
|
;; after initialization, set mode-line and buffer name.
|
||||||
|
(cider-set-repl-type cider-repl-type)
|
||||||
|
(cider-repl-init (current-buffer))
|
||||||
|
(cider--check-required-nrepl-version)
|
||||||
|
(cider--check-clojure-version-supported)
|
||||||
|
(cider--check-middleware-compatibility)
|
||||||
|
(when cider-redirect-server-output-to-repl
|
||||||
|
(cider--subscribe-repl-to-server-out))
|
||||||
|
(when cider-auto-mode
|
||||||
|
(cider-enable-on-existing-clojure-buffers))
|
||||||
|
;; Middleware on cider-nrepl's side is deferred until first usage, but
|
||||||
|
;; loading middleware concurrently can lead to occasional "require" issues
|
||||||
|
;; (likely a Clojure bug). Thus, we load the heavy debug middleware towards
|
||||||
|
;; the end, allowing for the faster "server-out" middleware to load
|
||||||
|
;; first.
|
||||||
|
(cider--debug-init-connection)
|
||||||
|
(when cider-repl-init-function
|
||||||
|
(funcall cider-repl-init-function))
|
||||||
|
(run-hooks 'cider-connected-hook)))
|
||||||
|
|
||||||
|
(defun cider--disconnected-handler ()
|
||||||
|
"Cleanup after nREPL connection has been lost or closed.
|
||||||
|
This function is appended to `nrepl-disconnected-hook' in the client
|
||||||
|
process buffer."
|
||||||
|
;; `nrepl-connected-hook' is run in the connection buffer
|
||||||
|
(cider-possibly-disable-on-existing-clojure-buffers)
|
||||||
|
(run-hooks 'cider-disconnected-hook))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Connection Info
|
||||||
|
|
||||||
|
(defun cider--java-version ()
|
||||||
|
"Retrieve the underlying connection's Java version."
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
(when nrepl-versions
|
||||||
|
(thread-first nrepl-versions
|
||||||
|
(nrepl-dict-get "java")
|
||||||
|
(nrepl-dict-get "version-string")))))
|
||||||
|
|
||||||
|
(defun cider--clojure-version ()
|
||||||
|
"Retrieve the underlying connection's Clojure version."
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
(when nrepl-versions
|
||||||
|
(thread-first nrepl-versions
|
||||||
|
(nrepl-dict-get "clojure")
|
||||||
|
(nrepl-dict-get "version-string")))))
|
||||||
|
|
||||||
|
(defun cider--nrepl-version ()
|
||||||
|
"Retrieve the underlying connection's nREPL version."
|
||||||
|
(with-current-buffer (cider-current-repl)
|
||||||
|
(when nrepl-versions
|
||||||
|
(thread-first nrepl-versions
|
||||||
|
(nrepl-dict-get "nrepl")
|
||||||
|
(nrepl-dict-get "version-string")))))
|
||||||
|
|
||||||
|
(defun cider--connection-info (connection-buffer &optional genericp)
|
||||||
|
"Return info about CONNECTION-BUFFER.
|
||||||
|
Info contains project name, current REPL namespace, host:port endpoint and
|
||||||
|
Clojure version. When GENERICP is non-nil, don't provide specific info
|
||||||
|
about this buffer (like variable `cider-repl-type')."
|
||||||
|
(with-current-buffer connection-buffer
|
||||||
|
(format "%s%s@%s:%s (Java %s, Clojure %s, nREPL %s)"
|
||||||
|
(if genericp "" (upcase (concat cider-repl-type " ")))
|
||||||
|
(or (cider--project-name nrepl-project-dir) "<no project>")
|
||||||
|
(plist-get nrepl-endpoint :host)
|
||||||
|
(plist-get nrepl-endpoint :port)
|
||||||
|
(cider--java-version)
|
||||||
|
(cider--clojure-version)
|
||||||
|
(cider--nrepl-version))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Cider's Connection Management UI
|
||||||
|
|
||||||
|
(defun cider-quit ()
|
||||||
|
"Quit the currently active CIDER connection."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(let ((connection (cider-current-repl)))
|
||||||
|
(cider--close-connection connection))
|
||||||
|
;; if there are no more connections we can kill all ancillary buffers
|
||||||
|
(unless (cider-connected-p)
|
||||||
|
(cider-close-ancillary-buffers)))
|
||||||
|
|
||||||
|
(defun cider-restart ()
|
||||||
|
"Restart the currently active CIDER connection.
|
||||||
|
Don't restart the server or other connections within the same session. Use
|
||||||
|
`sesman-restart' to restart the entire session."
|
||||||
|
(interactive)
|
||||||
|
(let* ((repl (or (cider-current-repl)
|
||||||
|
(user-error "No linked REPL")))
|
||||||
|
(params (thread-first (cider--gather-connect-params nil repl)
|
||||||
|
(plist-put :session-name (sesman-session-name-for-object 'CIDER repl))
|
||||||
|
(plist-put :repl-buffer repl))))
|
||||||
|
(cider--close-connection repl 'no-kill)
|
||||||
|
(cider-nrepl-connect params)))
|
||||||
|
|
||||||
|
(defun cider-close-ancillary-buffers ()
|
||||||
|
"Close buffers that are shared across connections."
|
||||||
|
(interactive)
|
||||||
|
(dolist (buf-name cider-ancillary-buffers)
|
||||||
|
(when (get-buffer buf-name)
|
||||||
|
(kill-buffer buf-name))))
|
||||||
|
|
||||||
|
(defun cider-describe-current-connection ()
|
||||||
|
"Display information about the current connection."
|
||||||
|
(interactive)
|
||||||
|
(message "%s" (cider--connection-info (cider-current-repl nil 'ensure))))
|
||||||
|
(define-obsolete-function-alias 'cider-display-connection-info 'cider-describe-current-connection "0.18.0")
|
||||||
|
|
||||||
|
(defconst cider-nrepl-session-buffer "*cider-nrepl-session*")
|
||||||
|
|
||||||
|
(defun cider-describe-nrepl-session ()
|
||||||
|
"Describe an nREPL session."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(let* ((repl (cider-current-repl nil 'ensure))
|
||||||
|
(selected-session (completing-read "Describe nREPL session: " (nrepl-sessions repl))))
|
||||||
|
(when (and selected-session (not (equal selected-session "")))
|
||||||
|
(let* ((session-info (nrepl-sync-request:describe repl))
|
||||||
|
(ops (nrepl-dict-keys (nrepl-dict-get session-info "ops")))
|
||||||
|
(session-id (nrepl-dict-get session-info "session"))
|
||||||
|
(session-type (cond
|
||||||
|
((equal session-id (cider-nrepl-eval-session)) "Active eval")
|
||||||
|
((equal session-id (cider-nrepl-tooling-session)) "Active tooling")
|
||||||
|
(t "Unknown"))))
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-nrepl-session-buffer 'select nil 'ancillary)
|
||||||
|
(read-only-mode -1)
|
||||||
|
(insert (format "Session: %s\n" session-id)
|
||||||
|
(format "Type: %s session\n" session-type)
|
||||||
|
(format "Supported ops:\n"))
|
||||||
|
(mapc (lambda (op) (insert (format " * %s\n" op))) ops)))
|
||||||
|
(display-buffer cider-nrepl-session-buffer))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Sesman's Session-Wise Management UI
|
||||||
|
|
||||||
|
(cl-defmethod sesman-more-relevant-p ((_system (eql CIDER)) session1 session2)
|
||||||
|
(sesman-more-recent-p (cdr session1) (cdr session2)))
|
||||||
|
|
||||||
|
(cl-defmethod sesman-session-info ((_system (eql CIDER)) session)
|
||||||
|
(interactive "P")
|
||||||
|
(let ((repl (cadr session)))
|
||||||
|
(format "\t%s: %s\n\tREPLS: %s"
|
||||||
|
(if (buffer-local-value 'nrepl-server-buffer repl) "SERVER" "CONNECTION")
|
||||||
|
(cider--connection-info repl t)
|
||||||
|
(mapconcat #'buffer-name (cdr session) ", "))))
|
||||||
|
|
||||||
|
(declare-function cider "cider")
|
||||||
|
(cl-defmethod sesman-start-session ((_system (eql CIDER)))
|
||||||
|
"Start a connection of any type interactively.
|
||||||
|
Fallback on `cider' command."
|
||||||
|
(call-interactively #'cider))
|
||||||
|
|
||||||
|
(cl-defmethod sesman-quit-session ((_system (eql CIDER)) session)
|
||||||
|
(mapc #'cider--close-connection (cdr session))
|
||||||
|
;; if there are no more connections we can kill all ancillary buffers
|
||||||
|
(unless (cider-connected-p)
|
||||||
|
(cider-close-ancillary-buffers)))
|
||||||
|
|
||||||
|
(cl-defmethod sesman-restart-session ((_system (eql CIDER)) session)
|
||||||
|
(let* ((repls (cdr session))
|
||||||
|
(s-buf (seq-some (lambda (r)
|
||||||
|
(buffer-local-value 'nrepl-server-buffer r))
|
||||||
|
repls))
|
||||||
|
(s-params (cider--gather-connect-params nil s-buf))
|
||||||
|
(ses-name (car session)))
|
||||||
|
;; 1) kill all connections, but keep the buffers
|
||||||
|
(mapc (lambda (conn)
|
||||||
|
(cider--close-connection conn 'no-kill))
|
||||||
|
repls)
|
||||||
|
;; 2) kill the server
|
||||||
|
(message "Waiting for CIDER server to quit...")
|
||||||
|
(nrepl-kill-server-buffer s-buf)
|
||||||
|
;; 3) start server
|
||||||
|
(nrepl-start-server-process
|
||||||
|
(plist-get s-params :project-dir)
|
||||||
|
(plist-get s-params :server-command)
|
||||||
|
(lambda (server-buf)
|
||||||
|
;; 4) restart the repls reusing the buffer
|
||||||
|
(dolist (r repls)
|
||||||
|
(cider-nrepl-connect
|
||||||
|
(thread-first ()
|
||||||
|
(cider--gather-connect-params r)
|
||||||
|
;; server params (:port, :project-dir etc) have precedence
|
||||||
|
(cider--gather-connect-params server-buf)
|
||||||
|
(plist-put :session-name ses-name)
|
||||||
|
(plist-put :repl-buffer r))))
|
||||||
|
(message "Restarted CIDER %s session" ses-name)))))
|
||||||
|
|
||||||
|
(defun cider-new-session-name (params)
|
||||||
|
"Create new session name given plist of connection PARAMS."
|
||||||
|
(let* ((dir (or (plist-get params :project-dir)
|
||||||
|
(clojure-project-dir (cider-current-dir))
|
||||||
|
default-directory))
|
||||||
|
(host (plist-get params :host))
|
||||||
|
;; showing host:port on remotes only
|
||||||
|
(host-port (if (not (or (null host)
|
||||||
|
(equal host "localhost")
|
||||||
|
(equal host "127.0.0.1")))
|
||||||
|
(format ":%s:%s" host (plist-get params :port))
|
||||||
|
""))
|
||||||
|
(root-name (file-name-nondirectory (directory-file-name dir)))
|
||||||
|
(name (format "%s%s" root-name host-port))
|
||||||
|
(other-names (mapcar #'car (sesman-sessions 'CIDER)))
|
||||||
|
(i 2))
|
||||||
|
(while (member name other-names)
|
||||||
|
(setq name (concat root-name "#" (number-to-string i))
|
||||||
|
i (+ i 1)))
|
||||||
|
name))
|
||||||
|
|
||||||
|
|
||||||
|
;;; REPL Buffer Init
|
||||||
|
|
||||||
|
(defvar-local cider-repl-type nil
|
||||||
|
"The type of this REPL buffer, usually either \"clj\" or \"cljs\".")
|
||||||
|
|
||||||
|
(defun cider-repl-type (repl-buffer)
|
||||||
|
"Get REPL-BUFFER's type."
|
||||||
|
(buffer-local-value 'cider-repl-type repl-buffer))
|
||||||
|
|
||||||
|
(defun cider-repl-type-for-buffer (&optional buffer)
|
||||||
|
"Return the matching connection type (clj or cljs) for BUFFER.
|
||||||
|
BUFFER defaults to the `current-buffer'. In cljc buffers return
|
||||||
|
\"multi\". This function infers connection type based on the major mode.
|
||||||
|
For the REPL type use the function `cider-repl-type'."
|
||||||
|
(with-current-buffer (or buffer (current-buffer))
|
||||||
|
(cond
|
||||||
|
((derived-mode-p 'clojurescript-mode) "cljs")
|
||||||
|
((derived-mode-p 'clojurec-mode) "multi")
|
||||||
|
((derived-mode-p 'clojure-mode) "clj")
|
||||||
|
(cider-repl-type))))
|
||||||
|
|
||||||
|
(defun cider-set-repl-type (&optional type)
|
||||||
|
"Set REPL TYPE to \"clj\" or \"cljs\".
|
||||||
|
Assume that the current buffer is a REPL."
|
||||||
|
(interactive)
|
||||||
|
(let ((type (or type (completing-read
|
||||||
|
(format "Set REPL type (currently `%s') to: "
|
||||||
|
cider-repl-type)
|
||||||
|
'("clj" "cljs")))))
|
||||||
|
(when (or (not (equal cider-repl-type type))
|
||||||
|
(null mode-name))
|
||||||
|
(setq cider-repl-type type)
|
||||||
|
(setq mode-name (format "REPL[%s]" type))
|
||||||
|
(rename-buffer (nrepl-repl-buffer-name))
|
||||||
|
(when (and nrepl-log-messages nrepl-messages-buffer)
|
||||||
|
(let ((mbuf-name (nrepl-messages-buffer-name (current-buffer))))
|
||||||
|
(with-current-buffer nrepl-messages-buffer
|
||||||
|
(rename-buffer mbuf-name)))))))
|
||||||
|
|
||||||
|
(declare-function cider-default-err-handler "cider-eval")
|
||||||
|
(declare-function cider-repl-mode "cider-repl")
|
||||||
|
(declare-function cider-repl--state-handler "cider-repl")
|
||||||
|
(declare-function cider-repl-reset-markers "cider-repl")
|
||||||
|
(defvar-local cider-repl-init-function nil)
|
||||||
|
(defun cider-repl-create (params)
|
||||||
|
"Create new repl buffer.
|
||||||
|
PARAMS is a plist which contains :repl-type, :host, :port, :project-dir,
|
||||||
|
:repl-init-function and :session-name. When non-nil, :repl-init-function
|
||||||
|
must be a function with no arguments which is called after repl creation
|
||||||
|
function with the repl buffer set as current."
|
||||||
|
;; Connection might not have been set as yet. Please don't send requests in
|
||||||
|
;; this function, but use cider--connected-handler instead.
|
||||||
|
(let ((buffer (or (plist-get params :repl-buffer)
|
||||||
|
(get-buffer-create (generate-new-buffer-name "*cider-uninitialized-repl*")))))
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((ses-name (or (plist-get params :session-name)
|
||||||
|
(cider-new-session-name params))))
|
||||||
|
(sesman-add-object 'CIDER ses-name buffer t))
|
||||||
|
(unless (derived-mode-p 'cider-repl-mode)
|
||||||
|
(cider-repl-mode))
|
||||||
|
(setq nrepl-err-handler #'cider-default-err-handler
|
||||||
|
;; used as a new-repl marker in cider-set-repl-type
|
||||||
|
mode-name nil
|
||||||
|
;; REPLs start with clj and then "upgrade" to a different type
|
||||||
|
cider-repl-type "clj"
|
||||||
|
;; ran at the end of cider--connected-handler
|
||||||
|
cider-repl-init-function (plist-get params :repl-init-function))
|
||||||
|
(cider-repl-reset-markers)
|
||||||
|
(add-hook 'nrepl-response-handler-functions #'cider-repl--state-handler nil 'local)
|
||||||
|
(add-hook 'nrepl-connected-hook 'cider--connected-handler nil 'local)
|
||||||
|
(add-hook 'nrepl-disconnected-hook 'cider--disconnected-handler nil 'local)
|
||||||
|
(current-buffer))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Current/other REPLs
|
||||||
|
|
||||||
|
(defun cider-current-repl (&optional type ensure)
|
||||||
|
"Get the most recent REPL of TYPE from the current session.
|
||||||
|
TYPE is either \"clj\", \"cljs\" or \"multi\". When nil, infer the type
|
||||||
|
from the current buffer. If ENSURE is non-nil, throw an error if either
|
||||||
|
there is no linked session or there is no REPL of TYPE within the current
|
||||||
|
session."
|
||||||
|
(if (and (derived-mode-p 'cider-repl-mode)
|
||||||
|
(or (null type)
|
||||||
|
(string= cider-repl-type type)))
|
||||||
|
;; shortcut when in REPL buffer
|
||||||
|
(current-buffer)
|
||||||
|
(let* ((type (or type (cider-repl-type-for-buffer)))
|
||||||
|
(repls (cider-repls type ensure))
|
||||||
|
(repl (if (<= (length repls) 1)
|
||||||
|
(car repls)
|
||||||
|
;; pick the most recent one
|
||||||
|
(seq-find (lambda (b)
|
||||||
|
(member b repls))
|
||||||
|
(buffer-list)))))
|
||||||
|
(if (and ensure (null repl))
|
||||||
|
(user-error "No %s REPL in current session (%s)"
|
||||||
|
type (car (sesman-current-session 'CIDER)))
|
||||||
|
repl))))
|
||||||
|
|
||||||
|
(defun cider-repls (&optional type ensure)
|
||||||
|
"Return cider REPLs of TYPE from the current session.
|
||||||
|
If TYPE is nil or \"multi\", return all repls. If ENSURE is non-nil, throw
|
||||||
|
an error if no linked session exists."
|
||||||
|
(let ((repls (cdr (if ensure
|
||||||
|
(sesman-ensure-session 'CIDER)
|
||||||
|
(sesman-current-session 'CIDER)))))
|
||||||
|
(if (or (null type) (equal type "multi"))
|
||||||
|
repls
|
||||||
|
(seq-filter (lambda (b)
|
||||||
|
(string= type (cider-repl-type b)))
|
||||||
|
repls))))
|
||||||
|
|
||||||
|
(defun cider-map-repls (which function)
|
||||||
|
"Call FUNCTION once for each appropriate REPL as indicated by WHICH.
|
||||||
|
The function is called with one argument, the REPL buffer. The appropriate
|
||||||
|
connections are found by inspecting the current buffer. WHICH is one of
|
||||||
|
the following keywords:
|
||||||
|
:auto - Act on the connections whose type matches the current buffer. In
|
||||||
|
`cljc' files, mapping happens over both types of REPLs.
|
||||||
|
:clj (:cljs) - Map over clj (cljs)) REPLs only.
|
||||||
|
:clj-strict (:cljs-strict) - Map over clj (cljs) REPLs but signal a
|
||||||
|
`user-error' in `clojurescript-mode' (`clojure-mode'). Use this for
|
||||||
|
commands only supported in Clojure (ClojureScript).
|
||||||
|
Error is signaled if no REPL buffer of specified type exists."
|
||||||
|
(declare (indent 1))
|
||||||
|
(let ((cur-type (cider-repl-type-for-buffer)))
|
||||||
|
(cl-case which
|
||||||
|
(:clj-strict (when (equal cur-type "cljs")
|
||||||
|
(user-error "Clojure-only operation requested in a ClojureScript buffer")))
|
||||||
|
(:cljs-strict (when (equal cur-type "clj")
|
||||||
|
(user-error "ClojureScript-only operation requested in a Clojure buffer"))))
|
||||||
|
(let* ((type (cl-case which
|
||||||
|
((:clj :clj-strict) "clj")
|
||||||
|
((:cljs :cljs-strict) "cljs")
|
||||||
|
(:auto cur-type)))
|
||||||
|
(repls (cider-repls type 'ensure)))
|
||||||
|
(mapcar function repls))))
|
||||||
|
|
||||||
|
;; REPLs double as connections in CIDER, so it's useful to be able to refer to
|
||||||
|
;; them as connections in certain contexts.
|
||||||
|
(defalias 'cider-current-connection #'cider-current-repl)
|
||||||
|
(defalias 'cider-connections #'cider-repls)
|
||||||
|
(defalias 'cider-map-connections #'cider-map-repls)
|
||||||
|
(defalias 'cider-connection-type-for-buffer #'cider-repl-type-for-buffer)
|
||||||
|
|
||||||
|
|
||||||
|
;; Deprecation after #2324
|
||||||
|
|
||||||
|
(define-obsolete-function-alias 'cider-current-repl-buffer 'cider-current-repl "0.18")
|
||||||
|
(define-obsolete-function-alias 'cider-repl-buffers 'cider-repls "0.18")
|
||||||
|
(define-obsolete-function-alias 'cider-current-session 'cider-nrepl-eval-session "0.18")
|
||||||
|
(define-obsolete-function-alias 'cider-current-tooling-session 'cider-nrepl-tooling-session "0.18")
|
||||||
|
(define-obsolete-function-alias 'cider-display-connection-info 'cider-describe-current-connection "0.18")
|
||||||
|
(define-obsolete-function-alias 'nrepl-connection-buffer-name 'nrepl-repl-buffer-name "0.18")
|
||||||
|
(define-obsolete-function-alias 'cider-repl-set-type 'cider-set-repl-type "0.18")
|
||||||
|
|
||||||
|
(make-obsolete 'cider-assoc-buffer-with-connection 'sesman-link-with-buffer "0.18")
|
||||||
|
(make-obsolete 'cider-assoc-project-with-connection 'sesman-link-with-project "0.18")
|
||||||
|
(make-obsolete 'cider-change-buffers-designation nil "0.18")
|
||||||
|
(make-obsolete 'cider-clear-buffer-local-connection nil "0.18")
|
||||||
|
(make-obsolete 'cider-close-nrepl-session 'cider-quit "0.18")
|
||||||
|
(make-obsolete 'cider-create-sibling-cljs-repl 'cider-connect-sibling-cljs "0.18")
|
||||||
|
(make-obsolete 'cider-current-messages-buffer nil "0.18")
|
||||||
|
(make-obsolete 'cider-default-connection "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-extract-designation-from-current-repl-buffer nil "0.18")
|
||||||
|
(make-obsolete 'cider-find-connection-buffer-for-project-directory 'sesman-linked-sessions "0.18")
|
||||||
|
(make-obsolete 'cider-find-reusable-repl-buffer nil "0.18")
|
||||||
|
(make-obsolete 'cider-make-connection-default "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-other-connection nil "0.18")
|
||||||
|
(make-obsolete 'cider-project-connections 'sesman-linked-sessions "0.18")
|
||||||
|
(make-obsolete 'cider-project-connections-types nil "0.18")
|
||||||
|
(make-obsolete 'cider-prompt-for-project-on-connect nil "0.18")
|
||||||
|
(make-obsolete 'cider-read-connection `sesman-ask-for-session "0.18")
|
||||||
|
(make-obsolete 'cider-replicate-connection nil "0.18")
|
||||||
|
(make-obsolete 'cider-request-dispatch "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-rotate-default-connection "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-toggle-buffer-connection nil "0.18")
|
||||||
|
(make-obsolete 'cider-toggle-request-dispatch nil "0.18")
|
||||||
|
(make-obsolete 'nrepl-connection-buffer-name-template 'nrepl-repl-buffer-name-template "0.18")
|
||||||
|
(make-obsolete 'nrepl-create-client-buffer-function nil "0.18")
|
||||||
|
(make-obsolete 'nrepl-post-client-callback nil "0.18")
|
||||||
|
(make-obsolete 'nrepl-prompt-to-kill-server-buffer-on-quit nil "0.18")
|
||||||
|
(make-obsolete 'nrepl-use-this-as-repl-buffer nil "0.18")
|
||||||
|
|
||||||
|
;; connection manager
|
||||||
|
(make-obsolete 'cider-client-name-repl-type "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connection-browser "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connections-buffer-mode "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connections-buffer-mode-map "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connections-close-connection "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connections-goto-connection "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-connections-make-default "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-display-connected-message "see sesman." "0.18")
|
||||||
|
(make-obsolete 'cider-project-name "see sesman." "0.18")
|
||||||
|
|
||||||
|
(provide 'cider-connection)
|
||||||
|
|
||||||
|
;;; cider-connection.el ends here
|
Binary file not shown.
|
@ -0,0 +1,755 @@
|
||||||
|
;;; cider-debug.el --- CIDER interaction with the cider.debug nREPL middleware -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;; Copyright © 2015-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
|
||||||
|
;; Author: Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Instrument code with `cider-debug-defun-at-point', and when the code is
|
||||||
|
;; executed cider-debug will kick in. See this function's doc for more
|
||||||
|
;; information.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
(require 'nrepl-client) ; `nrepl--mark-id-completed'
|
||||||
|
(require 'cider-eval)
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'cider-inspector)
|
||||||
|
(require 'cider-browse-ns)
|
||||||
|
(require 'cider-common)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'seq)
|
||||||
|
(require 'spinner)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Customization
|
||||||
|
(defgroup cider-debug nil
|
||||||
|
"Presentation and behaviour of the cider debugger."
|
||||||
|
:prefix "cider-debug-"
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defface cider-debug-code-overlay-face
|
||||||
|
'((((class color) (background light)) :background "grey80")
|
||||||
|
(((class color) (background dark)) :background "grey30"))
|
||||||
|
"Face used to mark code being debugged."
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.9.1"))
|
||||||
|
|
||||||
|
(defface cider-debug-prompt-face
|
||||||
|
'((t :underline t :inherit font-lock-builtin-face))
|
||||||
|
"Face used to highlight keys in the debug prompt."
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defface cider-enlightened-face
|
||||||
|
'((((class color) (background light)) :inherit cider-result-overlay-face
|
||||||
|
:box (:color "darkorange" :line-width -1))
|
||||||
|
(((class color) (background dark)) :inherit cider-result-overlay-face
|
||||||
|
;; "#dd0" is a dimmer yellow.
|
||||||
|
:box (:color "#990" :line-width -1)))
|
||||||
|
"Face used to mark enlightened sexps and their return values."
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.11.0"))
|
||||||
|
|
||||||
|
(defface cider-enlightened-local-face
|
||||||
|
'((((class color) (background light)) :weight bold :foreground "darkorange")
|
||||||
|
(((class color) (background dark)) :weight bold :foreground "yellow"))
|
||||||
|
"Face used to mark enlightened locals (not their values)."
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.11.0"))
|
||||||
|
|
||||||
|
(defcustom cider-debug-prompt 'overlay
|
||||||
|
"If and where to show the keys while debugging.
|
||||||
|
If `minibuffer', show it in the minibuffer along with the return value.
|
||||||
|
If `overlay', show it in an overlay above the current function.
|
||||||
|
If t, do both.
|
||||||
|
If nil, don't list available keys at all."
|
||||||
|
:type '(choice (const :tag "Show in minibuffer" minibuffer)
|
||||||
|
(const :tag "Show above function" overlay)
|
||||||
|
(const :tag "Show in both places" t)
|
||||||
|
(const :tag "Don't list keys" nil))
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-debug-use-overlays t
|
||||||
|
"Whether to higlight debugging information with overlays.
|
||||||
|
Takes the same possible values as `cider-use-overlays', but only applies to
|
||||||
|
values displayed during debugging sessions.
|
||||||
|
To control the overlay that lists possible keys above the current function,
|
||||||
|
configure `cider-debug-prompt' instead."
|
||||||
|
:type '(choice (const :tag "End of line" t)
|
||||||
|
(const :tag "Bottom of screen" nil)
|
||||||
|
(const :tag "Both" both))
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.9.1"))
|
||||||
|
|
||||||
|
(defcustom cider-debug-print-level 10
|
||||||
|
"The print level for values displayed by the debugger.
|
||||||
|
This variable must be set before starting the repl connection."
|
||||||
|
:type '(choice (const :tag "No limit" nil)
|
||||||
|
(integer :tag "Max depth" 10))
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-debug-print-length 10
|
||||||
|
"The print length for values displayed by the debugger.
|
||||||
|
This variable must be set before starting the repl connection."
|
||||||
|
:type '(choice (const :tag "No limit" nil)
|
||||||
|
(integer :tag "Max depth" 10))
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Implementation
|
||||||
|
(defun cider-browse-instrumented-defs ()
|
||||||
|
"List all instrumented definitions."
|
||||||
|
(interactive)
|
||||||
|
(if-let* ((all (thread-first (cider-nrepl-send-sync-request '("op" "debug-instrumented-defs"))
|
||||||
|
(nrepl-dict-get "list"))))
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-browse-ns-buffer t)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(erase-buffer)
|
||||||
|
(dolist (list all)
|
||||||
|
(let* ((ns (car list))
|
||||||
|
(ns-vars-with-meta (cider-sync-request:ns-vars-with-meta ns))
|
||||||
|
;; seq of metadata maps of the instrumented vars
|
||||||
|
(instrumented-meta (mapcar (apply-partially #'nrepl-dict-get ns-vars-with-meta)
|
||||||
|
(cdr list))))
|
||||||
|
(cider-browse-ns--list (current-buffer) ns
|
||||||
|
(seq-mapn #'cider-browse-ns--properties
|
||||||
|
(cdr list)
|
||||||
|
instrumented-meta)
|
||||||
|
|
||||||
|
ns 'noerase)
|
||||||
|
(goto-char (point-max))
|
||||||
|
(insert "\n"))))
|
||||||
|
(goto-char (point-min)))
|
||||||
|
(message "No currently instrumented definitions")))
|
||||||
|
|
||||||
|
(defun cider--debug-response-handler (response)
|
||||||
|
"Handles RESPONSE from the cider.debug middleware."
|
||||||
|
(nrepl-dbind-response response (status id causes)
|
||||||
|
(when (member "enlighten" status)
|
||||||
|
(cider--handle-enlighten response))
|
||||||
|
(when (or (member "eval-error" status)
|
||||||
|
(member "stack" status))
|
||||||
|
;; TODO: Make the error buffer a bit friendlier when we're just printing
|
||||||
|
;; the stack.
|
||||||
|
(cider--render-stacktrace-causes causes))
|
||||||
|
(when (member "need-debug-input" status)
|
||||||
|
(cider--handle-debug response))
|
||||||
|
(when (member "done" status)
|
||||||
|
(nrepl--mark-id-completed id))))
|
||||||
|
|
||||||
|
(defun cider--debug-init-connection ()
|
||||||
|
"Initialize a connection with the cider.debug middleware."
|
||||||
|
(cider-nrepl-send-request
|
||||||
|
(nconc '("op" "init-debugger")
|
||||||
|
(when cider-debug-print-level
|
||||||
|
`("print-level" ,cider-debug-print-level))
|
||||||
|
(when cider-debug-print-length
|
||||||
|
`("print-length" ,cider-debug-print-length)))
|
||||||
|
#'cider--debug-response-handler))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Debugging overlays
|
||||||
|
(defconst cider--fringe-arrow-string
|
||||||
|
#("." 0 1 (display (left-fringe right-triangle)))
|
||||||
|
"Used as an overlay's before-string prop to place a fringe arrow.")
|
||||||
|
|
||||||
|
(defun cider--debug-display-result-overlay (value)
|
||||||
|
"Place an overlay at point displaying VALUE."
|
||||||
|
(when cider-debug-use-overlays
|
||||||
|
;; This is cosmetic, let's ensure it doesn't break the session no matter what.
|
||||||
|
(ignore-errors
|
||||||
|
;; Result
|
||||||
|
(cider--make-result-overlay (cider-font-lock-as-clojure value)
|
||||||
|
:where (point-marker)
|
||||||
|
:type 'debug-result
|
||||||
|
'before-string cider--fringe-arrow-string)
|
||||||
|
;; Code
|
||||||
|
(cider--make-overlay (save-excursion (clojure-backward-logical-sexp 1) (point))
|
||||||
|
(point) 'debug-code
|
||||||
|
'face 'cider-debug-code-overlay-face
|
||||||
|
;; Higher priority than `show-paren'.
|
||||||
|
'priority 2000))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Minor mode
|
||||||
|
(defvar-local cider--debug-mode-commands-dict nil
|
||||||
|
"An nrepl-dict from keys to debug commands.
|
||||||
|
Autogenerated by `cider--turn-on-debug-mode'.")
|
||||||
|
|
||||||
|
(defvar-local cider--debug-mode-response nil
|
||||||
|
"Response that triggered current debug session.
|
||||||
|
Set by `cider--turn-on-debug-mode'.")
|
||||||
|
|
||||||
|
(defcustom cider-debug-display-locals nil
|
||||||
|
"If non-nil, local variables are displayed while debugging.
|
||||||
|
Can be toggled at any time with `\\[cider-debug-toggle-locals]'."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider-debug
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defun cider--debug-format-locals-list (locals)
|
||||||
|
"Return a string description of list LOCALS.
|
||||||
|
Each element of LOCALS should be a list of at least two elements."
|
||||||
|
(if locals
|
||||||
|
(let ((left-col-width
|
||||||
|
;; To right-indent the variable names.
|
||||||
|
(apply #'max (mapcar (lambda (l) (string-width (car l))) locals))))
|
||||||
|
;; A format string to build a format string. :-P
|
||||||
|
(mapconcat (lambda (l) (format (format " %%%ds: %%s\n" left-col-width)
|
||||||
|
(propertize (car l) 'face 'font-lock-variable-name-face)
|
||||||
|
(cider-font-lock-as-clojure (cadr l))))
|
||||||
|
locals ""))
|
||||||
|
""))
|
||||||
|
|
||||||
|
(defun cider--debug-prompt (command-dict)
|
||||||
|
"Return prompt to display for COMMAND-DICT."
|
||||||
|
;; Force `default' face, otherwise the overlay "inherits" the face of the text
|
||||||
|
;; after it.
|
||||||
|
(format (propertize "%s\n" 'face 'default)
|
||||||
|
(string-join
|
||||||
|
(nrepl-dict-map (lambda (char cmd)
|
||||||
|
(when-let* ((pos (cl-search char cmd)))
|
||||||
|
(put-text-property pos (1+ pos) 'face 'cider-debug-prompt-face cmd))
|
||||||
|
cmd)
|
||||||
|
command-dict)
|
||||||
|
" ")))
|
||||||
|
|
||||||
|
(defvar-local cider--debug-prompt-overlay nil)
|
||||||
|
|
||||||
|
(defun cider--debug-mode-redisplay ()
|
||||||
|
"Display the input prompt to the user."
|
||||||
|
(nrepl-dbind-response cider--debug-mode-response (debug-value input-type locals)
|
||||||
|
(when (or (eq cider-debug-prompt t)
|
||||||
|
(eq cider-debug-prompt 'overlay))
|
||||||
|
(if (overlayp cider--debug-prompt-overlay)
|
||||||
|
(overlay-put cider--debug-prompt-overlay
|
||||||
|
'before-string (cider--debug-prompt input-type))
|
||||||
|
(setq cider--debug-prompt-overlay
|
||||||
|
(cider--make-overlay
|
||||||
|
(max (car (cider-defun-at-point 'bounds))
|
||||||
|
(window-start))
|
||||||
|
nil 'debug-prompt
|
||||||
|
'before-string (cider--debug-prompt input-type)))))
|
||||||
|
(let* ((value (concat " " cider-eval-result-prefix
|
||||||
|
(cider-font-lock-as-clojure
|
||||||
|
(or debug-value "#unknown#"))))
|
||||||
|
(to-display
|
||||||
|
(concat (when cider-debug-display-locals
|
||||||
|
(cider--debug-format-locals-list locals))
|
||||||
|
(when (or (eq cider-debug-prompt t)
|
||||||
|
(eq cider-debug-prompt 'minibuffer))
|
||||||
|
(cider--debug-prompt input-type))
|
||||||
|
(when (or (not cider-debug-use-overlays)
|
||||||
|
(eq cider-debug-use-overlays 'both))
|
||||||
|
value))))
|
||||||
|
(if (> (string-width to-display) 0)
|
||||||
|
(message "%s" to-display)
|
||||||
|
;; If there's nothing to display in the minibuffer. Just send the value
|
||||||
|
;; to the Messages buffer.
|
||||||
|
(message "%s" value)
|
||||||
|
(message nil)))))
|
||||||
|
|
||||||
|
(defun cider-debug-toggle-locals ()
|
||||||
|
"Toggle display of local variables."
|
||||||
|
(interactive)
|
||||||
|
(setq cider-debug-display-locals (not cider-debug-display-locals))
|
||||||
|
(cider--debug-mode-redisplay))
|
||||||
|
|
||||||
|
(defun cider--debug-lexical-eval (key form &optional callback _point)
|
||||||
|
"Eval FORM in the lexical context of debug session given by KEY.
|
||||||
|
Do nothing if CALLBACK is provided.
|
||||||
|
Designed to be used as `cider-interactive-eval-override' and called instead
|
||||||
|
of `cider-interactive-eval' in debug sessions."
|
||||||
|
;; The debugger uses its own callback, so if the caller is passing a callback
|
||||||
|
;; we return nil and let `cider-interactive-eval' do its thing.
|
||||||
|
(unless callback
|
||||||
|
(cider-debug-mode-send-reply (format "{:response :eval, :code %s}" form)
|
||||||
|
key)
|
||||||
|
t))
|
||||||
|
|
||||||
|
(defvar cider--debug-mode-tool-bar-map
|
||||||
|
(let ((tool-bar-map (make-sparse-keymap)))
|
||||||
|
(tool-bar-add-item "right-arrow" #'cider-debug-mode-send-reply :next :label "Next step")
|
||||||
|
(tool-bar-add-item "next-node" #'cider-debug-mode-send-reply :continue :label "Continue non-stop")
|
||||||
|
(tool-bar-add-item "jump-to" #'cider-debug-mode-send-reply :out :label "Out of sexp")
|
||||||
|
(tool-bar-add-item "exit" #'cider-debug-mode-send-reply :quit :label "Quit")
|
||||||
|
tool-bar-map))
|
||||||
|
|
||||||
|
(defvar cider--debug-mode-map)
|
||||||
|
|
||||||
|
(define-minor-mode cider--debug-mode
|
||||||
|
"Mode active during debug sessions.
|
||||||
|
In order to work properly, this mode must be activated by
|
||||||
|
`cider--turn-on-debug-mode'."
|
||||||
|
nil " DEBUG" '()
|
||||||
|
(if cider--debug-mode
|
||||||
|
(if cider--debug-mode-response
|
||||||
|
(nrepl-dbind-response cider--debug-mode-response (input-type)
|
||||||
|
;; A debug session is an ongoing eval, but it's annoying to have the
|
||||||
|
;; spinner spinning while you debug.
|
||||||
|
(when spinner-current (spinner-stop))
|
||||||
|
(setq-local tool-bar-map cider--debug-mode-tool-bar-map)
|
||||||
|
(add-hook 'kill-buffer-hook #'cider--debug-quit nil 'local)
|
||||||
|
(add-hook 'before-revert-hook #'cider--debug-quit nil 'local)
|
||||||
|
(unless (consp input-type)
|
||||||
|
(error "Activated debug-mode on a message not asking for commands: %s" cider--debug-mode-response))
|
||||||
|
;; Integrate with eval commands.
|
||||||
|
(setq cider-interactive-eval-override
|
||||||
|
(apply-partially #'cider--debug-lexical-eval
|
||||||
|
(nrepl-dict-get cider--debug-mode-response "key")))
|
||||||
|
;; Set the keymap.
|
||||||
|
(nrepl-dict-map (lambda (char _cmd)
|
||||||
|
(unless (string= char "h") ; `here' needs a special command.
|
||||||
|
(define-key cider--debug-mode-map char #'cider-debug-mode-send-reply))
|
||||||
|
(when (string= char "o")
|
||||||
|
(define-key cider--debug-mode-map (upcase char) #'cider-debug-mode-send-reply)))
|
||||||
|
input-type)
|
||||||
|
(setq cider--debug-mode-commands-dict input-type)
|
||||||
|
;; Show the prompt.
|
||||||
|
(cider--debug-mode-redisplay)
|
||||||
|
;; If a sync request is ongoing, the user can't act normally to
|
||||||
|
;; provide input, so we enter `recursive-edit'.
|
||||||
|
(when nrepl-ongoing-sync-request
|
||||||
|
(recursive-edit)))
|
||||||
|
(cider--debug-mode -1)
|
||||||
|
(if (called-interactively-p 'any)
|
||||||
|
(user-error (substitute-command-keys "Don't call this mode manually, use `\\[universal-argument] \\[cider-eval-defun-at-point]' instead"))
|
||||||
|
(error "Attempt to activate `cider--debug-mode' without setting `cider--debug-mode-response' first")))
|
||||||
|
(setq cider-interactive-eval-override nil)
|
||||||
|
(setq cider--debug-mode-commands-dict nil)
|
||||||
|
(setq cider--debug-mode-response nil)
|
||||||
|
;; We wait a moment before clearing overlays and the read-onlyness, so that
|
||||||
|
;; cider-nrepl has a chance to send the next message, and so that the user
|
||||||
|
;; doesn't accidentally hit `n' between two messages (thus editing the code).
|
||||||
|
(when-let* ((proc (unless nrepl-ongoing-sync-request
|
||||||
|
(get-buffer-process (cider-current-repl)))))
|
||||||
|
(accept-process-output proc 1))
|
||||||
|
(unless cider--debug-mode
|
||||||
|
(setq buffer-read-only nil)
|
||||||
|
(cider--debug-remove-overlays (current-buffer)))
|
||||||
|
(when nrepl-ongoing-sync-request
|
||||||
|
(ignore-errors (exit-recursive-edit)))))
|
||||||
|
|
||||||
|
;;; Bind the `:here` command to both h and H, because it behaves differently if
|
||||||
|
;;; invoked with an uppercase letter.
|
||||||
|
(define-key cider--debug-mode-map "h" #'cider-debug-move-here)
|
||||||
|
(define-key cider--debug-mode-map "H" #'cider-debug-move-here)
|
||||||
|
|
||||||
|
(defun cider--debug-remove-overlays (&optional buffer)
|
||||||
|
"Remove CIDER debug overlays from BUFFER if variable `cider--debug-mode' is nil."
|
||||||
|
(when (or (not buffer) (buffer-live-p buffer))
|
||||||
|
(with-current-buffer (or buffer (current-buffer))
|
||||||
|
(unless cider--debug-mode
|
||||||
|
(kill-local-variable 'tool-bar-map)
|
||||||
|
(remove-overlays nil nil 'category 'debug-result)
|
||||||
|
(remove-overlays nil nil 'category 'debug-code)
|
||||||
|
(setq cider--debug-prompt-overlay nil)
|
||||||
|
(remove-overlays nil nil 'category 'debug-prompt)))))
|
||||||
|
|
||||||
|
(defun cider--debug-set-prompt (value)
|
||||||
|
"Set `cider-debug-prompt' to VALUE, then redisplay."
|
||||||
|
(setq cider-debug-prompt value)
|
||||||
|
(cider--debug-mode-redisplay))
|
||||||
|
|
||||||
|
(easy-menu-define cider-debug-mode-menu cider--debug-mode-map
|
||||||
|
"Menu for CIDER debug mode"
|
||||||
|
`("CIDER Debugger"
|
||||||
|
["Next step" (cider-debug-mode-send-reply ":next") :keys "n"]
|
||||||
|
["Continue non-stop" (cider-debug-mode-send-reply ":continue") :keys "c"]
|
||||||
|
["Move out of sexp" (cider-debug-mode-send-reply ":out") :keys "o"]
|
||||||
|
["Quit" (cider-debug-mode-send-reply ":quit") :keys "q"]
|
||||||
|
"--"
|
||||||
|
["Evaluate in current scope" (cider-debug-mode-send-reply ":eval") :keys "e"]
|
||||||
|
["Inject value" (cider-debug-mode-send-reply ":inject") :keys "i"]
|
||||||
|
["Inspect value" (cider-debug-mode-send-reply ":inspect")]
|
||||||
|
["Inspect local variables" (cider-debug-mode-send-reply ":locals") :keys "l"]
|
||||||
|
"--"
|
||||||
|
("Configure keys prompt"
|
||||||
|
["Don't show keys" (cider--debug-set-prompt nil) :style toggle :selected (eq cider-debug-prompt nil)]
|
||||||
|
["Show in minibuffer" (cider--debug-set-prompt 'minibuffer) :style toggle :selected (eq cider-debug-prompt 'minibuffer)]
|
||||||
|
["Show above function" (cider--debug-set-prompt 'overlay) :style toggle :selected (eq cider-debug-prompt 'overlay)]
|
||||||
|
["Show in both places" (cider--debug-set-prompt t) :style toggle :selected (eq cider-debug-prompt t)]
|
||||||
|
"--"
|
||||||
|
["List locals" cider-debug-toggle-locals :style toggle :selected cider-debug-display-locals])
|
||||||
|
["Customize" (customize-group 'cider-debug)]))
|
||||||
|
|
||||||
|
(defun cider--uppercase-command-p ()
|
||||||
|
"Return non-nil if the last command was uppercase letter."
|
||||||
|
(ignore-errors
|
||||||
|
(let ((case-fold-search nil))
|
||||||
|
(string-match "[[:upper:]]" (string last-command-event)))))
|
||||||
|
|
||||||
|
(defun cider-debug-mode-send-reply (command &optional key force)
|
||||||
|
"Reply to the message that started current bufer's debugging session.
|
||||||
|
COMMAND is sent as the input option. KEY can be provided to reply to a
|
||||||
|
specific message. If FORCE is non-nil, send a \"force?\" argument in the
|
||||||
|
message."
|
||||||
|
(interactive (list
|
||||||
|
(if (symbolp last-command-event)
|
||||||
|
(symbol-name last-command-event)
|
||||||
|
(ignore-errors
|
||||||
|
(concat ":" (nrepl-dict-get cider--debug-mode-commands-dict
|
||||||
|
(downcase (string last-command-event))))))
|
||||||
|
nil
|
||||||
|
(cider--uppercase-command-p)))
|
||||||
|
(when (and (string-prefix-p ":" command) force)
|
||||||
|
(setq command (format "{:response %s :force? true}" command)))
|
||||||
|
(cider-nrepl-send-unhandled-request
|
||||||
|
`("op" "debug-input"
|
||||||
|
"input" ,(or command ":quit")
|
||||||
|
"key" ,(or key (nrepl-dict-get cider--debug-mode-response "key"))))
|
||||||
|
(ignore-errors (cider--debug-mode -1)))
|
||||||
|
|
||||||
|
(defun cider--debug-quit ()
|
||||||
|
"Send a :quit reply to the debugger. Used in hooks."
|
||||||
|
(when cider--debug-mode
|
||||||
|
(cider-debug-mode-send-reply ":quit")
|
||||||
|
(message "Quitting debug session")))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Movement logic
|
||||||
|
(defconst cider--debug-buffer-format "*cider-debug %s*")
|
||||||
|
|
||||||
|
(defun cider--debug-trim-code (code)
|
||||||
|
"Remove whitespace and reader macros from the start of the CODE.
|
||||||
|
Return trimmed CODE."
|
||||||
|
(replace-regexp-in-string "\\`#[a-z]+[\n\r[:blank:]]*" "" code))
|
||||||
|
|
||||||
|
(declare-function cider-set-buffer-ns "cider-mode")
|
||||||
|
(defun cider--initialize-debug-buffer (code ns id &optional reason)
|
||||||
|
"Create a new debugging buffer with CODE and namespace NS.
|
||||||
|
ID is the id of the message that instrumented CODE.
|
||||||
|
REASON is a keyword describing why this buffer was necessary."
|
||||||
|
(let ((buffer-name (format cider--debug-buffer-format id)))
|
||||||
|
(if-let* ((buffer (get-buffer buffer-name)))
|
||||||
|
(cider-popup-buffer-display buffer 'select)
|
||||||
|
(with-current-buffer (cider-popup-buffer buffer-name 'select
|
||||||
|
#'clojure-mode 'ancillary)
|
||||||
|
(cider-set-buffer-ns ns)
|
||||||
|
(setq buffer-undo-list nil)
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(buffer-undo-list t))
|
||||||
|
(erase-buffer)
|
||||||
|
(insert (format "%s" (cider--debug-trim-code code)))
|
||||||
|
(when code
|
||||||
|
(insert "\n\n\n;; We had to create this temporary buffer because we couldn't find the original definition. That probably happened because "
|
||||||
|
reason
|
||||||
|
".")
|
||||||
|
(fill-paragraph))
|
||||||
|
(cider--font-lock-ensure)
|
||||||
|
(set-buffer-modified-p nil))))
|
||||||
|
(switch-to-buffer buffer-name)
|
||||||
|
(goto-char (point-min))))
|
||||||
|
|
||||||
|
(defun cider--debug-goto-keyval (key)
|
||||||
|
"Find KEY in current sexp or return nil."
|
||||||
|
(when-let* ((limit (ignore-errors (save-excursion (up-list) (point)))))
|
||||||
|
(search-forward-regexp (concat "\\_<" (regexp-quote key) "\\_>")
|
||||||
|
limit 'noerror)))
|
||||||
|
|
||||||
|
(defun cider--debug-move-point (coordinates)
|
||||||
|
"Place point on after the sexp specified by COORDINATES.
|
||||||
|
COORDINATES is a list of integers that specify how to navigate into the
|
||||||
|
sexp that is after point when this function is called.
|
||||||
|
|
||||||
|
As an example, a COORDINATES list of '(1 0 2) means:
|
||||||
|
- enter next sexp then `forward-sexp' once,
|
||||||
|
- enter next sexp,
|
||||||
|
- enter next sexp then `forward-sexp' twice.
|
||||||
|
|
||||||
|
In the following snippet, this takes us to the (* x 2) sexp (point is left
|
||||||
|
at the end of the given sexp).
|
||||||
|
|
||||||
|
(letfn [(twice [x]
|
||||||
|
(* x 2))]
|
||||||
|
(twice 15))
|
||||||
|
|
||||||
|
In addition to numbers, a coordinate can be a string. This string names the
|
||||||
|
key of a map, and it means \"go to the value associated with this key\"."
|
||||||
|
(condition-case-unless-debug nil
|
||||||
|
;; Navigate through sexps inside the sexp.
|
||||||
|
(let ((in-syntax-quote nil))
|
||||||
|
(while coordinates
|
||||||
|
(while (clojure--looking-at-non-logical-sexp)
|
||||||
|
(forward-sexp))
|
||||||
|
;; An `@x` is read as (deref x), so we pop coordinates once to account
|
||||||
|
;; for the extra depth, and move past the @ char.
|
||||||
|
(if (eq ?@ (char-after))
|
||||||
|
(progn (forward-char 1)
|
||||||
|
(pop coordinates))
|
||||||
|
(down-list)
|
||||||
|
;; Are we entering a syntax-quote?
|
||||||
|
(when (looking-back "`\\(#{\\|[{[(]\\)" (line-beginning-position))
|
||||||
|
;; If we are, this affects all nested structures until the next `~',
|
||||||
|
;; so we set this variable for all following steps in the loop.
|
||||||
|
(setq in-syntax-quote t))
|
||||||
|
(when in-syntax-quote
|
||||||
|
;; A `(. .) is read as (seq (concat (list .) (list .))). This pops
|
||||||
|
;; the `seq', since the real coordinates are inside the `concat'.
|
||||||
|
(pop coordinates)
|
||||||
|
;; Non-list seqs like `[] and `{} are read with
|
||||||
|
;; an extra (apply vector ...), so pop it too.
|
||||||
|
(unless (eq ?\( (char-before))
|
||||||
|
(pop coordinates)))
|
||||||
|
;; #(...) is read as (fn* ([] ...)), so we patch that here.
|
||||||
|
(when (looking-back "#(" (line-beginning-position))
|
||||||
|
(pop coordinates))
|
||||||
|
(if coordinates
|
||||||
|
(let ((next (pop coordinates)))
|
||||||
|
(when in-syntax-quote
|
||||||
|
;; We're inside the `concat' form, but we need to discard the
|
||||||
|
;; actual `concat' symbol from the coordinate.
|
||||||
|
(setq next (1- next)))
|
||||||
|
;; String coordinates are map keys.
|
||||||
|
(if (stringp next)
|
||||||
|
(cider--debug-goto-keyval next)
|
||||||
|
(clojure-forward-logical-sexp next)
|
||||||
|
(when in-syntax-quote
|
||||||
|
(clojure-forward-logical-sexp 1)
|
||||||
|
(forward-sexp -1)
|
||||||
|
;; Here a syntax-quote is ending.
|
||||||
|
(let ((match (when (looking-at "~@?")
|
||||||
|
(match-string 0))))
|
||||||
|
(when match
|
||||||
|
(setq in-syntax-quote nil))
|
||||||
|
;; A `~@' is read as the object itself, so we don't pop
|
||||||
|
;; anything.
|
||||||
|
(unless (equal "~@" match)
|
||||||
|
;; Anything else (including a `~') is read as a `list'
|
||||||
|
;; form inside the `concat', so we need to pop the list
|
||||||
|
;; from the coordinates.
|
||||||
|
(pop coordinates))))))
|
||||||
|
;; If that extra pop was the last coordinate, this represents the
|
||||||
|
;; entire #(...), so we should move back out.
|
||||||
|
(backward-up-list))))
|
||||||
|
;; Place point at the end of instrumented sexp.
|
||||||
|
(clojure-forward-logical-sexp 1))
|
||||||
|
;; Avoid throwing actual errors, since this happens on every breakpoint.
|
||||||
|
(error (message "Can't find instrumented sexp, did you edit the source?"))))
|
||||||
|
|
||||||
|
(defun cider--debug-position-for-code (code)
|
||||||
|
"Return non-nil if point is roughly before CODE.
|
||||||
|
This might move point one line above."
|
||||||
|
(or (looking-at-p (regexp-quote code))
|
||||||
|
(let ((trimmed (regexp-quote (cider--debug-trim-code code))))
|
||||||
|
(or (looking-at-p trimmed)
|
||||||
|
;; If this is a fake #dbg injected by `C-u
|
||||||
|
;; C-M-x', then the sexp we want is actually on
|
||||||
|
;; the line above.
|
||||||
|
(progn (forward-line -1)
|
||||||
|
(looking-at-p trimmed))))))
|
||||||
|
|
||||||
|
(defun cider--debug-find-source-position (response &optional create-if-needed)
|
||||||
|
"Return a marker of the position after the sexp specified in RESPONSE.
|
||||||
|
This marker might be in a different buffer! If the sexp can't be
|
||||||
|
found (file that contains the code is no longer visited or has been
|
||||||
|
edited), return nil. However, if CREATE-IF-NEEDED is non-nil, a new buffer
|
||||||
|
is created in this situation and the return value is never nil.
|
||||||
|
|
||||||
|
Follow the \"line\" and \"column\" entries in RESPONSE, and check whether
|
||||||
|
the code at point matches the \"code\" entry in RESPONSE. If it doesn't,
|
||||||
|
assume that the code in this file has been edited, and create a temp buffer
|
||||||
|
holding the original code.
|
||||||
|
Either way, navigate inside the code by following the \"coor\" entry which
|
||||||
|
is a coordinate measure in sexps."
|
||||||
|
(nrepl-dbind-response response (code file line column ns original-id coor)
|
||||||
|
(when (or code (and file line column))
|
||||||
|
;; This is for restoring current-buffer.
|
||||||
|
(save-excursion
|
||||||
|
(let ((out))
|
||||||
|
;; We prefer in-source debugging.
|
||||||
|
(when-let* ((buf (and file line column
|
||||||
|
(ignore-errors
|
||||||
|
(cider--find-buffer-for-file file)))))
|
||||||
|
;; The logic here makes it hard to use `with-current-buffer'.
|
||||||
|
(with-current-buffer buf
|
||||||
|
;; This is for restoring point inside buf.
|
||||||
|
(save-excursion
|
||||||
|
;; Get to the proper line & column in the file
|
||||||
|
(forward-line (- line (line-number-at-pos)))
|
||||||
|
(move-to-column column)
|
||||||
|
;; Check if it worked
|
||||||
|
(when (cider--debug-position-for-code code)
|
||||||
|
;; Find the desired sexp.
|
||||||
|
(cider--debug-move-point coor)
|
||||||
|
(setq out (point-marker))))))
|
||||||
|
;; But we can create a temp buffer if that fails.
|
||||||
|
(or out
|
||||||
|
(when create-if-needed
|
||||||
|
(cider--initialize-debug-buffer
|
||||||
|
code ns original-id
|
||||||
|
(if (and line column)
|
||||||
|
"you edited the code"
|
||||||
|
"your tools.nrepl version is older than 0.2.11"))
|
||||||
|
(save-excursion
|
||||||
|
(cider--debug-move-point coor)
|
||||||
|
(point-marker)))))))))
|
||||||
|
|
||||||
|
(defun cider--handle-debug (response)
|
||||||
|
"Handle debugging notification.
|
||||||
|
RESPONSE is a message received from the nrepl describing the input
|
||||||
|
needed. It is expected to contain at least \"key\", \"input-type\", and
|
||||||
|
\"prompt\", and possibly other entries depending on the input-type."
|
||||||
|
(nrepl-dbind-response response (debug-value key input-type prompt inspect)
|
||||||
|
(condition-case-unless-debug e
|
||||||
|
(progn
|
||||||
|
(pcase input-type
|
||||||
|
("expression" (cider-debug-mode-send-reply
|
||||||
|
(condition-case nil
|
||||||
|
(cider-read-from-minibuffer
|
||||||
|
(or prompt "Expression: "))
|
||||||
|
(quit "nil"))
|
||||||
|
key))
|
||||||
|
((pred sequencep)
|
||||||
|
(let* ((marker (cider--debug-find-source-position response 'create-if-needed)))
|
||||||
|
(pop-to-buffer (marker-buffer marker))
|
||||||
|
(goto-char marker))
|
||||||
|
;; The overlay code relies on window boundaries, but point could have been
|
||||||
|
;; moved outside the window by some other code. Redisplay here to ensure the
|
||||||
|
;; visible window includes point.
|
||||||
|
(redisplay)
|
||||||
|
;; Remove overlays AFTER redisplaying! Otherwise there's a visible
|
||||||
|
;; flicker even if we immediately recreate the overlays.
|
||||||
|
(cider--debug-remove-overlays)
|
||||||
|
(when cider-debug-use-overlays
|
||||||
|
(cider--debug-display-result-overlay debug-value))
|
||||||
|
(setq cider--debug-mode-response response)
|
||||||
|
(cider--debug-mode 1)))
|
||||||
|
(when inspect
|
||||||
|
(cider-inspector--render-value inspect)))
|
||||||
|
;; If something goes wrong, we send a "quit" or the session hangs.
|
||||||
|
(error (cider-debug-mode-send-reply ":quit" key)
|
||||||
|
(message "Error encountered while handling the debug message: %S" e)))))
|
||||||
|
|
||||||
|
(defun cider--handle-enlighten (response)
|
||||||
|
"Handle an enlighten notification.
|
||||||
|
RESPONSE is a message received from the nrepl describing the value and
|
||||||
|
coordinates of a sexp. Create an overlay after the specified sexp
|
||||||
|
displaying its value."
|
||||||
|
(when-let* ((marker (cider--debug-find-source-position response)))
|
||||||
|
(with-current-buffer (marker-buffer marker)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char marker)
|
||||||
|
(clojure-backward-logical-sexp 1)
|
||||||
|
(nrepl-dbind-response response (debug-value erase-previous)
|
||||||
|
(when erase-previous
|
||||||
|
(remove-overlays (point) marker 'category 'enlighten))
|
||||||
|
(when debug-value
|
||||||
|
(if (memq (char-before marker) '(?\) ?\] ?}))
|
||||||
|
;; Enlightening a sexp looks like a regular return value, except
|
||||||
|
;; for a different border.
|
||||||
|
(cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
|
||||||
|
:where (cons marker marker)
|
||||||
|
:type 'enlighten
|
||||||
|
:prepend-face 'cider-enlightened-face)
|
||||||
|
;; Enlightening a symbol uses a more abbreviated format. The
|
||||||
|
;; result face is the same as a regular result, but we also color
|
||||||
|
;; the symbol with `cider-enlightened-local-face'.
|
||||||
|
(cider--make-result-overlay (cider-font-lock-as-clojure debug-value)
|
||||||
|
:format "%s"
|
||||||
|
:where (cons (point) marker)
|
||||||
|
:type 'enlighten
|
||||||
|
'face 'cider-enlightened-local-face))))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Move here command
|
||||||
|
;; This is the inverse of `cider--debug-move-point'. However, that algorithm is
|
||||||
|
;; complicated, and trying to code its inverse would probably be insane.
|
||||||
|
;; Instead, we find the coordinate by trial and error.
|
||||||
|
(defun cider--debug-find-coordinates-for-point (target &optional list-so-far)
|
||||||
|
"Return the coordinates list for reaching TARGET.
|
||||||
|
Assumes that the next thing after point is a logical Clojure sexp and that
|
||||||
|
TARGET is inside it. The returned list is suitable for use in
|
||||||
|
`cider--debug-move-point'. LIST-SO-FAR is for internal use."
|
||||||
|
(when (looking-at (rx (or "(" "[" "#{" "{")))
|
||||||
|
(let ((starting-point (point)))
|
||||||
|
(unwind-protect
|
||||||
|
(let ((x 0))
|
||||||
|
;; Keep incrementing the last coordinate until we've moved
|
||||||
|
;; past TARGET.
|
||||||
|
(while (condition-case nil
|
||||||
|
(progn (goto-char starting-point)
|
||||||
|
(cider--debug-move-point (append list-so-far (list x)))
|
||||||
|
(< (point) target))
|
||||||
|
;; Not a valid coordinate. Move back a step and stop here.
|
||||||
|
(scan-error (setq x (1- x))
|
||||||
|
nil))
|
||||||
|
(setq x (1+ x)))
|
||||||
|
(setq list-so-far (append list-so-far (list x)))
|
||||||
|
;; We have moved past TARGET, now determine whether we should
|
||||||
|
;; stop, or if target is deeper inside the previous sexp.
|
||||||
|
(if (or (= target (point))
|
||||||
|
(progn (forward-sexp -1)
|
||||||
|
(<= target (point))))
|
||||||
|
list-so-far
|
||||||
|
(goto-char starting-point)
|
||||||
|
(cider--debug-find-coordinates-for-point target list-so-far)))
|
||||||
|
;; `unwind-protect' clause.
|
||||||
|
(goto-char starting-point)))))
|
||||||
|
|
||||||
|
(defun cider-debug-move-here (&optional force)
|
||||||
|
"Skip any breakpoints up to point.
|
||||||
|
The boolean value of FORCE will be sent in the reply."
|
||||||
|
(interactive (list (cider--uppercase-command-p)))
|
||||||
|
(unless cider--debug-mode
|
||||||
|
(user-error "`cider-debug-move-here' only makes sense during a debug session"))
|
||||||
|
(let ((here (point)))
|
||||||
|
(nrepl-dbind-response cider--debug-mode-response (line column)
|
||||||
|
(if (and line column (buffer-file-name))
|
||||||
|
(progn ;; Get to the proper line & column in the file
|
||||||
|
(forward-line (1- (- line (line-number-at-pos))))
|
||||||
|
(move-to-column column))
|
||||||
|
(beginning-of-defun))
|
||||||
|
;; Is HERE inside the sexp being debugged?
|
||||||
|
(when (or (< here (point))
|
||||||
|
(save-excursion
|
||||||
|
(forward-sexp 1)
|
||||||
|
(> here (point))))
|
||||||
|
(user-error "Point is outside the sexp being debugged"))
|
||||||
|
;; Move forward untill start of sexp.
|
||||||
|
(comment-normalize-vars)
|
||||||
|
(comment-forward (point-max))
|
||||||
|
;; Find the coordinate and send it.
|
||||||
|
(cider-debug-mode-send-reply
|
||||||
|
(format "{:response :here, :coord %s :force? %s}"
|
||||||
|
(cider--debug-find-coordinates-for-point here)
|
||||||
|
(if force "true" "false"))))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; User commands
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-debug-defun-at-point ()
|
||||||
|
"Instrument the \"top-level\" expression at point.
|
||||||
|
If it is a defn, dispatch the instrumented definition. Otherwise,
|
||||||
|
immediately evaluate the instrumented expression.
|
||||||
|
|
||||||
|
While debugged code is being evaluated, the user is taken through the
|
||||||
|
source code and displayed the value of various expressions. At each step,
|
||||||
|
a number of keys will be prompted to the user."
|
||||||
|
(interactive)
|
||||||
|
(cider-eval-defun-at-point 'debug-it))
|
||||||
|
|
||||||
|
(provide 'cider-debug)
|
||||||
|
;;; cider-debug.el ends here
|
Binary file not shown.
|
@ -0,0 +1,533 @@
|
||||||
|
;;; cider-doc.el --- CIDER documentation functionality -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2014-2018 Bozhidar Batsov, Jeff Valk and CIDER contributors
|
||||||
|
|
||||||
|
;; Author: Jeff Valk <jv@jeffvalk.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Mode for formatting and presenting documentation
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-common)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'cider-popup)
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-grimoire)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
(require 'org-table)
|
||||||
|
(require 'button)
|
||||||
|
(require 'easymenu)
|
||||||
|
(require 'cider-browse-spec)
|
||||||
|
|
||||||
|
|
||||||
|
;;; Variables
|
||||||
|
|
||||||
|
(defgroup cider-doc nil
|
||||||
|
"Documentation for CIDER."
|
||||||
|
:prefix "cider-doc-"
|
||||||
|
:group 'cider)
|
||||||
|
|
||||||
|
(defcustom cider-doc-auto-select-buffer t
|
||||||
|
"Controls whether to auto-select the doc popup buffer."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider-doc
|
||||||
|
:package-version '(cider . "0.15.0"))
|
||||||
|
|
||||||
|
(declare-function cider-apropos "cider-apropos")
|
||||||
|
(declare-function cider-apropos-select "cider-apropos")
|
||||||
|
(declare-function cider-apropos-documentation "cider-apropos")
|
||||||
|
(declare-function cider-apropos-documentation-select "cider-apropos")
|
||||||
|
|
||||||
|
(defvar cider-doc-map
|
||||||
|
(let (cider-doc-map)
|
||||||
|
(define-prefix-command 'cider-doc-map)
|
||||||
|
(define-key cider-doc-map (kbd "a") #'cider-apropos)
|
||||||
|
(define-key cider-doc-map (kbd "C-a") #'cider-apropos)
|
||||||
|
(define-key cider-doc-map (kbd "s") #'cider-apropos-select)
|
||||||
|
(define-key cider-doc-map (kbd "C-s") #'cider-apropos-select)
|
||||||
|
(define-key cider-doc-map (kbd "f") #'cider-apropos-documentation)
|
||||||
|
(define-key cider-doc-map (kbd "C-f") #'cider-apropos-documentation)
|
||||||
|
(define-key cider-doc-map (kbd "e") #'cider-apropos-documentation-select)
|
||||||
|
(define-key cider-doc-map (kbd "C-e") #'cider-apropos-documentation-select)
|
||||||
|
(define-key cider-doc-map (kbd "d") #'cider-doc)
|
||||||
|
(define-key cider-doc-map (kbd "C-d") #'cider-doc)
|
||||||
|
(define-key cider-doc-map (kbd "r") #'cider-grimoire)
|
||||||
|
(define-key cider-doc-map (kbd "C-r") #'cider-grimoire)
|
||||||
|
(define-key cider-doc-map (kbd "w") #'cider-grimoire-web)
|
||||||
|
(define-key cider-doc-map (kbd "C-w") #'cider-grimoire-web)
|
||||||
|
(define-key cider-doc-map (kbd "j") #'cider-javadoc)
|
||||||
|
(define-key cider-doc-map (kbd "C-j") #'cider-javadoc)
|
||||||
|
cider-doc-map)
|
||||||
|
"CIDER documentation keymap.")
|
||||||
|
|
||||||
|
(defconst cider-doc-menu
|
||||||
|
'("Documentation"
|
||||||
|
["CiderDoc" cider-doc]
|
||||||
|
["JavaDoc in browser" cider-javadoc]
|
||||||
|
["Grimoire" cider-grimoire]
|
||||||
|
["Grimoire in browser" cider-grimoire-web]
|
||||||
|
["Search symbols" cider-apropos]
|
||||||
|
["Search symbols & select" cider-apropos-select]
|
||||||
|
["Search documentation" cider-apropos-documentation]
|
||||||
|
["Search documentation & select" cider-apropos-documentation-select]
|
||||||
|
"--"
|
||||||
|
["Configure Doc buffer" (customize-group 'cider-docview-mode)])
|
||||||
|
"CIDER documentation submenu.")
|
||||||
|
|
||||||
|
|
||||||
|
;;; cider-docview-mode
|
||||||
|
|
||||||
|
(defgroup cider-docview-mode nil
|
||||||
|
"Formatting/fontifying documentation viewer."
|
||||||
|
:prefix "cider-docview-"
|
||||||
|
:group 'cider)
|
||||||
|
|
||||||
|
(defcustom cider-docview-fill-column fill-column
|
||||||
|
"Fill column for docstrings in doc buffer."
|
||||||
|
:type 'list
|
||||||
|
:group 'cider-docview-mode
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
|
||||||
|
;; Faces
|
||||||
|
|
||||||
|
(defface cider-docview-emphasis-face
|
||||||
|
'((t (:inherit default :underline t)))
|
||||||
|
"Face for emphasized text"
|
||||||
|
:group 'cider-docview-mode
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
(defface cider-docview-strong-face
|
||||||
|
'((t (:inherit default :underline t :weight bold)))
|
||||||
|
"Face for strongly emphasized text"
|
||||||
|
:group 'cider-docview-mode
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
(defface cider-docview-literal-face
|
||||||
|
'((t (:inherit font-lock-string-face)))
|
||||||
|
"Face for literal text"
|
||||||
|
:group 'cider-docview-mode
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
(defface cider-docview-table-border-face
|
||||||
|
'((t (:inherit shadow)))
|
||||||
|
"Face for table borders"
|
||||||
|
:group 'cider-docview-mode
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
|
||||||
|
;; Colors & Theme Support
|
||||||
|
|
||||||
|
(defvar cider-docview-code-background-color
|
||||||
|
(cider-scale-background-color)
|
||||||
|
"Background color for code blocks.")
|
||||||
|
|
||||||
|
(defadvice enable-theme (after cider-docview-adapt-to-theme activate)
|
||||||
|
"When theme is changed, update `cider-docview-code-background-color'."
|
||||||
|
(setq cider-docview-code-background-color (cider-scale-background-color)))
|
||||||
|
|
||||||
|
|
||||||
|
(defadvice disable-theme (after cider-docview-adapt-to-theme activate)
|
||||||
|
"When theme is disabled, update `cider-docview-code-background-color'."
|
||||||
|
(setq cider-docview-code-background-color (cider-scale-background-color)))
|
||||||
|
|
||||||
|
|
||||||
|
;; Mode & key bindings
|
||||||
|
|
||||||
|
(defvar cider-docview-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map "q" #'cider-popup-buffer-quit-function)
|
||||||
|
(define-key map "g" #'cider-docview-grimoire)
|
||||||
|
(define-key map "G" #'cider-docview-grimoire-web)
|
||||||
|
(define-key map "j" #'cider-docview-javadoc)
|
||||||
|
(define-key map "s" #'cider-docview-source)
|
||||||
|
(define-key map (kbd "<backtab>") #'backward-button)
|
||||||
|
(define-key map (kbd "TAB") #'forward-button)
|
||||||
|
(easy-menu-define cider-docview-mode-menu map
|
||||||
|
"Menu for CIDER's doc mode"
|
||||||
|
`("CiderDoc"
|
||||||
|
["Look up in Grimoire" cider-docview-grimoire]
|
||||||
|
["Look up in Grimoire (browser)" cider-docview-grimoire-web]
|
||||||
|
["JavaDoc in browser" cider-docview-javadoc]
|
||||||
|
["Jump to source" cider-docview-source]
|
||||||
|
"--"
|
||||||
|
["Quit" cider-popup-buffer-quit-function]
|
||||||
|
))
|
||||||
|
map))
|
||||||
|
|
||||||
|
(defvar cider-docview-symbol)
|
||||||
|
(defvar cider-docview-javadoc-url)
|
||||||
|
(defvar cider-docview-file)
|
||||||
|
(defvar cider-docview-line)
|
||||||
|
|
||||||
|
(define-derived-mode cider-docview-mode help-mode "Doc"
|
||||||
|
"Major mode for displaying CIDER documentation
|
||||||
|
|
||||||
|
\\{cider-docview-mode-map}"
|
||||||
|
(setq buffer-read-only t)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t))
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local cider-docview-symbol nil)
|
||||||
|
(setq-local cider-docview-javadoc-url nil)
|
||||||
|
(setq-local cider-docview-file nil)
|
||||||
|
(setq-local cider-docview-line nil))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Interactive functions
|
||||||
|
|
||||||
|
(defun cider-docview-javadoc ()
|
||||||
|
"Open the Javadoc for the current class, if available."
|
||||||
|
(interactive)
|
||||||
|
(if cider-docview-javadoc-url
|
||||||
|
(browse-url cider-docview-javadoc-url)
|
||||||
|
(error "No Javadoc available for %s" cider-docview-symbol)))
|
||||||
|
|
||||||
|
(defun cider-javadoc-handler (symbol-name)
|
||||||
|
"Invoke the nREPL \"info\" op on SYMBOL-NAME if available."
|
||||||
|
(when symbol-name
|
||||||
|
(let* ((info (cider-var-info symbol-name))
|
||||||
|
(url (nrepl-dict-get info "javadoc")))
|
||||||
|
(if url
|
||||||
|
(browse-url url)
|
||||||
|
(user-error "No Javadoc available for %s" symbol-name)))))
|
||||||
|
|
||||||
|
(defun cider-javadoc (arg)
|
||||||
|
"Open Javadoc documentation in a popup buffer.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "info")
|
||||||
|
(funcall (cider-prompt-for-symbol-function arg)
|
||||||
|
"Javadoc for"
|
||||||
|
#'cider-javadoc-handler))
|
||||||
|
|
||||||
|
(defun cider-docview-source ()
|
||||||
|
"Open the source for the current symbol, if available."
|
||||||
|
(interactive)
|
||||||
|
(if cider-docview-file
|
||||||
|
(if-let* ((buffer (and (not (cider--tooling-file-p cider-docview-file))
|
||||||
|
(cider-find-file cider-docview-file))))
|
||||||
|
(cider-jump-to buffer (if cider-docview-line
|
||||||
|
(cons cider-docview-line nil)
|
||||||
|
cider-docview-symbol)
|
||||||
|
nil)
|
||||||
|
(user-error
|
||||||
|
(substitute-command-keys
|
||||||
|
"Can't find the source because it wasn't defined with `cider-eval-buffer'")))
|
||||||
|
(error "No source location for %s" cider-docview-symbol)))
|
||||||
|
|
||||||
|
(defvar cider-buffer-ns)
|
||||||
|
|
||||||
|
(declare-function cider-grimoire-lookup "cider-grimoire")
|
||||||
|
|
||||||
|
(defun cider-docview-grimoire ()
|
||||||
|
"Return the grimoire documentation for `cider-docview-symbol'."
|
||||||
|
(interactive)
|
||||||
|
(if cider-buffer-ns
|
||||||
|
(cider-grimoire-lookup cider-docview-symbol)
|
||||||
|
(error "%s cannot be looked up on Grimoire" cider-docview-symbol)))
|
||||||
|
|
||||||
|
(declare-function cider-grimoire-web-lookup "cider-grimoire")
|
||||||
|
|
||||||
|
(defun cider-docview-grimoire-web ()
|
||||||
|
"Open the grimoire documentation for `cider-docview-symbol' in a web browser."
|
||||||
|
(interactive)
|
||||||
|
(if cider-buffer-ns
|
||||||
|
(cider-grimoire-web-lookup cider-docview-symbol)
|
||||||
|
(error "%s cannot be looked up on Grimoire" cider-docview-symbol)))
|
||||||
|
|
||||||
|
(defconst cider-doc-buffer "*cider-doc*")
|
||||||
|
|
||||||
|
(defun cider-create-doc-buffer (symbol)
|
||||||
|
"Populates *cider-doc* with the documentation for SYMBOL."
|
||||||
|
(when-let* ((info (cider-var-info symbol)))
|
||||||
|
(cider-docview-render (cider-make-popup-buffer cider-doc-buffer nil 'ancillary) symbol info)))
|
||||||
|
|
||||||
|
(defun cider-doc-lookup (symbol)
|
||||||
|
"Look up documentation for SYMBOL."
|
||||||
|
(if-let* ((buffer (cider-create-doc-buffer symbol)))
|
||||||
|
(cider-popup-buffer-display buffer cider-doc-auto-select-buffer)
|
||||||
|
(user-error "Symbol %s not resolved" symbol)))
|
||||||
|
|
||||||
|
(defun cider-doc (&optional arg)
|
||||||
|
"Open Clojure documentation in a popup buffer.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(funcall (cider-prompt-for-symbol-function arg)
|
||||||
|
"Doc for"
|
||||||
|
#'cider-doc-lookup))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Font Lock and Formatting
|
||||||
|
|
||||||
|
(defun cider-docview-fontify-code-blocks (buffer mode)
|
||||||
|
"Font lock BUFFER code blocks using MODE and remove markdown characters.
|
||||||
|
This processes the triple backtick GFM markdown extension. An overlay is used
|
||||||
|
to shade the background. Blocks are marked to be ignored by other fonification
|
||||||
|
and line wrap."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(while (search-forward-regexp "```\n" nil t)
|
||||||
|
(replace-match "")
|
||||||
|
(let ((beg (point))
|
||||||
|
(bg `(:background ,cider-docview-code-background-color)))
|
||||||
|
(when (search-forward-regexp "```\n" nil t)
|
||||||
|
(replace-match "")
|
||||||
|
(cider-font-lock-region-as mode beg (point))
|
||||||
|
(overlay-put (make-overlay beg (point)) 'font-lock-face bg)
|
||||||
|
(put-text-property beg (point) 'block 'code)))))))
|
||||||
|
|
||||||
|
(defun cider-docview-fontify-literals (buffer)
|
||||||
|
"Font lock BUFFER literal text and remove backtick markdown characters.
|
||||||
|
Preformatted code text blocks are ignored."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(while (search-forward "`" nil t)
|
||||||
|
(if (eq (get-text-property (point) 'block) 'code)
|
||||||
|
(forward-char)
|
||||||
|
(progn
|
||||||
|
(replace-match "")
|
||||||
|
(let ((beg (point)))
|
||||||
|
(when (search-forward "`" (line-end-position) t)
|
||||||
|
(replace-match "")
|
||||||
|
(put-text-property beg (point) 'font-lock-face 'cider-docview-literal-face)))))))))
|
||||||
|
|
||||||
|
(defun cider-docview-fontify-emphasis (buffer)
|
||||||
|
"Font lock BUFFER emphasized text and remove markdown characters.
|
||||||
|
One '*' represents emphasis, multiple '**'s represent strong emphasis.
|
||||||
|
Preformatted code text blocks are ignored."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(while (search-forward-regexp "\\(*+\\)\\(\\w\\)" nil t)
|
||||||
|
(if (eq (get-text-property (point) 'block) 'code)
|
||||||
|
(forward-char)
|
||||||
|
(progn
|
||||||
|
(replace-match "\\2")
|
||||||
|
(let ((beg (1- (point)))
|
||||||
|
(face (if (> (length (match-string 1)) 1)
|
||||||
|
'cider-docview-strong-face
|
||||||
|
'cider-docview-emphasis-face)))
|
||||||
|
(when (search-forward-regexp "\\(\\w\\)\\*+" (line-end-position) t)
|
||||||
|
(replace-match "\\1")
|
||||||
|
(put-text-property beg (point) 'font-lock-face face)))))))))
|
||||||
|
|
||||||
|
(defun cider-docview-format-tables (buffer)
|
||||||
|
"Align BUFFER tables and dim borders.
|
||||||
|
This processes the GFM table markdown extension using `org-table'.
|
||||||
|
Tables are marked to be ignored by line wrap."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(let ((border 'cider-docview-table-border-face))
|
||||||
|
(org-table-map-tables
|
||||||
|
(lambda ()
|
||||||
|
(org-table-align)
|
||||||
|
(goto-char (org-table-begin))
|
||||||
|
(while (search-forward-regexp "[+|-]" (org-table-end) t)
|
||||||
|
(put-text-property (match-beginning 0) (match-end 0) 'font-lock-face border))
|
||||||
|
(put-text-property (org-table-begin) (org-table-end) 'block 'table)))))))
|
||||||
|
|
||||||
|
(defun cider-docview-wrap-text (buffer)
|
||||||
|
"For text in BUFFER not propertized as 'block', apply line wrap."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(save-excursion
|
||||||
|
(while (not (eobp))
|
||||||
|
(unless (get-text-property (point) 'block)
|
||||||
|
(fill-region (point) (line-end-position)))
|
||||||
|
(forward-line)))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Rendering
|
||||||
|
|
||||||
|
(defun cider-docview-render-java-doc (buffer text)
|
||||||
|
"Emit into BUFFER formatted doc TEXT for a Java class or member."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((beg (point)))
|
||||||
|
(insert text)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char beg)
|
||||||
|
(cider-docview-fontify-code-blocks buffer 'java-mode) ; left alone hereafter
|
||||||
|
(cider-docview-fontify-literals buffer)
|
||||||
|
(cider-docview-fontify-emphasis buffer)
|
||||||
|
(cider-docview-format-tables buffer) ; may contain literals, emphasis
|
||||||
|
(cider-docview-wrap-text buffer))))) ; ignores code, table blocks
|
||||||
|
|
||||||
|
(defun cider--abbreviate-file-protocol (file-with-protocol)
|
||||||
|
"Abbreviate the file-path in `file:/path/to/file' of FILE-WITH-PROTOCOL."
|
||||||
|
(if (string-match "\\`file:\\(.*\\)" file-with-protocol)
|
||||||
|
(let ((file (match-string 1 file-with-protocol))
|
||||||
|
(proj-dir (clojure-project-dir)))
|
||||||
|
(if (and proj-dir
|
||||||
|
(file-in-directory-p file proj-dir))
|
||||||
|
(file-relative-name file proj-dir)
|
||||||
|
file))
|
||||||
|
file-with-protocol))
|
||||||
|
|
||||||
|
(defun cider-docview-render-info (buffer info)
|
||||||
|
"Emit into BUFFER formatted INFO for the Clojure or Java symbol."
|
||||||
|
(let* ((ns (nrepl-dict-get info "ns"))
|
||||||
|
(name (nrepl-dict-get info "name"))
|
||||||
|
(added (nrepl-dict-get info "added"))
|
||||||
|
(depr (nrepl-dict-get info "deprecated"))
|
||||||
|
(macro (nrepl-dict-get info "macro"))
|
||||||
|
(special (nrepl-dict-get info "special-form"))
|
||||||
|
(forms (when-let* ((str (nrepl-dict-get info "forms-str")))
|
||||||
|
(split-string str "\n")))
|
||||||
|
(args (when-let* ((str (nrepl-dict-get info "arglists-str")))
|
||||||
|
(split-string str "\n")))
|
||||||
|
(doc (or (nrepl-dict-get info "doc")
|
||||||
|
"Not documented."))
|
||||||
|
(url (nrepl-dict-get info "url"))
|
||||||
|
(class (nrepl-dict-get info "class"))
|
||||||
|
(member (nrepl-dict-get info "member"))
|
||||||
|
(javadoc (nrepl-dict-get info "javadoc"))
|
||||||
|
(super (nrepl-dict-get info "super"))
|
||||||
|
(ifaces (nrepl-dict-get info "interfaces"))
|
||||||
|
(spec (nrepl-dict-get info "spec"))
|
||||||
|
(clj-name (if ns (concat ns "/" name) name))
|
||||||
|
(java-name (if member (concat class "/" member) class))
|
||||||
|
(see-also (nrepl-dict-get info "see-also")))
|
||||||
|
(cider--help-setup-xref (list #'cider-doc-lookup (format "%s/%s" ns name)) nil buffer)
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cl-flet ((emit (text &optional face)
|
||||||
|
(insert (if face
|
||||||
|
(propertize text 'font-lock-face face)
|
||||||
|
text)
|
||||||
|
"\n")))
|
||||||
|
(emit (if class java-name clj-name) 'font-lock-function-name-face)
|
||||||
|
(when super
|
||||||
|
(emit (concat " Extends: " (cider-font-lock-as 'java-mode super))))
|
||||||
|
(when ifaces
|
||||||
|
(emit (concat "Implements: " (cider-font-lock-as 'java-mode (car ifaces))))
|
||||||
|
(dolist (iface (cdr ifaces))
|
||||||
|
(emit (concat " "(cider-font-lock-as 'java-mode iface)))))
|
||||||
|
(when (or super ifaces)
|
||||||
|
(insert "\n"))
|
||||||
|
(when-let* ((forms (or forms args)))
|
||||||
|
(dolist (form forms)
|
||||||
|
(insert " ")
|
||||||
|
(emit (cider-font-lock-as-clojure form))))
|
||||||
|
(when special
|
||||||
|
(emit "Special Form" 'font-lock-keyword-face))
|
||||||
|
(when macro
|
||||||
|
(emit "Macro" 'font-lock-variable-name-face))
|
||||||
|
(when added
|
||||||
|
(emit (concat "Added in " added) 'font-lock-comment-face))
|
||||||
|
(when depr
|
||||||
|
(emit (concat "Deprecated in " depr) 'font-lock-keyword-face))
|
||||||
|
(if class
|
||||||
|
(cider-docview-render-java-doc (current-buffer) doc)
|
||||||
|
(emit (concat " " doc)))
|
||||||
|
(when url
|
||||||
|
(insert "\n Please see ")
|
||||||
|
(insert-text-button url
|
||||||
|
'url url
|
||||||
|
'follow-link t
|
||||||
|
'action (lambda (x)
|
||||||
|
(browse-url (button-get x 'url))))
|
||||||
|
(insert "\n"))
|
||||||
|
(when javadoc
|
||||||
|
(insert "\n\nFor additional documentation, see the ")
|
||||||
|
(insert-text-button "Javadoc"
|
||||||
|
'url javadoc
|
||||||
|
'follow-link t
|
||||||
|
'action (lambda (x)
|
||||||
|
(browse-url (button-get x 'url))))
|
||||||
|
(insert ".\n"))
|
||||||
|
(insert "\n")
|
||||||
|
(when spec
|
||||||
|
(emit "Spec:" 'font-lock-function-name-face)
|
||||||
|
(insert (cider-browse-spec--pprint-indented spec))
|
||||||
|
(insert "\n\n")
|
||||||
|
(insert-text-button "Browse spec"
|
||||||
|
'follow-link t
|
||||||
|
'action (lambda (_)
|
||||||
|
(cider-browse-spec (format "%s/%s" ns name))))
|
||||||
|
(insert "\n\n"))
|
||||||
|
(if cider-docview-file
|
||||||
|
(progn
|
||||||
|
(insert (propertize (if class java-name clj-name)
|
||||||
|
'font-lock-face 'font-lock-function-name-face)
|
||||||
|
" is defined in ")
|
||||||
|
(insert-text-button (cider--abbreviate-file-protocol cider-docview-file)
|
||||||
|
'follow-link t
|
||||||
|
'action (lambda (_x)
|
||||||
|
(cider-docview-source)))
|
||||||
|
(insert "."))
|
||||||
|
(insert "Definition location unavailable."))
|
||||||
|
(when see-also
|
||||||
|
(insert "\n\n Also see: ")
|
||||||
|
(mapc (lambda (ns-sym)
|
||||||
|
(let* ((ns-sym-split (split-string ns-sym "/"))
|
||||||
|
(see-also-ns (car ns-sym-split))
|
||||||
|
(see-also-sym (cadr ns-sym-split))
|
||||||
|
;; if the var belongs to the same namespace,
|
||||||
|
;; we omit the namespace to save some screen space
|
||||||
|
(symbol (if (equal ns see-also-ns) see-also-sym ns-sym)))
|
||||||
|
(insert-text-button symbol
|
||||||
|
'type 'help-xref
|
||||||
|
'help-function (apply-partially #'cider-doc-lookup symbol)))
|
||||||
|
(insert " "))
|
||||||
|
see-also))
|
||||||
|
(cider--doc-make-xrefs)
|
||||||
|
(let ((beg (point-min))
|
||||||
|
(end (point-max)))
|
||||||
|
(nrepl-dict-map (lambda (k v)
|
||||||
|
(put-text-property beg end k v))
|
||||||
|
info)))
|
||||||
|
(current-buffer))))
|
||||||
|
|
||||||
|
(declare-function cider-set-buffer-ns "cider-mode")
|
||||||
|
(defun cider-docview-render (buffer symbol info)
|
||||||
|
"Emit into BUFFER formatted documentation for SYMBOL's INFO."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((javadoc (nrepl-dict-get info "javadoc"))
|
||||||
|
(file (nrepl-dict-get info "file"))
|
||||||
|
(line (nrepl-dict-get info "line"))
|
||||||
|
(ns (nrepl-dict-get info "ns"))
|
||||||
|
(inhibit-read-only t))
|
||||||
|
(cider-docview-mode)
|
||||||
|
|
||||||
|
(cider-set-buffer-ns ns)
|
||||||
|
(setq-local cider-docview-symbol symbol)
|
||||||
|
(setq-local cider-docview-javadoc-url javadoc)
|
||||||
|
(setq-local cider-docview-file file)
|
||||||
|
(setq-local cider-docview-line line)
|
||||||
|
|
||||||
|
(remove-overlays)
|
||||||
|
(cider-docview-render-info buffer info)
|
||||||
|
|
||||||
|
(goto-char (point-min))
|
||||||
|
(current-buffer))))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'cider-doc)
|
||||||
|
|
||||||
|
;;; cider-doc.el ends here
|
Binary file not shown.
|
@ -0,0 +1,481 @@
|
||||||
|
;;; cider-eldoc.el --- eldoc support for Clojure -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Tim King <kingtim@gmail.com>
|
||||||
|
;; Phil Hagelberg <technomancy@gmail.com>
|
||||||
|
;; Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
;; Hugo Duncan <hugo@hugoduncan.org>
|
||||||
|
;; Steve Purcell <steve@sanityinc.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; eldoc support for Clojure.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-common) ; for cider-symbol-at-point
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'cider-util)
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
|
||||||
|
(require 'seq)
|
||||||
|
|
||||||
|
(require 'eldoc)
|
||||||
|
|
||||||
|
(defvar cider-extra-eldoc-commands '("yas-expand")
|
||||||
|
"Extra commands to be added to eldoc's safe commands list.")
|
||||||
|
|
||||||
|
(defcustom cider-eldoc-max-num-sexps-to-skip 30
|
||||||
|
"The maximum number of sexps to skip while searching the beginning of current sexp."
|
||||||
|
:type 'integer
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.1"))
|
||||||
|
|
||||||
|
(defvar-local cider-eldoc-last-symbol nil
|
||||||
|
"The eldoc information for the last symbol we checked.")
|
||||||
|
|
||||||
|
(defcustom cider-eldoc-ns-function #'identity
|
||||||
|
"A function that returns a ns string to be used by eldoc.
|
||||||
|
Takes one argument, a namespace name.
|
||||||
|
For convenience, some functions are already provided for this purpose:
|
||||||
|
`cider-abbreviate-ns', and `cider-last-ns-segment'."
|
||||||
|
:type '(choice (const :tag "Full namespace" identity)
|
||||||
|
(const :tag "Abbreviated namespace" cider-abbreviate-ns)
|
||||||
|
(const :tag "Last name in namespace" cider-last-ns-segment)
|
||||||
|
(function :tag "Custom function"))
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.13.0"))
|
||||||
|
|
||||||
|
(defcustom cider-eldoc-max-class-names-to-display 3
|
||||||
|
"The maximum number of classes to display in an eldoc string.
|
||||||
|
An eldoc string for Java interop forms can have a number of classes prefixed to
|
||||||
|
it, when the form belongs to more than 1 class. When, not nil we only display
|
||||||
|
the names of first `cider-eldoc-max-class-names-to-display' classes and add
|
||||||
|
a \"& x more\" suffix. Otherwise, all the classes are displayed."
|
||||||
|
:type 'integer
|
||||||
|
:safe #'integerp
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.13.0"))
|
||||||
|
|
||||||
|
(defcustom cider-eldoc-display-for-symbol-at-point t
|
||||||
|
"When non-nil, display eldoc for symbol at point if available.
|
||||||
|
So in (map inc ...) when the cursor is over inc its eldoc would be
|
||||||
|
displayed. When nil, always display eldoc for first symbol of the sexp."
|
||||||
|
:type 'boolean
|
||||||
|
:safe #'booleanp
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.13.0"))
|
||||||
|
|
||||||
|
(defcustom cider-eldoc-display-context-dependent-info nil
|
||||||
|
"When non-nil, display context dependent info in the eldoc where possible.
|
||||||
|
CIDER will try to add expected function arguments based on the current context,
|
||||||
|
for example for the datomic.api/q function where it will show the expected
|
||||||
|
inputs of the query at point."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.15.0"))
|
||||||
|
|
||||||
|
(defun cider--eldoc-format-class-names (class-names)
|
||||||
|
"Return a formatted CLASS-NAMES prefix string.
|
||||||
|
CLASS-NAMES is a list of classes to which a Java interop form belongs.
|
||||||
|
Only keep the first `cider-eldoc-max-class-names-to-display' names, and
|
||||||
|
add a \"& x more\" suffix. Return nil if the CLASS-NAMES list is empty or
|
||||||
|
mapping `cider-eldoc-ns-function' on it returns an empty list."
|
||||||
|
(when-let* ((eldoc-class-names (seq-remove #'null (mapcar (apply-partially cider-eldoc-ns-function) class-names)))
|
||||||
|
(eldoc-class-names-length (length eldoc-class-names)))
|
||||||
|
(cond
|
||||||
|
;; truncate class-names list and then format it
|
||||||
|
((and cider-eldoc-max-class-names-to-display
|
||||||
|
(> eldoc-class-names-length cider-eldoc-max-class-names-to-display))
|
||||||
|
(format "(%s & %s more)"
|
||||||
|
(thread-first eldoc-class-names
|
||||||
|
(seq-take cider-eldoc-max-class-names-to-display)
|
||||||
|
(string-join " ")
|
||||||
|
(cider-propertize 'ns))
|
||||||
|
(- eldoc-class-names-length cider-eldoc-max-class-names-to-display)))
|
||||||
|
|
||||||
|
;; format the whole list but add surrounding parentheses
|
||||||
|
((> eldoc-class-names-length 1)
|
||||||
|
(format "(%s)"
|
||||||
|
(thread-first eldoc-class-names
|
||||||
|
(string-join " ")
|
||||||
|
(cider-propertize 'ns))))
|
||||||
|
|
||||||
|
;; don't add the parentheses
|
||||||
|
(t (format "%s" (car eldoc-class-names))))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-format-thing (ns symbol thing type)
|
||||||
|
"Format the eldoc subject defined by NS, SYMBOL, THING and TYPE.
|
||||||
|
THING represents the thing at point which triggered eldoc. Normally NS and
|
||||||
|
SYMBOL are used (they are derived from THING), but when empty we fallback to
|
||||||
|
THING (e.g. for Java methods). Format it as a function, if FUNCTION-P
|
||||||
|
is non-nil. Else format it as a variable."
|
||||||
|
(if-let* ((method-name (if (and symbol (not (string= symbol "")))
|
||||||
|
symbol
|
||||||
|
thing))
|
||||||
|
(propertized-method-name (cider-propertize method-name type))
|
||||||
|
(ns-or-class (if (and ns (stringp ns))
|
||||||
|
(funcall cider-eldoc-ns-function ns)
|
||||||
|
(cider--eldoc-format-class-names ns))))
|
||||||
|
(format "%s/%s"
|
||||||
|
;; we set font-lock properties of classes in `cider--eldoc-format-class-names'
|
||||||
|
;; to avoid font locking the parentheses and "& x more"
|
||||||
|
;; so we only propertize ns-or-class if not already done
|
||||||
|
(if (get-text-property 1 'face ns-or-class)
|
||||||
|
;; it is already propertized
|
||||||
|
ns-or-class
|
||||||
|
(cider-propertize ns-or-class 'ns))
|
||||||
|
propertized-method-name)
|
||||||
|
;; in case ns-or-class is nil
|
||||||
|
propertized-method-name))
|
||||||
|
|
||||||
|
(defun cider-eldoc-format-sym-doc (var ns docstring)
|
||||||
|
"Return the formatted eldoc string for VAR and DOCSTRING.
|
||||||
|
|
||||||
|
Consider the value of `eldoc-echo-area-use-multiline-p' while formatting.
|
||||||
|
If the entire line cannot fit in the echo area, the var name may be
|
||||||
|
truncated or eliminated entirely from the output to make room for the
|
||||||
|
description.
|
||||||
|
|
||||||
|
Try to truncate the var with various strategies, so that the var and
|
||||||
|
the docstring can be displayed in the minibuffer without resizing the window.
|
||||||
|
We start with `cider-abbreviate-ns' and `cider-last-ns-segment'.
|
||||||
|
Next, if the var is in current namespace, we remove NS from the eldoc string.
|
||||||
|
Otherwise, only the docstring is returned."
|
||||||
|
(let* ((ea-multi eldoc-echo-area-use-multiline-p)
|
||||||
|
;; Subtract 1 from window width since emacs will not write
|
||||||
|
;; any chars to the last column, or in later versions, will
|
||||||
|
;; cause a wraparound and resize of the echo area.
|
||||||
|
(ea-width (1- (window-width (minibuffer-window))))
|
||||||
|
(strip (- (+ (length var) (length docstring)) ea-width))
|
||||||
|
(newline (string-match-p "\n" docstring))
|
||||||
|
;; Truncated var can be ea-var long
|
||||||
|
;; Subtract 2 to account for the : and / added when including
|
||||||
|
;; the namespace prefixed form in eldoc string
|
||||||
|
(ea-var (- (- ea-width (length docstring)) 2)))
|
||||||
|
(cond
|
||||||
|
((or (eq ea-multi t)
|
||||||
|
(and (<= strip 0) (null newline))
|
||||||
|
(and ea-multi (or (> (length docstring) ea-width) newline)))
|
||||||
|
(format "%s: %s" var docstring))
|
||||||
|
|
||||||
|
;; Now we have to truncate either the docstring or the var
|
||||||
|
(newline (cider-eldoc-format-sym-doc var ns (substring docstring 0 newline)))
|
||||||
|
|
||||||
|
;; Only return the truncated docstring
|
||||||
|
((> (length docstring) ea-width)
|
||||||
|
(substring docstring 0 ea-width))
|
||||||
|
|
||||||
|
;; Try to truncate the var with cider-abbreviate-ns
|
||||||
|
((<= (length (cider-abbreviate-ns var)) ea-var)
|
||||||
|
(format "%s: %s" (cider-abbreviate-ns var) docstring))
|
||||||
|
|
||||||
|
;; Try to truncate var with cider-last-ns-segment
|
||||||
|
((<= (length (cider-last-ns-segment var)) ea-var)
|
||||||
|
(format "%s: %s" (cider-last-ns-segment var) docstring))
|
||||||
|
|
||||||
|
;; If the var is in current namespace, we try to truncate the var by
|
||||||
|
;; skipping the namespace from the returned eldoc string
|
||||||
|
((and (string-equal ns (cider-current-ns))
|
||||||
|
(<= (- (length var) (length ns)) ea-var))
|
||||||
|
(format "%s: %s"
|
||||||
|
(replace-regexp-in-string (format "%s/" ns) "" var)
|
||||||
|
docstring))
|
||||||
|
|
||||||
|
;; We couldn't fit the var and docstring in the available space,
|
||||||
|
;; so we just display the docstring
|
||||||
|
(t docstring))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-format-variable (thing eldoc-info)
|
||||||
|
"Return the formatted eldoc string for a variable.
|
||||||
|
|
||||||
|
THING is the variable name. ELDOC-INFO is a p-list containing the eldoc
|
||||||
|
information."
|
||||||
|
(let* ((ns (lax-plist-get eldoc-info "ns"))
|
||||||
|
(symbol (lax-plist-get eldoc-info "symbol"))
|
||||||
|
(docstring (lax-plist-get eldoc-info "docstring"))
|
||||||
|
(formatted-var (cider-eldoc-format-thing ns symbol thing 'var)))
|
||||||
|
(when docstring
|
||||||
|
(cider-eldoc-format-sym-doc formatted-var ns docstring))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-format-function (thing pos eldoc-info)
|
||||||
|
"Return the formatted eldoc string for a function.
|
||||||
|
THING is the function name. POS is the argument-index of the functions
|
||||||
|
arglists. ELDOC-INFO is a p-list containing the eldoc information."
|
||||||
|
(let ((ns (lax-plist-get eldoc-info "ns"))
|
||||||
|
(symbol (lax-plist-get eldoc-info "symbol"))
|
||||||
|
(arglists (lax-plist-get eldoc-info "arglists")))
|
||||||
|
(format "%s: %s"
|
||||||
|
(cider-eldoc-format-thing ns symbol thing 'fn)
|
||||||
|
(cider-eldoc-format-arglist arglists pos))))
|
||||||
|
|
||||||
|
(defun cider-highlight-args (arglist pos)
|
||||||
|
"Format the the function ARGLIST for eldoc.
|
||||||
|
POS is the index of the currently highlighted argument."
|
||||||
|
(let* ((rest-pos (cider--find-rest-args-position arglist))
|
||||||
|
(i 0))
|
||||||
|
(mapconcat
|
||||||
|
(lambda (arg)
|
||||||
|
(let ((argstr (format "%s" arg)))
|
||||||
|
(if (string= arg "&")
|
||||||
|
argstr
|
||||||
|
(prog1
|
||||||
|
(if (or (= (1+ i) pos)
|
||||||
|
(and rest-pos
|
||||||
|
(> (1+ i) rest-pos)
|
||||||
|
(> pos rest-pos)))
|
||||||
|
(propertize argstr 'face
|
||||||
|
'eldoc-highlight-function-argument)
|
||||||
|
argstr)
|
||||||
|
(setq i (1+ i)))))) arglist " ")))
|
||||||
|
|
||||||
|
(defun cider--find-rest-args-position (arglist)
|
||||||
|
"Find the position of & in the ARGLIST vector."
|
||||||
|
(seq-position arglist "&"))
|
||||||
|
|
||||||
|
(defun cider-highlight-arglist (arglist pos)
|
||||||
|
"Format the ARGLIST for eldoc.
|
||||||
|
POS is the index of the argument to highlight."
|
||||||
|
(concat "[" (cider-highlight-args arglist pos) "]"))
|
||||||
|
|
||||||
|
(defun cider-eldoc-format-arglist (arglist pos)
|
||||||
|
"Format all the ARGLIST for eldoc.
|
||||||
|
POS is the index of current argument."
|
||||||
|
(concat "("
|
||||||
|
(mapconcat (lambda (args) (cider-highlight-arglist args pos))
|
||||||
|
arglist
|
||||||
|
" ")
|
||||||
|
")"))
|
||||||
|
|
||||||
|
(defun cider-eldoc-beginning-of-sexp ()
|
||||||
|
"Move to the beginning of current sexp.
|
||||||
|
|
||||||
|
Return the number of nested sexp the point was over or after. Return nil
|
||||||
|
if the maximum number of sexps to skip is exceeded."
|
||||||
|
(let ((parse-sexp-ignore-comments t)
|
||||||
|
(num-skipped-sexps 0))
|
||||||
|
(condition-case _
|
||||||
|
(progn
|
||||||
|
;; First account for the case the point is directly over a
|
||||||
|
;; beginning of a nested sexp.
|
||||||
|
(condition-case _
|
||||||
|
(let ((p (point)))
|
||||||
|
(forward-sexp -1)
|
||||||
|
(forward-sexp 1)
|
||||||
|
(when (< (point) p)
|
||||||
|
(setq num-skipped-sexps 1)))
|
||||||
|
(error))
|
||||||
|
(while
|
||||||
|
(let ((p (point)))
|
||||||
|
(forward-sexp -1)
|
||||||
|
(when (< (point) p)
|
||||||
|
(setq num-skipped-sexps
|
||||||
|
(unless (and cider-eldoc-max-num-sexps-to-skip
|
||||||
|
(>= num-skipped-sexps
|
||||||
|
cider-eldoc-max-num-sexps-to-skip))
|
||||||
|
;; Without the above guard,
|
||||||
|
;; `cider-eldoc-beginning-of-sexp' could traverse the
|
||||||
|
;; whole buffer when the point is not within a
|
||||||
|
;; list. This behavior is problematic especially with
|
||||||
|
;; a buffer containing a large number of
|
||||||
|
;; non-expressions like a REPL buffer.
|
||||||
|
(1+ num-skipped-sexps)))))))
|
||||||
|
(error))
|
||||||
|
num-skipped-sexps))
|
||||||
|
|
||||||
|
(defun cider-eldoc-thing-type (eldoc-info)
|
||||||
|
"Return the type of the ELDOC-INFO being displayed by eldoc.
|
||||||
|
It can be a function or var now."
|
||||||
|
(pcase (lax-plist-get eldoc-info "type")
|
||||||
|
("function" 'fn)
|
||||||
|
("variable" 'var)))
|
||||||
|
|
||||||
|
(defun cider-eldoc-info-at-point ()
|
||||||
|
"Return eldoc info at point.
|
||||||
|
First go to the beginning of the sexp and check if the eldoc is to be
|
||||||
|
considered (i.e sexp is a method call) and not a map or vector literal.
|
||||||
|
Then go back to the point and return its eldoc."
|
||||||
|
(save-excursion
|
||||||
|
(unless (cider-in-comment-p)
|
||||||
|
(let* ((current-point (point)))
|
||||||
|
(cider-eldoc-beginning-of-sexp)
|
||||||
|
(unless (member (or (char-before (point)) 0) '(?\" ?\{ ?\[))
|
||||||
|
(goto-char current-point)
|
||||||
|
(when-let* ((eldoc-info (cider-eldoc-info
|
||||||
|
(cider--eldoc-remove-dot (cider-symbol-at-point)))))
|
||||||
|
`("eldoc-info" ,eldoc-info
|
||||||
|
"thing" ,(cider-symbol-at-point)
|
||||||
|
"pos" 0)))))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-info-at-sexp-beginning ()
|
||||||
|
"Return eldoc info for first symbol in the sexp."
|
||||||
|
(save-excursion
|
||||||
|
(when-let* ((beginning-of-sexp (cider-eldoc-beginning-of-sexp))
|
||||||
|
;; If we are at the beginning of function name, this will be -1
|
||||||
|
(argument-index (max 0 (1- beginning-of-sexp))))
|
||||||
|
(unless (or (memq (or (char-before (point)) 0)
|
||||||
|
'(?\" ?\{ ?\[))
|
||||||
|
(cider-in-comment-p))
|
||||||
|
(when-let* ((eldoc-info (cider-eldoc-info
|
||||||
|
(cider--eldoc-remove-dot (cider-symbol-at-point)))))
|
||||||
|
`("eldoc-info" ,eldoc-info
|
||||||
|
"thing" ,(cider-symbol-at-point)
|
||||||
|
"pos" ,argument-index))))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-info-in-current-sexp ()
|
||||||
|
"Return eldoc information from the sexp.
|
||||||
|
If `cider-eldoc-display-for-symbol-at-poin' is non-nil and
|
||||||
|
the symbol at point has a valid eldoc available, return that.
|
||||||
|
Otherwise return the eldoc of the first symbol of the sexp."
|
||||||
|
(or (when cider-eldoc-display-for-symbol-at-point
|
||||||
|
(cider-eldoc-info-at-point))
|
||||||
|
(cider-eldoc-info-at-sexp-beginning)))
|
||||||
|
|
||||||
|
(defun cider-eldoc--convert-ns-keywords (thing)
|
||||||
|
"Convert THING values that match ns macro keywords to function names."
|
||||||
|
(pcase thing
|
||||||
|
(":import" "clojure.core/import")
|
||||||
|
(":refer-clojure" "clojure.core/refer-clojure")
|
||||||
|
(":use" "clojure.core/use")
|
||||||
|
(":refer" "clojure.core/refer")
|
||||||
|
(_ thing)))
|
||||||
|
|
||||||
|
(defun cider-eldoc-info (thing)
|
||||||
|
"Return the info for THING.
|
||||||
|
This includes the arglist and ns and symbol name (if available)."
|
||||||
|
(let ((thing (cider-eldoc--convert-ns-keywords thing)))
|
||||||
|
(when (and (cider-nrepl-op-supported-p "eldoc")
|
||||||
|
thing
|
||||||
|
;; ignore empty strings
|
||||||
|
(not (string= thing ""))
|
||||||
|
;; ignore strings
|
||||||
|
(not (string-prefix-p "\"" thing))
|
||||||
|
;; ignore regular expressions
|
||||||
|
(not (string-prefix-p "#" thing))
|
||||||
|
;; ignore chars
|
||||||
|
(not (string-prefix-p "\\" thing))
|
||||||
|
;; ignore numbers
|
||||||
|
(not (string-match-p "^[0-9]" thing)))
|
||||||
|
;; check if we can used the cached eldoc info
|
||||||
|
(cond
|
||||||
|
;; handle keywords for map access
|
||||||
|
((string-prefix-p ":" thing) (list "symbol" thing
|
||||||
|
"type" "function"
|
||||||
|
"arglists" '(("map") ("map" "not-found"))))
|
||||||
|
;; handle Classname. by displaying the eldoc for new
|
||||||
|
((string-match-p "^[A-Z].+\\.$" thing) (list "symbol" thing
|
||||||
|
"type" "function"
|
||||||
|
"arglists" '(("args*"))))
|
||||||
|
;; generic case
|
||||||
|
(t (if (equal thing (car cider-eldoc-last-symbol))
|
||||||
|
(cadr cider-eldoc-last-symbol)
|
||||||
|
(when-let* ((eldoc-info (cider-sync-request:eldoc thing)))
|
||||||
|
(let* ((arglists (nrepl-dict-get eldoc-info "eldoc"))
|
||||||
|
(docstring (nrepl-dict-get eldoc-info "docstring"))
|
||||||
|
(type (nrepl-dict-get eldoc-info "type"))
|
||||||
|
(ns (nrepl-dict-get eldoc-info "ns"))
|
||||||
|
(class (nrepl-dict-get eldoc-info "class"))
|
||||||
|
(name (nrepl-dict-get eldoc-info "name"))
|
||||||
|
(member (nrepl-dict-get eldoc-info "member"))
|
||||||
|
(ns-or-class (if (and ns (not (string= ns "")))
|
||||||
|
ns
|
||||||
|
class))
|
||||||
|
(name-or-member (if (and name (not (string= name "")))
|
||||||
|
name
|
||||||
|
(format ".%s" member)))
|
||||||
|
(eldoc-plist (list "ns" ns-or-class
|
||||||
|
"symbol" name-or-member
|
||||||
|
"arglists" arglists
|
||||||
|
"docstring" docstring
|
||||||
|
"type" type)))
|
||||||
|
;; add context dependent args if requested by defcustom
|
||||||
|
;; do not cache this eldoc info to avoid showing info
|
||||||
|
;: of the previous context
|
||||||
|
(if cider-eldoc-display-context-dependent-info
|
||||||
|
(cond
|
||||||
|
;; add inputs of datomic query
|
||||||
|
((and (equal ns-or-class "datomic.api")
|
||||||
|
(equal name-or-member "q"))
|
||||||
|
(let ((arglists (lax-plist-get eldoc-plist "arglists")))
|
||||||
|
(lax-plist-put eldoc-plist "arglists"
|
||||||
|
(cider--eldoc-add-datomic-query-inputs-to-arglists arglists))))
|
||||||
|
;; if none of the clauses is successful, do cache the eldoc
|
||||||
|
(t (setq cider-eldoc-last-symbol (list thing eldoc-plist))))
|
||||||
|
;; middleware eldoc lookups are expensive, so we
|
||||||
|
;; cache the last lookup. This eliminates the need
|
||||||
|
;; for extra middleware requests within the same sexp.
|
||||||
|
(setq cider-eldoc-last-symbol (list thing eldoc-plist)))
|
||||||
|
eldoc-plist))))))))
|
||||||
|
|
||||||
|
(defun cider--eldoc-remove-dot (sym)
|
||||||
|
"Remove the preceding \".\" from a namespace qualified SYM and return sym.
|
||||||
|
Only useful for interop forms. Clojure forms would be returned unchanged."
|
||||||
|
(when sym (replace-regexp-in-string "/\\." "/" sym)))
|
||||||
|
|
||||||
|
(defun cider--eldoc-edn-file-p (file-name)
|
||||||
|
"Check whether FILE-NAME is representing an EDN file."
|
||||||
|
(and file-name (equal (file-name-extension file-name) "edn")))
|
||||||
|
|
||||||
|
(defun cider--eldoc-add-datomic-query-inputs-to-arglists (arglists)
|
||||||
|
"Add the expected inputs of the datomic query to the ARGLISTS."
|
||||||
|
(if (cider-second-sexp-in-list)
|
||||||
|
(let* ((query (cider-second-sexp-in-list))
|
||||||
|
(query-inputs (nrepl-dict-get
|
||||||
|
(cider-sync-request:eldoc-datomic-query query)
|
||||||
|
"inputs")))
|
||||||
|
(if query-inputs
|
||||||
|
(thread-first
|
||||||
|
(thread-last arglists
|
||||||
|
(car)
|
||||||
|
(remove "&")
|
||||||
|
(remove "inputs"))
|
||||||
|
(append (car query-inputs))
|
||||||
|
(list))
|
||||||
|
arglists))
|
||||||
|
arglists))
|
||||||
|
|
||||||
|
(defun cider-eldoc ()
|
||||||
|
"Backend function for eldoc to show argument list in the echo area."
|
||||||
|
(when (and (cider-connected-p)
|
||||||
|
;; don't clobber an error message in the minibuffer
|
||||||
|
(not (member last-command '(next-error previous-error)))
|
||||||
|
;; don't try to provide eldoc in EDN buffers
|
||||||
|
(not (cider--eldoc-edn-file-p buffer-file-name)))
|
||||||
|
(let* ((sexp-eldoc-info (cider-eldoc-info-in-current-sexp))
|
||||||
|
(eldoc-info (lax-plist-get sexp-eldoc-info "eldoc-info"))
|
||||||
|
(pos (lax-plist-get sexp-eldoc-info "pos"))
|
||||||
|
(thing (lax-plist-get sexp-eldoc-info "thing")))
|
||||||
|
(when eldoc-info
|
||||||
|
(if (equal (cider-eldoc-thing-type eldoc-info) 'fn)
|
||||||
|
(cider-eldoc-format-function thing pos eldoc-info)
|
||||||
|
(cider-eldoc-format-variable thing eldoc-info))))))
|
||||||
|
|
||||||
|
(defun cider-eldoc-setup ()
|
||||||
|
"Setup eldoc in the current buffer.
|
||||||
|
eldoc mode has to be enabled for this to have any effect."
|
||||||
|
(setq-local eldoc-documentation-function #'cider-eldoc)
|
||||||
|
(apply #'eldoc-add-command cider-extra-eldoc-commands))
|
||||||
|
|
||||||
|
(provide 'cider-eldoc)
|
||||||
|
|
||||||
|
;;; cider-eldoc.el ends here
|
Binary file not shown.
1098
configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el
Normal file
1098
configs/shared/emacs/.emacs.d/elpa/cider-20180719.542/cider-eval.el
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -0,0 +1,220 @@
|
||||||
|
;;; cider-find.el --- Functionality for finding things -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; A bunch of commands for finding resources and definitions.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-common)
|
||||||
|
|
||||||
|
(require 'thingatpt)
|
||||||
|
|
||||||
|
(defun cider--find-var-other-window (var &optional line)
|
||||||
|
"Find the definition of VAR, optionally at a specific LINE.
|
||||||
|
|
||||||
|
Display the results in a different window."
|
||||||
|
(if-let* ((info (cider-var-info var)))
|
||||||
|
(progn
|
||||||
|
(if line (setq info (nrepl-dict-put info "line" line)))
|
||||||
|
(cider--jump-to-loc-from-info info t))
|
||||||
|
(user-error "Symbol `%s' not resolved" var)))
|
||||||
|
|
||||||
|
(defun cider--find-var (var &optional line)
|
||||||
|
"Find the definition of VAR, optionally at a specific LINE."
|
||||||
|
(if-let* ((info (cider-var-info var)))
|
||||||
|
(progn
|
||||||
|
(if line (setq info (nrepl-dict-put info "line" line)))
|
||||||
|
(cider--jump-to-loc-from-info info))
|
||||||
|
(user-error "Symbol `%s' not resolved" var)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-find-var (&optional arg var line)
|
||||||
|
"Find definition for VAR at LINE.
|
||||||
|
Prompt according to prefix ARG and `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. The default value is
|
||||||
|
thing at point."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-ensure-op-supported "info")
|
||||||
|
(if var
|
||||||
|
(cider--find-var var line)
|
||||||
|
(funcall (cider-prompt-for-symbol-function arg)
|
||||||
|
"Symbol"
|
||||||
|
(if (cider--open-other-window-p arg)
|
||||||
|
#'cider--find-var-other-window
|
||||||
|
#'cider--find-var))))
|
||||||
|
|
||||||
|
(defun cider--find-dwim (symbol-file callback &optional other-window)
|
||||||
|
"Find the SYMBOL-FILE at point.
|
||||||
|
CALLBACK upon failure to invoke prompt if not prompted previously.
|
||||||
|
Show results in a different window if OTHER-WINDOW is true."
|
||||||
|
(if-let* ((info (cider-var-info symbol-file)))
|
||||||
|
(cider--jump-to-loc-from-info info other-window)
|
||||||
|
(progn
|
||||||
|
(cider-ensure-op-supported "resource")
|
||||||
|
(if-let* ((resource (cider-sync-request:resource symbol-file))
|
||||||
|
(buffer (cider-find-file resource)))
|
||||||
|
(cider-jump-to buffer 0 other-window)
|
||||||
|
(if (cider--prompt-for-symbol-p current-prefix-arg)
|
||||||
|
(error "Resource or var %s not resolved" symbol-file)
|
||||||
|
(let ((current-prefix-arg (if current-prefix-arg nil '(4))))
|
||||||
|
(call-interactively callback)))))))
|
||||||
|
|
||||||
|
(defun cider--find-dwim-interactive (prompt)
|
||||||
|
"Get interactive arguments for jump-to functions using PROMPT as needed."
|
||||||
|
(if (cider--prompt-for-symbol-p current-prefix-arg)
|
||||||
|
(list
|
||||||
|
(cider-read-from-minibuffer prompt (thing-at-point 'filename)))
|
||||||
|
(list (or (thing-at-point 'filename) "")))) ; No prompt.
|
||||||
|
|
||||||
|
(defun cider-find-dwim-other-window (symbol-file)
|
||||||
|
"Jump to SYMBOL-FILE at point, place results in other window."
|
||||||
|
(interactive (cider--find-dwim-interactive "Jump to: "))
|
||||||
|
(cider--find-dwim symbol-file 'cider-find-dwim-other-window t))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-find-dwim (symbol-file)
|
||||||
|
"Find and display the SYMBOL-FILE at point.
|
||||||
|
SYMBOL-FILE could be a var or a resource. If thing at point is empty then
|
||||||
|
show dired on project. If var is not found, try to jump to resource of the
|
||||||
|
same name. When called interactively, a prompt is given according to the
|
||||||
|
variable `cider-prompt-for-symbol'. A single or double prefix argument
|
||||||
|
inverts the meaning. A prefix of `-' or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. A default value of thing
|
||||||
|
at point is given when prompted."
|
||||||
|
(interactive (cider--find-dwim-interactive "Jump to: "))
|
||||||
|
(cider--find-dwim symbol-file `cider-find-dwim
|
||||||
|
(cider--open-other-window-p current-prefix-arg)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-find-resource (path)
|
||||||
|
"Find the resource at PATH.
|
||||||
|
Prompt for input as indicated by the variable `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix argument of `-` or a double prefix
|
||||||
|
argument causes the results to be displayed in other window. The default
|
||||||
|
value is thing at point."
|
||||||
|
(interactive
|
||||||
|
(list
|
||||||
|
(if (cider--prompt-for-symbol-p current-prefix-arg)
|
||||||
|
(completing-read "Resource: "
|
||||||
|
(cider-sync-request:resources-list)
|
||||||
|
nil nil
|
||||||
|
(thing-at-point 'filename))
|
||||||
|
(or (thing-at-point 'filename) ""))))
|
||||||
|
(cider-ensure-op-supported "resource")
|
||||||
|
(when (= (length path) 0)
|
||||||
|
(error "Cannot find resource for empty path"))
|
||||||
|
(if-let* ((resource (cider-sync-request:resource path))
|
||||||
|
(buffer (cider-find-file resource)))
|
||||||
|
(cider-jump-to buffer nil (cider--open-other-window-p current-prefix-arg))
|
||||||
|
(if (cider--prompt-for-symbol-p current-prefix-arg)
|
||||||
|
(error "Cannot find resource %s" path)
|
||||||
|
(let ((current-prefix-arg (cider--invert-prefix-arg current-prefix-arg)))
|
||||||
|
(call-interactively 'cider-find-resource)))))
|
||||||
|
|
||||||
|
(defun cider--invert-prefix-arg (arg)
|
||||||
|
"Invert the effect of prefix value ARG on `cider-prompt-for-symbol'.
|
||||||
|
This function preserves the `other-window' meaning of ARG."
|
||||||
|
(let ((narg (prefix-numeric-value arg)))
|
||||||
|
(pcase narg
|
||||||
|
(16 -1) ; empty empty -> -
|
||||||
|
(-1 16) ; - -> empty empty
|
||||||
|
(4 nil) ; empty -> no-prefix
|
||||||
|
(_ 4)))) ; no-prefix -> empty
|
||||||
|
|
||||||
|
(defun cider--prefix-invert-prompt-p (arg)
|
||||||
|
"Test prefix value ARG for its effect on `cider-prompt-for-symbol`."
|
||||||
|
(let ((narg (prefix-numeric-value arg)))
|
||||||
|
(pcase narg
|
||||||
|
(16 t) ; empty empty
|
||||||
|
(4 t) ; empty
|
||||||
|
(_ nil))))
|
||||||
|
|
||||||
|
(defun cider--prompt-for-symbol-p (&optional prefix)
|
||||||
|
"Check if cider should prompt for symbol.
|
||||||
|
Tests againsts PREFIX and the value of `cider-prompt-for-symbol'.
|
||||||
|
Invert meaning of `cider-prompt-for-symbol' if PREFIX indicates it should be."
|
||||||
|
(if (cider--prefix-invert-prompt-p prefix)
|
||||||
|
(not cider-prompt-for-symbol) cider-prompt-for-symbol))
|
||||||
|
|
||||||
|
(defun cider--find-ns (ns &optional other-window)
|
||||||
|
"Find the file containing NS's definition.
|
||||||
|
Optionally open it in a different window if OTHER-WINDOW is truthy."
|
||||||
|
(if-let* ((path (cider-sync-request:ns-path ns)))
|
||||||
|
(cider-jump-to (cider-find-file path) nil other-window)
|
||||||
|
(user-error "Can't find namespace `%s'" ns)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-find-ns (&optional arg ns)
|
||||||
|
"Find the file containing NS.
|
||||||
|
A prefix ARG of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider-ensure-op-supported "ns-path")
|
||||||
|
(if ns
|
||||||
|
(cider--find-ns ns)
|
||||||
|
(let* ((namespaces (cider-sync-request:ns-list))
|
||||||
|
(ns (completing-read "Find namespace: " namespaces)))
|
||||||
|
(cider--find-ns ns (cider--open-other-window-p arg)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-find-keyword (&optional arg)
|
||||||
|
"Find the namespace of the keyword at point and its first occurrence there.
|
||||||
|
|
||||||
|
For instance - if the keyword at point is \":cider.demo/keyword\", this command
|
||||||
|
would find the namespace \"cider.demo\" and afterwards find the first mention
|
||||||
|
of \"::keyword\" there.
|
||||||
|
|
||||||
|
Prompt according to prefix ARG and `cider-prompt-for-symbol'.
|
||||||
|
A single or double prefix argument inverts the meaning of
|
||||||
|
`cider-prompt-for-symbol'. A prefix of `-` or a double prefix argument causes
|
||||||
|
the results to be displayed in a different window. The default value is
|
||||||
|
thing at point."
|
||||||
|
(interactive "P")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(let* ((kw (let ((kw-at-point (cider-symbol-at-point 'look-back)))
|
||||||
|
(if (or cider-prompt-for-symbol arg)
|
||||||
|
(read-string
|
||||||
|
(format "Keyword (default %s): " kw-at-point)
|
||||||
|
nil nil kw-at-point)
|
||||||
|
kw-at-point)))
|
||||||
|
(ns-qualifier (and
|
||||||
|
(string-match "^:+\\(.+\\)/.+$" kw)
|
||||||
|
(match-string 1 kw)))
|
||||||
|
(kw-ns (if ns-qualifier
|
||||||
|
(cider-resolve-alias (cider-current-ns) ns-qualifier)
|
||||||
|
(cider-current-ns)))
|
||||||
|
(kw-to-find (concat "::" (replace-regexp-in-string "^:+\\(.+/\\)?" "" kw))))
|
||||||
|
|
||||||
|
(when (and ns-qualifier (string= kw-ns (cider-current-ns)))
|
||||||
|
(error "Could not resolve alias `%s' in `%s'" ns-qualifier (cider-current-ns)))
|
||||||
|
(cider--find-ns kw-ns arg)
|
||||||
|
(search-forward-regexp kw-to-find nil 'noerror)))
|
||||||
|
|
||||||
|
(provide 'cider-find)
|
||||||
|
;;; cider-find.el ends here
|
Binary file not shown.
|
@ -0,0 +1,150 @@
|
||||||
|
;;; cider-format.el --- Code and EDN formatting functionality -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Middleware-powered code and EDN formatting functionality.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'subr-x)
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-util)
|
||||||
|
|
||||||
|
|
||||||
|
;; Format
|
||||||
|
|
||||||
|
(defun cider--format-reindent (formatted start)
|
||||||
|
"Reindent FORMATTED to align with buffer position START."
|
||||||
|
(let* ((start-column (save-excursion (goto-char start) (current-column)))
|
||||||
|
(indent-line (concat "\n" (make-string start-column ? ))))
|
||||||
|
(replace-regexp-in-string "\n" indent-line formatted)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Format region
|
||||||
|
|
||||||
|
(defun cider--format-region (start end formatter)
|
||||||
|
"Format the contents of the given region.
|
||||||
|
|
||||||
|
START and END represent the region's boundaries.
|
||||||
|
|
||||||
|
FORMATTER is a function of one argument which is used to convert
|
||||||
|
the string contents of the region into a formatted string.
|
||||||
|
|
||||||
|
Uses the following heuristic to try to maintain point position:
|
||||||
|
|
||||||
|
- Take a snippet of text starting at current position, up to 64 chars.
|
||||||
|
- Search for the snippet, with lax whitespace, in the formatted text.
|
||||||
|
- If snippet is less than 64 chars (point was near end of buffer), search
|
||||||
|
from end instead of beginning.
|
||||||
|
- Place point at match beginning, or `point-min' if no match."
|
||||||
|
(let* ((original (buffer-substring-no-properties start end))
|
||||||
|
(formatted (funcall formatter original))
|
||||||
|
(indented (cider--format-reindent formatted start)))
|
||||||
|
(unless (equal original indented)
|
||||||
|
(let* ((pos (point))
|
||||||
|
(pos-max (1+ (buffer-size)))
|
||||||
|
(l 64)
|
||||||
|
(endp (> (+ pos l) pos-max))
|
||||||
|
(snippet (thread-last (buffer-substring-no-properties
|
||||||
|
pos (min (+ pos l) pos-max))
|
||||||
|
(replace-regexp-in-string "[[:space:]\t\n\r]+" "[[:space:]\t\n\r]*"))))
|
||||||
|
(delete-region start end)
|
||||||
|
(insert indented)
|
||||||
|
(goto-char (if endp (point-max) (point-min)))
|
||||||
|
(funcall (if endp #'re-search-backward #'re-search-forward) snippet nil t)
|
||||||
|
(goto-char (or (match-beginning 0) start))
|
||||||
|
(when (looking-at-p "\n") (forward-char))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-region (start end)
|
||||||
|
"Format the Clojure code in the current region.
|
||||||
|
START and END represent the region's boundaries."
|
||||||
|
(interactive "r")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider--format-region start end #'cider-sync-request:format-code))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Format defun
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-defun ()
|
||||||
|
"Format the code in the current defun."
|
||||||
|
(interactive)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(save-excursion
|
||||||
|
(mark-defun)
|
||||||
|
(cider-format-region (region-beginning) (region-end))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Format buffer
|
||||||
|
|
||||||
|
(defun cider--format-buffer (formatter)
|
||||||
|
"Format the contents of the current buffer.
|
||||||
|
|
||||||
|
Uses FORMATTER, a function of one argument, to convert the string contents
|
||||||
|
of the buffer into a formatted string."
|
||||||
|
(cider--format-region 1 (1+ (buffer-size)) formatter))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-buffer ()
|
||||||
|
"Format the Clojure code in the current buffer."
|
||||||
|
(interactive)
|
||||||
|
(check-parens)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider--format-buffer #'cider-sync-request:format-code))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Format EDN
|
||||||
|
|
||||||
|
(declare-function cider--pretty-print-width "cider-repl")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-edn-buffer ()
|
||||||
|
"Format the EDN data in the current buffer."
|
||||||
|
(interactive)
|
||||||
|
(check-parens)
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(cider--format-buffer (lambda (edn)
|
||||||
|
(cider-sync-request:format-edn edn (cider--pretty-print-width)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-edn-region (start end)
|
||||||
|
"Format the EDN data in the current region.
|
||||||
|
START and END represent the region's boundaries."
|
||||||
|
(interactive "r")
|
||||||
|
(cider-ensure-connected)
|
||||||
|
(let* ((start-column (save-excursion (goto-char start) (current-column)))
|
||||||
|
(right-margin (- (cider--pretty-print-width) start-column)))
|
||||||
|
(cider--format-region start end
|
||||||
|
(lambda (edn)
|
||||||
|
(cider-sync-request:format-edn edn right-margin)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-format-edn-last-sexp ()
|
||||||
|
"Format the EDN data of the last sexp."
|
||||||
|
(interactive)
|
||||||
|
(apply 'cider-format-edn-region (cider-sexp-at-point 'bounds)))
|
||||||
|
|
||||||
|
(provide 'cider-format)
|
||||||
|
;;; cider-format.el ends here
|
Binary file not shown.
|
@ -0,0 +1,130 @@
|
||||||
|
;;; cider-grimoire.el --- Grimoire integration -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; A few commands for Grimoire documentation lookup.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-client)
|
||||||
|
(require 'cider-common)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
(require 'cider-popup)
|
||||||
|
|
||||||
|
(require 'nrepl-dict)
|
||||||
|
|
||||||
|
(require 'url-vars)
|
||||||
|
|
||||||
|
(declare-function markdown-mode "markdown-mode.el")
|
||||||
|
(declare-function markdown-toggle-fontify-code-blocks-natively "markdown-mode.el")
|
||||||
|
|
||||||
|
(defconst cider-grimoire-url "http://conj.io/")
|
||||||
|
|
||||||
|
(defconst cider-grimoire-buffer "*cider-grimoire*")
|
||||||
|
|
||||||
|
(defun cider-grimoire-replace-special (name)
|
||||||
|
"Convert the dashes in NAME to a grimoire friendly format."
|
||||||
|
(thread-last name
|
||||||
|
(replace-regexp-in-string "\\?" "_QMARK_")
|
||||||
|
(replace-regexp-in-string "\\." "_DOT_")
|
||||||
|
(replace-regexp-in-string "\\/" "_SLASH_")
|
||||||
|
(replace-regexp-in-string "\\(\\`_\\)\\|\\(_\\'\\)" "")))
|
||||||
|
|
||||||
|
(defun cider-grimoire-url (name ns)
|
||||||
|
"Generate a grimoire search v0 url from NAME, NS."
|
||||||
|
(let ((base-url cider-grimoire-url))
|
||||||
|
(when (and name ns)
|
||||||
|
(concat base-url "search/v0/" ns "/" (cider-grimoire-replace-special name) "/"))))
|
||||||
|
|
||||||
|
(defun cider-grimoire-web-lookup (symbol)
|
||||||
|
"Open the grimoire documentation for SYMBOL in a web browser."
|
||||||
|
(if-let* ((var-info (cider-var-info symbol)))
|
||||||
|
(let ((name (nrepl-dict-get var-info "name"))
|
||||||
|
(ns (nrepl-dict-get var-info "ns")))
|
||||||
|
(browse-url (cider-grimoire-url name ns)))
|
||||||
|
(error "Symbol %s not resolved" symbol)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-grimoire-web (&optional arg)
|
||||||
|
"Open grimoire documentation in the default web browser.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates."
|
||||||
|
(interactive "P")
|
||||||
|
(funcall (cider-prompt-for-symbol-function arg)
|
||||||
|
"Grimoire doc for"
|
||||||
|
#'cider-grimoire-web-lookup))
|
||||||
|
|
||||||
|
(defun cider-create-grimoire-buffer (content)
|
||||||
|
"Create a new grimoire buffer with CONTENT."
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-grimoire-buffer t)
|
||||||
|
(read-only-mode -1)
|
||||||
|
(insert content)
|
||||||
|
(when (require 'markdown-mode nil 'noerror)
|
||||||
|
(markdown-mode)
|
||||||
|
(cider-popup-buffer-mode 1)
|
||||||
|
(when (fboundp 'markdown-toggle-fontify-code-blocks-natively)
|
||||||
|
(markdown-toggle-fontify-code-blocks-natively 1)))
|
||||||
|
(view-mode 1)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(current-buffer)))
|
||||||
|
|
||||||
|
(defun cider-grimoire-lookup (symbol)
|
||||||
|
"Look up the grimoire documentation for SYMBOL.
|
||||||
|
|
||||||
|
If SYMBOL is a special form, the clojure.core ns is used, as is
|
||||||
|
Grimoire's convention."
|
||||||
|
(if-let* ((var-info (cider-var-info symbol)))
|
||||||
|
(let ((name (nrepl-dict-get var-info "name"))
|
||||||
|
(ns (nrepl-dict-get var-info "ns" "clojure.core"))
|
||||||
|
(url-request-method "GET")
|
||||||
|
(url-request-extra-headers `(("Content-Type" . "text/plain"))))
|
||||||
|
(url-retrieve (cider-grimoire-url name ns)
|
||||||
|
(lambda (_status)
|
||||||
|
;; we need to strip the http header
|
||||||
|
(goto-char (point-min))
|
||||||
|
(re-search-forward "^$")
|
||||||
|
(delete-region (point-min) (point))
|
||||||
|
(delete-blank-lines)
|
||||||
|
;; and create a new buffer with whatever is left
|
||||||
|
(pop-to-buffer (cider-create-grimoire-buffer (buffer-string))))))
|
||||||
|
(error "Symbol %s not resolved" symbol)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-grimoire (&optional arg)
|
||||||
|
"Open grimoire documentation in a popup buffer.
|
||||||
|
|
||||||
|
Prompts for the symbol to use, or uses the symbol at point, depending on
|
||||||
|
the value of `cider-prompt-for-symbol'. With prefix arg ARG, does the
|
||||||
|
opposite of what that option dictates."
|
||||||
|
(interactive "P")
|
||||||
|
(when (derived-mode-p 'clojurescript-mode)
|
||||||
|
(user-error "`cider-grimoire' doesn't support ClojureScript"))
|
||||||
|
(funcall (cider-prompt-for-symbol-function arg)
|
||||||
|
"Grimoire doc for"
|
||||||
|
#'cider-grimoire-lookup))
|
||||||
|
|
||||||
|
(provide 'cider-grimoire)
|
||||||
|
|
||||||
|
;;; cider-grimoire.el ends here
|
Binary file not shown.
|
@ -0,0 +1,397 @@
|
||||||
|
;;; cider-inspector.el --- Object inspector -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2013-2018 Vital Reactor, LLC
|
||||||
|
;; Copyright © 2014-2018 Bozhidar Batsov and CIDER contributors
|
||||||
|
|
||||||
|
;; Author: Ian Eslick <ian@vitalreactor.com>
|
||||||
|
;; Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Clojure object inspector inspired by SLIME.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'seq)
|
||||||
|
(require 'cider-eval)
|
||||||
|
|
||||||
|
;; ===================================
|
||||||
|
;; Inspector Key Map and Derived Mode
|
||||||
|
;; ===================================
|
||||||
|
|
||||||
|
(defconst cider-inspector-buffer "*cider-inspect*")
|
||||||
|
|
||||||
|
;;; Customization
|
||||||
|
(defgroup cider-inspector nil
|
||||||
|
"Presentation and behaviour of the cider value inspector."
|
||||||
|
:prefix "cider-inspector-"
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-inspector-page-size 32
|
||||||
|
"Default page size in paginated inspector view.
|
||||||
|
The page size can be also changed interactively within the inspector."
|
||||||
|
:type '(integer :tag "Page size" 32)
|
||||||
|
:group 'cider-inspector
|
||||||
|
:package-version '(cider . "0.10.0"))
|
||||||
|
|
||||||
|
(defcustom cider-inspector-fill-frame nil
|
||||||
|
"Controls whether the cider inspector window fills its frame."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider-inspector
|
||||||
|
:package-version '(cider . "0.15.0"))
|
||||||
|
|
||||||
|
(defvar cider-inspector-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(set-keymap-parent map cider-popup-buffer-mode-map)
|
||||||
|
(define-key map (kbd "RET") #'cider-inspector-operate-on-point)
|
||||||
|
(define-key map [mouse-1] #'cider-inspector-operate-on-click)
|
||||||
|
(define-key map "l" #'cider-inspector-pop)
|
||||||
|
(define-key map "g" #'cider-inspector-refresh)
|
||||||
|
;; Page-up/down
|
||||||
|
(define-key map [next] #'cider-inspector-next-page)
|
||||||
|
(define-key map [prior] #'cider-inspector-prev-page)
|
||||||
|
(define-key map " " #'cider-inspector-next-page)
|
||||||
|
(define-key map (kbd "M-SPC") #'cider-inspector-prev-page)
|
||||||
|
(define-key map (kbd "S-SPC") #'cider-inspector-prev-page)
|
||||||
|
(define-key map "s" #'cider-inspector-set-page-size)
|
||||||
|
(define-key map [tab] #'cider-inspector-next-inspectable-object)
|
||||||
|
(define-key map "\C-i" #'cider-inspector-next-inspectable-object)
|
||||||
|
(define-key map [(shift tab)] #'cider-inspector-previous-inspectable-object)
|
||||||
|
;; Emacs translates S-TAB to BACKTAB on X.
|
||||||
|
(define-key map [backtab] #'cider-inspector-previous-inspectable-object)
|
||||||
|
map))
|
||||||
|
|
||||||
|
(define-derived-mode cider-inspector-mode special-mode "Inspector"
|
||||||
|
"Major mode for inspecting Clojure data structures.
|
||||||
|
|
||||||
|
\\{cider-inspector-mode-map}"
|
||||||
|
(set-syntax-table clojure-mode-syntax-table)
|
||||||
|
(setq-local electric-indent-chars nil)
|
||||||
|
(setq-local sesman-system 'CIDER)
|
||||||
|
(when cider-special-mode-truncate-lines
|
||||||
|
(setq-local truncate-lines t)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-inspect-last-sexp ()
|
||||||
|
"Inspect the result of the the expression preceding point."
|
||||||
|
(interactive)
|
||||||
|
(cider-inspect-expr (cider-last-sexp) (cider-current-ns)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-inspect-defun-at-point ()
|
||||||
|
"Inspect the result of the \"top-level\" expression at point."
|
||||||
|
(interactive)
|
||||||
|
(cider-inspect-expr (cider-defun-at-point) (cider-current-ns)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-inspect-last-result ()
|
||||||
|
"Inspect the most recent eval result."
|
||||||
|
(interactive)
|
||||||
|
(cider-inspect-expr "*1" (cider-current-ns)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-inspect (&optional arg)
|
||||||
|
"Inspect the result of the preceding sexp.
|
||||||
|
|
||||||
|
With a prefix argument ARG it inspects the result of the \"top-level\" form.
|
||||||
|
With a second prefix argument it prompts for an expression to eval and inspect."
|
||||||
|
(interactive "p")
|
||||||
|
(pcase arg
|
||||||
|
(1 (cider-inspect-last-sexp))
|
||||||
|
(4 (cider-inspect-defun-at-point))
|
||||||
|
(16 (call-interactively #'cider-inspect-expr))))
|
||||||
|
|
||||||
|
(defvar cider-inspector-location-stack nil
|
||||||
|
"A stack used to save point locations in inspector buffers.
|
||||||
|
These locations are used to emulate `save-excursion' between
|
||||||
|
`cider-inspector-push' and `cider-inspector-pop' operations.")
|
||||||
|
|
||||||
|
(defvar cider-inspector-page-location-stack nil
|
||||||
|
"A stack used to save point locations in inspector buffers.
|
||||||
|
These locations are used to emulate `save-excursion' between
|
||||||
|
`cider-inspector-next-page' and `cider-inspector-prev-page' operations.")
|
||||||
|
|
||||||
|
(defvar cider-inspector-last-command nil
|
||||||
|
"Contains the value of the most recently used `cider-inspector-*' command.
|
||||||
|
This is used as an alternative to the built-in `last-command'. Whenever we
|
||||||
|
invoke any command through \\[execute-extended-command] and its variants,
|
||||||
|
the value of `last-command' is not set to the command it invokes.")
|
||||||
|
|
||||||
|
;; Operations
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-inspect-expr (expr ns)
|
||||||
|
"Evaluate EXPR in NS and inspect its value.
|
||||||
|
Interactively, EXPR is read from the minibuffer, and NS the
|
||||||
|
current buffer's namespace."
|
||||||
|
(interactive (list (cider-read-from-minibuffer "Inspect expression: " (cider-sexp-at-point))
|
||||||
|
(cider-current-ns)))
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-expr expr ns (or cider-inspector-page-size 32))))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-pop ()
|
||||||
|
"Pop the last value off the inspector stack and render it.
|
||||||
|
See `cider-sync-request:inspect-pop' and `cider-inspector--render-value'."
|
||||||
|
(interactive)
|
||||||
|
(setq cider-inspector-last-command 'cider-inspector-pop)
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-pop)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-push (idx)
|
||||||
|
"Inspect the value at IDX in the inspector stack and render it.
|
||||||
|
See `cider-sync-request:insepect-push' and `cider-inspector--render-value'"
|
||||||
|
(push (point) cider-inspector-location-stack)
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-push idx)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-refresh ()
|
||||||
|
"Re-render the currently inspected value.
|
||||||
|
See `cider-sync-request:insepect-refresh' and `cider-inspector--render-value'"
|
||||||
|
(interactive)
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-refresh)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-next-page ()
|
||||||
|
"Jump to the next page when inspecting a paginated sequence/map.
|
||||||
|
|
||||||
|
Does nothing if already on the last page."
|
||||||
|
(interactive)
|
||||||
|
(push (point) cider-inspector-page-location-stack)
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-next-page)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-prev-page ()
|
||||||
|
"Jump to the previous page when expecting a paginated sequence/map.
|
||||||
|
|
||||||
|
Does nothing if already on the first page."
|
||||||
|
(interactive)
|
||||||
|
(setq cider-inspector-last-command 'cider-inspector-prev-page)
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-prev-page)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
(defun cider-inspector-set-page-size (page-size)
|
||||||
|
"Set the page size in pagination mode to the specified PAGE-SIZE.
|
||||||
|
|
||||||
|
Current page will be reset to zero."
|
||||||
|
(interactive "nPage size: ")
|
||||||
|
(when-let* ((value (cider-sync-request:inspect-set-page-size page-size)))
|
||||||
|
(cider-inspector--render-value value)))
|
||||||
|
|
||||||
|
;; nREPL interactions
|
||||||
|
(defun cider-sync-request:inspect-pop ()
|
||||||
|
"Move one level up in the inspector stack."
|
||||||
|
(thread-first '("op" "inspect-pop")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-push (idx)
|
||||||
|
"Inspect the inside value specified by IDX."
|
||||||
|
(thread-first `("op" "inspect-push"
|
||||||
|
"idx" ,idx)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-refresh ()
|
||||||
|
"Re-render the currently inspected value."
|
||||||
|
(thread-first '("op" "inspect-refresh")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-next-page ()
|
||||||
|
"Jump to the next page in paginated collection view."
|
||||||
|
(thread-first '("op" "inspect-next-page")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-prev-page ()
|
||||||
|
"Jump to the previous page in paginated collection view."
|
||||||
|
(thread-first '("op" "inspect-prev-page")
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-set-page-size (page-size)
|
||||||
|
"Set the page size in paginated view to PAGE-SIZE."
|
||||||
|
(thread-first `("op" "inspect-set-page-size"
|
||||||
|
"page-size" ,page-size)
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
(defun cider-sync-request:inspect-expr (expr ns page-size)
|
||||||
|
"Evaluate EXPR in context of NS and inspect its result.
|
||||||
|
Set the page size in paginated view to PAGE-SIZE."
|
||||||
|
(thread-first (append (nrepl--eval-request expr ns)
|
||||||
|
`("inspect" "true"
|
||||||
|
"page-size" ,page-size))
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "value")))
|
||||||
|
|
||||||
|
;; Render Inspector from Structured Values
|
||||||
|
(defun cider-inspector--render-value (value)
|
||||||
|
"Render VALUE."
|
||||||
|
(cider-make-popup-buffer cider-inspector-buffer 'cider-inspector-mode 'ancillary)
|
||||||
|
(cider-inspector-render cider-inspector-buffer value)
|
||||||
|
(cider-popup-buffer-display cider-inspector-buffer t)
|
||||||
|
(when cider-inspector-fill-frame (delete-other-windows))
|
||||||
|
(with-current-buffer cider-inspector-buffer
|
||||||
|
(when (eq cider-inspector-last-command 'cider-inspector-pop)
|
||||||
|
(setq cider-inspector-last-command nil)
|
||||||
|
;; Prevents error message being displayed when we try to pop
|
||||||
|
;; from the top-level of a data struture
|
||||||
|
(when cider-inspector-location-stack
|
||||||
|
(goto-char (pop cider-inspector-location-stack))))
|
||||||
|
|
||||||
|
(when (eq cider-inspector-last-command 'cider-inspector-prev-page)
|
||||||
|
(setq cider-inspector-last-command nil)
|
||||||
|
;; Prevents error message being displayed when we try to
|
||||||
|
;; go to a prev-page from the first page
|
||||||
|
(when cider-inspector-page-location-stack
|
||||||
|
(goto-char (pop cider-inspector-page-location-stack))))))
|
||||||
|
|
||||||
|
(defun cider-inspector-render (buffer str)
|
||||||
|
"Render STR in BUFFER."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(cider-inspector-mode)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(condition-case nil
|
||||||
|
(cider-inspector-render* (car (read-from-string str)))
|
||||||
|
(error (insert "\nInspector error for: " str))))
|
||||||
|
(goto-char (point-min))))
|
||||||
|
|
||||||
|
(defun cider-inspector-render* (elements)
|
||||||
|
"Render ELEMENTS."
|
||||||
|
(dolist (el elements)
|
||||||
|
(cider-inspector-render-el* el)))
|
||||||
|
|
||||||
|
(defun cider-inspector-render-el* (el)
|
||||||
|
"Render EL."
|
||||||
|
(cond ((symbolp el) (insert (symbol-name el)))
|
||||||
|
((stringp el) (insert (propertize el 'font-lock-face 'font-lock-keyword-face)))
|
||||||
|
((and (consp el) (eq (car el) :newline))
|
||||||
|
(insert "\n"))
|
||||||
|
((and (consp el) (eq (car el) :value))
|
||||||
|
(cider-inspector-render-value (cadr el) (cl-caddr el)))
|
||||||
|
(t (message "Unrecognized inspector object: %s" el))))
|
||||||
|
|
||||||
|
(defun cider-inspector-render-value (value idx)
|
||||||
|
"Render VALUE at IDX."
|
||||||
|
(cider-propertize-region
|
||||||
|
(list 'cider-value-idx idx
|
||||||
|
'mouse-face 'highlight)
|
||||||
|
(cider-inspector-render-el* (cider-font-lock-as-clojure value))))
|
||||||
|
|
||||||
|
|
||||||
|
;; ===================================================
|
||||||
|
;; Inspector Navigation (lifted from SLIME inspector)
|
||||||
|
;; ===================================================
|
||||||
|
|
||||||
|
(defun cider-find-inspectable-object (direction limit)
|
||||||
|
"Find the next/previous inspectable object.
|
||||||
|
DIRECTION can be either 'next or 'prev.
|
||||||
|
LIMIT is the maximum or minimum position in the current buffer.
|
||||||
|
|
||||||
|
Return a list of two values: If an object could be found, the
|
||||||
|
starting position of the found object and T is returned;
|
||||||
|
otherwise LIMIT and NIL is returned."
|
||||||
|
(let ((finder (cl-ecase direction
|
||||||
|
(next 'next-single-property-change)
|
||||||
|
(prev 'previous-single-property-change))))
|
||||||
|
(let ((prop nil) (curpos (point)))
|
||||||
|
(while (and (not prop) (not (= curpos limit)))
|
||||||
|
(let ((newpos (funcall finder curpos 'cider-value-idx nil limit)))
|
||||||
|
(setq prop (get-text-property newpos 'cider-value-idx))
|
||||||
|
(setq curpos newpos)))
|
||||||
|
(list curpos (and prop t)))))
|
||||||
|
|
||||||
|
(defun cider-inspector-next-inspectable-object (arg)
|
||||||
|
"Move point to the next inspectable object.
|
||||||
|
With optional ARG, move across that many objects.
|
||||||
|
If ARG is negative, move backwards."
|
||||||
|
(interactive "p")
|
||||||
|
(let ((maxpos (point-max)) (minpos (point-min))
|
||||||
|
(previously-wrapped-p nil))
|
||||||
|
;; Forward.
|
||||||
|
(while (> arg 0)
|
||||||
|
(seq-let (pos foundp) (cider-find-inspectable-object 'next maxpos)
|
||||||
|
(if foundp
|
||||||
|
(progn (goto-char pos) (setq arg (1- arg))
|
||||||
|
(setq previously-wrapped-p nil))
|
||||||
|
(if (not previously-wrapped-p) ; cycle detection
|
||||||
|
(progn (goto-char minpos) (setq previously-wrapped-p t))
|
||||||
|
(error "No inspectable objects")))))
|
||||||
|
;; Backward.
|
||||||
|
(while (< arg 0)
|
||||||
|
(seq-let (pos foundp) (cider-find-inspectable-object 'prev minpos)
|
||||||
|
;; CIDER-OPEN-INSPECTOR inserts the title of an inspector page
|
||||||
|
;; as a presentation at the beginning of the buffer; skip
|
||||||
|
;; that. (Notice how this problem can not arise in ``Forward.'')
|
||||||
|
(if (and foundp (/= pos minpos))
|
||||||
|
(progn (goto-char pos) (setq arg (1+ arg))
|
||||||
|
(setq previously-wrapped-p nil))
|
||||||
|
(if (not previously-wrapped-p) ; cycle detection
|
||||||
|
(progn (goto-char maxpos) (setq previously-wrapped-p t))
|
||||||
|
(error "No inspectable objects")))))))
|
||||||
|
|
||||||
|
(defun cider-inspector-previous-inspectable-object (arg)
|
||||||
|
"Move point to the previous inspectable object.
|
||||||
|
With optional ARG, move across that many objects.
|
||||||
|
If ARG is negative, move forwards."
|
||||||
|
(interactive "p")
|
||||||
|
(cider-inspector-next-inspectable-object (- arg)))
|
||||||
|
|
||||||
|
(defun cider-inspector-property-at-point ()
|
||||||
|
"Return property at point."
|
||||||
|
(let* ((properties '(cider-value-idx cider-range-button
|
||||||
|
cider-action-number))
|
||||||
|
(find-property
|
||||||
|
(lambda (point)
|
||||||
|
(cl-loop for property in properties
|
||||||
|
for value = (get-text-property point property)
|
||||||
|
when value
|
||||||
|
return (list property value)))))
|
||||||
|
(or (funcall find-property (point))
|
||||||
|
(funcall find-property (1- (point))))))
|
||||||
|
|
||||||
|
(defun cider-inspector-operate-on-point ()
|
||||||
|
"Invoke the command for the text at point.
|
||||||
|
1. If point is on a value then recursively call the inspector on
|
||||||
|
that value.
|
||||||
|
2. If point is on an action then call that action.
|
||||||
|
3. If point is on a range-button fetch and insert the range."
|
||||||
|
(interactive)
|
||||||
|
(seq-let (property value) (cider-inspector-property-at-point)
|
||||||
|
(cl-case property
|
||||||
|
(cider-value-idx
|
||||||
|
(cider-inspector-push value))
|
||||||
|
;; TODO: range and action handlers
|
||||||
|
(t (error "No object at point")))))
|
||||||
|
|
||||||
|
(defun cider-inspector-operate-on-click (event)
|
||||||
|
"Move to EVENT's position and operate the part."
|
||||||
|
(interactive "@e")
|
||||||
|
(let ((point (posn-point (event-end event))))
|
||||||
|
(cond ((and point
|
||||||
|
(or (get-text-property point 'cider-value-idx)))
|
||||||
|
(goto-char point)
|
||||||
|
(cider-inspector-operate-on-point))
|
||||||
|
(t
|
||||||
|
(error "No clickable part here")))))
|
||||||
|
|
||||||
|
(provide 'cider-inspector)
|
||||||
|
|
||||||
|
;;; cider-inspector.el ends here
|
Binary file not shown.
|
@ -0,0 +1,206 @@
|
||||||
|
;;; cider-macroexpansion.el --- Macro expansion support -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright © 2012-2013 Tim King, Phil Hagelberg, Bozhidar Batsov
|
||||||
|
;; Copyright © 2013-2018 Bozhidar Batsov, Artur Malabarba and CIDER contributors
|
||||||
|
;;
|
||||||
|
;; Author: Tim King <kingtim@gmail.com>
|
||||||
|
;; Phil Hagelberg <technomancy@gmail.com>
|
||||||
|
;; Bozhidar Batsov <bozhidar@batsov.com>
|
||||||
|
;; Artur Malabarba <bruce.connor.am@gmail.com>
|
||||||
|
;; Hugo Duncan <hugo@hugoduncan.org>
|
||||||
|
;; Steve Purcell <steve@sanityinc.com>
|
||||||
|
|
||||||
|
;; This program is free software: you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; Macro expansion support.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'cider-mode)
|
||||||
|
(require 'subr-x)
|
||||||
|
(require 'cider-compat)
|
||||||
|
|
||||||
|
(defconst cider-macroexpansion-buffer "*cider-macroexpansion*")
|
||||||
|
|
||||||
|
(defcustom cider-macroexpansion-display-namespaces 'tidy
|
||||||
|
"Determines if namespaces are displayed in the macroexpansion buffer.
|
||||||
|
Possible values are:
|
||||||
|
|
||||||
|
'qualified ;=> Vars are fully-qualified in the expansion
|
||||||
|
'none ;=> Vars are displayed without namespace qualification
|
||||||
|
'tidy ;=> Vars that are :refer-ed or defined in the current namespace are
|
||||||
|
displayed with their simple name, non-refered vars from other
|
||||||
|
namespaces are refered using the alias for that namespace (if
|
||||||
|
defined), other vars are displayed fully qualified."
|
||||||
|
:type '(choice (const :tag "Suppress namespaces" none)
|
||||||
|
(const :tag "Show fully-qualified namespaces" qualified)
|
||||||
|
(const :tag "Show namespace aliases" tidy))
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.7.0"))
|
||||||
|
|
||||||
|
(defcustom cider-macroexpansion-print-metadata nil
|
||||||
|
"Determines if metadata is included in macroexpansion results."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'cider
|
||||||
|
:package-version '(cider . "0.9.0"))
|
||||||
|
|
||||||
|
(defun cider-sync-request:macroexpand (expander expr &optional display-namespaces)
|
||||||
|
"Macroexpand, using EXPANDER, the given EXPR.
|
||||||
|
The default for DISPLAY-NAMESPACES is taken from
|
||||||
|
`cider-macroexpansion-display-namespaces'."
|
||||||
|
(cider-ensure-op-supported "macroexpand")
|
||||||
|
(thread-first `("op" "macroexpand"
|
||||||
|
"expander" ,expander
|
||||||
|
"code" ,expr
|
||||||
|
"ns" ,(cider-current-ns)
|
||||||
|
"display-namespaces" ,(or display-namespaces
|
||||||
|
(symbol-name cider-macroexpansion-display-namespaces)))
|
||||||
|
(nconc (when cider-macroexpansion-print-metadata
|
||||||
|
'("print-meta" "true")))
|
||||||
|
(cider-nrepl-send-sync-request)
|
||||||
|
(nrepl-dict-get "expansion")))
|
||||||
|
|
||||||
|
(defun cider-macroexpand-undo (&optional arg)
|
||||||
|
"Undo the last macroexpansion, using `undo-only'.
|
||||||
|
ARG is passed along to `undo-only'."
|
||||||
|
(interactive)
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(undo-only arg)))
|
||||||
|
|
||||||
|
(defvar cider-last-macroexpand-expression nil
|
||||||
|
"Specify the last macroexpansion preformed.
|
||||||
|
This variable specifies both what was expanded and the expander.")
|
||||||
|
|
||||||
|
(defun cider-macroexpand-expr (expander expr)
|
||||||
|
"Macroexpand, use EXPANDER, the given EXPR."
|
||||||
|
(when-let* ((expansion (cider-sync-request:macroexpand expander expr)))
|
||||||
|
(setq cider-last-macroexpand-expression expr)
|
||||||
|
(cider-initialize-macroexpansion-buffer expansion (cider-current-ns))))
|
||||||
|
|
||||||
|
(defun cider-macroexpand-expr-inplace (expander)
|
||||||
|
"Substitute the form preceding point with its macroexpansion using EXPANDER."
|
||||||
|
(interactive)
|
||||||
|
(let* ((expansion (cider-sync-request:macroexpand expander (cider-last-sexp)))
|
||||||
|
(bounds (cons (save-excursion (clojure-backward-logical-sexp 1) (point)) (point))))
|
||||||
|
(cider-redraw-macroexpansion-buffer
|
||||||
|
expansion (current-buffer) (car bounds) (cdr bounds))))
|
||||||
|
|
||||||
|
(defun cider-macroexpand-again ()
|
||||||
|
"Repeat the last macroexpansion."
|
||||||
|
(interactive)
|
||||||
|
(cider-initialize-macroexpansion-buffer cider-last-macroexpand-expression (cider-current-ns)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-macroexpand-1 (&optional prefix)
|
||||||
|
"Invoke \\=`macroexpand-1\\=` on the expression preceding point.
|
||||||
|
If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
|
||||||
|
\\=`macroexpand-1\\=`."
|
||||||
|
(interactive "P")
|
||||||
|
(let ((expander (if prefix "macroexpand" "macroexpand-1")))
|
||||||
|
(cider-macroexpand-expr expander (cider-last-sexp))))
|
||||||
|
|
||||||
|
(defun cider-macroexpand-1-inplace (&optional prefix)
|
||||||
|
"Perform inplace \\=`macroexpand-1\\=` on the expression preceding point.
|
||||||
|
If invoked with a PREFIX argument, use \\=`macroexpand\\=` instead of
|
||||||
|
\\=`macroexpand-1\\=`."
|
||||||
|
(interactive "P")
|
||||||
|
(let ((expander (if prefix "macroexpand" "macroexpand-1")))
|
||||||
|
(cider-macroexpand-expr-inplace expander)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun cider-macroexpand-all ()
|
||||||
|
"Invoke \\=`macroexpand-all\\=` on the expression preceding point."
|
||||||
|
(interactive)
|
||||||
|
(cider-macroexpand-expr "macroexpand-all" (cider-last-sexp)))
|
||||||
|
|
||||||
|
(defun cider-macroexpand-all-inplace ()
|
||||||
|
"Perform inplace \\=`macroexpand-all\\=` on the expression preceding point."
|
||||||
|
(interactive)
|
||||||
|
(cider-macroexpand-expr-inplace "macroexpand-all"))
|
||||||
|
|
||||||
|
(defun cider-initialize-macroexpansion-buffer (expansion ns)
|
||||||
|
"Create a new Macroexpansion buffer with EXPANSION and namespace NS."
|
||||||
|
(pop-to-buffer (cider-create-macroexpansion-buffer))
|
||||||
|
(setq cider-buffer-ns ns)
|
||||||
|
(setq buffer-undo-list nil)
|
||||||
|
(let ((inhibit-read-only t)
|
||||||
|
(buffer-undo-list t))
|
||||||
|
(erase-buffer)
|
||||||
|
(insert (format "%s" expansion))
|
||||||
|
(goto-char (point-max))
|
||||||
|
(cider--font-lock-ensure)))
|
||||||
|
|
||||||
|
(defun cider-redraw-macroexpansion-buffer (expansion buffer start end)
|
||||||
|
"Redraw the macroexpansion with new EXPANSION.
|
||||||
|
Text in BUFFER from START to END is replaced with new expansion,
|
||||||
|
and point is placed after the expanded form."
|
||||||
|
(with-current-buffer buffer
|
||||||
|
(let ((buffer-read-only nil))
|
||||||
|
(goto-char start)
|
||||||
|
(delete-region start end)
|
||||||
|
(insert (format "%s" expansion))
|
||||||
|
(goto-char start)
|
||||||
|
(indent-sexp)
|
||||||
|
(forward-sexp))))
|
||||||
|
|
||||||
|
(declare-function cider-mode "cider-mode")
|
||||||
|
|
||||||
|
(defun cider-create-macroexpansion-buffer ()
|
||||||
|
"Create a new macroexpansion buffer."
|
||||||
|
(with-current-buffer (cider-popup-buffer cider-macroexpansion-buffer 'select 'clojure-mode 'ancillary)
|
||||||
|
(cider-mode -1)
|
||||||
|
(cider-macroexpansion-mode 1)
|
||||||
|
(current-buffer)))
|
||||||
|
|
||||||
|
(declare-function cider-find-var "cider-find")
|
||||||
|
|
||||||
|
(defvar cider-macroexpansion-mode-map
|
||||||
|
(let ((map (make-sparse-keymap)))
|
||||||
|
(define-key map (kbd "g") #'cider-macroexpand-again)
|
||||||
|
(define-key map (kbd "q") #'cider-popup-buffer-quit-function)
|
||||||
|
(define-key map (kbd "d") #'cider-doc)
|
||||||
|
(define-key map (kbd "j") #'cider-javadoc)
|
||||||
|
(define-key map (kbd ".") #'cider-find-var)
|
||||||
|
(define-key map (kbd "m") #'cider-macroexpand-1-inplace)
|
||||||
|
(define-key map (kbd "a") #'cider-macroexpand-all-inplace)
|
||||||
|
(define-key map (kbd "u") #'cider-macroexpand-undo)
|
||||||
|
(define-key map [remap undo] #'cider-macroexpand-undo)
|
||||||
|
(easy-menu-define cider-macroexpansion-mode-menu map
|
||||||
|
"Menu for CIDER's doc mode"
|
||||||
|
'("Macroexpansion"
|
||||||
|
["Restart expansion" cider-macroexpand-again]
|
||||||
|
["Macroexpand-1" cider-macroexpand-1-inplace]
|
||||||
|
["Macroexpand-all" cider-macroexpand-all-inplace]
|
||||||
|
["Macroexpand-undo" cider-macroexpand-undo]
|
||||||
|
["Go to source" cider-find-var]
|
||||||
|
["Go to doc" cider-doc]
|
||||||
|
["Go to Javadoc" cider-docview-javadoc]
|
||||||
|
["Quit" cider-popup-buffer-quit-function]))
|
||||||
|
map))
|
||||||
|
|
||||||
|
(define-minor-mode cider-macroexpansion-mode
|
||||||
|
"Minor mode for CIDER macroexpansion.
|
||||||
|
|
||||||
|
\\{cider-macroexpansion-mode-map}"
|
||||||
|
nil
|
||||||
|
" Macroexpand"
|
||||||
|
cider-macroexpansion-mode-map)
|
||||||
|
|
||||||
|
(provide 'cider-macroexpansion)
|
||||||
|
|
||||||
|
;;; cider-macroexpansion.el ends here
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue