dot-emacs
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:Personal emacs configuration
#+STARTUP: showeverything
#+TITLE: grzm's Emacs configuration
#+AUTHOR: Michael Glaesemann
#+PROPERTY: header-args :tangle yes
#+BABEL :cache yes

This is my dot-emacs. There are many like it, but this one is mine. My
dot-emacs is my best friend. It is my life. I must master it as I
master my life. My dot-emacs, without me, is useless. Without my
dot-emacs, I am useless.

* Requirements

The configuration requires =use-package=.

I generally use this configuration with [[https://emacsformacosx.com][Emacs for Mac OS X]].

* Initialization

My brain works better in lexical scope.

=lexical-binding= is the default for =(version< emacs-version
"27.1")=. That's what I'm using now, so I've commented this out. I'm
leaving it for reference.

#+begin_src emacs-lisp
;;; -*- lexical-binding: t -*-
#+end_src

** Debugging (when I want it)

#+begin_src emacs-lisp
;; (setq debug-on-error  t)
#+end_src

And if I'm debugging, I'll likely want to start Emacs with
~--debug-init -nw~. With Emacs for Mac OS X, that's

#+begin_src shell :tangle no
~/Applications/Emacs.app/Contents/MacOS/Emacs --debug-init -nw
#+end_src

Including this shell block results in some additional message during startup:
#+begin_quote
Setting up indent for shell type zsh
Indentation variables are now local.
Indentation setup for shell type zsh
#+end_quote

These messages are hard-coded when =sh-mode= is invoked. You can get rid
of these messages using advice [[https://emacs.stackexchange.com/a/53009][this response]] in Stack
Overflow. Another way would be to use [[https://github.com/raxod502/el-patch][el-patch]] to remove these
hard-coded messages as Radon Rosborough does in the [[https://github.com/raxod502/radian/commit/4ae79d629c4360a5f281cfc330154c900720d4b1][radian
package]]. But for now I'll just leave this note. (Wow. [[https://github.com/raxod502][Radon Rosborough]]
is cranking out great Emacs packages!)

** Initialization timing

I'm interested in how long Emacs initialization takes. This isn't
something I monitor closely, but I can't measure it if I don't add
code to do so. This is lifted from [[https://github.com/jwiegley/dot-emacs][John Wiegley's config]], the
gentleman who brought us (among other things), =use-package=. Not
surprisingly, he's /very/ interested in initialization performance. His
is another Emacs config that's worth reviewing for ideas.

#+begin_src emacs-lisp
(defconst emacs-start-time (current-time))

(unless noninteractive
  (message "Loading %s..." load-file-name))
#+end_src

** Tangling

=init.el= is loaded first, which, among other things, tangles and loads
this file, which contains the majority of my Emacs configuration. The
tangled output actually replaces the =init.el= in the repo. After
initial checkout, I don't want to track this generated replacement, so
I can tell git to ignore it:

#+begin_src shell :tangle no
git update-index --assume-unchanged init.el
#+end_src

And if there /are/ modifications I want to make, I can tell git to track
changes again.

#+begin_src shell :tangle no
git update-index --no-assume-unchanged init.el
#+end_src

If for some reason you want to start from the committed =init.el= again,
just check it out. Git will pull it from the index, but still not track it.

#+begin_src shell :tangle no
git checkout init.el
#+end_src

And let's have this file automatically re-tangled on save to keep
=init.el= up-to-date.

#+begin_src emacs-lisp
(defun tangle-init ()
  "If the current buffer is 'init.org' the code-blocks are tangled, and the tangled file is compiled."
  (when (equal (buffer-file-name)
               (expand-file-name (concat user-emacs-directory "init.org")))
    ;; Avoid running hooks when tangling.
    (let ((prog-mode-hook nil))
      (org-babel-tangle))))

(add-hook 'after-save-hook 'tangle-init)
#+end_src

This method of is largely based on [[https://github.com/larstvei/dot-emacs][Lars Tveito's config]]. He also
byte-compiles the output. I haven't seen any performance advantage of
byte-compiling my setup, so I've removed that as it brings along
another layer of complexity. There's a lot of other great stuff his
config; it's well worth a look.

** straight.el
I want an immutable package manager. I'm primarily waiting on three
things:

  * determining how I can easily detect if my packages are out of date
    and update them individually
  * convince myself there aren't gotchas that will be too much work to
    work around
  * convince myself that the project is going to be maintained for the
    foreseeable future.

I was convinced that I could move to [[https://github.com/raxod502/straight.el][straight.el]] by a blog post by
David Crook, [[https://github.crookster.org/switching-to-straight.el-from-emacs-26-builtin-package.el/]["Switching to straight.el from Emacs 26 builtin
package.el"]]. The situation has improved quite a bit since the post was
written (13 November 2018); the org-specific fixes are now part of
straight itself.

I tried this first on 2020-12-06, but reverted because I couldn't
figure out issues around org-ref (likely related to my ignorance
around autoloading). However, the melpa issues on [[https://github.com/melpa/melpa/issues/7312#issuecomment-751142747][melpa packaging issues on 2020-12-24]],
um, scared me straight, so I'm giving it another go.

First, bootstrap straight.el.

#+begin_src emacs-lisp
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)

(setq straight-use-package-by-default t)
(setq-default use-package-always-defer t)
#+end_src

** Detection
#+begin_src emacs-lisp
(defun is-mac-p ()
  (eq system-type 'darwin))

(defun is-linux-p ()
  (eq system-type 'gnu/linux))

(defun grzm/is-koke-p ()
  (string-equal (system-name) "koke.local"))

(defun grzm/is-m1-arm-p ()
  (grzm/is-koke-p))

(defun grzm/use-selectrum-p ()
  (grzm/is-koke-p))

(defun grzm/use-prescient-p ()
  (grzm/use-selectrum-p))

(defun grzm/prefer-helm-p ()
  (not (grzm/use-selectrum-p)))

(defun grzm/use-ivy-p ()
  (not (grzm/use-selectrum-p)))
#+end_src

The built-in ~window-system~ function and variable are also useful (and
used below) when modifying configuration for particular machines and
environments. For example, I don't do work with org-roam or pdfs when
not using gui Emacs, so I'm including them only ~:if window-system~.

* Configuration

Set default directory to =$HOME= when it's not otherwise set (such as
startup). It can default to =/= which is rarely what I want.
#+begin_src emacs-lisp
(setq default-directory "~/")
#+end_src

All of my configuration should be declared here. I'm not going to use
the custom settings interface, so use a temporary file for anyone that
thinks they need to reference it.
#+begin_src emacs-lisp
(setq custom-file (make-temp-file "emacs--custom-file"))
#+end_src

Besides being Lisp, =cl= provides =labels= and =defvar=, used
below. Wrapped gently in =eval-when-compile= to silence

#+begin_quote
Warning (bytecomp): cl package required at runtime
#+end_quote

#+begin_src emacs-lisp
(eval-when-compile
  (let* ((grzm/cl-package-deprecated-p (<= 27 emacs-major-version)))
    (when (not grzm/cl-package-deprecated-p)
      (require 'cl))))
#+end_src

#+begin_src emacs-lisp
(prefer-coding-system 'utf-8)
#+end_src

#+begin_src emacs-lisp
(eval-and-compile
  (mapc #'(lambda (path)
            (add-to-list 'load-path
                         (expand-file-name path user-emacs-directory)))
        '("elisp" "elpa")))
#+end_src

#+begin_src emacs-lisp
(let* ((local-org-mode-lisp "~/dev/org-mode/lisp"))
  (when (file-exists-p local-org-mode-lisp)
    (add-to-list 'load-path (expand-file-name "~/dev/org-mode/lisp"))))
#+end_src

#+begin_src emacs-lisp
(defsubst hook-into-modes (func &rest modes)
  (dolist (mode-hook modes) (add-hook mode-hook func)))
#+end_src

Use =y= and =n= in lieu of =yes= and =no= in mini-buffer prompts.

#+begin_src emacs-lisp
(fset 'yes-or-no-p 'y-or-n-p)
#+end_src

#+begin_src emacs-lisp
(setq confirm-nonexistent-file-or-buffer nil)
#+end_src

#+begin_src emacs-lisp
(setq kill-buffer-query-functions
      (remq 'process-kill-buffer-query-function
            kill-buffer-query-functions))
#+end_src

#+begin_src emacs-lisp
(defconst sans-font-family "Source Code Pro")
(defconst variable-font-family "OfficinaSansITCStd")
(set-face-attribute 'default nil
                    :family sans-font-family
                    :weight 'normal
                    :height 140)
(set-face-attribute 'fixed-pitch nil :family sans-font-family :height 1.0)
(set-face-attribute 'variable-pitch nil :family variable-font-family :height 1.2)

(setq-default line-spacing 0.4)
#+end_src

#+begin_src emacs-lisp
(defun clean-up-buffer ()
  "Indent the entire buffer."
  (interactive)
  (delete-trailing-whitespace)
  (indent-region (point-min) (point-max) nil)
  (untabify (point-min) (point-max)))
#+end_src

#+begin_src emacs-lisp
(let ((sources (if (is-mac-p)
                   (quote
                    ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc" macos-keychain-internet))
                 (quote ("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")))))
  (setq auth-sources sources))
#+end_src

I don't want to hear about advice redefinitions, messages like
#+begin_quote
ad-handle-definition: ‘vc-revert’ got redefined
#+end_quote
From [[https://andrewjamesjohnson.com/suppressing-ad-handle-definition-warnings-in-emacs/][Andrew Johnson]]
#+begin_src emacs-lisp
(setq ad-redefinition-action 'accept)
#+end_src

** UI settings

Quiet startup: Don't display the splash screen, start with a clear
scratch buffer, and don't display /"For information about GNU Emacs
and the GNU system, type C-h C-a."/.  This last is surprisingly
difficult to do, and requires both the =put= call and setting the
value to your user name.

From https://emacs.stackexchange.com/a/36303, with one change: use a
non-empty list (e.g., =(t)=) instead of =t= for the ='saved-value= or
you'll see errors like /(wrong-type-argument listp t)/ when Emacs
first tries to write customizations, and errors like /'forward-sexp:
Scan error: "Unbalanced parentheses"/ when it subsequently tries to
read the malformed custom-file contents it attempted to write.

#+begin_src emacs-lisp
(put 'inhibit-startup-echo-area-message 'saved-value '(t))
(setq inhibit-startup-screen t
      initial-scratch-message ""
      inhibit-startup-echo-area-message user-login-name)
#+end_src

When in a windowing system, set the default window size.

#+begin_src emacs-lisp
(when (window-system)
  (setq initial-frame-alist
        `((top . 0)
          (left . 0.5)
          (height . 1.0)
          (width . 100)))
  (setq default-frame-alist (copy-alist initial-frame-alist)))
#+end_src

#+begin_src emacs-lisp
(add-to-list 'custom-theme-load-path
               (file-name-as-directory
                (expand-file-name "themes" user-emacs-directory)))
(let* ((theme (cond ((window-system) 'grzm-ivory)
                    ((is-linux-p) 'solarized-dark)
                    (t 'minima-ebony))))
  (load-theme theme t))
#+end_src

Hide the toolbar.

#+begin_src emacs-lisp
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'menu-bar-mode) (menu-bar-mode -1))
;; I generally want scrollbars, but as a reminder of the option:
;; (if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
#+end_src

Always display the column number.

#+begin_src emacs-lisp
(setq column-number-mode t)
#+end_src

Who likes to be interrupted by a bell? I certainly don't.

#+begin_src emacs-lisp
(setq ring-bell-function 'ignore)
#+end_src

** Editing

#+begin_src emacs-lisp
(setq-default indent-tabs-mode nil) ;; insert multiple spaces instead of tabs
#+end_src

#+begin_src emacs-lisp
(show-paren-mode t)
#+end_src

#+begin_src emacs-lisp

;; Use C-x C-m as a shortcut for M-x: Let's save our small fingers!
;; Hint from Steve Yegge: http://steve.yegge.googlepages.com/effective-emacs
;; Invoice M-x without the alt key
(global-set-key "\C-x\C-m" 'execute-extended-command)

;; Steve also recommends adding C-c C-m to allow for slop in hitting C-x
;; Don't know if I'll need that now, but it might be nice in the future
;;(global-set-key "\C-x\C-m" 'execute-extended-command)
;; However, I often mistype C-x m and I don't use mail, so
(global-set-key "\C-xm" 'execute-extended-command)

;;; Unbind `C-x f', which, by default sets fill-text width, which is uncommon
(global-unset-key "\C-xf")

;;; Rebind `C-x C-b' for 'buffer-menu', rather than list-buffers
(global-set-key "\C-x\C-b" 'buffer-menu)

;; Item 3: Prefer backward-kill-word over Backspace
;; Another of Steve Yegge's hints
;; For fast typists, it's faster to retype a word rather than backspace
;; to fix just the error, so map this to C-w. However, C-w is already
;; mapped for kill-region, so remap kill-region to C-x C-k
(global-set-key "\C-w" 'backward-kill-word)
(global-set-key "\C-x\C-k" 'kill-region)
;; Again, Steve maps C-c C-k as well
;; (global-set-key "\C-c\C-k" 'kill-region)

;; Item 9: Master Emacs's regular expressions
;; Bind M-r and M-s to isearch-forward-regexp and isearch-backward-regexp
;; Note that this stomps on the default binding for move-to-window-line (M-r)
(global-set-key "\M-s" 'isearch-forward-regexp)
(global-set-key "\M-r" 'search-backward-regexp)

;; Since query-replace-regexp and (replace-regexp) are so useful,
;; give them abbreviated aliases
(defalias 'rr 'replace-regexp)
(defalias 'qrr 'query-replace-regexp)

;; from http://wiki.rubygarden.org/Ruby/page/show/InstallingEmacsExtensions
;; This is also of interrest, it automagically does a "chmod u+x" when you
;; save a script file (starting with "#!").
(add-hook 'after-save-hook
          'executable-make-buffer-file-executable-if-script-p)

(setq backup-directory-alist `(("." . "~/.saves")))
(setq backup-by-copying t)

(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)

(setq vc-follow-symlinks t)
#+end_src

** f and s
I use the =f= (file) and =s= (string) packages to configure subsequent
packages, so load them first.

*** f
#+begin_src emacs-lisp
(use-package f
 :commands (f-touch))
#+end_src

*** s
#+begin_src emacs-lisp
(use-package s
  :commands (s-downcase s-join s-trim))
#+end_src


** Work/Personal separation

I have some work-specific Emacs configuration that I like to keep
in a separate repo from my personal setup. Let's see if it's there.

#+begin_src emacs-lisp
(defvar work-emacs-directory "~/.emacs.work.d/")
(defvar work-p (file-exists-p work-emacs-directory))
#+end_src

#+begin_src emacs-lisp
(when work-p
  (org-babel-load-file (expand-file-name "init.org" work-emacs-directory)))
#+end_src

If it's not, continue with my usual config.

#+begin_src emacs-lisp
(unless (or work-p (is-linux-p))
  (defvar grzm/org-directory "~/org/")
  (defvar grzm/beorg-directory "/Users/grzm/Library/Mobile Documents/iCloud~com~appsonthemove~beorg/Documents/org/")
  (setq grzm/org-inbox-dot-org (expand-file-name "inbox.org" grzm/org-directory)
        grzm/org-todo-dot-org (expand-file-name "todo.org" grzm/org-directory)
        grzm/org-someday-maybe-dot-org (expand-file-name "someday-maybe.org" grzm/org-directory)

        grzm/beorg-inbox-dot-org (expand-file-name "inbox.org" grzm/beorg-directory)

        grzm/org-template-directory (expand-file-name "org/templates/" user-emacs-directory)
        grzm/zotero-bib "~/Documents/references/bibliography/zotero.bib"

        org-capture-templates
        `(("t" "Task" entry
           (file ,grzm/org-inbox-dot-org)
           (file ,(expand-file-name "task.org" grzm/org-template-directory))
           :prepend t
           :empty-lines 1)

          ("p" "Project" entry
           (file+headline ,grzm/org-todo-dot-org "Projects")
           (file ,(expand-file-name "project.org" grzm/org-template-directory))
           :empty-lines 1)

          ("w" "web reference" entry
           (file ,grzm/org-inbox-dot-org)
           (file ,(expand-file-name "web-ref.org" grzm/org-template-directory))
           :prepend t
           :empty-lines 1))

        org-refile-targets `(((,grzm/org-todo-dot-org
                               ,grzm/org-someday-maybe-dot-org)
                              :maxlevel . 3))

        org-tag-alist
        '(("q" . ?q)
          ("automower" . ?a)
          ("postgresql" . ?p)
          ("emacs" . ?e))

        org-agenda-custom-commands
        '(("n" "Agenda and all TODOs"
           ((agenda "" nil)
            (alltodo "" nil))
           nil))

        org-roam-directory "~/org/org-roam"
        org-roam-db-location (expand-file-name "org-roam.db" org-roam-directory)
        grzm/bibtex-notes-directory (expand-file-name "bibliography/notes/" org-roam-directory)))
#+end_src

I've found Tasshin Michael Fogleman's work on using org-mode with GTD
really helpful.  The templates and daily-review function are built on
his work. See his [[https://github.com/mwfogleman/.emacs.d/blob/master/michael.org#capture-templates][Emacs config]] and his [[https://gist.github.com/mwfogleman/267b6bc7e512826a2c36cb57f0e3d854][Building a Second Brain
templates]]. He also has posted a [[https://www.youtube.com/watch?v=LQwjSd3X9xE][video of how he uses them during his
daily review]].

#+begin_src emacs-lisp
(unless work-p
  (setq grzm/review-dot-org "/tmp/reviews.org")
  (f-touch grzm/review-dot-org)

  ;; This is buggy: first time after startup, calling C-c r, d raises the following error:
  ;; (error "No capture template referred to by \"d\" keys")
  ;; Subsequent calls seem fine, as does calling the function directly.
  (defun grzm/new-daily-review ()
    (interactive)
    (let ((org-capture-templates `(("d" "Review: Daily Review" entry
                                    (file+olp+datetree ,grzm/review-dot-org)
                                    (file ,(expand-file-name "daily-review.org"
                                                             grzm/org-template-directory))))))
      (progn
        (org-capture nil "d")
        (org-capture-finalize t)
        (org-speed-move-safe 'outline-up-heading)
        (org-narrow-to-subtree)
        (org-clock-in))))

  (bind-keys :prefix-map review-map
             :prefix "C-c r"
             ("d" . grzm/new-daily-review)))
#+end_src

** packages
*** autopair
#+begin_src emacs-lisp
(use-package autopair)
#+end_src

*** avy
#+begin_src emacs-lisp
(use-package avy
  :bind (("C-:" . avy-goto-char)
         ("C-'" . avy-goto-char-2)
         ("M-g g" . avy-goto-line)))
#+end_src

*** beacon
#+begin_src emacs-lisp
(use-package beacon
  :if window-system
  :config
  (setq beacon-size 80
        beacon-color "#bbb"
        beacon-blink-duration 0.1
        beacon-blink-delay 0.1)
  (beacon-mode 1))
#+end_src

*** blackout
#+begin_src emacs-lisp
(use-package blackout)

(with-eval-after-load 'auto-revert
    (blackout 'auto-revert-mode))

(with-eval-after-load 'eldoc
    (blackout 'eldoc-mode))
#+end_src
*** browse-kill-ring
#+begin_src emacs-lisp
(use-package browse-kill-ring)
#+end_src

*** cider
#+begin_src emacs-lisp
(use-package cider
  :defines cider-prompt-save-file-on-load
  :config
  (setq cider-prompt-save-file-on-load nil
        cider-eval-result-prefix " ;; => "
        cider-font-lock-dynamically '(macro core function var)
        cider-repl-pop-to-buffer-on-connect 'display-only
        cider-repl-display-help-banner nil
        cider-repl-use-pretty-printing t
        cider-boot-parameters "cider repl -w wait"))
#+end_src

#+begin_src emacs-lisp
(put 'cider-clojure-cli-global-options 'safe-local-variable #'stringp)
(put 'cider-preferred-build-tool 'safe-local-variable #'symbolp)
(put 'cider-boot-parameters 'safe-local-variable #'stringp)
#+end_src


*** clj-refactor
#+begin_src emacs-lisp
(use-package clj-refactor
  :config
  (setq cljr-assume-language-context (quote clj)
        cljr-clojure-test-declaration "[clojure.test :as test :refer [are deftest is]]")
  ;; :bind ("/" . cljr-slash)
  )
#+end_src

*** clojure-mode
#+begin_src emacs-lisp
(use-package clojure-mode
  :blackout "λ"
  :config
  (setq clojure-indent-style :align-arguments
        clojure-align-forms-automatically nil)
  (defun my-clojure-mode-hook ()
    (paredit-mode +1)
    (put-clojure-indent 'defui '(1 nil nil (1)))
    (rainbow-delimiters-mode))
  (add-to-list 'interpreter-mode-alist '("bb" . clojure-mode))
  (add-hook 'clojure-mode-hook 'my-clojure-mode-hook)
  (add-hook 'clojure-mode-hook 'lsp)
  (add-hook 'clojurescript-mode-hook 'lsp)
  (add-hook 'clojurec-mode-hook 'lsp))
#+end_src

*** company
#+begin_src emacs-lisp
(use-package company
  :blackout " ㍿"
  :init
  (setq company-idle-delay nil
        company-async-timeout 15
        company-tooltip-align-annotations t)
  :hook (after-init . global-company-mode))
#+end_src

*** company-prescient
#+begin_src emacs-lisp
(use-package company-prescient
  :init (company-prescient-mode +1))
#+end_src

*** ctrlf
isearch replacement
#+begin_src emacs-lisp
(use-package ctrlf
  :config
  (ctrlf-mode t))
#+end_src

*** delight
#+begin_src emacs-lisp
(use-package delight)
#+end_src

*** dired
=ls= on Darwin doesn't support the =--dired= option.
https://stackoverflow.com/a/42038174
#+begin_src emacs-lisp
(when (is-mac-p)
  (setq dired-use-ls-dired nil))
#+end_src

*** dockerfile-mode
#+begin_src emacs-lisp
(use-package dockerfile-mode
  :mode "Dockerfile[a-zA-Z.-]*\\'")
#+end_src

*** el-patch
#+begin_src emacs-lisp
(use-package el-patch)
#+end_src

*** emacs-lisp-mode
Structural editing rocks. Use it for =emacs-lisp=, too.

#+begin_src emacs-lisp
(add-hook 'emacs-lisp-mode-hook
          (lambda () (paredit-mode +1)))
#+end_src

*** exec-path-from-shell
#+begin_src emacs-lisp
(use-package exec-path-from-shell
  :demand t
  :if (memq window-system '(mac ns))
  :config
  (exec-path-from-shell-initialize))
#+end_src

*** flycheck
#+begin_src emacs-lisp
(use-package flycheck
  :init (global-flycheck-mode))
#+end_src

*** git-gutter and git-gutter-fringe
#+begin_src emacs-lisp
(let ((package-name (if (display-graphic-p) 'git-gutter-fringe 'git-gutter)))
  (eval `(use-package ,package-name
           :init (global-git-gutter-mode))))
;; Don't need git-gutter to tell us it's active.
(setq git-gutter:lighter "")
#+end_src

*** graphviz-dot-mode
#+begin_src emacs-lisp
(use-package graphviz-dot-mode
  :config
  (setq graphviz-dot-ident-width 2))
#+end_src

*** helm

Binding =M-y= to =helm-show-kill-ring= is from [[https://sachachua.com/blog/2014/12/emacs-m-y-helm-show-kill-ring/][Sacha Chua]].

#+begin_src emacs-lisp
(use-package helm
  :blackout " Ⓗ"
  :bind (("M-y" . helm-show-kill-ring)
         :map helm-map
         ("" . helm-execute-persistent-action)
         ("C-z" . helm-select-action)
         ("A-v" . helm-previous-page))
  :config
  (when (grzm/prefer-helm-p)
    (helm-mode 1)
    (helm-autoresize-mode 1)))
#+end_src

*** helm-org-rifle
#+begin_src emacs-lisp
(use-package helm-org-rifle)
#+end_src

*** helm-bibtex
helm-bibtex includes bibtex-completion, so =bibtex-completion-*= configuration is here.

#+begin_src emacs-lisp
(use-package helm-bibtex
  :config
  (unless (or work-p (is-linux-p))
    (setq bibtex-completion-bibliography grzm/zotero-bib
          bibtex-completion-notes-path grzm/bibtex-notes-directory
          bibtex-completion-pdf-field "file"

          bibtex-completion-notes-template-multiple-files
          (f-read-text (expand-file-name "bibtex-completion-notes-template-multiple-files"
                                         grzm/org-template-directory)))))
#+end_src

*** inf-clojure
#+begin_src emacs-lisp
(use-package inf-clojure)
#+end_src

*** ivy
#+begin_src emacs-lisp
(when (grzm/use-ivy-p)
  (use-package ivy
    :config
    (setq ivy-use-virtual-buffers t
          enable-recursive-minibuffers t)
    (ivy-mode 1)
    :bind ("C-w" . ivy-backward-kill-word)))
#+end_src

*** lsp-mode
#+begin_src emacs-lisp
(use-package lsp-mode
  :delight '(" 

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。