39 KiB
Aner's Emacs Base Configuration
Base setup
Bootstrapping
(setq
vc-follow-symlinks t ;Follow symlinks
;Backups from https://www.emacswiki.org/emacs/BackupDirectory
backup-directory-alist `(("." . temporary-file-directory))
auto-save-file-name-transforms '((".*" temporary-file-directory t))
backup-by-copying t ;Always copy never link
delete-old-versions t ;Auto delete old backups
kept-new-versions 6 ;Number of versions to keep
kept-old-versions 2
version-control t ;Backups for files
;Garbage collection
gc-cons-threshold 100000000
;Set external cusotm file
custom-file (expand-file-name "custom.el" user-emacs-directory)
)
Load custom file
(if (file-exists-p custom-file) (load custom-file))
Utility functions
CL
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)
Copy file name
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!"))))
Font candidate
(defun azos/font-candidate (&rest fonts)
"Return existing font which first match."
(cl-find-if (lambda (f) (find-font (font-spec :name f))) fonts))
Regex match function
(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)))
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
This section binds keys for changing window size. Done here because can only do after evil loads.
(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)
)
(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")
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)
Assorted utility functions
UI
General
Clean UI
Disabling the toolbar, the splash-screen, the menu-bar and the scroll-bar
(menu-bar-mode -1) ; no menu bar
(when (display-graphic-p)
(tool-bar-mode -1) ; no tool bar with icons
(scroll-bar-mode -1) ; no scroll bars
(set-fringe-mode 0))
Background color
(add-to-list 'default-frame-alist '(background-color . "LightYellow"))
Fringe color
While we don't actually want fringes (almost at all), some frames use them.
;; (set-face-attribute 'fringe nil :background "LemonChiffon1")
Window dividers
(setq window-divider-default-bottom-width 1
window-divider-default-places 'bottom-only)
(window-divider-mode 1)
Tab bar
Base
Prettification of tab bar. We only use tab-bar if the version is greater than 27.1. We also use this section to bind keys.
;; If version greater than 27.1
(defun azos/new-tab-and-rename ()
"Created for back compatibility with emacs 27"
(interactive)
(progn
(tab-bar-new-tab)
(call-interactively 'tab-bar-rename-tab)))
(if (version<= "27.1" emacs-version) (progn
(tab-bar-mode 1)
(set-face-attribute 'tab-bar nil
:box t
:background "LightYellow3"
:foreground "DarkSlateGrey"
:font "LiberationMono"
:height 90)
(set-face-attribute 'tab-bar-tab nil
:box '(:color "DarkSlateGrey" :line-width -2)
:background "LightYellow3"
:weight 'bold)
(set-face-attribute 'tab-bar-tab-inactive nil
:background "LightYellow3"
:inherit 'tab-bar)
(define-key azos/global-minor-mode/keymap
(kbd "M-<tab>") 'tab-next)
(define-key azos/global-minor-mode/keymap
(kbd "M-'") 'tab-previous)
(define-key azos/global-minor-mode/keymap
(kbd "M-t r") 'tab-bar-rename-tab)
(define-key azos/global-minor-mode/keymap
(kbd "M-t n") 'tab-next)
(define-key azos/global-minor-mode/keymap
(kbd "M-t p") 'tab-previous)
(define-key azos/global-minor-mode/keymap
(kbd "M-t x") 'tab-bar-close-tab)
(define-key azos/global-minor-mode/keymap
(kbd "M-t c") 'azos/new-tab-and-rename)
(setq tab-bar-close-button-show nil
tab-bar-new-button-show nil
tab-bar-separator (propertize " ● " 'face
(list :foreground "LightYellow1"
:box '(:color "DarkSlateGrey")))
)
(add-hook 'emacs-startup-hook (lambda () (tab-bar-rename-tab "home" 1)))
))
Right Group Display
(defvar azos/tab-bar/right-update-group '()
"Functions needed to run to update tab bar")
(defvar azos/tab-bar/right-group '()
"A list of items to be displayed on the right of the tab-bar")
(defun azos/tab-bar/right-group-func ()
"Function that returns a string to be displayed on right of tab-bar"
(concat
tab-bar-separator
(mapconcat 'eval
(remove ""
(mapcar 'funcall azos/tab-bar/right-group))
tab-bar-separator)
tab-bar-separator))
(defun azos/tab-bar/update-func () "Function to update the tab bar"
(progn
(mapc 'funcall azos/tab-bar/right-update-group)
(force-mode-line-update)))
(if (version<= "28.1" emacs-version) (progn
(setq tab-bar-format
'(
tab-bar-format-history
tab-bar-format-tabs
tab-bar-separator
tab-bar-format-add-tab
tab-bar-format-align-right
azos/tab-bar/right-group-func)
tab-bar-auto-width nil)
(define-key azos/global-minor-mode/keymap
(kbd "M-n") 'tab-switch)
;; (if (member system-type '(gnu gnu/linux))
;; (azos/run-timer 'tab-timer 'azos/tab-bar/update-func 5))
;; No auto-update, maybe some other way
))
Let's define a clock for the tab bar
(defun azos/tab-bar/get-clock-string () "Get tab bar time string"
(propertize (format-time-string "%a, %b %d %H:%M")
'face '(:background "LightYellow3" :foreground "DarkSlateGrey")))
(defun azos/tab-bar/enable-clock-display ()
"Enables clock display in tab bar"
(cl-pushnew 'azos/tab-bar/get-clock-string
azos/tab-bar/right-group))
By default let's enable the clock display
(azos/tab-bar/enable-clock-display)
Tab bar addons
Battery status in tab bar
(defun azos/bat/get-stats () "Gets battery statistics. First value returned
is battery percentage, second one is t if charging"
(let* ((commandout (string-clean-whitespace (shell-command-to-string
"upower -i /org/freedesktop/UPower/devices/DisplayDevice"))))
(list
(string-to-number (progn
(string-match "\\(?:percentage\\:\s+\\)\\([0-9]+\\)" commandout)
(match-string 1 commandout)))
(progn
(string-match "\\(?:state\\:\s+\\)\\([^\s]+\\)" commandout)
(match-string 1 commandout)))
))
(defvar azos/bat/status-string nil "Holds battery string")
(defun azos/bat/set-status-string () "Sets battery-string"
(let* ((bat-stats (azos/bat/get-stats))
(bat-charge-state (nth 1 bat-stats))
(bat-percentage-number
(if (string= bat-charge-state "fully-charged") 100
(nth 0 bat-stats)))
(bat-color (if (<= bat-percentage-number 10) "red3"
(if (<= bat-percentage-number 20) "DarkOrange"
"DarkSlateGrey")))
(bat-weight (if (<= bat-percentage-number 20) 'bold 'normal))
(bat-charge-symbol (if (string= bat-charge-state "charging") "↑"
(if (string= bat-charge-state "fully-charged") "◼" "↓"))))
(setq azos/bat/status-string
(concat
"⚡" bat-charge-symbol " "
(propertize (format "%3d" bat-percentage-number)
'face (list :foreground bat-color
:box (list :color "DarkSlateGrey")))))))
(defun azos/bat/get-status-string () "Get battery string"
(if azos/bat/status-string azos/bat/status-string ""))
(defun azos/bat/enable-tab-display ()
"Enables battery display in tab bar"
(progn
(cl-pushnew 'azos/bat/get-status-string azos/tab-bar/right-group)
(cl-pushnew 'azos/bat/set-status-string azos/tab-bar/right-update-group)
))
Network status in tab bar
Code to check for internet connection:
https://emacs.stackexchange.com/questions/7653/elisp-code-to-check-for-internet-connection
(defvar azos/network/status-string nil "Holds network status string")
(defun azos/network/get-status-string () "Gets the network status string"
(if azos/network/status-string azos/network/status-string ""))
(defun azos/network/set-status-string-sentinel (process event)
"Sets the network string based on proc run"
(setq azos/network/status-string
(concat
"↹ "
(if (= 0 (process-exit-status process))
(propertize "✓" 'face
(list :foreground "green3"
:background "LightYellow3"
:box (list :color "DarkSlateGrey")))
(propertize "X" 'face
(list :foreground "red3"
:background "LightYellow3"
:box (list :color "DarkSlateGrey")))))))
(defun azos/network/start-test-proc () "Tests whether internet"
(interactive)
(set-process-sentinel
(start-process "wget" nil "wget" "--spider" "--timeout=1"
"www.google.com") 'azos/network/set-status-string-sentinel))
(defun azos/network/enable-tab-display ()
"Enables network display in tab bar"
(progn
(cl-pushnew 'azos/network/get-status-string
azos/tab-bar/right-group)
(cl-pushnew 'azos/network/start-test-proc
azos/tab-bar/right-update-group)
))
Easy Prompt
(defalias 'yes-or-no-p 'y-or-n-p)
Minibuff
(add-hook 'minibuffer-setup-hook
(lambda ()
(make-local-variable 'face-remapping-alist)
(add-to-list 'face-remapping-alist
'(default (:background "WhiteSmoke")))))
Bell
Disable bell, who needs the bell?
(setq ring-bell-function (lambda () ()))
Olivetti
Useful to have even if I rarely use it.
(use-package olivetti
:init
(setq olivetti-body-width 96))
Modeline
Setting colors
(set-face-attribute 'mode-line nil :box nil :background "AliceBlue")
(set-face-attribute 'mode-line-inactive nil :box nil :background "LightYellow3")
We use this stackoverflow page to make left\right aligned stuff.
We use this article to try and limit the mode name length.
(setq evil-normal-state-tag
(propertize " NORMAL " 'face
(list :background azos/evil-color-normal))
evil-emacs-state-tag
(propertize " EMACS " 'face
(list :background azos/evil-color-emacs))
evil-insert-state-tag
(propertize " INSERT " 'face
(list :background azos/evil-color-insert))
evil-replace-state-tag
(propertize " REPLACE " 'face
(list :background azos/evil-color-replace))
evil-motion-state-tag
(propertize " MOTION " 'face
(list :background azos/evil-color-motion))
evil-visual-state-tag
(propertize " VISUAL " 'face
(list :background azos/evil-color-visual))
evil-operator-state-tag
(propertize " OPERATE " 'face
(list :background azos/evil-color-operate)))
(defun azos/modeline/modeline-render (left right)
"Return a string of `window-width' length containing LEFT, and RIGHT
aligned respectively."
(let* ((available-width (- (window-width) (length left) 2)))
(format (format " %%s %%%ds " available-width) left right)))
(setq-default mode-line-buffer-identification
(list -80 (propertized-buffer-identification "%12b")))
(setq-default mode-line-format
'((:eval (azos/modeline/modeline-render
;;Left
(concat
(propertize (format-mode-line "%b") 'face '((:foreground "maroon")))
(format-mode-line " (%m) "))
;;Right
(concat
(format-mode-line "%5lL%4cC ")
evil-mode-line-tag)))))
Notifications
(require 'notifications)
Which-Key
(use-package which-key
:config
(which-key-mode))
Text
YASnippet
Loading yasnippet. Useful for snippeting. Mode-specific snippets defined in relevant sections.
(use-package yasnippet
:config
(yas-global-mode 1)
)
Text font
This section configures the base fonts. We select fonts if available (have configurations for good defaults in Linux and Windows).
Also setting default fixed-pitch and variable-pitch fonts.
Setting font size to 10. The value to place is font-size * 10
Font size 12 for variable pitch.
The function font-candidate is from https://www.gnu.org/software/emacs/manual/html_mono/cl.html.
(let ((variable-font (azos/font-candidate
"Liberation Serif" "Microsoft Sans Serif")))
(if variable-font
(set-face-attribute 'variable-pitch nil :font variable-font)))
(let ((fixed-font (azos/font-candidate
"Source Code Pro" "LiberationMono" "Consolas")))
(if fixed-font (progn
(set-face-attribute 'default nil :font fixed-font)
(set-face-attribute 'fixed-pitch nil :font fixed-font))))
(set-face-attribute 'default nil :height 100)
(set-face-attribute 'variable-pitch nil
:height 130
:weight 'normal
:width 'normal)
(set-face-attribute 'fixed-pitch nil
:height 100
:weight 'normal
:width 'normal)
(defun azos/default-variable-pitch ()
(face-remap-add-relative 'default '(:inherit 'variable-pitch)))
Line numbering
We want line numbering, but only in modes where it makes sense.
To do this, a custom minor-mode, azos/global-linum-mode, is created.
This mode selectively activates linum-mode if the mode is not one of a selected exempt modes.
These exempt modes are defined in display-line-numbers-exempt-modes.
Taken from this wiki entry.
(use-package display-line-numbers
:init
(defcustom azos/display-line-numbers-exempt-modes
'(vterm-mode
eshell-mode
shell-mode
term-mode
ansi-term-mode
magit-mode
magit-diff-mode
notmuch-hello
pdf-view-mode)
"Major modes on which to disable the linum mode, exempts them."
:group 'display-line-numbers
:type 'list
:version "green")
(define-global-minor-mode azos/global-linum-mode
display-line-numbers-mode
(lambda () (if (and
(not (apply 'derived-mode-p
azos/display-line-numbers-exempt-modes))
(not (minibufferp)))
(display-line-numbers-mode))))
(setq display-line-numbers-type 'visual
display-line-numbers-grow-only 1
display-line-numbers-width-start 1)
:config
(azos/global-linum-mode 1)
(set-face-attribute 'line-number nil
:family (face-attribute 'fixed-pitch :family))
)
Line highlight
Highlighting line with cursor.
Modification done to use EVIL colors on highlighted line.
(global-hl-line-mode)
(set-face-attribute 'hl-line nil :background azos/evil-color-emacs)
(defface hl-line-normal
(list (list t (list :inherit 'hl-line :background azos/evil-color-normal
:extend t)))
"Highlight face for evil normal mode."
:group 'hl-line)
(defface hl-line-insert
(list (list t (list :inherit 'hl-line :background azos/evil-color-insert
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defface hl-line-emacs
(list (list t (list :inherit 'hl-line :background azos/evil-color-emacs
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defface hl-line-replace
(list (list t (list :inherit 'hl-line :background azos/evil-color-replace
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defface hl-line-motion
(list (list t (list :inherit 'hl-line :background azos/evil-color-motion
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defface hl-line-visual
(list (list t (list :inherit 'hl-line :background azos/evil-color-visual
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defface hl-line-operate
(list (list t (list :inherit 'hl-line :background azos/evil-color-operate
:extend t)))
"Highlight face for evil insert mode."
:group 'hl-line)
(defun azos/hl-line-evil/set-hl-state (state-face)
"Refresh hl-line to be state-face"
(progn
(global-hl-line-unhighlight)
(setq-local hl-line-face state-face)
(global-hl-line-highlight)))
(add-hook 'evil-insert-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-insert)))
(add-hook 'evil-normal-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-normal)))
(add-hook 'evil-emacs-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-emacs)))
(add-hook 'evil-replace-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-replace)))
(add-hook 'evil-motion-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-motion)))
(add-hook 'evil-visual-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-visual)))
(add-hook 'evil-operate-state-entry-hook
(lambda () (azos/hl-line-evil/set-hl-state 'hl-line-operate)))
Line wrap
Don't want to have to scroll to see more chars.
(global-visual-line-mode t)
Parenthesis
Highlight matching parenthesis
(show-paren-mode 1)
Tabs
Using spaces instead of tabs, default offset is 4.
(setq-default indent-tabs-mode nil
tab-width 4
c-basic-offset 4
tab-always-indent 'complete)
BIDI and lang
Setting up Hebrew as alternative input, using bidi mode so that every line is aligned left\right accordingly.
(setq-default default-input-method "hebrew"
bidi-display-reordering t
bidi-paragraph-direction 'nil)
(defun azos/set-bidi-env ()
(setq bidi-paragraph-direction 'nil)
)
(define-key azos/global-minor-mode/keymap
(kbd "C-SPC") 'toggle-input-method)
Whitespace mode
We define a custom global-whitespace-mode in order to enable it only on relevant modes.
We check if the current mode doesn't derive from a set of blacklisted mode, the main culprit being terminal modes where whitespace occur naturally and are a pain to see all the time.
(setq-default whitespace-style
'(face tabs trailing tab-mark
lines-tail indentation))
(defun azos/whitespace-mode-func ()
(interactive)
(if (derived-mode-p 'text-mode 'prog-mode 'org-mode)
(whitespace-mode 1) (whitespace-mode -1)))
(add-hook 'after-change-major-mode-hook 'azos/whitespace-mode-func)
Commenter
Quick keybindings to comment out regions.
(use-package evil-nerd-commenter
:config
(define-key evil-normal-state-map (kbd "C-;")
'evilnc-comment-or-uncomment-lines))
Company mode
Auto completion framework.
(use-package company
:ensure t
:defer t
:init (add-hook 'after-init-hook 'global-company-mode)
:config
;; (use-package company-irony :ensure t :defer t)
(setq
company-minimum-prefix-length 2
company-show-numbers t
company-tooltip-limit 20
company-idle-delay 0.2
)
:bind ("C-;" . company-complete-common)
;; :hook (irony-mode . company-mode)
)
Folding
(add-hook 'prog-mode-hook 'hs-minor-mode)
Mode specific
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)
)
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)
Dired
Need to autoload dired-x for dired-omit
;; (autoload 'dired-omit-mode "dired-x")
(setq dired-omit-files "^\\...+$")
(add-hook 'dired-mode-hook 'dired-omit-mode)
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
(evil-collection-dired-setup)
(use-package dired-subtree
:config
(evil-collection-define-key 'normal 'dired-mode-map
(kbd "SPC") 'dired-subtree-toggle
(kbd "TAB") 'dired-subtree-cycle
)
(setq dired-subtree-use-backgrounds nil)
;Evil collection binds these keys, we need them for window movement
(evil-collection-define-key 'normal 'dired-mode-map
(kbd "M-j") nil
(kbd "M-k") nil)
)
Magit
(use-package magit
:config
(evil-collection-magit-setup)
:bind
(:map azos/global-minor-mode/open-keymap
("g" . 'magit-status))
)
Org
Base
(require 'org-faces)
(defun azos/set-org-mode-fixed-pitch-faces ()
(mapc (lambda (face) (set-face-attribute face nil
:font (face-attribute 'fixed-pitch :font)
:height (face-attribute 'fixed-pitch :height)))
`(line-number
org-block
org-special-keyword
org-drawer
org-todo
org-done
org-priority
org-checkbox
org-block-end-line
org-block-begin-line
org-table
org-verbatim)))
(use-package org
:hook
(org-mode . variable-pitch-mode)
(org-mode . azos/set-bidi-env)
(org-mode . (lambda ()
(setq-local whitespace-style '(face tabs trailing tab-mark
indentation))))
:config
(azos/set-org-mode-fixed-pitch-faces)
(setq org-src-tab-acts-natively t
org-adapt-indentation nil
org-startup-folded t
org-hide-emphasis-markers t)
(set-face-attribute 'org-code nil
:family (face-attribute 'fixed-pitch :family))
(set-face-attribute 'org-block nil
:family (face-attribute 'fixed-pitch :family))
:bind
("C-a" . nil)
("C-a l" . org-toggle-latex-fragment)
)
#+end_src
Code blocks
The following displays the contents of code blocks in Org-mode files using the major-mode of the code. It also changes the behavior of TAB to as if it were used in the appropriate major mode.
(setq org-src-fontify-natively t
org-src-tab-acts-natively t
org-src-preserve-indentation t)
(set-face-attribute 'org-block nil
:background "LemonChiffon1")
(set-face-attribute 'org-block-begin-line nil
:background "LightYellow2")
(set-face-attribute 'org-block-end-line nil
:background "LightYellow2")
Babel
Define languages to use
(require 'ob)
(require 'ob-tangle)
;; TODO Not sure I like this here
(org-babel-do-load-languages
'org-babel-load-languages
'((shell . t)
(emacs-lisp . t)
(python . t)
(org . t)
(lilypond . t)
(latex . t)
(js . t)
(java . t)
(dot . t)
(C . t)))
;; TODO move these around
;; (add-to-list 'org-src-lang-modes (quote ("dot". graphviz-dot)))
;; (add-to-list 'org-src-lang-modes (quote ("plantuml" . fundamental)))
;; (add-to-list 'org-babel-tangle-lang-exts '("clojure" . "clj"))
This section makes code-indentation correction work inside source blocks. Taken from: https://github.com/emacs-evil/evil/issues/1288
(defun azos/org/evil-org-insert-state-in-edit-buffer (fun &rest args)
"Bind `evil-default-state' to `insert' before calling FUN with ARGS."
(let ((evil-default-state 'insert)
;; Force insert state
evil-emacs-state-modes
evil-normal-state-modes
evil-motion-state-modes
evil-visual-state-modes
evil-operator-state-modes
evil-replace-state-modes)
(apply fun args)
(evil-refresh-cursor)))
(advice-add 'org-babel-do-key-sequence-in-edit-buffer
:around #'azos/org/evil-org-insert-state-in-edit-buffer)
Fonts
Fonts
;; (set-face-attribute 'org-document-title nil :height 200 :underline t)
Inline images
(setq org-startup-with-inline-images t)
(defun azos/org/shk-fix-inline-images ()
(when org-inline-image-overlays
(org-redisplay-inline-images)))
(with-eval-after-load 'org
(add-hook 'org-babel-after-execute-hook 'azos/org/shk-fix-inline-images))
Snippets
Want to create snippets for latex insertion. There is one template for inline and one template for standalone latex snippets. Each template is defind by two templates. One for other langauges and one for standard input. This is done to toggle back to the original language once done with the function toggle-input-method.
(defun azos/org/toggle-input-method ()
(if current-input-method (toggle-input-method))
)
;Inline
(add-hook 'org-mode-hook (lambda () (progn
(yas-define-snippets 'org-mode (list (list
nil
"\$$1\$$0"
"ORG_LATEX_INLINE_SNIPPET_ENG"
'(not (eval current-input-method))
nil
nil
nil
"C-l"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
"\$$1\$$0"
"ORG_LATEX_INLINE_SNIPPET_OTHER_LANG"
'(eval current-input-method)
nil
'((unused (azos/org/toggle-input-method))
(yas-after-exit-snippet-hook 'toggle-input-method))
nil
"C-l"
nil
nil
)))
;Not inline
(yas-define-snippets 'org-mode (list (list
nil
"\$\$$1\$\$$0"
"ORG_LATEX_OUTLINE_SNIPPET_ENG"
'(not (eval current-input-method))
nil
nil
nil
"C-S-l"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
"\$\$$1\$\$$0"
"ORG_LATEX_OUTLINE_SNIPPET_OTHER_LANG"
'(eval current-input-method)
nil
'((unused (azos/org/toggle-input-method))
(yas-after-exit-snippet-hook 'toggle-input-method))
nil
"C-S-l"
nil
nil
)))
)))
Snippet for src blocks
(add-hook 'org-mode-hook (lambda () (progn
(yas-define-snippets 'org-mode (list (list
nil
"#+begin_src $1\n$0\n#+end_src"
"ORG_SRC_BLOCK"
nil
nil
nil
nil
"C-c i b"
nil
nil
)))
(yas-define-snippets 'org-mode (list (list
nil
(concat
"#+begin_export latex\n"
"\\begin{english}\n"
"#+end_export\n"
"#+begin_src $1\n"
"$0\n#+end_src\n"
"#+begin_export latex\n"
"\\end{english}\n"
"#+end_export")
"ORG_SRC_ENGLISH_BLOCK"
nil
nil
nil
nil
"C-c i B"
nil
nil
)))
)))
Imenu quirks
(add-to-list 'org-show-context-detail '(isearch . tree))
(add-to-list 'org-show-context-detail '(default . tree))
Ibuffer
(evil-collection-ibuffer-setup)
(define-key azos/global-minor-mode/keymap
(kbd "C-x C-b") 'ibuffer)
Dashboard
(setq inhibit-startup-screen t)
(use-package dashboard
:config
(add-hook 'after-init-hook
(lambda () (dashboard-insert-startupify-lists)))
(add-hook 'emacs-startup-hook (lambda ()
(switch-to-buffer dashboard-buffer-name)
(goto-char (point-min))
(redisplay)
(run-hooks 'dashboard-after-initialize-hook)))
(add-to-list 'evil-emacs-state-modes 'dashboard-mode)
(setq dashboard-items '((recents . 5)
(bookmarks . 5)
(projects . 5))
dashboard-center-content t
dashboard-banner-logo-title nil
dashboard-set-init-info nil
dashboard-set-footer nil
dashboard-startup-banner 'ascii
dashboard-banner-ascii "azos"))
VTerm
;; (use-package xterm-color :ensure t)
;; (use-package eterm-256color :ensure t
;; :config
;; (add-hook 'term-mode-hook #'eterm-256color-mode)
;; (add-hook 'vterm-mode-hook #'eterm-256color-mode)
;; )
(use-package vterm
:if (member system-type '(gnu gnu/linux))
:config
(add-hook 'vterm-mode-hook
(lambda () (setq-local global-hl-line-mode nil)))
(evil-collection-define-key 'normal 'vterm-mode-map
(kbd "p") 'vterm-yank)
(setq vterm-timer-delay 0.01
vterm-term-environment-variable "xterm-256color"))
Boomkark
(use-package bookmark
:straight
(:type built-in)
:config
(evil-collection-bookmark-setup)
)
Provide
(provide 'azos-emacs-base)
(add-hook 'after-init-hook (lambda () (require 'azos-emacs-base)))