;; 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 '("-<<" "-<" "-<-" "<--" "<---" "<<-" "<-" "->" "->>" "-->" "--->" "->-" ">-" ">>-" "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>=" "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__" "<~~" "" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!=" "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>" "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "" "--->" "->-" ">-" ">>-" "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>=" "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__" "<~~" "" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!=" "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>" "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "