diff --git a/configuration.nix b/configuration.nix index c6b2c69..bf68e90 100644 --- a/configuration.nix +++ b/configuration.nix @@ -11,11 +11,17 @@ let config = ./emacs.el; defaultInitFile = true; package = pkgs.emacs29-pgtk.overrideAttrs (old: { withTreeSitter = true; }); - alwaysEnsure = true; + #alwaysEnsure = true; extraEmacsPackages = epkgs: [ pkgs.mu + pkgs.mu.mu4e epkgs.treesit-grammars.with-all-grammars + epkgs.evil-collection ]; + override = final: prev: { + evil-collection = prev.melpaPackages.evil-collection.overrideAttrs + (old: { patches = [ ./evil-collection.patch ]; }); + }; }); in { @@ -175,6 +181,7 @@ in { neovim go gopls + lazygit #network-manager-applet (clang-tools.override { llvmPackages = llvmPackages_17; @@ -388,7 +395,18 @@ in { home-manager.users.knazarov = { # The home.stateVersion option does not have a default and must be set - home.stateVersion = "23.05"; + home.stateVersion = "23.11"; + + home.sessionVariables = { EDITOR = "emacs -nw --no-splash"; }; + + programs.lf = { + enable = true; + extraConfig = '' + set sixel true + set previewer ${pkgs.chafa}/bin/chafa + ''; + + }; programs.bash = { enable = true; @@ -398,11 +416,23 @@ in { && [[ -f ''${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh ]]; then source ''${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh fi + + lfcd () { + tmp="$(mktemp -uq)" + trap 'rm -f $tmp >/dev/null 2>&1 && trap - HUP INT QUIT TERM PWR EXIT' HUP INT QUIT TERM PWR EXIT + lf -last-dir-path="$tmp" "$@" + if [ -f "$tmp" ]; then + dir="$(cat "$tmp")" + [ -d "$dir" ] && [ "$dir" != "$(pwd)" ] && cd "$dir" + fi + } + bind '"\C-o":"lfcd\n"' ''; shellAliases = { nn = "notes.sh -n"; ne = ''notes.sh -l | fzf --tac --with-nth="2..-1" | xargs -o notes.sh -e''; + vim = "emacs -nw --no-splash"; }; }; @@ -471,10 +501,12 @@ in { create = "maildir"; }; + neomutt = { enable = true; }; }; }; }; + programs.neomutt = { enable = true; }; programs.mu = { enable = true; }; programs.msmtp.enable = true; @@ -510,54 +542,6 @@ in { }; - programs.neovim = let - modus-themes = pkgs.vimUtils.buildVimPlugin { - pname = "modus-themes.nvim"; - version = "2024-05-06"; - src = pkgs.fetchFromGitHub { - owner = "miikanissi"; - repo = "modus-themes.nvim"; - rev = "705ea8debb9d9afe4e631166fcc6121782dd0b32"; - sha256 = "0hs2ylf1rj0655kpwr4blh399r8k7lg0r2a4nbnymy1pbkx1gh1i"; - }; - meta.homepage = "https://github.com/miikanissi/modus-themes.nvim/"; - }; - - in { - enable = true; - plugins = with pkgs; [ - vimPlugins.nvim-treesitter - vimPlugins.nvim-treesitter.withAllGrammars - pkgs.vimPlugins.nvim-treesitter-textobjects - vimPlugins.nvim-lspconfig - - vimPlugins.lualine-nvim - vimPlugins.telescope-nvim - vimPlugins.telescope-fzf-native-nvim - vimPlugins.nvim-web-devicons - - vimPlugins.nvim-cmp - vimPlugins.cmp-nvim-lsp - vimPlugins.cmp-buffer - vimPlugins.cmp-cmdline - vimPlugins.luasnip - - modus-themes - ]; - extraConfig = '' - lua << EOF - ${builtins.readFile nvim/basics.lua} - ${builtins.readFile nvim/treesitter.lua} - ${builtins.readFile nvim/lualine.lua} - ${builtins.readFile nvim/telescope.lua} - ${builtins.readFile nvim/completion.lua} - ${builtins.readFile nvim/luasnip.lua} - ${builtins.readFile nvim/lspconfig.lua} - ''; - viAlias = true; - vimAlias = true; - }; - wayland.windowManager.sway = { enable = true; xwayland = true; @@ -577,7 +561,8 @@ in { "XF86MonBrightnessDown" = "exec brightnessctl s 5%-"; #"Mod4+Return" = #"exec emacs --eval '(progn (setq confirm-kill-processes nil) (vterm))'"; - "Mod4+Return" = "exec emacsclient -c"; + #"Mod4+Return" = "exec emacsclient -c"; + "Mod4+Return" = "exec foot"; "Mod4+space" = "exec ${pkgs.foot}/bin/foot -T mylauncher -a mylauncher ${pkgs.q-sh}/bin/q"; "Mod4+p" = diff --git a/emacs.el b/emacs.el index 0348180..d425282 100755 --- a/emacs.el +++ b/emacs.el @@ -1,4 +1,5 @@ ;; -------- Speed up load time ------- +;; (package-initialize) ;; I don't use emacs-server, so startup times are very important to me. @@ -23,10 +24,25 @@ gc-cons-percentage 0.1) (setq file-name-handler-alist saved--file-name-handler-alist))) + +;; Required by use-package :bind in compiled mode +(require 'bind-key) + +(setq package-enable-at-startup nil) +(setq package-archives nil) +(add-to-list 'package-archives + '("melpa" . "https://melpa.org/packages/") t) +(add-to-list 'package-archives + '("gnu" . "http://elpa.gnu.org/packages/") t) + + + +;;(setq initial-major-mode 'text-mode) + ;; -------- Default directories -------- (setq default-directory "~/") -(setq command-line-default-directory "~/") +;;(setq command-line-default-directory "~/") ;; -------- State files -------- @@ -46,28 +62,38 @@ ;; is preserved. (setq savehist-file "~/.emacs.d/savehist") -(savehist-mode +1) -(setq savehist-save-minibuffer-history +1) -(setq savehist-additional-variables - '(kill-ring - search-ring - regexp-search-ring)) + +(use-package savehist-mode + :defer 1 + :config + (setq savehist-save-minibuffer-history +1) + (setq savehist-additional-variables + '(kill-ring + search-ring + regexp-search-ring)) + (savehist-mode +1) + ) + ;; -------- Recent files -------- ;; Recent files are convenient to record because you can use them to ;; quickly jump to what you've been editing recently. -(setq recentf-save-file "~/.emacs.d/recentf" - recentf-max-menu-items 0 - recentf-max-saved-items 300 - recentf-filename-handlers '(file-truename) - recentf-exclude - (list "^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$" - "^/var/folders/.+$" - )) -(recentf-mode 1) +(use-package recentf-mode + :defer 1 + :config + (setq recentf-save-file "~/.emacs.d/recentf" + recentf-max-menu-items 0 + recentf-max-saved-items 300 + recentf-filename-handlers '(file-truename) + recentf-exclude + (list "^/tmp/" "^/ssh:" "\\.?ido\\.last$" "\\.revive$" "/TAGS$" + "^/var/folders/.+$" + )) + (recentf-mode 1) + ) ;; -------- De-clutter -------- @@ -76,7 +102,9 @@ (tool-bar-mode -1) (scroll-bar-mode -1) +(setq inhibit-start-screen 1) (setq inhibit-startup-screen t) +(setq inhibit-splash-screen t) (if (not (eq window-system 'mac)) (menu-bar-mode -1)) @@ -88,7 +116,12 @@ (setq-default window-divider-default-places t window-divider-default-bottom-width 0 window-divider-default-right-width 1) -(window-divider-mode +1) + +(use-package window-divider-mode + :defer 1 + :config + (window-divider-mode +1) + ) ;; Remove continuation arrow on right fringe @@ -102,8 +135,11 @@ (setq initial-scratch-message "") ;; Hide modeline in the vterm mode -(use-package hide-mode-line) -(add-hook 'vterm-mode-hook #'hide-mode-line-mode) +(use-package hide-mode-line + :ensure t + :defer t + :hook (vterm-mode . hide-mode-line-mode) + ) ;; Disable "when done with this frame..." message when running ;; emacsclient @@ -143,15 +179,7 @@ ;; Hide some miror modes from sight to not clutter the modeline -(use-package diminish) -(require 'diminish) - -(diminish 'company-mode) -(diminish 'projectile-mode) -(diminish 'editorconfig-mode) -(diminish 'eldoc-mode) -(diminish 'flycheck-mode) -(diminish 'which-key-mode) +(use-package diminish :ensure t) ;; -------- Theme -------- @@ -159,8 +187,11 @@ ;; background color ;; - Panels look better without outset/inset shadows -(use-package modus-themes) -(load-theme 'modus-operandi t) +(use-package modus-themes + :ensure t + :config + (load-theme 'modus-operandi t) + ) (set-face-attribute 'fringe nil :foreground (face-foreground 'default) @@ -201,13 +232,6 @@ Intended for `after-make-frame-functions'." ;; -------- Packages -------- -(diminish 'company-mode) -(diminish 'projectile-mode) -(diminish 'editorconfig-mode) -(diminish 'eldoc-mode) -(diminish 'flycheck-mode) -(diminish 'which-key-mode) - ;; -------- Navigation -------- ;; Quickly find my way around emacs @@ -215,7 +239,7 @@ Intended for `after-make-frame-functions'." ;; Default scheme for uniquifying buffer names is not convenient. ;; It's better to have a regular path-like structure. -;;(require 'uniquify) +;;(use-package 'uniquify) (setq uniquify-buffer-name-style 'forward) (setq uniquify-separator "/") (setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified @@ -226,35 +250,55 @@ Intended for `after-make-frame-functions'." ;; options in minibuffer. -(use-package which-key) -(add-hook 'after-init-hook 'which-key-mode) -(with-eval-after-load 'which-key - (which-key-setup-side-window-bottom)) +(use-package which-key + :defer 2 + :config + (which-key-mode) + (which-key-setup-side-window-bottom) + ) ;; persp-mode allows you to have tagged workspaces akin to ;; Linux tiled-window managers. -(use-package persp-mode) -;; persp-mode clashes with corfu -(setq persp-auto-resume-time 0) -(add-hook 'after-init-hook 'persp-mode) -(global-set-key (kbd "C-x x s") 'persp-switch) +;;(use-package persp-mode + ;;:ensure t + ;;:bind + ;;("C-x x s" . persp-switch) + ;;:init + ;;;; persp-mode clashes with corfu + ;;(setq persp-auto-resume-time 0) + ;;:config + ;;(persp-mode) + ;;) ;; vertico-mode allows for easy navigation between buffers and files -(use-package vertico) -(add-hook 'after-init-hook 'vertico-mode) -(setq completion-ignore-case t) -(setq completion-styles '(basic substring partial-completion flex)) +(use-package vertico + :ensure t + :defer 0.1 + :config + (require 'bind-key) + (setq completion-ignore-case t) + (setq completion-styles '(basic substring partial-completion flex)) + (vertico-mode) + ) -(use-package marginalia) -(add-hook 'after-init-hook 'marginalia-mode) +(use-package marginalia + :ensure t + :defer 0.1 + :config + (marginalia-mode) + ) ;; ripgrep search with consult -(use-package consult) -(global-set-key (kbd "M-s r") 'consult-ripgrep) -(setq completion-in-region-function 'consult-completion-in-region) +(use-package consult + :ensure t + :defer 0.1 + :config + (global-set-key (kbd "M-s r") 'consult-ripgrep) + (setq completion-in-region-function 'consult-completion-in-region) + ) ;; Navigation when in russian layout @@ -279,9 +323,12 @@ Intended for `after-make-frame-functions'." ;; But use editorconfig to guess proper project-wide indentation rules -(use-package editorconfig) -(add-hook 'prog-mode-hook #'editorconfig-mode) - +(use-package editorconfig + :ensure t + :defer t + :diminish editorconfig-mode + :hook (prog-mode . editorconfig-mode) + ) ;; Speed up comint buffers by disabling bidirectional language support @@ -292,521 +339,563 @@ Intended for `after-make-frame-functions'." ;; Evil mode is a vi/vim compatibility layer for Emacs that provides roughly ;; equivalent keybindings for editing. -(setq evil-want-keybinding nil) -(setq evil-want-C-u-scroll t) -(use-package evil) -(use-package evil-collection) -(add-hook 'after-init-hook #'(lambda () - (evil-mode 1) - (evil-set-undo-system 'undo-redo) - (evil-collection-init))) +(use-package evil + :ensure t + :defer .1 ;; don't block emacs when starting, load evil immediately after startup -(evil-set-leader 'normal " ") -(evil-define-key 'normal 'global (kbd "f") 'find-file) -(evil-define-key 'normal 'global (kbd "b") 'switch-to-buffer) -(evil-define-key 'normal 'global (kbd "r") 'consult-ripgrep) + :init + ;;(setq evil-want-integration nil) ;; required by evil-collection + (setq evil-want-keybinding nil) + (setq evil-want-C-u-scroll t) -;; Make :q close the current buffer, and not the whole emacs process -(global-set-key [remap evil-quit] 'kill-buffer-and-window) + :config + + (evil-mode) + (evil-set-leader 'normal " ") + (evil-set-undo-system 'undo-redo) + + (evil-define-key 'normal 'global (kbd "f") 'find-file) + (evil-define-key 'normal 'global (kbd "b") 'switch-to-buffer) + (evil-define-key 'normal 'global (kbd "r") 'consult-ripgrep) + + ;; Make :q close the current buffer, and not the whole emacs process + (global-set-key [remap evil-quit] 'kill-buffer-and-window) + + (use-package evil-collection + :after evil + :diminish evil-collection-unimpaired-mode + :config + (evil-collection-init)) + ) + +(use-package evil-terminal-cursor-changer + :ensure t + :if (not (display-graphic-p)) + :after evil + :defer t + :init (evil-terminal-cursor-changer-activate)) ;; -------- Tools and environment -------- ;; By default, Emacs doesn't add system path to its search places -(use-package exec-path-from-shell) -(require 'exec-path-from-shell) -(setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH"))) +(use-package exec-path-from-shell + :ensure t + :defer 1 + :config + (setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH"))) -;; On a mac, this will set up PATH and MANPATH from your environment -(when (memq window-system '(mac ns x pgtk)) - (exec-path-from-shell-initialize)) + ;; On a mac, this will set up PATH and MANPATH from your environment + (when (memq window-system '(mac ns x pgtk)) + (exec-path-from-shell-initialize)) + ) ;; -------- Org roam -------- -(use-package org) -(use-package org-contrib) -(use-package org-roam) -(use-package consult-org-roam) +(use-package org-roam + :ensure t + :defer t + :bind + ("C-c n l" . org-roam-buffer-toggle) + ("C-c n i" . org-roam-node-insert) + ("C-c n f" . org-roam-node-find) + ("C-c n r" . consult-org-roam-search) + ("C-c n d" . org-roam-dailies-goto-today) + ("C-c n w" . org-roam-week) -(setq org-roam-completion-everywhere t) -(setq org-roam-directory "~/notes") -(setq org-roam-node-default-sort 'file-mtime) -(setq consult-org-roam-grep-func #'consult-ripgrep) + :config + (use-package consult-org-roam + :ensure t + ) -(global-set-key (kbd "C-c n l") 'org-roam-buffer-toggle) -(global-set-key (kbd "C-c n i") 'org-roam-node-insert) -(global-set-key (kbd "C-c n f") 'org-roam-node-find) -(global-set-key (kbd "C-c n r") 'consult-org-roam-search) -(global-set-key (kbd "C-c n d") 'org-roam-dailies-goto-today) + (setq org-roam-directory "~/notes") + (setq org-roam-node-default-sort 'file-mtime) + (setq consult-org-roam-grep-func #'consult-ripgrep) -(autoload 'org-roam-buffer-toggle "org-roam" "\ -Enable org-roam -" t nil) -(autoload 'org-roam-setup "org-roam" "\ -Enable org-roam -" t nil) + (setq org-roam-capture-templates + `( + ("d" "default" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + "#+title: ${title}\n") + :unnarrowed t) + ("p" "post" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + ,(concat "#+date: %<%Y-%m-%dT%H:%M:%S>Z\n" + "#+slug: ${slug}\n" + "#+title: ${title}\n" + "#+filetags: Post\n" + "\n")) + :unnarrowed t) + ("i" "interview" plain "%?" + :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" + ,(concat "#+title: ${title}\n" + "#+filetags: Interview\n" + "\n")) + :unnarrowed t) -(setq org-roam-capture-templates - `( - ("d" "default" plain "%?" - :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" - "#+title: ${title}\n") - :unnarrowed t) - ("p" "post" plain "%?" - :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" - ,(concat "#+date: %<%Y-%m-%dT%H:%M:%S>Z\n" - "#+slug: ${slug}\n" - "#+title: ${title}\n" - "#+filetags: Post\n" - "\n")) - :unnarrowed t) - ("i" "interview" plain "%?" - :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" - ,(concat "#+title: ${title}\n" - "#+filetags: Interview\n" - "\n")) - :unnarrowed t) + )) - )) + (setq org-roam-node-display-template + (concat "${title:80} " (propertize "${tags:20}" 'face 'org-tag)) + org-roam-node-annotation-function + (lambda (node) (marginalia--time (org-roam-node-file-mtime node)))) -(setq org-roam-node-display-template - (concat "${title:80} " (propertize "${tags:20}" 'face 'org-tag)) - org-roam-node-annotation-function - (lambda (node) (marginalia--time (org-roam-node-file-mtime node)))) + (defun roam-extra:get-filetags () + (split-string (or (org-roam-get-keyword "filetags") ""))) -(add-hook 'after-init-hook 'org-roam-setup) + (defun roam-extra:add-filetag (tag) + (let* ((new-tags (cons tag (roam-extra:get-filetags))) + (new-tags-str (combine-and-quote-strings new-tags))) + (org-roam-set-keyword "filetags" new-tags-str))) -(defun roam-extra:get-filetags () - (split-string (or (org-roam-get-keyword "filetags") ""))) + (defun roam-extra:del-filetag (tag) + (let* ((new-tags (seq-difference (roam-extra:get-filetags) `(,tag))) + (new-tags-str (combine-and-quote-strings new-tags))) + (org-roam-set-keyword "filetags" new-tags-str))) -(defun roam-extra:add-filetag (tag) - (let* ((new-tags (cons tag (roam-extra:get-filetags))) - (new-tags-str (combine-and-quote-strings new-tags))) - (org-roam-set-keyword "filetags" new-tags-str))) + (defun roam-extra:todo-p () + "Return non-nil if current buffer has any TODO entry. -(defun roam-extra:del-filetag (tag) - (let* ((new-tags (seq-difference (roam-extra:get-filetags) `(,tag))) - (new-tags-str (combine-and-quote-strings new-tags))) - (org-roam-set-keyword "filetags" new-tags-str))) + TODO entries marked as done are ignored, meaning the this + function returns nil if current buffer contains only completed + tasks." + (org-element-map + (org-element-parse-buffer 'headline) + 'headline + (lambda (h) + (eq (org-element-property :todo-type h) + 'todo)) + nil 'first-match)) -(defun roam-extra:todo-p () - "Return non-nil if current buffer has any TODO entry. + (defun roam-extra:update-todo-tag () + "Update TODO tag in the current buffer." + (when (and (not (active-minibuffer-window)) + (org-roam-file-p)) + (org-with-point-at 1 + (let* ((tags (roam-extra:get-filetags)) + (is-todo (roam-extra:todo-p))) + (cond ((and is-todo (not (seq-contains-p tags "todo"))) + (roam-extra:add-filetag "todo")) + ((and (not is-todo) (seq-contains-p tags "todo")) + (roam-extra:del-filetag "todo"))))))) - TODO entries marked as done are ignored, meaning the this - function returns nil if current buffer contains only completed - tasks." - (org-element-map - (org-element-parse-buffer 'headline) - 'headline - (lambda (h) - (eq (org-element-property :todo-type h) - 'todo)) - nil 'first-match)) + (defun roam-extra:todo-files () + "Return a list of roam files containing todo tag." + (org-roam-db-sync) + (let ((todo-nodes (seq-filter (lambda (n) + (seq-contains-p (org-roam-node-tags n) "todo")) + (org-roam-node-list)))) + (seq-uniq (seq-map #'org-roam-node-file todo-nodes)))) -(defun roam-extra:update-todo-tag () - "Update TODO tag in the current buffer." - (when (and (not (active-minibuffer-window)) - (org-roam-file-p)) - (org-with-point-at 1 - (let* ((tags (roam-extra:get-filetags)) - (is-todo (roam-extra:todo-p))) - (cond ((and is-todo (not (seq-contains-p tags "todo"))) - (roam-extra:add-filetag "todo")) - ((and (not is-todo) (seq-contains-p tags "todo")) - (roam-extra:del-filetag "todo"))))))) + (defun roam-extra:update-todo-files (&rest _) + "Update the value of `org-agenda-files'." + (setq org-agenda-files (roam-extra:todo-files))) -(defun roam-extra:todo-files () - "Return a list of roam files containing todo tag." - (org-roam-db-sync) - (let ((todo-nodes (seq-filter (lambda (n) - (seq-contains-p (org-roam-node-tags n) "todo")) - (org-roam-node-list)))) - (seq-uniq (seq-map #'org-roam-node-file todo-nodes)))) - -(defun roam-extra:update-todo-files (&rest _) - "Update the value of `org-agenda-files'." - (setq org-agenda-files (roam-extra:todo-files))) - -(add-hook 'find-file-hook #'roam-extra:update-todo-tag) -(add-hook 'before-save-hook #'roam-extra:update-todo-tag) -(advice-add 'org-agenda :before #'roam-extra:update-todo-files) + (add-hook 'find-file-hook #'roam-extra:update-todo-tag) + (add-hook 'before-save-hook #'roam-extra:update-todo-tag) + (advice-add 'org-agenda :before #'roam-extra:update-todo-files) -(defun org-roam-week (&optional other-window) - "Opens or creates a weekly note." - (interactive) - (let* ((title (format-time-string "Week %U %Y")) - (nodes (org-roam-node-list)) - (node (seq-find (lambda (n) (string-equal (org-roam-node-title n) title)) nodes))) - (if (and node (org-roam-node-file node)) - (org-roam-node-visit node other-window) - (org-roam-capture- - :node (org-roam-node-create :title title) - :templates - `(("w" "week" plain "* Goals\n\n%?\n\n* Tasks\n\n" - :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: Week") - :unnarrowed t)) - :props '(:finalize find-file)) + (defun org-roam-week (&optional other-window) + "Opens or creates a weekly note." + (interactive) + (let* ((title (format-time-string "Week %U %Y")) + (nodes (org-roam-node-list)) + (node (seq-find (lambda (n) (string-equal (org-roam-node-title n) title)) nodes))) + (if (and node (org-roam-node-file node)) + (org-roam-node-visit node other-window) + (org-roam-capture- + :node (org-roam-node-create :title title) + :templates + `(("w" "week" plain "* Goals\n\n%?\n\n* Tasks\n\n" + :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: Week") + :unnarrowed t)) + :props '(:finalize find-file)) + ) ) ) - ) -(global-set-key (kbd "C-c n w") 'org-roam-week) + (org-roam-setup) + + ) ;; -------- Org mode --------- -(use-package org-modern) -(with-eval-after-load 'org (global-org-modern-mode)) +(use-package org + :ensure t + :mode (("\\.org$" . org-mode)) + :config + (use-package org-contrib + :ensure t) + (use-package org-modern + :ensure t + :config + (global-org-modern-mode) + ) -(setq org-modules '(org-w3m org-bbdb org-bibtex org-docview - org-gnus org-info org-irc org-mhe - org-rmail org-checklist org-mu4e)) + (setq org-modules '(org-w3m org-bbdb org-bibtex org-docview + org-gnus org-info org-irc org-mhe + org-rmail org-checklist org-mu4e)) -;; Enable line wrap by default in org buffers -(setq org-startup-truncated nil) + ;; Enable line wrap by default in org buffers + (setq org-startup-truncated nil) -;; Sometimes I sit at night until 4 AM, and I still want org to treat it -;; as "today" -(setq org-extend-today-until 4) + ;; Sometimes I sit at night until 4 AM, and I still want org to treat it + ;; as "today" + (setq org-extend-today-until 4) -;; navigate with (org-goto) by offering the full list of targets in ido-mode -(setq org-goto-interface 'outline-path-completion) ;; don't search incrementally -(setq org-outline-path-complete-in-steps nil) ;; see whole path at once + ;; navigate with (org-goto) by offering the full list of targets in ido-mode + (setq org-goto-interface 'outline-path-completion) ;; don't search incrementally + (setq org-outline-path-complete-in-steps nil) ;; see whole path at once -;; avoid inadvertently editing hidden text -(setq org-catch-invisible-edits 'show-and-error) + ;; avoid inadvertently editing hidden text + (setq org-catch-invisible-edits 'show-and-error) -;; hide empty spaces between folded subtrees -(setq org-cycle-separator-lines 0) + ;; hide empty spaces between folded subtrees + (setq org-cycle-separator-lines 0) -;; use hours in clocktable instead of days and hours -(setq org-time-clocksum-format "%d:%02d") + ;; use hours in clocktable instead of days and hours + (setq org-time-clocksum-format "%d:%02d") -;; After a recurring task is marked as done, reset it to TODO. This -;; is important because I have the "INBOX" state first in the sequence -;; of states. -(setq org-todo-repeat-to-state "TODO") + ;; After a recurring task is marked as done, reset it to TODO. This + ;; is important because I have the "INBOX" state first in the sequence + ;; of states. + (setq org-todo-repeat-to-state "TODO") -;; Default format for column view -(setq org-columns-default-format "%38ITEM(Details) %TAGS(Context) %7TODO(To Do) %5Effort(Time){:} %6CLOCKSUM(Total){:}") + ;; Default format for column view + (setq org-columns-default-format "%38ITEM(Details) %TAGS(Context) %7TODO(To Do) %5Effort(Time){:} %6CLOCKSUM(Total){:}") -;; Better source code editing + ;; Better source code editing -(setq org-src-fontify-natively t - org-src-window-setup 'current-window - org-src-strip-leading-and-trailing-blank-lines t - org-src-preserve-indentation t - org-src-tab-acts-natively t) + (setq org-src-fontify-natively t + org-src-window-setup 'current-window + org-src-strip-leading-and-trailing-blank-lines t + org-src-preserve-indentation t + org-src-tab-acts-natively t) -;; Default tags -(setq org-tag-alist '((:startgroup . nil) - ("WORK" . ?w) ("HOME" . ?h) - (:endgroup . nil) - ("PROJECT" . ?p) - ("PHONE" . ?n) - ("MEETING" . ?m) - ("DOC" . ?d) - ("GOOGLE" . ?g) - ("QUICK" . ?q))) + ;; Default tags + (setq org-tag-alist '((:startgroup . nil) + ("WORK" . ?w) ("HOME" . ?h) + (:endgroup . nil) + ("PROJECT" . ?p) + ("PHONE" . ?n) + ("MEETING" . ?m) + ("DOC" . ?d) + ("GOOGLE" . ?g) + ("QUICK" . ?q))) -;; Default todo sequence -(setq org-todo-keywords - '((sequence "INBOX(i)" "TODO(t)" "ERRAND(k)" - "SOMEDAY(s)" "WAITING(w@/!)" "APPT(a)" "|" - "DONE(d!)" "CANCELLED(c!)"))) + ;; Default todo sequence + (setq org-todo-keywords + '((sequence "INBOX(i)" "TODO(t)" "ERRAND(k)" + "SOMEDAY(s)" "WAITING(w@/!)" "APPT(a)" "|" + "DONE(d!)" "CANCELLED(c!)"))) -;; Babel and code block embedding -(setq org-confirm-babel-evaluate nil) -(org-babel-do-load-languages - 'org-babel-load-languages - '((emacs-lisp . t) - (python . t))) + ;; Babel and code block embedding + (setq org-confirm-babel-evaluate nil) + (org-babel-do-load-languages + 'org-babel-load-languages + '((emacs-lisp . t) + (python . t))) -;; Log TODO state changes and clock-ins into the LOGBOOK drawer -(setq org-clock-into-drawer t) -(setq org-log-into-drawer t) + ;; Log TODO state changes and clock-ins into the LOGBOOK drawer + (setq org-clock-into-drawer t) + (setq org-log-into-drawer t) -;; Quickly creating new tasks -(global-set-key (kbd "\C-c r") 'org-capture) -(setq org-capture-templates - `(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks") - "* TODO %?\n %U\n %a") - ("i" "Inbox" entry (file+headline "~/org/gtd.org" "Tasks") - "* INBOX %?\n %U") - ("f" "Follow-up" entry (file+headline "~/org/gtd.org" "Tasks") - ,(concat "* TODO %? :EMAIL:\n" - " %U\n" - " %a")) - ("c" "Contacts" entry (file "~/org/contacts.org") - (concat "* %(org-contacts-template-name)\n" - ":PROPERTIES:\n" - ":EMAIL: %(org-contacts-template-email)\n" - ":END:")) + ;; Quickly creating new tasks + (global-set-key (kbd "\C-c r") 'org-capture) + (setq org-capture-templates + `(("t" "Todo" entry (file+headline "~/org/gtd.org" "Tasks") + "* TODO %?\n %U\n %a") + ("i" "Inbox" entry (file+headline "~/org/gtd.org" "Tasks") + "* INBOX %?\n %U") + ("f" "Follow-up" entry (file+headline "~/org/gtd.org" "Tasks") + ,(concat "* TODO %? :EMAIL:\n" + " %U\n" + " %a")) + ("c" "Contacts" entry (file "~/org/contacts.org") + (concat "* %(org-contacts-template-name)\n" + ":PROPERTIES:\n" + ":EMAIL: %(org-contacts-template-email)\n" + ":END:")) - ("q" - "Org capture template" - entry - (file+headline "~/org/capture.org" "Notes") - "* %:description\n\n Source: %u, %:link\n\n %i" - :empty-lines 1) + ("q" + "Org capture template" + entry + (file+headline "~/org/capture.org" "Notes") + "* %:description\n\n Source: %u, %:link\n\n %i" + :empty-lines 1) + ) ) - ) -;; org-protocol allows you to capture stuff into your system from web -;; browsers -(require 'org-protocol) + ;; org-protocol allows you to capture stuff into your system from web + ;; browsers + (require 'org-protocol) -;; Refiling allows you to quickly move an element with its children to -;; another location. + ;; Refiling allows you to quickly move an element with its children to + ;; another location. -;; By default, refile works up to 2-level sections, which is not very -;; convenient if you have project-based organization -;; (/Projects/ProjectName). -(setq org-refile-targets '((org-agenda-files :maxlevel . 3))) + ;; By default, refile works up to 2-level sections, which is not very + ;; convenient if you have project-based organization + ;; (/Projects/ProjectName). + (setq org-refile-targets '((org-agenda-files :maxlevel . 3))) -;; Then, it's nice to have a full path to the target element appear in -;; completion -(setq org-refile-use-outline-path 'file) + ;; Then, it's nice to have a full path to the target element appear in + ;; completion + (setq org-refile-use-outline-path 'file) -;; But, when using helm, we also need to tell org mode to present the -;; whole list of possible completions right away, and not use -;; incremental search: -(setq org-outline-path-complete-in-steps nil) + ;; But, when using helm, we also need to tell org mode to present the + ;; whole list of possible completions right away, and not use + ;; incremental search: + (setq org-outline-path-complete-in-steps nil) -;; It may also be useful to be able to create elements, if the refile -;; target doesn't already exist. -(setq org-refile-allow-creating-parent-nodes 'confirm) + ;; It may also be useful to be able to create elements, if the refile + ;; target doesn't already exist. + (setq org-refile-allow-creating-parent-nodes 'confirm) -;; Agenda -(global-set-key "\C-ca" 'org-agenda) -(setq org-agenda-files '("~/org/gtd.org" - "~/org/weeklyreview.org" + ;; Agenda + (global-set-key "\C-ca" 'org-agenda) + (setq org-agenda-files '("~/org/gtd.org" + "~/org/weeklyreview.org" + )) + + (setq org-agenda-custom-commands nil) + (add-to-list 'org-agenda-custom-commands + '("h" "Work todos" tags-todo + "-personal-doat={.+}-dowith={.+}/!-ERRAND" + ((org-agenda-todo-ignore-scheduled t)))) + (add-to-list 'org-agenda-custom-commands + '("H" "All work todos" tags-todo "-personal/!-ERRAND-MAYBE" + ((org-agenda-todo-ignore-scheduled nil)))) + (add-to-list 'org-agenda-custom-commands + '("A" "Work todos with doat or dowith" tags-todo + "-personal+doat={.+}|dowith={.+}/!-ERRAND" + ((org-agenda-todo-ignore-scheduled nil)))) + (add-to-list 'org-agenda-custom-commands + '("P" "Projects" + tags "+PROJECT-TODO=\"SOMEDAY\"")) + + (add-to-list 'org-agenda-custom-commands + '("i" "Inbox" + todo "INBOX")) + + (add-to-list 'org-agenda-custom-commands + '("o" "Someday" + todo "SOMEDAY")) + + (add-to-list 'org-agenda-custom-commands + '("c" "Simple agenda view" + ( + (agenda "" + ) + (todo "" + ( + (org-agenda-overriding-header "\nUnscheduled TODO") + (org-agenda-skip-function '(org-agenda-skip-entry-if + 'timestamp 'todo '("SOMEDAY" "ERRAND"))) + (org-agenda-sorting-strategy + (quote ((agenda time-up priority-down tag-up)))) )) - -(setq org-agenda-custom-commands nil) -(add-to-list 'org-agenda-custom-commands - '("h" "Work todos" tags-todo - "-personal-doat={.+}-dowith={.+}/!-ERRAND" - ((org-agenda-todo-ignore-scheduled t)))) -(add-to-list 'org-agenda-custom-commands - '("H" "All work todos" tags-todo "-personal/!-ERRAND-MAYBE" - ((org-agenda-todo-ignore-scheduled nil)))) -(add-to-list 'org-agenda-custom-commands - '("A" "Work todos with doat or dowith" tags-todo - "-personal+doat={.+}|dowith={.+}/!-ERRAND" - ((org-agenda-todo-ignore-scheduled nil)))) -(add-to-list 'org-agenda-custom-commands - '("P" "Projects" - tags "+PROJECT-TODO=\"SOMEDAY\"")) - -(add-to-list 'org-agenda-custom-commands - '("i" "Inbox" - todo "INBOX")) - -(add-to-list 'org-agenda-custom-commands - '("o" "Someday" - todo "SOMEDAY")) - -(add-to-list 'org-agenda-custom-commands - '("c" "Simple agenda view" - ( - (agenda "" - ) - (todo "" - ( - (org-agenda-overriding-header "\nUnscheduled TODO") - (org-agenda-skip-function '(org-agenda-skip-entry-if - 'timestamp 'todo '("SOMEDAY" "ERRAND"))) - (org-agenda-sorting-strategy - (quote ((agenda time-up priority-down tag-up)))) - )) - ) - ((org-agenda-overriding-columns-format - "%38ITEM(Details) %TAGS(Context) %7TODO(To Do) %5Effort(Time){:} %6CLOCKSUM_T(Total){:}") - (org-agenda-view-columns-initially t)) + ) + ((org-agenda-overriding-columns-format + "%38ITEM(Details) %TAGS(Context) %7TODO(To Do) %5Effort(Time){:} %6CLOCKSUM_T(Total){:}") + (org-agenda-view-columns-initially t)) + ) ) - ) -(setq org-todo-keyword-faces - '(("ERRAND" . (:foreground "light sea green" :weight bold)) - ("INBOX" . (:foreground "DarkGoldenrod" :weight bold)))) + (setq org-todo-keyword-faces + '(("ERRAND" . (:foreground "light sea green" :weight bold)) + ("INBOX" . (:foreground "DarkGoldenrod" :weight bold)))) -;;(set-face-foreground 'org-scheduled-previously "DarkGoldenrod") - -(setq org-tags-exclude-from-inheritance '("PROJECT") - org-stuck-projects '("+PROJECT/-MAYBE-DONE-SOMEDAY" - ("TODO" "ERRAND" "WAITING") () ())) + ;;(set-face-foreground 'org-scheduled-previously "DarkGoldenrod") + (setq org-tags-exclude-from-inheritance '("PROJECT") + org-stuck-projects '("+PROJECT/-MAYBE-DONE-SOMEDAY" + ("TODO" "ERRAND" "WAITING") () ())) +) ;; -------- Email -------- -;;(use-package mu4e) +(use-package mu4e + :defer t + :commands (mu4e) + :config + (setq sendmail-program (executable-find "msmtp")) + + (autoload 'mu4e "mu4e" "\ + If mu4e is not running yet, start it. Then, show the main + window, unless BACKGROUND (prefix-argument) is non-nil. + " t nil) + + (setq mu4e-update-interval 600) ;; refresh every X seconds + + (setq message-citation-line-format "On %d %b %Y at %R, %f wrote:\n") + (setq message-citation-line-function 'message-insert-formatted-citation-line) + + (setq mu4e-attachment-dir "~/Downloads") + + (setq mu4e-html2text-command 'mu4e-shr2text) + + (setq mu4e-user-mail-address-list '("mail@knazarov.com" "k.nazarov@corp.mail.ru")) + + ;; exlude myself from the email replies + (setq mu4e-compose-dont-reply-to-self t) + + ;; set mu4e as a default mail agent + (setq mail-user-agent 'mu4e-user-agent) + + (setq mu4e-maildir "/home/knazarov/Maildir") + + (setq + mu4e-view-show-images t + mu4e-image-max-width 800 + mu4e-view-prefer-html t + mu4e-change-filenames-when-moving t ;; prevent duplicate UIDs + mu4e-get-mail-command "mbsync -a -q" + mu4e-headers-include-related nil) + + (setq mu4e-sent-folder "/personal/Sent" + mu4e-drafts-folder "/personal/Drafts" + mu4e-trash-folder "/personal/Trash" + mu4e-refile-folder "/personal/Archive" + user-full-name "Konstantin Nazarov" + user-mail-address "mail@knazarov.com" + smtpmail-default-smtp-server "smtp.fastmail.com" + smtpmail-local-domain "knazarov.com" + smtpmail-smtp-server "smtp.fastmail.com" + smtpmail-stream-type 'starttls + smtpmail-smtp-service 587 + message-send-mail-function 'message-send-mail-with-sendmail + ;;message-sendmail-extra-arguments '("--read-envelope-from") + ) + + (setq mu4e-compose-signature + "<#part type=text/html>

