From e9cd60bf35685d17f0be97bb849683dec0825efd Mon Sep 17 00:00:00 2001 From: Martin Michalec Date: Tue, 10 Feb 2026 02:19:19 +0300 Subject: add emacs config --- dot_config/emacs/early-init.el | 40 + dot_config/emacs/init.el | 1475 +++++++++++++++++++++++++++++++++ dot_config/emacs/private_eshell/alias | 2 + 3 files changed, 1517 insertions(+) create mode 100644 dot_config/emacs/early-init.el create mode 100644 dot_config/emacs/init.el create mode 100644 dot_config/emacs/private_eshell/alias (limited to 'dot_config') diff --git a/dot_config/emacs/early-init.el b/dot_config/emacs/early-init.el new file mode 100644 index 0000000..0eea59d --- /dev/null +++ b/dot_config/emacs/early-init.el @@ -0,0 +1,40 @@ +;; early-init.el -*- lexical-binding: t; -*- + +;; Disable package.el +(setq package-enable-at-startup nil) + +;; Defer garbage collection further back in the startup process +(setq gc-cons-threshold most-positive-fixnum + gc-cons-percentage 0.6) + +(add-hook 'emacs-startup-hook + (lambda () + (setq gc-cons-threshold 16777216 ; 16mb + gc-cons-percentage 0.1))) + +;; Ignore X resources +(setq inhibit-x-resources t) + +;; Do not resize the frame at this early stage. +(setq frame-inhibit-implied-resize t) + +(push '(menu-bar-lines . 0) default-frame-alist) +(push '(tool-bar-lines . 0) default-frame-alist) +(push '(vertical-scroll-bars) default-frame-alist) +(push '(horizontal-scroll-bars) default-frame-alist) +(push (cons 'left-fringe 8) default-frame-alist) +(push (cons 'right-fringe 8) default-frame-alist) +(push '(no-special-glyphs) default-frame-alist) +(push '(undecorated) default-frame-alist) +(setq menu-bar-mode nil tool-bar-mode nil scroll-bar-mode nil) +(push '(internal-border-width . 4) default-frame-alist) +;; (setq inhibit-startup-screen t) +(setq inhibit-startup-message t) +(setq initial-scratch-message nil) + +;; Local Variables: +;; no-byte-compile: t +;; no-native-compile: t +;; no-update-autoloads: t +;; End: + diff --git a/dot_config/emacs/init.el b/dot_config/emacs/init.el new file mode 100644 index 0000000..e9fc0fb --- /dev/null +++ b/dot_config/emacs/init.el @@ -0,0 +1,1475 @@ +;; Example Elpaca configuration -*- lexical-binding: t; -*- +(defvar elpaca-installer-version 0.11) +(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) +(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) +(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) +(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" + :ref nil :depth 1 :inherit ignore + :files (:defaults "elpaca-test.el" (:exclude "extensions")) + :build (:not elpaca--activate-package))) +(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) + (build (expand-file-name "elpaca/" elpaca-builds-directory)) + (order (cdr elpaca-order)) + (default-directory repo)) + (add-to-list 'load-path (if (file-exists-p build) build repo)) + (unless (file-exists-p repo) + (make-directory repo t) + (when (<= emacs-major-version 28) (require 'subr-x)) + (condition-case-unless-debug err + (if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) + ((zerop (apply #'call-process `("git" nil ,buffer t "clone" + ,@(when-let* ((depth (plist-get order :depth))) + (list (format "--depth=%d" depth) "--no-single-branch")) + ,(plist-get order :repo) ,repo)))) + ((zerop (call-process "git" nil buffer t "checkout" + (or (plist-get order :ref) "--")))) + (emacs (concat invocation-directory invocation-name)) + ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" + "--eval" "(byte-recompile-directory \".\" 0 'force)"))) + ((require 'elpaca)) + ((elpaca-generate-autoloads "elpaca" repo))) + (progn (message "%s" (buffer-string)) (kill-buffer buffer)) + (error "%s" (with-current-buffer buffer (buffer-string)))) + ((error) (warn "%s" err) (delete-directory repo 'recursive)))) + (unless (require 'elpaca-autoloads nil t) + (require 'elpaca) + (elpaca-generate-autoloads "elpaca" repo) + (let ((load-source-file-function nil)) (load "./elpaca-autoloads")))) +(add-hook 'after-init-hook #'elpaca-process-queues) +(elpaca `(,@elpaca-order)) + +;; Install use-package support +(elpaca elpaca-use-package + ;; Enable use-package :ensure support for Elpaca. + (elpaca-use-package-mode) + ;; Auto ensure + (require 'use-package-ensure) + (setq use-package-always-ensure t)) + + + +(use-package project + :ensure (:wait t)) + +(use-package emacs + :ensure nil + :custom + (default-frame-alist (assq-delete-all 'background-color default-frame-alist)) + (context-menu-mode t) + (enable-recursive-minibuffers t) + (read-extended-command-predicate #'command-completion-default-include-p) + (read-file-name-completion-ignore-case t) + (read-buffer-completion-ignore-case t) + (completion-ignore-case t) + (minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (ring-bell-function #'ignore) + (display-time-24hr-format t) + (custom-file (expand-file-name "customs.el" user-emacs-directory)) + (history-length 10000) + (savehist-file (concat (or (getenv "XDG_CACHE_HOME") "~/.cache") + "/emacs/history")) + :config + (blink-cursor-mode 0) + (set-face-attribute 'default nil :font "Aporetic Serif Mono" :height 125) + (set-face-attribute 'variable-pitch nil :font "Aporetic Serif" :inherit 'default) + (set-face-attribute 'fixed-pitch nil :inherit 'default) + (set-fontset-font t 'emoji (font-spec :family "Noto Emoji") nil 'prepend) + + (server-start) + + (column-number-mode 1) + + (setq mode-line-compact 'long) + + ;; Save all tempfiles in $TMPDIR/emacs$UID/ + (defconst emacs-tmp-dir (expand-file-name (format "emacs%d" (user-uid)) temporary-file-directory)) + (setq backup-directory-alist `((".*" . ,emacs-tmp-dir))) + (setq auto-save-file-name-transforms `((".*" ,emacs-tmp-dir t))) + (setq auto-save-list-file-prefix emacs-tmp-dir) + + (prefer-coding-system 'utf-8) + (set-language-environment "UTF-8") + (set-default-coding-systems 'utf-8) + (set-terminal-coding-system 'utf-8) + (setq-default buffer-file-coding-system 'utf-8) + + (defalias 'yes-or-no-p 'y-or-n-p)) + +(setq default-input-method "russian-computer") + +(define-prefix-command 'cmmm/toggle-map nil) +(define-key mode-specific-map (kbd "x") '("toggles" . cmmm/toggle-map)) + +(define-prefix-command 'cmmm/application-map nil) +(define-key mode-specific-map (kbd "a") '("applications" . cmmm/application-map)) +(define-key cmmm/application-map (kbd "w") 'woman) +(define-key cmmm/application-map (kbd "m") 'man) + +(use-package modus-themes + :custom + (modus-themes-bold-constructs t) + (modus-themes-italic-constructs t) + (modus-themes-slanted-constructs t) + (modus-themes-mixed-fonts t) + (modus-themes-variable-pitch-ui t) + (modus-themes-common-palette-overrides '((border-mode-line-active unspecified) + (border-mode-line-inactive unspecified) + (fringe unspecified) + (fg-line-number-inactive "gray50") + (fg-line-number-active fg-main) + (bg-line-number-inactive unspecified) + (bg-line-number-active unspecified) + (bg-region bg-ochre) + (fg-region unspecified) + ;; (comment green-warmer) + )) + (modus-themes-headings '(((1 . (1.15)) + (2 . (1.1)) + (3 . (1.1)) + (4 . (1.0)) + (5 . (1.0)) + (6 . (1.0)) + (7 . (0.9)) + (8 . (0.9))))) + :bind + (:map cmmm/toggle-map + ("t" . modus-themes-toggle)) + :hook (after-init . cmmm/modus-themes-load-vivendi) + :config + (defun cmmm/modus-themes-load-vivendi () + (modus-themes-load-theme 'modus-vivendi)) + ;; (modus-themes-load-theme 'modus-vivendi) + ) + +(defun cmmm/sync-gtk-theme () + (interactive) + (let ((gtk-theme (pcase (car custom-enabled-themes) + ('modus-operandi "Adwaita-light") + ('modus-vivendi "Adwaita")))) + (shell-command (format "gsettings set org.gnome.desktop.interface gtk-theme %s" gtk-theme) nil))) +(advice-add 'modus-themes-toggle :after 'cmmm/sync-gtk-theme) + +(use-package savehist + :ensure nil + :config + (savehist-mode)) + +(use-package spacious-padding) + +(use-package subword + :ensure nil + :config + (global-subword-mode)) + +(use-package ansi-color + :ensure nil + :config + (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) + (add-hook 'compilation-mode-hook 'toggle-truncate-lines)) + +(use-package eshell + :ensure nil + :init + (require 'esh-mode) + :bind + (:map eshell-mode-map + ("C-c M-o" . eshell/clear))) + +(use-package eshell-syntax-highlighting + :config + (eshell-syntax-highlighting-global-mode)) + +(use-package eshell-prompt-extras + :config + (with-eval-after-load 'em-prompt + (autoload 'epe-theme-lambda "eshell-prompt-extras") + (setq eshell-prompt-function 'epe-theme-lambda) + (setq eshell-highlight-prompt nil))) + +(setq world-clock-list + '(("UTC" "UTC") + ("Europe/Bratislava" "Bratislava") + ("Europe/Moscow" "Moscow") + ("America/La_Paz" "La Paz"))) + +(with-eval-after-load 'xref + (setq xref-auto-jump-to-first-definition 'move) + (setq xref-auto-jump-to-first-xref 'move) + ;; (setq xref-prompt-for-identifier + ;; '(not xref-find-definitions-other-window + ;; xref-find-definitions-other-frame)) + (setq xref-show-xrefs-function 'consult-xref) + (setq xref-show-definitions-function 'consult-xref)) + +(define-key global-map (kbd "s-d") 'dired-jump) +(define-key global-map (kbd "s-r") 'recompile) +(define-key global-map (kbd "s-b") 'consult-buffer) +(define-key minibuffer-local-map (kbd "s-b") 'exit-minibuffer) +(define-key global-map (kbd "C-x C-b") 'ibuffer) +(defun cmmm/switch-to-prev-buffer-or-eshell (arg) + (interactive "P") + (if arg + (eshell arg) + (switch-to-buffer (other-buffer (current-buffer) 1)))) +(with-eval-after-load 'esh-mode + (define-key eshell-mode-map (kbd "s-e") 'cmmm/switch-to-prev-buffer-or-eshell)) +(define-key global-map (kbd "s-e") 'eshell) +(define-key global-map (kbd "s-t") 'vterm) +(define-key global-map (kbd "s-w") 'kill-current-buffer) +(define-key global-map (kbd "s-W") 'kill-buffer-and-window) +(define-key global-map (kbd "s-o") 'other-window) + +(use-package dired + :ensure nil + :custom + (dired-clean-confirm-killing-deleted-buffers nil) + (dired-auto-revert-buffer t) + (dired-listing-switches "-Alh --time-style=long-iso") + (dired-dwim-target t) + (dired-recursive-copies 'always) + (dired-recursive-deletes 'always) + (dired-omit-files (string-join '("\\`[.]?#" "\\`[.][.]?" "\\`[.].*" "\\`[_].*" + "\\`compile_commands.json" + "\\`GPATH" "\\`GRTAGS" "\\`GTAGS\\'") + "\\|")) + :hook + (dired-mode . dired-omit-mode) + (dired-mode . dired-hide-details-mode)) +(use-package dired-rsync) +(use-package dired-rsync-transient + :after (transient dired-rsync)) + +(defvar cmmm/monocle--previous-window-configuration nil + "Window configuration for restoring on monocle exit.") +(defun cmmm/toggle-monocle (arg) + "Make window occupy whole frame if there are many windows. Restore +previous window layout otherwise. With universal argument toggles +`global-olivetti-mode'." + (interactive "P") + + (if arg + (if (and global-olivetti-mode global-hide-mode-line-mode) + (progn + (global-hide-mode-line-mode -1) + (global-olivetti-mode -1)) + (progn + (global-hide-mode-line-mode 1) + (global-olivetti-mode 1))) + (if (one-window-p) + (if cmmm/monocle--previous-window-configuration + (let ((cur-buffer (current-buffer))) + (set-window-configuration + cmmm/monocle--previous-window-configuration) + (setq cmmm/monocle--previous-window-configuration nil) + (switch-to-buffer cur-buffer))) + (setq cmmm/monocle--previous-window-configuration + (current-window-configuration)) + (delete-other-windows)))) +(define-key global-map (kbd "s-f") 'cmmm/toggle-monocle) + +(use-package which-key + :config + (which-key-mode)) + +(use-package keycast) + +(use-package xref + :ensure nil + :config + (setq xref-search-program 'ripgrep)) + +;; https://coredumped.dev/2025/06/18/making-tramp-go-brrrr./ +(use-package tramp + :custom + (tramp-copy-size-limit (* 1024 1024)) ; 1MB + (tramp-use-scp-direct-remote-copying t) + (tramp-allow-unsafe-temporary-files t) + (tramp-file-name-with-method "doas") + (tramp-verbose 2) + (tramp-ssh-controlmaster-options + (concat "-o ControlPath=/tmp/ssh-ControlPath-%%r@%%h:%%p " + "-o ControlMaster=auto -o ControlPersist=yes")) + (tramp-use-connection-share nil) + :config + (connection-local-set-profile-variables + 'vps-profile + '((dired-listing-switches . "-Alh --full-time"))) + + (connection-local-set-profiles + '(:application tramp :machine "vps") + 'vps-profile) + + (connection-local-set-profile-variables + 'remote-profile + `((tramp-direct-async-process . t) + (vc-ignore-dir-regexp . ,(format "\\(%s\\)\\|\\(%s\\)" + vc-ignore-dir-regexp + tramp-file-name-regexp)))) + + (connection-local-set-profiles + '(:application tramp :protocol "ssh") + 'remote-profile) + + (with-eval-after-load 'compile + (remove-hook 'compilation-mode-hook #'tramp-compile-disable-ssh-controlmaster-options))) + +(use-package vc-hooks + :ensure nil + :config + (setq vc-handled-backends '(Git))) + +(use-package files + :ensure nil + :custom + (remote-file-name-inhibit-locks t) + (remote-file-name-inhibit-cache t) + (remote-file-name-inhibit-delete-by-moving-to-trash t)) + +(use-package treesit + :ensure nil + :custom + (treesit-language-source-alist + '((c "https://github.com/tree-sitter/tree-sitter-c") + (cpp "https://github.com/tree-sitter/tree-sitter-cpp") + (json "https://github.com/tree-sitter/tree-sitter-json") + (cmake "https://github.com/uyha/tree-sitter-cmake") + (python "https://github.com/tree-sitter/tree-sitter-python"))) + (treesit-font-lock-level 4) + (add-to-list 'major-mode-remap-alist (c-mode . c-ts-mode)) + (add-to-list 'major-mode-remap-alist (c++-m ode . c++-ts-mode)) + (add-to-list 'major-mode-remap-alist (json- mode . json-ts-mode)) + (add-to-list 'major-mode-remap-alist (pytho n-mode . python-ts-mode)) + :hook + (c-ts-mode . c-ts-mode-toggle-comment-style)) + +(use-package olivetti + :config + (add-hook 'org-mode-hook 'olivetti-mode) + (define-key cmmm/toggle-map (kbd "o") 'olivetti-mode) + (define-key cmmm/toggle-map (kbd "O") 'global-olivetti-mode)) + +(use-package hide-mode-line + :config + (define-key cmmm/toggle-map (kbd "m") 'hide-mode-line-mode) + (define-key cmmm/toggle-map (kbd "M") 'global-hide-mode-line-mode)) + +(use-package helpful + :custom + (help-window-select t) + :bind (:map help-map + ("o" . helpful-at-point)) + :init + (with-eval-after-load 'embark + (define-key embark-symbol-map (vector 'remap 'describe-symbol) 'helpful-symbol) + (let ((map embark-become-help-map)) + (define-key map (vector 'remap 'describe-function) 'helpful-callable) + (define-key map (vector 'remap 'describe-variable) 'helpful-variable) + (define-key map (vector 'remap 'describe-symbol) 'helpful-symbol) + (define-key map (vector 'remap 'describe-command) 'helpful-command))) + (add-hook 'helpful-mode-hook 'visual-line-mode) + (let ((map global-map)) + (define-key map (vector 'remap 'describe-function ) 'helpful-callable) + (define-key map (vector 'remap 'describe-variable ) 'helpful-variable) + (define-key map (vector 'remap 'describe-key ) 'helpful-key ) + (define-key map (vector 'remap 'describe-command ) 'helpful-command ) + (define-key map (vector 'Info-goto-emacs-command-node) 'helpful-function))) + +(use-package lorem-ipsum) + +(use-package crontab-mode) +(defun cmmm/crontab-e () + "Run `crontab -e' in a emacs buffer." + (interactive) + (with-editor-async-shell-command "crontab -e" nil nil "VISUAL")) +(define-key cmmm/application-map (kbd "c") 'cmmm/crontab-e) + +(add-hook 'comint-preoutput-filter-functions 'ansi-color-apply nil t) + +(use-package dashboard + :custom (dashboard-center-content t) + :config + (add-hook 'elpaca-after-init-hook #'dashboard-insert-startupify-lists) + (add-hook 'elpaca-after-init-hook #'dashboard-initialize) + (dashboard-setup-startup-hook)) + +(unload-feature 'eldoc t) +(setq custom-delayed-init-variables '()) +(defvar global-eldoc-mode nil) +(elpaca eldoc + (require 'eldoc) + (global-eldoc-mode)) +(use-package flymake + :after (eldoc)) +(use-package jsonrpc) +(use-package eglot + :after (eldoc) + :config + (defun cmmm/eglot-dissable-features () + (eglot-inlay-hints-mode -1) + (flymake-mode -1)) + :hook + (eglot-managed-mode . cmmm/eglot-dissable-features) + (c-mode . eglot-ensure) + (c++-mode . eglot-ensure)) + +(use-package orderless + :init + (setq orderless-component-separator + #'orderless-escapable-split-on-space) + :custom + (completion-styles '(orderless basic)) + (completion-category-defaults nil) + (completion-category-overrides '((file (styles partial-completion))))) + +(use-package simple-modeline + :init + (defun cmmm/move-modeline-to-header () + (setq-default header-line-format mode-line-format) + (setq-default mode-line-format nil)) + (defun cmmm/simple-modeline-segment-spacer () + " ") + :custom + (simple-modeline-segments '((simple-modeline-segment-modified + simple-modeline-segment-buffer-name + cmmm/simple-modeline-segment-spacer + simple-modeline-segment-major-mode + cmmm/simple-modeline-segment-spacer + simple-modeline-segment-position) + (simple-modeline-segment-input-method + simple-modeline-segment-vc + simple-modeline-segment-misc-info + simple-modeline-segment-process))) + :hook + (after-init . simple-modeline-mode) + (simple-modeline-mode . cmmm/move-modeline-to-header)) + +(use-package marginalia + :config + (marginalia-mode)) + +(use-package vertico + :init + (vertico-mode) + ;; (setq vertico-scroll-margin 0) + ;; (setq vertico-count 20) + ;; (setq vertico-resize t) + (vertico-multiform-mode) + :bind + (:map vertico-map + ("M-?" . minibuffer-completion-help) + ("M-RET" . minibuffer-force-complete-and-exit) + ("M-TAB" . minibuffer-complete)) + + :custom + (vertico-cycle t) + (vertico-multiform-categories + '((consult-grep buffer) + (imenu buffer) + (buffer) + ;; (file buffer) + ;; (project-file buffer) + (info-menu buffer) + (consult-org-heading buffer) + (consult-history buffer) + (consult-lsp-symbols buffer) + (consult-xref buffer) + (embark-keybinding buffer) + (consult-location buffer))) + (vertico-multiform-commands + '((telega-chat-with buffer) + (magit:--author flat) + ;; For some reason it doesn't have an info-menu + ;; category and also setting + ;; marginalia-command-categories doesn't help + ;; (org-roam-node-find buffer) + (Info-goto-node buffer) + (info-lookup-symbol buffer) + (Info-follow-reference buffer) + (consult-yank-pop buffer))) + :bind + (("s-s" . vertico-repeat)) + :hook + (minibuffer-setup . vertico-repeat-save) + :config + (advice-add + 'vertico--format-candidate :around + (lambda (orig cand prefix suffix index _start) + (let ((cand (funcall orig cand prefix suffix index _start))) + (concat + (if (= vertico--index index) + (propertize "ยป " 'face 'vertico-current) + " ") + cand)))) + + ;; TODO(cmmm): add monocle support + + (with-eval-after-load + 'minibuffer + (setq completion-in-region-function 'consult-completion-in-region))) + +(use-package consult + :init + (require 'em-hist) + :bind + (;; C-c bindings in `mode-specific-map' + ("C-c M-x" . consult-mode-command) + ("C-c h" . consult-history) + ("C-c k" . consult-kmacro) + ("C-c m" . consult-man) + ("C-c i" . consult-info) + ([remap Info-search] . consult-info) + ;; C-x bindings in `ctl-x-map' + ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("C-x b" . consult-buffer) ;; orig. switch-to-buffer + ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump + ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + ;; M-g bindings in `goto-map' + ("M-g e" . consult-compile-error) + ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings in `search-map' + ("M-s d" . consult-find) ;; Alternative: consult-fd + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history) ;; orig. previous-matching-history-element + :map eshell-hist-mode-map + ("M-r" . consult-history)) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook (completion-list-mode . consult-preview-at-point-mode) + :init + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key "M-.") + ;; (setq consult-preview-key '("S-" "S-")) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + ;; :preview-key "M-." + :preview-key '(:debounce 0.4 any)) + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; "C-+" + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + ) + +(use-package corfu + :custom + (corfu-min-width 60) + (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + (corfu-auto t) ;; Enable auto completion + (corfu-separator ?\s) ;; Orderless field separator + (corfu-preview-current nil) ;; Disable current candidate preview + (corfu-preselect 'prompt) ;; Preselect the prompt + (corfu-scroll-margin 2) ;; Use scroll margin + :init + (global-corfu-mode) + (corfu-echo-mode) + (corfu-history-mode) + :bind + (:map corfu-map + ("M-SPC" . corfu-insert-separator))) + +;; cloning failed -- busy +;; (use-package corfu-candidate-overylay) + +(use-package detached + :init + (detached-init) + :bind + (;; Replace `async-shell-command' with `detached-shell-command' + ([remap async-shell-command] . detached-shell-command) + ;; Replace `compile' with `detached-compile' + ;; For recompile buffer has to have session... bad + ;; ([remap compile] . detached-compile) + ;; ([remap recompile] . detached-compile-recompile) + ;; Replace built in completion of sessions with `consult' + ([remap detached-open-session] . detached-consult-session)) + :custom + (detached-init-block-list '(nano-modeline projectile)) + (detached-show-output-on-attach t) + (detached-terminal-data-command system-type) + (detached-metadata-annotators-alist '((branch . detached--metadata-git-branch))) + (detached-degraded-commands '("^ls "))) + +(use-package simple + :ensure nil + :custom + (display-fill-column-indicator-column 79) + :config + (indent-tabs-mode -1) + :hook + (prog-mode . display-fill-column-indicator-mode)) + +(use-package copyright + :ensure nil + :config + (setq copyright-names-regexp + (format "%s <%s>" user-full-name user-mail-address)) + (add-hook 'after-save-hook (lambda () (copyright-update nil nil)))) + +(use-package flyspell + :ensure nil + :config + (defun cmmm/flyspell-on-for-buffer-type + () + "Enable Flyspell appropriately for the major mode of the current\nbuffer. Uses `flyspell-prog-mode' for modes derived from `prog-mode',\nso only strings and comments get checked. All other buffers get\n`flyspell-mode' to check all text. If flyspell is already enabled,\ndoes nothing." + (if (not (symbol-value flyspell-mode)) + (progn (if (derived-mode-p 'prog-mode) + (progn (message "Flyspell on (code)") (flyspell-prog-mode)) + (progn (message "Flyspell on (text)") + (flyspell-mode 1)))))) + (defun cmmm/flyspell-toggle + () + "Turn Flyspell on if it is off, or off if it is on. When turning\non, it uses `flyspell-on-for-buffer-type' so code-vs-text is\nhandled appropriately." + (interactive) + (if (symbol-value flyspell-mode) + (progn (message "Flyspell off") (flyspell-mode -1)) + (cmmm/flyspell-on-for-buffer-type))) + (setq flyspell-consider-dash-as-word-delimiter-flag t) + (define-key global-map (kbd "C-c x s") 'cmmm/flyspell-toggle) + (add-hook 'telega-chat-mode-hook 'cmmm/flyspell-on-for-buffer-type) + (add-hook 'text-mode-hook 'cmmm/flyspell-on-for-buffer-type) + (add-hook 'prog-mode-hook 'cmmm/flyspell-on-for-buffer-type)) + +(use-package embark + :bind + (("s-." . embark-act) + ("s->" . embark-become) + :map embark-general-map + ("R n" . eglot-rename) + ("R g" . rg-project))) +(use-package embark-consult) + +(setq nobreak-char-display nil) + +(use-package trashed + :custom + (delete-by-moving-to-trash t)) + +(use-package page-break-lines + :custom + (page-break-lines-modes '(prog-mode conf-mode + compilation-mode outline-mode help-mode)) + :config + (global-page-break-lines-mode)) + +(use-package pdf-tools + :demand t + :hook (pdf-view-mode . pdf-view-themed-minor-mode) + :custom + ;; Enable seamless scrolling between pages + (pdf-view-continuous-scroll-mode t) + ;; Use normal Emacs keybindings for scrolling + (pdf-view-continuous-scroll-keystrokes nil) + (pdf-view-display-size 'fit-page) + (pdf-view-use-scaling t) + (pdf-view-resize-factor 1.025) + :config + ;; Initialize the package + (pdf-tools-install) + ;; Associate pdf-view-mode with PDF files + (add-to-list 'auto-mode-alist '("\\.[pP][dD][fF]\\'" . pdf-view-mode)) + (add-to-list 'magic-mode-alist '("%PDF" . pdf-view-mode)) + (with-eval-after-load 'saveplace + (require 'saveplace-pdf-view))) + +(use-package nov + :custom + (nov-text-width t) + :config + (add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode)) + (require 'justify-kp) + (defun cmmm/nov-window-configuration-change-hook () + (cmmm/nov-post-html-render-hook) + (remove-hook 'window-configuration-change-hook + 'cmmm/nov-window-configuration-change-hook + t)) + (defun cmmm/nov-post-html-render-hook () + (if (get-buffer-window) + (let ((max-width (pj-line-width)) + buffer-read-only) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (when (not (looking-at "^[[:space:]]*$")) + (goto-char (line-end-position)) + (when (> (shr-pixel-column) max-width) + (goto-char (line-beginning-position)) + (pj-justify))) + (forward-line 1)))) + (add-hook 'window-configuration-change-hook + 'cmmm/nov-window-configuration-change-hook + nil t))) + :hook + (nov-mode . olivetti-mode) + (nov-post-html-render-hook . cmmm/nov-post-html-render-hook)) + +(use-package vterm) +(use-package eat) + +(use-package telega + :custom + (telega-server-libs-prefix "/usr") + (telega-chat-fill-column 70) + (telega-open-file-function 'embark-open-externally) + (telega-open-message-as-file '(video audio voice-note animation video-note)) + :config + (defun cmmm/telega-chatbuf-attach-markdown2 () + (interactive) + (telega-chatbuf-attach-markup "markdown2")) + :bind + (:map cmmm/application-map + ("t" . telega) + :map telega-root-mode-map + ("s-B" . telega-chat-with) + :map telega-chat-mode-map + ("s-B" . telega-chat-with) + ("C-c C-m" . cmmm/telega-chatbut-attach-markdown2)) + :hook (telega-load-hook . telega-notifications-mode)) + +(use-package highlight-doxygen + :config + (highlight-doxygen-global-mode) + (set-face-background 'highlight-doxygen-comment nil)) + +(setq ispell-program-name "aspell") +(defun cmmm/ispell-change-dictionary-input-method + () + (ispell-change-dictionary + (pcase current-input-method-title + ("RU" "ru-yeyo") + ("SK" "sk")))) +(add-hook + 'input-method-activate-hook + 'cmmm/ispell-change-dictionary-input-method) +(add-hook + 'input-method-deactivate-hook + 'cmmm/ispell-change-dictionary-input-method) +;; (defun cmmm/sync-cursor-color () +;; (set-cursor-color (if current-input-method "orange" "white"))) +;; (add-hook 'post-command-hook 'cmmm/sync-cursor-color) + +(use-package multiple-cursors + :bind + (("C-S-c" . mc/edit-lines) + ("C->" . mc/mark-next-like-this) + ("C-<" . mc/mark-previous-like-this) + ("C-c C-S-c" . mc/mark-all-like-this) + ("C-\"" . mc/skip-to-next-like-this) + ("C-:" . mc/skip-to-previous-like-this))) + +(use-package expand-region + :bind + (("C-=" . er/expand-region))) + +(use-package move-text + :config + (define-key global-map (kbd "M-P") 'move-text-up) + (define-key global-map (kbd "M-N") 'move-text-down)) +(define-key global-map (kbd "C-'") 'duplicate-dwim) +(setq duplicate-line-final-position 1) + +(use-package hl-todo + :config + (global-hl-todo-mode 1)) + +(use-package ligature + :config + (ligature-set-ligatures + 't '("-<<" "-<" "-<-" "<--" "<---" "<<-" "<-" "->" "->>" "-->" "--->" "->-" ">-" ">>-" + "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>=" + "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__" + "<~~" "" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!=" + "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>" + "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "" "--->" "->-" ">-" ">>-" "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>=" "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__" "<~~" "" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!=" "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>" "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "