Skip to content

Latest commit

 

History

History
1524 lines (1278 loc) · 44.8 KB

File metadata and controls

1524 lines (1278 loc) · 44.8 KB

Emacs Config

Startup Performance

;; The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

(defun efs/display-startup-time ()
  (message "Emacs loaded in %s with %d garbage collections."
           (format "%.2f seconds"
                   (float-time
                    (time-subtract after-init-time before-init-time)))
           gcs-done))

(add-hook 'emacs-startup-hook #'efs/display-startup-time)

Config Variables

General

(defvar my/home user-emacs-directory 
  "Original value of `user-emacs-directory'.")

(defvar my/cache (expand-file-name "~/.cache/emacs/") 
  "Redirection target of `user-emacs-directory'.")

(defvar my/browser (getenv "BROWSER") 
  "Default system web browser.")

(defvar my/language (getenv "LANG") 
  "Default system dictionary language.")

(defvar my/font "Fira Code" 
  "Unified system font family.")

(defvar my/font-size 130
  "Unified system font size.")

(defvar my/frame-transparency '(95 . 95)
  "transperaency")

(defvar my/idle 1.0
  "Delay time before offering suggestions and completions.")

(defvar my/leader-key "SPC" 
  "All powerful leader key.")

(defvar my/leader-key-global 
  (concat "C-" my/leader-key) 
  "Global prefix for the leader key.")

(defvar my/projects 
  (expand-file-name "~/.local/source/") 
  "Location of source code projects.")

(defvar my/passwords 
  (expand-file-name "~/.password-store/") 
  "Location of local password store.")

(defvar my/public-key 
  "" ;;Override in host config
  "GPG key to encrypt org files for.")

Org

private org setting should be in host config

(defvar my/org-directory "~/org"
  "location of org files")

Hooks

(defvar my/end-hook nil
  "Hook called at the end of the config for custom host configs")

Per Host Config (Overrides)

Must be ran after the config section These are host specific variables, plus all the private variables

(defun my/load-host (host-name)
  "Load the configuration file for `host-name'."
  (let ((host-file (concat my/home "hosts/" host-name ".el")))
    (if (file-exists-p host-file)
        (progn
          (message "Loading Host file: %s" host-file)
          (load host-file))
      ;;(org-babel-load-file host-file))
      (message "No Host file found: %s" host-file))))

(my/load-host system-name)

Cache

