mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-22 11:00:27 +10:00
Updating Doom Emacs.
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/ansible/packages.el
|
||||
|
||||
(package! yaml-mode)
|
||||
(package! ansible :recipe (:nonrecursive t))
|
||||
(package! ansible-doc)
|
||||
(package! jinja2-mode)
|
||||
(package! ansible :recipe (:nonrecursive t) :pin "c6532e52161a381ed3dddfeaa7c92ae636d3f052")
|
||||
(package! ansible-doc :pin "86083a7bb2ed0468ca64e52076b06441a2f8e9e0")
|
||||
(package! jinja2-mode :pin "4540f99a3e363403a633587e05a9707605c16473")
|
||||
(package! yaml-mode :pin "34648f2502f52f4744d62758fa381fa35db1da49")
|
||||
|
||||
(when (featurep! :completion company)
|
||||
(package! company-ansible))
|
||||
(package! company-ansible :pin "79dd421b161efa49fbdffad57fa40edb41f484a3"))
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
(pcase major-mode
|
||||
((or 'c-mode 'c++-mode)
|
||||
(realgud:gdb (if path (concat "gdb " path))))
|
||||
((or 'ruby-mode 'enh-ruby-mode)
|
||||
('ruby-mode
|
||||
;; FIXME
|
||||
(doom:repl nil (format "run '%s'" (file-name-nondirectory (or path buffer-file-name)))))
|
||||
('sh-mode
|
||||
|
||||
@@ -1,52 +1,28 @@
|
||||
;;; tools/debugger/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +debugger--realgud-alist
|
||||
'((realgud:zshdb :modes (sh-mode))
|
||||
(realgud:kshdb :modes (sh-mode))
|
||||
(realgud:rdebug :modes (ruby-mode enh-ruby-mode))
|
||||
(realgud:pdb :modes (python-mode))
|
||||
(realgud:trepan2 :modes (python-mode))
|
||||
(realgud:gub :modes (go-mode))
|
||||
'((realgud:bashdb :modes (sh-mode))
|
||||
(realgud:gdb)
|
||||
(realgud:trepan :modes (perl-mode perl6-mode))
|
||||
(realgud:trepanpl :modes (perl-mode perl6-mode))
|
||||
(realgud:trepanjs :modes (javascript-mode js2-mode js3-mode))
|
||||
(realgud:gub :modes (go-mode))
|
||||
(realgud:kshdb :modes (sh-mode))
|
||||
(realgud:pdb :modes (python-mode))
|
||||
(realgud:perldb :modes (perl-mode perl6-mode))
|
||||
(realgud:rdebug :modes (ruby-mode))
|
||||
(realgud:remake)
|
||||
(realgud:trepan :modes (perl-mode perl6-mode))
|
||||
(realgud:trepan2 :modes (python-mode))
|
||||
(realgud:trepan3k :modes (python-mode))
|
||||
(realgud:bashdb :modes (sh-mode))
|
||||
(realgud:perldb :modes (perl-mode perl6-mode))))
|
||||
(realgud:trepanjs :modes (javascript-mode js2-mode js3-mode))
|
||||
(realgud:trepanpl :modes (perl-mode perl6-mode))
|
||||
(realgud:zshdb :modes (sh-mode))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! dap-mode
|
||||
:when (featurep! :tools lsp)
|
||||
:hook (dap-mode . dap-ui-mode)
|
||||
:after lsp-mode
|
||||
:init
|
||||
(setq dap--breakpoints-file (concat doom-etc-dir "dap-breakpoints"))
|
||||
:config
|
||||
(dap-mode 1)
|
||||
(dolist (module '(((:lang . cc) ccls dap-lldb dap-gdb-lldb)
|
||||
((:lang . elixir) elixir-mode dap-elixir)
|
||||
((:lang . go) go-mode dap-go)
|
||||
((:lang . java) lsp-java dap-java)
|
||||
((:lang . php) php-mode dap-php)
|
||||
((:lang . python) python dap-python)
|
||||
((:lang . ruby) enh-ruby-mode dap-ruby)
|
||||
((:lang . rust) rust-mode dap-lldb)))
|
||||
(when (doom-module-p (caar module) (cdar module) '+lsp)
|
||||
(with-eval-after-load (nth 1 module)
|
||||
(mapc #'require (cddr module)))))
|
||||
|
||||
(when (featurep! :lang javascript +lsp)
|
||||
(with-eval-after-load 'js2-mode
|
||||
(require 'dap-node)
|
||||
(require 'dap-chrome)
|
||||
(require 'dap-firefox)
|
||||
(when IS-WINDOWS
|
||||
(require 'dap-edge)))))
|
||||
;;;###package gdb
|
||||
(setq gdb-show-main t
|
||||
gdb-many-windows t)
|
||||
|
||||
|
||||
(use-package! realgud
|
||||
@@ -104,9 +80,47 @@
|
||||
(if (boundp 'starting-directory)
|
||||
(realgud-cmdbuf-info-starting-directory= starting-directory))
|
||||
(set minibuffer-history-var
|
||||
(cl-remove-duplicates (cons cmd-str minibuffer-history)
|
||||
(cl-remove-duplicates (cons cmd-str (eval minibuffer-history-var))
|
||||
:from-end t))))))
|
||||
(t
|
||||
(if cmd-buf (switch-to-buffer cmd-buf))
|
||||
(message "Error running command: %s" (mapconcat #'identity cmd-args " "))))
|
||||
cmd-buf)))
|
||||
|
||||
|
||||
(use-package! dap-mode
|
||||
:when (and (featurep! +lsp) (not (featurep! :tools lsp +eglot)))
|
||||
:hook (dap-mode . dap-tooltip-mode)
|
||||
:after lsp-mode
|
||||
:demand t
|
||||
:preface
|
||||
(setq dap-breakpoints-file (concat doom-etc-dir "dap-breakpoints")
|
||||
dap-utils-extension-path (concat doom-etc-dir "dap-extension/"))
|
||||
:config
|
||||
(dolist (module '(((:lang . cc) ccls dap-lldb dap-gdb-lldb)
|
||||
((:lang . elixir) elixir-mode dap-elixir)
|
||||
((:lang . go) go-mode dap-go)
|
||||
((:lang . java) lsp-java dap-java)
|
||||
((:lang . php) php-mode dap-php)
|
||||
((:lang . python) python dap-python)
|
||||
((:lang . ruby) ruby-mode dap-ruby)
|
||||
((:lang . rust) rust-mode dap-lldb)))
|
||||
(when (doom-module-p (caar module) (cdar module) '+lsp)
|
||||
(with-eval-after-load (nth 1 module)
|
||||
(mapc #'require (cddr module)))))
|
||||
|
||||
(when (featurep! :lang javascript +lsp)
|
||||
(after! (:or js2-mode typescript-mode)
|
||||
(require 'dap-node)
|
||||
(require 'dap-chrome)
|
||||
(require 'dap-firefox)
|
||||
(when IS-WINDOWS
|
||||
(require 'dap-edge))))
|
||||
|
||||
(dap-mode 1))
|
||||
|
||||
|
||||
(use-package! dap-ui-mode
|
||||
:when (featurep! +lsp)
|
||||
:hook (dap-mode . dap-ui-mode)
|
||||
:hook (dap-ui-mode . dap-ui-controls-mode))
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/debugger/packages.el
|
||||
|
||||
(when (package! realgud)
|
||||
(when (package! realgud :pin "1238d8e72945a84bb06cd39d7ded75f37105d4d2")
|
||||
(when (featurep! :lang javascript)
|
||||
(package! realgud-trepan-ni)))
|
||||
(package! realgud-trepan-ni :pin "6e9cac5e8097018aadf41c88de541168036cc227")))
|
||||
|
||||
(when (featurep! :tools lsp)
|
||||
(package! dap-mode))
|
||||
(when (featurep! +lsp)
|
||||
(package! dap-mode :pin "7ad915794b75481f12b3f02ac8f5c9bcfddd6938")
|
||||
(package! posframe :pin "6285217711bc846e565940261829b523e298f82e"))
|
||||
|
||||
@@ -67,27 +67,8 @@ Or ~nix-env -i direnv~
|
||||
* Troubleshooting
|
||||
** direnv + nix is slow
|
||||
Consider augmenting direnv with [[https://github.com/target/lorri][lorri]], which will cache nix builds and speed up
|
||||
direnv tremendously.
|
||||
|
||||
At the time of writing, the lorri package in nixpkgs simply emits an error
|
||||
message, telling you to install it manually. You can get around this with:
|
||||
direnv tremendously:
|
||||
|
||||
#+BEGIN_SRC nix
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
lorri =
|
||||
let src = (super.fetchFromGitHub {
|
||||
owner = "target";
|
||||
repo = "lorri";
|
||||
rev = "38eae3d487526ece9d1b8c9bb0d27fb45cf60816";
|
||||
sha256 = "11k9lxg9cv6dlxj4haydvw4dhcfyszwvx7jx9p24jadqsy9jmbj4";
|
||||
});
|
||||
in import src { inherit src; };
|
||||
})
|
||||
];
|
||||
|
||||
environment.systemPackages = [ pkgs.lorri ];
|
||||
services.lorri.enable = true;
|
||||
#+END_SRC
|
||||
|
||||
Otherwise, follow [[https://github.com/target/lorri#installing-lorri][the instructions in lorri's README]] on how to install it
|
||||
manually.
|
||||
|
||||
@@ -1,69 +1,34 @@
|
||||
;;; tools/direnv/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +direnv--keywords
|
||||
(defvar +direnv-keywords
|
||||
'("direnv_layout_dir" "PATH_add" "path_add" "log_status" "log_error" "has"
|
||||
"join_args" "expand_path" "dotenv" "user_rel_path" "find_up" "source_env"
|
||||
"watch_file" "source_up" "direnv_load" "MANPATH_add" "load_prefix" "layout"
|
||||
"use" "rvm" "use_nix" "use_guix")
|
||||
"TODO")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! direnv
|
||||
:after-call after-find-file dired-initial-position-hook
|
||||
:hook (before-hack-local-variables . direnv--maybe-update-environment)
|
||||
:hook (flycheck-before-syntax-check . direnv--maybe-update-environment)
|
||||
:hook (direnv-envrc-mode . +direnv-envrc-fontify-keywords-h)
|
||||
:config
|
||||
(add-hook! 'direnv-mode-hook
|
||||
(defun +direnv-init-h ()
|
||||
"Instead of checking for direnv on `post-command-hook', check only once,
|
||||
when the file is first opened/major mode is activated. This is significantly
|
||||
less expensive, but is less sensitive to changes to .envrc done outside of
|
||||
Emacs."
|
||||
(direnv--disable)
|
||||
(when direnv-mode
|
||||
(add-hook 'after-change-major-mode-hook
|
||||
#'direnv--maybe-update-environment))))
|
||||
(add-to-list 'direnv-non-file-modes 'vterm-mode)
|
||||
|
||||
(defadvice! +direnv--make-process-environment-buffer-local-a (items)
|
||||
:filter-return #'direnv--export
|
||||
(when items
|
||||
(mapc 'kill-local-variable '(process-environment exec-path))
|
||||
(mapc 'make-local-variable '(process-environment exec-path)))
|
||||
items)
|
||||
(defun +direnv-envrc-fontify-keywords-h ()
|
||||
"Fontify special .envrc keywords; it's a good indication of whether or not
|
||||
we've typed them correctly."
|
||||
(font-lock-add-keywords
|
||||
nil `((,(regexp-opt +direnv-keywords 'symbols)
|
||||
(0 font-lock-keyword-face)))))
|
||||
|
||||
;; Fontify special .envrc keywords; it's a good indication of whether or not
|
||||
;; we've typed them correctly.
|
||||
(add-hook! 'direnv-envrc-mode-hook
|
||||
(defun +direnv-envrc-fontify-keywords-h ()
|
||||
(font-lock-add-keywords
|
||||
nil `((,(regexp-opt +direnv--keywords 'symbols)
|
||||
(0 font-lock-keyword-face)))))
|
||||
(defun +direnv-update-on-save-h ()
|
||||
(add-hook 'after-save-hook #'direnv--maybe-update-environment
|
||||
nil 'local)))
|
||||
|
||||
(defadvice! +direnv-update-a (&rest _)
|
||||
"Update direnv. Useful to advise functions that may run
|
||||
environment-sensitive logic like `flycheck-default-executable-find'. This fixes
|
||||
flycheck issues with direnv and on nix."
|
||||
:before #'flycheck-default-executable-find
|
||||
(direnv--maybe-update-environment))
|
||||
|
||||
(defadvice! +direnv--fail-gracefully-a (orig-fn)
|
||||
"Don't try to update direnv if the executable isn't present."
|
||||
:around #'direnv--maybe-update-environment
|
||||
(if (executable-find "direnv")
|
||||
(when (file-readable-p (or buffer-file-name default-directory))
|
||||
(funcall orig-fn))
|
||||
(doom-log "Couldn't find direnv executable")))
|
||||
|
||||
(defadvice! +direnv-update-async-shell-command-a (command &optional output-buffer _error-buffer)
|
||||
:before #'shell-command
|
||||
(when (string-match "[ \t]*&[ \t]*\\'" command)
|
||||
(let ((environment process-environment)
|
||||
(path exec-path)
|
||||
(shell shell-file-name))
|
||||
(with-current-buffer
|
||||
(get-buffer-create (or output-buffer "*Async Shell Command*"))
|
||||
(setq-local process-environment environment)
|
||||
(setq-local exec-path path)
|
||||
(setq-local shell-file-name shell)))))
|
||||
(defadvice! +direnv--fail-gracefully-a (&rest _)
|
||||
"Don't try to use direnv if the executable isn't present."
|
||||
:before-while #'direnv-update-directory-environment
|
||||
(or (executable-find "direnv")
|
||||
(ignore (doom-log "Couldn't find direnv executable"))))
|
||||
|
||||
(direnv-mode +1))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/direnv/packages.el
|
||||
|
||||
(package! direnv)
|
||||
(package! direnv :pin "f5484b0fc33d4e5116612626294efb362ff9ecd4")
|
||||
|
||||
@@ -29,7 +29,7 @@ convenience functions allow images to be built easily.
|
||||
=docker-tramp.el= offers a [[https://www.gnu.org/software/tramp/][TRAMP]] method for Docker containers.
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
+ =+lsp= Enables integration for the Dockerfile Language Server.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/Silex/docker.el][docker]]
|
||||
@@ -40,6 +40,10 @@ This module provides no flags.
|
||||
This module assumes =docker=, =docker-compose= and =docker-machine= binaries
|
||||
are installed and accessible from your PATH.
|
||||
|
||||
Optionally, this module also uses the following programs:
|
||||
|
||||
+ =docker-langserver= (for LSP users): ~npm install -g dockerfile-language-server-nodejs~
|
||||
|
||||
* Features
|
||||
** Docker control
|
||||
Use =M-x docker=, select a resource, and then mark or unmark items using the
|
||||
|
||||
@@ -8,3 +8,9 @@
|
||||
docker-volume-mode
|
||||
docker-machine-mode)
|
||||
'emacs))
|
||||
|
||||
(after! dockerfile-mode
|
||||
(set-docsets! 'dockerfile-mode "Docker")
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'dockerfile-mode-local-vars-hook #'lsp!)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/docker/packages.el
|
||||
|
||||
(package! docker)
|
||||
(package! docker-tramp)
|
||||
(package! dockerfile-mode)
|
||||
(package! docker :pin "d6233bdb9ccaee4da7cdc0ef162bfe4727227142")
|
||||
(package! docker-tramp :pin "8e2b671eff7a81af43b76d9dfcf94ddaa8333a23")
|
||||
(package! dockerfile-mode :pin "d31f7685ebc5832d957e25070a930aa42984327d")
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
;; appending an extension to `buffer-file-name' when we talk to editorconfig.
|
||||
(defvar +editorconfig-mode-alist
|
||||
'((emacs-lisp-mode . "el")
|
||||
(enh-ruby-mode . "rb")
|
||||
(js2-mode . "js")
|
||||
(perl-mode . "pl")
|
||||
(php-mode . "php")
|
||||
@@ -20,8 +19,11 @@
|
||||
;; Handles whitespace (tabs/spaces) settings externally. This way projects can
|
||||
;; specify their own formatting rules.
|
||||
(use-package! editorconfig
|
||||
:after-call doom-switch-buffer-hook after-find-file
|
||||
:hook (doom-first-buffer . editorconfig-mode)
|
||||
:config
|
||||
(when (require 'ws-butler nil t)
|
||||
(setq editorconfig-trim-whitespaces-mode 'ws-butler-mode))
|
||||
|
||||
(defadvice! +editorconfig--smart-detection-a (orig-fn)
|
||||
"Retrieve the properties for the current file. If it doesn't have an
|
||||
extension, try to guess one."
|
||||
@@ -31,25 +33,15 @@ extension, try to guess one."
|
||||
(file-name-extension buffer-file-name))
|
||||
buffer-file-name
|
||||
(format "%s%s" (buffer-file-name (buffer-base-buffer))
|
||||
(if-let* ((ext (cdr (assq major-mode +editorconfig-mode-alist))))
|
||||
(if-let (ext (alist-get major-mode +editorconfig-mode-alist))
|
||||
(concat "." ext)
|
||||
"")))))
|
||||
(funcall orig-fn)))
|
||||
|
||||
(add-hook! 'editorconfig-after-apply-functions
|
||||
(defun +editorconfig-disable-ws-butler-maybe-h (props)
|
||||
"Disable `ws-butler-mode' if trim_trailing_whitespace is true."
|
||||
(when (and (equal (gethash 'trim_trailing_whitespace props) "true")
|
||||
(bound-and-true-p ws-butler-mode))
|
||||
(ws-butler-mode -1))))
|
||||
|
||||
(add-hook! 'editorconfig-after-apply-functions
|
||||
(defun +editorconfig-disable-indent-detection-h (props)
|
||||
"Inhibit `dtrt-indent' if an explicit indent_style and indent_size is
|
||||
specified by editorconfig."
|
||||
(when (or (gethash 'indent_style props)
|
||||
(gethash 'indent_size props))
|
||||
(setq doom-inhibit-indent-detection 'editorconfig))))
|
||||
|
||||
;;
|
||||
(editorconfig-mode +1))
|
||||
(setq doom-inhibit-indent-detection 'editorconfig)))))
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/editorconfig/packages.el
|
||||
|
||||
(package! editorconfig :recipe (:nonrecursive t))
|
||||
(package! editorconfig
|
||||
:recipe (:nonrecursive t)
|
||||
:pin "9a73ff743b9fe820301ea9b5c5c7804bfc967324")
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#interaction-with-a-jupyter-server][Interaction with a Jupyter server]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#setting-the-default-location-of-your-notebooks][Setting the default location of your notebooks]]
|
||||
- [[#using-hydra][Using hydra]]
|
||||
|
||||
* Description
|
||||
Adds Jupyter notebook integration into emacs.
|
||||
@@ -27,41 +23,4 @@ This module provides no flags.
|
||||
This module has no prereqisites.
|
||||
|
||||
* Features
|
||||
** Interaction with a Jupyter server
|
||||
Three functions are available to start EIN:
|
||||
|
||||
1. ~ein:jupyter-server-start~ --- Start a jupyter server within emacs
|
||||
2. ~ein:notebooklist-login~ --- Login to an existing jupyter server
|
||||
3. ~ein:notebooklist-open~ --- Open the list of jupyter notebooks
|
||||
|
||||
These functions do not have default key bindings.
|
||||
|
||||
When ~ein:jupyter-server-start~ is called, after successfully finishing,
|
||||
~ein:notebooklist-login~ and ~ein:notebooklist-open~ will be automatically
|
||||
called.
|
||||
|
||||
When in the ~Notebook List~ buffer, the key =o= calls ~ace-link~ to speed up the
|
||||
process of selecting links in the buffer.
|
||||
|
||||
If ~company-mode~ is enabled as a module, ~company-ein~ will handle completion.
|
||||
|
||||
* Configuration
|
||||
** Setting the default location of your notebooks
|
||||
Change ~+ein-notebook-dir~ to tell ein where to find your Jupityr notebooks.
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq +ein-notebook-dir "~/my-notebooks")
|
||||
#+END_SRC
|
||||
|
||||
** Using hydra
|
||||
This module provides a batteries-included hydra - ~+ein/hydra~ - to make using ein
|
||||
easier. Things like navigating between cells, workbook management etc, are greatly
|
||||
simplified and are easily accessible. However, by default, it's not bound to any key.
|
||||
Here's an example of how to bind it:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(map! :map ein:notebook-mode-map
|
||||
:localleader
|
||||
"," #'+ein/hydra/body)
|
||||
#+END_SRC
|
||||
|
||||
Please refer [[https://github.com/millejoh/emacs-ipython-notebook][millejoh/emacs-ipython-notebook's README]].
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
;;; tools/ein/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defun +ein--collect-ein-buffer-links ()
|
||||
(let ((end (window-end))
|
||||
points)
|
||||
(save-excursion
|
||||
(goto-char (window-start))
|
||||
(while (re-search-forward "~?/.+\\|\s\\[" end t)
|
||||
(push (+ (match-beginning 0) 1) points))
|
||||
(nreverse points))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +ein/ace-link-ein ()
|
||||
"Ace jump to links in ein notebooklist."
|
||||
(interactive)
|
||||
(require 'avy)
|
||||
(let ((res (avy-with +ein/ace-link-ein
|
||||
(avy--process
|
||||
(+ein--collect-ein-buffer-links)
|
||||
#'avy--overlay-pre))))
|
||||
;(avy--style-fn avy-style)))))
|
||||
(when (numberp res)
|
||||
(goto-char (1+ res))
|
||||
(widget-button-press (point)))))
|
||||
@@ -1,47 +0,0 @@
|
||||
;;; tools/ein/autoload/hydra.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :ui hydra)
|
||||
|
||||
;;;###autoload (autoload '+ein/hydra/body "tools/ein/autoload/hydra" nil t)
|
||||
(defhydra +ein/hydra (:hint t :color red)
|
||||
"
|
||||
Operations on Cells^^^^^^ Other
|
||||
----------------------------^^^^^^ ----------------------------------^^^^
|
||||
[_k_/_j_]^^ select prev/next [_t_]^^ toggle output
|
||||
[_K_/_J_]^^ move up/down [_C-l_/_C-S-l_] clear/clear all output
|
||||
[_C-k_/_C-j_]^^ merge above/below [_C-o_]^^ open console
|
||||
[_O_/_o_]^^ insert above/below [_C-s_/_C-r_] save/rename notebook
|
||||
[_y_/_p_/_d_] copy/paste [_x_]^^ close notebook
|
||||
[_u_]^^^^ change type [_q_]^^ quit
|
||||
[_RET_]^^^^ execute
|
||||
"
|
||||
("q" nil :exit t)
|
||||
("h" ein:notebook-worksheet-open-prev-or-last)
|
||||
("j" ein:worksheet-goto-next-input)
|
||||
("k" ein:worksheet-goto-prev-input)
|
||||
("l" ein:notebook-worksheet-open-next-or-first)
|
||||
("H" ein:notebook-worksheet-move-prev)
|
||||
("J" ein:worksheet-move-cell-down)
|
||||
("K" ein:worksheet-move-cell-up)
|
||||
("L" ein:notebook-worksheet-move-next)
|
||||
("t" ein:worksheet-toggle-output)
|
||||
("d" ein:worksheet-kill-cell)
|
||||
("R" ein:worksheet-rename-sheet)
|
||||
("y" ein:worksheet-copy-cell)
|
||||
("p" ein:worksheet-yank-cell)
|
||||
("o" ein:worksheet-insert-cell-below)
|
||||
("O" ein:worksheet-insert-cell-above)
|
||||
("u" ein:worksheet-change-cell-type)
|
||||
("RET" ein:worksheet-execute-cell-and-goto-next)
|
||||
;; Output
|
||||
("C-l" ein:worksheet-clear-output)
|
||||
("C-S-l" ein:worksheet-clear-all-output)
|
||||
;;Console
|
||||
("C-o" ein:console-open :exit t)
|
||||
;; Merge and split cells
|
||||
("C-k" ein:worksheet-merge-cell)
|
||||
("C-j" spacemacs/ein:worksheet-merge-cell-next)
|
||||
("s" ein:worksheet-split-cell-at-point)
|
||||
;; Notebook
|
||||
("C-s" ein:notebook-save-notebook-command)
|
||||
("C-r" ein:notebook-rename-command)
|
||||
("x" ein:notebook-close :exit t))
|
||||
@@ -1,43 +1,14 @@
|
||||
;;; tools/ein/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +ein-notebook-dir "~/"
|
||||
"Default directory from where Jupyter notebooks are to be opened.")
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
|
||||
(after! ein
|
||||
(setq ein:notebook-modes
|
||||
'(ein:notebook-multilang-mode
|
||||
ein:notebook-python-mode
|
||||
ein:notebook-plain-mode)
|
||||
;; Slice images into rows; easier to navigate around images
|
||||
ein:slice-image t)
|
||||
|
||||
(set-popup-rules!
|
||||
'(("\\*ein: .*" :ignore t)
|
||||
("\\*ein:tb .*" :side 'bottom :size 0.3 :quit t :ttl nil :select nil)
|
||||
("\\*ein:notebooklist *" :side 'left :size 50 :select nil)))
|
||||
|
||||
(when (featurep! :completion company)
|
||||
;; Code completion with company
|
||||
(setq ein:completion-backend 'ein:use-company-backend)
|
||||
(set-company-backend! '(ein:notebook-multilang-mode
|
||||
ein:notebook-python-mode
|
||||
ein:notebook-plain-mode)
|
||||
'ein:company-backend))
|
||||
|
||||
(after! ein-jupyter
|
||||
(setq ein:jupyter-server-args '("--no-browser"))
|
||||
(unless ein:jupyter-default-notebook-directory
|
||||
(setq ein:jupyter-default-notebook-directory "~/")))
|
||||
;;; Packages
|
||||
|
||||
(after! ein-notebook
|
||||
(defun +ein-buffer-p (buf)
|
||||
(string-match-p "^\\*ein: .*" (buffer-name buf)))
|
||||
(or (memq buf (ein:notebook-opened-buffers))
|
||||
(memq buf (mapcar #'ein:notebooklist-get-buffer (ein:notebooklist-keys)))))
|
||||
(add-to-list 'doom-real-buffer-functions #'+ein-buffer-p nil #'eq)
|
||||
|
||||
(map! :map ein:notebook-mode-map
|
||||
"M-s" #'ein:notebook-save-notebook-command
|
||||
"M-s" #'ein:notebook-save-notebook-command-km
|
||||
:map ein:notebooklist-mode-map
|
||||
"o" #'+ein/ace-link-ein))
|
||||
"o" #'ein:notebook-open-km))
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/ein/packages.el
|
||||
|
||||
(package! ein)
|
||||
(package! avy)
|
||||
(package! ein :pin "ee31cdb77de397bdff01abf5ffa087f384517f0c")
|
||||
|
||||
@@ -3,27 +3,22 @@
|
||||
;;;###autoload
|
||||
(defun +eval-display-results-in-popup (output &optional _source-buffer)
|
||||
"Display OUTPUT in a popup buffer."
|
||||
(if (with-temp-buffer
|
||||
(insert output)
|
||||
(>= (count-lines (point-min) (point-max))
|
||||
+eval-popup-min-lines))
|
||||
(let ((output-buffer (get-buffer-create "*doom eval*"))
|
||||
(origin (selected-window)))
|
||||
(with-current-buffer output-buffer
|
||||
(setq-local scroll-margin 0)
|
||||
(erase-buffer)
|
||||
(insert output)
|
||||
(goto-char (point-min))
|
||||
(if (fboundp '+word-wrap-mode)
|
||||
(+word-wrap-mode +1)
|
||||
(visual-line-mode +1)))
|
||||
(when-let (win (display-buffer output-buffer))
|
||||
(fit-window-to-buffer
|
||||
win (/ (frame-height) 2)
|
||||
nil (/ (frame-width) 2)))
|
||||
(select-window origin)
|
||||
output-buffer)
|
||||
(message "%s" output)))
|
||||
(let ((output-buffer (get-buffer-create "*doom eval*"))
|
||||
(origin (selected-window)))
|
||||
(with-current-buffer output-buffer
|
||||
(setq-local scroll-margin 0)
|
||||
(erase-buffer)
|
||||
(insert output)
|
||||
(goto-char (point-min))
|
||||
(if (fboundp '+word-wrap-mode)
|
||||
(+word-wrap-mode +1)
|
||||
(visual-line-mode +1)))
|
||||
(when-let (win (display-buffer output-buffer))
|
||||
(fit-window-to-buffer
|
||||
win (/ (frame-height) 2)
|
||||
nil (/ (frame-width) 2)))
|
||||
(select-window origin)
|
||||
output-buffer))
|
||||
|
||||
;;;###autoload
|
||||
(defun +eval-display-results-in-overlay (output &optional source-buffer)
|
||||
@@ -42,8 +37,14 @@
|
||||
(funcall (if (or current-prefix-arg
|
||||
(with-temp-buffer
|
||||
(insert output)
|
||||
(>= (count-lines (point-min) (point-max))
|
||||
+eval-popup-min-lines))
|
||||
(or (>= (count-lines (point-min) (point-max))
|
||||
+eval-popup-min-lines)
|
||||
(>= (string-width
|
||||
(buffer-substring (point-min)
|
||||
(save-excursion
|
||||
(goto-char (point-min))
|
||||
(line-end-position))))
|
||||
(window-width))))
|
||||
(not (require 'eros nil t)))
|
||||
#'+eval-display-results-in-popup
|
||||
#'+eval-display-results-in-overlay)
|
||||
|
||||
@@ -37,8 +37,10 @@ recognized:
|
||||
"Alist mapping major modes to interactive runner functions.")
|
||||
|
||||
;;;###autodef
|
||||
(defun set-eval-handler! (mode command)
|
||||
"Define a code evaluator for major mode MODE with `quickrun'.
|
||||
(defun set-eval-handler! (modes command)
|
||||
"Define a code evaluator for major mode MODES with `quickrun'.
|
||||
|
||||
MODES can be list of major mode symbols, or a single one.
|
||||
|
||||
1. If MODE is a string and COMMAND is the string, MODE is a file regexp and
|
||||
COMMAND is a string key for an entry in `quickrun-file-alist'.
|
||||
@@ -50,17 +52,18 @@ recognized:
|
||||
4. If MODE is not a string and COMMANd is a symbol, add it to
|
||||
`+eval-runners', which is used by `+eval/region'."
|
||||
(declare (indent defun))
|
||||
(cond ((symbolp command)
|
||||
(push (cons mode command) +eval-runners))
|
||||
((stringp command)
|
||||
(after! quickrun
|
||||
(push (cons mode command)
|
||||
(if (stringp mode)
|
||||
quickrun-file-alist
|
||||
quickrun--major-mode-alist))))
|
||||
((listp command)
|
||||
(after! quickrun
|
||||
(quickrun-add-command
|
||||
(or (cdr (assq mode quickrun--major-mode-alist))
|
||||
(string-remove-suffix "-mode" (symbol-name mode)))
|
||||
command :mode mode)))))
|
||||
(dolist (mode (doom-enlist modes))
|
||||
(cond ((symbolp command)
|
||||
(push (cons mode command) +eval-runners))
|
||||
((stringp command)
|
||||
(after! quickrun
|
||||
(push (cons mode command)
|
||||
(if (stringp mode)
|
||||
quickrun-file-alist
|
||||
quickrun--major-mode-alist))))
|
||||
((listp command)
|
||||
(after! quickrun
|
||||
(quickrun-add-command
|
||||
(or (cdr (assq mode quickrun--major-mode-alist))
|
||||
(string-remove-suffix "-mode" (symbol-name mode)))
|
||||
command :mode mode))))))
|
||||
|
||||
@@ -68,23 +68,32 @@ buffer rather than an overlay on the line at point or the minibuffer.")
|
||||
(with-selected-window win
|
||||
(goto-char (point-min))))))
|
||||
|
||||
;; Display evaluation results in an overlay next to the cursor. If the output
|
||||
;; is more than 4 lines long, it is displayed in a popup.
|
||||
;; Display evaluation results in an overlay at the end of the current line. If
|
||||
;; the output is more than `+eval-popup-min-lines' (4) lines long, it is
|
||||
;; displayed in a popup.
|
||||
(when (featurep! +overlay)
|
||||
(defadvice! +eval--show-output-in-overlay-a (fn)
|
||||
:filter-return #'quickrun--make-sentinel
|
||||
(lambda (process event)
|
||||
(funcall fn process event)
|
||||
(with-current-buffer quickrun--buffer-name
|
||||
(when (> (buffer-size) 0)
|
||||
(+eval-display-results
|
||||
(string-trim (buffer-string))
|
||||
quickrun--original-buffer)))))
|
||||
|
||||
;; Suppress quickrun's popup window because we're using an overlay instead.
|
||||
(defadvice! +eval--inhibit-quickrun-popup-a (buf cb)
|
||||
:override #'quickrun--pop-to-buffer
|
||||
(setq quickrun--original-buffer (current-buffer))
|
||||
(with-current-buffer buf
|
||||
(setq quickrun-option-outputter #'ignore)
|
||||
(funcall cb)))
|
||||
(save-window-excursion
|
||||
(with-current-buffer (pop-to-buffer buf)
|
||||
(setq quickrun-option-outputter #'ignore)
|
||||
(funcall cb))))
|
||||
|
||||
(advice-add #'quickrun--recenter :override #'ignore)
|
||||
(add-hook! 'quickrun-after-run-hook
|
||||
(defun +eval-display-in-popup-overlay-h ()
|
||||
(+eval-display-results
|
||||
(with-current-buffer quickrun--buffer-name
|
||||
(string-trim (buffer-string)))
|
||||
quickrun--original-buffer)))))
|
||||
;; HACK Without this, `+eval--inhibit-quickrun-popup-a' throws a
|
||||
;; window-live-p error because no window exists to be recentered!
|
||||
(advice-add #'quickrun--recenter :override #'ignore)))
|
||||
|
||||
|
||||
(use-package! eros
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/eval/packages.el
|
||||
|
||||
(package! quickrun)
|
||||
(package! quickrun :pin "c6ce1f315b768af8688d06bc57d2eb403f875a63")
|
||||
(when (featurep! +overlay)
|
||||
(package! eros))
|
||||
(package! eros :pin "dd8910279226259e100dab798b073a52f9b4233a"))
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
;;; tools/flycheck/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +flycheck-init-popups-h ()
|
||||
"Activate `flycheck-posframe-mode' if available and in GUI Emacs.
|
||||
Activate `flycheck-popup-tip-mode' otherwise.
|
||||
Do nothing if `lsp-ui-mode' is active and `lsp-ui-sideline-enable' is non-nil."
|
||||
(unless (and (bound-and-true-p lsp-ui-mode)
|
||||
lsp-ui-sideline-enable)
|
||||
(if (and (fboundp 'flycheck-posframe-mode)
|
||||
(display-graphic-p))
|
||||
(flycheck-posframe-mode +1)
|
||||
(flycheck-popup-tip-mode +1))))
|
||||
@@ -1,80 +0,0 @@
|
||||
;;; tools/flycheck/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +flycheck-lazy-idle-delay 3.0
|
||||
"The delay before flycheck checks the buffer, after a check that produces no
|
||||
errors.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! flycheck
|
||||
:commands flycheck-list-errors flycheck-buffer
|
||||
:after-call doom-switch-buffer-hook after-find-file
|
||||
:config
|
||||
(setq flycheck-emacs-lisp-load-path 'inherit)
|
||||
|
||||
;; Check only when saving or opening files. Newline & idle checks are a mote
|
||||
;; excessive, especially when that can easily catch code in an incomplete
|
||||
;; state, so we removed them.
|
||||
(setq flycheck-check-syntax-automatically '(save mode-enabled))
|
||||
|
||||
;; Display errors a little quicker (default is 0.9s)
|
||||
(setq flycheck-display-errors-delay 0.25)
|
||||
|
||||
;; Don't commandeer input focus if the error message pops up (happens when
|
||||
;; tooltips and childframes are disabled).
|
||||
(set-popup-rule! "^\\*Flycheck error messages\\*" :select nil)
|
||||
|
||||
(add-hook! 'doom-escape-hook :append
|
||||
(defun +flycheck-buffer-h ()
|
||||
"Flycheck buffer on ESC in normal mode."
|
||||
(when flycheck-mode
|
||||
(ignore-errors (flycheck-buffer))
|
||||
nil)))
|
||||
|
||||
(map! :map flycheck-error-list-mode-map
|
||||
:n "C-n" #'flycheck-error-list-next-error
|
||||
:n "C-p" #'flycheck-error-list-previous-error
|
||||
:n "j" #'flycheck-error-list-next-error
|
||||
:n "k" #'flycheck-error-list-previous-error
|
||||
:n "RET" #'flycheck-error-list-goto-error
|
||||
:n [return] #'flycheck-error-list-goto-error)
|
||||
|
||||
(global-flycheck-mode +1))
|
||||
|
||||
|
||||
(use-package! flycheck-popup-tip
|
||||
:commands flycheck-popup-tip-show-popup flycheck-popup-tip-delete-popup
|
||||
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
|
||||
:config
|
||||
(setq flycheck-popup-tip-error-prefix "✕ ")
|
||||
(after! evil
|
||||
;; Don't display popups while in insert or replace mode, as it can affect
|
||||
;; the cursor's position or cause disruptive input delays.
|
||||
(add-hook! '(evil-insert-state-entry-hook evil-replace-state-entry-hook)
|
||||
#'flycheck-popup-tip-delete-popup)
|
||||
(defadvice! +flycheck--disable-popup-tip-maybe-a (&rest _)
|
||||
:before-while #'flycheck-popup-tip-show-popup
|
||||
(if evil-local-mode
|
||||
(eq evil-state 'normal)
|
||||
(not (bound-and-true-p company-backend))))))
|
||||
|
||||
|
||||
(use-package! flycheck-posframe
|
||||
:when (featurep! +childframe)
|
||||
:defer t
|
||||
:init (add-hook 'flycheck-mode-hook #'+flycheck-init-popups-h)
|
||||
:config
|
||||
(setq flycheck-posframe-warning-prefix "⚠ "
|
||||
flycheck-posframe-info-prefix "··· "
|
||||
flycheck-posframe-error-prefix "✕ ")
|
||||
(after! company
|
||||
;; Don't display popups if company is open
|
||||
(add-hook 'flycheck-posframe-inhibit-functions #'company--active-p))
|
||||
(after! evil
|
||||
;; Don't display popups while in insert or replace mode, as it can affect
|
||||
;; the cursor's position or cause disruptive input delays.
|
||||
(add-hook! 'flycheck-posframe-inhibit-functions
|
||||
#'evil-insert-state-p
|
||||
#'evil-replace-state-p)))
|
||||
@@ -1,7 +0,0 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/flycheck/packages.el
|
||||
|
||||
(package! flycheck)
|
||||
(package! flycheck-popup-tip)
|
||||
(when (featurep! +childframe)
|
||||
(package! flycheck-posframe))
|
||||
@@ -1,27 +0,0 @@
|
||||
;;; tools/flyspell/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'flyspell-mode! #'flyspell-mode)
|
||||
|
||||
(defvar +flyspell--predicate-alist nil
|
||||
"TODO")
|
||||
|
||||
;;;###autodef
|
||||
(defun set-flyspell-predicate! (modes predicate)
|
||||
"TODO"
|
||||
(declare (indent defun))
|
||||
(dolist (mode (doom-enlist modes) +flyspell--predicate-alist)
|
||||
(add-to-list '+flyspell--predicate-alist (cons mode predicate))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +flyspell-init-predicate-h ()
|
||||
"TODO"
|
||||
(when-let (pred (assq major-mode +flyspell--predicate-alist))
|
||||
(setq-local flyspell-generic-check-word-predicate (cdr pred))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +flyspell-correction-at-point-p (&optional point)
|
||||
"TODO"
|
||||
(cl-loop for ov in (overlays-at (or point (point)))
|
||||
if (overlay-get ov 'flyspell-overlay)
|
||||
return t))
|
||||
@@ -1,84 +0,0 @@
|
||||
;;; tools/flyspell/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(after! ispell
|
||||
(add-to-list 'ispell-extra-args "--dont-tex-check-comments")
|
||||
|
||||
;; Don't spellcheck org blocks
|
||||
(pushnew! ispell-skip-region-alist
|
||||
'(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")
|
||||
'("#\\+BEGIN_SRC" . "#\\+END_SRC")
|
||||
'("#\\+BEGIN_EXAMPLE" . "#\\+END_EXAMPLE"))
|
||||
|
||||
;; Enable either aspell or hunspell.
|
||||
;; If no module flags are given, enable either aspell or hunspell if their
|
||||
;; binary is found.
|
||||
;; If one of the flags `+aspell' or `+hunspell' is given, only enable that
|
||||
;; spell checker.
|
||||
(pcase (cond ((featurep! +aspell) 'aspell)
|
||||
((featurep! +hunspell) 'hunspell)
|
||||
((executable-find "aspell") 'aspell)
|
||||
((executable-find "hunspell") 'hunspell))
|
||||
(`aspell
|
||||
(setq ispell-program-name "aspell"
|
||||
ispell-extra-args '("--sug-mode=ultra" "--run-together"))
|
||||
|
||||
(add-hook! 'text-mode-hook
|
||||
(defun +flyspell-remove-run-together-switch-for-aspell-h ()
|
||||
(setq-local ispell-extra-args (remove "--run-together" ispell-extra-args))))
|
||||
|
||||
(defun +flyspell-setup-ispell-extra-args-a (orig-fun &rest args)
|
||||
:around '(ispell-word flyspell-auto-correct-word)
|
||||
(let ((ispell-extra-args (remove "--run-together" ispell-extra-args)))
|
||||
(ispell-kill-ispell t)
|
||||
(apply orig-fun args)
|
||||
(ispell-kill-ispell t))))
|
||||
|
||||
(`hunspell
|
||||
(setq ispell-program-name "hunspell"))
|
||||
|
||||
(_ (doom-log "Spell checker not found. Either install `aspell' or `hunspell'"))))
|
||||
|
||||
|
||||
;;;###package flyspell
|
||||
(progn ; built-in
|
||||
(setq flyspell-issue-welcome-flag nil
|
||||
;; Significantly speeds up flyspell, which would otherwise print
|
||||
;; messages for every word when checking the entire buffer
|
||||
flyspell-issue-message-flag nil)
|
||||
|
||||
(add-hook 'text-mode-hook #'flyspell-mode)
|
||||
(when (featurep! +prog)
|
||||
(add-hook 'prog-mode-hook #'flyspell-prog-mode))
|
||||
|
||||
(add-hook! 'flyspell-mode-hook
|
||||
(defun +flyspell-inhibit-duplicate-detection-maybe-h ()
|
||||
"Don't mark duplicates when style/grammar linters are present.
|
||||
e.g. proselint and langtool."
|
||||
(when (or (and (bound-and-true-p flycheck-mode)
|
||||
(executable-find "proselint"))
|
||||
(featurep 'langtool))
|
||||
(setq-local flyspell-mark-duplications-flag nil))))
|
||||
|
||||
;; Ensure mode-local predicates declared with `set-flyspell-predicate!' are
|
||||
;; used in their respective major modes.
|
||||
(add-hook 'flyspell-mode-hook #'+flyspell-init-predicate-h)
|
||||
|
||||
(map! :map flyspell-mouse-map
|
||||
"RET" #'flyspell-correct-word-generic
|
||||
[return] #'flyspell-correct-word-generic
|
||||
[mouse-1] #'flyspell-correct-word-generic))
|
||||
|
||||
|
||||
(use-package! flyspell-correct
|
||||
:commands flyspell-correct-word-generic flyspell-correct-previous-word-generic
|
||||
:config
|
||||
(cond ((and (featurep! :completion helm)
|
||||
(require 'flyspell-correct-helm nil t)))
|
||||
((and (featurep! :completion ivy)
|
||||
(require 'flyspell-correct-ivy nil t)))
|
||||
((require 'flyspell-correct-popup nil t)
|
||||
(setq flyspell-popup-correct-delay 0.8)
|
||||
(define-key popup-menu-keymap [escape] #'keyboard-quit))))
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
(unless (or (executable-find "aspell")
|
||||
(executable-find "hunspell"))
|
||||
(warn! "Could not find aspell or hunspell. Flyspell will fall back to ispell, which may not work."))
|
||||
@@ -1,9 +0,0 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/flyspell/packages.el
|
||||
|
||||
(package! flyspell-correct)
|
||||
(cond ((featurep! :completion ivy)
|
||||
(package! flyspell-correct-ivy))
|
||||
((featurep! :completion helm)
|
||||
(package! flyspell-correct-helm))
|
||||
((package! flyspell-correct-popup)))
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/gist/packages.el
|
||||
|
||||
(package! gist)
|
||||
(package! gist :pin "314fe6ab80fae35b95f0734eceb82f72813b6f41")
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#macos][MacOS]]
|
||||
- [[#arch-linux][Arch Linux]]
|
||||
- [[#nixos][NixOS]]
|
||||
- [[#features][Features]]
|
||||
- [[#jump-to-definition][Jump to definition]]
|
||||
- [[#find-references][Find references]]
|
||||
@@ -24,33 +25,51 @@
|
||||
- [[#commands][Commands]]
|
||||
|
||||
* Description
|
||||
Integrates with code navigation and documentation tools to help you quickly look
|
||||
up definitions, references and documentation.
|
||||
This module adds code navigation and documentation lookup tools to help you
|
||||
quickly look up definitions, references, documentation, dictionary definitions
|
||||
or synonyms.
|
||||
|
||||
+ Jump-to-definition and find-references implementations that just work.
|
||||
+ Powerful xref integration for languages that support it.
|
||||
+ Documentation lookup for a variety of online sources (like devdocs.io,
|
||||
stackoverflow or youtube).
|
||||
+ Search online providers like devdocs.io, stackoverflow, google, duckduckgo or
|
||||
youtube (duckduckgo and google have live suggestions).
|
||||
+ Integration with Dash.app docsets.
|
||||
+ Support for online (and offline) dictionaries and thesauruses.
|
||||
|
||||
** Module Flags
|
||||
+ ~+dictionary~ Enable word definition and thesaurus lookup functionality.
|
||||
+ ~+offline~ Install and prefer offline dictionary/thesaurus.
|
||||
+ ~+docsets~ Enable integration with Dash.app docsets.
|
||||
+ ~+xwidget~ Enable integration with [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Embedded-WebKit-Widgets.html][Embedded Webkit Widgets]].
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/jacktasia/dumb-jump][dumb-jump]]
|
||||
+ [[https://github.com/alexmurray/ivy-xref][ivy-xref]] or [[https://github.com/brotzeit/helm-xref][helm-xref]]
|
||||
+ [[https://github.com/nathankot/counsel-dash][counsel-dash]] or [[https://github.com/areina/helm-dash][helm-dash]]
|
||||
+ [[https://github.com/tkf/emacs-request][request]]
|
||||
+ =+docsets=
|
||||
+ [[https://github.com/dash-docs-el/dash-docs][dash-docs]]
|
||||
+ [[https://github.com/nathankot/counsel-dash][counsel-dash]] or [[https://github.com/areina/helm-dash][helm-dash]]
|
||||
+ =+dictionary=
|
||||
+ if macOS
|
||||
+ [[https://github.com/xuchunyang/osx-dictionary.el][osx-dictionary]]* (on macOS)
|
||||
+ else
|
||||
+ [[https://github.com/abo-abo/define-word][define-word]]
|
||||
+ [[https://github.com/maxchaos/emacs-powerthesaurus][powerthesaurus]]
|
||||
+ =+offline=
|
||||
+ [[https://github.com/gromnitsky/wordnut][wordnut]]
|
||||
+ [[https://github.com/hpdeifel/synosaurus][synosaurus]]
|
||||
|
||||
* Prerequisites
|
||||
This module has several soft dependencies:
|
||||
|
||||
+ ~the_silver_searcher~ or ~ripgrep~ (recommended) as a last-resort fallback for
|
||||
jump-to-definition/find-references.
|
||||
+ ~sqlite3~ for Dash docset support.
|
||||
+ ~ripgrep~ as a last-resort fallback for jump-to-definition/find-references.
|
||||
+ ~sqlite3~ for Dash docset support (if you have =+docsets= enabled)
|
||||
+ ~wordnet~ for offline dictionary and thesaurus support (if you have
|
||||
=+dictionary +offline= enabled).
|
||||
|
||||
** MacOS
|
||||
#+BEGIN_SRC sh
|
||||
brew install the_silver_searcher ripgrep
|
||||
brew install ripgrep wordnet
|
||||
|
||||
# An older version of sqlite is included in MacOS. If it causes you problems (and
|
||||
# folks have reported it will), install it through homebrew:
|
||||
@@ -62,7 +81,17 @@ export PATH="/usr/local/opt/sqlite/bin:$PATH"
|
||||
|
||||
** Arch Linux
|
||||
#+BEGIN_SRC sh
|
||||
sudo pacman -S sqlite the_silver_searcher ripgrep
|
||||
sudo pacman -S sqlite ripgrep
|
||||
yay -S wordnet-cli
|
||||
#+END_SRC
|
||||
|
||||
** NixOS
|
||||
#+BEGIN_SRC nix
|
||||
environment.systemPackages = with pkgs; [
|
||||
ripgrep
|
||||
sqlite
|
||||
wordnet
|
||||
];
|
||||
#+END_SRC
|
||||
|
||||
* Features
|
||||
@@ -77,7 +106,7 @@ following sources before giving up:
|
||||
~:lookup~ setting (see "Configuration" section).
|
||||
2. Any available xref backends.
|
||||
3. ~dumb-jump~ (a text search with aides to reduce false positives).
|
||||
3. An ordinary project-wide text search with ripgrep or the_silver_searcher.
|
||||
3. An ordinary project-wide text search with ripgrep.
|
||||
5. If ~evil-mode~ is active, use ~evil-goto-definition~, which preforms a simple
|
||||
text search within the current buffer.
|
||||
|
||||
@@ -93,7 +122,7 @@ will try:
|
||||
1. Whatever ~:references~ function is registered for the current buffer with the
|
||||
~:lookup~ setting (see "Configuration" section).
|
||||
2. Any available xref backends.
|
||||
3. An ordinary project-wide text search with ripgrep or the_silver_searcher.
|
||||
3. An ordinary project-wide text search with ripgrep.
|
||||
|
||||
If there are multiple results, you will be prompted to select one.
|
||||
|
||||
|
||||
@@ -86,11 +86,12 @@ installed with `dash-docs-install-docset'."
|
||||
(interactive "P")
|
||||
(require 'dash-docs)
|
||||
(let ((dash-docs-common-docsets)
|
||||
(dash-docs-browser-func +lookup-open-url-fn)
|
||||
(dash-docs-docsets
|
||||
(if arg
|
||||
(dash-docs-installed-docsets)
|
||||
(cl-remove-if-not #'dash-docs-docset-path (or docsets dash-docs-docsets))))
|
||||
(query (or query (+lookup-symbol-or-region) "")))
|
||||
(query (doom-thing-at-point-or-region query)))
|
||||
(doom-log "Searching docsets %s" dash-docs-docsets)
|
||||
(cond ((featurep! :completion helm)
|
||||
(helm-dash query))
|
||||
|
||||
@@ -15,6 +15,12 @@ properties:
|
||||
|
||||
:definition FN
|
||||
Run when jumping to a symbol's definition. Used by `+lookup/definition'.
|
||||
:implementations FN
|
||||
Run when looking for implementations of a symbol in the current project. Used
|
||||
by `+lookup/implementations'.
|
||||
:type-definition FN
|
||||
Run when jumping to a symbol's type definition. Used by
|
||||
`+lookup/type-definition'.
|
||||
:references FN
|
||||
Run when looking for usage references of a symbol in the current project. Used
|
||||
by `+lookup/references'.
|
||||
@@ -46,6 +52,7 @@ change the current buffer or window or return non-nil when it succeeds.
|
||||
|
||||
If it doesn't change the current buffer, or it returns nil, the lookup module
|
||||
will fall back to the next handler in `+lookup-definition-functions',
|
||||
`+lookup-implementations-functions', `+lookup-type-definition-functions',
|
||||
`+lookup-references-functions', `+lookup-file-functions' or
|
||||
`+lookup-documentation-functions'.
|
||||
|
||||
@@ -57,35 +64,40 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g.
|
||||
|
||||
(set-lookup-handlers! 'python-mode nil)
|
||||
|
||||
\(fn MODES &key DEFINITION REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)"
|
||||
\(fn MODES &key DEFINITION IMPLEMENTATIONS TYPE-DEFINITION REFERENCES DOCUMENTATION FILE XREF-BACKEND ASYNC)"
|
||||
(declare (indent defun))
|
||||
(dolist (mode (doom-enlist modes))
|
||||
(let ((hook (intern (format "%s-hook" mode)))
|
||||
(fn (intern (format "+lookup--init-%s-handlers-h" mode))))
|
||||
(cond ((null (car plist))
|
||||
(remove-hook hook fn)
|
||||
(unintern fn nil))
|
||||
((fset
|
||||
fn
|
||||
(lambda ()
|
||||
(cl-destructuring-bind (&key definition references documentation file xref-backend async)
|
||||
plist
|
||||
(cl-mapc #'+lookup--set-handler
|
||||
(list definition
|
||||
references
|
||||
documentation
|
||||
file
|
||||
xref-backend)
|
||||
(list '+lookup-definition-functions
|
||||
'+lookup-references-functions
|
||||
'+lookup-documentation-functions
|
||||
'+lookup-file-functions
|
||||
'xref-backend-functions)
|
||||
(make-list 5 async)
|
||||
(make-list 5 (or (eq major-mode mode)
|
||||
(and (boundp mode)
|
||||
(symbol-value mode))))))))
|
||||
(add-hook hook fn))))))
|
||||
(if (null (car plist))
|
||||
(progn
|
||||
(remove-hook hook fn)
|
||||
(unintern fn nil))
|
||||
(fset
|
||||
fn
|
||||
(lambda ()
|
||||
(cl-destructuring-bind (&key definition implementations type-definition references documentation file xref-backend async)
|
||||
plist
|
||||
(cl-mapc #'+lookup--set-handler
|
||||
(list definition
|
||||
implementations
|
||||
type-definition
|
||||
references
|
||||
documentation
|
||||
file
|
||||
xref-backend)
|
||||
(list '+lookup-definition-functions
|
||||
'+lookup-implementations-functions
|
||||
'+lookup-type-definition-functions
|
||||
'+lookup-references-functions
|
||||
'+lookup-documentation-functions
|
||||
'+lookup-file-functions
|
||||
'xref-backend-functions)
|
||||
(make-list 5 async)
|
||||
(make-list 5 (or (eq major-mode mode)
|
||||
(and (boundp mode)
|
||||
(symbol-value mode))))))))
|
||||
(add-hook hook fn)))))
|
||||
|
||||
|
||||
;;
|
||||
@@ -130,20 +142,24 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g.
|
||||
|
||||
(defun +lookup--jump-to (prop identifier &optional display-fn arg)
|
||||
(let* ((origin (point-marker))
|
||||
(handlers (plist-get (list :definition '+lookup-definition-functions
|
||||
:references '+lookup-references-functions
|
||||
:documentation '+lookup-documentation-functions
|
||||
:file '+lookup-file-functions)
|
||||
prop))
|
||||
(handlers
|
||||
(plist-get (list :definition '+lookup-definition-functions
|
||||
:implementations '+lookup-implementations-functions
|
||||
:type-definition '+lookup-type-definition-functions
|
||||
:references '+lookup-references-functions
|
||||
:documentation '+lookup-documentation-functions
|
||||
:file '+lookup-file-functions)
|
||||
prop))
|
||||
(result
|
||||
(if arg
|
||||
(if-let*
|
||||
((handler (intern-soft
|
||||
(completing-read "Select lookup handler: "
|
||||
(delete-dups
|
||||
(remq t (append (symbol-value handlers)
|
||||
(default-value handlers))))
|
||||
nil t))))
|
||||
(if-let
|
||||
(handler
|
||||
(intern-soft
|
||||
(completing-read "Select lookup handler: "
|
||||
(delete-dups
|
||||
(remq t (append (symbol-value handlers)
|
||||
(default-value handlers))))
|
||||
nil t)))
|
||||
(+lookup--run-handlers handler identifier origin)
|
||||
(user-error "No lookup handler selected"))
|
||||
(run-hook-wrapped handlers #'+lookup--run-handlers identifier origin))))
|
||||
@@ -160,40 +176,29 @@ This can be passed nil as its second argument to unset handlers for MODES. e.g.
|
||||
(better-jumper-set-jump (marker-position origin)))
|
||||
result)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup-symbol-or-region (&optional initial)
|
||||
"Grab the symbol at point or selected region."
|
||||
(cond ((stringp initial)
|
||||
initial)
|
||||
((use-region-p)
|
||||
(buffer-substring-no-properties (region-beginning)
|
||||
(region-end)))
|
||||
((require 'xref nil t)
|
||||
;; A little smarter than using `symbol-at-point', though in most cases,
|
||||
;; xref ends up using `symbol-at-point' anyway.
|
||||
(xref-backend-identifier-at-point (xref-find-backend)))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Lookup backends
|
||||
|
||||
(defun +lookup--xref-show (fn identifier)
|
||||
(defun +lookup--xref-show (fn identifier &optional show-fn)
|
||||
(let ((xrefs (funcall fn
|
||||
(xref-find-backend)
|
||||
identifier)))
|
||||
(when xrefs
|
||||
(xref--show-xrefs xrefs nil)
|
||||
(funcall (or show-fn #'xref--show-defs)
|
||||
(lambda () xrefs)
|
||||
nil)
|
||||
(if (cdr xrefs)
|
||||
'deferred
|
||||
t))))
|
||||
|
||||
(defun +lookup-xref-definitions-backend-fn (identifier)
|
||||
"Non-interactive wrapper for `xref-find-definitions'"
|
||||
(+lookup--xref-show 'xref-backend-definitions identifier))
|
||||
(+lookup--xref-show 'xref-backend-definitions identifier #'xref--show-defs))
|
||||
|
||||
(defun +lookup-xref-references-backend-fn (identifier)
|
||||
"Non-interactive wrapper for `xref-find-references'"
|
||||
(+lookup--xref-show 'xref-backend-references identifier))
|
||||
(+lookup--xref-show 'xref-backend-references identifier #'xref--show-xrefs))
|
||||
|
||||
(defun +lookup-dumb-jump-backend-fn (_identifier)
|
||||
"Look up the symbol at point (or selection) with `dumb-jump', which conducts a
|
||||
@@ -243,12 +248,36 @@ Each function in `+lookup-definition-functions' is tried until one changes the
|
||||
point or current buffer. Falls back to dumb-jump, naive
|
||||
ripgrep/the_silver_searcher text search, then `evil-goto-definition' if
|
||||
evil-mode is active."
|
||||
(interactive (list (+lookup-symbol-or-region)
|
||||
(interactive (list (doom-thing-at-point-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((null identifier) (user-error "Nothing under point"))
|
||||
((+lookup--jump-to :definition identifier nil arg))
|
||||
((error "Couldn't find the definition of %S" identifier))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/implementations (identifier &optional arg)
|
||||
"Jump to the implementations of IDENTIFIER (defaults to the symbol at point).
|
||||
|
||||
Each function in `+lookup-implementations-functions' is tried until one changes
|
||||
the point or current buffer."
|
||||
(interactive (list (doom-thing-at-point-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((null identifier) (user-error "Nothing under point"))
|
||||
((+lookup--jump-to :implementations identifier nil arg))
|
||||
((error "Couldn't find the implementations of %S" identifier))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/type-definition (identifier &optional arg)
|
||||
"Jump to the type definition of IDENTIFIER (defaults to the symbol at point).
|
||||
|
||||
Each function in `+lookup-type-definition-functions' is tried until one changes
|
||||
the point or current buffer."
|
||||
(interactive (list (doom-thing-at-point-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((null identifier) (user-error "Nothing under point"))
|
||||
((+lookup--jump-to :type-definition identifier nil arg))
|
||||
((error "Couldn't find the definition of %S" identifier))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/references (identifier &optional arg)
|
||||
"Show a list of usages of IDENTIFIER (defaults to the symbol at point)
|
||||
@@ -256,7 +285,7 @@ evil-mode is active."
|
||||
Tries each function in `+lookup-references-functions' until one changes the
|
||||
point and/or current buffer. Falls back to a naive ripgrep/the_silver_searcher
|
||||
search otherwise."
|
||||
(interactive (list (+lookup-symbol-or-region)
|
||||
(interactive (list (doom-thing-at-point-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((null identifier) (user-error "Nothing under point"))
|
||||
((+lookup--jump-to :references identifier nil arg))
|
||||
@@ -269,7 +298,7 @@ search otherwise."
|
||||
First attempts the :documentation handler specified with `set-lookup-handlers!'
|
||||
for the current mode/buffer (if any), then falls back to the backends in
|
||||
`+lookup-documentation-functions'."
|
||||
(interactive (list (+lookup-symbol-or-region)
|
||||
(interactive (list (doom-thing-at-point-or-region)
|
||||
current-prefix-arg))
|
||||
(cond ((+lookup--jump-to :documentation identifier #'pop-to-buffer arg))
|
||||
((user-error "Couldn't find documentation for %S" identifier))))
|
||||
@@ -290,33 +319,56 @@ Otherwise, falls back on `find-file-at-point'."
|
||||
(or (ffap-guesser)
|
||||
(ffap-read-file-or-url
|
||||
(if ffap-url-regexp "Find file or URL: " "Find file: ")
|
||||
(+lookup-symbol-or-region))))))
|
||||
(doom-thing-at-point-or-region))))))
|
||||
(require 'ffap)
|
||||
(cond ((not path)
|
||||
(call-interactively #'find-file-at-point))
|
||||
(cond ((and path
|
||||
buffer-file-name
|
||||
(file-equal-p path buffer-file-name)
|
||||
(user-error "Already here")))
|
||||
|
||||
((ffap-url-p path)
|
||||
(find-file-at-point path))
|
||||
((+lookup--jump-to :file path))
|
||||
|
||||
((not (+lookup--jump-to :file path))
|
||||
(let ((fullpath (doom-path path)))
|
||||
(when (and buffer-file-name (file-equal-p fullpath buffer-file-name))
|
||||
(user-error "Already here"))
|
||||
(let* ((insert-default-directory t)
|
||||
(project-root (doom-project-root))
|
||||
(ffap-file-finder
|
||||
(cond ((not (doom-glob fullpath))
|
||||
#'find-file)
|
||||
((ignore-errors (file-in-directory-p fullpath project-root))
|
||||
(lambda (dir)
|
||||
(let* ((default-directory dir)
|
||||
projectile-project-name
|
||||
projectile-project-root
|
||||
(projectile-project-root-cache (make-hash-table :test 'equal))
|
||||
(file (projectile-completing-read "Find file: "
|
||||
(projectile-current-project-files)
|
||||
:initial-input path)))
|
||||
(find-file (expand-file-name file (doom-project-root)))
|
||||
(run-hooks 'projectile-find-file-hook))))
|
||||
(#'doom-project-browse))))
|
||||
(find-file-at-point path))))))
|
||||
((stringp path) (find-file-at-point path))
|
||||
|
||||
((call-interactively #'find-file-at-point))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Dictionary
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/dictionary-definition (identifier &optional arg)
|
||||
"Look up the definition of the word at point (or selection)."
|
||||
(interactive
|
||||
(list (or (doom-thing-at-point-or-region 'word)
|
||||
(read-string "Look up in dictionary: "))
|
||||
current-prefix-arg))
|
||||
(message "Looking up definition for %S" identifier)
|
||||
(cond ((and IS-MAC (require 'osx-dictionary nil t))
|
||||
(osx-dictionary--view-result identifier))
|
||||
((and +lookup-dictionary-prefer-offline
|
||||
(require 'wordnut nil t))
|
||||
(unless (executable-find wordnut-cmd)
|
||||
(user-error "Couldn't find %S installed on your system"
|
||||
wordnut-cmd))
|
||||
(wordnut-search identifier))
|
||||
((require 'define-word nil t)
|
||||
(define-word identifier nil arg))
|
||||
((user-error "No dictionary backend is available"))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/synonyms (identifier &optional _arg)
|
||||
"Look up and insert a synonym for the word at point (or selection)."
|
||||
(interactive
|
||||
(list (doom-thing-at-point-or-region 'word) ; TODO actually use this
|
||||
current-prefix-arg))
|
||||
(message "Looking up synonyms for %S" identifier)
|
||||
(cond ((and +lookup-dictionary-prefer-offline
|
||||
(require 'synosaurus-wordnet nil t))
|
||||
(unless (executable-find synosaurus-wordnet--command)
|
||||
(user-error "Couldn't find %S installed on your system"
|
||||
synosaurus-wordnet--command))
|
||||
(synosaurus-choose-and-replace))
|
||||
((require 'powerthesaurus nil t)
|
||||
(powerthesaurus-lookup-word-dwim))
|
||||
((user-error "No thesaurus backend is available"))))
|
||||
|
||||
@@ -25,8 +25,8 @@ argument is non-nil)."
|
||||
(+lookup--online-provider (not current-prefix-arg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup/online (arg &optional query provider)
|
||||
"Looks up QUERY (a string) in you browser using PROVIDER.
|
||||
(defun +lookup/online (query provider)
|
||||
"Looks up QUERY (a string) in you browser usin PROVIDER.
|
||||
|
||||
PROVIDER should be a key of `+lookup-provider-url-alist'.
|
||||
|
||||
@@ -34,14 +34,13 @@ When used interactively, it will prompt for a query and, for the first time, the
|
||||
provider from `+lookup-provider-url-alist'. On consecutive uses, the last
|
||||
provider will be reused. If the universal argument is supplied, always prompt
|
||||
for the provider."
|
||||
(interactive "P")
|
||||
(let* ((provider (or provider (+lookup--online-provider arg)))
|
||||
(query (or query (+lookup-symbol-or-region)))
|
||||
(backend (cl-find-if (lambda (x) (or (stringp x) (fboundp x)))
|
||||
(cdr (assoc provider +lookup-provider-url-alist)))))
|
||||
(if (and (functionp backend)
|
||||
(commandp backend))
|
||||
(call-interactively backend)
|
||||
(interactive
|
||||
(list (if (use-region-p) (doom-thing-at-point-or-region))
|
||||
(+lookup--online-provider current-prefix-arg)))
|
||||
(let ((backend (cl-find-if (lambda (x) (or (stringp x) (fboundp x)))
|
||||
(cdr (assoc provider +lookup-provider-url-alist)))))
|
||||
(unless (and (functionp backend)
|
||||
(funcall backend query))
|
||||
(unless backend
|
||||
(user-error "%S is an invalid query engine backend for %S provider"
|
||||
backend provider))
|
||||
@@ -69,3 +68,32 @@ for the provider."
|
||||
(interactive)
|
||||
(let ((current-prefix-arg t))
|
||||
(call-interactively #'+lookup/online)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Special provider frontends
|
||||
|
||||
(defvar ivy-initial-inputs-alist)
|
||||
(defvar counsel-search-engine)
|
||||
;;;###autoload
|
||||
(defun +lookup--online-backend-google (query)
|
||||
"Search google, starting with QUERY, with live autocompletion."
|
||||
(cond ((fboundp 'counsel-search)
|
||||
(let ((ivy-initial-inputs-alist `((t . ,query)))
|
||||
(counsel-search-engine 'google))
|
||||
(call-interactively #'counsel-search)
|
||||
t))
|
||||
((require 'helm-net nil t)
|
||||
(helm :sources 'helm-source-google-suggest
|
||||
:buffer "*helm google*"
|
||||
:input query)
|
||||
t)))
|
||||
|
||||
;;;###autoload
|
||||
(defun +lookup--online-backend-duckduckgo (query)
|
||||
"Search duckduckgo, starting with QUERY, with live autocompletion."
|
||||
(cond ((fboundp 'counsel-search)
|
||||
(let ((ivy-initial-inputs-alist `((t . ,query)))
|
||||
(counsel-search-engine 'ddg))
|
||||
(call-interactively #'counsel-search)
|
||||
t))))
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
;; "What am I looking at?" This module helps you answer this question.
|
||||
;;
|
||||
;; + `+lookup/definition': a jump-to-definition that should 'just work'
|
||||
;; + `+lookup/implementations': find a symbol's implementations in the current
|
||||
;; project
|
||||
;; + `+lookup/references': find a symbol's references in the current project
|
||||
;; + `+lookup/file': open the file referenced at point
|
||||
;; + `+lookup/online'; look up a symbol on online resources
|
||||
@@ -13,11 +15,12 @@
|
||||
;; `dumb-jump' to find what you want.
|
||||
|
||||
(defvar +lookup-provider-url-alist
|
||||
(append '(("Google" counsel-search helm-google-suggest "https://google.com/search?q=%s")
|
||||
(append '(("Doom Emacs issues" "https://github.com/hlissner/doom-emacs/issues?q=is%%3Aissue+%s")
|
||||
("Google" +lookup--online-backend-google "https://google.com/search?q=%s")
|
||||
("Google images" "https://www.google.com/images?q=%s")
|
||||
("Google maps" "https://maps.google.com/maps?q=%s")
|
||||
("Project Gutenberg" "http://www.gutenberg.org/ebooks/search/?query=%s")
|
||||
("DuckDuckGo" counsel-search "https://duckduckgo.com/?q=%s")
|
||||
("DuckDuckGo" +lookup--online-backend-duckduckgo "https://duckduckgo.com/?q=%s")
|
||||
("DevDocs.io" "https://devdocs.io/#q=%s")
|
||||
("StackOverflow" "https://stackoverflow.com/search?q=%s")
|
||||
("Github" "https://github.com/search?ref=simplesearch&q=%s")
|
||||
@@ -51,6 +54,24 @@ If the argument is interactive (satisfies `commandp'), it is called with
|
||||
argument: the identifier at point. See `set-lookup-handlers!' about adding to
|
||||
this list.")
|
||||
|
||||
(defvar +lookup-implementations-functions ()
|
||||
"Function for `+lookup/implementations' to try. Stops at the first function to
|
||||
return non-nil or change the current window/point.
|
||||
|
||||
If the argument is interactive (satisfies `commandp'), it is called with
|
||||
`call-interactively' (with no arguments). Otherwise, it is called with one
|
||||
argument: the identifier at point. See `set-lookup-handlers!' about adding to
|
||||
this list.")
|
||||
|
||||
(defvar +lookup-type-definition-functions ()
|
||||
"Functions for `+lookup/type-definition' to try. Stops at the first function to
|
||||
return non-nil or change the current window/point.
|
||||
|
||||
If the argument is interactive (satisfies `commandp'), it is called with
|
||||
`call-interactively' (with no arguments). Otherwise, it is called with one
|
||||
argument: the identifier at point. See `set-lookup-handlers!' about adding to
|
||||
this list.")
|
||||
|
||||
(defvar +lookup-references-functions
|
||||
'(+lookup-xref-references-backend-fn
|
||||
+lookup-project-search-backend-fn)
|
||||
@@ -84,6 +105,19 @@ If the argument is interactive (satisfies `commandp'), it is called with
|
||||
argument: the identifier at point. See `set-lookup-handlers!' about adding to
|
||||
this list.")
|
||||
|
||||
(defvar +lookup-dictionary-prefer-offline (featurep! +offline)
|
||||
"If non-nil, look up dictionaries online.
|
||||
|
||||
Setting this to nil will force it to use offline backends, which may be less
|
||||
than perfect, but available without an internet connection.
|
||||
|
||||
Used by `+lookup/dictionary-definition' and `+lookup/synonyms'.
|
||||
|
||||
For `+lookup/dictionary-definition', this is ignored on Mac, where Emacs users
|
||||
Dictionary.app behind the scenes to get definitions.")
|
||||
|
||||
(defvar +lookup--dash-docs-xwidget-webkit-last-session-buffer nil)
|
||||
|
||||
|
||||
;;
|
||||
;;; dumb-jump
|
||||
@@ -92,6 +126,7 @@ this list.")
|
||||
:commands dumb-jump-result-follow
|
||||
:config
|
||||
(setq dumb-jump-default-project doom-emacs-dir
|
||||
dumb-jump-prefer-searcher 'rg
|
||||
dumb-jump-aggressive nil
|
||||
dumb-jump-selector
|
||||
(cond ((featurep! :completion ivy) 'ivy)
|
||||
@@ -124,12 +159,17 @@ this list.")
|
||||
(use-package! ivy-xref
|
||||
:when (featurep! :completion ivy)
|
||||
:config
|
||||
(setq xref-show-xrefs-function #'ivy-xref-show-xrefs)
|
||||
(set-popup-rule! "^\\*xref\\*$" :ignore t))
|
||||
(set-popup-rule! "^\\*xref\\*$" :ignore t)
|
||||
;; xref initialization is different in Emacs 27 - there are two different
|
||||
;; variables which can be set rather than just one
|
||||
(when EMACS27+
|
||||
(setq xref-show-definitions-function #'ivy-xref-show-defs))
|
||||
;; Necessary in Emacs <27. In Emacs 27 it will affect all xref-based
|
||||
;; commands other than xref-find-definitions too (eg project-find-regexp)
|
||||
(setq xref-show-xrefs-function #'ivy-xref-show-xrefs))
|
||||
|
||||
(use-package! helm-xref
|
||||
:when (featurep! :completion helm)
|
||||
:config (setq xref-show-xrefs-function #'helm-xref-show-xrefs)))
|
||||
:when (featurep! :completion helm)))
|
||||
|
||||
|
||||
;;
|
||||
@@ -141,7 +181,7 @@ this list.")
|
||||
:init
|
||||
(add-hook '+lookup-documentation-functions #'+lookup-dash-docsets-backend-fn)
|
||||
:config
|
||||
(setq dash-docs-enable-debugging doom-debug-mode
|
||||
(setq dash-docs-enable-debugging doom-debug-p
|
||||
dash-docs-docsets-path (concat doom-etc-dir "docsets/")
|
||||
dash-docs-min-length 2
|
||||
dash-docs-browser-func #'eww)
|
||||
@@ -160,8 +200,44 @@ See https://github.com/magit/ghub/issues/81"
|
||||
(let ((gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3"))
|
||||
(funcall orig-fn url)))
|
||||
|
||||
(use-package! helm-dash
|
||||
:when (featurep! :completion helm))
|
||||
;; Dash docset + Xwidget integration
|
||||
(when (featurep! +xwidget)
|
||||
(defun +lookup-dash-docs-xwidget-webkit-browse-url-fn (url &optional new-session)
|
||||
(if (not (display-graphic-p))
|
||||
(eww url new-session)
|
||||
(setq xwidget-webkit-last-session-buffer +lookup--dash-docs-xwidget-webkit-last-session-buffer)
|
||||
(save-window-excursion
|
||||
(xwidget-webkit-browse-url url new-session))
|
||||
(with-popup-rules! '(("^\\*xwidget" :vslot -11 :size 0.35 :select nil))
|
||||
(pop-to-buffer xwidget-webkit-last-session-buffer))
|
||||
(setq +lookup--dash-docs-xwidget-webkit-last-session-buffer xwidget-webkit-last-session-buffer
|
||||
xwidget-webkit-last-session-buffer nil)))
|
||||
(setq dash-docs-browser-func #'+lookup-dash-docs-xwidget-webkit-browse-url-fn))
|
||||
|
||||
(use-package! counsel-dash
|
||||
:when (featurep! :completion ivy)))
|
||||
(cond ((featurep! :completion helm)
|
||||
(require 'helm-dash nil t))
|
||||
((featurep! :completion ivy)
|
||||
(require 'counsel-dash nil t))))
|
||||
|
||||
|
||||
;;
|
||||
;;; Dictionary integration
|
||||
|
||||
(use-package! define-word
|
||||
:when (featurep! +dictionary)
|
||||
:unless IS-MAC
|
||||
:defer t
|
||||
:config
|
||||
(setq define-word-displayfn-alist
|
||||
(cl-loop for (service . _) in define-word-services
|
||||
collect (cons service #'+eval-display-results-in-popup))))
|
||||
|
||||
|
||||
(when (featurep! +dictionary)
|
||||
(define-key! text-mode-map
|
||||
[remap +lookup/definition] #'+lookup/dictionary-definition
|
||||
[remap +lookup/references] #'+lookup/synonyms))
|
||||
|
||||
|
||||
;;;###package synosaurus
|
||||
(setq synosaurus-choose-method 'default) ; use ivy/helm instead of ido
|
||||
|
||||
@@ -8,18 +8,31 @@
|
||||
(package! helm))
|
||||
|
||||
;;
|
||||
(package! dumb-jump)
|
||||
(package! dumb-jump :pin "d86f59c4c0eb9371dd84bc2aaff5d7445f04ba27")
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-xref)
|
||||
;; Need for Google/DuckDuckGo auto-completion on `+lookup/online'
|
||||
(package! request))
|
||||
(package! ivy-xref :pin "3d4c35fe2b243d948d8fe02a1f0d76a249d63de9"))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-google)
|
||||
(package! helm-xref))
|
||||
(package! helm-xref :pin "6b4a8bd91f5eaf82f51bd31b03f6587387fe6983"))
|
||||
|
||||
;; For dictionary and online lookup
|
||||
(package! request :pin "912525c772984c6af0fd84acd6699ee43d91037a")
|
||||
|
||||
(when (featurep! +docsets)
|
||||
(package! dash-docs)
|
||||
(package! dash-docs :pin "dafc8fc9f1ddb2e4e39e0b8d066c42d5d7ce8d06")
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-dash))
|
||||
(package! helm-dash :pin "7f853bd34da666f0e9a883011c80f451b06f6c59"))
|
||||
(when (featurep! :completion ivy)
|
||||
(package! counsel-dash)))
|
||||
(package! counsel-dash :pin "370d5f6f14b5294d0eb717f7b2a6a8e93df1ed24")))
|
||||
|
||||
(when (featurep! +dictionary)
|
||||
(if IS-MAC
|
||||
(package! osx-dictionary :pin "1b79ff64c72485cb078db9ab7ee3256b11a99f4b")
|
||||
(package! define-word :pin "08c71b1ff4fd07bf0c78d1fcf77efeaafc8f7443")
|
||||
;; HACK Fix #2945: the main package is broken due to
|
||||
;; SavchenkoValeriy/emacs-powerthesaurus#11
|
||||
(package! powerthesaurus
|
||||
:recipe (:host github :repo "maxchaos/emacs-powerthesaurus" :branch "pt-api-change")
|
||||
:pin "4a834782a394f2dc70fc02d68b6962b44d87f0cf")
|
||||
(when (featurep! +offline)
|
||||
(package! wordnut :pin "feac531404041855312c1a046bde7ea18c674915")
|
||||
(package! synosaurus :pin "14d34fc92a77c3a916b4d58400424c44ae99cd81"))))
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
- [[#description][Description]]
|
||||
- [[#module-flags][Module Flags]]
|
||||
- [[#plugins][Plugins]]
|
||||
- [[#hacks][Hacks]]
|
||||
- [[#prerequisites][Prerequisites]]
|
||||
- [[#features][Features]]
|
||||
- [[#lsp-powered-project-search][LSP-powered project search]]
|
||||
- [[#configuration][Configuration]]
|
||||
- [[#troubleshooting][Troubleshooting]]
|
||||
|
||||
@@ -40,23 +42,36 @@ As of this writing, this is the state of LSP support in Doom Emacs:
|
||||
| [[../../lang/haskell/README.org][:lang haskell]] | haskell-mode | haskell-ide-engine |
|
||||
| [[../../lang/java/README.org][:lang java]] | java-mode | lsp-java |
|
||||
| [[../../lang/javascript/README.org][:lang javascript]] | js2-mode, rjsx-mode, typescript-mode | typescript-language-server |
|
||||
| [[../../lang/ocaml/README.org][:lang ocaml]] | taureg-mode | ocaml-language-server |
|
||||
| [[../../lang/ocaml/README.org][:lang ocaml]] | tuareg-mode | ocaml-language-server |
|
||||
| [[../../lang/php/README.org][:lang php]] | php-mode | php-language-server |
|
||||
| [[../../lang/python/README.org][:lang python]] | python-mode | lsp-python-ms |
|
||||
| [[../../lang/ruby/README.org][:lang ruby]] | ruby-mode, enh-ruby-mode | solargraph |
|
||||
| [[../../lang/ruby/README.org][:lang ruby]] | ruby-mode | solargraph |
|
||||
| [[../../lang/rust/README.org][:lang rust]] | rust-mode | rls |
|
||||
| [[../../lang/scala/README.org][:lang scala]] | scala-mode | metals |
|
||||
| [[../../lang/sh/README.org][:lang sh]] | sh-mode | bash-language-server |
|
||||
| [[../../lang/swift/README.org][:lang swift]] | swift-mode | sourcekit |
|
||||
| [[../../lang/web/README.org][:lang web]] | web-mode, css-mode, scss-mode, sass-mode, less-css-mode | vscode-css-languageserver-bin, vscode-html-languageserver-bin |
|
||||
| [[../../lang/purescript/README.org][:lang purescript]] | purescript-mode | purescript-language-server |
|
||||
|
||||
** Module Flags
|
||||
This module provides no flags.
|
||||
+ =+peek= Use =lsp-ui-peek= when looking up definitions and references with
|
||||
functionality from the =:tools lookup= module.
|
||||
+ =+eglot= Use [[https://elpa.gnu.org/packages/eglot.html][Eglot]] instead of [[https://github.com/emacs-lsp/lsp-mode][LSP-mode]] to implement the LSP client in
|
||||
Emacs.
|
||||
|
||||
** Plugins
|
||||
+ [[https://github.com/emacs-lsp/lsp-mode][lsp-mode]]
|
||||
+ [[https://github.com/emacs-lsp/lsp-ui][lsp-ui]]
|
||||
+ [[https://github.com/tigersoldier/company-lsp][company-lsp]]*
|
||||
+ [[https://github.com/emacs-lsp/lsp-ivy][lsp-ivy]]
|
||||
+ [[https://github.com/emacs-lsp/helm-lsp][helm-lsp]]
|
||||
+ [[https://github.com/joaotavora/eglot][eglot]]
|
||||
|
||||
** Hacks
|
||||
+ ~lsp-mode~ has been modified not to automatically install missing LSP servers.
|
||||
This is done to adhere to our "Your system, your rules" mantra, which insist
|
||||
that it is better etiquette to let the user decide when their development
|
||||
environment is modified. Use ~M-x lsp-install-server~ to install LSP servers
|
||||
manually.
|
||||
|
||||
* Prerequisites
|
||||
This module has no direct prerequisites, but major-modes require you to install
|
||||
@@ -66,8 +81,37 @@ You'll find a table that lists available language servers and how to install
|
||||
them [[https://github.com/emacs-lsp/lsp-mode#supported-languages][in the lsp-mode project README]]. The documentation of the module for your
|
||||
targeted language will contain brief instructions as well.
|
||||
|
||||
For eglot users, you can see the list of [[https://github.com/joaotavora/eglot/blob/master/README.md#connecting-to-a-server][default servers supported in the README]].
|
||||
There is also instructions to add another server easily.
|
||||
|
||||
* TODO Features
|
||||
** LSP-powered project search
|
||||
Without the =+eglot= flag, and when =:completion ivy= or =:completion helm= is
|
||||
active, LSP is used to search a symbol indexed by the LSP server :
|
||||
| Keybind | Description |
|
||||
|-----------+-------------------------------------|
|
||||
| =SPC c j= | Jump to symbol in current workspace |
|
||||
| =SPC c J= | Jump to symbol in any workspace |
|
||||
** Differences between eglot and lsp-mode
|
||||
Entering the debate about which one to use would be useless. Doom provides an
|
||||
easy way to switch out lsp client implementations so you can test for yourself
|
||||
which one you prefer.
|
||||
|
||||
Mainly, from a code point of view, lsp-mode has a lot of custom code for UI
|
||||
(=lsp-ui-peek=, =lsp-ui-sideline=, ...), while eglot is more barebones with a
|
||||
closer integration with "more basic" emacs packages (=eldoc=, =xref=, ...).
|
||||
|
||||
* TODO Configuration
|
||||
|
||||
* TODO Troubleshooting
|
||||
** My language server is not found
|
||||
Check the entry in the [[../../../docs/faq.org][FAQ]] about "Doom can't find my executables/doesn't inherit
|
||||
the correct ~PATH~"
|
||||
** LSP/Eglot is not started automatically in my buffer
|
||||
Make sure that you added the =+lsp= flag to the language you're using too in
|
||||
your init.el :
|
||||
#+BEGIN_SRC diff
|
||||
:lang
|
||||
-python
|
||||
+(python +lsp)
|
||||
#+END_SRC
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
;;; feature/lsp/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defalias 'lsp! #'lsp-deferred)
|
||||
@@ -1,150 +1,16 @@
|
||||
;;; tools/lsp/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(defvar +lsp-company-backend 'company-lsp
|
||||
"What backend to prepend to `company-backends' when `lsp-mode' is active.
|
||||
(defvar +lsp-defer-shutdown 3
|
||||
"If non-nil, defer shutdown of LSP servers for this many seconds after last
|
||||
workspace buffer is closed.
|
||||
|
||||
This can be a single company backend or a list thereof. It can be anything
|
||||
`company-backends' will accept.")
|
||||
This delay prevents premature server shutdown when a user still intends on
|
||||
working on that project after closing the last buffer.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
;;; Implementations
|
||||
|
||||
(use-package! lsp-mode
|
||||
:defer t
|
||||
:init
|
||||
(setq lsp-session-file (concat doom-etc-dir "lsp-session"))
|
||||
;; Don't prompt the user for the project root every time we open a new
|
||||
;; lsp-worthy file, instead, try to guess it with projectile.
|
||||
(setq lsp-auto-guess-root t)
|
||||
;; Auto-kill LSP server once you've killed the last buffer associated with its
|
||||
;; project.
|
||||
(setq lsp-keep-workspace-alive nil)
|
||||
|
||||
;; For `lsp-clients'
|
||||
(setq lsp-fsharp-server-install-dir (concat doom-etc-dir "lsp-fsharp/")
|
||||
lsp-groovy-server-install-dir (concat doom-etc-dir "lsp-groovy/")
|
||||
lsp-intelephense-storage-path (concat doom-cache-dir "lsp-intelephense/"))
|
||||
|
||||
:config
|
||||
(set-lookup-handlers! 'lsp-mode :async t
|
||||
:documentation 'lsp-describe-thing-at-point
|
||||
:definition 'lsp-find-definition
|
||||
:references 'lsp-find-references)
|
||||
|
||||
(defvar +lsp--deferred-shutdown-timer nil)
|
||||
(defadvice! +lsp-defer-server-shutdown-a (orig-fn)
|
||||
"Defer server shutdown for a few seconds.
|
||||
This gives the user a chance to open other project files before the server is
|
||||
auto-killed (which is usually an expensive process)."
|
||||
:around #'lsp--shutdown-workspace
|
||||
(if (or lsp-keep-workspace-alive
|
||||
(eq (lsp--workspace-shutdown-action lsp--cur-workspace)
|
||||
'restart))
|
||||
(funcall orig-fn)
|
||||
(when (timerp +lsp--deferred-shutdown-timer)
|
||||
(cancel-timer +lsp--deferred-shutdown-timer))
|
||||
(setq +lsp--deferred-shutdown-timer
|
||||
(run-at-time
|
||||
3 nil (lambda (workspace)
|
||||
(let ((lsp--cur-workspace workspace))
|
||||
(unless (lsp--workspace-buffers lsp--cur-workspace)
|
||||
(funcall orig-fn))))
|
||||
lsp--cur-workspace))))
|
||||
|
||||
(defadvice! +lsp-prompt-if-no-project-a (session file-name)
|
||||
"Prompt for the project root only if no project was found."
|
||||
:after-until #'lsp--calculate-root
|
||||
(cond ((not lsp-auto-guess-root)
|
||||
nil)
|
||||
((cl-find-if (lambda (dir)
|
||||
(and (lsp--files-same-host dir file-name)
|
||||
(file-in-directory-p file-name dir)))
|
||||
(lsp-session-folders-blacklist session))
|
||||
nil)
|
||||
((lsp--find-root-interactively session))))
|
||||
|
||||
(defadvice! +lsp-init-a (&optional arg)
|
||||
"Enable `lsp-mode' in the current buffer.
|
||||
|
||||
Meant to be a lighter alternative to `lsp', which is too eager about
|
||||
initializing lsp-ui-mode, company, yasnippet and flycheck. Instead, these have
|
||||
been moved out to their respective modules, or these hooks:
|
||||
|
||||
+ `+lsp-init-company-h' (on `lsp-mode-hook')
|
||||
+ `+lsp-init-ui-flycheck-or-flymake-h' (on `lsp-ui-mode-hook')
|
||||
|
||||
Also logs the resolved project root, if found."
|
||||
:override #'lsp
|
||||
(interactive "P")
|
||||
(require 'lsp-mode)
|
||||
(when lsp-auto-configure
|
||||
(require 'lsp-clients))
|
||||
(and (buffer-file-name)
|
||||
(setq-local
|
||||
lsp--buffer-workspaces
|
||||
(or (lsp--try-open-in-library-workspace)
|
||||
(lsp--try-project-root-workspaces
|
||||
(equal arg '(4))
|
||||
(and arg (not (equal arg 1))))))
|
||||
(prog1 (lsp-mode 1)
|
||||
;; Announce what project root we're using, for diagnostic purposes
|
||||
(if-let (root (lsp--calculate-root (lsp-session) (buffer-file-name)))
|
||||
(lsp--info "Guessed project root is %s" (abbreviate-file-name root))
|
||||
(lsp--info "Could not guess project root."))
|
||||
(lsp--info "Connected to %s."
|
||||
(apply #'concat
|
||||
(mapcar
|
||||
(lambda (it) (format "[%s]" (lsp--workspace-print it)))
|
||||
lsp--buffer-workspaces))))))
|
||||
|
||||
;; Don't prompt to restart LSP servers while quitting Emacs
|
||||
(add-hook! 'kill-emacs-hook (setq lsp-restart 'ignore)))
|
||||
|
||||
|
||||
(use-package! lsp-ui
|
||||
:hook (lsp-mode . lsp-ui-mode)
|
||||
:init
|
||||
(add-hook! 'lsp-ui-mode-hook
|
||||
(defun +lsp-init-ui-flycheck-or-flymake-h ()
|
||||
"Sets up flymake-mode or flycheck-mode, depending on `lsp-prefer-flymake'."
|
||||
(cond ((eq :none lsp-prefer-flymake))
|
||||
(lsp-prefer-flymake
|
||||
(lsp--flymake-setup))
|
||||
((require 'flycheck nil t)
|
||||
(require 'lsp-ui-flycheck)
|
||||
(lsp-ui-flycheck-enable t)))))
|
||||
:config
|
||||
(setq lsp-prefer-flymake nil
|
||||
lsp-ui-doc-max-height 8
|
||||
lsp-ui-doc-max-width 35
|
||||
lsp-ui-sideline-ignore-duplicate t
|
||||
;; lsp-ui-doc is redundant with and more invasive than
|
||||
;; `+lookup/documentation'
|
||||
lsp-ui-doc-enable nil
|
||||
;; Don't show symbol definitions in the sideline. They are pretty noisy,
|
||||
;; and there is a bug preventing Flycheck errors from being shown (the
|
||||
;; errors flash briefly and then disappear).
|
||||
lsp-ui-sideline-show-hover nil)
|
||||
|
||||
(set-lookup-handlers! 'lsp-ui-mode :async t
|
||||
:definition 'lsp-ui-peek-find-definitions
|
||||
:references 'lsp-ui-peek-find-references))
|
||||
|
||||
|
||||
(use-package! company-lsp
|
||||
:when (featurep! :completion company)
|
||||
:defer t
|
||||
:init
|
||||
;; Make sure that `company-capf' is disabled since it is incompatible with
|
||||
;; `company-lsp' (see lsp-mode#884)
|
||||
(add-hook! 'lsp-mode-hook
|
||||
(defun +lsp-init-company-h ()
|
||||
(if (not (bound-and-true-p company-mode))
|
||||
(add-hook 'company-mode-hook #'+lsp-init-company-h t t)
|
||||
(setq-local company-backends
|
||||
(cons +lsp-company-backend
|
||||
(remq 'company-capf company-backends)))
|
||||
(remove-hook 'company-mode-hook #'+lsp-init-company-h t))))
|
||||
:config
|
||||
(setq company-lsp-cache-candidates 'auto)) ;; cache candidates for better performance
|
||||
(if (featurep! +eglot)
|
||||
(load! "+eglot")
|
||||
(load! "+lsp"))
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/lsp/packages.el
|
||||
|
||||
(package! lsp-mode)
|
||||
(package! lsp-ui)
|
||||
(when (featurep! :completion company)
|
||||
(package! company-lsp))
|
||||
(if (featurep! +eglot)
|
||||
(progn
|
||||
(package! eglot :pin "ac9239bed5e3bfbf057382d1a75cdfa23f2caddd")
|
||||
(package! project
|
||||
:recipe (:host github :repo "emacs-straight/project")
|
||||
:pin "da0333a697b18f0a863c1b1523d2fc7991b31174"))
|
||||
(package! lsp-mode :pin "5f3f9848b2d4afc69049121c60126a6405447106")
|
||||
(package! lsp-ui :pin "d92cf83d95c9ca177b735500ead88cf68dc2e2db")
|
||||
(when (featurep! :completion ivy)
|
||||
(package! lsp-ivy :pin "dce58b5509271bbedb53ba9d0278dcb563a43977"))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-lsp :pin "5018af9c709a783de1b9e101e07c948cceed67f1")))
|
||||
|
||||
@@ -49,3 +49,6 @@
|
||||
;;;###autoload (autoload '+macos/send-project-to-launchbar "tools/macos/autoload" nil t)
|
||||
(+macos--open-with send-project-to-launchbar "LaunchBar"
|
||||
(or (doom-project-root) default-directory))
|
||||
|
||||
;;;###autoload (autoload '+macos/open-in-iterm "tools/macos/autoload" nil t)
|
||||
(+macos--open-with open-in-iterm "iTerm" default-directory)
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
;;; tools/magit/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; HACK Magit complains loudly when it can't determine its own version, which is
|
||||
;; the case when magit is built through straight. The warning is harmless,
|
||||
;; however, so we just need it to shut up.
|
||||
;; HACK Magit complains loudly (but harmlessly) when it can't determine its own
|
||||
;; version in a sparse clone. This was fixed upstream in
|
||||
;; magit/magit@b1b2683, but only for macOS and Linux users. Windows doesn't
|
||||
;; support symlinks as unix knows them, so `magit-version' can't resolve
|
||||
;; its own repo's path.
|
||||
;;;###autoload
|
||||
(advice-add #'magit-version :override #'ignore)
|
||||
(when! IS-WINDOWS
|
||||
(defadvice! +magit--ignore-version-a (&optional print-dest)
|
||||
:override #'magit-version
|
||||
(when print-dest
|
||||
(defvar magit-git-debug)
|
||||
(princ (format "Magit (unknown), Git %s, Emacs %s, %s"
|
||||
(or (let ((magit-git-debug
|
||||
(lambda (err)
|
||||
(display-warning '(magit git) err :error))))
|
||||
(magit-git-version t))
|
||||
"(unknown)")
|
||||
emacs-version
|
||||
system-type)
|
||||
print-dest))
|
||||
nil))
|
||||
|
||||
;;;###autoload
|
||||
(defun +magit-display-buffer-fn (buffer)
|
||||
@@ -41,28 +57,42 @@
|
||||
|
||||
|
||||
;;
|
||||
;; Commands
|
||||
;;; Auto-revert
|
||||
|
||||
(defun +magit--refresh-vc-in-buffer (buffer)
|
||||
(defvar +magit--stale-p nil)
|
||||
|
||||
(defun +magit--revert-buffer (buffer)
|
||||
(with-current-buffer buffer
|
||||
(when (and vc-mode (fboundp 'vc-refresh-state))
|
||||
(vc-refresh-state))
|
||||
(when (and (bound-and-true-p git-gutter-mode)
|
||||
(fboundp '+version-control|update-git-gutter))
|
||||
(+version-control|update-git-gutter))
|
||||
(setq +magit--vc-is-stale-p nil)))
|
||||
(kill-local-variable '+magit--stale-p)
|
||||
(when buffer-file-name
|
||||
(if (buffer-modified-p (current-buffer))
|
||||
(when (bound-and-true-p vc-mode)
|
||||
(vc-refresh-state)
|
||||
(force-mode-line-update))
|
||||
(revert-buffer t t)))))
|
||||
|
||||
;;;###autoload
|
||||
(defvar-local +magit--vc-is-stale-p nil)
|
||||
(defun +magit-mark-stale-buffers-h ()
|
||||
"Revert all visible buffers and mark buried buffers as stale.
|
||||
|
||||
Stale buffers are reverted when they are switched to, assuming they haven't been
|
||||
modified."
|
||||
(dolist (buffer (buffer-list))
|
||||
(when (buffer-live-p buffer)
|
||||
(if (get-buffer-window buffer)
|
||||
(+magit--revert-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
(setq-local +magit--stale-p t))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +magit-refresh-vc-state-maybe-h ()
|
||||
(defun +magit-revert-buffer-maybe-h ()
|
||||
"Update `vc' and `git-gutter' if out of date."
|
||||
(when +magit--vc-is-stale-p
|
||||
(+magit--refresh-vc-in-buffer (current-buffer))))
|
||||
(when +magit--stale-p
|
||||
(+magit--revert-buffer (current-buffer))))
|
||||
|
||||
;;;###autoload
|
||||
(add-hook 'doom-switch-buffer-hook #'+magit-refresh-vc-state-maybe-h)
|
||||
|
||||
;;
|
||||
;;; Commands
|
||||
|
||||
;;;###autoload
|
||||
(defun +magit/quit (&optional kill-buffer)
|
||||
@@ -76,12 +106,7 @@ control in buffers."
|
||||
(eq major-mode 'magit-status-mode)))
|
||||
(window-list)))
|
||||
(mapc #'+magit--kill-buffer (magit-mode-get-buffers))
|
||||
(dolist (buffer (buffer-list))
|
||||
(when (buffer-live-p buffer)
|
||||
(if (get-buffer-window buffer)
|
||||
(+magit--refresh-vc-in-buffer buffer)
|
||||
(with-current-buffer buffer
|
||||
(setq +magit--vc-is-stale-p t)))))))
|
||||
(+magit-mark-stale-buffers-h)))
|
||||
|
||||
(defun +magit--kill-buffer (buf)
|
||||
"TODO"
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
;;; tools/magit/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;
|
||||
;;; Packages
|
||||
|
||||
(use-package! magit
|
||||
:commands magit-file-delete
|
||||
:defer-incrementally (dash f s with-editor git-commit package eieio lv transient)
|
||||
:init
|
||||
(setq magit-auto-revert-mode nil) ; we do this ourselves
|
||||
(setq magit-auto-revert-mode nil) ; we do this ourselves further down
|
||||
;; Must be set early to prevent ~/.emacs.d/transient from being created
|
||||
(setq transient-levels-file (concat doom-etc-dir "transient/levels")
|
||||
transient-values-file (concat doom-etc-dir "transient/values")
|
||||
@@ -19,12 +16,27 @@
|
||||
;; Don't autosave repo buffers. This is too magical, and saving can
|
||||
;; trigger a bunch of unwanted side-effects, like save hooks and
|
||||
;; formatters. Trust us to know what we're doing.
|
||||
magit-save-repository-buffers nil)
|
||||
magit-save-repository-buffers nil
|
||||
;; Magit runs git *a lot*. Having to scan your PATH so many times can
|
||||
;; add up with each invokation, especially on Catalina (macOS) or
|
||||
;; Windows, so we resolve it once.
|
||||
magit-git-executable (executable-find magit-git-executable))
|
||||
(add-hook 'magit-process-mode-hook #'goto-address-mode)
|
||||
|
||||
(defadvice! +magit-invalidate-projectile-cache-a (&rest _args)
|
||||
;; We ignore the args to `magit-checkout'.
|
||||
(defadvice! +magit-revert-repo-buffers-deferred-a (&rest _)
|
||||
:after '(magit-checkout magit-branch-and-checkout)
|
||||
(projectile-invalidate-cache nil))
|
||||
;; Since the project likely now contains new files, best we undo the
|
||||
;; projectile cache so it can be regenerated later.
|
||||
(projectile-invalidate-cache nil)
|
||||
;; Use a more efficient strategy to auto-revert buffers whose git state has
|
||||
;; changed: refresh the visible buffers immediately...
|
||||
(+magit-mark-stale-buffers-h))
|
||||
;; ...then refresh the rest only when we switch to them, not all at once.
|
||||
(add-hook 'doom-switch-buffer-hook #'+magit-revert-buffer-maybe-h)
|
||||
|
||||
;; Center the target file, because it's poor UX to have it at the bottom of
|
||||
;; the window after invoking `magit-status-here'.
|
||||
(advice-add #'magit-status-here :after #'doom-recenter-a)
|
||||
|
||||
;; The default location for git-credential-cache is in
|
||||
;; ~/.cache/git/credential. However, if ~/.git-credential-cache/ exists, then
|
||||
@@ -36,6 +48,20 @@
|
||||
"~/.cache/")
|
||||
"git/credential/socket")))
|
||||
|
||||
;; Prevent scrolling when manipulating magit-status hunks. Otherwise you must
|
||||
;; reorient yourself every time you stage/unstage/discard/etc a hunk.
|
||||
;; Especially so on larger projects."
|
||||
(defvar +magit--pos nil)
|
||||
(add-hook! 'magit-pre-refresh-hook
|
||||
(defun +magit--set-window-state-h ()
|
||||
(setq-local +magit--pos (list (current-buffer) (point) (window-start)))))
|
||||
(add-hook! 'magit-post-refresh-hook
|
||||
(defun +magit--restore-window-state-h ()
|
||||
(when (and +magit--pos (eq (current-buffer) (car +magit--pos)))
|
||||
(goto-char (cadr +magit--pos))
|
||||
(set-window-start nil (caddr +magit--pos) t)
|
||||
(kill-local-variable '+magit--pos))))
|
||||
|
||||
;; Magit uses `magit-display-buffer-traditional' to display windows, by
|
||||
;; default, which is a little primitive. `+magit-display-buffer' marries
|
||||
;; `magit-display-buffer-fullcolumn-most-v1' with
|
||||
@@ -50,7 +76,7 @@
|
||||
(set-popup-rule! "^\\(?:\\*magit\\|magit:\\| \\*transient\\*\\)" :ignore t)
|
||||
(add-hook 'magit-popup-mode-hook #'hide-mode-line-mode)
|
||||
|
||||
;; Add --tags switch
|
||||
;; Add additional switches that seem common enough
|
||||
(transient-append-suffix 'magit-fetch "-p"
|
||||
'("-t" "Fetch all tags" ("-t" "--tags")))
|
||||
(transient-append-suffix 'magit-pull "-r"
|
||||
@@ -63,7 +89,8 @@
|
||||
(and (derived-mode-p 'magit-mode)
|
||||
(not (eq major-mode 'magit-process-mode))))))
|
||||
|
||||
;; properly kill leftover magit buffers on quit
|
||||
;; Clean up after magit by killing leftover magit buffers and reverting
|
||||
;; affected buffers (or at least marking them as need-to-be-reverted).
|
||||
(define-key magit-status-mode-map [remap magit-mode-bury-buffer] #'+magit/quit)
|
||||
|
||||
;; Close transient with ESC
|
||||
@@ -71,10 +98,12 @@
|
||||
|
||||
|
||||
(use-package! forge
|
||||
:when (featurep! +forge)
|
||||
;; We defer loading even further because forge's dependencies will try to
|
||||
;; compile emacsql, which is a slow and blocking operation.
|
||||
:after-call magit-status
|
||||
:init
|
||||
:commands forge-create-pullreq forge-create-issue
|
||||
:preface
|
||||
(setq forge-database-file (concat doom-etc-dir "forge/forge-database.sqlite"))
|
||||
:config
|
||||
;; All forge list modes are derived from `forge-topic-list-mode'
|
||||
@@ -101,8 +130,8 @@ ensure it is built when we actually use Forge."
|
||||
(message (concat "Failed to build emacsql; forge may not work correctly.\n"
|
||||
"See *Compile-Log* buffer for details"))
|
||||
;; HACK Due to changes upstream, forge doesn't initialize completely if
|
||||
;; it doesn't find `emacsql-sqlite-executable', so we have to do it
|
||||
;; manually after installing it.
|
||||
;; it doesn't find `emacsql-sqlite-executable', so we have to do it
|
||||
;; manually after installing it.
|
||||
(setq forge--sqlite-available-p t)
|
||||
(magit-add-section-hook 'magit-status-sections-hook 'forge-insert-pullreqs nil t)
|
||||
(magit-add-section-hook 'magit-status-sections-hook 'forge-insert-issues nil t)
|
||||
@@ -142,7 +171,7 @@ ensure it is built when we actually use Forge."
|
||||
(setq evil-magit-state 'normal
|
||||
evil-magit-use-z-for-folds t)
|
||||
:config
|
||||
(unmap! magit-mode-map
|
||||
(undefine-key! magit-mode-map
|
||||
;; Replaced by z1, z2, z3, etc
|
||||
"M-1" "M-2" "M-3" "M-4"
|
||||
"1" "2" "3" "4"
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/magit/packages.el
|
||||
|
||||
(when (package! magit)
|
||||
(package! forge)
|
||||
(package! magit-gitflow)
|
||||
(package! magit-todos)
|
||||
(package! github-review)
|
||||
(when (package! magit :pin "793e387a508984ae2586b93ff78afddf7a1164ac")
|
||||
(when (featurep! +forge)
|
||||
(package! forge :pin "6f299d2d84a0c92a6656a6db03656c2d554d2cac"))
|
||||
(package! magit-gitflow :pin "cc41b561ec6eea947fe9a176349fb4f771ed865b")
|
||||
(package! magit-todos :pin "a0e5d1f3c7dfcb4f18c1b0d57f1746a4872df5c6")
|
||||
(package! github-review :pin "50c6bcc7cf4d7193577b3f74eea4dd72f2b7795b")
|
||||
(when (featurep! :editor evil +everywhere)
|
||||
(package! evil-magit)))
|
||||
(package! evil-magit :pin "88dc26ce59dbf4acb4e2891c79c4bd329553ba56")))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/make/packages.el
|
||||
|
||||
(package! makefile-executor)
|
||||
(package! makefile-executor :pin "9a7d78f814a4b372d8f8179819cb1b37b83b1973")
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/pass/packages.el
|
||||
|
||||
(package! pass)
|
||||
(package! password-store)
|
||||
(package! password-store-otp)
|
||||
(package! pass :pin "919d8e3826d556433ab67d4ee21a509d209d1baa")
|
||||
(package! password-store :pin "07b169ec32ad6961ed8625a0b932a663abcb01d2")
|
||||
(package! password-store-otp :pin "04998c8578a060ab4a4e8f46f2ee0aafad4ab4d5")
|
||||
|
||||
;; an older version of `auto-source-pass' is built into Emacs 26+, so we must
|
||||
;; install the new version directly from the source and with a psuedonym.
|
||||
(package! auth-source-pass
|
||||
:recipe (:host github :repo "DamienCassou/auth-password-store"))
|
||||
:recipe (:host github :repo "DamienCassou/auth-password-store")
|
||||
:pin "ff4940c647786914b3cbef69103d96a4ea334111")
|
||||
|
||||
(when (featurep! :completion ivy)
|
||||
(package! ivy-pass))
|
||||
(package! ivy-pass :pin "5b523de1151f2109fdd6a8114d0af12eef83d3c5"))
|
||||
(when (featurep! :completion helm)
|
||||
(package! helm-pass))
|
||||
(package! helm-pass :pin "ed5798f2d83937575e8f23fde33323bca9e85131"))
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
;;; tools/pdf/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(use-package! pdf-tools
|
||||
(use-package! pdf-view
|
||||
:mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode)
|
||||
:magic ("%PDF" . pdf-view-mode)
|
||||
:config
|
||||
(map! :map pdf-view-mode-map :gn "q" #'kill-current-buffer)
|
||||
|
||||
:init
|
||||
(after! pdf-annot
|
||||
(defun +pdf-cleanup-windows-h ()
|
||||
"Kill left-over annotation buffers when the document is killed."
|
||||
@@ -19,9 +17,27 @@
|
||||
(add-hook! 'pdf-view-mode-hook
|
||||
(add-hook 'kill-buffer-hook #'+pdf-cleanup-windows-h nil t)))
|
||||
|
||||
(setq-default pdf-view-display-size 'fit-page
|
||||
pdf-view-use-scaling t
|
||||
pdf-view-use-imagemagick nil)
|
||||
:config
|
||||
(map! :map pdf-view-mode-map :gn "q" #'kill-current-buffer)
|
||||
|
||||
(setq-default pdf-view-display-size 'fit-page)
|
||||
;; Enable hiDPI support, but at the cost of memory! See politza/pdf-tools#51
|
||||
(setq pdf-view-use-scaling t
|
||||
pdf-view-use-imagemagick nil)
|
||||
|
||||
;; Persist current page for PDF files viewed in Emacs
|
||||
(defvar +pdf--page-restored-p nil)
|
||||
(add-hook! 'pdf-view-change-page-hook
|
||||
(defun +pdf-remember-page-number-h ()
|
||||
(when-let (page (and buffer-file-name (pdf-view-current-page)))
|
||||
(doom-store-put buffer-file-name page nil "pdf-view"))))
|
||||
(add-hook! 'pdf-view-mode-hook
|
||||
(defun +pdf-restore-page-number-h ()
|
||||
(when-let (page (and buffer-file-name (doom-store-get buffer-file-name "pdf-view")))
|
||||
(and (not +pdf--page-restored-p)
|
||||
(<= page (or (pdf-cache-number-of-pages) 1))
|
||||
(pdf-view-goto-page page)
|
||||
(setq-local +pdf--page-restored-p t)))))
|
||||
|
||||
;; Add retina support for MacOS users
|
||||
(when IS-MAC
|
||||
@@ -31,44 +47,48 @@
|
||||
:around '(pdf-annot-show-annotation
|
||||
pdf-isearch-hl-matches
|
||||
pdf-view-display-region)
|
||||
(cl-letf* ((old-create-image (symbol-function #'create-image))
|
||||
((symbol-function #'create-image)
|
||||
(lambda (file-or-data &optional type data-p &rest props)
|
||||
(apply old-create-image file-or-data type data-p
|
||||
:width (car (pdf-view-image-size))
|
||||
props))))
|
||||
(letf! (defun create-image (file-or-data &optional type data-p &rest props)
|
||||
(apply create-image file-or-data type data-p
|
||||
:width (car (pdf-view-image-size))
|
||||
props))
|
||||
(apply orig-fn args))))
|
||||
|
||||
;; Turn off cua so copy works
|
||||
(add-hook! 'pdf-view-mode-hook (cua-mode 0))
|
||||
;; Handle PDF-tools related popups better
|
||||
(set-popup-rule! "^\\*Outline*" :side 'right :size 40 :select nil)
|
||||
(set-popup-rule! "\\(?:^\\*Contents\\|'s annots\\*$\\)" :ignore t)
|
||||
(set-popup-rules!
|
||||
'(("^\\*Outline*" :side right :size 40 :select nil)
|
||||
("\\(?:^\\*Contents\\|'s annots\\*$\\)" :ignore t)))
|
||||
|
||||
;; The mode-line does serve any useful purpose is annotation windows
|
||||
(add-hook 'pdf-annot-list-mode-hook #'hide-mode-line-mode)
|
||||
;; Fix #1107: flickering pdfs when evil-mode is enabled
|
||||
|
||||
;; HACK Fix #1107: flickering pdfs when evil-mode is enabled
|
||||
(setq-hook! 'pdf-view-mode-hook evil-normal-state-cursor (list nil))
|
||||
|
||||
;; Install epdfinfo binary if needed, blocking until it is finished
|
||||
(unless (file-executable-p pdf-info-epdfinfo-program)
|
||||
(let ((wconf (current-window-configuration)))
|
||||
(pdf-tools-install)
|
||||
(message "Building epdfinfo, this will take a moment...")
|
||||
;; HACK We reset all `pdf-view-mode' buffers to fundamental mode so that
|
||||
;; `pdf-tools-install' has a chance to reinitialize them as
|
||||
;; `pdf-view-mode' buffers. This is necessary because `pdf-tools-install'
|
||||
;; won't do this to buffers that are already in pdf-view-mode.
|
||||
(dolist (buffer (doom-buffers-in-mode 'pdf-view-mode))
|
||||
(with-current-buffer buffer (fundamental-mode)))
|
||||
(while compilation-in-progress
|
||||
;; Block until `pdf-tools-install' is done
|
||||
(sleep-for 1))
|
||||
;; HACK If pdf-tools was loaded by you opening a pdf file, once
|
||||
;; `pdf-tools-install' completes, `pdf-view-mode' will throw an error
|
||||
;; because the compilation buffer is focused, not the pdf buffer.
|
||||
;; Therefore, it is imperative that the window config is restored.
|
||||
(when (file-executable-p pdf-info-epdfinfo-program)
|
||||
(set-window-configuration wconf))))
|
||||
(when doom-interactive-p
|
||||
(require 'pdf-tools)
|
||||
(unless (file-executable-p pdf-info-epdfinfo-program)
|
||||
(let ((wconf (current-window-configuration)))
|
||||
(pdf-tools-install)
|
||||
(message "Building epdfinfo, this will take a moment...")
|
||||
;; HACK We reset all `pdf-view-mode' buffers to fundamental mode so that
|
||||
;; `pdf-tools-install' has a chance to reinitialize them as
|
||||
;; `pdf-view-mode' buffers. This is necessary because
|
||||
;; `pdf-tools-install' won't do this to buffers that are already in
|
||||
;; pdf-view-mode.
|
||||
(dolist (buffer (doom-buffers-in-mode 'pdf-view-mode))
|
||||
(with-current-buffer buffer (fundamental-mode)))
|
||||
(while compilation-in-progress
|
||||
;; Block until `pdf-tools-install' is done
|
||||
(redisplay)
|
||||
(sleep-for 1))
|
||||
;; HACK If pdf-tools was loaded by you opening a pdf file, once
|
||||
;; `pdf-tools-install' completes, `pdf-view-mode' will throw an error
|
||||
;; because the compilation buffer is focused, not the pdf buffer.
|
||||
;; Therefore, it is imperative that the window config is restored.
|
||||
(when (file-executable-p pdf-info-epdfinfo-program)
|
||||
(set-window-configuration wconf))))
|
||||
|
||||
;; Sets up `pdf-tools-enable-minor-modes', `pdf-occur-global-minor-mode' and
|
||||
;; `pdf-virtual-global-minor-mode'.
|
||||
(pdf-tools-install-noverify))
|
||||
;; Sets up `pdf-tools-enable-minor-modes', `pdf-occur-global-minor-mode' and
|
||||
;; `pdf-virtual-global-minor-mode'.
|
||||
(pdf-tools-install-noverify)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/pdf/packages.el
|
||||
|
||||
(package! pdf-tools)
|
||||
(package! pdf-tools :pin "c510442ab89c8a9e9881230eeb364f4663f59e76")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/prodigy/packages.el
|
||||
|
||||
(package! prodigy)
|
||||
(package! prodigy :pin "6ae71f27b09b172f03fb55b9eeef001206baacd3")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/rgb/packages.el
|
||||
|
||||
(package! rainbow-mode)
|
||||
(package! kurecolor)
|
||||
(package! rainbow-mode :pin "f780ddb18c2a73a666d093f606df92058e5601ea")
|
||||
(package! kurecolor :pin "3fc84840cbbd75e646cafa2fd3a00004b55e37ec")
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
;;; tools/terraform/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(when (featurep! +lsp)
|
||||
(add-hook 'terraform-mode-local-vars-hook #'lsp!))
|
||||
|
||||
|
||||
(map! :after terraform-mode
|
||||
:map terraform-mode-map
|
||||
:localleader
|
||||
:desc "terraform apply" "a" (λ! (compile "terraform apply"))
|
||||
:desc "terraform init" "i" (λ! (compile "terraform init"))
|
||||
:desc "terraform plan" "p" (λ! (compile "terraform plan")))
|
||||
:desc "terraform apply" "a" (cmd! (compile "terraform apply" t))
|
||||
:desc "terraform init" "i" (cmd! (compile "terraform init"))
|
||||
:desc "terraform plan" "p" (cmd! (compile "terraform plan")))
|
||||
|
||||
|
||||
(use-package! company-terraform
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/terraform/packages.el
|
||||
|
||||
(package! terraform-mode)
|
||||
(package! terraform-mode :pin "2967e7bdc05d15617e121052f6e43c61439b9070")
|
||||
(when (featurep! :completion company)
|
||||
(package! company-terraform))
|
||||
(package! company-terraform :pin "2d11a21fee2f298e48968e479ddcaeda4d736e12"))
|
||||
|
||||
@@ -104,7 +104,7 @@ but do not execute them."
|
||||
(if-let* ((lines
|
||||
(+tmux (format "list-windows %s -F '#{window_id};#{session_id};#{window_active};#{window_name};#{window_activity_flag}'"
|
||||
(if session
|
||||
(concat "-t " (car session))
|
||||
(concat "-t " (shell-quote-argument (car session)))
|
||||
"-a")))))
|
||||
(cl-loop for line in (split-string lines "\n" t)
|
||||
collect (let ((window (split-string line ";")))
|
||||
@@ -122,7 +122,7 @@ but do not execute them."
|
||||
(if sess-or-win
|
||||
(concat (if (string-prefix-p "$" (car sess-or-win)) "-s ")
|
||||
"-t "
|
||||
(car sess-or-win))
|
||||
(shell-quote-argument (car sess-or-win)))
|
||||
"-a")))))
|
||||
(cl-loop for line in (split-string lines "\n" t)
|
||||
collect (let ((pane (split-string line ";")))
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
;; -*- no-byte-compile: t; -*-
|
||||
;;; tools/upload/packages.el
|
||||
|
||||
(package! ssh-deploy)
|
||||
|
||||
(package! ssh-deploy :pin "1bb2f821d4a78d483c147759348a29531486cdc4")
|
||||
|
||||
Reference in New Issue
Block a user