Berezhnev’s GNU Emacs config
File structure of files
.
├── images
│ ├── black-hole-2.png
│ ├── black-hole.png
│ ├── emacs-e-medium.png
│ ├── emacs-e.png
│ ├── emacs-e-small.png
│ └── RMS.png <~ Best photo ever.
├── local-packages
│ └── company-go.el
├── README.org <~ All settings with comments
├── init.el <~ Main init file
├── example.org <~ For Org preview testing
├── sound.wav <~ Bing sound for Org pomodoro
Setting base of Emacs
Window
(eval-when-compile (defvar display-time-24hr-format t))
(eval-when-compile (defvar display-time-default-load-average nil))
(display-battery-mode t) ;; Show battery.
(display-time-mode t) ;; Show time.
(set-fringe-mode 1) ;; Give us some space.
(delete-selection-mode nil) ;; Use a more sane delete mode than evil.
(fset 'yes-or-no-p 'y-or-n-p) ;; Set yes or no to y/n
(global-font-lock-mode 1) ;; always highlight code
(global-auto-revert-mode 1) ;; refresh a buffer if changed on disk
;; (global-hl-line-mode 1) ;; Highlight current line
(semantic-mode 1) ;; help out with semantics
(savehist-mode 1) ;; Save history
(save-place-mode 1) ;; when buffer is closed, save the cursor position
;; (blink-cursor-mode 1)
;; Setup fonts
(set-face-attribute 'default nil :font "JetBrainsMono Nerd Font Mono" :height 130)
(set-face-attribute 'fixed-pitch nil :font "JetBrainsMono Nerd Font Mono")
(set-face-attribute 'variable-pitch nil :font "Iosevka Aile" :height 150)
(variable-pitch-mode t)
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq-default shell-file-name "/usr/bin/fish")
(setq ad-redefinition-action 'accept
default-buffer-file-coding-system 'utf-8
blink-cursor-interval 0.7 ;; Little slower cursor blinking . default is 0.5
create-lockfiles nil
idle-update-delay 1.2 ;; Speed things up by not updating so often
read-process-output-max (* 8 1024 1024)
ediff-split-window-function 'split-window-horizontally
highlight-nonselected-windows t
auto-mode-case-fold nil
backup-by-copying t
byte-compile-warnings '(ck-functions)
confirm-kill-processes nil
fast-but-imprecise-scrolling t
jit-lock-defer-time 0.0
echo-keystrokes 0.2
kill-buffer-query-functions nil ;; Dont ask for closing spawned processes
line-number-mode nil
use-dialog-box nil
load-prefer-newer t
word-wrap nil
visible-bell nil
bidi-display-reordering nil
large-file-warning-threshold nil ;; Disable "File is large. Really open?"
x-stretch-cursor t ;; stretch cursor on tabs
scroll-margin 4 ;; scroll N to screen edge
undo-limit 6710886400 ;; 64mb
undo-strong-limit 100663296 ;; x 1.5 (96mb)
undo-outer-limit 1006632960) ;; x 10 (960mb), (Emacs uses x100), but this seems too high.
Emacs blur (toggle)
;;________________________________________________________________
;; Transparent Emacs
;;________________________________________________________________
(set-frame-parameter (selected-frame) 'alpha '(85 . 50))
(add-to-list 'default-frame-alist '(alpha . (85 . 50)))
;; (set-frame-parameter (selected-frame) 'alpha '(<active> . <inactive>))
;; (set-frame-parameter (selected-frame) 'alpha <both>)
;; Use the following snippet after you’ve set the alpha as above to assign a toggle to “C-c t”:
(defun toggle-transparency ()
"Crave for transparency!"
(interactive)
(let ((alpha (frame-parameter nil 'alpha)))
(set-frame-parameter
nil 'alpha
(if (eql (cond ((numberp alpha) alpha)
((numberp (cdr alpha)) (cdr alpha))
;; Also handle undocumented (<active> <inactive>) form.
((numberp (cadr alpha)) (cadr alpha)))
100)
'(85 . 50) '(100 . 100)
))))
(global-set-key (kbd "C-c t b") 'toggle-transparency)
Import local files
(use-package go-mode :ensure t)
(use-package company :ensure t)
;; (load "~/.emacs.d/local-packages/epubmode")
;; (require 'epubmode)
;; (load "~/.emacs.d/local-packages/company-go")
;; (require 'company-go)
;; (load "~/.emacs.d/local-packages/chep-video")
;; (require 'chep-video)
;; (load "~/.emacs.d/local-packages/dired+")
;; (require 'dired+)
;; (load "~/.emacs.d/local-packages/nov")
;; (require 'nov)
;; (use-package nov :ensure t)
;;(add-to-list 'load-path "~/.emacs.d/local-themes/catppucin-macchiato-theme")
Integrate clipboard with X11 (Need for Emacs TTY)
(use-package xclip
:ensure t)
(xclip-mode 1)
Share clipoard with OS
(use-package pbcopy
:ensure t)
Disable backup and auto save
;; Disable backup
(setq backup-inhibited t)
;; Disable auto save
(setq auto-save-default nil)
Pixelwise for frames
(setq frame-resize-pixelwise t)
(dotimes (n 3)
(toggle-frame-maximized))
Disable Messages and Completions buffers
(setq-default message-log-max nil)
(kill-buffer "*Messages*")
(add-hook 'minibuffer-exit-hook
'(lambda ()
(let ((buffer "*Completions*"))
(and (get-buffer buffer)
(kill-buffer buffer)))))
(setq initial-major-mode (quote fundamental-mode))
Intefrace disablings
(scroll-bar-mode -1) ; Disable visible scrollbar
(tool-bar-mode -1) ; Disable the toolbar
(tooltip-mode -1) ; Disable tooltips
(set-fringe-mode 10) ; Give some breathing room
(menu-bar-mode -1) ; Disable the menu bar
Setting line numbers
(global-display-line-numbers-mode t)
(use-package display-line-numbers
;;:straight nil
:hook (prog-mode . display-line-numbers-mode)
:custom
(setq display-line-numbers-type 'relative)
(display-line-numbers-width 4)
(display-line-numbers-grow-only t)
(display-line-numbers-width-start t))
Setting font face
Setting fonts
(set-face-attribute 'default t
:font "Iosevka" ;; Terminess Nerd Font Propo, Input, Terminess Nerd Font Propo
:height 100
:weight 'regular
)
(set-face-attribute 'variable-pitch nil
:font "Iosevka"
:height 100
:weight 'medium
)
(set-face-attribute 'fixed-pitch nil
:font "Iosevka"
:height 100
:weight 'medium
)
(set-frame-font "Iosevka" nil t)
;; Makes commented text and keywords italics.
;; This is working in emacsclient but not emacs.
;; Your font must have an italic face available.
(set-face-attribute 'font-lock-comment-face nil
:slant 'italic)
(set-face-attribute 'font-lock-keyword-face nil
:slant 'italic)
;; Uncomment the following line if line spacing needs adjusting.
(setq-default line-spacing 0.12)
;; Needed if using emacsclient. Otherwise, your fonts will be smaller than expected.
(add-to-list 'default-frame-alist '(font . "Iosevka 11"))
;; (add-to-list 'default-frame-alist
;; '(font . "DejaVu Sans Mono-11"))
(add-to-list 'default-frame-alist '(font . "Iosevka"))
;; changes certain keywords to symbols, such as lamda!
(setq global-prettify-symbols-mode t)
Setting and installing themes
(use-package gruvbox-theme
:ensure t)
(use-package doom-themes
:ensure t
;; :config
;; Global settings (defaults)
;; (setq doom-themes-enable-bold t ; if nil, bold is universally disabled
;; doom-themes-enable-italic t) ; if nil, italics is universally disabled
;; Enable flashing mode-line on errors
;; (doom-themes-visual-bell-config)
;; or for treemacs users
;; (setq doom-themes-treemacs-theme "all-the-icons") ; use "doom-colors" for less minimal icon theme
;; (doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
;; (doom-themes-org-config)
)
;; (load-theme 'atom-one-dark t)
;; (load-theme 'doom-monokai-classic t)
Change theme by time
(use-package theme-changer
:ensure t
:config
(setq calendar-location-name "Vladivostok, RU")
(setq calendar-latitude 43.11)
(setq calendar-longitude 131.88))
(change-theme 'doom-one-light 'gruvbox-dark-medium)
;; (change-theme 'doom-one-light 'doom-one)
;; (change-theme 'doom-ayu-light 'doom-ayu-dark)
Setting packages
Org
Org-mode
Setting Org
(use-package org
;; :hook (org-mode . mk/org-mode-setup)
:config
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(setq
org-hide-emphasis-markers t
org-hide-leading-stars t
org-log-into-drawer t
org-log-done 'time))
(with-eval-after-load 'org
(setq org-confirm-babel-evaluate nil)
(require 'org-tempo)
;; Setup fonts for org-mode
(set-face-attribute 'org-block nil :inherit 'fixed-pitch)
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-table nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number nil :inherit 'fixed-pitch)
(set-face-attribute 'line-number-current-line nil :inherit 'fixed-pitch)
(add-hook 'org-babel-after-execute-hook (lambda ()
(when org-inline-image-overlays
(org-redisplay-inline-images))))
(add-to-list 'org-modules 'org-tempo t))
(setq org-display-remote-inline-images t)
Some replaces
;;; replace-org-char
;; Replace list hyphen with dot
(font-lock-add-keywords 'org-mode
'(("^ *\\([-]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
;; Replace list plus with arrow
(font-lock-add-keywords 'org-mode
'(("^ *\\([+]\\) "
(0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "➤"))))))
Improve org-mode looks
(setq
org-ellipsis " ▾" ; ↴, ▼, ▶, ⤵, ▾
org-roam-v2-ack t ; anonying startup message
org-log-done 'time ; I need to know when a task is done
org-startup-folded t
;; org-odd-levels-only t
org-pretty-entities t
org-startup-indented t
org-adapt-indentation t
org-hide-leading-stars t
org-hide-macro-markers t
org-hide-block-startup nil
org-src-fontify-natively t
org-src-tab-acts-natively t
org-hide-emphasis-markers t
org-cycle-separator-lines 2
org-startup-folded 'content
org-startup-with-inline-images t
org-src-preserve-indentation nil
org-edit-src-content-indentation 2
org-fontify-quote-and-verse-blocks t
org-image-actual-width '(300))
Increase the size of various headings
(set-face-attribute 'org-document-title nil) ;; :font "Terminess Nerd Font Propo" :weight 'bold :height 1.5
(dolist (face '((org-level-1 . 1.2)
(org-level-2 . 1.1)
(org-level-3 . 1.05)
(org-level-4 . 1.0)
(org-level-5 . 1.1)
(org-level-6 . 1.1)
(org-level-7 . 1.1)
(org-level-8 . 1.1)))
(set-face-attribute (car face) nil)) ;; :font "Terminess Nerd Font Propo" :weight 'medium :height (cdr face)
Beautiful quotes
(defun org-quote-beautify ()
"Beautify quotes in org-mode."
(when (org-in-src-block-p)
(let ((begin-quote "#+begin_quote")
(end-quote "#+end_quote")
(quote-symbol "❝")
(close-quote-symbol "❞"))
(goto-char (point-min))
(while (search-forward-regexp begin-quote nil t)
(let ((beg (match-beginning 0))
(end (search-forward-regexp end-quote)))
(when end
(let ((buffer-undo-list t)
(buffer-read-only nil))
(goto-char beg)
(insert quote-symbol)
(goto-char end)
(insert close-quote-symbol))))))))
(add-hook 'org-mode-hook 'org-quote-beautify)
Org modern (disabled)
(use-package org-modern
:ensure t
:config
;; Add frame borders and window dividers
;; (modify-all-frames-parameters
;; '((right-divider-width . 40)
;; (internal-border-width . 40)))
(dolist (face '(window-divider
window-divider-first-pixel
window-divider-last-pixel))
(face-spec-reset-face face)
(set-face-foreground face (face-attribute 'default :background)))
(set-face-background 'fringe (face-attribute 'default :background))
(setq
;; Edit settings
org-auto-align-tags nil
org-tags-column 0
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
;; Org styling, hide markup etc.
org-hide-emphasis-markers t
org-pretty-entities t
org-ellipsis "…"
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"⭠ now ─────────────────────────────────────────────────")
(setq org-enable-table-editor nil)
(global-org-modern-mode))
(add-hook 'org-mode-hook 'my-org-mode-hook)
(defun my-org-mode-hook ()
(add-hook 'hack-local-variables-hook
(lambda () (setq org-enable-table-editor nil) )))
Org bullets
;; (use-package org-superstar
;; :ensure t
;; :config
;; (setq org-superstar-headline-bullets-list '("◉" "⬢" "○" "✸" "✿")))
;; (add-hook 'org-mode-hook (lambda () (org-superstar-mode 1)))
;; (use-package org-bullets
;; :ensure t
;; :hook (org-mode . org-bullets-mode)
;; :custom
;; (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))
(use-package org-bullets
:ensure t
:after org
:hook (org-mode . org-bullets-mode)
:custom
(org-bullets-bullet-list '("◉" "✿" "✚" "✸" "❀" "○"))) ; "●" "▷" "🞛" "◈" "✖"
Change TODO’s states
(with-eval-after-load 'org
(setq org-log-done 'time))
(with-eval-after-load 'org
(setq org-todo-keywords
'((sequence "TODO" "DOING" "BLOCKED" "REVIEW" "|" "DONE" "ARCHIVED"))))
(with-eval-after-load 'org
(setq org-todo-keyword-faces
'(("TODO" . "SlateGray")
("DOING" . "DarkOrchid")
("BLOCKED" . "Firebrick")
("REVIEW" . "Teal")
("DONE" . "ForestGreen")
("ARCHIVED" . "SlateBlue"))))
Org timer (Pomodoro)
(setq org-clock-sound "~/.emacs.d/sound.wav")
Org notifications
(use-package org-alert
:ensure t)
Org babel
(use-package ob-typescript
:ensure t)
(use-package ob-rust
:ensure t)
;; Execute org src block
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(js . t)
(typescript . t)
(shell . t)
(python . t)
(rust . t)
(C . t)
(latex . t)))
Beautiful Org Checkbox Symbol
(add-hook 'org-mode-hook (lambda ()
"Beautify Org Checkbox Symbol"
(push '("[ ]" . "☐") prettify-symbols-alist)
(push '("[X]" . "☑" ) prettify-symbols-alist)
(push '("[-]" . "❍" ) prettify-symbols-alist)
(prettify-symbols-mode)))
(defface org-checkbox-done-text
'((t (:foreground "#71696A" :strike-through t)))
"Face for the text part of a checked org-mode checkbox.")
;; (font-lock-add-keywords
;; 'org-mode
;; `(("^[ \t]*\\(?:[-+*]\\|[0-9]+[).]\\)[ \t]+\\(\\(?:\\[@\\(?:start:\\)?[0-9]+\\][ \t]*\\)?\\[\\(?:X\\|\\([0-9]+\\)/\\2\\)\\][^\n]*\n\\)"
;; 1 'org-checkbox-done-text prepend))
;; 'append)
Build your Org agenda from Org Roam notes (disabled)
;; The buffer you put this code in must have lexical-binding set to t!
;; See the final configuration at the end for more details.
(defun my/org-roam-filter-by-tag (tag-name)
(lambda (node)
(member tag-name (org-roam-node-tags node))))
(defun my/org-roam-list-notes-by-tag (tag-name)
(mapcar #'org-roam-node-file
(seq-filter
(my/org-roam-filter-by-tag tag-name)
(org-roam-node-list))))
(defun my/org-roam-refresh-agenda-list ()
(interactive)
(setq org-agenda-files (my/org-roam-list-notes-by-tag "Project")))
;; Build the agenda list the first time for the session
(my/org-roam-refresh-agenda-list)
Org-roam-bibtex
(use-package org-roam-bibtex
:ensure t
:after org-roam
:hook (org-roam-mode . org-roam-bibtex-mode)
:config
(setq org-roam-bibtex-preformat-keywords
'("=key=" "title" "url" "file" "author-or-editor" "keywords"))
(setq orb-templates
'(("r" "ref" plain (function org-roam-capture--get-point)
""
:file-name "${slug}"
:head "#+TITLE: ${=key=}: ${title}\n#+ROAM_KEY: ${ref}
- tags ::
- keywords :: ${keywords}
\n* ${title}\n :PROPERTIES:\n :Custom_ID: ${=key=}\n :URL: ${url}\n :AUTHOR: ${author-or-editor}\n :NOTER_DOCUMENT: %(orb-process-file-field \"${=key=}\")\n :NOTER_PAGE: \n :END:\n\n"
:unnarrowed t)))
(require 'org-ref)) ; optional: if using Org-ref v2 or v3 citation links
Deps for org-roam-bibtex:
Org ref
(use-package org-ref :ensure t
:config
(setq reftex-default-bibliography '("~/Org/2Brain/bibtex/ref.bib"))
(setq org-ref-bibliography-notes "~/Org/2Brain/bibtex/ref_notes.org"
org-ref-default-bibliography '("~/Org/2Brain/ref.bib")
org-ref-pdf-directory "~/Org/2Brain/bibtex/bibtex-pdfs/")
(setq bibtex-completion-bibliography "~/Org/2Brain/bibtex/ref.bib"
bibtex-completion-library-path "~/Org/2Brain/bibtex/bibtex-pdfs/"
bibtex-completion-notes-path "~/Org/2Brain/bibtex/bibtex-notes")
; Optional. Open pdf in external viewer.
(setq bibtex-completion-pdf-open-function
(lambda (fpath)
(start-process "open" "*open*" "open" fpath))))
Citar
(use-package citar-embark
:ensure t
:after citar embark
:no-require
:config
(org-cite-global-bibliography
'("~/Org/2Brain/bibtex/ref.bib"))
(citar-embark-mode))
;; Use `citar' with `org-cite'
(use-package citar-org
:after oc
:custom
(org-cite-insert-processor 'citar)
(org-cite-follow-processor 'citar)
(org-cite-activate-processor 'citar))
Helm bibtex
(use-package helm-bibtex :ensure t)
Company-org-roam
(use-package company-org-roam
:straight (:host github :repo "org-roam/company-org-roam")
:config
(push 'company-org-roam company-backends))
Md-roam (add md for org-roam)
(load "~/.emacs.d/local-packages/md-roam")
(use-package md-roam
:config
(md-roam-mode 1) ; md-roam-mode must be active before org-roam-db-sync
(setq org-roam-file-extensions '("org" "md"))
(setq md-roam-file-extension "md") ; default "md". Specify an extension such as "markdown"
)
(with-eval-after-load 'markdown-mode
(advice-add #'markdown-indent-line :before-until #'completion-at-point))
Org-download
(use-package org-download
:ensure t)
(setq-default org-download-image-dir "./assets-org/")
;; Drag-and-drop to `dired`
(add-hook 'dired-mode-hook 'org-download-enable)
Org noter
(use-package org-noter
:ensure t)
(use-package org-pdftools
:ensure t
:hook (org-mode . org-pdftools-setup-link)
)
(use-package org-noter-pdftools
:ensure t
:after org-noter
:config
;; Add a function to ensure precise note is inserted
(defun org-noter-pdftools-insert-precise-note (&optional toggle-no-questions)
(interactive "P")
(org-noter--with-valid-session
(let ((org-noter-insert-note-no-questions (if toggle-no-questions
(not org-noter-insert-note-no-questions)
org-noter-insert-note-no-questions))
(org-pdftools-use-isearch-link t)
(org-pdftools-use-freepointer-annot t))
(org-noter-insert-note (org-noter--get-precise-info)))))
;; fix https://github.com/weirdNox/org-noter/pull/93/commits/f8349ae7575e599f375de1be6be2d0d5de4e6cbf
(defun org-noter-set-start-location (&optional arg)
"When opening a session with this document, go to the current location.
With a prefix ARG, remove start location."
(interactive "P")
(org-noter--with-valid-session
(let ((inhibit-read-only t)
(ast (org-noter--parse-root))
(location (org-noter--doc-approx-location (when (called-interactively-p 'any) 'interactive))))
(with-current-buffer (org-noter--session-notes-buffer session)
(org-with-wide-buffer
(goto-char (org-element-property :begin ast))
(if arg
(org-entry-delete nil org-noter-property-note-location)
(org-entry-put nil org-noter-property-note-location
(org-noter--pretty-print-location location))))))))
(with-eval-after-load 'pdf-annot
(add-hook 'pdf-annot-activate-handler-functions #'org-noter-pdftools-jump-to-note)))
Org agenda
C-c a
– for entering in Org agenda
(setq org-agenda-files (list "~/Org")
org-log-done 'time)
(setq who/org-agenda-directory "~/Org/agenda")
(require 'find-lisp)
(defun who/find-org-files (directory)
(find-lisp-find-files directory "\.org$"))
;; "TODO" "DOING" "BLOCKED" "REVIEW" "|" "DONE" "ARCHIVED"
(defun who-org/agenda-files-update (&rest _)
(let ((todo-zettels (->> "rg --files-with-matches '(TODO)|(DOING)|(BLOCKED)|(REVIEW)' ~/Org/2Brain"
(shell-command-to-string)
(s-lines)
(-filter (lambda (line) (not (s-blank? line)))))))
(setq org-agenda-files (append (who/find-org-files who/org-agenda-directory)
todo-zettels))))
(advice-add 'org-agenda :before #'who-org/agenda-files-update)
;; Set default column view headings: Task Total-Time Time-Stamp
(setq org-columns-default-format "%50ITEM(Task) %10CLOCKSUM %16TIMESTAMP_IA")
Main settings
(setq org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-include-deadlines t
org-agenda-block-separator #x2501
org-agenda-compact-blocks t
org-agenda-start-with-log-mode t)
(with-eval-after-load 'org-journal
(define-key org-journal-mode-map (kbd "<C-tab>") 'yas-expand))
(setq org-agenda-clockreport-parameter-plist
(quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80)))
(setq org-agenda-deadline-faces
'((1.0001 . org-warning) ; due yesterday or before
(0.0 . org-upcoming-deadline))) ; due today or later(setq-default org-icalendar-include-todo t)
(setq org-combined-agenda-icalendar-file "~/Org/calendar.ics")
;; (icalendar-import-file "~/Org/calendar.ics" "diary-google")
(setq org-icalendar-combined-name "Hugo Org")
(setq org-icalendar-use-scheduled '(todo-start event-if-todo event-if-not-todo))
(setq org-icalendar-use-deadline '(todo-due event-if-todo event-if-not-todo))
(setq org-icalendar-timezone "Asia/Vladivostok")
(setq org-icalendar-store-UID t)
(setq org-icalendar-alarm-time 30)
(setq calendar-date-style 'european
calendar-mark-holidays-flag t
calendar-week-start-day 1
calendar-mark-diary-entries-flag nil)
Agenda reminders
(alert-define-style 'who/alert-style-reminder
:title "Agenda reminders"
:notifier (lambda (info)
(alert-libnotify-notify (plist-put info :persistent t))))
(add-to-list 'alert-user-configuration
'(((:title . "Agenda"))
who/alert-style-reminder))
Agenda style
(setq org-columns-default-format "%50ITEM(Task) %10CLOCKSUM %16TIMESTAMP_IA")
(defun my/style-org-agenda()
;; (my/buffer-face-mode-variable)
(set-face-attribute 'org-agenda-date nil :height 1.1)
(set-face-attribute 'org-agenda-date-today nil :height 1.1 :slant 'italic)
(set-face-attribute 'org-agenda-date-weekend nil :height 1.1))
(add-hook 'org-agenda-mode-hook 'my/style-org-agenda)
(setq org-agenda-breadcrumbs-separator " ❱ "
org-agenda-current-time-string "⏰ ┈┈┈┈┈┈┈┈┈┈┈ now"
org-agenda-time-grid '((weekly today require-timed)
(800 1000 1200 1400 1600 1800 2000)
"---" "┈┈┈┈┈┈┈┈┈┈┈┈┈")
org-agenda-prefix-format '((agenda . "%i %-12:c%?-12t%b% s")
(todo . " %i %-12:c")
(tags . " %i %-12:c")
(search . " %i %-12:c")))
(setq org-agenda-format-date (lambda (date) (concat "\n" (make-string (window-width) 9472)
"\n"
(org-agenda-format-date-aligned date))))
(setq org-cycle-separator-lines 2)
;; (setq org-agenda-category-icon-alist
;; `(("Work" ,(list (all-the-icons-faicon "cogs")) nil nil :ascent center)
;; ("Personal" ,(list (all-the-icons-material "person")) nil nil :ascent center)
;; ("Calendar" ,(list (all-the-icons-faicon "calendar")) nil nil :ascent center)
;; ("Reading" ,(list (all-the-icons-faicon "book")) nil nil :ascent center)))
Colorize block
;; work with org-agenda dispatcher [c] "Today Clocked Tasks" to view today's clocked tasks.
(defun org-agenda-log-mode-colorize-block ()
"Set different line spacing based on clock time duration."
(save-excursion
(let* ((colors (cl-case (alist-get 'background-mode (frame-parameters))
('light
(list "#F6B1C3" "#FFFF9D" "#BEEB9F" "#ADD5F7"))
('dark
(list "#aa557f" "DarkGreen" "DarkSlateGray" "DarkSlateBlue"))))
pos
duration)
(nconc colors colors)
(goto-char (point-min))
(while (setq pos (next-single-property-change (point) 'duration))
(goto-char pos)
(when (and (not (equal pos (point-at-eol)))
(setq duration (org-get-at-bol 'duration)))
;; larger duration bar height
(let ((line-height (if (< duration 15) 1.0 (+ 0.5 (/ duration 30))))
(ov (make-overlay (point-at-bol) (1+ (point-at-eol)))))
(overlay-put ov 'face `(:background ,(car colors) :foreground "black"))
(setq colors (cdr colors))
(overlay-put ov 'line-height line-height)
(overlay-put ov 'line-spacing (1- line-height))))))))
(add-hook 'org-agenda-finalize-hook #'org-agenda-log-mode-colorize-block)
Super agenda
(use-package org-super-agenda :ensure t)
(setq org-agenda-custom-commands
'(("z" "Hugo view"
((agenda "" ((org-agenda-span 'day)
(org-super-agenda-groups
'((:name "Today"
:time-grid t
:date today
:todo "TODAY"
:scheduled today
:order 1)))))
(alltodo "" ((org-agenda-overriding-header "")
(org-super-agenda-groups
'(;; Each group has an implicit boolean OR operator between its selectors.
(:name "Today"
:deadline today
:face (:background "black"))
(:name "Passed deadline"
:and (:deadline past :todo ("TODO" "DOING" "BLOCKED" "REVIEW"))
:face (:background "#7f1b19"))
(:name "Work important"
:and (:priority>= "B" :category "Work" :todo ("TODO" "NEXT")))
(:name "Work other"
:and (:category "Work" :todo ("TODO" "NEXT")))
(:name "Important"
:priority "A")
(:priority<= "B"
;; Show this section after "Today" and "Important", because
;; their order is unspecified, defaulting to 0. Sections
;; are displayed lowest-number-first.
:order 1)
(:name "Papers"
:file-path "org/roam/notes")
(:name "Waiting"
:todo "WAITING"
:order 9)
(:name "On review"
:todo "REVIEW"
:order 10)))))))))
(add-hook 'org-agenda-mode-hook 'org-super-agenda-mode)
Capture
(setq org-directory "~/Org")
(setq org-default-notes-file "~/Org/agenda/notes.org")
;; (setq org-capture-templates
;; '(("t" "todo" entry (file org-default-notes-file)
;; "* TODO %?\n%u\n%a\n" :clock-in t :clock-resume t)
;; ("m" "Meeting" entry (file org-default-notes-file)
;; "* MEETING with %? :MEETING:\n%t" :clock-in t :clock-resume t)
;; ("d" "Diary" entry (file+datetree "~/Org/diary.org")
;; "* %?\n%U\n" :clock-in t :clock-resume t)
;; ("i" "Idea" entry (file org-default-notes-file)
;; "* %? :IDEA: \n%t" :clock-in t :clock-resume t)
;; ))
;; (setq org-capture-templates
;; `(("i" "inbox" entry (file ,(concat who/org-agenda-directory "inbox.org"))
;; "* TODO %?\n")
;; ("a" "appointment" entry (file "~/Org/gtd/calendars/personal.org" ))
;; ("e" "email" entry (file+headline ,(concat who/org-agenda-directory "inbox.org") "Emails")
;; "* TODO [#B] %a" :immediate-finish t)
;; ("l" "link" entry (file ,(concat who/org-agenda-directory "inbox.org"))
;; "* TODO %(org-cliplink-capture)" :immediate-finish t)
;; ("c" "org-protocol-capture" entry (file ,(concat who/org-agenda-directory "inbox.org"))
;; "* TODO [[%:link][%:description]]\n\n %i" :immediate-finish t)))
(setq org-capture-templates
'(
("t" "TODO" entry
(file "~/Org/agenda/inbox.org") "* TODO %^{Title}")
("m" "Meeting notes" entry
(file "~/Org/agenda/appointments.org") "* TODO %^{Title} %t\n- %?")
("w" "Work TODO" entry
(file "~/Org/agenda/work.org") "* TODO %^{Title}")
("d" "Diary" entry (file "~/Org/2Brain/diary.org.gpg") ;; "~/Org/2Brain/2023-03-14-13:48:46.org.gpg"
"* %U\n" :clock-in t :clock-resume t) ;; "*** %?\n%U\n" :clock-in t :clock-resume t)
("n" "Notes" entry
(file "~/Org/agenda/inbox.org") "* %^{Description} %^g\n Added: %U\n%?")
))
org-gcal
(use-package org-gcal
:after org
:ensure t
:commands (org-gcal-request-token)
:config
(setq org-gcal-token-file "~/.config/org-gcal/.org-gcal-token"
org-gcal-client-id (who/get-file-contents "~/.config/org-gcal/.org-gcal-client-id")
org-gcal-client-secret (who/get-file-contents "~/.config/org-gcal/.org-gcal-client-secret")
org-gcal-local-timezone "Canada/Pacific"))
org-caldav
(use-package org-caldav
:ensure t
:custom
(org-caldav-url "https://lunarcloud.ddns.net/remote.php/dav/calendars/ncp")
(org-caldav-calendar-id "personal")
(org-caldav-inbox "~/Org/agenda/cal_inbox.org")
(org-caldav-files '("~/Org/agenda/calendar.org"))
(org-icalendar-timezone "Asia/Vladivostok")
(org-caldav-delete-org-entries 'never))
;; (org-caldav-sync)
Ox-hugo
(use-package ox-hugo
:ensure t ;Auto-install the package from Melpa
:pin melpa ;`package-archives' should already have ("melpa" . "https://melpa.org/packages/")
:after ox)
Presentations with org and reval.js
(use-package org-re-reveal :ensure t)
(use-package ox-reveal :ensure t)
(setq org-reveal-root "file:~/Org/Presentations/reveal.js/")
Ement (matrix in emacs)
(use-package ement
:ensure t)
Spell checking
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
(add-hook 'org-mode-hook 'flyspell-mode)
(setq ispell-program-name "hunspell")
(setq ispell-local-dictionary "ru_RU")
(setq ispell-local-dictionary-alist
'(("ru_RU" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil nil nil utf-8)))
LaTeX
Auctex
(use-package auctex
:ensure t)
(use-package auctex-latexmk
:ensure t
:config
(auctex-latexmk-setup)
(add-hook 'LaTeX-mode-hook 'linum-mode)
(add-hook 'TeX-mode-hook
(lambda () (TeX-fold-mode 1))));; Automatically activate
;; TeX-fold-mode.
;; Use pdf-tools to open PDF files
(setq TeX-view-program-selection '((output-pdf "PDF Tools"))
TeX-source-correlate-start-server t)
;; Update PDF buffers after successful LaTeX runs
(add-hook 'TeX-after-compilation-finished-functions
#'TeX-revert-document-buffer)
Embed LaTeX in org-mode
;; (require 'ox-latex)
;; (setq org-latex-create-formula-image-program 'dvipng)
;; (org-babel-do-load-languages 'org-babel-load-languages '((latex . t)))
(setq org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
;; Set up default LaTeX preview configuration
(setq org-latex-create-formula-image-program 'imagemagick)
(setq org-preview-latex-default-process 'imagemagick) ; or 'dvisvgm
(setq org-preview-latex-process-alist
'((imagemagick :programs ("latex" "convert")
:description "imagemagick"
:message "You need to install the programs: latex and imagemagick."
:image-input-type "pdf"
:image-output-type "png"
:image-size-adjust (1.0 . 1.0)
:latex-compiler ("pdflatex -interaction nonstopmode -output-directory %o %f")
:image-converter ("convert -density %D -trim -antialias %f -quality 100 %O"))
(dvisvgm :programs ("latex" "dvisvgm")
:description "dvisvgm"
:message "You need to install the programs: latex and dvisvgm."
:image-input-type "xdv"
:image-output-type "svg"
:image-size-adjust (1.7 . 1.5)
:latex-compiler ("xelatex -no-pdf -interaction nonstopmode -output-directory %o %f")
:image-converter ("dvisvgm %f -n -b min -c %S -o %O"))))
;; Enable inline LaTeX previews in org-mode
(add-hook 'org-mode-hook 'org-toggle-latex-fragment)
;; Display images in org-mode buffers
(setq org-startup-with-inline-images t)
(setq org-image-actual-width nil) ; adjust to your liking
kind-icon
https://github.com/jdtsmith/kind-icon
(use-package kind-icon
:ensure t
:after corfu
:custom
(kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly
:config
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))
Pdf, epub, Djvu readers
PDF Tools (pdf)
pdf-tools
(use-package pdf-tools
:ensure t
:defer t
:mode (("\\.pdf\\'" . pdf-view-mode))
:config
;; (add-hook 'pdf-tools-enabled-hook 'pdf-view-midnight-minor-mode)
(setq-default pdf-view-display-size 'fit-page)
;; (pdf-tools-install)
:bind (:map pdf-view-mode-map
("\\" . hydra-pdftools/body)
("<s-spc>" . pdf-view-scroll-down-or-next-page)
("g" . pdf-view-first-page)
("G" . pdf-view-last-page)
("l" . image-forward-hscroll)
("h" . image-backward-hscroll)
("j" . pdf-view-next-page)
("k" . pdf-view-previous-page)
("e" . pdf-view-goto-page)
("u" . pdf-view-revert-buffer)
("al" . pdf-annot-list-annotations)
("ad" . pdf-annot-delete)
("aa" . pdf-annot-attachment-dired)
("am" . pdf-annot-add-markup-annotation)
("at" . pdf-annot-add-text-annotation)
("y" . pdf-view-kill-ring-save)
("i" . pdf-misc-display-metadata)
("s" . pdf-occur)
("b" . pdf-view-set-slice-from-bounding-box)
("r" . pdf-view-reset-slice)))
;; (defhydra hydra-pdftools (:color blue :hint nil)
;; "
;; ╭───────────┐
;; Move History Scale/Fit Annotations Search/Link Do │ PDF Tools │
;; ╭──────────────────────────────────────────────────────────────────┴───────────╯
;; ^^_g_^^ _B_ ^↧^ _+_ ^ ^ [_al_] list [_s_] search [_u_] revert buffer
;; ^^^↑^^^ ^↑^ _H_ ^↑^ ↦ _W_ ↤ [_am_] markup [_o_] outline [_i_] info
;; ^^_p_^^ ^ ^ ^↥^ _0_ ^ ^ [_at_] text [_F_] link [_d_] dark mode
;; ^^^↑^^^ ^↓^ ╭─^─^─┐ ^↓^ ╭─^ ^─┐ [_ad_] delete [_f_] search link
;; _h_ ←pag_e_→ _l_ _N_ │ _P_ │ _-_ _b_ [_aa_] dired
;; ^^^↓^^^ ^ ^ ╰─^─^─╯ ^ ^ ╰─^ ^─╯ [_y_] yank
;; ^^_n_^^ ^ ^ _r_eset slice box
;; ^^^↓^^^
;; ^^_G_^^
;; --------------------------------------------------------------------------------
;; "
;; ("\\" hydra-master/body "back")
;; ("<ESC>" nil "quit")
;; ("al" pdf-annot-list-annotations)
;; ("ad" pdf-annot-delete)
;; ("aa" pdf-annot-attachment-dired)
;; ("am" pdf-annot-add-markup-annotation)
;; ("at" pdf-annot-add-text-annotation)
;; ("y" pdf-view-kill-ring-save)
;; ("+" pdf-view-enlarge :color red)
;; ("-" pdf-view-shrink :color red)
;; ("0" pdf-view-scale-reset)
;; ("H" pdf-view-fit-height-to-window)
;; ("W" pdf-view-fit-width-to-window)
;; ("P" pdf-view-fit-page-to-window)
;; ("n" pdf-view-next-page-command :color red)
;; ("p" pdf-view-previous-page-command :color red)
;; ("d" pdf-view-dark-minor-mode)
;; ("b" pdf-view-set-slice-from-bounding-box)
;; ("r" pdf-view-reset-slice)
;; ("g" pdf-view-first-page)
;; ("G" pdf-view-last-page)
;; ("e" pdf-view-goto-page)
;; ("o" pdf-outline)
;; ("s" pdf-occur)
;; ("i" pdf-misc-display-metadata)
;; ("u" pdf-view-revert-buffer)
;; ("F" pdf-links-action-perfom)
;; ("f" pdf-links-isearch-link)
;; ("B" pdf-history-backward :color red)
;; ("N" pdf-history-forward :color red)
;; ("l" image-forward-hscroll :color red)
;; ("h" image-backward-hscroll :color red))
saveplace-view
(use-package saveplace-pdf-view :ensure t)
(save-place-mode 1)
nov.el (epub)
For more information: https://depp.brause.cc/nov.el/
(use-package nov
:ensure t
:config
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))
(setq nov-text-width 80)
(setq nov-text-width t)
(setq visual-fill-column-center-text t)
(add-hook 'nov-mode-hook 'visual-line-mode)
(add-hook 'nov-mode-hook 'visual-fill-column-mode)
)
nov-xwidget (epub)
(load "~/.emacs.d/local-packages/nov-xwidget")
(require 'nov-xwidget)
(use-package cl-lib :ensure t)
;; Best .epub reader
(use-package nov-xwidget
:demand t
:after nov
:config
(define-key nov-mode-map (kbd "o") 'nov-xwidget-view)
(add-hook 'nov-mode-hook 'nov-xwidget-inject-all-files))
Calibre (books management)
(setq sql-sqlite-program "/usr/bin/sqlite3")
;; (setq calibredb-program "/Applications/calibre.app/Contents/MacOS/calibredb")
(use-package calibredb
:ensure t
:defer t
:config
(setq calibredb-root-dir "~/Calibre Library")
(setq calibredb-db-dir (expand-file-name "metadata.db" calibredb-root-dir))
(setq calibredb-library-alist '(("~/Books")))
(setq calibredb-virtual-library-alist '(("1. Development - work" . "work \\(pdf\\|epub\\)")
("2. Read it later" . "Readit epub")
("3. Development - rust" . "rust")))
(setq calibredb-format-all-the-icons t)
(setq calibredb-format-icons-in-terminal t))
;; Keybindings
(defvar calibredb-show-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "?" #'calibredb-entry-dispatch)
(define-key map "o" #'calibredb-find-file)
(define-key map "O" #'calibredb-find-file-other-frame)
(define-key map "V" #'calibredb-open-file-with-default-tool)
(define-key map "s" #'calibredb-set-metadata-dispatch)
(define-key map "e" #'calibredb-export-dispatch)
(define-key map "q" #'calibredb-entry-quit)
(define-key map "y" #'calibredb-yank-dispatch)
(define-key map "," #'calibredb-quick-look)
(define-key map "." #'calibredb-open-dired)
(define-key map "\M-/" #'calibredb-rga)
(define-key map "\M-t" #'calibredb-set-metadata--tags)
(define-key map "\M-a" #'calibredb-set-metadata--author_sort)
(define-key map "\M-A" #'calibredb-set-metadata--authors)
(define-key map "\M-T" #'calibredb-set-metadata--title)
(define-key map "\M-c" #'calibredb-set-metadata--comments)
map)
"Keymap for `calibredb-show-mode'.")
(defvar calibredb-search-mode-map
(let ((map (make-sparse-keymap)))
(define-key map [mouse-3] #'calibredb-search-mouse)
(define-key map (kbd "<RET>") #'calibredb-find-file)
(define-key map "?" #'calibredb-dispatch)
(define-key map "a" #'calibredb-add)
(define-key map "A" #'calibredb-add-dir)
(define-key map "c" #'calibredb-clone)
(define-key map "d" #'calibredb-remove)
(define-key map "D" #'calibredb-remove-marked-items)
(define-key map "j" #'calibredb-next-entry)
(define-key map "k" #'calibredb-previous-entry)
(define-key map "l" #'calibredb-virtual-library-list)
(define-key map "L" #'calibredb-library-list)
(define-key map "n" #'calibredb-virtual-library-next)
(define-key map "N" #'calibredb-library-next)
(define-key map "p" #'calibredb-virtual-library-previous)
(define-key map "P" #'calibredb-library-previous)
(define-key map "s" #'calibredb-set-metadata-dispatch)
(define-key map "S" #'calibredb-switch-library)
(define-key map "o" #'calibredb-find-file)
(define-key map "O" #'calibredb-find-file-other-frame)
(define-key map "v" #'calibredb-view)
(define-key map "V" #'calibredb-open-file-with-default-tool)
(define-key map "," #'calibredb-quick-look)
(define-key map "." #'calibredb-open-dired)
(define-key map "y" #'calibredb-yank-dispatch)
(define-key map "b" #'calibredb-catalog-bib-dispatch)
(define-key map "e" #'calibredb-export-dispatch)
(define-key map "r" #'calibredb-search-refresh-and-clear-filter)
(define-key map "R" #'calibredb-search-clear-filter)
(define-key map "q" #'calibredb-search-quit)
(define-key map "m" #'calibredb-mark-and-forward)
(define-key map "f" #'calibredb-toggle-favorite-at-point)
(define-key map "x" #'calibredb-toggle-archive-at-point)
(define-key map "h" #'calibredb-toggle-highlight-at-point)
(define-key map "u" #'calibredb-unmark-and-forward)
(define-key map "i" #'calibredb-edit-annotation)
(define-key map (kbd "<DEL>") #'calibredb-unmark-and-backward)
(define-key map (kbd "<backtab>") #'calibredb-toggle-view)
(define-key map (kbd "TAB") #'calibredb-toggle-view-at-point)
(define-key map "\M-n" #'calibredb-show-next-entry)
(define-key map "\M-p" #'calibredb-show-previous-entry)
(define-key map "/" #'calibredb-search-live-filter)
(define-key map "\M-t" #'calibredb-set-metadata--tags)
(define-key map "\M-a" #'calibredb-set-metadata--author_sort)
(define-key map "\M-A" #'calibredb-set-metadata--authors)
(define-key map "\M-T" #'calibredb-set-metadata--title)
(define-key map "\M-c" #'calibredb-set-metadata--comments)
map)
"Keymap for `calibredb-search-mode'.")
Dashboard
;; Setting dashboard
(use-package dashboard
:ensure t
:hook (dashboard-mode . (lambda ()
;; No title
(setq-local frame-title-format nil)
;; Enable `page-break-lines-mode'
(when (fboundp 'page-break-lines-mode)
(page-break-lines-mode 1))))
:init ;; tweak dashboard config before loading it
(setq dashboard-set-heading-icons t
dashboard-set-file-icons t
dashboard-center-content t
dashboard-banner-logo-title "Welcome back, Darling!"
dashboard-startup-banner "~/.emacs.d/images/emacs-e-small.png"
;; dashboard-page-separator ""
dashboard-set-navigator t
dashboard-items '(
(recents . 6)
;; (agenda . 4 )
;;(registers . 3)
(bookmarks . 4)
(projects . 4))) ;; use standard emacs logo as banner
(add-hook 'dashboard-mode-hook (lambda () (setq show-trailing-whitespace nil)))
;; Format: "(icon title help action face prefix suffix)"
;; (setq dashboard-navigator-buttons
;; `(;; line1
;; ((,(all-the-icons-wicon "tornado" :height 1.1 :v-adjust 0.0)
;; "Main site"
;; "Browse homepage"
;; (lambda (&rest _) (browse-url "homepage")))
;; ("★" "Star" "Show stars" (lambda (&rest _) (show-stars)) warning)
;; ("?" "" "?/h" #'show-help nil "<" ">"))
;; ;; line 2
;; ((,(all-the-icons-faicon "github" :height 1.1 :v-adjust 0.0)
;; "Github"
;; ""
;; (lambda (&rest _) (browse-url "homepage")))
;; ("⚑" nil "Show flags" (lambda (&rest _) (message "flag")) error))))
(setq dashboard-footer-messages '("Richard Stallman is proud of you."))
;; (setq dashboard-footer-icon (all-the-icons-octicon "dashboard"
;; :height 1.1
;; :v-adjust -0.05
;; :face 'font-lock-keyword-face))
:config
;; (dashboard-modify-heading-icons '((recents . "file-text")
;; (bookmarks . "book")))
(dashboard-setup-startup-hook)
)
(setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*"))
)
(defun dashboard-refresh-buffer ()
(interactive)
(when (get-buffer dashboard-buffer-name)
(kill-buffer dashboard-buffer-name))
(dashboard-insert-startupify-lists)
(switch-to-buffer dashboard-buffer-name))
Ligature
(use-package ligature
:config
;; Enable the "www" ligature in every possible major mode
(ligature-set-ligatures 't '("www"))
;; Enable traditional ligature support in eww-mode, if the
;; `variable-pitch' face supports it
(ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
;; Enable all Cascadia Code ligatures in programming modes
(ligature-set-ligatures 'prog-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
"\\\\" "://"))
;; Enables ligature checks globally in all buffers. You can also do it
;; per mode with `ligature-mode'.
(global-ligature-mode t))
;;;;; ligature-for-jetbrain
;; (when (aorst/font-installed-p "JetBrainsMono")
;; (dolist (char/ligature-re
;; `((?- ,(rx (or (or "-->" "-<<" "->>" "-|" "-~" "-<" "->") (+ "-"))))
;; (?/ ,(rx (or (or "/==" "/=" "/>" "/**" "/*") (+ "/"))))
;; (?* ,(rx (or (or "*>" "*/") (+ "*"))))
;; (?< ,(rx (or (or "<<=" "<<-" "<|||" "<==>" "<!--" "<=>" "<||" "<|>" "<-<"
;; "<==" "<=<" "<-|" "<~>" "<=|" "<~~" "<$>" "<+>" "</>" "<*>"
;; "<->" "<=" "<|" "<:" "<>" "<$" "<-" "<~" "<+" "</" "<*")
;; (+ "<"))))
;; (?: ,(rx (or (or ":?>" "::=" ":>" ":<" ":?" ":=") (+ ":"))))
;; (?= ,(rx (or (or "=>>" "==>" "=/=" "=!=" "=>" "=:=") (+ "="))))
;; (?! ,(rx (or (or "!==" "!=") (+ "!"))))
;; (?> ,(rx (or (or ">>-" ">>=" ">=>" ">]" ">:" ">-" ">=") (+ ">"))))
;; (?& ,(rx (+ "&")))
;; (?| ,(rx (or (or "|->" "|||>" "||>" "|=>" "||-" "||=" "|-" "|>" "|]" "|}" "|=")
;; (+ "|"))))
;; (?. ,(rx (or (or ".?" ".=" ".-" "..<") (+ "."))))
;; (?+ ,(rx (or "+>" (+ "+"))))
;; (?\[ ,(rx (or "[<" "[|")))
;; (?\{ ,(rx "{|"))
;; (?\? ,(rx (or (or "?." "?=" "?:") (+ "?"))))
;; (?# ,(rx (or (or "#_(" "#[" "#{" "#=" "#!" "#:" "#_" "#?" "#(") (+ "#"))))
;; (?\; ,(rx (+ ";")))
;; (?_ ,(rx (or "_|_" "__")))
;; (?~ ,(rx (or "~~>" "~~" "~>" "~-" "~@")))
;; (?$ ,(rx "$>"))
;; (?^ ,(rx "^="))
;; (?\] ,(rx "]#"))))
;; (apply (lambda (char ligature-re)
;; (set-char-table-range composition-function-table char
;; `([,ligature-re 0 font-shape-gstring])))
;; char/ligature-re)))
Dired
Docs for dired
Dired Basics
Invocation
C-x d
orC-x C-f
-dired
dired-jump
- open Dired buffer, select the current fileprojectile-dired
Navigation
Emacs / Evil
n
/j
- next linep
/k
- previous linej
/J
- jump to file in bufferRET
- select file or directory^
- go to parent directoryS-RET
/g O
- Open file in “other” windowM-RET
- Show file in other window without focusing (previewing files)g o
(dired-view-file
) - Open file but in a “preview” mode, close withq
Configuration
dired-listing-switches:
Try-agho --group-directories-first
g
/g r
Refresh the buffer withrevert-buffer
after changing configuration (and after filesystem changes!)(use-package dired :ensure nil :commands (dired dired-jump) :bind (("C-x C-j" . dired-jump)) :config (evil-collection-define-key 'normal 'dired-mode-map "h" 'dired-up-directory "l" 'dired-find-file))
Other dired config
(use-package dired
:defer t
:config
(setq dired-dwim-target t) ; Dired tries to guess the target directory
(setq dired-recursive-deletes 'always) ; Allow deleting directories recursively
(setq dired-listing-switches "-alh --group-directories-first") ; Use human-readable file sizes and group directories first
(setq dired-hide-details-mode t) ; Hide file and directory details by default
(setq dired-auto-revert-buffer t) ; Automatically refresh Dired buffers when changes are made
(setq diredp-hide-details-initially-flag nil)
(put 'dired-find-alternate-file 'disabled nil) ; Allow using Enter key to open files
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file) ; Bind Enter to open files
(define-key dired-mode-map (kbd "^")
(lambda () (interactive) (find-alternate-file ".."))) ; Bind ^ to go up a directory
(define-key dired-mode-map (kbd "(") 'dired-hide-details-mode) ; Bind ( to toggle file and directory details
(define-key dired-mode-map (kbd "N") 'dired-create-file) ; Bind N to create a new file
(define-key dired-mode-map (kbd "n") 'dired-create-directory) ; Bind n to create a new directory
(use-package all-the-icons-dired
:ensure t
:hook (dired-mode . all-the-icons-dired-mode) ; Display icons in Dired mode
:init
(setq all-the-icons-dired-mode-inline-electric-icons t)) ; Show electric icons for Dired mode
;; (use-package image-dired
;; :ensure t
;; :config
;; (image-dired-track-modified-flag t) ; Automatically track modifications in images
;; (image-dired-thumb-margin 5)) ; Set margin for image thumbnails in Image Dired mode
)
Single Dired buffer
Closed Dired buffers are just buried! They need to be refreshed if you go back to them.
Use dired-single
to help with this: https://github.com/crocket/dired-single
;; Inside `use-package dired`
(use-package dired-single)
(evil-collection-define-key 'normal 'dired-mode-map
"h" 'dired-single-up-directory
"l" 'dired-single-buffer)
File icons
(use-package all-the-icons-dired
:ensure t
:hook (dired-mode . all-the-icons-dired-mode))
Open external files
!
or&
to launch an external program on a file
BUG BUG BUG
(use-package dired-open
:config
;; Doesn't work as expected!
(add-to-list 'dired-open-functions 'dired-open-xdg t)
;; -- OR! --
(setq dired-open-extensions '(("png" . "feh")
("mkv" . "mpv"))))
Hide / show dotfiles
(setq dired-omit-mode t)
(setq dired-omit-files
(concat dired-omit-files "\\|^\\..+$"))
Make dired open in the same window
;; (setf dired-kill-when-;; Make dired open in the same window when using RET or ^
(put 'dired-find-alternate-file 'disabled nil) ; disables warning
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file) ; was dired-advertised-find-file
(define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file ".."))) ; was dired-up-directoryopening-new-dired-buffer t)
Dired sort directories first
(defun sof/dired-sort ()
"Dired sort hook to list directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max))))
(and (featurep 'xemacs)
(fboundp 'dired-insert-set-properties)
(dired-insert-set-properties (point-min) (point-max)))
(set-buffer-modified-p nil))
(add-hook 'dired-after-readin-hook 'sof/dired-sort)
dired-rainbow
(use-package dired-rainbow
:ensure t
:config
(progn
(dired-rainbow-define-chmod directory "#6cb2eb" "d.*")
(dired-rainbow-define html "#eb5286" ("css" "less" "sass" "scss" "htm" "html" "jhtm" "mht" "eml" "mustache" "xhtml"))
(dired-rainbow-define xml "#f2d024" ("xml" "xsd" "xsl" "xslt" "wsdl" "bib" "json" "msg" "pgn" "rss" "yaml" "yml" "rdata"))
(dired-rainbow-define document "#9561e2" ("docm" "doc" "docx" "odb" "odt" "pdb" "pdf" "ps" "rtf" "djvu" "epub" "odp" "ppt" "pptx"))
(dired-rainbow-define markdown "#ffed4a" ("org" "etx" "info" "markdown" "md" "mkd" "nfo" "pod" "rst" "tex" "textfile" "txt"))
(dired-rainbow-define database "#6574cd" ("xlsx" "xls" "csv" "accdb" "db" "mdb" "sqlite" "nc"))
(dired-rainbow-define media "#de751f" ("mp3" "mp4" "MP3" "MP4" "avi" "mpeg" "mpg" "flv" "ogg" "mov" "mid" "midi" "wav" "aiff" "flac"))
(dired-rainbow-define image "#f66d9b" ("tiff" "tif" "cdr" "gif" "ico" "jpeg" "jpg" "png" "psd" "eps" "svg"))
(dired-rainbow-define log "#c17d11" ("log"))
(dired-rainbow-define shell "#f6993f" ("awk" "bash" "bat" "sed" "sh" "zsh" "vim"))
(dired-rainbow-define interpreted "#38c172" ("py" "ipynb" "rb" "pl" "t" "msql" "mysql" "pgsql" "sql" "r" "clj" "cljs" "scala" "js"))
(dired-rainbow-define compiled "#4dc0b5" ("asm" "cl" "lisp" "el" "c" "h" "c++" "h++" "hpp" "hxx" "m" "cc" "cs" "cp" "cpp" "go" "f" "for" "ftn" "f90" "f95" "f03" "f08" "s" "rs" "hi" "hs" "pyc" ".java"))
(dired-rainbow-define executable "#8cc4ff" ("exe" "msi"))
(dired-rainbow-define compressed "#51d88a" ("7z" "zip" "bz2" "tgz" "txz" "gz" "xz" "z" "Z" "jar" "war" "ear" "rar" "sar" "xpi" "apk" "xz" "tar"))
(dired-rainbow-define packaged "#faad63" ("deb" "rpm" "apk" "jad" "jar" "cab" "pak" "pk3" "vdf" "vpk" "bsp"))
(dired-rainbow-define encrypted "#ffed4a" ("gpg" "pgp" "asc" "bfe" "enc" "signature" "sig" "p12" "pem"))
(dired-rainbow-define fonts "#6cb2eb" ("afm" "fon" "fnt" "pfb" "pfm" "ttf" "otf"))
(dired-rainbow-define partition "#e3342f" ("dmg" "iso" "bin" "nrg" "qcow" "toast" "vcd" "vmdk" "bak"))
(dired-rainbow-define vc "#0074d9" ("git" "gitignore" "gitattributes" "gitmodules"))
(dired-rainbow-define-chmod executable-unix "#38c172" "-.*x.*")
))
Doom modeline
(use-package doom-modeline
:ensure t
:hook
(after-init . doom-modeline-mode)
:custom
(setq doom-modeline-buffer-encoding nil
doom-modeline-buffer-file-name-style 'file-name
doom-modeline-checker-simple-format t
doom-modeline-vcs-max-length 50
doom-modeline-major-mode-icon nil
doom-modeline-icon t
doom-modeline-modal-icon t
doom-modeline-lsp nil
doom-modeline-major-mode-color-icon nil
doom-modeline-buffer-state-icon nil
doom-modeline-time-icon nil
doom-modeline-battery t
doom-modeline-lsp t
doom-modeline-workspace-name t
doom-modeline-enable-word-count t)
(custom-set-faces
'(mode-line ((t (:family "Iosevka Aile" :height 1.0))))
'(mode-line-active ((t (:family "Iosevka Aile" :height 1.0)))) ; For 29+
'(mode-line-inactive ((t (:family "Iosevka Aile" :height 0.95)))))
(doom-modeline-buffer-file-name-style 'relative-from-project)
)
;; (use-package doom-modeline
;; :ensure t
;; :defer t
;; :custom
;; (doom-modeline-modal-icon nil)
;; (doom-modeline-buffer-file-name-style 'relative-from-project)
;; :hook
;; (after-init . doom-modeline-mode)
;; (doom-modeline-mode . display-battery-mode))
Elfeed (RSS)
(use-package elfeed
:ensure t
:config
;; data is stored in ~/.elfeed
(setq elfeed-feeds
'(
;; freelance
("https://freelance.habr.com/user_rss_tasks/vsE2OtRKoyNeUnK7RGd+0w==" freelance)
;;
("https://habr.com/ru/rss/feed/posts/all/bd769e8234cb6e6444ae3197fd0c0d9b/?fl=ru" habr-my-topics)
;; programming
;;("https://news.ycombinator.com/rss" hacker)
;;("https://www.reddit.com/r/programming.rss" programming)
("https://www.reddit.com/r/emacs.rss" emacs)
("https://www.opennet.ru/opennews/opennews_all_utf.rss" opennet-news)
;; ("https://habr.com/ru/rss/all/all/?fl=ru" habr-all)
("https://habr.com/ru/rss/news/?fl=ru" habr-news)
("https://nuancesprog.ru/feed" nop)
("https://dev.to/feed" dev-to)
;; hobby
("https://www.reddit.com/r/nasa.rss" nasa)
("https://habr.com/ru/rss/hub/astronomy/all/?fl=ru" habr-astronomy)
;; ("https://habr.com/ru/rss/flows/popsci/all/?fl=ru" habr-popsci)
("https://nplus1.ru/rss" np1)
;; programming languages
("https://www.reddit.com/r/javascript.rss" javascript)
("https://www.reddit.com/r/typescript.rss" typescript)
("https://www.reddit.com/r/golang.rss" golang)
("https://www.reddit.com/r/rust.rss" rust)
;; Books
;; ("https://habr.com/ru/rss/hub/read/all/?fl=ru" habr-books)
;; cloud
;;("https://www.reddit.com/r/aws.rss" aws)
;;("https://www.reddit.com/r/googlecloud.rss" googlecloud)
;;("https://www.reddit.com/r/azure.rss" azure)
;;("https://www.reddit.com/r/devops.rss" devops)
;;("https://www.reddit.com/r/kubernetes.rss" kubernetes)
))
(setq-default elfeed-search-filter "@7-days-ago +unread")
(setq-default elfeed-search-title-max-width 100)
(setq-default elfeed-search-title-min-width 100))
(use-package elfeed-dashboard
:ensure t
:config
(setq elfeed-dashboard-file "~/elfeed-dashboard.org")
;; update feed counts on elfeed-quit
(advice-add 'elfeed-search-quit-window :after #'elfeed-dashboard-update-links))
Evil
Set initial Evil
(use-package evil
:ensure t
:init ;; tweak evil's configuration before loading it
(setq evil-want-integration t) ;; This is optional since it's already set to t by default.
(setq evil-want-keybinding nil)
(setq evil-vsplit-window-right t)
(setq evil-split-window-below t))
(evil-mode 1)
General (more keymaps from vim)
(use-package general
:ensure t)
(general-evil-setup t)
Evil collection
(use-package evil-collection
:after evil
:ensure t
:config
(setq evil-emacs-state-cursor '("#FF5D62" box))
(setq evil-normal-state-cursor '("#FF5D62" box))
(setq evil-visual-state-cursor '("#98BB6C" box))
(setq evil-insert-state-cursor '("#E82424" bar))
(setq evil-replace-state-cursor '("#FF9E3B" hbar))
(setq evil-operator-state-cursor '("#7E9CD8" hollow))
(evil-collection-init))
Evil leader (disabled)
(use-package evil-leader
:init
(global-evil-leader-mode)
(evil-leader/set-leader "<SPC>")
(evil-leader/set-key
;; General
".f" 'consult-isearch
".q" 'delete-frame
".e" 'eval-region
;; Files
"fr" 'consult-recent-file
"fb" 'consult-bookmark
"ff" 'find-file
"fd" 'dired
;; Org
"oa" 'org-agenda
"fh" 'consult-org-heading
;; Open
"om" 'mu4e
"os" 'eshell
;; Notes
"no" 'deft
"nf" 'deft-find-file
"nn" 'deft-new-file-named
;; Bufffers
"bd" 'kill-current-buffer
"bb" 'consult-buffer
"bx" 'switch-to-scratch
"bi" 'ibuffer
;; Windows
"wv" 'split-window-right
"wh" 'split-window-below
"wt" 'window-split-toggle
"ws" 'ace-window
;; Help
"hh" 'help
"hk" 'describe-key
"hv" 'describe-variable
"hF" 'describe-function
"hf" 'describe-face
"hs" 'describe-symbol
"hm" 'describe-mode))
Evil multiple cursors (disabled)
(use-package evil-multiedit
:after evil
:bind
(:map evil-normal-state-map
("M-d". evil-multiedit-match-symbol-and-next)
("M-D". evil-multiedit-match-symbol-and-prev)
("C-M-d". evil-multiedit-match-all)
:map evil-visual-state-map
("M-d". evil-multiedit-match-and-next)
("M-D". evil-multiedit-match-and-prev)
("C-M-d". evil-multiedit-match-all)))
Set evil states
(evil-set-initial-state 'ibuffer-mode 'normal)
(evil-set-initial-state 'bookmark-bmenu-mode 'normal)
(evil-set-initial-state 'vterm-mode 'normal)
(evil-set-initial-state 'calibredb-mode 'normal)
;; (evil-set-initial-state 'dired-mode 'emacs)
(evil-set-initial-state 'sunrise-mode 'emacs)
FZF
(use-package fzf
:ensure t
:bind
;; Don't forget to set keybinds!
:config
(setq fzf/args "-x --color bw --print-query --margin=1,0 --no-hscroll"
fzf/executable "fzf"
fzf/git-grep-args "-i --line-number %s"
;; command used for `fzf-grep-*` functions
;; example usage for ripgrep:
;; fzf/grep-command "rg --no-heading -nH"
fzf/grep-command "grep -nrH"
;; If nil, the fzf buffer will appear at the top of the window
fzf/position-bottom t
fzf/window-height 15))
Git
Magit
Magit
(use-package magit
:ensure t
:commands (magit-status magit-ediff-show-working-tree)
:bind ("C-c C-d" . magit-ediff-show-working-tree)
:custom (magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1))
Magit todos
(use-package magit-todos
:ensure t
:commands (magit-todos-mode)
:hook (magit-mode . magit-todos-mode)
:config
(setq magit-todos-recursive t
magit-todos-depth 4
magit-todos-exclude-globs '("*Pods*" ".git/" "*elpa*" "*var/lsp/*" "node_modules/" "target/"))
(custom-set-variable
'(magit-todos-keywords (list "TODO" "FIXME" "BUGFIX" "HACK"))))
Blamer
(use-package blamer
:ensure t
:bind (("s-i" . blamer-show-commit-info)
("C-c i" . ("s-i" . blamer-show-posframe-commit-info)))
:defer 20
:custom
(blamer-idle-time 0.3)
(blamer-min-offset 70)
:custom-face
(blamer-face ((t :foreground "#7a88cf"
:background nil
:height 140
:italic t)))
:config
(setq blamer-view 'overlay
blamer-type 'posframe-popup
blamer-max-commit-message-length 70
blamer-force-truncate-long-line nil
blamer-author-formatter " ✎ [%s] - "
blamer-commit-formatter "● %s ● ")
(global-blamer-mode 1))
(defun blamer-callback-show-commit-diff (commit-info)
(interactive)
(let ((commit-hash (plist-get commit-info :commit-hash)))
(when commit-hash
(magit-show-commit commit-hash))))
(defun blamer-callback-open-remote (commit-info)
(interactive)
(let ((commit-hash (plist-get commit-info :commit-hash)))
(when commit-hash
(message commit-hash)
(forge-browse-commit commit-hash))))
(setq blamer-bindings '(("<mouse-3>" . blamer-callback-open-remote)
("<mouse-1>" . blamer-callback-show-commit-diff)))
;; (use-package blamer
;; :ensure t
;; :commands (blamer-mode)
;; :config
;; (setq blamer-view 'overlay
;; blamer-type 'posframe-popup
;; blamer-max-commit-message-length 70
;; blamer-force-truncate-long-line nil
;; blamer-author-formatter " ✎ [%s] - "
;; blamer-commit-formatter "● %s ● ")
;; :custom
;; (blamer-idle-time 1.0)
;; :custom-face
;; (blamer-face ((t :foreground "#E46876"
;; :height 140
;; :italic t))))
Git gutter
(use-package git-gutter
:ensure t
:hook (prog-mode . git-gutter-mode)
:diminish git-gutter-mode
:config
(setq git-gutter:update-interval 0.5))
(use-package git-gutter-fringe
:ensure t
:after git-gutter
:config
(define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
(define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
(define-fringe-bitmap 'git-gutter-fr:deleted [224] nil nil '(center repeated)))
(global-git-gutter-mode +1)
Projectile
(use-package projectile
:ensure t
:init
(projectile-mode +1)
:bind (:map projectile-mode-map
("s-p" . projectile-command-map)
("C-c p" . projectile-command-map)))
(defun my/highlight-todo-like-words ()
(font-lock-add-keywords
nil `(("\\<\\(FIXME\\|TODO\\)"
1 font-lock-warning-face t))))
(add-hook 'prog-mode-hook 'my/highlight-todo-like-words)
(setq projectile-globally-ignored-files "node_modules")
Telega.el
(use-package telega
:ensure t
:config
(setq telega-use-docker t)
(add-hook 'telega-load-hook 'telega-notifications-mode)
(add-hook 'telega-load-hook 'telega-appindicator-mode)
(add-hook 'telega-load-hook 'global-telega-url-shorten-mode))
Treemacs
(use-package treemacs
:ensure t
:defer t
:init
(with-eval-after-load 'winum
(define-key winum-keymap (kbd "M-0") 'treemacs-select-window))
:config
(progn
(setq treemacs-collapse-dirs (if treemacs-python-executable 3 0)
treemacs-deferred-git-apply-delay 0.5
treemacs-directory-name-transformer #'identity
treemacs-display-in-side-window t
treemacs-eldoc-display 'simple
treemacs-file-event-delay 2000
treemacs-file-extension-regex treemacs-last-period-regex-value
treemacs-file-follow-delay 0.2
treemacs-file-name-transformer #'identity
treemacs-follow-after-init t
treemacs-expand-after-init t
treemacs-find-workspace-method 'find-for-file-or-pick-first
treemacs-git-command-pipe ""
treemacs-goto-tag-strategy 'refetch-index
treemacs-header-scroll-indicators '(nil . "^^^^^^")
treemacs-hide-dot-git-directory t
treemacs-indentation 2
treemacs-indentation-string " "
treemacs-is-never-other-window nil
treemacs-max-git-entries 5000
treemacs-missing-project-action 'ask
treemacs-move-forward-on-expand nil
treemacs-no-png-images nil
treemacs-no-delete-other-windows t
treemacs-project-follow-cleanup nil
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
treemacs-position 'left
treemacs-read-string-input 'from-child-frame
treemacs-recenter-distance 0.1
treemacs-recenter-after-file-follow nil
treemacs-recenter-after-tag-follow nil
treemacs-recenter-after-project-jump 'always
treemacs-recenter-after-project-expand 'on-distance
treemacs-litter-directories '("/node_modules" "/.venv" "/.cask")
treemacs-show-cursor nil
treemacs-show-hidden-files t
treemacs-silent-filewatch nil
treemacs-silent-refresh nil
treemacs-sorting 'alphabetic-asc
treemacs-select-when-already-in-treemacs 'move-back
treemacs-space-between-root-nodes t
treemacs-tag-follow-cleanup t
treemacs-tag-follow-delay 1.5
treemacs-text-scale nil
treemacs-user-mode-line-format nil
treemacs-user-header-line-format nil
treemacs-wide-toggle-width 70
treemacs-width 35
treemacs-width-increment 1
treemacs-width-is-initially-locked t
treemacs-workspace-switch-cleanup nil)
;; The default width and height of the icons is 22 pixels. If you are
;; using a Hi-DPI display, uncomment this to double the icon size.
;; (treemacs-resize-icons 48)
(treemacs-follow-mode t)
(treemacs-filewatch-mode t)
(treemacs-fringe-indicator-mode 'always)
(when treemacs-python-executable
(treemacs-git-commit-diff-mode t))
(pcase (cons (not (null (executable-find "git")))
(not (null treemacs-python-executable)))
(`(t . t)
(treemacs-git-mode 'deferred))
(`(t . _)
(treemacs-git-mode 'simple)))
(treemacs-hide-gitignored-files-mode nil))
:bind
(:map global-map
("M-0" . treemacs-select-window)
("C-x t 1" . treemacs-delete-other-windows)
("C-x t t" . treemacs)
("C-x t d" . treemacs-select-directory)
("C-x t B" . treemacs-bookmark)
("C-x t C-t" . treemacs-find-file)
("C-x t M-t" . treemacs-find-tag)))
(use-package treemacs-all-the-icons
:ensure t)
;; (treemacs-load-theme "all-the-icons")
(use-package treemacs-evil
:after (treemacs evil)
:ensure t)
Terminal (vterm, multi-vterm)
vterm + multi-vterm
(use-package vterm
:ensure t)
(use-package multi-vterm
:ensure t
:bind
("C-x q" . vterm-clear)
("C-x w" . multi-vterm))
Other packages
Helm
(use-package helm
:ensure t
:defer t
:custom
(helm-M-x-use-completion-styles nil)
(helm-split-window-inside-p t)
(helm-follow-mode-persistent t)
(helm-buffers-show-icons t)
:bind (:map helm-map
("<tab>" . 'helm-execute-persistent-action))
:config
(helm-mode 1))
(with-eval-after-load 'helm
(add-to-list 'display-buffer-alist
'("\\`\\*helm.*\\*\\'"
(display-buffer-in-side-window)
(inhibit-same-window . t)
(window-height . 0.4))))
Reverse im
;; Needed for `:after char-fold' to work
(use-package char-fold
:custom
(char-fold-symmetric t)
(search-default-mode #'char-fold-to-regexp))
(use-package reverse-im
:ensure t ; install `reverse-im' using package.el
:demand t ; always load it
:after char-fold ; but only after `char-fold' is loaded
:bind
("M-T" . reverse-im-translate-word) ; fix a word in wrong layout
:custom
(reverse-im-char-fold t) ; use lax matching
(reverse-im-read-char-advice-function #'reverse-im-read-char-include)
(reverse-im-input-methods '("ukrainian-computer")) ; translate these methods
:config
(reverse-im-mode t)) ; turn the mode on
Format all
(use-package format-all
:ensure t
:preface
(defun ian/format-code ()
"Auto-format whole buffer."
(interactive)
(if (derived-mode-p 'prolog-mode)
(prolog-indent-buffer)
(format-all-buffer)))
:config
(global-set-key (kbd "M-F") 'ian/format-code)
(add-hook 'prog-mode-hook 'format-all-ensure-formatter))
Emojify
(use-package emojify
:ensure t
:config
(when (member "Segoe UI Emoji" (font-family-list))
(set-fontset-font
t 'symbol (font-spec :family "Segoe UI Emoji") nil 'prepend))
(setq emojify-display-style 'unicode)
(setq emojify-emoji-styles '(unicode))
(bind-key* (kbd "C-c e") #'emojify-insert-emoji)) ; override binding in any mode
Rainbow delimiter
(use-package rainbow-delimiters
:ensure t
:hook
(prog-mode . rainbow-delimiters-mode))
Which key
(use-package which-key
:ensure t
:config (which-key-mode))
Zygospore (to easy fullscreening split screens)
(use-package zygospore :ensure t)
(global-set-key (kbd "C-x 1") 'zygospore-toggle-delete-other-windows)
all-the-icons
(use-package all-the-icons
:if (display-graphic-p))
Indent mode
Show vertical lines to guide indentation
(use-package indent-guide
:ensure t
:config
(indent-guide-global-mode))
Parrot
(defun my/parrot-animate-when-compile-success (buffer result)
(if (string-match "^finished" result)
(parrot-start-animation)))
(use-package parrot
:ensure t
:config
(parrot-mode)
(parrot-set-parrot-type 'thumbsup)
(add-hook 'before-save-hook 'parrot-start-animation)
(add-to-list 'compilation-finish-functions 'my/parrot-animate-when-compile-success))
Highlight TODO
(use-package hl-todo
:ensure t
:config
(hl-todo-mode t))
Setting keymap
;; zoom in/out like we do everywhere else.
(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "<C-wheel-up>") 'text-scale-increase)
(global-set-key (kbd "<C-wheel-down>") 'text-scale-decrease)
; Mak;; ESC quit prompts
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
(global-auto-revert-mode t)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "M-x") 'helm-M-x)
;;Org
(global-set-key (kbd "M-q") #'toggle-truncate-lines)
;; Org agenda
(global-set-key (kbd "C-c l") #'org-store-link)
(global-set-key (kbd "C-c a") #'org-agenda)
(global-set-key (kbd "C-c c") #'org-capture)
;; Org timer
(global-set-key (kbd "C-c t s") #'org-timer-set-timer)
(global-set-key (kbd "C-c t SPC") #'org-timer-pause-or-continue)
(global-set-key (kbd "C-c t <deletechar>") #'org-timer-stop)
(global-set-key (kbd "\C-c w") 'evil-window-map)
(global-set-key (kbd "\C-c f") 'format-all-buffer)
(xterm-mouse-mode t)
(setq-default tab-width 2) ; set default tab char's display width to 2 spaces
(setq tab-width 2) ; set current buffer's tab char's display width to 2 spaces
(dolist (mode '(org-mode-hook ; Disable line numbers for some modes
term-mode-hook
vterm-mode-hook
shell-mode-hook
treemacs-mode-hook
eshell-mode-hook
nov-mode-hook
neotree-mode-hook
pdf-view-mode-hook))
(add-hook mode (lambda () (display-line-numbers-mode 0))))
Setting LSP
(lsp-treemacs-sync-mode 1)
(helm-mode 1)
Setting Company
(use-package company
:ensure t
:hook (after-init . global-company-mode)
:config
(setq company-idle-delay 0
company-minimum-prefix-length 1
company-tooltip-limit 10
company-show-numbers t
company-dabbrev-downcase nil
company-dabbrev-ignore-case nil
company-require-match nil
company-global-modes '(not erc-mode message-mode help-mode)
company-transformers '(company-sort-by-occurrence))
;; Enable company mode in specific modes
(add-hook 'rust-mode-hook #'company-mode)
(add-hook 'go-mode-hook #'company-mode)
(add-hook 'typescript-mode-hook #'company-mode)
(add-hook 'js-mode-hook #'company-mode)
(add-hook 'rjsx-mode-hook #'company-mode)
;; Set up company backends for each major mode
(setq company-backends-rust '((company-capf company-files)))
(setq company-backends-go '((company-capf company-files)))
(setq company-backends-typescript '((company-tide company-files)))
(setq company-backends-js '((company-tide company-files)))
(setq company-backends-react '((company-tide company-files)))
;; Set keybindings for company
(define-key company-active-map (kbd "C-n") 'company-select-next)
(define-key company-active-map (kbd "C-p") 'company-select-previous)
(define-key company-active-map (kbd "TAB") 'company-complete-common-or-cycle)
(define-key company-active-map (kbd "<tab>") 'company-complete-common-or-cycle)
(define-key company-active-map (kbd "RET") 'company-complete-selection))
BibTeX company
(use-package company-bibtex
:ensure t)
AUCTeX company
(use-package ac-math
:ensure t)
(use-package company-auctex
:ensure t)
(company-auctex-init)
Setting company-org-block
(use-package company-org-block
:ensure t
:custom
(company-org-block-edit-style 'auto) ;; 'auto, 'prompt, or 'inline
:hook ((org-mode . (lambda ()
(setq-local company-backends '(company-org-block))
(company-mode +1)))))
Setting yasnippet
(use-package yasnippet :ensure t)
Setting LSP-Mode
LSP-Mode
(use-package lsp-mode
:init
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "C-c l")
(setq lsp-tex-server 'digestif)
:hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
(go-mode . lsp)
(javascript-mode . lsp)
(typescript-mode . lsp)
(rust-mode . lsp)
;; if you want which-key integration
(lsp-mode . lsp-enable-which-key-integration))
(LaTeX-mode . lsp)
:commands lsp)
;; optionally
(use-package lsp-ui
:ensure t
:commands lsp-ui-mode
:config
(setq lsp-ui-doc-enable t)
(setq lsp-ui-sideline-show-diagnostics t)
(setq lsp-ui-sideline-show-hover t))
;; if you are helm user
(use-package helm-lsp :commands helm-lsp-workspace-symbol)
;; if you are ivy user
(use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
;; Symbol highlighting
(setq lsp-enable-symbol-highlighting nil)
(use-package lsp-treemacs :ensure t :commands lsp-treemacs-errors-list)
;; optionally if you want to use debugger
(use-package dap-mode :ensure t)
;; (use-package dap-LANGUAGE) to load the dap adapter for your language
LSP UI
(use-package lsp-ui :ensure t)
JavaScript
(use-package web-mode :ensure t
:mode (("\\.js\\'" . web-mode)
("\\.jsx\\'" . web-mode)
("\\.ts\\'" . web-mode)
("\\.tsx\\'" . typescript-mode)
("\\.html\\'" . web-mode)
("\\.vue\\'" . web-mode)
("\\.json\\'" . web-mode))
:commands web-mode
:config
(setq web-mode-content-types-alist
'(("jsx" . "\\.js[x]?\\'")))
)
(use-package import-js :ensure t)
;; JSX syntax highlighting
(add-to-list 'auto-mode-alist '("\\.jsx?$" . web-mode)) ;; auto-enable for .js/.jsx files
(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))
(use-package js2-mode :ensure t :defer 20
:mode
(("\\.js\\'" . js2-mode))
:custom
(js2-include-node-externs t)
;;(js2-global-externs '("customElements"))
(js2-highlight-level 3)
(js2r-prefer-let-over-var t)
(js2r-prefered-quote-type 2)
(js-indent-align-list-continuation t)
(global-auto-highlight-symbol-mode t)
:config
(setq js-indent-level 2)
;; patch in basic private field support
(advice-add #'js2-identifier-start-p
:after-until
(lambda (c) (eq c ?#))))
(add-hook 'web-mode-hook #'(lambda ()
(enable-minor-mode
'("\\.jsx?\\'" . prettier-js-mode))))
(add-hook 'web-mode-hook #'(lambda ()
(enable-minor-mode
'("\\.tsx?\\'" . prettier-js-mode))))
(add-hook 'web-mode-hook 'prettier-js-mode)
TypeScript Tide
(use-package tide
:ensure t
:after (typescript-mode company flycheck)
:hook ((typescript-mode . tide-setup)
(typescript-mode . tide-hl-identifier-mode)
(before-save . tide-format-before-save)))
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
(company-mode +1))
;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)
;; formats the buffer before saving
(add-hook 'before-save-hook 'tide-format-before-save)
(add-hook 'typescript-mode-hook #'setup-tide-mode)
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
(add-hook 'web-mode-hook
(lambda ()
(when (string-equal "tsx" (file-name-extension buffer-file-name))
(setup-tide-mode))))
;; enable typescript-tslint checker
(flycheck-add-mode 'typescript-tslint 'web-mode)
(add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
(add-hook 'web-mode-hook
(lambda ()
(when (string-equal "jsx" (file-name-extension buffer-file-name))
(setup-tide-mode))))
;; configure jsx-tide checker to run after your default jsx checker
(flycheck-add-mode 'javascript-eslint 'web-mode)
;; (flycheck-add-next-checker 'javascript-eslint 'jsx-tide 'append)
JSON
(use-package json-mode :ensure t :defer 20
:custom
(json-reformat:indent-width 2)
:mode (("\\.bowerrc$" . json-mode)
("\\.jshintrc$" . json-mode)
("\\.json_schema$" . json-mode)
("\\.json\\'" . json-mode))
:bind (:package json-mode-map
:map json-mode-map
("C-c <tab>" . json-mode-beautify)))
Vue.js (disabled)
(use-package vue-mode
:mode "\\.vue\\'"
:config
(add-hook 'vue-mode-hook 'lsp))
(setq vue-mode-packages
'(vue-mode))
(setq vue-mode-excluded-packages '())
(defun vue-mode/init-vue-mode ()
"Initialize my package"
(use-package vue-mode))
Golang
;; Set up before-save hooks to format buffer and add/delete imports.
;; Make sure you don't have other gofmt/goimports hooks enabled.
(defun lsp-go-install-save-hooks ()
(add-hook 'before-save-hook 'lsp-format-buffer t t)
(add-hook 'before-save-hook 'lsp-organize-imports t t))
(add-hook 'go-mode-hook 'lsp-go-install-save-hooks)
;; (lsp-register-custom-settings
;; '(("gopls.completeUnimported" t t)
;; ("gopls.staticcheck" t t)))
Rust
*Quick start with rust-analyzer*
cargo install rustfmt
cargo install racer
(use-package rust-playground :ensure t)
(use-package rust-mode
:ensure t
:if (executable-find "rustc"))
(use-package cargo
:ensure t
:if (executable-find "cargo")
:after rust-mode
:bind (:map cargo-minor-mode-map
("C-c C-t" . cargo-process-test)
("C-c C-b" . cargo-process-build)
("C-c C-c" . cargo-process-run))
:config
(add-hook 'rust-mode-hook 'cargo-minor-mode))
(add-hook 'rust-mode-hook 'lsp-deferred)
;; (use-package racer
;; :ensure t
;; :if (executable-find "racer")
;; :after rust-mode
;; :custom
;; (racer-rust-src-path "~/Code/rust/src/src")
;; :hook ((rust-mode . racer-mode)
;; (racer-mode . eldoc-mode)
;; (racer-mode . company-mode))
;; :config
;; (evil-leader/set-key-for-mode 'rust-mode "d" 'racer-find-definition))
Flycheck
(use-package flycheck
:ensure t
:hook (prog-mode . flycheck-mode)
:diminish
:custom
(flycheck-indication-mode 'left-fringe)
(flycheck-display-errors-delay 0.2)
(flycheck-check-syntax-automatically '(save idle-change))
(flycheck-idle-change-delay 2))
(use-package flycheck-inline
:ensure t
:hook (flycheck-mode . turn-on-flycheck-inline))
(use-package flycheck-rust
:ensure t
:config
(with-eval-after-load 'rust-mode
(add-hook 'flycheck-mode-hook #'flycheck-rust-setup)))
Tree Sitter
(use-package tree-sitter
:ensure t
:config
;; activate tree-sitter on any buffer containing code for which it has a parser available
(global-tree-sitter-mode)
;; you can easily see the difference tree-sitter-hl-mode makes for python, ts or tsx
;; by switching on and off
(add-hook 'tree-sitter-after-on-hook 'tree-sitter-hl-mode))
(use-package tree-sitter-langs
:ensure t
:after tree-sitter)
;; auto-format different source code files extremely intelligently
;; https://github.com/radian-software/apheleia
(use-package apheleia
:ensure t
:config
(apheleia-global-mode +1))
;; (add-hook 'prog-mode-hook 'linum-mode)
(add-hook 'prog-mode-hook 'visual-line-mode)
(add-hook 'prog-mode-hook 'show-paren-mode)
(add-hook 'prog-mode-hook 'hs-minor-mode)
Setting performance
Better GC
(defvar better-gc-cons-threshold 134217728 ; 128mb
"If you experience freezing, decrease this.
If you experience stuttering, increase this.")
(add-hook 'emacs-startup-hook
(lambda ()
(setq gc-cons-threshold better-gc-cons-threshold)
(setq file-name-handler-alist file-name-handler-alist-original)
(makunbound 'file-name-handler-alist-original)))
Auto GC
(add-hook 'emacs-startup-hook
(lambda ()
(if (boundp 'after-focus-change-function)
(add-function :after after-focus-change-function
(lambda ()
(unless (frame-focus-state)
(garbage-collect))))
(add-hook 'after-focus-change-function 'garbage-collect))
(defun gc-minibuffer-setup-hook ()
(setq gc-cons-threshold (* better-gc-cons-threshold 2)))
(defun gc-minibuffer-exit-hook ()
(garbage-collect)
(setq gc-cons-threshold better-gc-cons-threshold))
(add-hook 'minibuffer-setup-hook #'gc-minibuffer-setup-hook)
(add-hook 'minibuffer-exit-hook #'gc-minibuffer-exit-hook)))