Конфигурация GNU Emacs
Emacs – текстовый редактор от сообщества GNU. Он расширяется при помощи языка Emacs Lisp и является одним из старейших текстовых редакторов, который используется многими и по сей день. Далее идёт моя конфигурация этого редактора.
Исходный код
About this Emacs configuration
Configuration uses org-mode to tangle its contents to init.el and then be used by emacs. I use guix home for my emacs config on gnu guix system.
If you see :tangle nil it means that snippet is not used anymore, but it is left because it might be valuable in a future for me.
This configuration is available here: https://w96k.dev/emacs.html
The git source code is hosted on Sourcehut: https://git.sr.ht/~w96k/dotfiles/tree/master/item/emacs
The license of emacs config and dotfiles is CC0 which is Public Domain.
Packets
Only needed when I need to install a package from Melpa and not GNU Guix
(require 'package)
(setq package-archives '(("gnu" . "http://elpa.gnu.org/packages/")
("melpa" . "http://melpa.org/packages/")))
(when (< emacs-major-version 27)
(package-initialize))
(require 'gnutls)
EXWM
(require 'exwm) (require 'exwm-config) (exwm-config-example)
Init.el
;; -*- lexical-binding: t -*-
;; Show/Hide errors
;; (setq debug-on-error nil)
;; (setq debug-on-quit nil)
;; Timer
(add-hook 'emacs-startup-hook
(lambda ()
(message
"Emacs ready in %s with %d garbage collections."
(format "%.2f seconds"
(float-time
(time-subtract after-init-time before-init-time)))
gcs-done)))
;; Dont ask when following symlinks
(setq vc-follow-symlinks t)
;; Load your custom settings
(setq custom-file "~/.emacs.d/custom-settings.el")
(load custom-file t)
Meta
About me
;; Information about me
(setq user-full-name "Mikhail Kirillov"
user-mail-address "w96k@runbox.com")
Configuration
(setq config-dotfiles-path "/home/w96k/projects/dotfiles/emacs/.emacs.d/"
config-path "~/.emacs.d/"
config-name ".emacs-config.org")
(defun config-visit ()
(interactive)
(find-file (concat config-path config-name)))
(defun config-tangle ()
(interactive)
(org-babel-tangle-file (concat config-dotfiles-path config-name))
;; Configuration stored in another directory,
;; so I need to move files .emacs.d manually
;; (rename-file (concat config-dotfiles-path "early-init.el") config-path t)
(rename-file (concat config-dotfiles-path "init.el") config-path t))
Appereance
Line numbers
Изначально они отключены, но можно вызвать по клавише F7.
(define-key global-map (kbd "<f7>") 'display-line-numbers-mode) (define-key global-map (kbd "<f6>") 'whitespace-mode)
Editing
Completion styles
(setq completion-styles '(basic partial-completion emacs22 substring))
Dired
;; Show files in KiB
(use-package dired
:hook
(dired-mode . hl-line-mode)
:config
(setq dired-listing-switches "-hlap"
dired-kill-when-opening-new-dired-buffer t)
(customize-set-variable 'global-auto-revert-non-file-buffers t)
(global-auto-revert-mode 1))
Linter
I use Flymake and Flycheck
- Flymake
(add-hook 'prog-mode-hook 'flymake-mode) (require 'psalm) (define-prefix-command 'flymake-map) (global-set-key (kbd "C-q") 'flymake-map) (define-key flymake-map (kbd "n") 'flymake-goto-next-error) (define-key flymake-map (kbd "p") 'flymake-goto-prev-error) (define-key flymake-map (kbd "l") 'flymake-show-diagnostics-buffer) (define-key flymake-map (kbd "e") 'flymake-show-diagnostic)
- Flycheck
;; (require 'psalm) (when (package-loaded? "flycheck") (defun flycheck-phanclient-start-daemon () "Start the phan daemon" (interactive) (let* ((default-directory (php-project-get-root-dir)) (phan-executable (or flycheck-phanclient--phan-executable (if (file-exists-p "vendor/bin/phan") (concat default-directory "vendor/bin/phan") (executable-find "phan")))) (cmd (list phan-executable "--daemonize-tcp-port" "4846" "--quick"))) (apply #'start-process "PhanDaemon" "*phan daemon*" cmd))) (flycheck-define-checker php-phanclient "Phan" :command ("phan_client" "-l" source-original "-f" source) :error-patterns ((warning line-start (or "Parse" "Fatal" "syntax" "Phan") " error" (any ":" ",") " " (message) " in " (file-name) " on line " line line-end)) :modes (php-mode php+-mode)) (add-to-list 'flycheck-checkers 'php-phanclient) (flycheck-add-next-checker 'php '(warning . php-phanclient)) (add-hook 'prog-mode-hook 'flycheck-mode))
Imenu List
(use-package imenu-list
:bind
("C-x C-d" . imenu-list-smart-toggle)
:config
(setq imenu-list-focus-after-activation nil
imenu-list-auto-resize nil
imenu-list-mode-line-format '()
imenu-list-size 0.4))
Version Control System
Модуль VC + Magit.
| Operation | VC | Magit |
|---|---|---|
| Project status | project-vc-dir (C-x p v) | magit-status (C-x g) |
| Pull | vc-update (F, in my case) | magit-pull (F p) |
| New branch | vc-retrieve-tag (C-u B s) | magit-branch (b c) |
| Commit | vc-next-action (C-x v v) | magit-commit (c c) |
| Rebase | shell-command (M-!) + git rebase master | magit-rebase (r p) |
| Push | vc-push (P or C-u P) | magit-push (P p) |
| Stash | mu-vc-git-stash (z) | magit-stash (z) |
| Log | vc-print-root-log (L) | magit-log (l l) |
https://www.manueluberti.eu//emacs/2021/11/27/vc/
(setq vc-command-messages t)
(global-set-key "\C-xvB" 'git-branch-next-action)
;; Use magit only when built-in VC fails
(use-package magit
:defer t
:bind (("C-x g" . magit-status)))
(use-package git-timemachine :defer t)
Jumps
;; Jumps by highlighting symbols on screen
(use-package avy
:defer t
:bind (("M-s M-s" . avy-goto-char)
("M-s s" . avy-goto-char)
("M-s g" . avy-goto-line)
("M-s l" . avy-goto-char-in-line)
("M-s M-l" . avy-goto-char-in-line)
("M-g g" . avy-goto-line)
("M-s M-g" . avy-goto-line)))
(use-package link-hint
:defer t
:bind (("M-s j" . link-hint-open-link)))
;; Jumps to last change
(use-package goto-chg
:defer t
:bind (("C-z" . goto-last-change)
("M-z" . goto-last-change-reverse)))
;; Jumps using grep and similar tools
(use-package dumb-jump
:defer t
:bind (("M-g o" . dumb-jump-go-other-window)
("M-g j" . dumb-jump-go)
("M-g b" . dumb-jump-back)
("M-g q" . dumb-jump-quick-look)
("M-g x" . dumb-jump-go-prefer-external)
("M-g z" . dumb-jump-go-prefer-external-other-window)))
Проекты
Использую встроенный project.el I use built-in project.el
Ограничение ширины строки
(add-hook 'prog-mode-hook 'display-fill-column-indicator-mode)
;;; Set column width to 79 according to pep8 for python
(add-hook 'python-mode-hook
(lambda () (set-fill-column 79)))
Ввод парных скобок и кавычек (electric)
;;; Input of pair delimiters (electric-pair-mode) (add-hook 'prog-mode-hook 'electric-pair-mode) (add-hook 'prog-mode-hook 'electric-indent-mode)
Kill-ring
(use-package browse-kill-ring
:defer t
:bind ("C-M-y" . browse-kill-ring))
Tags
Для прыжков и поиска функций/классов и т.д.
(setq path-to-ctags "~/.guix-home/profile/bin/ctags")
(defun tags-create (dir-name)
"Create tags file."
(interactive "DDirectory: ")
(shell-command
(format "%s -f TAGS -e -R %s" path-to-ctags
(directory-file-name dir-name))))
(defun tags-create-python (dir-name)
"Create tags with python interpreter"
(interactive "DDirectory: ")
(shell-command
(format "%s -f TAGS -e -R --fields=+l --languages=python --python-kinds=-iv $(python -c \"import os, sys; print(' '.join('{}'.format(d) for d in sys.path if os.path.isdir(d)))\") %s" path-to-ctags
(directory-file-name dir-name))))
(use-package ggtags :defer t :hook (c-mode . ggtags-mode))
Дебаггер
(when (package-loaded? "realgud") (load "~/.emacs.d/site-lisp/realgud-xdebug/realgud-xdebug.el"))
(when (package-loaded? "geben") (setq geben-dbgp-default-port 9003))
- Автодополнение кода и документация
По большей части я использую дефолтный Completion Buffer и Corfu
(when (package-loaded? "corfu") (progn (setq corfu-preview-current 'nil corfu-popupinfo-delay t) (corfu-mode 1) (corfu-popupinfo-mode 1) (defun show-default-completion-buffer () (interactive) (corfu-quit) (corfu-mode -1) (completion-at-point) (corfu-mode 1) (corfu-popupinfo-mode 1)) (define-key corfu-map (kbd "M-TAB") 'show-default-completion-buffer) (define-key corfu-map (kbd "TAB") 'show-default-completion-buffer) (define-key corfu-map (kbd "C-M-i") 'show-default-completion-buffer) (corfu-mode -1) (add-hook 'prog-mode-hook 'corfu-mode) (defun corfu-send-shell (&rest _) "Send completion candidate when inside comint/eshell." (cond ((and (derived-mode-p 'eshell-mode) (fboundp 'eshell-send-input)) (eshell-send-input)) ((and (derived-mode-p 'comint-mode) (fboundp 'comint-send-input)) (comint-send-input)))) (advice-add #'corfu-insert :after #'corfu-send-shell) (add-hook 'eshell-mode-hook 'corfu-mode))) - Агрессивный дефолтный комплит
(setq aggressive-completion-delay 0.5) (aggressive-completion-mode t)
Полнотекстовый поиск
Для выхода из поиска – C-c C-q
(load "deft-autoloads")
(define-key global-map
(kbd "C-c n s") 'deft)
(setq deft-recursive t
deft-use-filter-string-for-filename t
deft-default-extension "org md"
deft-directory "~/projects/at-w96k/content/digarden")
Визуализирование откатов
При помощи пакета undo-tree
(use-package undo-tree :defer t :hook (prog-mode . undo-tree-mode) (org-mode . undo-tree-mode))
Сниппеты
(when (package-loaded? "yasnippet")
(progn
(add-hook 'prog-mode-hook #'yas-minor-mode)))
Клиент LSP
(with-eval-after-load 'eglot
(add-to-list 'eglot-server-programs
'((php-mode phps-mode php-ts-mode) . ("/home/w96k/projects/phpactor/bin/phpactor" "language-server" "-vvv"))))
;; (with-eval-after-load 'eglot
;; (add-to-list 'eglot-server-programs '((php-mode phps-mode) . ("~/projects/phpactor/bin/phpactor" "language-server" "-vvv")))
;; (add-to-list 'eglot-server-programs '((php-mode phps-mode) . ("intelephense" "--stdio")))
;; ;; No event buffers, disable providers cause a lot of hover traffic. Shutdown unused servers.
;; (setq eglot-events-buffer-size 0
;; eglot-ignored-server-capabilities '(:hoverProvider
;; :documentHighlightProvider)
;; eglot-autoshutdown t))
;; Show all of the available eldoc information when we want it. This way Flymake errors
;; don't just get clobbered by docstrings.
(add-hook 'eglot-managed-mode-hook
(lambda ()
"Make sure Eldoc will show us all of the feedback at point."
(setq-local eldoc-documentation-strategy
#'eldoc-documentation-compose)))
Линтеры
(defun my-php-mode-setup () "My PHP-mode hook." (require 'flycheck-phpstan) (flycheck-mode t)) (add-hook 'php-mode-hook 'my-php-mode-setup)
;; (add-hook 'php-mode-hook 'flymake-php-load)
;; (add-hook 'php-mode-hook 'flymake-phpstan-turn-on)
;; (require 'flycheck-phpstan)
;;(add-to-list 'auto-mode-alist '("\\.\\(php\\|phtml\\)\\'" . phps-mode))
;; (phps-mode-flycheck-setup)
;; (setq phps-mode-async-process t)
;; (setq phps-mode-async-process-using-async-el t)
Выделение
(use-package expand-region
:defer t
:bind (("C-=" . er/expand-region)))
Сессия
(desktop-save-mode 1)
Скроллинг
(setq scroll-margin 0)
Поиск
- Isearch
(with-eval-after-load 'isearch (define-key isearch-mode-map "\C-h" 'isearch-delete-char) (define-key isearch-mode-map "\C-ch" 'isearch-help-for-help))
- Подсчёт кандидатов
(use-package anzu :config (global-anzu-mode t))
- Swiper (не используется)
(load "swiper-autoloads") (global-set-key (kbd "C-s") 'swiper) (setq swiper-include-line-number-in-search t swiper-use-visual-line t swiper-stay-on-quit t)
Which function
(which-function-mode t)
Подсказка биндов
Пакет Which-key
(load "which-key-autoloads")
(which-key-setup-side-window-right)
(which-key-mode)
(setq which-key-side-window-max-width 0.5
which-key-show-remaining-keys t
which-key-max-display-columns 50
which-key-max-description-length 35
which-key-sort-order 'which-key-local-then-key-order
which-key-idle-delay 0.25)
Права суперпользователя
Sudo-edit
(use-package sudo-edit :defer t)
Промежуточный код
Показывает собранное состояние будь то собранный куски на ассемблере или байт-код при помощи пакета RMSbolt.
(use-package rmsbolt :defer t)
Быстрый запуск программы
;; (when (package-loaded? "quickrun") ;; (define-key global-map (kbd "C-c C-c") 'quickrun))
Языки программирования
Common Lisp
Ruby
(when (package-loaded? "inf-ruby") (add-hook 'ruby-mode-hook 'inf-ruby-minor-mode)) (when (package-loaded? "inf-ruby") (add-hook 'ruby-mode-hook 'robe-mode))
Scheme
(setq geiser-active-implementations '("guile"))
GO
(use-package go-mode)
Python
- Автодополнение и линт
(when (package-loaded? "anaconda-mode") (progn (add-hook 'python-mode-hook 'anaconda-mode) (add-hook 'python-mode-hook 'anaconda-eldoc-mode))) ;; (when (load "flymake" t) ;; (defun flymake-pylint-init () ;; (let* ((temp-file (flymake-init-create-temp-buffer-copy ;; 'flymake-create-temp-inplace)) ;; (local-file (file-relative-name ;; temp-file ;; (file-name-directory buffer-file-name)))) ;; (list "epylint" (list local-file)))) ;; (add-to-list 'flymake-allowed-file-name-masks ;; '("\\.py\\'" flymake-pylint-init))) ;; (add-hook 'python-mode-hook 'flymake-mode) - Прыжки в функции стандартной библиотеки на си
SML
(add-hook 'sml-mode-hook 'sml-mode)
Java
PHP
- PHP-Mode
Необходимо скачать и распаковать мануал PHP (в формате html) в директорию
~/.emacs.d/php-manual/.;; (add-to-list 'load-path "~/.emacs.d/site-lisp/realgud-xdebug/") ;; (require 'realgud-xdebug) ;; (defun init-php-mode () ;; (eglot-ensure)) (use-package php-mode :bind ("C-c h" . 'php-quickhelp-at-point) :config (setq php-manual-path "~/projects/php-manual/" php-quickhelp-dir "~/projects/php-manual/" php-quickhelp--dest "~/projects/php-manual/php_manual_en.json")) ;; (add-hook 'php-mode-hook ;; '(lambda () ;; ;; (auto-complete-mode t) ;; ;; (require 'ac-php) ;; (require 'php-quickhelp) ;; (require 'company) ;; (company-mode t) ;; (require 'company-php) ;; (require 'company-quickhelp) ;; (require 'yasnippet) ;; (require 'yasnippet-snippets) ;; (set (make-local-variable 'company-backends) ;; '((company-ac-php-backend company-dabbrev-code) ;; php-quickhelp-company-php ;; company-capf company-files)) ;; (company-quickhelp-mode t) ;; (define-key php-mode-map (kbd "C-M-i") 'company-complete) ;; (define-key company-mode-map (kbd "M-TAB") 'company-complete) ;; ;; (setq ac-sources '(ac-source-php php-quickhelp-company-php)) ;; ;; (setq eldoc-documentation-function ;; ;; 'php-quickhelp-eldoc-func) ;; (yas-minor-mode t) ;; ;; (define-key php-mode-map (kbd "C-M-i") 'auto-complete) ;; ;; (define-key ac-mode-map (kbd "M-TAB") 'auto-complete) ;; (define-key php-mode-map (kbd "C-c H") ;; 'php-local-manual-search) ;; (define-key php-mode-map (kbd "C-c h") 'php-quickhelp-at-point) ;; (define-key company-mode-map (kbd "C-c h") 'php-quickhelp-at-point) ;; ;; (define-key php-mode-map (kbd "C-c t") 'ac-php-show-tip) ;; ;; Jump to definition (optional) ;; (define-key php-mode-map ;; (kbd "M-.") 'ac-php-find-symbol-at-point) ;; ;; Return back (optional) ;; (define-key php-mode-map ;; (kbd "M-,") 'ac-php-location-stack-back))) )) - Composer
(setq composer-executable-bin "~/.bin/composer")
- Flymake PHP
- REPL
- LSP сервер
PHPactor
(setq phpactor-executable "~/.bin/phpactor") (custom-set-variables '(lsp-phpactor-path "~/.bin/phpactor")) (use-package phpactor :ensure t) (use-package company-phpactor :ensure t) ;; (with-eval-after-load 'php-mode ;; (define-key php-mode-map (kbd "M-.") #'phpactor-goto-definition) ;; (define-key php-mode-map (kbd "M-?") #'phpactor-find-references))
- Transient меню
(require 'transient) (define-transient-command php-menu () "Php" [["Class" ("cc" "Copy" phpactor-copy-class) ("cn" "New" phpactor-create-new-class) ("cr" "Move" phpactor-move-class) ("ci" "Inflect" phpactor-inflect-class) ("n" "Namespace" phpactor-fix-namespace)] ["Properties" ("a" "Accessor" phpactor-generate-accessors) ("pc" "Constructor" phpactor-complete-constructor) ("pm" "Add missing props" phpactor-complete-properties) ("r" "Rename var locally" phpactor-rename-variable-local) ("R" "Rename var in file" phpactor-rename-variable-file)] ["Extract" ("ec" "constant" phpactor-extract-constant) ("ee" "expression" phpactor-extract-expression) ("em" "method" phpactor-extract-method)] ["Methods" ("i" "Implement Contracts" phpactor-implement-contracts) ("m" "Generate method" phpactor-generate-method)] ["Navigate" ("x" "List refs" phpactor-list-references) ("X" "Replace refs" phpactor-replace-references) ("." "Goto def" phpactor-goto-definition)] ["Phpactor" ("s" "Status" phpactor-status) ("u" "Install" phpactor-install-or-update)]])
Языки декларирования
SQL
to install lsp-server called sqls https://emacs-lsp.github.io/lsp-mode/page/lsp-sqls/
;; Empty for now (was using emacsql)
(setq lsp-sqls-server "~/go/bin/sqls")
;; (setq lsp-sqls-workspace-config-path nil)
(setq lsp-sqls-connections
'(((driver . "mysql") (dataSourceName . "dbuser:mangoworms@tcp(localhost:3306)/profile24"))))
The main way to interact with SQL is using org-mode
(when (package-loaded? "org-sql")
(setq org-sql-files "~/projects/profile24/org"))
(add-hook 'sql-interactive-mode-hook
(lambda ()
(sql-connect "profile24")
(toggle-truncate-lines t)))
(setq sql-connection-alist
'((profile24
(sql-product 'mysql)
(sql-server "localhost")
(sql-user "dbuser")
(sql-password "123456")
(sql-database "testdb")
(sql-port 3306))))
Веб шаблоны
- Web-mode
(use-package web-mode :defer t :config (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode)) (add-to-list 'auto-mode-alist '("\\.twig.html\\'" . web-mode)) (setq web-mode-markup-indent-offset 2) (setq web-mode-enable-auto-pairing t) (setq web-mode-enable-css-colorization t) (setq web-mode-enable-block-face t) (setq web-mode-enable-current-element-highlight t))
Org
- Org-mode
(use-package org :defer t :config (org-babel-do-load-languages 'org-babel-load-languages '((R . t) (ditaa . t) (dot . t) ;; (php . t) (emacs-lisp . t) (gnuplot . t) (haskell . nil) (latex . t) ;;(ledger . t) (ocaml . nil) (octave . t) (python . t) (ruby . t) (screen . nil) (shell . t) (sql . t) (js . t))) (setq org-default-notes-file "~/Documents/todo.org" system-time-locale "C" org-use-speed-commands t org-adapt-indentation nil org-return-follows-link t org-agenda-include-diary t org-display-remote-inline-images 'download org-agenda-start-with-log-mode t org-image-actual-width (list 400) org-hide-emphasis-markers t org-outline-path-complete-in-steps nil org-src-tab-acts-natively t org-id-track-globally t org-confirm-babel-evaluate nil) (setq org-todo-keywords (quote ((sequence "TODO(t)" "MIGRATE(m)" "IN PROGRESS(p)" "DONE(d)") (sequence "BLOCKED(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING" "NEED CLARIFICATION(t)" )))) (setq org-todo-keyword-faces (quote (("TODO" :foreground "red" :weight bold) ("NEXT" :foreground "blue" :weight bold) ("DONE" :foreground "forest green" :weight bold) ("WAITING" :foreground "orange" :weight bold) ("HOLD" :foreground "magenta" :weight bold) ("CANCELLED" :foreground "forest green" :weight bold) ("MEETING" :foreground "forest cyan" :weight bold) ("PHONE" :foreground "blue" :weight bold)))) :bind ("C-c l" . org-store-link) ("C-c a" . org-agenda) ("C-c c" . org-capture) ) (defun org-babel-edit-prep:sql (babel-info) (setq-local buffer-file-name (->> babel-info caddr (alist-get :tangle))) (setq-local lsp-buffer-uri (->> babel-info caddr (alist-get :tangle) lsp--path-to-uri)) (setq-local lsp-headerline-breadcrumb-enable nil) (lsp)) ;; (global-set-key (kbd "M-f") 'org-metaright) ;; (global-set-key (kbd "M-b") 'org-metaleft) ;; (global-set-key (kbd "M-p") 'org-metaup) ;; (global-set-key (kbd "M-n") 'org-metadown) - Org-ref
(load "org-ref-autoloads") (setq reftex-default-bibliography '("~/Documents/bibliography/references.bib")) ;; see org-ref for use of these variables (setq org-ref-bibliography-notes "~/Documents/bibliography/notes.org" org-ref-default-bibliography '("~/Documents/Bibliography/references.bib") org-ref-pdf-directory "~/Documents/bibliography/bibtex-pdfs/") - Org-roam
(use-package org-roam :defer t :bind ("C-c n l" . org-roam-node-insert) ("C-c n b" . org-roam-buffer-toggle) ("C-c n f" . org-roam-node-find) ("C-c n t t" . org-roam-tag-add) ("C-c n t r" . org-roam-tag-remove) ("C-c n i" . org-roam-jump-to-index) ("C-c n g" . org-roam-graph) ("C-c n d" . org-roam-db-build-cache) ("C-c n r" . org-roam-node-random) ("C-c n j" . org-roam-dailies-find-date) :config (setq org-roam-directory (file-truename "~/Zettelkasten") org-roam-v2-ack t org-roam-completion-everywhere t org-roam-index-file (concat org-roam-directory "/20210409054712-жизнь.org") org-roam-dailies-directory (concat org-roam-directory "journals/")) (org-roam-db-autosync-mode t)) (defun org-roam-jump-to-index () "Stub of recreating the function from V1" (interactive) (let ((org-roam-index org-roam-index-file)) (find-file org-roam-index))) (use-package org :defer t :config (customize-set-variable 'org-link-descriptive t) (add-to-list 'org-agenda-files "~/Documents/todo.org") (setq org-directory "~/Documents" org-default-notes-file (concat org-directory "/todo.org")))
YAML
(use-package yaml-mode :defer t)
Коммуникации
Gnus
Telega
(use-package telega
:bind (("C-c t" . telega-prefix-map)))
Mastodon
(use-package mastodon
:defer t
:config
(setq mastodon-active-user "w96k"
mastodon-instance-url "https://fosstodon.org/"))
Разное
*Highlight
(use-package highlight :defer t)
Минорные твики дефолтного имакса
- Короткие ответы на вопросы
(if (boundp 'use-short-answers) (setq use-short-answers t) (advice-add 'yes-or-no-p :override #'y-or-n-p))
- Не сохранять дубликаты в killring
- Подсвечивать текущую строку
(global-hl-line-mode t)
- Автодополнение в echo при M-x и других командах
(icomplete-mode t)
- Проверять орфографию
(flyspell-mode t)
- Не спрашивать о несуществующих буферах
(setq-default confirm-nonexistent-file-or-buffer t)
- Переключение буферов
(global-set-key (kbd "M-o") 'mode-line-other-buffer)
- Минорные твики
;; (setq redisplay-dont-pause t) (setq select-enable-clipboard t select-enable-primary t) (setq completions-detailed nil) (setq kill-buffer-delete-auto-save-files t) (setq next-error-message-highlight t) (setq mode-line-compact 'long) (setq completions-group t) ;;(set-frame-parameter nil 'internal-border-width 0) ;; (set-window-buffer nil (current-buffer)) (setq default-directory "~/" custom-safe-themes t delete-old-versions t enable-local-variables t) - Shell
(setq ansi-color-for-comint-mode t) (setq shell-command-prompt-show-cwd t)
- Переменная PATH в eshell
(setq exec-path-from-shell-variables '("PATH" "MANPATH")) (when (and (memq window-system '(mac ns x)) (not (eq system-type 'berkeley-unix))) (exec-path-from-shell-initialize)) - Отображение номера колонки
(column-number-mode)
- nobreak символы
(setq nobreak-char-display nil)
- Меню
- Сохранять временные файлы не в той же директории
(defvar backup-dir "~/.emacs.d/backups/") (setq backup-by-copying t backup-directory-alist '(("~/.emacs.d/backups/")) version-control nil) - Календарь
Делаем начало недели в понедельник.
(setq calendar-week-start-day 1)
- Вернуться в предыдущий буфер
(define-key global-map (kbd "C-q C-q") 'previous-buffer) (define-key global-map (kbd "C-S-q C-S-q") 'next-buffer)
- Смена раскладки (EN / RU) и поддержка биндов на других языках
Работает на C-\
(set-input-method "russian-computer") (toggle-input-method)
- Требовать создания последней пустой строки
(setq require-final-newline t)
- Стирать текст на C-h как в Bash
И переназначаем старые бинды
(define-key global-map (kbd "C-h") 'delete-backward-char) (define-key global-map (kbd "C-c h") 'help-command)
- Bash completion
(use-package bash-completion :config (bash-completion-setup))
- Поддержка CamelCase в навигации
(global-subword-mode 1)
Браузер
(setq browse-url-browser-function #'eww-browse-url)
(add-hook 'eww-mode-hook
(lambda ()
(set-fill-column 80)
(display-fill-column-indicator-mode)
(visual-fill-column-mode)))
Tramp
(add-to-list 'tramp-remote-path 'tramp-own-remote-path)
Docker
(use-package docker :defer t) (use-package docker-compose-mode :defer t)
Debian
Инструменты для работы с пакетным менеджером Debian'а apt'ом и смежными инструментами.
(load "debian-el-autoloads") (load "dpkg-dev-el-autoloads")
Guix
;; (use-package geiser-guile :defer t)
(use-package guix
:defer t
:config
(setq geiser-guile-binary "guile")
(with-eval-after-load 'geiser-guile
(progn
(add-to-list 'geiser-guile-load-path "~/projects/guix/")))
(let ((guix-copyright "~/projects/guix/etc/copyright.el"))
(if (file-exists-p guix-copyright)
(load-file "~/projects/guix/etc/copyright.el")))
(setq copyright-names-regexp
(format "%s <%s>" user-full-name user-mail-address)))
Nix
(use-package nix)
Direnv
(when (package-loaded? "direnv")
(direnv-mode))
Увеличение/уменьшение шрифта
(defun zoom-in ()
(interactive)
(let ((x (+ (face-attribute 'default :height)
10)))
(set-face-attribute 'default nil :height x)
(set-face-attribute 'mode-line nil :height x)
(set-face-attribute 'mode-line-inactive nil :height x)
(set-face-attribute 'mode-line-position-face nil :height x)))
(defun zoom-out ()
(interactive)
(let ((x (- (face-attribute 'default :height)
10)))
(set-face-attribute 'default nil :height x)
(set-face-attribute 'mode-line nil :height x)
(set-face-attribute 'mode-line-inactive nil :height x)
(set-face-attribute 'mode-line-position-face nil :height x)))
(define-key global-map (kbd "C-=") 'zoom-in)
(define-key global-map (kbd "C-+") 'zoom-out)
Автокомплит у yes-or-no
Полный экран
Открывать Emacs на полный экран
(add-to-list 'default-frame-alist '(fullscreen . maximized))
Фуллскрин
Отображать ровно столько строчек, сколько вмещает экран.
Не работает с native-comp.
(toggle-frame-fullscreen)
(defun fullscreen ()
"Fullscreen."
(interactive)
(x-send-client-message nil 0 nil "_NET_WM_STATE" 32
;; if first parameter is '1', can't toggle fullscreen status
'(1 "_NET_WM_STATE_FULLSCREEN" 0)))
Удаление буфера и файла
(defun delete-file-and-buffer ()
"Kill the current buffer and deletes the file it is visiting."
(interactive)
(let ((filename (buffer-file-name)))
(if filename
(if (y-or-n-p (concat "Do you really want to delete file " filename " ?"))
(progn
(delete-file filename)
(message "Deleted file %s." filename)
(kill-buffer)))
(message "Not a file visiting buffer!"))))
Длинные строки
;; Better support for files with long lines (setq-default bidi-paragraph-direction 'left-to-right) (setq-default bidi-inhibit-bpa t) (global-so-long-mode 1)
Make shebang (#!) file executable when saved
(add-hook 'after-save-hook #'executable-make-buffer-file-executable-if-script-p)
Enable savehist-mode for command history
(savehist-mode 1)
Ignore case sensitive in completions, search and etc
(setq completion-ignore-case t
read-buffer-completion-ignore-case t
read-file-name-completion-ignore-case t)
Make scripts executable automatically
(add-hook 'after-save-hook
'executable-make-buffer-file-executable-if-script-p)
F1 for M-x shell and F2 for grep
(global-set-key (kbd "<f1>") 'shell) (global-set-key (kbd "<f2>") 'rgrep)
Hippie expand
(global-set-key [remap dabbrev-expand] 'hippie-expand)
Window Divider
(window-divider-mode t)
Use specific font for major modes
(buffer-face-mode t) (defun set-normal-font () "Set normal weight font in current buffer" (interactive) (buffer-face-mode 1) (setq buffer-face-mode-face '(:weight normal)) (buffer-face-mode)) ;; Use monospaced font faces in current buffer (defun set-bold-font () "Sets a bold font in current buffer" (interactive) (buffer-face-mode 1) (setq buffer-face-mode-face '(:weight bold)) (buffer-face-mode)) (add-hook 'dired-mode-hook 'set-normal-font) (add-hook 'org-mode-hook 'set-normal-font) (add-hook 'Info-mode-hook 'set-normal-font)