Skip to content

Latest commit

 

History

History
903 lines (784 loc) · 32.1 KB

config.org

File metadata and controls

903 lines (784 loc) · 32.1 KB

Here are some additional functions/macros that could help you configure Doom:

  • load! for loading external *.el files relative to this one
  • use-package! for configuring packages
  • after! for running code after a package has loaded
  • add-load-path! for adding directories to the `load-path’, relative to this file. Emacs searches the `load-path’ when you load packages with `require’ or `use-package’.
  • map! for binding new keys

!!! doom lisp demos

Variables

;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-

(setq
 ;; Some functionality uses this to identify you,
 ;; e.g. GPG configuration, email clients, file templates and snippets.
 user-full-name "earthian"
 user-mail-address "418@duck.com"

 org-directory "~/Documents/org/"
 fill-column 80
 display-fill-column-indicator-column 80
 better-jumper-context 'buffer
 default-input-method "russian-computer"
 browse-url-secondary-browser-function #'browse-url-xdg-open
 browse-url-generic-program #'eww
 projectile-project-search-path '(("~/git" . 3)))

Fonts:

;; 'pmsl nerd' - get all installed nerd fonts

(setq
 ;; firacode nerd font
 ;; saucecodepro nerd font - copy of source code pro but with better composite glyphs
 ;; hasklug nerd font
 ;; hack nerd font
 doom-font (font-spec :family "jetbrainsmono nf" :size 17) ;; :weight 'light
 ;; for text modes, like Zen, Org or Markdown.
 doom-variable-pitch-font (font-spec :family "daddytimemono nerd font" :size 17)
 ;; Cyrillyc fonts:
 ;; BellotaText-Regular.ttf -> ../.
 ;; Comfortaa-VariableFont_wght.ttf
 ;; PoiretOne-Regular.ttf
 ;; PressStart2P-Regular.ttf
 ;; ShantellSans-VariableFont_BNCE,
 ;; Unbounded-VariableFont_wght.ttf
 ;; Jura-VariableFont_wght.ttf -> ..
 ;; MontserratAlternates-Regular.ttf
 doom-unicode-font (font-spec :family "bellotatext") ;; Symbola
 doom-big-font (font-spec :family "jetbrainsmono nf" :size 24))

;; https://www.reddit.com/r/emacs/comments/8tz1r0/how_to_set_font_according_to_languages_that_i/
;; https://fonts.google.com/?script=Thai
;; Set decent default font for Thai and maybe some other langs in future
;; but *only* if in a graphical context.
;; Set the one language last glyphs of which should override others
;; when both charsets cover the same codepoints.
(when (fboundp #'set-fontset-font)
  (set-fontset-font t 'thai "Krub"))
(dolist (item '(("Krub" . 1.6)))
  (add-to-list 'face-font-rescale-alist item))

Hlissner:

;; https://github.com/hlissner/.doom.d

(setq
 ;; Line numbers are pretty slow all around. The performance boost of
 ;; disabling them outweighs the utility of always keeping them on.
 display-line-numbers-type nil
 doom-scratch-initial-major-mode 'org-mode ;; or lisp-interaction-mode
 ;; An evil mode indicator is redundant with cursor shape
 doom-modeline-modal nil)

Keybindings

describe-function map!

(map! :leader :desc "M-x" "x" 'execute-extended-command)

(map! :leader :desc "Find file other window" "f o" 'find-file-other-window)
(map! :leader :desc "Switch to true last buffer" "b o" 'sad-true-switch-last-buffer)

(define-key global-map (kbd "C-,") 'embark-act)

;; Workspace binds
(map! :leader :desc "Previous workspace" "-" '+workspace/other)
(map! :leader :desc "Workspace swap right" :n "TAB ]" '+workspace/swap-right)
(map! :leader :desc "Workspace swap left" :n "TAB [" '+workspace/swap-left)

;; diff-hl bindings
(map! :leader :desc "Git show hunk" "gv" 'diff-hl-show-hunk)
(map! :leader :desc "Git show hunk" "g{" 'diff-hl-show-hunk-previous)
(map! :leader :desc "Git show hunk" "g}" 'diff-hl-show-hunk-next)

;; Other packages
(map! :leader :desc "Ace window" "ww" 'ace-window)

Startup and Global modes

(global-subword-mode)
(global-auto-revert-mode)

Other settings

(add-hook 'markdown-mode-hook 'auto-fill-mode)
(add-hook 'prog-mode-hook 'display-fill-column-indicator-mode)
(add-hook 'pdf-view-mode-hook 'pdf-view-midnight-minor-mode)

(map! :leader "fl" (cmd! (consult-fd "/")))

(setq
 consult-fd-args '((if (executable-find "fdfind" 'remote) "fdfind" "fd")
                   "--color=never" "--full-path --absolute-path --follow" "--hidden --exclude .git"))

Custom f-s & advices

(defun advice--center-buffer (orig-fun &rest args)
  "Center butter."
  (evil-scroll-line-to-center (line-number-at-pos)))

(advice-add 'evil-ex-search :after #'advice--center-buffer)
(advice-add 'Info-next-reference :after #'advice--center-buffer)
(advice-add 'Info-prev-reference :after #'advice--center-buffer)

(defun sad-true-switch-last-buffer ()
  "Switch to REAL last open buffer (including buffers starting with *)."
  (interactive)
  (let ((previous-place (car (window-prev-buffers))))
    (when previous-place
      (switch-to-buffer (car previous-place))
      (goto-char (car (last previous-place))))))

;; --- vertico debugging
;; (setq debug-on-error t)

;; (defun force-debug (func &rest args)
;;   (condition-case e
;;       (apply func args)
;;     ((debug error) (signal (car e) (cdr e)))))

;; (advice-add #'vertico--exhibit :around #'force-debug)

Development

LSP

;; Disable invasive lsp-mode features
;; https://emacs-lsp.github.io/lsp-mode/tutorials/how-to-turn-off/
(setq
 ;; lsp-ui-sideline-enable nil   ; not anymore useful than flycheck
 lsp-ui-doc-enable nil)        ; slow and redundant with K

(map! :map lsp-mode-map :leader
      ;; another option is xref-find-definition-other-window
      :desc "Find def other window" :n "c O" 'godef-jump-other-window
      :desc "Inlay hints mode" :n "c I" 'lsp-inlay-hints-mode)

Golang

;; https://github.com/golang/tools/blob/master/gopls/doc/settings.md
(after! go-mode
  (setq
   gofmt-command "golines"
   gofmt-args '("-m" "80"))
  ;; (add-hook 'go-mode-hook #'flymake-golangci-load-backend)
  (add-hook 'go-mode-hook
            (lambda () (add-hook 'before-save-hook 'gofmt-before-save)))
  (map! :map go-mode-map :localleader :n "z" 'dap-breakpoint-toggle))

(after! lsp-mode
  ;; https://github.com/golang/tools/blob/master/gopls/doc/settings.md
  (lsp-register-custom-settings
   '(("gopls.completeUnimported" t t)
     ;; ("gopls.vulncheck" "imports")
     ("gopls.usePlaceholders" t t)
     ("gopls.hints.assignVariableTypes" t t)
     ("gopls.hints.compositeLiteralFields" t t)
     ("gopls.staticcheck" t t))))
     ;; NOTE: setting passed args here doesn't work for some reason
     ;; ("golangci-lint.command" ["golangci-lint" "run" "--out-format=json" "--show-stats=false" "--issues-exit-code=0"])))

  ;; (setq lsp-golangci-lint-run-args '("--out-format=json" "--show-stats=false" "--issues-exit-code=0"))

  ;; (lsp-register-client
  ;;  (make-lsp-client :new-connection (lsp-stdio-connection
  ;;                                    '("golangci-lint-langserver"))
  ;;                   :major-modes '(go-mode)
  ;;                   ;; :activation-fn (lsp-activate-on "go")
  ;;                   :language-id "go"
  ;;                   :priority 0
  ;;                   :server-id 'golangci-lint
  ;;                   :add-on? t
  ;;                   :library-folders-fn #'lsp-go--library-default-directories
  ;;                   :initialization-options (lambda ()
  ;;                                             (gethash "golangci-lint"
  ;;                                                      (lsp-configuration-section "golangci-lint"))))))

SQL

(setq sqlformat-command 'pgformatter)
;; Optional additional args
(setq sqlformat-args '("-s2" "-f2" "-w80" "--no-space-function"))
(add-hook 'sql-mode-hook 'sqlformat-on-save-mode)

KILL JS

(push '(rjsx-mode . typescript-mode) major-mode-remap-alist)

Shell

(after! sh-script
  (setq! sh-shellcheck-arguments '("-x"))

  (set-formatter! 'shfmt
    ;; "-ci" for case-indent is the only difference from default formatter
    '("shfmt" "-filename" filepath "-ci" "-ln"
      (cl-case (bound-and-true-p sh-shell) (sh "posix") (t "bash"))
      (when apheleia-formatters-respect-indent-level
        (list "-i"
              (number-to-string
               (cond (indent-tabs-mode 0)
                     ((boundp 'sh-basic-offset) sh-basic-offset) (t 4)))))))
  (add-hook! 'sh-mode-hook
    (setq
     apheleia-formatter 'shfmt
     ;; want 'remote' only for sh files cuz that's how emacs handles root files
     apheleia-remote-algorithm 'local)))

Magit & forge

Magit:

(setq
 ;; Don't restore the wconf after quitting magit, it's jarring
 magit-inhibit-save-previous-winconf t
 ;; This will enable gravatars when viewing commits.
 ;; The service used by default is Libravatar.
 magit-revision-show-gravatars '("^Author:     " . "^Commit:     "))

Forge:

;; my attempts to make forge work with custom gitlab url...
;; did not suffice elisp knowledge to do that (not all forge functions were working..)
(after! forge
  (push '("gitlab.medpoint24.ru" "gitlab.medpoint24.ru/api/v4"
          "gitlab.medpoint24.ru" forge-gitlab-repository) forge-alist))

Docker

(setq! docker-command "podman"
       docker-container-shell-file-name "/bin/zsh")

Doom dashboard

;; (setq fancy-splash-image (concat doom-private-dir "splash.png"))
;; Hide the menu for as minimalistic a startup screen as possible.
(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)

(setq +doom-dashboard-functions
      '(doom-dashboard-widget-banner doom-dashboard-widget-loaded))

Elfeed

(setq
 rmh-elfeed-org-files '("~/Documents/rss/elfeed.org")
 elfeed-db-directory "~/Documents/rss/db"
 ;; "@6-month-ago +unread" will show only unread ones
 ;; and thats how you add tags to filter string
 elfeed-search-filter "@6-month-ago")

(map! :leader
      :prefix ("r" . "RSS")
      "o" #'=rss
      "r" #'elfeed-update
      "l" #'elfeed-goodies/toggle-logs
      "e" #'sad/elfeed-org-export-opml
      "u" #'elfeed-show-tag--unread)

;; maybe call this func in 'elfeed-new-entry-hook', but for now manually
(defun sad/elfeed-org-export-opml ()
  "Export Org feeds under `rmh-elfeed-org-files' to an OPML file."
  (interactive)
  (let ((opml-body (cl-loop for org-file in rmh-elfeed-org-files
                            concat
                            (with-temp-buffer
                              (insert-file-contents
                               (expand-file-name org-file org-directory))
                              (rmh-elfeed-org-convert-org-to-opml
                               (current-buffer))))))
    (with-temp-file "~/Documents/rss/elfeed.opml"
      (insert "<?xml version=\"1.0\"?>\n")
      (insert "<opml version=\"1.0\">\n")
      (insert "  <head>\n")
      (insert "    <title>Elfeed-Org Export</title>\n")
      (insert "  </head>\n")
      (insert "  <body>\n")
      (insert opml-body)
      (insert "  </body>\n")
      (insert "</opml>\n"))))

Emms

(after! emms
  (add-to-list 'emms-player-list 'emms-player-mpd)
  (add-to-list 'emms-info-functions 'emms-info-mpd)
  (add-hook 'emms-player-started-hook #'emms-mpris-enable)
  (add-hook 'emms-player-stopped-hook #'emms-mpris-disable)
  (setq!
   emms-source-file-default-directory "~/Music"
   emms-player-mpd-music-directory "~/Music"
   emms-source-playlist-default-format 'm3u
   emms-info-native--max-vorbis-comment-size 150000
   emms-repeat-playlist t
   emms-playlist-mode-center-when-go t
   emms-show-format "♪ %s"
   emms-browser-default-browse-type 'info-album
   ;; new settings
   ;; covers
   emms-browser-covers #'emms-browser-cache-thumbnail-async
   emms-browser-thumbnail-small-size 32
   emms-browser-thumbnail-medium-size 64))

;; run the 'emms-cache-set-from-mpd-all' to fill the Emms cache with the
;; contents of your MusicPD database. The music in your MusicPD database should
;; then be accessible via the Emms browser.

(map! :leader
      (:prefix ("l" . "listen")

       ;; Playback
       :desc "Current playlist buffer" "c" #'emms
       :desc "Pause" "x" #'emms-pause
       :desc "Stop" "X" #'emms-stop
       :desc "Next" "n" #'emms-next
       :desc "Previous" "p" #'emms-previous
       :desc "Shuffle" "S" #'emms-shuffle
       :desc "Loop playlist (toggle)" "L" #'emms-toggle-repeat-playlist
       ;; :desc "Loop track (toggle)" "L" #'emms-toggle-repeat-track
       ;; :desc "Browser / open close" "b" #'emms-smart-browse
       ;; :desc "Bury emms buffers" "q" #'emms-browser-bury-buffer

       ;; Daemon / db bindings
       :desc "Start daemon" "s" #'+emms/mpd-start-music-daemon
       :desc "Restart daemon" "r" #'+emms/mpd-restart-music-daemon
       ;; call this manually for the newly added tracks to show up in emms
       :desc "Update db" "u" #'+emms/mpc-update-database ;; gets called on 'start'
       :desc "Update all + cache" "R" #'emms-player-mpd-update-all-reset-cache

       ;; Play ...
       (:prefix ("l" . "Play")
        :desc "directory" "d" #'emms-play-directory
        :desc "directory tree" "D" #'emms-play-directory-tree
        :desc "files matching regex" "f" #'emms-play-find
        :desc "file" "F" #'emms-play-file
        :desc "url (ie for streaming)" "u" #'emms-play-url)))

Evil

(setq
 ;; Focus new window after splitting
 evil-split-window-below t
 evil-vsplit-window-right t
 evil-want-C-u-delete nil)

;; Evil digraph
(map! :leader
      (:prefix ("d" . "digraph")
       :desc "Insert COUNT digraphs" "i" 'evil-insert-digraph
       :desc "Shows a list of all available digraphs" "s" 'evil-ex-show-digraphs
       :desc "Read two keys from keyboard forming a digraph" "r" 'evil-read-digraph-char))

Ewal

  • [ ] package is abandoned, some time in the future clone it and rewrite to your needs
  • [ ] any way to make all colors brighter? not contrasty, but just brighter
(use-package! ewal
  :init
  (setq
   ewal-use-built-in-always-p nil
   ewal-use-built-in-on-failure-p t
   ewal-shade-percent-difference 20)
  :config
  (load-theme 'ewal-doom-one t) ;; ewal-doom-vibrant-theme
  (enable-theme 'ewal-doom-one)
  (ewal-evil-cursors-get-colors :apply t))

Eww

(map! :leader :desc "Web Wowser" "oe" 'eww) ;; from within eww its just 'o'

(setq! +lookup-open-url-fn #'eww)

(after! eww
  (setq!
   ;; make emacs always use its own browser for opening URL links
   browse-url-browser-function 'eww-browse-url
   eww-search-prefix "https://www.google.com/search?q="
   eww-bookmarks-directory "~/Documents/it/"
   eww-history-limit 500
   eww-auto-rename-buffer 'title)

  (map! :leader "ge" #'eww-switch-to-buffer)

  (map! :map eww-text-map "TAB" nil "<backtab>" nil)
  (map! :map eww-textarea-map "TAB" nil "<backtab>" nil)
  (map! :map shr-map "TAB" nil "<backtab>" nil)

  (map! :map eww-mode-map
        ;; don't need all windows closing
        [remap quit-window] #'quit-window
        :nv "C-k" #'shrface-previous-headline
        :nv "C-j" #'shrface-next-headline
        :n "<tab>" #'shrface-outline-cycle
        :n "<backtab>" #'shrface-outline-cycle-buffer)

  (map! :map eww-buffers-mode-map
        :n "C-k" #'eww-buffer-show-previous
        :n "C-j" #'eww-buffer-show-next)

  (map! :map eww-mode-map :localleader
        :n "y" #'eww-copy-page-url
        :n "r" #'eww-reload
        :vn "s" #'eww-search-words
        :n "l" #'shrface-links-consult
        :n "L" #'+eww/jump-to-url-on-page
        :n "." #'shrface-headline-consult
        ;; different from 'headline-consult' since uses separate buffer
        :n "h" #'shrface-occur))

(after! dash-docs (setq dash-docs-browser-func #'eww))

Shrface

;; (add-hook 'eww-after-render-hook #'org-indent-mode) ;; FIXME
(add-hook 'eww-mode-hook #'shrface-mode)
(add-hook 'mu4e-view-mode-hook (lambda () (progn)
                                       (require 'eww)
                                       (shrface-mode)))

(after! shrface
  ;; (unless shrface-toggle-bullets
  ;;   (shrface-regexp)
  ;;   (setq-local imenu-create-index-function #'shrface-imenu-get-tree)))
  (require 'shr-tag-pre-highlight)
  (add-hook 'outline-view-change-hook 'shrface-outline-visibility-changed)
  (setq!
   shr-max-width 100
   shr-cookie-policy nil
   ;; shr-width 65
   shr-indentation 3
   tab-width 2
   ;; shrface-toggle-bullets nil
   shr-use-fonts nil
   shrface-href-versatile t

   shr-external-rendering-functions (append '((title . eww-tag-title)
                                              (form . eww-tag-form)
                                              (input . eww-tag-input)
                                              (button . eww-form-submit)
                                              (textarea . eww-tag-textarea)
                                              (select . eww-tag-select)
                                              (link . eww-tag-link)
                                              (meta . eww-tag-meta)
                                              ;; (a . eww-tag-a)
                                              (code . shrface-tag-code)
                                              (pre . shr-tag-pre-highlight))
                                            shrface-supported-faces-alist)))

Golden-ratio

(use-package! golden-ratio
  :init
  (golden-ratio-mode)
  :config
  (setq! golden-ratio-extra-commands
         '(windmove-left windmove-right windmove-down windmove-up evil-window-up
           evil-window-down evil-window-right evil-window-left)
         golden-ratio--value 1.95
         golden-ratio-exclude-buffer-regexp '("^\\*")
         golden-ratio-exclude-modes '(dired-mode image-mode))) ;; otherwise emacs hangs

WAIT IRC

(map! :leader :desc "IRC" "oi" '=irc)

;; if you omit =:host=, ~SERVER~ will be used instead.
(after! circe
  (setq circe-default-part-message "(⌣_⌣”)"
        circe-default-quit-message "o/")

  ;; view 'circe-network-defaults' var to view predefined networks
  (setq circe-network-options
    `(("Libera Chat"
       :nick "earthian"
       :sasl-username ,(+pass-get-user "social/irc/libera.chat")
       :sasl-password ,(+pass-get-secret "social/irc/libera.chat"))
       ;; :channels ("#emacs" "#systemcrafters"))
      ("OFTC"
       :nick "earthian"
       :sasl-username ,(+pass-get-user "social/irc/libera.chat")
       :sasl-password ,(+pass-get-secret "social/irc/libera.chat")))))
       ;; :channels ("#emacs" "#systemcrafters")))))

  ;; in case circe will start supporting DCC
  ;; (set-irc-server! "irc.undernet.org"
  ;;   `(;; :tls t
  ;;     :port 6667
  ;;     :nick "seme4eg"
  ;;     :channels ("#ebooks" "#Bookz")
  ;;     ))
  ;; (set-irc-server! "irc.irchighway.net"
  ;;   `(:port 6669
  ;;     :nick "seme4eg"
  ;;     :channels ("#ebooks")
  ;;     ))

;; TODO: write a function to upload image to 0x0 from a clipboard
;; (use-package! 0x0)

Langtool

(after! langtool
  (setq langtool-default-language "ru-RU"
        langtool-disabled-rules '(
                                  "Many_PNN"
                                  "OPREDELENIA"
                                  "talk"
                                  "DoubleNOT"
                                  "COMMA_DEFIS"
                                  "UPPERCASE_SENTENCE_START"
                                  "DOUBLE_PUNCTUATION"
                                  "DoubleIH"
                                  "LICHNO_JA")))
;; langtool-disabled-rules '("DOUBLE_PUNCTUATION[1] premium: false" "Many_PNN[1] premium: false prio=-50")))
(map! :leader
    :prefix ("y" . "langtool")
    "." #'langtool-show-message-at-point
    "," #'langtool-show-brief-message-at-point
    "c" #'langtool-check
    "b" #'langtool-check-buffer
    "f" #'langtool-correct-buffer ;; fix fix fix
    "s" #'langtool-check-done
    "[" #'langtool-goto-previous-error
    "]" #'langtool-goto-next-error)

Mu4e

(load-file "~/.config/doom/mu4e.el")

Org

(defun org-iscroll-setup ()
  "Set up iscroll mode and keybindings for iscroll in org mode."
  (iscroll-mode)
  (map! :n "C-n" (cmd! (iscroll-up 1))
        :n "C-p" (cmd! (iscroll-down 1))))

(add-hook 'org-mode-hook
          (lambda () (progn
                       (org-iscroll-setup)
                       (auto-fill-mode)
                       (map! :map evil-org-mode-map
                             :vmn "gl" 'evil-lion-left)))) ;; don't override that

(after! org
  (map! :map org-mode-map
        :localleader
        :n "bS" 'org-table-shrink
        :n "bE" 'org-table-expand
        :n "bts" 'org-table-toggle-column-width)

  (set-popup-rule! "^\\*Org Src" :ignore t)
  (setq
   ;; show files like TOC on startup
   org-startup-folded 'content
   org-hide-block-startup t
   org-startup-shrink-all-tables t
   org-id-link-to-org-use-id 'create-if-interactive-and-no-custom-id
   org-hide-emphasis-markers t)

  (add-to-list 'org-capture-templates '("t" "Tea entry" entry
                                        (file +org-capture-project-notes-file)
                                        "%[~/git/tea/template]"
                                        :jump-to-captured t
                                        :clock-in t
                                        :clock-keep t
                                        :empty-lines 1))

  ;; now after typing 'C-c C-,' u will will get a new option to chose from
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp\n")))

Popup

  • see doom package readme, but here is settings example
  • current popup settings see in display-buffer-alist var
(set-popup-rules!
  '(("^\\*eww" :ignore t)
    ("^\\*helpful" :ignore t) ;; Any way to open helpful buffers on top of each other?
    ("^\\*\\(?:Wo\\)?Man " :ignore t)
    ("^\\*info\\*$" :ignore t)))

Casual Suite

;; (require 'casual-suite)
;; (map! :map reb-mode-map :n "," #'casual-re-builder-tmenu)

;; (keymap-set ibuffer-mode-map "F" #'casual-ibuffer-filter-tmenu)
;; (keymap-set ibuffer-mode-map "s" #'casual-ibuffer-sortby-tmenu)

Dired + Dirvish

(remove-hook 'dired-mode-hook #'dired-omit-mode)
(after! dirvish
  (setq dirvish-hide-details t
        dirvish-default-layout '(0 0 0.55))
  (map! :leader "sf" #'dirvish-fd-jump)
  (map! :map dirvish-mode-map
        :n "," #'dirvish-dispatch
        :n "?" #'dirvish-fd-switches-menu
        :n "s" #'dirvish-total-file-size))
(setq! proced-tree-flag t
       proced-auto-update-flag t
       proced-enable-color-flag t
       proced-format 'medium
       proced-auto-update-interval 1
       proced-format-alist
       '((short user pid tree pcpu pmem start time (args comm))
         (medium user pid tree pcpu pmem vsize rss ttname state start time comm)
         (long
          user euid group pid tree pri nice pcpu pmem vsize rss ttname state
          start time comm)
         (verbose
          user euid group egid pid ppid tree pgrp sess pri nice pcpu pmem state
          thcount vsize rss ttname tpgid minflt majflt cminflt cmajflt start time
          utime stime ctime cutime cstime etime comm)))

Syntax + flymake

(after! flymake
  (setq flymake-popon-method (if (modulep! :checkers syntax +childframe)
                                 'postframe
                               'popon)
        flymake-popon-width 75)
  (map! :n "]e" #'flymake-goto-next-error)
  (map! :n "[e" #'flymake-goto-prev-error)
  (map! :leader :prefix ("v" . "syntax")
        "l" #'consult-flymake
        "P" #'flymake-show-project-diagnostics
        "x" #'flymake-proc-stop-all-syntax-checks))

Telega

(map! :leader "o c" 'telega)
(setq telega-server-libs-prefix "/usr") ;; cuz aur package installs there
(map! :after telega :leader
      :prefix ("z" . "telegram")
      "a" #'telega-account-switch
      "b" #'telega-switch-buffer
      "c" #'telega-chat-with
      "S" #'telega-chatbuf-attach-scheduled
      "f" #'telega-buffer-file-send
      "s" #'telega-saved-messages
      "t" #'telega
      "z" #'telega-translate-region
      "u" #'telega-switch-unread-chat)

(map! :after telega :map telega-msg-button-map
      "D" #'telega-msg-delete-dwim)

(after! telega
  (telega-notifications-mode)
  (telega-mode-line-mode)
  (global-telega-squash-message-mode)
  ;; (telega-image-mode) ;; n/p next prev img in chat
  (auto-fill-mode)

  (require 'telega-dired-dwim)

  ;; eval-buffer: Cannot open load file: No such file or directory, dashboard
  ;; (require 'telega-dashboard)
  ;; (add-to-list 'dashboard-items '(telega-chats . 5))

  (setq
   telega-database-dir (expand-file-name "~/.local/share/telega")
   telega-directory (expand-file-name "~/.local/share/telega")
   telega-temp-dir (expand-file-name "~/.local/share/telega/temp")
   telega-cache-dir (expand-file-name "~/.local/share/telega/cache")
   telega-voip-logfile (expand-file-name "~/.local/share/telega/telega-voip.log")
   telega-server-logfile (expand-file-name "~/.local/share/telega/telega-server.log")
   telega-completing-read-function #'completing-read
   telega-notifications-delay 1
   ;; to not get notified on outgoing messages form phone
   telega-notifications-msg-temex '(and (not outgoing) (call telega-notifications-msg-notify-p))
   telega-notifications-timeout 3600 ;; crutch basically
   telega-url-shorten-use-images t
   telega-translate-to-language-by-default "ru"
   telega-video-player-command '(concat "mpv"
                                 (when telega-ffplay-media-timestamp
                                   (format "%f" telega-ffplay-media-timestamp))))


  (add-hook 'telega-chat-mode-hook
            (lambda ()
              (define-key telega-msg-button-map (kbd "SPC") nil)
              (setq truncate-lines nil
                    visual-fill-column-extra-text-width '(0 . 2)))))

GPTel #gh

Here are some unbound bindings in case you ever decide to go heavier on org-gptel integration:

  • gptel-org-set-topic - Store the active gptel topic and limit conversation to it
  • gptel-org-set-properties - Store the active gptel configuration under the current heading.
  • gptel-end-of-response - Move point to the end of the LLM response ARG times.
  • gptel-beginning-of-response - Move point to the beginning of the LLM response ARG times.

RET not working - user C-m - karthink/gptel#75

(use-package! gptel
  :config
  (map! :leader
        :prefix ("e" . "gptel")
        "e" #'gptel
        "r" #'gptel-rewrite-menu ;; Rewrite or refactor text region using an LLM
        "a" #'gptel-add ;; Add/remove regions or buffers from gptel’s context
        "f" #'gptel-add-file ;; Add files to gptel’s context.
        ;; if region selected send region otherwise whole buf up from the cursor
        "s" #'gptel-send
        "m" #'gptel-menu
        "M" #'gptel-mode)

  ;; :key can be a function that returns the API key.
  (gptel-make-gemini "Gemini"
    :key (+pass-get-secret "apikeys/gemini")
    :stream t)

  (add-hook 'gptel-mode-hook (lambda () (setq gptel-api-key (+pass-get-secret "apikeys/openai"))))

  (setq! gptel-default-mode 'org-mode
         gptel-model 'gpt-4o))
         ;; gptel-api-key (+pass-get-secret "apikeys/openai")))

Corfu #gh

NOTE: transfer completion to minibuffer

Using Vertico , one could use this to export with doom-package:embark via C-c C-l and get a buffer with all candidates.

(after! corfu
  (remove-hook 'corfu-mode-hook #'corfu-history-mode)
  (setq
   ;; Configures startup selection, choosing between the first candidate or the prompt.
   corfu-preselect 'first
   corfu-sort-function nil
   ;; fix of memory leak on child-frames on pgtk emacs
   corfu-popupinfo-resize nil

   ;; corfu-info ;; Actions to access the candidate location and documentation
   corfu-auto nil ;; disable idle (as-you-type) completion
   ;; corfu-popupinfo-mode ;; C-h below does same but manually
   ;; corfu-echo-mode
   corfu-history-mode nil

   +corfu-want-ret-to-confirm t) ;; prompt is in doom

  (let ((cmds-ret
         `(menu-item "Insert completion DWIM" corfu-insert
           :filter ,(lambda (cmd)
                      (cond
                       ((null +corfu-want-ret-to-confirm)
                        (corfu-quit)
                        nil)
                       ((eq +corfu-want-ret-to-confirm 'minibuffer)
                        (funcall-interactively cmd)
                        nil)
                       ((and (or (not (minibufferp nil t))
                                 (eq +corfu-want-ret-to-confirm t))
                             (>= corfu--index 0))
                        cmd)
                       ((or (not (minibufferp nil t))
                            (eq +corfu-want-ret-to-confirm t))
                        nil)
                       (t cmd))))))

    ;; "C-u" (cmd! (let (corfu-cycle)
    ;; (funcall-interactively #'corfu-next (- corfu-count)))))))

    (map! :map corfu-map
          :nvi "SPC" #'corfu-insert-separator
          "C-g" (lambda () (progn (corfu-reset)
                                  (corfu-quit))))))

WAIT Colemak

(use-package! evil-colemak-basics
  :after evil
  :init
  (setq evil-colemak-basics-layout-mod 'mod-dh) ;; swap h and m
  :config
  (global-evil-colemak-basics-mode))

;; hjkl
;; mnei
;; (defun my-hjkl-rotation (_mode mode-keymaps &rest _rest)
;;   ;; (evil-collection-translate-key '(normal motion visual operator) mode-keymaps
;;   (evil-collection-translate-key 'normal mode-keymaps
;;     "m" "h"
;;     "n" "j"
;;     "e" "k"
;;     "i" "l"
;;     "h" "m"
;;     "j" "e"
;;     "k" "n"
;;     "l" "i"
;;     (kbd "C-n") (kbd "C-j")
;;     (kbd "C-e") (kbd "C-k")
;;     "gn" "gj"
;;     "ge" "gk"
;;     :destructive nil))

;; called after evil-collection makes its keybindings
;; (add-hook! 'evil-collection-setup-hook #'my-hjkl-rotation)
;; (add-hook 'evil-collection-setup-hook #'my-hjkl-rotation)
;; (evil-collection-init)

WAIT Elm

(after! elm-mode
  (add-hook 'elm-mode-hook 'elm-format-on-save-mode))

NO Elcord #gh

Removed cuz its just a fancy-dandy useless stuff + armcord rich presence isn’t working 80% of the time + moved to different dis client.

(elcord-mode)
(setq!
 elcord-idle-message "Brewing tea ..."
 elcord-editor-icon "emacs_material_icon")
;; ignore all telega stuff
(add-to-list 'elcord-boring-buffers-regexp-list "")
(add-to-list 'elcord-boring-buffers-regexp-list  "\\\\*Telega Root\\\\*")