Hello ! I am the html signature which can contains anything in html !

<#/part>" ) + + (defvar my-mu4e-account-alist + `(("personal" + (mu4e-sent-folder "/personal/Sent") + (mu4e-drafts-folder "/personal/Drafts") + (mu4e-trash-folder "/personal/Trash") + (mu4e-refile-folder "/personal/Archive") + (user-mail-address "mail@knazarov.com") + (message-sendmail-envelope-from "mail@knazarov.com") + ;;(mu4e-compose-signature-auto-include nil) + (mu4e-compose-signature ,(if (file-exists-p "~/.mail-sig.txt") + (with-temp-buffer + (insert-file-contents "~/.mail-sig.txt") + (buffer-string)) + "")) + (message-signature-file "~/.mail-sig.txt") + (message-cite-reply-position above) + (message-cite-style message-cite-style-outlook)) + ("work" + (mu4e-sent-folder "/work/Sent") + (mu4e-drafts-folder "/work/Drafts") + (mu4e-trash-folder "/work/Trash") + (mu4e-refile-folder "/work/Archive") + (user-mail-address "k.nazarov@corp.mail.ru") + (message-sendmail-envelope-from "k.nazarov@corp.mail.ru") + (mu4e-compose-signature-auto-include nil) + (message-signature-file "~/.mail-sig.txt") + (mu4e-compose-signature ,(if (file-exists-p "~/.mail-sig.txt") + (with-temp-buffer + (insert-file-contents "~/.mail-sig.txt") + (buffer-string)) + "")) + (message-cite-reply-position above) + (message-cite-style message-cite-style-outlook)) + )) + + (defun my-mu4e-set-account () + "Set the account for composing a message." + (let* ((account + (if mu4e-compose-parent-message + (let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir))) + (string-match "/\\(.*?\\)/" maildir) + (match-string 1 maildir)) + (completing-read (format "Compose with account: (%s) " + (mapconcat #'(lambda (var) (car var)) + my-mu4e-account-alist "/")) + (mapcar #'(lambda (var) (car var)) my-mu4e-account-alist) + nil t nil nil (caar my-mu4e-account-alist)))) + (account-vars (cdr (assoc account my-mu4e-account-alist)))) + (if account-vars + (mapc #'(lambda (var) + (set (car var) (cadr var))) + account-vars) + (error "No email account found")))) + + (defun my-mu4e-refile-folder-function (msg) + (let ((mu4e-accounts my-mu4e-account-alist) + (current-message msg) + (account)) + (setq account (catch 'found + (dolist (candidate mu4e-accounts) + (if (string-match (car candidate) + (mu4e-message-field current-message :maildir)) + (throw 'found candidate) + )))) + (if account + (cadr (assoc 'mu4e-refile-folder account)) + (throw 'account_not_found (mu4e-message-field current-message :maildir)) + ) + ) + ) + + (setq mu4e-refile-folder 'my-mu4e-refile-folder-function) + + (add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account) + + ;; Be smart about inserting signature for either cite-reply-position used + (defun insert-signature () + "Insert signature where you are replying" + ;; Do not insert if already done - needed when switching modes back/forth + (unless (save-excursion (message-goto-signature)) + (save-excursion + (if (eq message-cite-reply-position 'below) + (goto-char (point-max)) + (message-goto-body)) + (insert-file-contents message-signature-file) + (save-excursion (insert "\n-- \n"))))) + (add-hook 'mu4e-compose-mode-hook 'insert-signature) + + ;;(add-to-list 'mu4e-bookmarks + ;; '("maildir:/work/INBOX" "work inbox" ?w)) + + ;;(add-to-list 'mu4e-bookmarks + ;; '("maildir:/knazarov/INBOX" "personal inbox" ?p)) + + (setq mu4e-bookmarks + '(("maildir:/personal/INBOX OR maildir:/work/INBOX" "inbox" ?i))) + ) ;;(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e") -(setq sendmail-program (executable-find "msmtp")) - -(autoload 'mu4e "mu4e" "\ -If mu4e is not running yet, start it. Then, show the main -window, unless BACKGROUND (prefix-argument) is non-nil. -" t nil) - -(setq mu4e-update-interval 600) ;; refresh every X seconds - -(setq message-citation-line-format "On %d %b %Y at %R, %f wrote:\n") -(setq message-citation-line-function 'message-insert-formatted-citation-line) - -(setq mu4e-attachment-dir "~/Downloads") - -(setq mu4e-html2text-command 'mu4e-shr2text) - -(setq mu4e-user-mail-address-list '("mail@knazarov.com" "k.nazarov@corp.mail.ru")) - -;; exlude myself from the email replies -(setq mu4e-compose-dont-reply-to-self t) - -;; set mu4e as a default mail agent -(setq mail-user-agent 'mu4e-user-agent) - -(setq mu4e-maildir "/home/knazarov/Maildir") - -(setq - mu4e-view-show-images t - mu4e-image-max-width 800 - mu4e-view-prefer-html t - mu4e-change-filenames-when-moving t ;; prevent duplicate UIDs - mu4e-get-mail-command "mbsync -a -q" - mu4e-headers-include-related nil) - -(setq mu4e-sent-folder "/personal/Sent" - mu4e-drafts-folder "/personal/Drafts" - mu4e-trash-folder "/personal/Trash" - mu4e-refile-folder "/personal/Archive" - user-full-name "Konstantin Nazarov" - user-mail-address "mail@knazarov.com" - smtpmail-default-smtp-server "smtp.fastmail.com" - smtpmail-local-domain "knazarov.com" - smtpmail-smtp-server "smtp.fastmail.com" - smtpmail-stream-type 'starttls - smtpmail-smtp-service 587 - message-send-mail-function 'message-send-mail-with-sendmail - ;;message-sendmail-extra-arguments '("--read-envelope-from") - ) - -(setq mu4e-compose-signature - "<#part type=text/html>

