Emacs.org 18 KB

Internals

Store custom variables in separate file

This config inspired by SystemCrafters' crafted-emacs This code simply defines path of file with contains custsom-set-variables and loads it.

(setq custom-file (concat user-emacs-directory "custom.el")) (when (file-exists-p custom-file) (load custom-file))

Ui customization

(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 0) ; Disable fringes (menu-bar-mode -1) ; Disagel menubar

(setq visual-bell t)

(column-number-mode)

(setq display-line-numbers-type 'relative) ;; Display relative line numbers (add-hook 'prog-mode-hook #'display-line-numbers-mode) ;; Enable line numbers only when programming

Font

(defvar my/default-font "JetBrains Mono") (defvar my/default-font-size 130) (defvar my/default-variable-font-size 130)

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

Package.el initialization

Using package.el instead of straight because I just want to install packages.

(require 'package) (when (version< emacs-version "28") (add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/"))) (add-to-list 'package-archives '("stable" . "https://stable.melpa.org/packages/")) (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))

(customize-set-variable 'package-archive-priorities '(("gnu" . 99) ; prefer GNU packages ("nongnu" . 80) ; use non-gnu packages if ; not found in GNU elpa ("stable" . 70) ; prefer "released" versions ; from elpa ("melpa" . 0))) ; if all else fails, get it ; from melpa (package-initialize)

Frame opacity

Set frame opacity and ability to toggle it. Borrowed from EmacsWiki.

(defun toggle-transparency () (interactive) (let ((alpha (frame-parameter nil 'alpha))) (set-frame-parameter nil 'alpha (if (eql (cond ((numberp alpha) alpha) ((numberp (cdr alpha)) (cdr alpha)) ;; Also handle undocumented ( ) form. ((numberp (cadr alpha)) (cadr alpha))) 100) '(85 . 50) '(100 . 100))))) (global-set-key (kbd "C-c t") 'toggle-transparency)

Create directories automatically on file save

(defadvice find-file (before make-directory-maybe (filename &optional wildcards) activate) "Create parent directory if not exists while visiting file." (unless (file-exists-p filename) (let ((dir (file-name-directory filename))) (unless (file-exists-p dir) (make-directory dir t)))))

Do not leave autosave & backup files

Change autosave file directory

(defvar auto-save-directory (expand-file-name "autosaves/" user-emacs-directory)) (when (not (file-exists-p auto-save-directory)) (make-directory auto-save-directory)) (setq auto-save-file-name-transforms `((".*" ,auto-save-directory t)))

Multiple languages

(set-language-environment 'Russian)

Move around windows

Windmove config is described in wiki.

(global-set-key (kbd "C-c w h") 'windmove-left) (global-set-key (kbd "C-c w l") 'windmove-right) (global-set-key (kbd "C-c w k") 'windmove-up) (global-set-key (kbd "C-c w j") 'windmove-down)

Package

Use-package

Use-package helps simplify .emacs file

;; No need to put :ensure t (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t)

Elpa keyring updated

Import gpg keys from elpa to avoid bad signatures

(use-package gnu-elpa-keyring-update)

Meow (Modal editing)

Meow keymap

Meow brings to emacs new way of modal editing similar to Kakoune's Define meow keymap for qwerty layout

(defun meow-setup () (setq meow-cheatsheet-layout meow-cheatsheet-layout-qwerty) (meow-motion-overwrite-define-key '("j" . meow-next) '("k" . meow-prev) '("" . ignore)) (meow-leader-define-key ;; SPC j/k will run the original command in MOTION state. '("j" . "H-j") '("k" . "H-k") ;; Use SPC (0-9) for digit arguments. '("1" . meow-digit-argument) '("2" . meow-digit-argument) '("3" . meow-digit-argument) '("4" . meow-digit-argument) '("5" . meow-digit-argument) '("6" . meow-digit-argument) '("7" . meow-digit-argument) '("8" . meow-digit-argument) '("9" . meow-digit-argument) '("0" . meow-digit-argument) '("/" . meow-keypad-describe-key) '("?" . meow-cheatsheet)) (meow-normal-define-key '("0" . meow-expand-0) '("9" . meow-expand-9) '("8" . meow-expand-8) '("7" . meow-expand-7) '("6" . meow-expand-6) '("5" . meow-expand-5) '("4" . meow-expand-4) '("3" . meow-expand-3) '("2" . meow-expand-2) '("1" . meow-expand-1) '("-" . negative-argument) '(";" . meow-reverse) '("," . meow-inner-of-thing) '("." . meow-bounds-of-thing) '("[" . meow-beginning-of-thing) '("]" . meow-end-of-thing) '("a" . meow-append) '("A" . meow-open-below) '("b" . meow-back-word) '("B" . meow-back-symbol) '("c" . meow-change) '("d" . meow-delete) '("D" . meow-backward-delete) '("e" . meow-next-word) '("E" . meow-next-symbol) '("f" . meow-find) '("g" . meow-cancel-selection) '("G" . meow-grab) '("h" . meow-left) '("H" . meow-left-expand) '("i" . meow-insert) '("I" . meow-open-above) '("j" . meow-next) '("J" . meow-next-expand) '("k" . meow-prev) '("K" . meow-prev-expand) '("l" . meow-right) '("L" . meow-right-expand) '("m" . meow-join) '("n" . meow-search) '("o" . meow-block) '("O" . meow-to-block) '("p" . meow-yank) '("q" . meow-quit) '("Q" . meow-goto-line) '("r" . meow-replace) '("R" . meow-swap-grab) '("s" . meow-kill) '("t" . meow-till) '("u" . meow-undo) '("U" . meow-undo-in-selection) '("v" . meow-visit) '("w" . meow-mark-word) '("W" . meow-mark-symbol) '("x" . meow-line) '("X" . meow-goto-line) '("y" . meow-save) '("Y" . meow-sync-grab) '("z" . meow-pop-selection) '("'" . repeat) '("" . ignore)))

Meow package

(use-package meow :config (meow-setup) (meow-global-mode 1))

Doom UI

Doom themes

Doom-themes is collection of cool themes that I like.

(use-package doom-themes :config ;; Global settings (defaults) (setq doom-themes-enable-bold t ; if nil, bold is universally disabled doom-themes-enable-italic t) ; if nil, italics is universally disabled (load-theme 'doom-monokai-classic t)

;; Enable flashing mode-line on errors (doom-themes-visual-bell-config) ;; Enable custom neotree theme (all-the-icons must be installed!) ;;(doom-themes-neotree-config) ;; or for treemacs users ;;(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme ;;(doom-themes-treemacs-config) ;; Corrects (and improves) org-mode's native fontification. (doom-themes-org-config))

Dom modeline

(use-package all-the-icons)

(use-package doom-modeline :init (doom-modeline-mode 1))

Org

Improve font faces

Sometimes using variable-pitch font anin't good.

(use-package org-faces :ensure nil :after org :custom-face (org-block ((nil (:inherit fixed-pitch :foreground nil)))) (org-code ((nil (:inherit (shadow fixed-pitch))))) (org-table ((nil (:inherit fixed-pitch)))) (org-verbatim ((nil (:inherit (shadow fixed-pitch))))) (org-special-keyword ((nil (:inherit (font-lock-comment-face fixed-pitch))))) (org-meta-line ((nil (:inherit (font-lock-comment-face fixed-pitch))))) (org-checkbox ((nil (:inherit fixed-pitch)))))

Base config

(defun my/org-mode-setup () (org-indent-mode) (org-hide-block-all) ;; Collapse all blocks (variable-pitch-mode 1) (visual-line-mode 1))

(use-package org :hook (org-mode . my/org-mode-setup))

Nicer org bullets

Org-superstar is providing nice org mode symbols

(use-package org-superstar :after org :hook (org-mode . (lambda () (org-superstar-mode 1))))

Center org buffer

Visual-fill-column is used to center the org buffer

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

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

Completion

Corfu

Corfu deals auto-completion popup.

(use-package corfu :custom (corfu-auto t) (corfu-separator ?\s) (corfu-quit-no-match 'separator) :init (global-corfu-mode) :bind (:map corfu-map ([remap isearch-forward] . corfu-insert-separator)))

Complementary config

(use-package emacs :init (setq tab-always-indent 'complete))

Corfu-popupinfo

(use-package corfu-popupinfo :ensure nil :after corfu :custom (corfu-popupinfo-delay 0) :init (corfu-popupinfo-mode) :bind (:map corfu-popupinfo-map ("M-p" . corfu-popupinfo-scroll-down) ("M-n" . corfu-popupinfo-scroll-up)))

Kind icon

Kind-icon provides nice icons for corfu popup

(use-package kind-icon :ensure t :after corfu :custom (kind-icon-use-icons nil) (kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly :config (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

Orderless

Orderlsess is a new completion system

(use-package orderless :custom (completion-styles '(orderless basic)) (completion-category-defaults nil) (completion-category-overrides '((file (styles basic partial-completion)) (eglot (styles orderless)))))

Cape

Cape adds capfs to corfu

(use-package cape :init (dolist (capf (list #'cape-dabbrev #'cape-file)) (add-to-list 'completion-at-point-functions capf)))

Yasnippet

Add some nice snippets

(use-package yasnippet :diminish :config (yas-reload-all) (yas-global-mode))

(use-package yasnippet-snippets)

(use-package company)

(use-package company-yasnippet :ensure nil :config (add-to-list 'completion-at-point-functions (cape-company-to-capf #'company-yasnippet)))

Vertico

Vertico provides interactive completion ui

(use-package vertico :init (vertico-mode))

;; Persist history over Emacs restarts. Vertico sorts by history position. (use-package savehist :init (savehist-mode))

;; A few more useful configurations... (use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. ;; We display [CRM], e.g., [CRM,] if the separator is a comma. (defun crm-indicator (args) (cons (format "[CRM%s] %s" (replace-regexp-in-string "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" crm-separator) (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

;; Emacs 28: Hide commands in M-x which do not work in the current mode. ;; Vertico commands are hidden in normal buffers. ;; (setq read-extended-command-predicate ;; #'command-completion-default-include-p)

;; Enable recursive minibuffers (setq enable-recursive-minibuffers t))

Vertico directory

(use-package vertico-directory :after vertico :ensure nil :bind (:map vertico-map ("RET" . vertico-directory-enter) ("DEL" . vertico-directory-delete-char) ("M-DEL" . vertico-directory-delete-word)) :hook (rfn-eshadow-update-overlay . vertico-directory-tidy))

Marginilia

Marginilia enables rich buffer annotations

(use-package marginalia ;; Either bind `marginalia-cycle' globally or only in the minibuffer :bind (("M-A" . marginalia-cycle) :map minibuffer-local-map ("M-A" . marginalia-cycle))

;; The :init configuration is always executed (Not lazy!) :init

;; Must be in the :init section of use-package such that the mode gets ;; enabled right away. Note that this forces loading the package. (marginalia-mode))

Eglot

Eglot is like lsp but more lightweight

(defun my/eglot-capf () (setq-local completion-at-point-functions (list (cape-super-capf #'eglot-completion-at-point (cape-company-to-capf #'company-yasnippet) #'cape-dabbrev #'cape-file)))) (use-package eglot :config (advice-add 'eglot-completion-at-point :around #'cape-wrap-buster) :bind (("C-c l a a" . eglot-code-actions) ("C-c l a i" . eglot-code-actions-inline) ("C-c l a q" . eglot-code-actions-quickfix) ("C-c l a e" . eglot-code-actions-extract) ("C-c l a r" . eglot-code-actions-rewrite) ("C-c l r" . elot-rename) ("C-c l s d" . xref-find-definitions) ("C-c l s i" . eglot-find-implementation) ("C-c l s c" . eglot-find-declaration) ("C-c l s t" . eglot-find-typeDefinition))

:hook (eglot-managed-mode . my/eglot-capf))

Magit

Magit provides git integration

(use-package magit)

Helpful

Heplful profives better documentation for emacs

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

Do not liter

Do not leave litter files

(use-package no-littering :init (setq no-littering-etc-directory (expand-file-name "config/" user-emacs-directory)) (setq no-littering-var-directory (expand-file-name "data/" user-emacs-directory)) (setq backup-directory-alist `(("\\`/tmp/" . nil) ("\\`/dev/shm/" . nil) ("." . ,(no-littering-expand-var-file-name "backup/")))))

Languages

Fish

Language-specific configurations

(use-package fish-mode)

Haskell

(use-package haskell-mode)

Clojure

(use-package clojure-mode)

Cider

Cider brings REPL driven clojure develpment to clojure in emacs.

(use-package cider)

Clj-refactor

Clj-refactor provides powerful refactoring functionality for Clojure projects.

(defun my/clojure-mode-hook () (clj-refactor-mode 1) (yas-minor-mode 1) ; for adding require/use/import statements ;; This choice of keybinding leaves cider-macroexpand-1 unbound (cljr-add-keybindings-with-prefix "C-c C-m")) (use-package clj-refactor :hook (clojure-mode . my/clojure-mode-hook))

Telega.el

Telega enables telegram integration. Requires tdlib.

(use-package telega)