Files
azos/home-manager/suites/base/emacs/el/azos-emacs-base.org
T

8.8 KiB

Aner's Emacs Base Configuration

Bootstrapping

Taken from this post on StackOverflow

Backups are moved to a .cache directory in order to keep them out of local dirs.

Follow symlinks

(setq
    vc-follow-symlinks t
    backup-directory-alist `(("." . "~/.cache/emacs-backups/"))
    auto-save-file-name-transforms '((".*" "~/.cache/emacs-backups/" t))
    backup-by-copying t
    delete-old-versions t
    kept-new-versions 6
    kept-old-versions 2
    version-control t
    gc-cons-threshold 100000000 ;Setting garbage collection to 100M.
)

Make sure CL is loaded

CL is a base library that has a bunch of useful stuff, primarily for lists. We are using the built-in version, no need to pull from anywhere. This just makes sure the code is loaded early on for later use.

(require 'cl-lib)

Keymap setup

In this section global keybindings are defined using a global minor mode.

First, utility functions that will be bound are defined.

The first, azos/set-window-width is a helper function that resizes a window. Used because I wanted a function that resizes a window to 85 cols easily.

The second, azos/open-conf-file, opens the configuration file.

(defun azos/set-window-width (n)
    (adjust-window-trailing-edge (selected-window) ( - n (window-width)) t))

(defun azos/open-conf-file ()
    (interactive)
    (find-file (concat user-emacs-directory "config.org")))

Now let's define keybindings. To start, we'd like M-o to be available to us, so let's unbind it.

;Unbind face menu map
(define-key global-map (kbd "M-o") nil)

This creates an "open keymap", a bunch of keybindings we'll use to open basic applications and files. This will be mapped to M-o, and things will be opened form this sub-menu. We'll start it with a binding to open the conf file with M-o o (MOO!)

Setting of keybindings based on this

;We'll define a basic keymap and already load window-manip funcs
(defvar azos/global-minor-mode/open-keymap
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "o") 'azos/open-conf-file)
    map)
  "global keymap for opening stuff on azos")

At this stage a minor-mode-map is defined with keybindings, and an accompanying minor-mode is added.

(defvar azos/global-minor-mode/keymap
  (let ((map (make-sparse-keymap)))

    ;Window movement and manipulation
    (define-key map (kbd "M-h") 'windmove-left)
    (define-key map (kbd "M-l") 'windmove-right)
    (define-key map (kbd "M-k") 'windmove-up)
    (define-key map (kbd "M-j") 'windmove-down)

    (define-key map (kbd "M-<left>") 'windmove-left)
    (define-key map (kbd "M-<right>") 'windmove-right)
    (define-key map (kbd "M-<up>") 'windmove-up)
    (define-key map (kbd "M-<down>") 'windmove-down)
    (define-key map (kbd "M-d M-d") 'delete-window)
    (define-key map (kbd "M-d D") 'kill-buffer-and-window)
    (define-key map (kbd "M-\\") 'split-window-horizontally)
    (define-key map (kbd "M-\-") 'split-window-vertically)
    (define-key map (kbd "M-d R") (lambda () (interactive)
                    (set-window-width 85)))
    (define-key map (kbd "M-o") azos/global-minor-mode/open-keymap)
    map)
  "azos/global-minor-mode keymap.")

(define-minor-mode azos/global-minor-mode
  "A minor mode for azos global keymaps."
  :init-value t
  :lighter "azos"
  :keymap azos/global-minor-mode/keymap)

(azos/global-minor-mode 1)

This keymap will be referenced many times during this document at relevant points.

Keymaps are included with relevant sections.

EVIL mode

Using evil mode.

This section includes unbinding C-w (I honestly forget why).

This section binds keys for changing window size. Done here because can only do after evil loads.

Unbinding C-w taken from https://stackoverflow.com/questions/24988406/unbinding-evils-c-w-mappings

(setq evil-want-keybinding nil)

(use-package evil
  :init
  (setq evil-want-C-i-jump nil)
  :config
  (require 'evil )
  (evil-mode 1)

  :bind
  (:map azos/global-minor-mode/keymap
        ("M-w h" . evil-window-decreace-width)
        ("M-w l" . evil-window-increase-width)
        ("M-w k" . evil-window-decrease-height)
        ("M-w j" . evil-window-increase-height))
)

Loading evil collection. Functions from this package will be referenced many times later in the configuration.

(use-package evil-collection
  :config
  (setq evil-collection-setup-minibuffer t)
)

Setting theme colors

(defvar azos/evil-color-normal "LightGoldenrod1")
(defvar azos/evil-color-emacs "LightBlue1")
(defvar azos/evil-color-insert "PaleGreen1")
(defvar azos/evil-color-replace "LightPink")
(defvar azos/evil-color-motion "LightCyan")
(defvar azos/evil-color-visual "LightGray")
(defvar azos/evil-color-operate "sandy brown")

Undo tree

Loading undo-tree for undo/redo functionality with evil.

Redo taken from https://github.com/syl20bnr/spacemacs/issues/14036

(use-package undo-tree
  :after evil
  :config
    (evil-set-undo-system 'undo-tree)
    (setq undo-tree-history-directory-alist
        (list (cons "." (concat user-emacs-directory "undo-tree"))))
    (global-undo-tree-mode 1)
)

IVY

Enabling IVY. Taken from their website.

Using ivy, hydra, counsel.

(use-package ivy
  :custom
    (ivy-use-virtual-buffers t)
    (enable-recursive-minibuffers t)
    (ivy-count-format "(%d/%d) ")
  :config
    (ivy-mode 1)
)

(use-package ivy-hydra
  :after ivy)
(use-package ivy-avy
  :after ivy)
(use-package counsel
  :after ivy

  :bind
    (:map azos/global-minor-mode/keymap
        ("M-i" . counsel-imenu)
        ("M-b" . counsel-switch-buffer)
        ("C-x C-f" . counsel-find-file))
    (:map azos/global-minor-mode/open-keymap
        ("l" . counsel-linux-app))
)

Using swiper. Replacing evil search with swiper search.

(use-package swiper
    :after ivy evil
    :config
    (setq evil-search-module 'swiper-isearch)

    :bind
    (:map azos/global-minor-mode/keymap
        ("C-s" . swiper-isearch))
)

Setting up keymaps

(evil-collection-ivy-setup)

Projectile

Startup up projectile.

A config line here disables modeline display because I don't want my modeline to be cluttered.

Mapping modeline commands to M-p prefix. Also adding a shortcut to add project.

(use-package projectile
  :config
    (projectile-mode +1)
    (setq projectile-mode-line-function (lambda () ""))
  :bind
    (:map projectile-command-map
          ("a" . projectile-add-known-project)
    )
    (:map azos/global-minor-mode/keymap
          ("M-p" . projectile-command-map))
)

Ivy for projectile: Parts taken from this post and this post from StackOverflow.

Helps with many functions to use counsel's/ivy's autocomplete with projectile.

(use-package counsel-projectile
  :after counsel projectile
  :config
    (counsel-projectile-mode +1)
    (setq projectile-completion-system 'ivy)
    ;Making counsel start with empty regex
    (when (commandp 'counsel-M-x)
        (global-set-key [remap execute-extended-command] 'counsel-M-x))
    (setcdr (assoc 'counsel-M-x ivy-initial-inputs-alist) "")
)

Tramp

Ensuring tramp is loaded, and loading counsel-tramp for easy tramping.

(use-package tramp
  :straight (:type built-in))

(use-package counsel-tramp)

Assorted utility functions

Defining a function to copy filename.

(defun azos/copy-file-name () (interactive)
       (let ((fpath buffer-file-name))
         (if fpath (kill-new fpath) (message "No current file!"))))

Need to define this here so that other parts of code have access to it

(defun azos/font-candidate (&rest fonts)
    "Return existing font which first match."
    (cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts))
(defun azos/re-seq (regexp string)
  "Get a list of all regexp matches in a string"
  (save-match-data
    (let ((pos 0)
          matches)
      (while (string-match regexp string pos)
        (push (match-string 0 string) matches)
        (setq pos (match-end 0)))
      matches)))

Tie it up

(provide 'azos-emacs-base)