Hello ! I am the html signature which can contains anything in html !

<#/part>" ) - -(defvar my-mu4e-account-alist - `(("personal" - (mu4e-sent-folder "/personal/Sent") - (mu4e-drafts-folder "/personal/Drafts") - (mu4e-trash-folder "/personal/Trash") - (mu4e-refile-folder "/personal/Archive") - (user-mail-address "mail@knazarov.com") - (message-sendmail-envelope-from "mail@knazarov.com") - ;;(mu4e-compose-signature-auto-include nil) - (mu4e-compose-signature ,(if (file-exists-p "~/.mail-sig.txt") - (with-temp-buffer - (insert-file-contents "~/.mail-sig.txt") - (buffer-string)) - "")) - (message-signature-file "~/.mail-sig.txt") - (message-cite-reply-position above) - (message-cite-style message-cite-style-outlook)) - ("work" - (mu4e-sent-folder "/work/Sent") - (mu4e-drafts-folder "/work/Drafts") - (mu4e-trash-folder "/work/Trash") - (mu4e-refile-folder "/work/Archive") - (user-mail-address "k.nazarov@corp.mail.ru") - (message-sendmail-envelope-from "k.nazarov@corp.mail.ru") - (mu4e-compose-signature-auto-include nil) - (message-signature-file "~/.mail-sig.txt") - (mu4e-compose-signature ,(if (file-exists-p "~/.mail-sig.txt") - (with-temp-buffer - (insert-file-contents "~/.mail-sig.txt") - (buffer-string)) - "")) - (message-cite-reply-position above) - (message-cite-style message-cite-style-outlook)) - )) - -(defun my-mu4e-set-account () - "Set the account for composing a message." - (let* ((account - (if mu4e-compose-parent-message - (let ((maildir (mu4e-message-field mu4e-compose-parent-message :maildir))) - (string-match "/\\(.*?\\)/" maildir) - (match-string 1 maildir)) - (completing-read (format "Compose with account: (%s) " - (mapconcat #'(lambda (var) (car var)) - my-mu4e-account-alist "/")) - (mapcar #'(lambda (var) (car var)) my-mu4e-account-alist) - nil t nil nil (caar my-mu4e-account-alist)))) - (account-vars (cdr (assoc account my-mu4e-account-alist)))) - (if account-vars - (mapc #'(lambda (var) - (set (car var) (cadr var))) - account-vars) - (error "No email account found")))) - -(defun my-mu4e-refile-folder-function (msg) - (let ((mu4e-accounts my-mu4e-account-alist) - (current-message msg) - (account)) - (setq account (catch 'found - (dolist (candidate mu4e-accounts) - (if (string-match (car candidate) - (mu4e-message-field current-message :maildir)) - (throw 'found candidate) - )))) - (if account - (cadr (assoc 'mu4e-refile-folder account)) - (throw 'account_not_found (mu4e-message-field current-message :maildir)) - ) - ) - ) - -(setq mu4e-refile-folder 'my-mu4e-refile-folder-function) - -(add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account) - -;; Be smart about inserting signature for either cite-reply-position used -(defun insert-signature () - "Insert signature where you are replying" - ;; Do not insert if already done - needed when switching modes back/forth - (unless (save-excursion (message-goto-signature)) - (save-excursion - (if (eq message-cite-reply-position 'below) - (goto-char (point-max)) - (message-goto-body)) - (insert-file-contents message-signature-file) - (save-excursion (insert "\n-- \n"))))) -(add-hook 'mu4e-compose-mode-hook 'insert-signature) - -;;(add-to-list 'mu4e-bookmarks -;; '("maildir:/work/INBOX" "work inbox" ?w)) - -;;(add-to-list 'mu4e-bookmarks -;; '("maildir:/knazarov/INBOX" "personal inbox" ?p)) - -(setq mu4e-bookmarks - '(("maildir:/personal/INBOX OR maildir:/work/INBOX" "inbox" ?i))) ;; -------- Programming -------- -;; Enable direnv-mode to automatically load Nix flake dependencies for projects -(use-package direnv - :config - (direnv-mode)) +(use-package eldoc + :defer t + :diminish eldoc-mode + :hook (prog-mode . eldoc-mode) + :init + ;;(setq eldoc-idle-delay 0.1) + ) ;; Rainbow delimeters highlight matching pairs of braces in different colors -(use-package rainbow-delimiters) -(add-hook 'prog-mode-hook #'rainbow-delimiters-mode) +(use-package rainbow-delimiters + :ensure t + :hook (prog-mode . rainbow-delimiters-mode) + ) ;; Flycheck is an on-the-fly syntax checker for emacs with pluggable backengs. -(use-package flycheck) +(use-package flycheck + :ensure t + :hook (prog-mode . rainbow-delimiters-mode) + :diminish flycheck-mode + ) + ;; Not usable for every single mode, so need to be selective ;;(add-hook 'prog-mode-hook #'flycheck-mode) @@ -816,10 +905,15 @@ window, unless BACKGROUND (prefix-argument) is non-nil. ;; Projectile auto-detects projects and allows to run project-wide commands -(use-package projectile) -(setq projectile-cache-file "~/.emacs.d/projectile.cache") -(projectile-mode +1) -(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map) +(use-package projectile + :ensure t + :defer 0.1 + :diminish projectile-mode + :config + (setq projectile-cache-file "~/.emacs.d/projectile.cache") + (projectile-mode +1) + (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map) + ) ;; Corfu mode is a simple auto completion framework with ;; pluggable backends @@ -827,30 +921,51 @@ window, unless BACKGROUND (prefix-argument) is non-nil. ;;(setq company-backends '(company-capf (company-dabbrev-code) company-dabbrev)) ;;(add-hook 'prog-mode-hook #'company-mode) ;;(add-hook 'mu4e-compose-mode-hook #'company-mode) -(use-package corfu) -(add-hook 'after-init-hook 'global-corfu-mode) -(add-hook 'after-init-hook 'corfu-popupinfo-mode) -(setq corfu-auto t) -(setq tab-always-indent 'complete) -(setq corfu-quit-no-match 'separator) +(use-package corfu + :ensure t + :defer 1 + :init + (setq corfu-auto t) + (setq tab-always-indent 'complete) + (setq corfu-quit-no-match 'separator) + :config + (global-corfu-mode) + (corfu-popupinfo-mode) + ) -(use-package cape) -(add-to-list 'completion-at-point-functions #'cape-dabbrev) -(add-to-list 'completion-at-point-functions #'cape-file) +(use-package corfu-terminal + :ensure t + :after corfu + :config + (unless (display-graphic-p) + (corfu-terminal-mode +1)) + ) + +;; (setq corfu-auto t) + ;;(setq tab-always-indent 'complete) + ;;(setq corfu-quit-no-match 'separator) + ;;(global-corfu-mode) + ;;(corfu-popupinfo-mode) + +(use-package cape + :ensure t + :defer 0.1 + :config + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + ) ;; Can't live without magit. It makes working with git sooo much easie -(use-package magit) -(global-set-key (kbd "C-x g") 'magit-status) +(use-package magit + :ensure t + :bind + ("C-x g" . magit-status) + ) ;;(setq magit-completing-read-function 'magit-ido-completing-read) -;; LSP - -;; Maybe switch to EGLOT, which is shipped in Emacs 29 -(add-hook 'lua-mode-hook #'lsp) - ;; Tree-sitter (setq major-mode-remap-alist @@ -874,88 +989,106 @@ window, unless BACKGROUND (prefix-argument) is non-nil. ;; speed and features. (setq vterm-always-compile-module t) -(use-package vterm) +(use-package vterm + :ensure t + :defer t + :commands + vterm + :config + (defun vterm-less (content) + (let ((less-buffer (get-buffer-create (make-temp-name "vterm-less-")))) + (with-current-buffer less-buffer + (switch-to-buffer less-buffer) + (special-mode) + (insert (base64-decode-string content))) + ) + ) + + (defun my-vterm-mode-hook () + (add-to-list 'vterm-eval-cmds (list "less" #'vterm-less)) + (with-editor-export-editor) + ) + + (add-hook 'vterm-mode-hook #'my-vterm-mode-hook) + + (defun vterm-new () + (interactive) + (setq current-prefix-arg '(4)) ; C-u + (call-interactively 'vterm)) + ) ;;(add-to-list 'load-path (expand-file-name "~/dev/emacs-libvterm/")) -(defun vterm-less (content) - (let ((less-buffer (get-buffer-create (make-temp-name "vterm-less-")))) - (with-current-buffer less-buffer - (switch-to-buffer less-buffer) - (special-mode) - (insert (base64-decode-string content))) - ) - ) - -(use-package with-editor) -(defun my-vterm-mode-hook () - (add-to-list 'vterm-eval-cmds (list "less" #'vterm-less)) - (with-editor-export-editor) - ) - -(add-hook 'vterm-mode-hook #'my-vterm-mode-hook) +(use-package with-editor + :ensure t + :defer 1 + ) (put 'upcase-region 'disabled nil) -(autoload 'vterm "vterm" "\ -If vterm is not running yet, start it. Then, show the main -window, unless BACKGROUND (prefix-argument) is non-nil. -" t nil) - -(defun vterm-new () - (interactive) - (setq current-prefix-arg '(4)) ; C-u - (call-interactively 'vterm)) - -;; EAT terminal - -(use-package eat) ;; lua -(use-package lua-mode) -(setq lua-indent-level 4) +(use-package lua-mode + :ensure t + :mode "\\.lua$" + :config + (setq lua-indent-level 4) + ) + ;; common lisp -(use-package sly) -(use-package sly-asdf) -(use-package aggressive-indent) +;;(use-package sly) +;;(use-package sly-asdf) +;;(use-package aggressive-indent) -(add-to-list 'sly-contribs 'sly-asdf 'append) -(autoload 'sly "sly" - "Start an inferior^_superior Lisp and connect to its Swank server." - t nil) +;;(add-to-list 'sly-contribs 'sly-asdf 'append) +;;(autoload 'sly "sly" + ;;"Start an inferior^_superior Lisp and connect to its Swank server." + ;;t nil) -(define-key lisp-mode-map (kbd "C-c v") - 'sly-asdf-test-system) +;;(define-key lisp-mode-map (kbd "C-c v") + ;;'sly-asdf-test-system) ;autoload 'sly-lisp-mode-hook "sly" ; "Set up sly for a lisp buffer." ; t nil) -(add-hook 'lisp-mode-hook #'aggressive-indent-mode) +;;(add-hook 'lisp-mode-hook #'aggressive-indent-mode) ;(add-hook 'lisp-mode-hook 'sly-lisp-mode-hook) ;(setq slime-contribs '(slime-fancy slime-company)) -(setq inferior-lisp-program "sbcl") +;;(setq inferior-lisp-program "sbcl") ;; Markdown -(use-package markdown-mode) +(use-package markdown-mode + :ensure t + :mode "\\.md$" + ) ;; Dockerfiles -(use-package dockerfile-mode) +(use-package dockerfile-mode + :ensure t + :mode "Dockerfile$" + ) ;; Yaml -(use-package yaml-mode) +(use-package yaml-mode + :ensure t + :mode "\\.(yaml|yml)$" + ) ;; CMake -(use-package cmake-mode) +(use-package cmake-mode + :ensure t + :mode "CMakeLists.txt$" + ) ;; C/C++ @@ -1014,40 +1147,45 @@ window, unless BACKGROUND (prefix-argument) is non-nil. (add-hook 'go-ts-mode-hook 'eglot-ensure) (add-hook 'go-mode-hook 'eglot-ensure) -(use-package clang-format) -(use-package clang-format+) -(add-hook 'c-mode-hook 'clang-format+-mode) -(add-hook 'c-ts-mode-hook 'clang-format+-mode) -(add-hook 'c++-mode-hook 'clang-format+-mode) -(add-hook 'c++-ts-mode-hook 'clang-format+-mode) -(setq clang-format+-context 'buffer) - -;; for viewing C/C++ coverage reports -(use-package cov) -(setq cov-coverage-mode t) - -;; Make lcov.info file in the root of the project discoverable -;; as the source of coverage -(setq cov-coverage-file-paths - (list #'(lambda (file-dir file-name) - (let ((try (format "%s/lcov.info" - (project-root (project-current t))))) - (and (file-exists-p try) - (cons (file-truename try) 'lcov)))))) +(use-package clang-format + :ensure t + :defer 2 + :config + ) +(use-package clang-format+ + :ensure t + :defer 2 + :config + (add-hook 'c-mode-hook 'clang-format+-mode) + (add-hook 'c-ts-mode-hook 'clang-format+-mode) + (add-hook 'c++-mode-hook 'clang-format+-mode) + (add-hook 'c++-ts-mode-hook 'clang-format+-mode) + (setq clang-format+-context 'buffer) + ) ;; Go -(add-hook 'before-save-hook #'gofmt-before-save) -(use-package go-mode) +(use-package go-mode + :ensure t + :mode "\\.go$" + :config + (add-hook 'before-save-hook #'gofmt-before-save) + ) ;; Zig -(use-package zig-mode) +(use-package zig-mode + :ensure t + :mode "\\.zig$" + ) ;; Terraform -(use-package terraform-mode) +(use-package terraform-mode + :ensure t + :mode "\\.tf$" + ) ;; Bash @@ -1055,10 +1193,16 @@ window, unless BACKGROUND (prefix-argument) is non-nil. ;; Nix -(use-package nix-mode) +(use-package nix-mode + :ensure t + :mode "\\.nix$" + ) -(use-package sudo-edit) -(global-set-key (kbd "C-c C-r") 'sudo-edit) +(use-package sudo-edit + :ensure t + :bind + ("C-c C-r" . sudo-edit) + ) (provide 'init) ;;; init.el ends here diff --git a/evil-collection.patch b/evil-collection.patch new file mode 100644 index 0000000..8b13d4c --- /dev/null +++ b/evil-collection.patch @@ -0,0 +1,3 @@ +diff --git a/modes/.nosearch b/modes/.nosearch +new file mode 100644 +index 0000000..e69de29 diff --git a/flake.lock b/flake.lock index 4e8dd75..06e1edf 100755 --- a/flake.lock +++ b/flake.lock @@ -11,11 +11,11 @@ ] }, "locked": { - "lastModified": 1714669473, - "narHash": "sha256-LuwvRYxFw8bE3b75oun2HjdbnwGArYEDzRdhtxkx95o=", + "lastModified": 1715533419, + "narHash": "sha256-PDlWxvgHqWEJdfAxMYLmoof+ohJrOHx9IZIxvHKE24U=", "owner": "nix-community", "repo": "emacs-overlay", - "rev": "8f77253911c7dc3ac829781ac7f37d1d35447c5a", + "rev": "dc94f94b49abb487f80e91978a1392e3e2b19fae", "type": "github" }, "original": { @@ -49,11 +49,11 @@ ] }, "locked": { - "lastModified": 1708027330, - "narHash": "sha256-7jqtoikxzTgy68P+yRg5lGWnJit6S9LdkVM1wCDVlGc=", + "lastModified": 1715696748, + "narHash": "sha256-e/xBDyInmuMSiDoXWEJCmxudjPiuyvRKpVupDYr76do=", "owner": "~knazarov", "repo": "git-plan", - "rev": "e94eee1acefbabfb8b0e9e64a6cf14f0730c5954", + "rev": "1d8f6f0c7c3146ec627a7e811723fc7f68eb7c6d", "type": "sourcehut" }, "original": { @@ -69,11 +69,11 @@ ] }, "locked": { - "lastModified": 1714043624, - "narHash": "sha256-Xn2r0Jv95TswvPlvamCC46wwNo8ALjRCMBJbGykdhcM=", + "lastModified": 1715381426, + "narHash": "sha256-wPuqrAQGdv3ISs74nJfGb+Yprm23U/rFpcHFFNWgM94=", "owner": "nix-community", "repo": "home-manager", - "rev": "86853e31dc1b62c6eeed11c667e8cdd0285d4411", + "rev": "ab5542e9dbd13d0100f8baae2bc2d68af901f4b4", "type": "github" }, "original": { @@ -105,11 +105,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1714679241, - "narHash": "sha256-Ufz2WBGCcqeXkVgD7bdc+JCrnyPt6G28Xpq2ussqygs=", + "lastModified": 1715539458, + "narHash": "sha256-lJm3R3EeBBBWnFmt7ZoDjuiGPCPzi7ruaN44R3V6Xqo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a6f8947d5a77b88ff43625408e2685c0be100a9b", + "rev": "6cd6e4db4279039918efc1dd8e28f55abeb0acaa", "type": "github" }, "original": { @@ -120,11 +120,11 @@ }, "nixpkgs-stable": { "locked": { - "lastModified": 1714531828, - "narHash": "sha256-ILsf3bdY/hNNI/Hu5bSt2/KbmHaAVhBbNUOdGztTHEg=", + "lastModified": 1715395895, + "narHash": "sha256-DreMqi6+qa21ffLQqhMQL2XRUkAGt3N7iVB5FhJKie4=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0638fe2715d998fa81d173aad264eb671ce2ebc1", + "rev": "71bae31b7dbc335528ca7e96f479ec93462323ff", "type": "github" }, "original": { @@ -198,11 +198,11 @@ ] }, "locked": { - "lastModified": 1713892811, - "narHash": "sha256-uIGmA2xq41vVFETCF1WW4fFWFT2tqBln+aXnWrvjGRE=", + "lastModified": 1715482972, + "narHash": "sha256-y1uMzXNlrVOWYj1YNcsGYLm4TOC2aJrwoUY1NjQs9fM=", "owner": "Mic92", "repo": "sops-nix", - "rev": "f1b0adc27265274e3b0c9b872a8f476a098679bd", + "rev": "b6cb5de2ce57acb10ecdaaf9bbd62a5ff24fa02e", "type": "github" }, "original": { diff --git a/nvim/basics.lua b/nvim/basics.lua index 6ff2e83..a78448c 100644 --- a/nvim/basics.lua +++ b/nvim/basics.lua @@ -15,3 +15,6 @@ vim.g.mapleader = ' ' vim.opt.shortmess :append("I") + +require('leap').set_default_keymaps() +require('neogit').setup() diff --git a/nvim/diagnostic.lua b/nvim/diagnostic.lua new file mode 100644 index 0000000..00cf8f4 --- /dev/null +++ b/nvim/diagnostic.lua @@ -0,0 +1,7 @@ +vim.diagnostic.config({ + virtual_text = false, + signs = true, + float = { border = "single" }, +}) +vim.o.updatetime = 250 +vim.cmd [[autocmd CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]] diff --git a/nvim/lspconfig.lua b/nvim/lspconfig.lua index 6aef3ce..8231c53 100644 --- a/nvim/lspconfig.lua +++ b/nvim/lspconfig.lua @@ -1,4 +1,3 @@ local capabilities = require('cmp_nvim_lsp').default_capabilities(vim.lsp.protocol.make_client_capabilities()) require'lspconfig'.gopls.setup{capabilities=capabilities} -require'lspconfig'.rnix.setup{capabilities=capabilities} diff --git a/secrets.yaml b/secrets.yaml index 7df324d..94fa778 100644 --- a/secrets.yaml +++ b/secrets.yaml @@ -2,7 +2,7 @@ hello: ENC[AES256_GCM,data:+LPt8J+Ks1m10+zZ2Q96r3K2W6Yeng7M7+c2TYDQ+/4AJl6Xc6hVn fastmail_password: ENC[AES256_GCM,data:tHr8PqIg9DigRBu2bgjUeg==,iv:NI9bENFPuKcOt1cd2kg2DKU22J1dJ+3mK7UoceZagR4=,tag:oEgeQb1iLKisOqHi9Ds7xg==,type:str] github_token: ENC[AES256_GCM,data:ET4zFSe1dyFum/HMlzT/0bEP/Kzr3vdp16eKZb63hBYcz0+bKmJ/NZGk4KyojPKgRfgHR3XrrJbVdFdP2QTjfX3XtVq6N7RoU4wOwjrdOgm+4JCKRqO6pWa5ieX0m1DB5NuU7hN6X6Yqwcu38dpGzBUinpcyQDmMHSby6epL,iv:IoFHQ6sC9ZxvOIckkoF5Wnn4+VvCHapwNduCBlELzrU=,tag:gfF24P2JUWUhEIxt3Np3MQ==,type:str] mullvad_account: ENC[AES256_GCM,data:CO4wl2vNAMEC9oy37nIrpw==,iv:a3w64u8XQ/tihIDxIPPtdZ6F7dldLPvRzGUs1MpVe4M=,tag:HQxJVuGEvI0fVj8yGptbdA==,type:str] -git_plan_config: ENC[AES256_GCM,data:N+CCMXP4JUCbhrIhddPXyB/we4ZmE8FYL0ms/MxSOdizInsuIOhfkJR5DlIFh2d45Pw/2e2b2lZNBYKU1r+tHwCJRrp/YuB39ee7E8ygq6uBXgL9KirNjGCQxttXvbulz27cJDQy0n5GVp9176nOwaxWtieG7VsE8PdyaszhkWt3fnFwefPZm5F0WCTxgd0rC7oamZE83FOdIW4rJupgcVYGQox/kLWyvbDxGL5KfQQ6x1Ho6v94rW4W6lXPCGwSSbW4i05vR94/Nv0atYPFB2WUBERCEIbUGJ4seawxfld464wtV5xSlSlkDDEHRGDCtzBdRkVOrLDCT0wDq+AfQQFViChiQoATAaHyK8zZqJgnEU0araOUdlxKQOEEj7Lm/HGwHvIxLGtZPlyfhybYcMfwTcb10nw61D+UqqbKjIvHZ+Q80DK0y0NnrVsehYMEcCqz1h0hfgh5v9Ygk6eiu7yDEk7GkbkWXkPCR0PHO/NOGwyQIHa0fVWnVCdkQDFHyWW77de4IcxnUhUwYsRWtULPuFYvcfog/9W6prgfluDW51y1K9vJK9yCaIPvpvOsmRK98zfgeET/vJYvTvmPw5kKOfeYMxXu8+3YQmeN7EePTBGRSalLxaS22tUXUB30WJEmhhFTnNCrkWugkC1zsvcUvY5/SKq5eKMbj54Mh7D7dm2hDveEIdgRIQtV9UJA6PDbrqqZj4GQrQLTp+1qrZl/i/kg3HYb2HA6ENMbGttJoAyv0YGj+YmlcvsC/rf5/lsiiPuFSSBHsir/uPtLeEg7JkiFBBE5Tm/QaTw08XMWB2YKQm7glq6cY9gHf/uH14LGuF0COc/Cbrc1O0+XqFoSvQ7LXJuB4Dr+4lfr49KzgId1wuMsFkxEsfpUC0aZtV7gVrA0bzlHHNfVpwk3TbwpmSmbjefImCswzXnzS/MJUUL2niY0RzguAwcDedbz+l/z83qNn0fWYpxpjVyhwhMOp/bvogYu6R6fVlz67NHvD52CTlKawEJw+O+cbX3UjcbX2WnDc59vsbDJRANDDrC6hmmj,iv:NXOlkzSW/LaSQxN11jY1qzQ4gOVaEJcmT4I9NkcfbXY=,tag:VoAIom2UF99XtCu+YXaS5A==,type:str] +git_plan_config: ENC[AES256_GCM,data:+mLBXtXEzqKrbLJkwZlW5veUaPEkgQ2TuT2gt237Nw/O6zqrAyl9ezKM5kFFHQ3yOkQyIiDRLpy0t9UiBFs+x43qkzVopjNniehwYcgYlAIcSTOrd3pcLWW3YVz1jYIrIdHMTF408rTrcSWHpO9DrKCs+/QJHLEmROelzaFUOmr9Q36CRzWCZ2xjNFbXKg3+00Hhc7UK7UbOnOPrIVNFLWcJ1ipmYPlqK2a5BCBWamGBddwhCypzh9TVjXDyARgBSQvnTpmwb3QAYmdpniDtRHiRHwyUDPGqoZXdPiguDb6QVjiPpRKrwtNGwEGlapCrqfltPi8yoIfJV88SBDKDfoYFgQODRWGMm0X1XL57voJB+G6SsoEbm8elrMbJx7LiIpQH1Tv1gXzbgl8tIB38vHsPhXHbGvavUJBcZ12q7vL/Whw0XWl8x1wrZQe92NeyjN8sjF9QUsfsg6NK6Dziiye6iIVzW4wXezjUSc/A3maeXcEZX2649FubCMV7rZ+Kqu3QVQH1agm5IgqY3UQ88Bc/i+gwISJvzP43/65JSOcxl0yp8tSrx7l/AYyRJjuoA5OwlcaTMECUNagUbFft9qb+7X0O6pz6L9h2z9hnNdWmTght7NDHaziMCsY0BzytdazgCWvRnWYDPEA9DCZTjjpVPQIxoB7wpUv/7nDCIT7faT0x3+hG8wTDyFAqV/N+/JgwSQSX,iv:o5Yc8Qa2eR5OaQYzVgjrBLUfQEMxKj11URuiS9fLNbY=,tag:bpfTTu03ip/NcYFe11PScA==,type:str] git_plan_credentials: ENC[AES256_GCM,data:d4egK2w4TGIDNaI2Wc3ViOBnH7/WpdeS1EoYe4/oaM4iayBXOEQMvT9qIgu/Hml34gvbBN9lRmlNkESVh7YpwO5wACkkRcO/0ZTyP8XzFUUo0IfUh1iHPjEQOF7vygW/woqBiQgFPRws9F+g6BW8aSQrBgvBF5IeNLhFBvSJUvTft1xEsNwFnkWnfZ2JWmYqLjEggoUEqtXMRw9KKcqm4DNXIzxmA8wSzDriIzeCVuSEV8sJD21saFPPaLw/jupLTLdWp5F8rAxLGa6e9coCNu8vSuqUgfv0jFET71bNw28xPrN38A/PIlUcR9MXe1SGqKAFxEv134ZkJr78g1PIWNoVDrmIlMpV6dYRLKM1FOcpAhJorIXooIl6quCdg2/U5onP8cQ7lt2LsEG5APKj7pz7huatdwM/CgxrcqPVb0E2Lk5c+wi3Rf9/Jz3BqcWQm3bwkHwivWyCD1Nw+qRXLFSfXGTovSBsxX0j4LbdP0o4iPuj068DGawpYC/AfcKfOCmh8aInQhGCQtIq14QGffU9GbW37gHu,iv:ZzOUYu3s+kfwbKajA+6fdu2EysipjoKD49muLNFBZ58=,tag:e0RI7rA8eLQI8h5L4pvS1A==,type:str] sops: kms: [] @@ -28,8 +28,8 @@ sops: U3loV2xDMkM5SWNXRDJobDloL0FVUUkK3OP7KvcKkE8mJ880dm6LMFZUxELjl8/P 6+q8qAYiAvl0Cbd4GzkNpUuBbLlFFWfFmC0vbgg8gyZ6xI5AFhHAPw== -----END AGE ENCRYPTED FILE----- - lastmodified: "2024-01-10T11:00:59Z" - mac: ENC[AES256_GCM,data:Y5AeyLjTDWIG4ZgB5dfOAJsyttZ3//B1Y7zFOgRwCPDSYTzNAJaOayI2d9iLFbKRT4lMDd3/u8esBrFyM50IhCQkuY7yWfjvuvyfEFE/3nF3X+Fgao4T9RlTF5YqH1JZg3MC785MLYo8jZteQ2l1iuXXZI94A+bMg9dctliCySs=,iv:nYk2AJVBA1eB1/2isklkQOcg1eQbWtSxS1kg7fVBPBY=,tag:1wNpL33fvVvQh0UKTDmUWg==,type:str] + lastmodified: "2024-05-14T14:42:26Z" + mac: ENC[AES256_GCM,data:dDv0TvWEioUn3w9RYqd9tPC9hNy0EDsA2sRhoDDC5nnNp55ZbjfqgVF5Kh91E8j1rd+8xjsqY/93i4PdRwGFYIb3gOsAhUmqx8LiI1DwQT9mUgv9anT/KcST5TfRU9/C1Vnz0SBhksl1yK+4mF2orubI5HMirg/l7Zqvvv7OnMU=,iv:ZXdryqFcaNNXqPDWIzACG5v+QRxRtWhxUHc/hCVaDQY=,tag:CIEkhxiHHhdUu7Z0CsNsng==,type:str] pgp: - created_at: "2023-06-10T01:03:11Z" enc: |- @@ -52,4 +52,4 @@ sops: -----END PGP MESSAGE----- fp: DDB4423999505236CF585F9B0560020C9C577C1B unencrypted_suffix: _unencrypted - version: 3.7.3 + version: 3.8.1