Shortly after initialization, before most packages load, we change the value to `my/cache’. https://chrishayward.xyz/immutable-emacs/.

(setq user-emacs-directory my/cache
      url-history-file (concat user-emacs-directory "url/history"))

(setq custom-file (concat user-emacs-directory "custom.el"))
(load custom-file t)

Server Mode

Start the Emacs server from this instance so that all emacsclient calls are routed here.

(server-start)

Package Management

Set up ELPA, MELPA, and Org package repositories and load use-package to manage package configuration.

NOTE: I’m keeping this section in but disabling tangling for now because I’m trying out straight.el as an alternative.

;; Initialize package sources
(require 'package)

(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                         ("melpa-stable" . "https://stable.melpa.org/packages/")
                         ("org" . "https://orgmode.org/elpa/")
                         ("elpa" . "https://elpa.gnu.org/packages/")))

(package-initialize)
;; (unless package-archive-contents
;;   (package-refresh-contents))

;; Initialize use-package on non-Linux platforms
(unless (package-installed-p 'use-package)
  (package-install 'use-package))

(require 'use-package)

;; Uncomment this to get a reading on packages that get loaded at startup
(setq use-package-verbose t)

(setq use-package-always-ensure t)

straight.el

Trying out straight.el for package management. So far so good!

;; Bootstrap straight.el
(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))

(setq straight-use-package-by-default t)

;; Use straight.el for use-package expressions
(straight-use-package 'use-package)

;; Load the helper package for commands like `straight-x-clean-unused-repos'
(require 'straight-x)

No littering

;; Use no-littering to automatically set common paths to the new user-emacs-directory
(use-package no-littering)

Auto Updates

(use-package auto-package-update
  :custom
  (auto-package-update-interval 7)
 (auto-package-update-prompt-before-update t)
 (auto-package-update-hide-results t)
 :config
 (auto-package-update-maybe)
(auto-package-update-at-time "09:00"))

Diminish

(use-package diminish
   :ensure t)

Editor

Selection menu

(use-package ivy
  :diminish
  :after evil
  :bind (("C-s" . swiper)
         :map ivy-minibuffer-map
         ("TAB" . ivy-alt-done)
         ("C-l" . ivy-alt-done)
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         :map ivy-switch-buffer-map
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         ("C-l" . ivy-done)
         ("C-d" . ivy-switch-buffer-kill)
         :map ivy-reverse-i-search-map
         ("C-k" . ivy-previous-line)
         ("C-j" . ivy-next-line)
         ("C-d" . ivy-reverse-i-search-kill))
  :init
  (ivy-mode 1)
  :config
  (setq ivy-use-virtual-buffers t)
  (evil-define-key 'insert ivy-minibuffer-map (kbd "C-k") 'ivy-previous-line)
  (evil-define-key 'insert ivy-switch-buffer-map (kbd "C-d") 'ivy-switch-buffer-kill)
  )

Swiper

M-n put word at point into Swiper

Keybinding Completions

(use-package which-key
  :demand t
  :bind (("C-h SPC" . which-key-toggle-docstring))

  :config
  (setq which-key-show-early-on-C-h t)
                                        ; Only show when you hit C-h manually
  (setq which-key-idle-delay my/idle)
  (setq which-key-idle-secondary-delay 0.05)
  (which-key-mode 1)
  )

Replace built in commands

*Counsel*[fn:1] is a customized set of commands to replace built in completion buffers.

(use-package counsel
  :after ivy
  :custom (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
  :config (counsel-mode 1))

Undo

(setq evil-want-fine-undo t)

Show recent m-x commands

(use-package amx)

Additional columns in Ivy

(use-package all-the-icons-ivy-rich
  :ensure counsel
  :init (all-the-icons-ivy-rich-mode 1))

(use-package ivy-rich
  :ensure counsel
  :init (ivy-rich-mode 1))

Y or N

(defalias 'yes-or-no-p 'y-or-n-p)

Keybindings

Make ESC quit prompts

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Evil

(use-package evil
  :custom (evil-want-integration t)  ;; Required for `evil-collection'.
  (evil-want-keybinding nil) ;; Same as above
  :config (evil-mode +1)
  :init   (setq evil-undo-system 'undo-fu))

(use-package evil-collection
  :after evil
  :custom (evil-collection-setup-minibuffer t)
  :init (evil-collection-init)
  (setq evil-toggle-key "C-`"))

(use-package undo-fu
  :config
  ;;    (global-undo-tree-mode -1)
  (define-key evil-normal-state-map "u" 'undo-fu-only-undo)
  (define-key evil-normal-state-map "\C-r" 'undo-fu-only-redo))

Leader Key

(use-package general
  :after evil
  :config
  (general-create-definer my/leader
    :states '(normal motion)
    :keymaps 'override
    :prefix my/leader-key
    :global-prefix my/leader-key-global))

Transient bindings

  • Defer loading for performance
(use-package hydra
  :defer t)

Commenting

(use-package evil-nerd-commenter
  :after evil
  :bind ("M-;" . evilnc-comment-or-uncomment-lines))

Top Level Keybindings

(my/leader
  ;;"."   '(find-file :which-key "Files")
  ":"   '(eval-expression :which-key "expression")
  "SPC" '(counsel-M-x :which-key "M-x")
  "r"   '(ivy-resume :which-key "ivy resume")
  "c"   '(kill-buffer-and-window :which-key "Close")

  "a"  '(:ignore t :which-key "Apps")
  "b"  '(:ignore t :which-key "Buffer")
  "o"  '(:ignore t :which-key "Open")
  "s"  '(:ignore t :which-key "search")
  "S"  '(:ignore t :which-key "Spelling")
  "t"  '(:ignore t :which-key "Toggle")

  "au" '(straight-pull-all :which-key "update pkgs")

  "td" '(toggle-debug-on-error :which-key "debug")
  )

Buffer

(defun my/kill-buffer ()
  (interactive)
  (kill-buffer nil)) 

(defun my/close-all-buffers ()
  (interactive)
  (mapc 'kill-buffer (buffer-list)))


(my/leader
  "," '(counsel-switch-buffer :which-key "Buffers")
  "SPC"  '(counsel-M-x :which-key "M-x")
  "bb"  '(ivy-switch-buffer :which-key "list")
  "bB"  '(ivy-switch-buffer-other-window :which-key "list +other win")
  "bd"  '(my/kill-buffer :which-key "delete")
  "bD"  '(evil-delete-buffer :which-key "delete + windows")
  "bl"  '(evil-switch-to-windows-last-buffer :which-key "last")
  "bm"  '(exit-minibuffer :which-key "exit-mini")
  "bn"  '(next-buffer :which-key "next")
  "bp"  '(previous-buffer :which-key "prev")
  "br"  '(counsel-buffer-or-recentf  :which-key "recent"))

Exiting / Quiting Keybindings

(my/leader
  "q" '(:ignore t :which-key "Quit")
  "qq" '(save-buffers-kill-terminal :which-key "Save")
  "qw" '(kill-emacs :which-key "Now")
  "qf" '(delete-frame :which-key "Frame"))

File

(my/leader
  "f"  '(:ignore t :which-key "file")
  "fd" '((lambda () (interactive) (find-file (expand-file-name "~/.emacs.d/emacs.org"))) :which-key "dotfile" )
  "fD"  '(diff-buffer-with-file :which-key "unsaved diff")
  "ff"  '(find-file :which-key "find file")
  "fF"  '(counsel-locate :which-key "global find")
  "fj"  '(counsel-file-jump :which-key "jump to file")
  "fr"  '(counsel-recentf :which-key "recent")
  "fR"  '(revert-buffer :which-key "revert file")
  "fs"  '(save-buffer :which-key "save"))

Frame

(my/leader
  "F"  '(:ignore t :which-key "Frame")
  "Fn"  '(make-frame :which-key "new"))

Window Management

Winum

(use-package winum
  :after evil
  :config (winum-mode)
  )

(my/leader
  "0" '(winum-select-window-0 :which-key "Window-0")
  "1" '(winum-select-window-1 :which-key "Window-1")
  "2" '(winum-select-window-2 :which-key "Window-2")
  "3" '(winum-select-window-3 :which-key "Window-3")
  "4" '(winum-select-window-4 :which-key "Window-4")
  )

Keybindings

(defun my/window-split-and-follow ()
  (interactive)
  (split-window-below)
  (other-window 1)
  (switch-to-buffer (other-buffer)))

(defun my/window-vsplit-and-follow ()
  (interactive)
  (split-window-right)
  (other-window 1)
  (switch-to-buffer (other-buffer)))

(my/leader
  "w" '(:ignore t :which-key "Window")
  "ww" '(window-swap-states :which-key "Swap")
  "wd" '(delete-window :which-key "Delete")
  "wh" '(windmove-left :which-key "Left")
  "wj" '(windmove-down :which-key "Down")
  "wk" '(windmove-up :which-key "Up")
  "wl" '(windmove-right :which-key "Right")
  "ws" '(my/window-split-and-follow :which-key "split Down")
  "wS" '(my/window-vsplit-and-follow :which-key "split Right")
  "wH" '(evil-window-move-far-left :which-key "Left")
  "wJ" '(evil-window-move-far-bottom :which-key "Down")
  "wK" '(evil-window-move-far-top :which-key "Up")
  "wL" '(evil-window-move-far-right :which-key "Right"))

Yanking

Links

(defun my/yank-link (&optional arg)
  "Extract URL from org-mode link and add it to kill ring."
  (interactive "P")
  (let* ((link (org-element-lineage (org-element-context) '(link) t))
         (type (org-element-property :type link))
         (url (org-element-property :path link))
         (url (concat type ":" url)))
    (kill-new url)
    (message (concat "Copied URL: " url))))

Keybindings

(my/leader
  "y" '(:ignore t :which-key "yank")
  "yl" '(my/yank-link :which-key "link"))

Interface

Make the window modernized

(setq inhibit-startup-message t)

(scroll-bar-mode -1)        ; Disable visible scrollbar
(tool-bar-mode -1)          ; Disable the toolbar
(tooltip-mode -1)           ; Disable tooltips
(set-fringe-mode 10)        ; Give some breathing room

(menu-bar-mode -1)            ; Disable the menu bar

;; Set up the visible bell
(setq visible-bell t)

Unified fonts

Write out to all of Emacs’ available font faces with the unified font defined in the options.

(set-face-attribute 'default nil :font my/font :height my/font-size)
(set-face-attribute 'fixed-pitch nil :font my/font :height my/font-size)
(set-face-attribute 'variable-pitch nil :font my/font :height my/font-size)

Text scaling

Define a transient keybinding for Scaling the text.

(defhydra hydra-text-scale (:timeout 4)
  "Scale"
  ("j" text-scale-increase "Increase")
  ("k" text-scale-decrease "Decrease")
  ("f" nil "Finished" :exit t))
  • Scale the text inside of buffers with SPC t f
    • Increase j
    • Decrease k
    • Finished f
(my/leader
  "tf" '(hydra-text-scale/body :which-key "Font"))

Icon fonts

Dired feels more modern with prioritized icon fonts using *All the Icons*[fn:3]. This makes navigation and visually parsing directories much faster, given that file types are quickly identified by their corresponding icons.

(use-package all-the-icons)

Integration with the *All the Icons Dired*[fn:4]package.

(use-package all-the-icons-dired)
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode)

Symbols

Programming buffers made prettier with *Pretty mode*[fn:9], complimentary to the built-in *Prettify symbols mode*[fn:10].

(use-package pretty-mode
  :hook (python-mode . turn-on-pretty-mode))

Ligatures

Enable font ligatures via *Fira Code mode*[fn:11].

  • Perform when Fira Code is the current font
  • Don’t enable on TTY
(use-package fira-code-mode
  :when (and (window-system)
             (equal my/font "Fira Code"))
  :hook (prog-mode))

Toggle global ligature mode with SPC t g.

(my/leader
  "tg" '(global-fira-code-mode :which-key "Ligatures"))

Emojification

Gotta have those emojis, first class support for Emacs via the *Emacs-emojify*[fn:13] package.

(use-package emojify
  :when (window-system)
  :hook (after-init . global-emojify-mode))
  • Place *Emojify*[fn:13] bindings behind SPC f
    • List with l
    • Search with s
    • Insert with i
    • Describe with d
(my/leader
  "i" '(:ignore t :which-key "insert")
  "is" '(yas-insert-snippet :which-key "snippet")
  "iu" '(insert-char :which-key "unicode")
  "ir" '(counsel-evil-registers :which-key "register")
  ;;"iy" '( :which-key "From Clipboard") ;;TODO
  "if" '(:ignore t :which-key "Emojify")
  "ifl" '(emojify-list-emojis :which-key "List")
  "ifs" '(emojify-apropos-emoji :which-key "Search")
  "ifi" '(emojify-insert-emoji :which-key "Insert")
  "ifd" '(emojify-describe-emoji :which-key "Describe"))

Modern themes

High quality and modern colour themes are provided in the *Doom Themes*[fn:5] package.

(use-package doom-themes
  :init (load-theme 'doom-one t))

Load a theme with SPC t t.

(my/leader
  "tt" '(counsel-load-theme t t :which-key "Theme"))

Status bar

Doom Modeline

Doom modeline provides an elegant and modern status bar / modeline.

(use-package doom-modeline
  :custom
  (doom-modeline-height 16)
  :config
  (doom-modeline-mode 1)
  )

Which Function

(which-function-mode t)

Include full tree of the org location

(defun org-which-function ()
  (interactive)
  (when (eq major-mode 'org-mode)
    (org-display-outline-path)
    ;;(org-display-outline-path nil t ">" t)
    ))

(add-to-list 'which-func-functions #'org-which-function)

Transparency

(set-frame-parameter (selected-frame) 'alpha my/frame-transparency)
(add-to-list 'default-frame-alist `(alpha . ,my/frame-transparency))
;;(set-frame-parameter (selected-frame) 'fullscreen 'maximized)
;;(add-to-list 'default-frame-alist '(fullscreen . maximized))

Parentheses

Highlight matching

(show-paren-mode 1)

Parenthesis

Colorize nested parenthesis with *Rainbow delimiters*[fn:8].

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

flycheck

(use-package flycheck
  :defer t
  :hook (lsp-mode . flycheck-mode))

evil-owl

(use-package evil-owl
  :config
  ;; (setq evil-owl-max-string-length 500)
  ;; (add-to-list 'display-buffer-alist
  ;;              '("*evil-owl*"
  ;;                (display-buffer-in-side-window)
  ;;                (side . bottom)
  ;;                (window-height . 0.3)))

  ;;use posframe
  (setq evil-owl-display-method 'posframe
        evil-owl-extra-posframe-args '(:width 50 :height 20)
        evil-owl-max-string-length 50)
  (evil-owl-mode))

company

(use-package company
  :bind (:map company-active-map
              ("C-n" . company-select-next)
              ("C-p" . company-select-previous))
  :config
  (setq company-idle-delay 0.3)
  (global-company-mode t))

ansi-color

fix the encoding in the shell buffers

(require 'ansi-color)
(defun my/ansi-colorize-buffer ()
  (let ((buffer-read-only nil))
    (ansi-color-apply-on-region (point-min) (point-max))))
(add-hook 'compilation-filter-hook 'my/ansi-colorize-buffer)

UTF

(set-language-environment "UTF-8")

Snippets

(use-package yasnippet
  :hook (prog-mode . yas-minor-mode)
  :config
  (yas-reload-all))

(use-package yasnippet-snippets)

Files

Auto-save

(setq auto-save-default t
      auto-saves-dir (concat my/cache "autosave/")
      auto-save-file-name-transforms `((".*" ,auto-saves-dir t)))

Backups

(setq create-lockfiles t
      make-backup-files t
      ;; But in case the user does enable it, some sensible defaults:
      version-control t     ; number each backup file
      backup-by-copying t   ; instead of renaming current file (clobbers links)
      delete-old-versions t ; clean up after itself
      kept-old-versions 5
      kept-new-versions 5
      backup-directory-alist (list (cons "." (concat my/cache "backup/")))
      tramp-backup-directory-alist backup-directory-alist)

Track Recent Files

Turn on Recent file mode

(recentf-mode 1)

Auto save the recent list

;;(run-at-time nil (* 15 60) 'recentf-save-list)
;;moved to end

Auto-save Org files

(add-hook 'auto-save-hook 'org-save-all-org-buffers)

Auto Revert

(custom-set-variables
 '(auto-revert-interval 1))
(global-auto-revert-mode 1)

Org

Better Font Faces

The efs/org-font-setup function configures various text faces to tweak the sizes of headings and use variable width fonts in most cases so that it looks more like we’re editing a document in org-mode. We switch back to fixed width (monospace) fonts for code blocks and tables so that they display correctly.

(defun my/org-font-setup ()
  ;; Replace list hyphen with dot
  (font-lock-add-keywords 'org-mode
                          '(("^ *\\([-]\\) "
                             (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) ""))))))

  ;; Set faces for heading levels
  (dolist (face '((org-level-1 . 1.2)
                  (org-level-2 . 1.1)
                  (org-level-3 . 1.05)
                  (org-level-4 . 1.0)
                  (org-level-5 . 1.1)
                  (org-level-6 . 1.1)
                  (org-level-7 . 1.1)
                  (org-level-8 . 1.1)))
    (set-face-attribute (car face) nil :font "Cantarell" :weight 'regular :height (cdr face)))

  ;; Ensure that anything that should be fixed-pitch in Org files appears that way
  (set-face-attribute 'org-block nil    :foreground 'unspecified :inherit 'fixed-pitch)
  (set-face-attribute 'org-table nil    :inherit 'fixed-pitch)
  (set-face-attribute 'org-formula nil  :inherit 'fixed-pitch)
  (set-face-attribute 'org-code nil     :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-table nil    :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-checkbox nil  :inherit 'fixed-pitch)
  (set-face-attribute 'line-number nil :inherit 'fixed-pitch)
  (set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch))

Templates

(defun my/org-mode-config-templates ()
  :config (require 'org-tempo)
  (add-to-list 'org-structure-template-alist '("ss" . "src"))
  (add-to-list 'org-structure-template-alist '("q" . "quote"))
  (add-to-list 'org-structure-template-alist '("x" . "example"))
  (add-to-list 'org-structure-template-alist '("sb" . "src shell"))
  (add-to-list 'org-structure-template-alist '("se" . "src emacs-lisp"))
  (org-babel-do-load-languages 'org-babel-load-languages '((shell . t)
                                                           (emacs-lisp . t)))
  )

General & Package Setup

(defun my/org-mode-setup ()
  (org-indent-mode)
  (variable-pitch-mode 1)
  (visual-line-mode 1))

(use-package org
  :straight (:type git :repo "https://code.orgmode.org/bzg/org-mode.git")
  :hook (org-mode . my/org-mode-setup)
  :config
  (setq org-ellipsis "")
  (my/org-font-setup)
  (my/org-mode-config-templates))

;; (use-package org-bullets
;;   :after org
;;   :hook (org-mode . org-bullets-mode)
;;   :custom
;;   (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))

(defun my/org-mode-visual-fill ()
  (setq visual-fill-column-width 100
        visual-fill-column-center-text t)
  (visual-fill-column-mode 1))

;; (use-package visual-fill-column
;;   :hook (org-mode . my/org-mode-visual-fill))

superstar

Make headline stars super with *Org superstar mode*[fn:14].

;; (use-package org-superstar
;;   :when (window-system)
;;   :after org
;;   :hook (org-mode . org-superstar-mode))

Indent setting

Enable `org-indent-mode’ by default

(setq org-startup-indented t) 

Todo settings

Task flow

(setq org-todo-keywords 
      '((sequence "LATER(l)" "TODO(t)" "NEXT(n)" "|" "DONE(d!)" "ARCHIVED(a)" "DROPPED(x)")
	(sequence "FU(f)" "|" "DONE(d!)" )
	;;(sequence "HABIT(h)", "|", "DONE(d!)")
	))
(setq org-use-fast-todo-selection 'nil)
(setq org-log-into-drawer t)
(setq org-log-reschedule 'note)

when marking a task as Done it will get a timestamp

(setq org-log-done 'time)  

Agenda

(setq org-agenda-skip-deadline-prewarning-if-scheduled 1)
(setq org-agenda-window-setup 'other-window)
;;(setq org-agenda-prefix-format '(
;;                                 (todo .
;;                                       " %i %-1:c %(concat \"[ \"(org-format-outline-path ;;(org-get-outline-path)) \" ]\") ")))

Evil

(use-package evil-org
  :after org
  :hook ((org-mode . evil-org-mode)
         (org-agenda-mode . evil-org-mode)
         (evil-org-mode . (lambda () (evil-org-set-key-theme '(navigation todo insert textobjects additional shift)))))
  :config
  (require 'evil-org-agenda)
  (evil-org-agenda-set-keys))

Keybindings

;;(evil-define-key 'normal org-mode-map (kbd "RET") 'org-open-at-point)

(my/leader
  "oa" '(org-agenda :which-key "agenda")
  "oc" '(org-capture :which-key "capture"))

(my/leader org-mode-map
  "er" '(eval-region :which-key "eval region")
  "es" '(org-babel-execute-src-block :which-key "eval src block")
  "m." '(counsel-org-goto :which-key "org-goto")
  "mA" '(org-archive-subtree :which-key "archieve subtree")
  "mc" '(org-capture :which-key "capture")
  "mb" '(:ignore t :which-key "babel")
  "mbf" '(org-babel-tangle-file :which-key "tangle-file")
  "mbt" '(org-babel-tangle :which-key "tangle")
  "md" '(:ignore t :which-key "dates")
  "mdd" '(org-deadline :which-key "deadline")
  "mds" '(org-schedule :which-key "schedule")
  "mdt" '(org-time-stamp :which-key "timestamp")
  "mdT" '(org-timestamp-inactive :which-key "timestamp inactive")
  "mi" '(:ignore t :which-key "Insert")
  "mih" '(org-insert-heading-after-current :which-key "heading(after)")
  "mit" '(org-insert-structure-template :which-key "template")
  "mR" '(org-refile :which-key "refile")
  "mt" '(org-todo :which-key "todo")
  "mT" '(org-todo-list :which-key "todo list")
  "mx" '(org-toggle-checkboox :which-key "toggle checkbox"))


(my/leader emacs-lisp-mode-map
  "eb" '(eval-buffer :which-key "eval buffer")
  "ee" '(eval-last-sexp :which-key "eval exp")
  "er" '(eval-region :which-key "eval region"))

Setting

(setq org-src-tab-acts-natively t) 
(setq org-directory my/org-directory)

Refiling

Allow refiling to top level header

(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps 'nil)

Capture

support for creating a floating window for capture from DM http://www.diegoberrocal.com/blog/2015/08/19/org-protocol/

for EXWM see .\desktop.org for i3 see ~.config\i3\config

(require 'org-protocol)

(defadvice org-capture
    (after make-full-window-frame activate)
  "Advise capture to be the only window when used as a popup"
  (message "org-capture")
  (if (equal "emacs-capture" (frame-parameter nil 'name))
      (delete-other-windows)))


(defadvice org-capture-finalize
    (after delete-capture-frame activate)
  "Advise capture-finalize to close the frame"
  (message "org-capture-finalize")
  (if (equal "emacs-capture" (frame-parameter nil 'name))
      (delete-frame)))

script file ~\bin\emacs-capture

#!/usr/bin/env bash
/usr/bin/emacsclient -n -c -F "((name . \"emacs-capture\") (height . 20) (width . 80))" "$@"

i3 example

for_window [title="emacs-capture"] floating enable

set $emacs-capture "Emacs Capture:  (T)odo  (I)dea  (L)ink"
mode $emacs-capture {
    bindsym t exec ~/bin/emacs-capture --eval '(org-capture nil "t")'; mode "default"
    bindsym l exec emacs-capture --eval '(org-capture nil "l")'; mode "default"
    bindsym i exec emacs-capture --eval '(org-capture nil "i")'; mode "default"

    bindsym q mode "default"
    bindsym Ctrl+g mode "default"
    bindsym Return mode "default"
}
#bindsym --release $mod+Shift+x  mode $emacs-capture
bindsym $mod+Control+x exec ~/bin/emacs-capture --eval '(org-capture)'

auto-tangle Configuration Files

Tangle any file with this “`#+auto_tangle: t“`

(use-package org-auto-tangle
  :defer t
  :hook (org-mode . org-auto-tangle-mode))

org-roam

Init

(use-package org-roam
  :ensure t
  :init
  (setq org-roam-v2-ack t
	org-roam-directory "~/roam"
	org-roam-dailies-journal "journal/"
	org-roam-mode-sections
        (list #'org-roam-backlinks-section
              #'org-roam-reflinks-section
              ;; #'org-roam-unlinked-references-section
              ))
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n I" . org-roam-node-insert-immediate))
  :config
  ;;(org-roam-setup))
  (org-roam-db-autosync-mode))

Key Command

(my/leader
  "r" '(org-roam-node-find :which-key "org-roam")
  "or" '(org-roam-node-find :which-key "org-roam-node-find")
  "ar" '(:ignore t :which-key "org-roam")
  "arc" '(org-roam-capture :which-key "capture")
  "arf" '(org-roam-node-find :which-key "node find")
  "arg" '(org-roam-graph :which-key "graph")
  "ali" '(org-roam-node-insert :which-key "node insert")
  "arl" '(org-roam-buffer-toggle :which-key "buffer-toggle")
  "art" '(:ignore t :which-key "tags")
  "arta" '(org-roam-tag-add :which-key "tag add")
  "artr" '(org-roam-tag-remove :which-key "tag remove")
  "ara" '(org-roam-alias-add :which-key "alias add"))

(my/leader org-mode-map
  "mr" '(:ignore t :which-key "org-roam")
  "mrc" '(org-roam-capture :which-key "capture")
  "mrf" '(org-roam-node-find :which-key "node find")
  "mrg" '(org-roam-graph :which-key "graph")
  "mri" '(org-roam-node-insert :which-key "node insert")
  "mri" '(org-roam-node-insert-immediate :which-key "node insert")
  "mrl" '(org-roam-buffer-toggle :which-key "buffer-toggle")
  "mrr" '(org-roam-refile :which-key "refile")
  "mrt" '(:ignore t :which-key "tags")
  "mrta" '(org-roam-tag-add :which-key "tag add")
  "mrtr" '(org-roam-tag-remove :which-key "tag remove")
  "mra" '(org-roam-alias-add :which-key "alias add"))

(my/leader 
  "d" '(:ignore t :which-key "dailies")
  "dd" '(org-roam-dailies-capture-today :which-key "capture today")
  "dt" '(org-roam-dailies-goto-today :which-key "Today")
  "dy" '(org-roam-dailies-goto-yesterday :which-key "Yesterday")
  "dl" '(org-roam-dailies-goto-tomorrow :which-key "Later (Tommorow)")
  "dg" '(org-roam-dailies-goto-date :which-key "Goto Date")
  "db" '(org-roam-dailies-goto-previous-note :which-key "Back a Note")
  "df" '(org-roam-dailies-goto-next-note :which-key "Forward a Note")
  )

(my/leader org-roam-dailies-map
  "," '(org-roam-dailies-goto-previous-note :which-key "Back a Note")
  "." '(org-roam-dailies-goto-next-note :which-key "Forward a Note")
  )

Fast note insertion for a smoother writing flow

(defun org-roam-node-insert-immediate (arg &rest args)
  (interactive "P")
  (let ((args (cons arg args))
        (org-roam-capture-templates (list (append (car org-roam-capture-templates)
                                                  '(:immediate-finish t)))))
    (apply #'org-roam-node-insert args)))

Refile to today

(defun my/org-roam-copy-todo-to-today ()
  (interactive)
  (let ((org-refile-keep nil) ;; Set this to nil to delete the original!
	(org-roam-dailies-capture-templates
         '(("t" "tasks" entry "%?"
            :if-new (file+head+olp "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n" ("Tasks")))))
	(org-after-refile-insert-hook #'save-buffer)
	today-file
	pos)
    (save-window-excursion
      (org-roam-dailies--capture (current-time) t)
      (setq today-file (buffer-file-name))
      (setq pos (point)))

    ;; Only refile if the target file is different than the current file
    (unless (equal (file-truename today-file)
                   (file-truename (buffer-file-name)))
      (org-refile nil nil (list "Tasks" today-file nil pos)))))

Org-roam UI

(use-package org-roam-ui
  :straight
  (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
  :after org-roam
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  ;;  :hook (after-init . org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))

(my/leader org-mode-map
  "mru" '(org-roam-ui-open :which-key "ui"))

org-joural

(use-package org-journal
  :init
  (setq org-journal-dir "~/org/journal/")
  )

Habits

(require 'org-habit)
(add-to-list 'org-modules 'org-habit t)
(setq org-habit-graph-column 80)
(setq org-habit-show-habits-only-for-today t)

Help

Keybindings

(my/leader
  "h" '(:ignore t :which-key "help")
  "hf" '(counsel-describe-function :which-key "Describe Function")
  "hc" '(helpful-command :which-key "Describe Command")
  "hv" '(counsel-describe-variable :which-key "Describe Variable")
  "hk" '(helpful-key :which-key "Describe Key")
  "hp" '(helpful-at-point :which-key "Describe at Point")
  "hw" '(which-key-toggle-docstrings :which-key "which-key"))

Helpful

(use-package helpful
  :custom
  (counsel-describe-function-function #'helpful-callable)
  (counsel-describe-variable-function #'helpful-variable)
  :bind
  ([remap describe-function] . counsel-describe-function)
  ([remap describe-command] . helpful-command)
  ([remap describe-variable] . counsel-describe-variable)
  ([remap describe-key] . helpful-key))

Git

Load Package

(use-package magit
  :commands magit-status
  :custom (magit-display-buffer-function
           #'magit-display-buffer-same-window-except-diff-v1))

Keybindings

(my/leader
  "g" '(:ignore t :which-key "Magit")
  "gc" '(magit-clone :which-key "Clone")
  "gg" '(magit-status :which-key "Status"))

Development

LSP mode

We use the excellent lsp-mode to enable IDE-like functionality for many different programming languages via “language servers” that speak the Language Server Protocol. Before trying to set up lsp-mode for a particular language, check out the documentation for your language so that you can learn which language servers are available and how to install them.

The lsp-keymap-prefix setting enables you to define a prefix for where lsp-mode’s default keybindings will be added. I highly recommend using the prefix to find out what you can do with lsp-mode in a buffer.

The which-key integration adds helpful descriptions of the various keys so you should be able to learn a lot just by pressing C-c l in a lsp-mode buffer and trying different things that you find there.

(defun efs/lsp-mode-setup ()
  (setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
  (lsp-headerline-breadcrumb-mode))

(use-package lsp-mode
  :commands (lsp lsp-deferred)
  :hook (lsp-mode . efs/lsp-mode-setup)
  :init
  (setq lsp-keymap-prefix "C-c l")  ;; Or 'C-l', 's-l'
  :config
  (lsp-enable-which-key-integration t))

lsp-ui

(use-package lsp-ui
  :hook (lsp-mode . lsp-ui-mode)
  :config
  (setq lsp-ui-sideline-enable t)
  (setq lsp-ui-sideline-show-hover nil)
  (setq lsp-ui-doc-position 'bottom)
  (lsp-ui-doc-show))

lsp-treemacs

(use-package lsp-treemacs
  :after lsp)

Emacs LSP

(add-hook 'emacs-lisp-mode-hook #'flycheck-mode)

(my/leader
  "e"   '(:ignore t :which-key "eval")
  "eb"  '(eval-buffer :which-key "eval buffer")
  "ee" '(eval-last-sexp :which-key "eval exp"))


(my/leader
  :keymaps '(visual)
  "er" '(eval-region :which-key "eval region"))
(use-package overseer
  :defer t
  :init (my/leader emacs-lisp-mode-map
          "ta" '(overseer-test :which-key "overseer-test")
          "tt" '(overseer-test-run-test :which-key "overseer-test-run-test")
          "tb" '(overseer-test-this-buffer :which-key "overseer-test-this-buffer")
          "tf" '(overseer-test-file :which-key "overseer-test-file")
          "tg" '(overseer-test-tags :which-key "overseer-test-tags")
          "tp" '(overseer-test-prompt :which-key "overseer-test-prompt")
          "tA" '(overseer-test-debug :which-key "overseer-test-debug")
          "tq" '(overseer-test-quiet :which-key "overseer-test-quiet")
          "tv" '(overseer-test-verbose :which-key "overseer-test-verbose")
          "th" '(overseer-help :which-key "overseer-help")))

Python

Prereqs

Install pyLint for flycheck

`brew install pylint`

Config

(use-package elpy
  :ensure t
  :init
  (elpy-enable))

(use-package pyvenv
  :ensure t
  :config
  (pyvenv-mode t)

  ;; Set correct Python interpreter
  (setq pyvenv-post-activate-hooks
	(list (lambda ()
		(setq python-shell-interpreter (concat pyvenv-virtual-env "bin/python3")))))
  (setq pyvenv-post-deactivate-hooks
	(list (lambda ()
		(setq python-shell-interpreter "python3")))))

(use-package py-autopep8
  :hook ((python-mode) . py-autopep8-mode)
  :hook 'elpy-mode-hook 'py-autopep8-enable-on-save)

(defun flycheck-python-setup ()
  (flycheck-mode))
(add-hook 'python-mode-hook #'flycheck-python-setup)

Docker

(use-package docker
  :ensure t
  :bind ("C-c d" . docker))

(use-package dockerfile-mode
  :ensure t
  :mode
  ("Dockerfile\\'" . dockerfile-mode)
  :config
  (setq-default docker-use-sudo nil))

Spelling

Flyspell

(use-package flyspell
  :defer t
  :diminish flyspell-mode
  :init
  (my/leader
    "ts" '(flyspell-mode :which-key  "flyspell-mode")
    "Sb" '(flyspell-buffer :which-key "flyspell-buffer")
    "Sd" '((lambda () (interactive) (find-file (expand-file-name ispell-personal-dictionary))) :which-key "dictionary" )
    "Sn" '(flyspell-goto-next-error :which-key "flyspell-goto-next-error")
    "Sp" '(flyspell-correct-at-point) :which-key "flyspell-correct-at-point)")
  (defhydra hydra-spelling ()
    ("b" flyspell-buffer "check buffer")
    ("d" ispell-change-dictionary "change dictionary")
    ("n" flyspell-goto-next-error "next")
    ("c" flyspell-correct-previous-word-generic "correct")
    ("q" nil "quit"))
  (my/leader
    "Ss" 'hydra-spelling/body)
  :config
  (add-hook 'text-mode-hook 'flyspell-mode)
  (add-hook 'prog-mode-hook 'flyspell-prog-mode)
  (add-hook 'org-mode-hook 'turn-on-flyspell)
  (add-hook 'flyspell-mode-hook 'flyspell-buffer)
  (add-to-list 'ispell-skip-region-alist '("^#+BEGIN_SRC" . "^#+END_SRC"))

  )

Flyspell w/ Ivy

(use-package flyspell-correct
  :after flyspell
  :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)))

(use-package flyspell-correct-ivy
  :after flyspell-correct)

(use-package flyspell-correct-popup
  :after flyspell-correct)

Alerts

(use-package alert
  :commands alert
  :config
  (setq alert-default-style 'notifications))

Dashboard

(use-package dashboard
  :custom (dashboard-center-content t)
  (dashboard-set-init-info t)
  (dashboard-set-file-icons t)
  (dashboard-set-heading-icons t)
  (dashboard-set-navigator t)
  (dashboard-startup-banner 'logo)
  ;;        (dashboard-projects-backend 'projectile)
  (dashboard-items '(
                     ;;(projects . 10)
                     (recents  . 10)
                     (agenda . 10)
                     ))
  :config (dashboard-setup-startup-hook))

Dired

(my/leader
  "ad" '(dired :which-key "Dired"))

Calendar

org-gcal

Set files list and tokens in the host specific file.

(use-package org-gcal
  :init
  (setq org-gcal-local-timezone "America/Chicago")
  (setq org-gcal-notify-p nil)
  (setq org-gcal-remove-api-cancelled-events t))

(my/leader
  "ac" '(org-gcal-fetch :which-key "gCal fetch"))

;;(setq plstore-cache-passphrase-for-symmetric-encryption t)

Search

(my/leader
  "sd" '(counsel-rg :which-key "rp-directory")
  "sp" '(swiper-thing-at-point :which-key "swiper at point")
  "ss" '(swiper :which-key "swiper")
  "sr" '(query-replace :which-key "replace"))

Projectile

Setup

(use-package projectile
  :diminish projectile-mode
  :config (projectile-mode)
  :custom ((projectile-completion-system 'ivy))
  :bind-keymap
  ("C-c p" . projectile-command-map)
  :init
  ;; NOTE: Set this to the folder where you keep your Git repos!
  (when (file-directory-p "~/src")
    (setq projectile-project-search-path '("~/src")))
  (setq projectile-switch-project-action #'projectile-dired))

(use-package counsel-projectile
  :after projectile
  :config (counsel-projectile-mode))

Keybindings

(my/leader
  "pf"  '(counsel-projectile-find-file :which-key "counsel-projectile-find-file")
  "ps"  '(counsel-projectile-switch-project :which-key "counsel-projectile-switch-project")
  "pF"  '(counsel-projectile-rg :which-key "counsel-projectile-rg")
  ;; "pF"  'consult-ripgrep
  "pp"  '(counsel-projectile :which-key "counsel-projectile")
  "pc"  '(projectile-compile-project :which-key "projectile-compile-project")
  "pd"  '(projectile-dired :which-key "projectile-dired")
  )

Pinentry

(setq epg-pinentry-mode 'loopback)
;;(pinentry-start)

howm

(use-package howm
  :ensure t
  :init
  ;; Where to store the files?
  (setq howm-directory "~/howm")
  (setq howm-home-directory howm-directory)
  ;; What format to use for the files?
  (setq howm-file-name-format "%Y-%m-%d-%H%M%S.org")
  (setq howm-view-title-header "*")
  (setq howm-dtime-format "<%Y-%m-%d %a %H:%M>")
  ;; Avoid conflicts with Org-mode by changing Howm's prefix from "C-c ,".
  (setq howm-prefix (kbd "C-c ;"))
  :bind*
  ;; Conveniently open the Howm menu with "C-c ; ;".
  ("C-c ; ;" . howm-menu))

(my/leader
  "ah" '(howm-menu :which-key "howm"))

Shell

(setq system-uses-terminfo nil)

(setq explicit-shell-file-name "/bin/zsh")
(setq shell-file-name "zsh")
(setq explicit-zsh-args '("--login" "--interactive"))
(defun zsh-shell-mode-setup ()
  (setq-local comint-process-echoes t))
(add-hook 'shell-mode-hook #'zsh-shell-mode-setup)

End hook

(run-hooks 'my/end-hook)

Timers

(run-with-timer 60 (* 60 60) 'recentf-save-list)
;;(run-with-timer 60 (* 60 60) 'org-gcal-sync)

References