Skip to content

arkhan/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Configuración de Emacs usando Org-Babel

Config

base

;;; init.el --- Emacs Configuration -*- lexical-binding: t -*
;;; Commentary:
;; This config start here

(defvar cfg--file-name-handler-alist file-name-handler-alist)
(setq gc-cons-threshold 402653184
      gc-cons-percentage 0.6
      file-name-handler-alist nil)

(defvar conf:cache-dir (concat user-emacs-directory "cache/"))
(unless (file-exists-p conf:cache-dir)
  (make-directory conf:cache-dir))

(setq nsm-settings-file (concat conf:cache-dir "network-security.data"))
(setq network-security-level 'high)

(setq straight-repository-branch "develop"
      straight-base-dir conf:cache-dir
      straight-check-for-modifications '(check-on-save-find-when-checking))
      ;;straight-vc-git-default-clone-depth 100)

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" conf:cache-dir))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(require 'straight-x)

;; Removes in-build version from the `load-path'
(when-let (orglib (locate-library "org" nil load-path))
   (setq-default load-path (delete (substring (file-name-directory orglib) 0 -1)
                                   load-path)))

(straight-use-package
 '(org-plus-contrib
   :repo "https://code.orgmode.org/bzg/org-mode.git"
   :local-repo "org"
   :files (:defaults "contrib/lisp/*.el")
   :includes (org)))

leaf

(straight-use-package 'leaf)
(straight-use-package 'leaf-keywords)

(leaf leaf
  :require t
  :init
  (leaf leaf-keywords
	:emacs> 24.4
	:require t
    ;; :setq (leaf-defaults . '(:straight t))
	:init
	(leaf-keywords-init)))

(leaf diminish
  :straight t
  :require t)

(leaf async
  :straight t
  :leaf-defer nil
  :setq (async-bytecomp-package-mode . t))

(setq inhibit-startup-screen t
	  use-dialog-box nil
	  use-file-dialog nil
	  initial-scratch-message nil
	  large-file-warning-threshold (* 15 1024 1024))

(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
(toggle-indicate-empty-lines)
(delete-selection-mode)
(blink-cursor-mode -1)
(add-hook 'before-save-hook 'delete-trailing-whitespace)
(set-default 'truncate-lines 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 buffer-file-coding-system 'utf-8-auto-unix
			  x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))

(setq auto-save-default nil
	  auto-save-list-file-prefix nil
	  make-backup-files nil
	  create-lockfiles nil
	  ring-bell-function 'ignore
	  major-mode 'text-mode)
                                        ;current-language-environment "Spanish")

(setq-default indent-tabs-mode nil
              frame-resize-pixelwise t
			  tab-width 4
			  frame-title-format (list (user-login-name) "@" (system-name) " %b [%m]"))

(global-set-key (kbd "RET") 'newline-and-indent)
(global-set-key (kbd "<f5>") 'revert-buffer)
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key "\M-p" 'backward-paragraph)
(global-set-key "\M-n" 'forward-paragraph)
(global-set-key (kbd "C-x k") 'kill-buffer-and-window)

(set-frame-parameter nil 'fullscreen 'maximized)

better-defaults

(leaf better-defaults
  :straight t
  :pre-setq `((custom-file . ,(concat conf:cache-dir "custom.el"))
              (url-configuration-directory . ,(concat conf:cache-dir "url/"))
              (eshell-directory-name . ,(concat conf:cache-dir "eshell/" ))
              (savehist-file . ,(concat conf:cache-dir "history"))
              (history-length . 1000)
              (history-delete-duplicates . t)
              (savehist-save-minibuffer-history . 1)
              (savehist-additional-variables . '(kill-ring
                                                 search-ring
                                                 regexp-search-ring)))
  :config
  (unless (file-exists-p custom-file)
    (with-temp-buffer
      (write-file custom-file)))
  (load custom-file)
  (savehist-mode t)
  (ido-mode -1))

abbrev

(leaf abbrev
  ;; :straight nil
  :pre-setq `((abbrev-file-name . ,(concat conf:cache-dir "abbrev.el"))
              (save-abbrevs . 'silently)
              (default-abbrev-mode . t)
              (save-abbrevs . t))
  :init
  (unless (file-exists-p abbrev-file-name)
    (with-temp-buffer
      (write-file abbrev-file-name)))
  (when (file-exists-p abbrev-file-name)
    (quietly-read-abbrev-file))

  (abbrev-mode t))

bookmarks

(leaf bookmark
  ;; :straight nil
  :pre-setq `(bookmark-default-file . ,(concat conf:cache-dir "bookmarks"))
  :setq (bookmark-save-flag . 1)
  :config
  (when (file-exists-p bookmark-default-file)
    (bookmark-load bookmark-default-file t)))

recentf

(leaf recentf
  ;; :straight nil
  :pre-setq `((recentf-save-file . ,(concat conf:cache-dir "recentf"))
              (recentf-exclude . '("/tmp/" "/ssh:" "/sudo:" "/su:"
                                   "/scp:" "/root" "/scpx:" "/sshx:"
                                   "/media/data/org/" "/home/arkhan/.emacs.d/cache/"
                                   "/media/data/Mail/Maildir/"
                                   "/home/arkhan/mail/"))
              (recentf-max-saved-items . 10)
              (recentf-max-menu-items . 10)
              (recentf-keep . '(file-remote-p file-readable-p))
              (recentf-auto-cleanup . 'never))
  :config (recentf-mode +1))

saveplace

(leaf saveplace
  ;; :straight nil
  :pre-setq `(save-place-file . ,(concat conf:cache-dir "saveplace.el"))
  :setq-default (save-place . t)
  :init (save-place-mode))

semantic

(leaf semantic
  ;; :straight nil
  :leaf-defer nil
  :require t
  :setq `(semanticdb-default-save-directory . ,(concat conf:cache-dir "semanticdb/"))
  :init
  (add-to-list 'semantic-default-submodes
               'global-semantic-idle-summary-mode)
  (semantic-mode 1))

tramp

(eval-after-load 'tramp '(setenv "SHELL" "/bin/bash"))

(leaf exec-path-from-shell
  :straight t
  :require t
  :pre-setq (shell-file-name . "/bin/bash")
  :config (exec-path-from-shell-initialize))


(leaf tramp
  :setq `((tramp-persistency-file-name . ,(concat conf:cache-dir "tramp"))
          (tramp-auto-save-directory . ,(concat conf:cache-dir "tramp-autosave"))
          (tramp-default-method . "scp")
          (tramp-debug-buffer . t)
          (tramp-verbose . 10)
          (tramp-chunksize . 2000)
          (tramp-shell-prompt-pattern . "\\(?:^\\|\r\\)[^]#$%>\n]*#?[]#$%>] *\\(^[\\[[0-9;]*[a-zA-Z] *\\)*")))
          ;;(tramp-use-ssh-controlmaster-options . nil)))

load-user-files

(defun load-user-file (file)
  (interactive "f")
  "Load a file in current user's configuration directory"
  (load-file (expand-file-name (concat file ".el") "~/.emacs.d/private")))

UI

all-the-icons

(leaf all-the-icons
  :straight t)

avy

(leaf avy
  :straight t
  :setq (avy-all-windows . t))

bufler

(leaf bufler
  :straight t
  :require t
  :bind ("C-x C-b" . bufler-switch-buffer)
  :setq (bufler-columns . '("Name" "Path"))
  :config
  (bufler-defgroups
   (group
    ;; Subgroup collecting all named workspaces.
    (auto-workspace))
   (group
    ;; Subgroup collecting all `help-mode' and `info-mode' buffers.
    (group-or "*Help/Info*"
              (mode-match "*Help*" (rx bos "help-"))
              (mode-match "*Info*" (rx bos "info-"))))
   (group
    ;; Subgroup collecting all special buffers (i.e. ones that are not
    ;; file-backed), except `magit-status-mode' buffers (which are allowed to fall
    ;; through to other groups, so they end up grouped with their project buffers).
    (group-and "*Special*"
               (lambda (buffer)
                 (unless (or (funcall (mode-match "Magit" (rx bos "magit-status"))
                                      buffer)
                             (funcall (mode-match "Dired" (rx bos "dired"))
                                      buffer)
                             (funcall (auto-file) buffer))
                   "*Special*")))
    (group
     ;; Subgroup collecting these "special special" buffers
     ;; separately for convenience.
     (name-match "**Special**"
                 (rx bos "*" (or "Messages" "Warnings" "scratch" "Backtrace") "*")))
    (group
     ;; Subgroup collecting all other Magit buffers, grouped by directory.
     (mode-match "*Magit* (non-status)" (rx bos (or "magit" "forge") "-"))
     (auto-directory))
    ;; Subgroup for Helm buffers.
    (mode-match "*Helm*" (rx bos "helm-"))
    ;; Remaining special buffers are grouped automatically by mode.
    (auto-mode))
   ;; All buffers under "~/.emacs.d" (or wherever it is).
   (dir user-emacs-directory)
   (group
    ;; Subgroup collecting buffers in `org-directory' (or "~/org" if
    ;; `org-directory' is not yet defined).
    (dir (if (bound-and-true-p org-directory)
             org-directory
           "~/org"))
    (group
     ;; Subgroup collecting indirect Org buffers, grouping them by file.
     ;; This is very useful when used with `org-tree-to-indirect-buffer'.
     (auto-indirect)
     (auto-file))
    ;; Group remaining buffers by whether they're file backed, then by mode.
    (group-not "*special*" (auto-file))
    (auto-mode))
   (group
    ;; Subgroup collecting buffers in a version-control project,
    ;; grouping them by directory.
    (auto-project))
   ;; Group remaining buffers by directory, then major mode.
   (auto-directory)
   (auto-mode)))

cursor

(leaf frame
  ;; :straight nil
  :setq-default (cursor-type . '(hbar . 2))
  :setq (x-stretch-cursor . t)
  :config
  (defun set-cursor-hook (frame)
    (modify-frame-parameters
     frame (list (cons 'cursor-color "white"))))

  :hook (after-make-frame-functions . set-cursor-hook))

dashboard

(leaf page-break-lines
  :straight t
  :diminish page-break-lines-mode
  :config (page-break-lines-mode))

(leaf dashboard
  :straight t
  :pre-setq `((dashboard-banner-logo-title . ,(concat "GNU Emacs " emacs-version
                                                      " kernel " (car (split-string (shell-command-to-string "uname -r") "-"))
                                                      " x86_64 " (car (split-string (shell-command-to-string "/bin/sh -c '. /etc/os-release && echo $PRETTY_NAME'") "\n"))))
              (dashboard-startup-banner . 'logo)
              (dashboard-center-content . t)
              (dashboard-set-heading-icons . t)
              (dashboard-set-file-icons . t)
              (dashboard-items . '((recents  . 10)
                                   (bookmarks . 5)
                                   (projects . 5)))
              (initial-buffer-choice . '(lambda () (switch-to-buffer "*dashboard*"))))
  :config (dashboard-setup-startup-hook))

font

unicode-fonts

(leaf pcache
  :straight t
  :setq `(pcache-directory . ,(let ((dir (concat conf:cache-dir "pcache/")))
                                (make-directory dir t)
                                dir)))

(leaf unicode-fonts
  :straight t
  ;; :init
  ;; (setq unicode-fonts-block-font-mapping
  ;;     '(("Emoticons"
  ;;        ("DejaVu Sans Mono")))
  ;;     unicode-fonts-fontset-names '("fontset-default"))
  :hook (emacs-startup-hook . unicode-fonts-setup))

config

(leaf emacs
    ;; :straight nil
    :config
    ;; (setq conf:font-family "PragmataPro Mono Liga"
    ;;       conf:font-name "PragmataPro Mono Liga"
    ;;       conf:font-size 13.5
    ;;       inhibit-compacting-font-caches t)

    (setq conf:font-family "Fantasque Sans Mono"
          conf:font-name "Fantasque Sans Mono"
          conf:font-size 13.5
          inhibit-compacting-font-caches t)


    (defun fc-list ()
      "Genera una lista de tipografías disponibles usando fc-list"
      (if (executable-find "fc-list")
          (split-string (shell-command-to-string "fc-list --format='%{family[0]}\n' | sort | uniq") "\n")
        (progn
          (warn "fc-list no disponible en $PATH")
          nil)))

    (defun font-exists-p (font)
      "Comprueba si una tipografía FONT existe.

      Código parcialmente sacado de https://redd.it/1xe7vr"
      (let ((font-list (or (font-family-list) (fc-list))))
        (if (member font font-list)
            t
          nil)))

    (defun font-pt-to-height (pt)
      "Transforma una altura en puntos PT a altura de `face-attribute'."
      ;; el valor es de 1/10pt, por tanto 100 seria equivalente a 10pt, etc.
      (truncate (* pt 10)))

    (defun font-setup (&optional frame)
      (cond ((font-exists-p conf:font-family)
             (set-face-attribute 'default frame :height (font-pt-to-height conf:font-size) :font conf:font-name))))

    (defun font-setup-frame (frame)
      "configura la tipografía por cada nuevo marco FRAME creado."
      (select-frame frame)
      (when (display-graphic-p)
        (font-setup frame)))

    (if (daemonp)
        (add-hook 'after-make-frame-functions #'font-setup-frame)
      (font-setup)))

pretty

(leaf composite
  ;; :straight nil
  :leaf-defer nil
  :emacs>="27.0"
  :config
  (dolist (hook `(ediff-mode-hook
                  mu4e-headers-mode-hook
                  notmuch-show-mode-hook
                  package-menu-mode-hook))
    (add-hook hook (lambda () (setq-local auto-composition-mode nil))))

  ;; support ligatures, some toned down to prevent hang
  (let ((alist
         '((33 . ".\\(?:\\(==\\|[!=]\\)[!=]?\\)")
           (35 . ".\\(?:\\(###?\\|_(\\|[(:=?[_{]\\)[#(:=?[_{]?\\)")
           (36 . ".\\(?:\\(>\\)>?\\)")
           (37 . ".\\(?:\\(%\\)%?\\)")
           (38 . ".\\(?:\\(&\\)&?\\)")
           (42 . ".\\(?:\\(\\*\\*\\|[*>]\\)[*>]?\\)")
           ;; (42 . ".\\(?:\\(\\*\\*\\|[*/>]\\).?\\)")
           (43 . ".\\(?:\\([>]\\)>?\\)")
           ;; (43 . ".\\(?:\\(\\+\\+\\|[+>]\\).?\\)")
           (45 . ".\\(?:\\(-[->]\\|<<\\|>>\\|[-<>|~]\\)[-<>|~]?\\)")
           (46 . ".\\(?:\\(\\.[.<]\\|[-.=]\\)[-.<=]?\\)")
           (47 . ".\\(?:\\(//\\|==\\|[=>]\\)[/=>]?\\)")
           ;; (47 . ".\\(?:\\(//\\|==\\|[*/=>]\\).?\\)")
           (48 . ".\\(?:\\(x[a-fA-F0-9]\\).?\\)")
           (58 . ".\\(?:\\(::\\|[:<=>]\\)[:<=>]?\\)")
           (59 . ".\\(?:\\(;\\);?\\)")
           (60 . ".\\(?:\\(!--\\|\\$>\\|\\*>\\|\\+>\\|-[-<>|]\\|/>\\|<[-<=]\\|=[<>|]\\|==>?\\||>\\||||?\\|~[>~]\\|[$*+/:<=>|~-]\\)[$*+/:<=>|~-]?\\)")
           (61 . ".\\(?:\\(!=\\|/=\\|:=\\|<<\\|=[=>]\\|>>\\|[=>]\\)[=<>]?\\)")
           (62 . ".\\(?:\\(->\\|=>\\|>[-=>]\\|[-:=>]\\)[-:=>]?\\)")
           (63 . ".\\(?:\\([.:=?]\\)[.:=?]?\\)")
           (91 . ".\\(?:\\(|\\)|?\\)")
           ;; (92 . ".\\(?:\\([\\n]\\)[\\]?\\)")
           (94 . ".\\(?:\\(=\\)=?\\)")
           (95 . ".\\(?:\\(|_\\|[_]\\)_?\\)")
           (119 . ".\\(?:\\(ww\\)w?\\)")
           (123 . ".\\(?:\\(|\\).?\\)")
           (124 . ".\\(?:\\(->\\|=>\\||[-=>]\\||||*>\\|[]=>|}-]\\).?\\)")
           (126 . ".\\(?:\\(~>\\|[-=>@~]\\).?\\)"))))
    (dolist (char-regexp alist)
      (set-char-table-range composition-function-table (car char-regexp)
                            `([,(cdr char-regexp) 0 font-shape-gstring])))))

(add-hook 'org-mode-hook '(lambda ()
                            (mapc (lambda (pair) (push pair prettify-symbols-alist))
                                  '(("#+BEGIN_SRC" . )
                                    ("#+END_SRC" . )
                                    ("#+BEGIN_EXAMPLE" . )
                                    ("#+END_EXAMPLE" . )
                                    ("#+BEGIN_QUOTE" . )
                                    ("#+END_QUOTE" . )
                                    ("#+begin_quote" . )
                                    ("#+end_quote" . )
                                    ("#+begin_example" . )
                                    ("#+end_example" . )
                                    ("#+begin_src" . )
                                    ("#+end_src" . )))))

(add-hook 'prog-mode-hook '(lambda ()
                             (mapc (lambda (pair) (push pair prettify-symbols-alist))
                                   '(("in" . ?\u2208)
                                     ("IN" . ?\u2208)
                                     ("not in" . ?\u2209)
                                     ("NOT IN" . ?\u2209)
                                     ("not" . ?\u00AC)
                                     ("NOT" . ?\u00AC)))))
(add-hook 'prog-common-hook '(lambda ()
                               (font-lock-add-keywords
                                nil
                                '(("\\<\\(FIX\\|FIXME\\|TODO\\|BUG\\|HACK\\):" 1 font-lock-warning-face t)))))

(add-hook 'after-init-hook #'global-prettify-symbols-mode)

ivy

(leaf ivy
  :straight t
  :diminish ivy-mode
  :bind (ivy-mode-map
         ("C-'" . ivy-avy))
  :setq ((ivy-wrap . t)
         (ivy-virtual-abbreviate . 'full)
         (ivy-use-virtual-buffers . t)
         (ivy-use-selectable-prompt . t)
         (ivy-count-format . "(%d/%d) ")
         (ivy-re-builders-alist . '((read-file-name-internal . ivy--regex-fuzzy)
                                    (t . ivy--regex-plus)))
         (ivy-on-del-error-function . nil)
         (ivy-initial-inputs-alist . nil)
         (enable-recursive-minibuffers . t))

  :config
  (add-to-list 'ivy-ignore-buffers "\\*Async Shell Command\\*")
  (add-to-list 'ivy-ignore-buffers "\\*Messages\\*")
  (add-to-list 'ivy-ignore-buffers "\\*elfeed-log\\*")
  (add-to-list 'ivy-ignore-buffers "\\*Help\\*")
  (add-to-list 'ivy-ignore-buffers "\\*Compile-Log\\*")
  (add-to-list 'ivy-ignore-buffers "\\*magit-.*")
  (add-to-list 'ivy-ignore-buffers "\\magit-.*")
  (add-to-list 'ivy-ignore-buffers "\\*tide")
  (add-to-list 'ivy-ignore-buffers "\\*Flycheck.*")
  (add-to-list 'ivy-ignore-buffers "\\*lsp-.*")
  (add-to-list 'ivy-ignore-buffers "\\*git-gutter:.*")
  (with-eval-after-load "projectile"
    (setf projectile-globally-ignored-buffers ivy-ignore-buffers))
  (ivy-mode))

(leaf prescient
  :straight t
  :require t
  :pre-setq `(prescient-save-file . ,(concat conf:cache-dir "prescient.el"))
  :config (prescient-persist-mode))

(leaf ivy-prescient
  :straight t
  :require t
  :after ivy
  :init (ivy-prescient-mode))

(leaf ivy-xref
  :straight t
  :require t
  :init (if (< emacs-major-version 27)
            (setq xref-show-xrefs-function #'ivy-xref-show-xrefs)
          (setq xref-show-definitions-function #'ivy-xref-show-defs)))

;;(setq confirm-nonexistent-file-or-buffer t)

(leaf swiper
  :straight t
  :bind* (("C-s" . swiper)
          ("C-r" . swiper)
          ("C-M-s" . swiper-all))
  :bind (read-expression-map
         ("C-r" . counsel-minibuffer-history)))

(leaf counsel
  :straight t
  :bind (("M-x" . counsel-M-x)
         ("C-c b" . counsel-imenu)
         ("C-x C-r" . counsel-rg)
         ("C-x C-f" . counsel-find-file)
         ("C-h f" . counsel-describe-function)
         ("C-h v" . counsel-describe-variable)
         ("C-h b" . counsel-descbinds)
         ("M-y" . counsel-yank-pop)
         ("M-SPC" . counsel-shell-history))
  :setq (counsel-rg-base-command . "sh -c \"rg -uuu -S --ignore-file-case-insensitive -g '!/volumes' -g '!/backups' -g '!/.git' --no-heading --line-number --color never %s\""))

(leaf ivy-rich
  :straight t
  :require t
  :setq (ivy-format-function . 'ivy-format-function-line)
  :config (ivy-rich-mode))

maple

(leaf maple-imenu
  :straight (maple-imenu
             :type git
             :host github
             :repo "honmaple/emacs-maple-imenu")
  :bind ("M-2" . maple-imenu)
  :require t
  :commands (maple-imenu)
  :setq ((maple-imenu-display-alist . '((side . left) (slot . -1)))
         (maple-imenu-autoresize . nil)
         (maple-imenu-width . 36))
  :hook (mode-hook . (lambda ()
                       (setq imenu-create-index-function 'semantic-create-imenu-index))))

;; (leaf maple-preview
;;   :straight (maple-preview
;;              :type git
;;              :host github
;;              :repo "honmaple/emacs-maple-preview"
;;              :files ("*.el" "index.html" "static"))
;;   :commands (maple-preview-mode))

;; (leaf maple-minibuffer
;;   :straight (maple-minibuffer
;;              :type git
;;              :host github
;;              :repo "honmaple/emacs-maple-minibuffer")
;;   :require t
;;   :setq ((maple-minibuffer:height . nil)
;;          (maple-minibuffer:position-type . 'frame-bottom-left)
;;          (maple-minibuffer:border-color . "gray50")
;;          (maple-minibuffer:width . 0.7)
;;          (maple-minibuffer:cache . nil)
;;          (maple-minibuffer:action . '(read-from-minibuffer read-string))
;;          (maple-minibuffer:ignore-action . '(org-schedule org-time-stamp eval-expression))
;;          (maple-minibuffer:ignore-regexp . '("^anzu-" "^mu4e-" "^yes-" "^save-")))
;;   :config
;;   ;; more custom parameters for frame
;;   (defun maple-minibuffer:parameters ()
;;     "Maple minibuffer parameters."
;;     `((height . ,(or maple-minibuffer:height 10))
;;       (width . ,(or (round (* (frame-width) 0.80)) maple-minibuffer:width))
;;       (left-fringe . 5)
;;       (right-fringe . 5)))

;;   :hook (after-init-hook))

modeline

doom-modeline

(leaf doom-modeline
  :straight t
  :setq ((doom-modeline-height . 15)
         (doom-modeline-bar-width . 7)
         (doom-modeline-icon . nil)
         (doom-modeline-checker-simple-format . nil)
         (doom-modeline-modal-icon . nil)
         (doom-modeline-mu4e . t)
         (doom-modeline-window-width-limit . 'window-width)
         (doom-modeline-project-detection . 'projectile)
         (doom-modeline-buffer-file-name-style . 'truncate-from-project))
  :hook (emacs-startup-hook . doom-modeline-mode))

smart-mode-line

(leaf smart-mode-line
  :straight t
  :setq ((line-number-mode . t)
         (column-number-mode . t)
         (sml/mode-width . 10)
         (sml/no-confirm-load-theme . t)
         (sml/theme . 'respectful))
  :hook (emacs-startup-hook . sml/setup))

(leaf mini-modeline
  :straight t
  :custom-face ((mini-modeline-mode-line . '((t (:background "dim gray" :box nil :height 0.1))))
                (mini-modeline-mode-line-inactive . '((t (:background "#333333" :box nil :height 0.1)))))
  :setq ((mini-modeline-truncate-p . t)
         (mini-modeline-)
         (mini-modeline-r-format . '("%e"
                                     mode-line-front-space
                                     mode-line-mule-info
                                     mode-line-client
                                     mode-line-modified
                                     mode-line-remote
                                     mode-line-frame-identification
                                     mode-line-buffer-identification
                                     (vc-mode vc-mode)
                                     " "
                                     mode-line-position
                                     " "
                                     mode-line-modes
                                     mode-line-misc-info
                                     mode-line-end-spaces)))
  :hook (emacs-startup-hook . mini-modeline-mode))

(leaf rich-minority
  :straight t
  :setq ((rm-blacklist . nil)
         (rm-whitelist . "FlyC\\|Flymake\\|lsp"))
  :hook (emacs-startup-hook . rich-minority-mode))

move-dup

(leaf move-dup
  :straight t
  :leaf-defer nil
  :diminish t
  :bind (("M-<up>" . md-move-lines-up)
         ("M-<down>" . md-move-lines-down)
         ("C-M-<up>" . md-duplicate-up)
         ("C-M-<down>" . md-duplicate-down))
  :config (global-move-dup-mode))

dired

(leaf dired-toggle
  :straight t
  :require dired
  :leaf-defer nil
  :bind (("M-1" . dired-toggle)
         (dired-mode-map
          ("q" . dired-toggle-quit)
          ([remap dired-find-file] . dired-toggle-find-file)
          ([remap dired-up-directory] . dired-toggle-up-directory)
          ("C-c C-u" . dired-toggle-up-directory)))
  :setq ((dired-toggle-window-size . 32)
         (dired-toggle-window-side . 'left))
  :hook (dired-toggle-mode-hook . (lambda () (interactive)
                                    (visual-line-mode 1)
                                    (setq-local visual-line-fringe-indicators '(nil right-curly-arrow))
                                    (setq-local word-wrap nil))))

(leaf dired-subtree
  :straight t
  :after dired
  :setq (dired-subtree-use-backgrounds . nil)
  :bind (dired-mode-map
         ("<tab>" . dired-subtree-toggle)
         ("<C-tab>" . dired-subtree-cycle)
         ("<S-iso-lefttab>" . dired-subtree-remove)))

neotree

(leaf shrink-path
  :straight t
  :require t)

(leaf neotree
  :straight t
  :bind (("M-1" . neotree-project-dir-toggle)
         (neotree-mode-map
          ("<C-return>" . neotree-change-root)
          ("C" . neotree-change-root)
          ("c" . neotree-create-node)
          ("+" . neotree-create-node)
          ("d" . neotree-delete-node)
          ("r" . neotree-rename-node)))
  :setq-default (neo-persist-show . t)
  :setq ((neo-theme . 'ascii)
         (neo-vc-integration . nil)
         (neo-window-width . 36)
         (neo-create-file-auto-open . t)
         (neo-smart-open . t)
         (neo-show-auto-change-root . t)
         (neo-autorefresh . nil)
         (neo-banner-message . nil)
         (neo-mode-line-type . 'none)
         (neo-dont-be-alone . t)
         (neo-show-updir-line . nil)
         (neo-show-hidden-files . nil)
         (neo-auto-indent-point . t)
         (neo-hidden-regexp-list . '(".DS_Store" ".idea/" ".pyc" ".tern-port"
                                     ".git/*" "node_modules/*" ".meteor" "deps")))
  :config
  (defun shrink-root-entry (node)
    "shrink-print pwd in neotree"
    (insert (propertize (concat (shrink-path-dirs node) "\n") 'face `(:inherit (,neo-root-dir-face)))))

  (advice-add #'neo-buffer--insert-root-entry :override #'shrink-root-entry)

  (defun neotree-project-dir-toggle ()
    "Open NeoTree using the project root, using find-file-in-project,
  or the current buffer directory."
    (interactive)
    (let ((project-dir
           (ignore-errors
             ;;; Pick one: projectile or find-file-in-project
             (projectile-project-root)))
          (file-name (buffer-file-name))
          (neo-smart-open t))
      (if (and (fboundp 'neo-global--window-exists-p)
               (neo-global--window-exists-p))
          (neotree-hide)
        (progn
          (neotree-show)
          (if project-dir
              (neotree-dir project-dir))
          (if file-name
              (neotree-find file-name)))))))

selectrum

(leaf selectrum
  :straight t
  :require t
  :hook (emacs-startup-hook))

(leaf selectrum-prescient
  :straight t
  :require t
  :after (selectrum)
  :hook ((emacs-startup-hook . selectrum-prescient-mode)
         (emacs-startup-hook . prescient-persist-mode)))

(leaf ctrlf
  :straight t
  :hook (after-init-hook))

shackle

(leaf shackle
  :straight t
  :setq ((shackle-default-size . 0.4)
         (shackle-rules . '(
                            ;;("*Bufler*" :select t :size 0.3 :align left :popup t)
                            ("*Calendar*" :select t :size 0.3 :align below)
                            ("*Compile-Log*" :ignore t)
                            ("*Completions*" :size 0.3  :align t)
                            ("*format-all-errors*" :select t :size 0.1 :align below)
                            ("*Help*" :select t :inhibit-window-quit t :other t)
                            ("*Messages*" :ignore t)
                            ("*Process List*" :select t :size 0.3 :align below)
                            ("*Proced*" :select t :size 0.3 :align below)
                            ("*Python*" :select t :size 0.3 :align bellow)
                            ("*Shell Command Output*" :select nil)
                            ("\\*TeX.*\\*" :regexp t :autoclose t :align below :size 10)
                            ("*Warnings*" :ignore t)
                            ("*el-get bootstrap*" :ignore t)
                            ("*undo-tree*" :size 0.25 :align left)
                            ("\\*Async Shell.*\\*" :regexp t :ignore t)
                            ("\\*[Wo]*Man.*\\*" :regexp t :select t :inhibit-window-quit t :other t)
                            ("\\*poporg.*\\*" :regexp t :select t :other t)
                            ("\\*shell*\\*" :select t :other t)
                            ("\\`\\*ivy.*?\\*\\'" :regexp t :size 0.3 :align t)
                            ("edbi-dbviewer" :regexp t :select t :same t)
                            ("*edbi:query-result" :regexp t :size 0.8 :align bellow)
                            (occur-mode :select nil :align t)
                            (pdf-view-mode :other t)
                            (compilation-mode :select nil))))
  :hook (emacs-startup-hook))

sublimity

(leaf sublimity-scroll
  :straight sublimity
  :require t
  :setq ((hscroll-margin . 2)
         (hscroll-step . 1)
         (scroll-conservatively . 1001)
         (scroll-margin . 0)
         (scroll-preserve-screen-position . t))
  :init (sublimity-mode 1))

switch-windows

(leaf switch-window
  :straight t
  :bind (("C-x o" . switch-window)
         ("C-x 1" . switch-window-then-maximize)
         ("C-x 2" . switch-window-then-split-below)
         ("C-x 3" . switch-window-then-split-right)
         ("C-x 0" . switch-window-then-delete)))

theme

(leaf vibrant-ink-theme
  :straight (vibrant-ink-theme
             :type git
             :host github
             :repo "arkhan/vibrant-ink-theme")
  :init (load-theme 'vibrant-ink t))

zoom

(leaf zoom-frm
  :straight t
  :bind (("C-+" . zoom-in/out)
         ("C--" . zoom-in/out)
         ("C-=" . zoom-in/out)
         ("C-0" . zoom-in/out)
         ("<C-mouse-4>" . zoom-in)
         ("<C-mouse-5>" . zoom-out))
  :setq (zoom-frame/buffer . 'frame))

Prog

company

(leaf company
  :straight t
  :diminish company-mode
  :commands (company-complete-common company-manual-begin company-grab-line)
  :setq ((company-idle-delay . 0)
         (company-show-numbers . t)
         (company-minimum-prefix-length . 2)
         (company-tooltip-limit . 5)
         (company-dabbrev-downcase . nil)
         (company-dabbrev-ignore-case . nil)
         (company-dabbrev-code-other-buffers . t)
         (company-tooltip-align-annotations . t)
         (company-require-match . 'never)
         (company-global-modes . '(not erc-mode message-mode help-mode gud-mode eshell-mode))
         (company-backends . '((company-capf
                                company-keywords
                                company-yasnippet)
                               (company-abbrev company-dabbrev)))
         (company-frontends . '(company-pseudo-tooltip-frontend
                                company-echo-metadata-frontend)))

  :config (global-company-mode +1))

(leaf company-dict
  :straight t
  :require t
  :setq `(company-dict-dir . ,(concat conf:cache-dir "dict/"))
  :config (add-to-list 'company-backends 'company-dict))

(leaf company-prescient
  :straight t
  :require t
  :after company
  :init (company-prescient-mode))

(leaf company-posframe
  :straight t
  :diminish company-posframe-mode
  :config (company-posframe-mode))

(leaf company-box
  :straight t
  :diminish company-box-mode
  :commands (company-box--get-color
             company-box--resolve-colors
             company-box--add-icon
             company-box--apply-color
             company-box--make-line
             company-box-icons--elisp)
  :hook (company-mode-hook . company-box-mode)
  :setq ((company-box-backends-colors . nil)
         (company-box-show-single-candidate . t)
         (company-box-max-candidates . 50)
         (company-box-doc-delay . 0.3))
  :config
  ;; Support `company-common'
  (defun my-company-box--make-line (candidate)
    (-let* (((candidate annotation len-c len-a backend) candidate)
            (color (company-box--get-color backend))
            ((c-color a-color i-color s-color) (company-box--resolve-colors color))
            (icon-string (and company-box--with-icons-p (company-box--add-icon candidate)))
            (candidate-string (concat (propertize (or company-common "") 'face 'company-tooltip-common)
                                      (substring (propertize candidate 'face 'company-box-candidate) (length company-common) nil)))
            (align-string (when annotation
                            (concat " " (and company-tooltip-align-annotations
                                             (propertize " " 'display `(space :align-to (- right-fringe ,(or len-a 0) 1)))))))
            (space company-box--space)
            (icon-p company-box-enable-icon)
            (annotation-string (and annotation (propertize annotation 'face 'company-box-annotation)))
            (line (concat (unless (or (and (= space 2) icon-p) (= space 0))
                            (propertize " " 'display `(space :width ,(if (or (= space 1) (not icon-p)) 1 0.75))))
                          (company-box--apply-color icon-string i-color)
                          (company-box--apply-color candidate-string c-color)
                          align-string
                          (company-box--apply-color annotation-string a-color)))
            (len (length line)))
      (add-text-properties 0 len (list 'company-box--len (+ len-c len-a)
                                       'company-box--color s-color)
                           line)
      line))
  (advice-add #'company-box--make-line :override #'my-company-box--make-line)

  ;; Prettify icons
  (defun my-company-box-icons--elisp (candidate)
    (when (derived-mode-p 'emacs-lisp-mode)
      (let ((sym (intern candidate)))
        (cond ((fboundp sym) 'Function)
              ((featurep sym) 'Module)
              ((facep sym) 'Color)
              ((boundp sym) 'Variable)
              ((symbolp sym) 'Text)
              (t . nil)))))
  (advice-add #'company-box-icons--elisp :override #'my-company-box-icons--elisp)

  (when (and (display-graphic-p)
             (require 'all-the-icons nil t))
    (declare-function all-the-icons-faicon 'all-the-icons)
    (declare-function all-the-icons-material 'all-the-icons)
    (declare-function all-the-icons-octicon 'all-the-icons)
    (setq company-box-icons-all-the-icons
          `((Unknown . ,(all-the-icons-material "find_in_page" :height 0.85 :v-adjust -0.2))
            (Text . ,(all-the-icons-faicon "text-width" :height 0.8 :v-adjust -0.05))
            (Method . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple))
            (Function . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple))
            (Constructor . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple))
            (Field . ,(all-the-icons-octicon "tag" :height 0.8 :v-adjust 0 :face 'all-the-icons-lblue))
            (Variable . ,(all-the-icons-octicon "tag" :height 0.8 :v-adjust 0 :face 'all-the-icons-lblue))
            (Class . ,(all-the-icons-material "settings_input_component" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange))
            (Interface . ,(all-the-icons-material "share" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue))
            (Module . ,(all-the-icons-material "view_module" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue))
            (Property . ,(all-the-icons-faicon "wrench" :height 0.8 :v-adjust -0.05))
            (Unit . ,(all-the-icons-material "settings_system_daydream" :height 0.85 :v-adjust -0.2))
            (Value . ,(all-the-icons-material "format_align_right" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue))
            (Enum . ,(all-the-icons-material "storage" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange))
            (Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.85 :v-adjust -0.2))
            (Snippet . ,(all-the-icons-material "format_align_center" :height 0.85 :v-adjust -0.2))
            (Color . ,(all-the-icons-material "palette" :height 0.85 :v-adjust -0.2))
            (File . ,(all-the-icons-faicon "file-o" :height 0.85 :v-adjust -0.05))
            (Reference . ,(all-the-icons-material "collections_bookmark" :height 0.85 :v-adjust -0.2))
            (Folder . ,(all-the-icons-faicon "folder-open" :height 0.85 :v-adjust -0.05))
            (EnumMember . ,(all-the-icons-material "format_align_right" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue))
            (Constant . ,(all-the-icons-faicon "square-o" :height 0.85 :v-adjust -0.05))
            (Struct . ,(all-the-icons-material "settings_input_component" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange))
            (Event . ,(all-the-icons-faicon "bolt" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-orange))
            (Operator . ,(all-the-icons-material "control_point" :height 0.85 :v-adjust -0.2))
            (TypeParameter . ,(all-the-icons-faicon "arrows" :height 0.8 :v-adjust -0.05))
            (Template . ,(all-the-icons-material "format_align_center" :height 0.85 :v-adjust -0.2)))
          company-box-icons-alist 'company-box-icons-all-the-icons)))

csv

(leaf csv-mode
  :straight t
  :leaf-defer nil
  :mode ("\\.[Cc][Ss][Vv]\\'" . csv-mode)
  :setq (csv-separators . '("," ";" "|" " ")))

editorconfig

(leaf editorconfig
  :straight t
  :leaf-defer nil
  :diminish editorconfig-mode
  :config (editorconfig-mode))

empty buffer

(defun empty-buffer? ()
  (= (buffer-end 1) (buffer-end -1)))

flycheck

(leaf flycheck
  :straight t
  :leaf-defer nil
  :bind (("C-c e n" . flycheck-next-error)
         ("C-c e p" . flycheck-previous-error))
  :setq (flycheck-indication-mode . 'right-fringe)
  :init
  (define-fringe-bitmap 'flycheck-fringe-bitmap-arrow
    (vector #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00011001
            #b00110110
            #b01101100
            #b11011000
            #b01101100
            #b00110110
            #b00011001
            #b00000000
            #b00000000
            #b00000000
            #b00000000
            #b00000000))
  (flycheck-define-error-level 'error
    :severity 2
    :overlay-category 'flycheck-error-overlay
    :fringe-bitmap 'flycheck-fringe-bitmap-arrow
    :fringe-face 'flycheck-fringe-error)
  (flycheck-define-error-level 'warning
    :severity 1
    :overlay-category 'flycheck-warning-overlay
    :fringe-bitmap 'flycheck-fringe-bitmap-arrow
    :fringe-face 'flycheck-fringe-warning)
  (flycheck-define-error-level 'info
    :severity 0
    :overlay-category 'flycheck-info-overlay
    :fringe-bitmap 'flycheck-fringe-bitmap-arrow
    :fringe-face 'flycheck-fringe-info)
  :hook (after-init-hook . global-flycheck-mode))

flymake

(leaf flymake-proc
  :setq-default (flymake-diagnostic-functions . nil))

(leaf flymake
  :straight (flymake :type built-in)
  :setq (flymake-fringe-indicator-position . 'right-fringe))

(leaf flymake-diagnostic-at-point
  :straight (flymake-diagnostic-at-point
             :type git
             :host github
             :repo "waymondo/flymake-diagnostic-at-point")
  :after (flymake)
  :setq (flymake-diagnostic-at-point-display-diagnostic-function . 'flymake-diagnostic-at-point-display-posframe)
  :hook (flymake-mode-hook . flymake-diagnostic-at-point-mode))

format

(leaf format-all
  :straight t
  :bind (prog-mode-map
         ("<M-f8>" . format-all-buffer)))

(leaf reformatter
  :straight t
  :require t)

highlight-indent-guides

(leaf highlight-indent-guides
  :straight t
  :diminish highlight-indent-guides-mode
  :setq (highlight-indent-guides-method . 'character)
  :hook (prog-mode-hook . highlight-indent-guides-mode))

jinja

(leaf jinja2-mode
  :straight t)

lsp

(leaf lsp-mode
  :straight t
  :commands (lsp lsp-deferred)
  :require (lsp-mode lsp-clients)
  :pre-setq `((lsp-session-file . ,(concat conf:cache-dir "lsp-session"))
              (lsp-auto-guess-root . t)
              (lsp-enable-folding . nil)
              (lsp-enable-snippet . nil)
              (lsp-enable-symbol-highlighting . nil)
              (lsp-idle-delay . 0.500)
              (lsp-inhibit-message . t)
              (lsp-message-project-root-warning . t)
              (lsp-prefer-capf . t)
              (lsp-prefer-flymake . nil)
              (lsp-print-io . nil)
              (lsp-restart . 'interactive)
              (lsp-signature-auto-activate . nil)
              (lsp-eldoc-render-all . nil))
  :hook (lsp-after-open-hook . lsp-enable-imenu))

;; ref: https://gitlab.com/shackra/emacs/commit/b0df30fe744e4483a08731e6a9f6482ab408124c
(defvar-local conf:lsp-on-change-exist nil
  "indica si la función `lsp-on-change' estaba insertada en `after-change-functions'")

(defun conf:lsp-on-change-modify-hook ()
  "Remueve o agrega `lsp-on-change' de `after-change-functions'"
  (if (not conf:lsp-on-change-exist)
      ;; quita la función, solamente si estaba insertada desde un principio
      (when (memq 'lsp-on-change after-change-functions)
        (setq conf:lsp-on-change-exist t)
        (remove-hook 'after-change-functions 'lsp-on-change t))
    ;; agrega la función
    (add-hook 'after-change-functions #'lsp-on-change nil t)
    (setq conf:lsp-on-change-exist nil)))

(leaf lsp-ui
  :straight t
  :after lsp-mode
  :commands lsp-ui-mode
  :bind (lsp-ui-mode-map
         ([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
         ([remap xref-find-references] . lsp-ui-peek-find-references))
  :setq  ((lsp-ui-sideline-enable . t)
          (lsp-ui-sideline-ignore-duplicate . t)
          (lsp-ui-sideline-show-hover . nil)
          (lsp-ui-doc-enable . nil))
  :config (lsp-ui-mode))

makefile

(leaf makefile-runner
  :straight (makefile-runner
             :type git
             :host github
             :repo "danamlund/emacs-makefile-runner")
  :bind ("<C-f11>" . makefile-runner))

multiple-cursors

(leaf multiple-cursors
  :straight t
  :leaf-defer nil)

parents

(electric-pair-mode 1)

(leaf paren
  :straight t
  :init (show-paren-mode)
  :config
  (set-face-background 'show-paren-match (face-background 'default))
  (set-face-foreground 'show-paren-match "#def")
  (set-face-attribute 'show-paren-match nil :weight 'extra-bold))

(leaf smartparens-config
  :straight smartparens
  :commands (smartparens-mode smartparens-strict-mode)
  :bind (smartparens-strict-mode-map
         ("C-}" . sp-forward-slurp-sexp)
         ("M-s" . sp-backward-unwrap-sexp)
         ("C-c [" . sp-select-next-thing)
         ("C-c ]" . sp-select-next-thing-exchange)))

(leaf rainbow-delimiters
  :straight t
  :hook (prog-mode-hook))

plantuml

(leaf plantuml-mode
  :straight t
  :setq (plantuml-jar-path . "/usr/share/java/plantuml/plantuml.jar"))

projectile

(leaf projectile
  :straight t
  :bind* ("C-x b" . conf:switch-to-project-buffer-if-in-project)
  :pre-setq `((projectile-known-projects-file . ,(concat conf:cache-dir "projectile-bookmarks.eld"))
              (projectile-cache-file . ,(concat conf:cache-dir "projectile.cache"))
              (projectile-file-exists-remote-cache-expire . '(* 10 60))
              (projectile-indexing-method . 'alien)
              (projectile-enable-caching . t)
              (projectile-completion-system . 'default))
  :config
  (defun conf:switch-to-project-buffer-if-in-project (arg)
    "Custom switch to buffer.
       With universal argument ARG or when not in project, rely on
       `switch-to-buffer'.
       Otherwise, use `projectile-switch-to-buffer'."
    (interactive "P")
    (if (or arg
            (not (projectile-project-p)))
        (let ((completion-regexp-list '("\\`[^*]"
                                        "\\`\\([^T]\\|T\\($\\|[^A]\\|A\\($\\|[^G]\\|G\\($\\|[^S]\\|S.\\)\\)\\)\\).*")))
          (call-interactively 'switch-to-buffer))
      (projectile-switch-to-buffer)))

  (projectile-global-mode))

;; (leaf deadgrep
;;   :straight t
;;   :commands (deadgrep--read-search-term)
;;   :bind (("C-x C-r" . deadgrep)
;;          ("C-x r R" . projectile-deadgrep))
;;   :config
;;   (defun projectile-selection-at-point ()
;;     (when (use-region-p)
;;       (buffer-substring-no-properties (region-beginning) (region-end))))

;;   (defun projectile-deadgrep (search-term)
;;     (interactive (list (deadgrep--read-search-term)))
;;     (let ((deadgrep-project-root-function #'projectile-project-root))
;;       (deadgrep search-term))))


(leaf counsel-projectile
  :straight t
  :bind (("C-x r R" . counsel-projectile-rg)
         ("<C-tab>" . counsel-projectile-switch-project))
  :config
  (defun conf:switch-to-project-buffer-if-in-project (arg)
    "Custom switch to buffer.
       With universal argument ARG or when not in project, rely on
       `ivy-switch-buffer'.
       Otherwise, use `counsel-projectile-switch-to-buffer'."
    (interactive "P")
    (if (or arg
            (not (projectile-project-p)))
        (ivy-switch-buffer)
      (counsel-projectile-switch-to-buffer)))
  :hook ((text-mode-hook prog-mode-hook) . counsel-projectile-mode))

polymode

(leaf polymode
  :straight t
  :setq (polymode-prefix-key . '(kbd "C-c n"))
  :config
  (define-hostmode poly-python-hostmode :mode 'python-mode)

  (define-innermode poly-sql-expr-python-innermode
    :mode 'sql-mode
    :head-matcher (rx "r" (= 3 (char "\"'")) (* (any space)))
    :tail-matcher (rx (= 3 (char "\"'")))
    :head-mode 'host
    :tail-mode 'host)

  (defun poly-python-sql-eval-chunk (beg end msg)
    "Calls out to `sql-send-region' with the polymode chunk region"
    (sql-send-region beg end))

  (define-polymode poly-python-sql-mode
    :hostmode 'poly-python-hostmode
    :innermodes '(poly-sql-expr-python-innermode)
    (setq polymode-eval-region-function #'poly-python-sql-eval-chunk)
    (define-key poly-python-sql-mode-map (kbd "C-c C-c") 'polymode-eval-chunk))

  ;; Bug? Fix polymode kill chunk so it works.
  (defun polymode-kill-chunk ()
    "Kill current chunk."
    (interactive)
    (pcase (pm-innermost-span)
      (`(,(or `nil `host) ,beg ,end ,_) (delete-region beg end))
      (`(body ,beg ,_ ,_)
       (goto-char beg)
       (pm--kill-span '(body))
       ;; (pm--kill-span '(head tail))
       ;; (pm--kill-span '(head tail))
       )
      (`(tail ,beg ,end ,_)
       (if (eq beg (point-min))
           (delete-region beg end)
         (goto-char (1- beg))
         (polymode-kill-chunk)))
      (`(head ,_ ,end ,_)
       (goto-char end)
       (polymode-kill-chunk))
      (_ (error "Canoot find chunk to kill"))))
  :hook (python-mode-hook . poly-python-sql-mode))

python

lsp-python

(defun python-template ()
  (interactive)
  (insert "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n"))

(add-hook 'python-mode-hook '(lambda ()
                               (when (empty-buffer?) (python-template))))

(leaf python
  :require (smartparens-python electric)
  :setq ((python-indent . 4)
         (python-indent-offset . 4)
         (py-switch-buffers-on-execute-p . t)
         (py-split-window-on-execute . nil)
         (lsp-pyls-plugins-pycodestyle-enabled . nil)
         (lsp-pyls-plugins-pyflakes-enabled . nil)
         (lsp-pyls-plugins-flake8-enabled . t))
  :config
  (projectile-register-project-type 'python '("pyproject.toml")
                                    :compile ""
                                    :test "")
  :hook (python-mode-hook . lsp))

pyenv

;; (leaf auto-virtualenvwrapper
;;   :straight t
;;   :require t
;;   :after python
;;   :config
;;   (add-to-list 'mode-line-misc-info
;;                '(:eval (when (boundp 'venv-current-name)
;;                          (if venv-current-name
;;                              (format "Pyenv:%s" venv-current-name)
;;                            nil))))
;;   :hook ((python-mode-hook projectile-after-switch-project-hook) . auto-virtualenvwrapper-activate))
(leaf direnv
  :straight t
  :require t
  :hook (after-init-hook . direnv-mode))

pep8

(leaf blacken
  :straight t
  :diminish blacken-mode
  :setq (blacken-fast-unsafe . t)
  :hook (python-mode-hook . blacken-mode))

(leaf py-isort
  :straight t
  :setq (py-isort-options . '("--lines=100"))
  :hook (before-save-hook . py-isort-before-save))

stuff

(leaf pyimport
  :straight t
  :require t)

(leaf pip-requirements
  :straight t)

rainbow

(leaf rainbow-mode
  :straight t
  :diminish rainbow-mode
  :hook ((prog-mode-hook
          conf-mode-hook
          xrdb-mode-hook) . rainbow-mode))

rest

restclient

(leaf restclient  :straight t)

(leaf company-restclient
  :straight t
  :after restclient
  :config (add-to-list 'company-backends 'company-restclient))

(leaf ob-restclient
  :straight t
  :commands (org-babel-execute:restclient))

verb

(leaf verb
  :straight t
  :require (verb ob-verb)
  :mode ("\\.verb\\'" . verb-mode))

sql

(leaf sqlup-mode
  :straight t
  :bind ("C-c u" . sqlup-capitalize-keywords-in-region)
  :hook ((sql-mode-hook . sqlup-mode)
         (sql-interactive-mode-hook . sqlup-mode)))

(leaf sql-indent
  :straight t
  :after sql
  :bind (sql-mode-map
         ("C-c \\" . sql-indent-buffer))
  :hook (sql-mode-hook . sqlind-minor-mode))

tex

(leaf tex
  :straight auctex
  :leaf-defer nil
  :bind ("C-c c" . TeX-clean)
  :init
  (progn
    (require 'smartparens-latex)
    (add-hook 'TeX-mode-hook
              (lambda ()
                (outline-minor-mode t)
                (flyspell-mode t)
                (TeX-PDF-mode t)
                (TeX-fold-mode t)
                (switch-dictionary)))
    (add-hook 'LaTeX-mode-hook
              (lambda ()
                (LaTeX-math-mode t)
                (reftex-mode t)))
    (setq TeX-auto-save t
          TeX-parse-self t
          LaTeX-syntactic-comment t
          TeX-save-query nil
          TeX-PDF-mode t
          TeX-auto-untabify t)
    (setq-default TeX-engine 'xetex))
  :config
  (add-hook 'TeX-mode-hook 'turn-on-auto-fill)
  (add-hook 'LaTeX-mode-hook 'turn-on-auto-fill)

  ;; 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)

                                        ;(setq TeX-view-program-list '(("zathura" "zathura %o"))
                                        ;      TeX-view-program-selection '((output-pdf "zathura")))

  ;; set XeTeX mode in TeX/LaTeX
  (add-hook 'LaTeX-mode-hook
            (lambda () (push
                   '("cTeX" "%(ctex_bin) %t " TeX-run-TeX nil t
                     :help "Compilation with custom script") TeX-command-list)
              (add-to-list 'TeX-expand-list
                           '("%(ctex_bin)" (lambda ()
                                             (concat "~/.bin/" "ctex" ))))
              (setq TeX-command-default "cTeX"
                    TeX-save-query nil
                    TeX-show-compilation t))))

(leaf cdlatex
  :straight t
  :hook (LaTeX-mode-hook . turn-on-cdlatex))

(leaf reftex
  :straight t
  :commands turn-on-reftex
  :init
  (progn
    (setq reftex-plug-into-AUCTeX t)))

(leaf bibtex
  :straight t
  :init
  (progn
    (setq bibtex-align-at-equal-sign t)
    (add-hook 'bibtex-mode-hook
              (lambda ()
                (set-fill-column 120)))))

(leaf company-auctex
  :straight t
  :config
  (defun conf:TeX-mode-hook ()
    (company-auctex-init))
  (add-hook 'LaTeX-mode-hook 'conf:TeX-mode-hook)
  (add-hook 'TeX-mode-hook 'conf:TeX-mode-hook))

xml

(leaf nxml-mode
  ;; :straight nil
  :mode (("\\.plist\\'" . nxml-mode)
         ("\\.rss\\'"   . nxml-mode)
         ("\\.svg\\'"   . nxml-mode)
         ("\\.xml\\'"   . nxml-mode)
         ("\\.xsd\\'"   . nxml-mode)
         ("\\.xslt\\'"  . nxml-mode)
         ("\\.pom$"     . nxml-mode))
  :magic ("<\\?xml" . nxml-mode)
  :bind (nxml-mode-map
         ("C-x f" . pretty-print-xml-buffer))
  :setq ((nxml-slash-auto-complete-flag . t)
         (nxml-auto-insert-xml-declaration-flag . t))
  :config
  (mapc
   (lambda (pair)
     (if (or (eq (cdr pair) 'xml-mode)
             (eq (cdr pair) 'sgml-mode))
         (setcdr pair 'nxml-mode)))
   auto-mode-alist)

  (defun nxml-template ()
    (interactive)
    (insert "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n\n"))

  ;; https://gist.github.com/DinoChiesa/5489021
  (defun pretty-print-xml-region (begin end)
    "Pretty format XML markup in region. You need to have nxml-mode
      http://www.emacswiki.org/cgi-bin/wiki/NxmlMode installed to do
      this. The function inserts linebreaks to separate tags that have
      nothing but whitespace between them. It then indents the markup
      by using nxml's indentation rules."
    (interactive "r")
    (save-excursion
      (nxml-mode)
      ;; split <foo><bar> or </foo><bar>, but not <foo></foo>
      (goto-char begin)
      (while (search-forward-regexp ">[ \t]*<[^/]" end t)
        (backward-char 2) (insert "\n") (incf end))
      ;; split <foo/></foo> and </foo></foo>
      (goto-char begin)
      (while (search-forward-regexp "<.*?/.*?>[ \t]*<" end t)
        (backward-char) (insert "\n") (incf end))
      ;; put xml namespace decls on newline
      (goto-char begin)
      (while (search-forward-regexp "\\(<\\([a-zA-Z][-:A-Za-z0-9]*\\)\\|['\"]\\) \\(xmlns[=:]\\)" end t)
        (goto-char (match-end 0))
        (backward-char 6) (insert "\n") (incf end))
      (indent-region begin end nil)
      (normal-mode))
    (message "All indented!"))

  (defun pretty-print-xml-buffer ()
    "pretty print the XML in a buffer."
    (interactive)
    (pretty-print-xml-region (point-min) (point-max))))

yaml

(leaf yaml-mode
  :straight t)

yasnippet

(leaf yasnippet
  :straight t
  :diminish yas-minor-mode
  :setq (yas-snippet-dirs . '("~/.emacs.d/snippets"))
  :config
  :hook (emacs-startup-hook . yas-global-mode))

(leaf yasnippet-snippets
  :straight t
  :after yasnippet)

(defun company-mode/backend-with-yas (backend)
  "http://emacs.stackexchange.com/questions/10431/get-company-to-show-suggestions-for-yasnippet-names"
  "Add yasnippet support for all company backends"
  "https://github.com/syl20bnr/spacemacs/pull/179"
  (if (or (and (listp backend) (member 'company-yasnippet backend)))
      backend
    (append (if (consp backend) backend (list backend))
            '(:with company-yasnippet))))

(add-hook 'after-init-hook (lambda () (setf company-backends (mapcar #'company-mode/backend-with-yas company-backends))) t)

(leaf org-sync-snippets
  :straight t
  :require t
  :after yasnippet
  :setq (org-sync-snippets-org-snippets-file . "~/.emacs.d/snippets/snippets.org")
  :hook (yas-after-reload-hook . org-sync-snippets-org-to-snippets))

(leaf doom-snippets
  :straight (doom-snippets
             :type git
             :host github
             :repo "hlissner/doom-snippets"
             :files ("*.el" "*"))
  :after yasnippet)

guix

(leaf geiser
  :straight t
  :require t
  :config
  (with-eval-after-load 'geiser-guile
    (add-to-list 'geiser-guile-load-path "~/guix"))
  (with-eval-after-load 'yasnippet
    (add-to-list 'yas-snippet-dirs "~/guix/etc/snippets")))

Tools

alert

(leaf alert
  :straight t
  :require t
  :init
  (if (eq system-type 'windows-nt)
      (setq alert-default-style 'message)
    (setq alert-default-style 'libnotify)))

anzu

(leaf anzu
  :straight t
  :bind (("M-%" . anzu-query-replace)
	     ("C-M-%" . anzu-query-replace-regexp))
  :setq ((anzu-cons-mode-line-p . nil)
	     (anzu-mode-lighter . "")
	     (anzu-deactivate-region . t)
	     (anzu-search-threshold . 1000)
	     (anzu-replace-threshold . 50)
	     (anzu-replace-to-string-separator . " => ")
	     (anzu-mode-line-update-function . 'cfg:anzu-update-func))
  :config
  (set-face-attribute 'anzu-mode-line nil :foreground "yellow" :weight 'bold)

  (defun cfg:anzu-update-func (here total)
	(when anzu--state
	  (let ((status (cl-case anzu--state
			          (search (format "[%d/%d Seek]" here total))
			          (replace-query (format "(%d Replaces)" total))
			          (replace (format "[%d/%d Replaces]" here total)))))
	    (propertize status 'face 'anzu-mode-line))))

  (add-to-list 'minor-mode-alist
		       '(:eval (when anzu--state
			             (concat " " (anzu--update-mode-line)))))
  (global-anzu-mode +1))

bughunter

(leaf bug-hunter
  :straight t
  :commands (bug-hunter-file bug-hunter-init-file))

(leaf benchmark-init
  :straight t
  :require t
  :hook (after-init-hook . benchmark-init/deactivate))

autorevert

(leaf autorever
  ;; :straight nil
  :diminish auto-revert-mode
  :setq ((auto-revert-remote-files . t)
         (auto-revert-interval . 1)))

caldav

(leaf org-caldav
  :straight t
  :bind ("<f6>" . org-caldav-sync)
  :setq `((org-icalendar-alarm-time . 30)
          (org-icalendar-categories . '(all-tags category todo-state))
          (org-icalendar-include-todo . t)
          (org-icalendar-use-deadline . '(event-if-todo event-if-not-todo todo-due))
          (org-icalendar-use-scheduled . '(event-if-todo event-if-not-todo todo-start))
          (org-icalendar-with-timestamps . t)
          (org-icalender-sync-todo . t)
          (org-icalendar-timezone . "America/Guayaquil")
          (org-caldav-calendars . '((:calendar-id "arkhan/work"
                                                  :files ("~/org/work.org")
                                                  :inbox "~/org/inbox.org")
                                    (:calendar-id "arkhan/stuff"
                                                  :files ("~/org/stuff.org")
                                                  :inbox "~/org/inbox.org")))
          (org-caldav-files . org-agenda-files)
          (org-caldav-show-sync-results . nil)
          (org-caldav-url . "https://cloud.disroot.org/remote.php/dav/calendars")
          (org-caldav-backup-file . ,(concat conf:cache-dir "caldav-backup.org"))))


(leaf calfw
  :straight t
  :setq ((cfw:display-calendar-holidays . nil)
         (calendar-week-start-day . 1)
         (cfw:fchar-junction . ?╬)
         (cfw:fchar-vertical-line . ?║)
         (cfw:fchar-horizontal-line . ?═)
         (cfw:fchar-left-junction . ?╠)
         (cfw:fchar-right-junction . ?╣)
         (cfw:fchar-top-junction . ?╦)
         (cfw:fchar-top-left-corner . ?╔)
         (cfw:fchar-top-right-corner . ?╗)))

(leaf calfw-org
  :straight t
  :require t
  :bind ("C-c f" . cfw:open-org-calendar)
  :setq (cfw:org-overwrite-default-keybinding . t))

comment-dwim-2

(leaf comment-dwim-2
  :straight t
  :leaf-defer nil
  :bind* ("M-;" . comment-dwim-2))

docker

(leaf dockerfile-mode
  :straight t
  :mode "Dockerfile\\'")

(leaf docker-compose-mode
  :straight t
  :mode ("docker-compose.*\.yml\\'" . docker-compose-mode))

dumb-jump

(leaf dumb-jump
  :straight t
  :bind (("M-g o" . dumb-jump-go-other-window)
         ("M-g j" . dumb-jump-go)
         ("M-g i" . dumb-jump-go-prompt)
         ("M-g x" . dumb-jump-go-prefer-external)
         ("M-g z" . dumb-jump-go-prefer-external-other-window))
  :setq (dumb-jump-selector 'completing-read))

email

misc

(leaf visual-fill-column
  :straight t)

(defun extract-email (str)
  ;; return last sub-string looking like an email address
  (let ((tokens (reverse (split-string-and-unquote str)))
        (match))
    (dolist (token tokens)
      (string-match "<?\\([^ ]+@[^ ]+\.[^ >]+\\)>?" token)
      (setq match (or match (match-string 1 token))))
    match))

(defun visual-clean ()
  "Clean up messy buffers (i.e. web wikis or elfeed-show)"
  (interactive)
  (visual-line-mode)
  (visual-fill-column-mode))

message

(leaf message
  ;; :straight nil
  :setq ((message-citation-line-format . "\nEl %A %d de %B del %Y a las %H%M horas, %N escribió:\n")
         (message-citation-line-function . 'message-insert-formatted-citation-line)
         (message-cite-reply-position . 'below)
         (message-kill-buffer-on-exit . t)
         (message-send-mail-function . 'message-send-mail-with-sendmail)
         (sendmail-program . "msmtp"))
  :config
  (defun choose-msmtp-account ()
    (if (message-mail-p)
        (save-excursion
          (let*
              ((from (save-restriction
                       (message-narrow-to-headers)
                       (message-fetch-field "from")))
               (account (extract-email from)))
            (setq message-sendmail-extra-arguments (list '"-a" account))))))
  :hook (message-send-mail-hook . choose-msmtp-account))

mu4e

(leaf mu4e
  :if (executable-find "mu")
  ;; :straight nil
  :require mu4e-contrib
  :bind (("<f1>" . mu4e)
         (mu4e-main-mode-map
          ("j" . conf:mu4e~headers-jump-to-maildir))
         (mu4e-headers-mode-map
          ("j" . conf:mu4e~headers-jump-to-maildir)))
  :preface
  (defadvice mu4e (before mu4e-start activate)
    "Antes de ejecutar `mu4e' borramos todas las ventanas"
    (when (> 1 (count-windows))
      (window-configuration-to-register :mu4e-fullscreen)
      (delete-other-windows)))

  :pre-setq ((mail-user-agent . 'mu4e-user-agent)
             (mu4e-attachment-dir .  "~/Descargas")
             (mu4e-auto-retrieve-keys . t)
             (mu4e-compose-context-policy . 'ask)
             (mu4e-compose-dont-reply-to-self . t)
             (mu4e-change-filenames-when-moving . t)
             (mu4e-compose-keep-self-cc . nil)
             (mu4e-context-policy . 'pick-first)
             (mu4e-headers-date-format . "%Y-%m-%d %H:%M")
             (mu4e-headers-include-related . t)
             (mu4e-headers-auto-update . t)
             (mu4e-headers-leave-behavior . 'ignore)
             (mu4e-headers-from-or-to-prefix . '("" . ""))
             (mu4e-headers-visible-lines . 8)
             (mu4e-headers-fields . '((:human-date    .   10)
                                      (:from          .   30)
                                      (:to            .   30)
                                      (:flags         .   10)
                                      (:maildir       .   30)
                                      (:subject       .   nil)))
             (mu4e-view-fields . '(:from
                                   :to
                                   :cc
                                   :bcc
                                   :subject
                                   :flags
                                   :date
                                   :maildir
                                   :mailing-list
                                   :tags
                                   :attachments
                                   :signature))
             (mu4e-html2text-command . "w3m -dump -T text/html -cols 72 -o display_link_number=true -o display_image=true")
             (mu4e-view-html-plaintext-ratio-heuristic . most-positive-fixnum)
             (mu4e-compose-format-flowed . t)
             (mu4e-org-contacts-file . "~/org/contacts.org")
             (mu4e-maildir . "~/.mail")
             (mu4e-view-show-images . t)
             (mu4e-view-show-addresses . t)
             (mu4e-view-prefer-html . t)
             (mu4e-index-update-in-background . t)
             (mu4e-get-mail-command . "offlineimap")
             (mu4e-update-interval . 300))
  :config
  (add-to-list 'mu4e-headers-actions
               '("org-contact-add" . mu4e-action-add-org-contact) t)
  (add-to-list 'mu4e-view-actions
               '("org-contact-add" . mu4e-action-add-org-contact) t)

  (defun conf:mu4e~headers-jump-to-maildir()
    (interactive)
    (let ((maildir (completing-read "Maildir: " (mu4e-get-maildirs))))
      (mu4e-headers-search (format "maildir:\"%s\"" maildir))))

  (when (fboundp 'imagemagick-register-types)
    (imagemagick-register-types))

  (run-at-time nil (* 60 5) '(lambda ()
                               (interactive)
                               (mu4e-update-mail-and-index t)))
  :hook ((mu4e-compose-mode-hook . visual-clean)
         (mu4e-compose-mode-hook . flyspell-mode)))

(leaf mu4e-alert
  :if (executable-find "mu")
  :straight t
  :setq ((mu4e-compose-forward-as-attachment . t)
         (mu4e-compose-crypto-reply-encrypted-policy . 'sign-and-encrypt)
         (mu4e-compose-crypto-reply-plain-policy . 'sign)
         (mu4e-index-update-in-background . t)
         (mu4e-alert-email-notification-types . '(subjects)))
  :config
  (defun conf:refresh-mu4e-alert-mode-line ()
    (interactive)
    (mu4e~proc-kill)
    (mu4e-alert-enable-mode-line-display))
  (run-with-timer 0 60 'conf:refresh-mu4e-alert-mode-line)
  (mu4e-alert-set-default-style 'libnotify)
  :hook ((emacs-startup-hook . mu4e-alert-enable-notifications)
         (emacs-startup-hook . mu4e-alert-enable-mode-line-display)))

(leaf mu4e-maildirs-extension
  :if (executable-find "mu")
  :straight t
  :after mu4e
  :setq ((mu4e-maildirs-extension-hide-empty-maildirs . t)
         (mu4e-maildirs-extension-action-text . nil)
         (mu4e-maildirs-extension-title . nil)
         (mu4e-maildirs-extension-maildir-collapsed-prefix . "*")
         (mu4e-maildirs-extension-maildir-default-prefix . ""))
  :config (mu4e-maildirs-extension))

notmuch

(leaf htmlize
  :straight t)

(leaf notmuch
  :if (executable-find "notmuch")
  :straight t
  :bind (("<f1>" . notmuch)
         (notmuch-search-mode-map
          ;; bind 'r' to reply-all, and 'R' to reply
          ("r" . notmuch-search-reply-to-thread)
          ("R" . notmuch-search-reply-to-thread-sender)
          ("K" . conf:notmuch-mark-read-and-delete)))
  :setq ((mail-user-agent . 'notmuch-user-agent)
         (mm-text-html-renderer . 'w3m-standalone)
         ;;(notmuch-multipart/alternative-discouraged . ("text/html" "text"))
         (notmuch-multipart/alternative-discouraged . '("text/plain" "text/html"))
         (notmuch-show-logo . nil)
         ;;(notmuch-always-prompt-for-sender . t)
         (notmuch-archive-tags . '("-inbox" "-unread"))
         (notmuch-crypto-process-mime . t)
         ;;(notmuch-labeler-hide-known-labels . nil)
         (notmuch-search-oldest-first . nil)
         (notmuch-draft-save-plaintext . t))
  :config
  (defun conf:notmuch-mark-read-and-delete ()
    (interactive)
    (notmuch-search-tag '("-unread" "+delete"))
    (notmuch-search-archive-thread))

  (defun conf:notmuch-update ()
    (interactive)
    ;; create output buffer and jump to beginning
    (let ((buf (get-buffer-create "*notmuch update*")))
      (with-current-buffer buf
        (erase-buffer))
      (set-process-sentinel
       (start-process-shell-command "notmuch update" buf "offlineimap -u basic && notmuch new && afew -a -t")
       ;; refresh notmuch buffers if sync was successful
       (lambda (_process event)
         (if (string= event "finished\n")
             (notmuch-refresh-all-buffers))))))
  (run-with-timer 0 60 'conf:notmuch-update))

(leaf notmuch-show
  :bind ((notmuch-show-mode-map
          ;; bind 'r' to reply-all, and 'R' to reply
          ("r" . notmuch-show-reply)
          ("R" . notmuch-show-reply-sender)))
  :setq ((notmuch-show-imenu-indent . t)
         (notmuch-message-headers . '("To" "Cc" "Subject" "Date"))
         (mm-decrypt-option . 'known))

  :config
  (defun conf:notmuch-show-decrypt-message ()
    (interactive)
    ;; make sure the content is not indented, as this confuses epa
    (when notmuch-show-indent-content
      (notmuch-show-toggle-thread-indentation))

    (cl-letf ((extent (notmuch-show-message-extent))
              ((symbol-function 'y-or-n-p) #'(lambda (msg) t)))
      (epa-decrypt-armor-in-region (car extent) (cdr extent))))

  (defun turn-on-notmuch-show-decrypt-region ()
    (epa-mail-mode 1)
    (make-local-variable 'epa-mail-mode-map)
    (define-key epa-mail-mode-map (kbd "C-c C-e d") nil)
    (define-key epa-mail-mode-map (kbd "C-c C-e C-d") nil)

    (local-set-key (kbd "C-c C-e d") 'conf:notmuch-show-decrypt-message)
    (local-set-key (kbd "C-c C-e C-d") 'conf:notmuch-show-decrypt-message))
  :hook (notmuch-show-hook . turn-on-notmuch-show-decrypt-region))

(leaf org-notmuch
  :require t
  :after (:any org notmuch))

(leaf org-msg
  :straight (org-msg
             :type git
             :host github
             :repo "obar/org-msg")
  :require t
  :after notmuch
  :config
  (load-user-file "org-msg")
  (org-msg-mode))

(leaf notmuch-unread
  :straight (notmuch-unread
             :type git
             :host github
             :repo "arkhan/notmuch-unread")
  :require t
  :config (notmuch-unread-mode t))

(leaf profile
  :straight (profile
             :type git
             :host github
             :repo "DamienCassou/profile")
  :bind ("C-c F" . profile-force-profile-in-compose)
  :after notmuch
  :init
  (load-user-file "profile")

  (defun my:notmuch-build-identity (&optional email)
    "Return a string of the form \"name <EMAIL>\"."
    (let ((email (or email user-mail-address)))
      (format "%s <%s>" (notmuch-user-name) email)))

  (setq notmuch-identities
        (mapcar #'my:notmuch-build-identity
                (profile-email-addresses)))

  (defun my:notmuch-prompt-for-sender ()
    "Prompt for a sender using `profile-binding-alist'."
    ;; (profile-set-profile)
    (save-excursion
      (let*
          ((from (save-restriction
                   (message-narrow-to-headers)
                   (message-fetch-field "from")))
           (account (extract-email from)))
        (profile-set-profile-from-name account))
      (my:notmuch-build-identity)))

  (advice-add #'notmuch-mua-prompt-for-sender
              :override
              #'my:notmuch-prompt-for-sender)

  ;; https://notmuchmail.org/pipermail/notmuch/2017/025320.html
  (defun my:notmuch-mua-new-reply (arguments)
    "Always set PROMPT-FOR-SENDER to t when using `notmuch-mua-new-reply'."
    (list (cl-first arguments) t (cl-third arguments)))

  (advice-add #'notmuch-mua-new-reply :filter-args #'my:notmuch-mua-new-reply)
  (add-to-list 'notmuch-hello-sections #'profile-queue-insert-section t))

;; First, install notmuch-bookmarks:
(leaf notmuch-bookmarks
  :straight t
  :after notmuch
  :config (notmuch-bookmarks-mode))

;; Second, install the alert package:
(leaf notmuch-alert
  :straight (notmuch-alert
             :type git
             :host github
             :repo "publicimageltd/notmuch-alerts")
  :after notmuch-bookmarks
  :require t
  :bind* ("<f3>" . notmuch-alert-visit)
  :config (notmuch-alert-mode))

org-msg

(leaf org-msg
  :straight t
  :require t
  :config
  (load-user-file "org-msg")
  (org-msg-mode))

links

(leaf link-hint
  :straight t
  :bind (("C-c l o" . link-hint-open-link)
         ("C-c l c" . link-hint-copy-link)))

shrface

(leaf org-bullets
  :straight t)

(leaf pcre2el
  :straight t)

(leaf shrface
  :straight (shrface
             :type git
             :host github
             :repo "chenyanming/shrface")
  :after shr
  :require t
  :config
  (with-eval-after-load 'mu4e
    (add-hook 'mu4e-view-mode-hook 'shrface-mode)))

profile

(leaf profile
  :straight (profile
             :type git
             :host github
             :repo "DamienCassou/profile")
  :bind ("C-c F" . profile-force-profile-in-compose)
  :after mu4e
  :init (load-user-file "profile")
  :hook (mu4e-compose-pre-hook . profile-set-profile-in-compose))

spelling

spell-fu

(leaf spell-fu
  :straight t
  :require t
  :hook (after-init-hook . global-spell-fu-mode))

(setq-default ispell-program-name "hunspell"
                ispell-really-hunspell t
                ispell-check-comments t
                ispell-local-dictionary "en_US"
                ispell-local-dictionary-alist
                '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8)
                  ("es_EC" "[[:alpha:]]" "[^[:alpha:]]" "[ñ]" nil ("-d" "es_EC") nil utf-8)))

  (defun switch-dictionary ()
    (interactive)
    (let* ((dic ispell-current-dictionary)
           (change (if (string= dic "en_US") "es_EC" "en_US")))
      (ispell-change-dictionary change)
      (setq ispell-alternate-dictionary change)
      (message "Dictionary switched from %s to %s" dic change)))

flyspell

(leaf flyspell
  :require t
  :diminish flyspell-mode
  :bind (("C-c t s" . flyspell-mode)
         ("C-c l b" . flyspell-buffer)
         ("M-i" . switch-dictionary)
         (flyspell-mode-map
          ("C-\"" . flyspell-add-word-to-dict)
          ("\M-\t" . nil)
          ([down-mouse-2] . nil)
          ([mouse-2] . nil)))
  :setq-default ((ispell-program-name . "hunspell")
                 (ispell-really-hunspell . t)
                 (ispell-check-comments . t)
                 (ispell-local-dictionary . "en_US")
                 (ispell-local-dictionary-alist . '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8)
                                                    ("es_EC" "[[:alpha:]]" "[^[:alpha:]]" "[ñ]" nil ("-d" "es_EC") nil utf-8))))
  :setq ((flyspell-use-meta-tab . nil)
         (flyspell-issue-welcome-flag . nil)
         (flyspell-issue-message-flag . nil))
  :config
  (defun switch-dictionary ()
    (interactive)
    (let* ((dic ispell-current-dictionary)
           (change (if (string= dic "en_US") "es_EC" "en_US")))
      (ispell-change-dictionary change)
      (setq ispell-alternate-dictionary change)
      (message "Dictionary switched from %s to %s" dic change)))

  (defun turn-on-spell-check ()
    (flyspell-mode 1))

  (defun flyspell-add-word-to-dict ()
    "Add the word at the current location to the private dictionary
       without question."
    (interactive)
    ;; use the correct dictionary
    (flyspell-accept-buffer-local-defs)
    (setq opoint (point-marker))
    (let ((cursor-location (point))
          (word (flyspell-get-word nil)))
      (if (consp word)
          (let ((start (car (cdr word)))
                (end (car (cdr (cdr word))))
                (word (car word)))
            ;; The word is incorrect, we have to propose a replacement.
            (flyspell-do-correct 'save nil word cursor-location start end opoint)))
      (ispell-pdict-save t)))

  (dolist (hook '(TeX-mode-hook LaTeX-mode-hook text-mode-hook message-mode-hook markdown-mode-hook org-mode-hook))
    (add-hook hook 'turn-on-flyspell))

  :hook (prog-mode-hook . flyspell-prog-mode))

(leaf frog-menu
  :straight t
  :require t)

(leaf flyspell-correct
  :straight t
  :bind ("C-M-'" . flyspell-correct-at-point)
  :setq ((flyspell-correct-interface . #'frog-menu-flyspell-correct)
         (flyspell-correct-auto-mode-interface . #'frog-menu-flyspell-correct))
  :config
  (defun frog-menu-flyspell-correct (candidates word)
    "Run `frog-menu-read' for the given CANDIDATES.
     List of CANDIDATES is given by flyspell for the WORD.
     Return selected word to use as a replacement or a tuple
     of (command . word) to be used by `flyspell-do-correct'."
    (let* ((corrects (if flyspell-sort-corrections
                         (sort candidates 'string<)
                       candidates))
           (actions `(("C-s" "Save word"         (save    . ,word))
                      ("C-a" "Accept (session)"  (session . ,word))
                      ("C-b" "Accept (buffer)"   (buffer  . ,word))
                      ("C-c" "Skip"              (skip    . ,word))))
           (prompt   (format "Dictionary: [%s]"  (or ispell-local-dictionary
                                                     ispell-dictionary
                                                     "default")))
           (res      (frog-menu-read prompt corrects actions)))
      (unless res
        (error "Quit"))
      res)))

gif-screencast

(leaf gif-screencast
  :straight t
  :bind (("<f8>" . gif-screencast)
         (gif-screencast-mode-map
          ("<f8>" . gif-screencast-toggle-pause)
          ("<f9>" . gif-screencast-stop))))

git

(setq vc-follows-symlinks t
      auto-revert-check-vc-info t
      find-file-visit-truename t)

(leaf transient
  :straight t
  :config (setq transient-history-file (concat conf:cache-dir "transient.el")))

(leaf magit
  :straight t
  :bind* (("C-x g c" . magit-commit-create)
          ("C-x g e" . magit-ediff-resolve)
          ("C-x g g" . magit-grep)
          ("C-x g l" . magit-file-log)
          ("C-x g p" . magit-push-other)
          ("C-x g r" . magit-rebase-interactive)
          ("C-x g s" . magit-status)
          ("C-x g u" . magit-pull-other)
          ("C-x g x" . magit-checkout))
  :init
  (progn
    (defadvice magit-status (around magit-fullscreen activate)
      (window-configuration-to-register :magit-fullscreen)
      ad-do-it
      (delete-other-windows))
    (defadvice git-commit-commit (after delete-window activate)
      (delete-window))
    (defadvice git-commit-abort (after delete-window activate)
      (delete-window))
    (defun magit-commit-mode-init ()
      (when (looking-at "\n")
        (open-line 1))))
  :config
  (progn
    (defadvice magit-quit-window (around magit-restore-screen activate)
      (let ((current-mode major-mode))
        ad-do-it
        (when (eq 'magit-status-mode current-mode)
          (jump-to-register :magit-fullscreen))))
    (defun magit-maybe-commit (&optional show-options)
      "Runs magit-commit unless prefix is passed"
      (interactive "P")
      (if show-options
          (magit-key-mode-popup-committing)
        (magit-commit-create)))
    (define-key magit-mode-map "c" 'magit-maybe-commit)

    (setq magit-git-executable "git"
          magit-completing-read-function 'completing-read
          magit-default-tracking-name-function 'magit-default-tracking-name-branch-only
          magit-status-buffer-switch-function 'switch-to-buffer
          magit-diff-refine-hunk t
          magit-rewrite-inclusive 'ask
          magit-process-find-password-functions '(magit-process-password-auth-source)
          magit-save-some-buffers t
          magit-process-popup-time 10
          magit-set-upstream-on-push 'askifnotset
          magit-refs-show-commit-count 'all
          magit-log-buffer-file-locket t)))

(leaf magit-todos
  :straight t
  :require t
  :hook (magit-mode-hook))

(leaf magit-gitflow
  :straight t
  :require t
  :hook (magit-mode-hook . turn-on-magit-gitflow))

(leaf magit-lfs
  :straight t
  :require t)

(leaf git-gutter
  :straight t
  :diminish git-gutter-mode
  :leaf-defer nil
  :bind (("C-x C-g" . git-gutter)
         ("C-x v =" . git-gutter:popup-hunk)
         ("C-x p" . git-gutter:previous-hunk)
         ("C-x n" . git-gutter:next-hunk)
         ("C-x v s" . git-gutter:stage-hunk)
         ("C-x v r" . git-gutter:revert-hunk)
         ("C-x v SPC" . git-gutter:mark-hunk))
  :setq ((indicate-empty-lines . nil)
         (git-gutter:handled-backends . '(git hg bzr svn)))
  :config
  (if (display-graphic-p)
      (leaf git-gutter-fringe
        :straight t
        :require t
        :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 [128 192 224 240]
          nil nil 'bottom)))
  :hook (after-init-hook . global-git-gutter-mode))

(leaf gitconfig-mode
  :straight t
  :leaf-defer nil
  :mode ("/\\.?git/?config$"
         "/\\.gitmodules$")
  :hook (gitconfig-mode-hook . flyspell-mode))

(leaf gitignore-mode
  :straight t
  :leaf-defer nil
  :mode ("/\\.gitignore$"
         "/\\.git/info/exclude$"
         "/git/ignore$"))

(leaf gitattributes-mode
  :straight t
  :leaf-defer nil)

(leaf git-timemachine
  :straight t
  :leaf-defer nil
  :commands git-timemachine
  :bind (git-timemachine-mode
         ("c" . git-timemachine-show-current-revision)
         ("b" . git-timemachine-switch-branch)))

mingus

(leaf mingus
  :straight t
  :bind ("M-3" . mingus)
  :require t
  :setq (mingus-mpd-config-file . "~/.config/mpd/mpd.conf")
  :config
  (require 'mingus-stays-home))

nginx

(leaf nginx-mode
  :straight t
  :mode ("/nginx/sites-\\(?:available\\|enabled\\)/" . nginx-mode))

org

(leaf org
  :straight org-plus-contrib
  :setq `((org-modules . '(ol-bbdb
                           ol-bibtex ol-docview ol-info
                           org-crypt org-protocol org-id
                           org-habit org-annotate-file
                           org-eval org-expiry org-tempo
                           org-panel org-toc ox-md))
          (org-id-locations-file . ,(concat conf:cache-dir "org-id.el"))
          (org-directory . "~/org")
          (org-default-notes-file . ,(concat org-directory "/notes.org"))
          (org-startup-indented . t))
  :config
  (progn
    (add-hook 'org-mode-hook
              (lambda ()
                (turn-on-auto-fill)
                ;; (org-indent-mode)
                (switch-dictionary)))

    ;; ;; set default directories
    ;; (setq org-id-locations-file (concat conf:cache-dir "org-id.el")
    ;;       org-directory "~/org"
    ;;       org-default-notes-file (concat org-directory "/notes.org"))

    ;; set the archive
    (setq org-archive-location (concat org-directory "/archive.org::datetree/** Archived"))

    ;; highlight code blocks syntax
    (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)

    ;; more sane emphasis regex to export to HTML as substitute of Markdown
    ;;(org-set-emph-re 'org-emphasis-regexp-components
    ;;                 '(" \t({"
    ;;		"- \t.,:!?;)}[:multibyte:]"
    ;;		" \t\r\n,"
    ;;		"."
    ;;		1))

    ;; highlight code blocks syntax in PDF export
    ;; Include the latex-exporter
    (leaf ox-latex :require t)
    (setq org-latex-packages-alist nil
          org-latex-default-packages-alist nil
          org-latex-hyperref-template nil
          org-latex-create-formula-image-program 'dvipng)
    ;; Tell the latex export to use the minted package for source
    ;; code coloration.
    (setq org-latex-listings 'minted)
    ;; Let the exporter use the -shell-escape option to let latex
    ;; execute external programs.
    (setq org-latex-pdf-process '("~/.bin/ctex %f"))

    ;; tasks management
    (setq org-refile-targets '((org-agenda-files :maxlevel . 1)))
    (setq org-log-done t
          org-clock-idle-time nil
          org-duration-format (quote h:mm)
          org-todo-keywords (quote
                             ((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d)")
                              (sequence "WAITING(w)" "HOLD(h)" "|" "CANCELLED(c)" "PHONE" "MEETING"))))

    ;; date insertion configuration
    (setq org-expiry-created-property-name "CREATED"
          org-expiry-inactive-timestamps t
          org-todo-state-tags-triggers (quote
                                        (("CANCELLED" ("CANCELLED" . t))
                                         ("WAITING" ("WAITING" . t))
                                         ("HOLD" ("WAITING") ("HOLD" . t))
                                         (done ("WAITING") ("HOLD"))
                                         ("TODO" ("WAITING") ("CANCELLED") ("HOLD"))
                                         ("NEXT" ("WAITING") ("CANCELLED") ("HOLD"))
                                         ("DONE" ("WAITING") ("CANCELLED") ("HOLD")))))
    ;; capture
    (setq org-capture-templates
          '(("w" "Work TODO" entry (file+olp "~/org/work.org" "Tasks") "* TODO %? \nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CATEGORY: TASKS\n:CREATED: %U\n:END:")
            ("o" "Work Overtime" entry (file+olp "~/org/work.org" "COMMENT Overtime") "* %? \nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CREATED: %U\n:END:")
            ("m" "Work Meetings" entry (file+olp "~/org/work.org" "Meetings") "* %? \nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CATEGORY: MEETINGS\n:CREATED: %U\n:END:")
            ("t" "Work Training's" entry (file+olp "~/org/work.org" "Training's") "* %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CATEGORY: TRAINING'S\n:CREATED: %U\n:END:")
            ("S" "Stuff TODO" entry (file+olp "~/org/stuff.org" "Tasks") "* TODO %? \n:PROPERTIES:\n:CATEGORY: TASKS\n:CREATED: %U\n:END:")
            ("M" "Stuff Meetings" entry (file+olp "~/org/stuff.org" "Meetings") "* %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CATEGORY: MEETINGS\n:CREATED: %U\n:END:")
            ("T" "Stuff Training's" entry (file+olp "~/org/stuff.org" "Training's") "* %?\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n:PROPERTIES:\n:CATEGORY: TRAINING'S\n:CREATED: %U\n:END:")))

    ;; protect hidden trees for being inadvertily edited (do not work with evil)
    (setq-default org-catch-invisible-edits  'error
                  org-ctrl-k-protect-subtree 'error)

    ;; limit images width
    (setq org-image-actual-width nil)

    ;; :::::: Org-Babel ::::::
    ;; languages supported
    (org-babel-do-load-languages
     (quote org-babel-load-languages)
     (quote ((org . t))))
    (setq org-babel-python-command "python")

    (defun conf:org-confirm-babel-evaluate (lang body)
      (not (member lang '("python" "sh"))))

    (setq org-confirm-babel-evaluate 'conf:org-confirm-babel-evaluate)

    ;; (defalias 'org-babel-execute:emacs-lisp 'org-babel-execute:emacs-lisp)

    ;; refresh images after execution
    (add-hook 'org-babel-after-execute-hook 'org-redisplay-inline-images)))

(leaf org-superstar
  :straight t
  :require t
  :setq ((org-superstar-leading-bullet . "  ")
         (org-superstar-headline-bullets-list . '("")))
  :hook (org-mode-hook . (lambda () (org-superstar-mode 1))))

(leaf org-agenda
  :straight org-plus-contrib
  :bind (("C-x a" . org-agenda-list)
         ("C-x c" . org-capture))
  :require t
  :setq ((org-columns-default-format . "%50ITEM(Task) %10CLOCKSUM %16TIMESTAMP_IA")
         (org-agenda-include-diary . nil)
         (org-agenda-tags-todo-honor-ignore-options . t)
         (org-agenda-start-on-weekday . nil)
         (org-agenda-start-day . "-1d")
         (org-agenda-span . 7)
         (show-week-agenda-p . t)
         (org-agenda-timegrid-use-ampm . 1)
         (org-agenda-inhibit-startup . t)
         (org-agenda-files . (quote
                              ("~/org/work.org"
                               "~/org/stuff.org")))
         (org-agenda-custom-commands . '(("Q" . "Custom queries") ;; gives label to "Q"
                                         ("Qa" "Archive search" search "" ((org-agenda-files (file-expand-wildcards "~/org/archive.org"))))
                                         ("n" todo "NEXT")
                                         ("w" todo "WAITING")
                                         ("d" "Agenda + Next Actions" ((agenda) (todo "NEXT")))))))

(leaf doct
  :straight t
  :require t
  :commands (doct)
  :config
  (setq org-capture-templates
        (doct '(("Work" :keys "w"
                 :file "~/org/work.org"
                 :prepend t
                 :template ("* %{todo-state} %^{Description}"
                            "SCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))"
                            ":PROPERTIES:"
                            ":CREATED: %U"
                            ":CATEGORY: %{headline}"
                            ":END:"
                            "%?")
                 :children (("Task"
                             :keys "t"
                             :headline "Task"
                             :todo-state "TODO")
                            ("COMMENT Overtime" :keys "o"
                             :headline   "Two"
                             :todo-state "NEXT")
                            ("Third Child"  :keys "3"
                             :headline   "Three"
                             :todo-state "MAYBE")))))))

(leaf org-super-agenda
  :straight t
  :after (org-agenda)
  :config
  (setq org-super-agenda-groups '((:name "Today"
                                         :time-grid t
                                         :scheduled today)
                                  (:name "Due today"
                                         :deadline today)
                                  (:name "Important"
                                         :priority "A")
                                  (:name "Overdue"
                                         :deadline past)
                                  (:name "Due soon"
                                         :deadline future)
                                  (:name "Big Outcomes"
                                         :tag "bo")))
  (org-super-agenda-mode))

(leaf org-sidebar
  :straight t
  :after (org-agenda)
  :setq (org-sidebar-side . 'left)
  :config
  (defun conf:org-today-sidebar ()
    "Show my Org Today Sidebar."
    (interactive)
    (org-sidebar
     :sidebars (make-org-sidebar
                :name "Today"
                :description "Today items"
                :items (org-ql (org-agenda-files)
                         (and (not (done))
                              (or (deadline auto)
                                  (scheduled :to today)))
                         :action element-with-markers)
                :super-groups '((:time-grid t)
                                (:name "Overdue" :scheduled past :deadline past)
                                (:name "Due today" :scheduled today :deadline today)
                                (:tag "bills")
                                (:priority "A")
                                (:name "Non-tasks"
                                       :todo nil))))))

(leaf org-contacts
  :straight org-plus-contrib
  :require t
  :setq (org-contacts-files . (quote
                               ("~/org/contacts.org"))))

(leaf org-vcard
  :straight t
  :require t
  :setq ((org-vcard-default-style . "tree")
         (org-vcard-append-to-existing-import-buffer . nil)
         (org-vcard-default-export-file . "~/.contacts/contacts.vcf")
         (org-vcard-default-import-file . "")))

(leaf secretaria
  :straight t
  :require t
  :hook (after-init-hook . secretaria-unknown-time-always-remind-me))

(leaf ob-ditaa
  :leaf-defer nil
  :straight org-plus-contrib
  :commands (org-babel-execute:ditaa)
  :setq (org-ditaa-jar-path . "/usr/share/java/ditaa/ditaa-0.11.jar"))

(leaf ob-sql
  :leaf-defer nil
  :straight org-plus-contrib
  :commands (org-babel-execute:sql))

(leaf ob-python
  :leaf-defer nil
  :straight org-plus-contrib
  :commands (org-babel-execute:python))

(leaf ob-shell
  :leaf-defer nil
  :straight org-plus-contrib
  :commands (org-babel-execute:shell
             org-babel-expand-body:shell))

(leaf ob-plantuml
  :leaf-defer nil
  :straight org-plus-contrib
  :commands (org-babel-execute:plantuml)
  :setq (org-plantuml-jar-path . "/usr/share/java/plantuml/plantuml.jar"))

(leaf ob-async
  :straight t)

(leaf ob-translate
  :straight t)

(leaf org-re-reveal
  :straight t
  :require t)

(leaf htmlize
  :straight t)

org-tree-slide

;; https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-org.el#L1581
(leaf org-tree-slide
  :straight t
  :bind (org-tree-slide-mode-map
         ("q" . org-tree-slide-mode)
         ("C-b" . org-tree-slide-move-previous-tree)
         ("C-f" . org-tree-slide-move-next-tree)
         ("C-0" . conf:org-tree-slide-text-scale-reset)
         ("C-+" . conf:org-tree-slide-text-scale-inc1)
         ("C--" . conf:org-tree-slide-text-scale-dec1)
         ("C-1" . org-tree-slide-content)
         ("C-2" . conf:org-tree-slide-set-profile)
         ("C-3" . org-tree-slide-simple-profile)
         ("C-4" . org-tree-slide-presentation-profile))
  :config
  (progn
    (setq org-tree-slide--lighter " Slide")

    (defvar conf:org-tree-slide-text-scale 100
      "Text scale ratio to default when `org-tree-slide-mode' is enabled.")

    (defun conf:org-tree-slide-set-profile ()
      "Customize org-tree-slide variables."
      (interactive)
      (setq org-tree-slide-header t)
      (setq org-tree-slide-slide-in-effect nil)
      (setq org-tree-slide-heading-emphasis t)
      (setq org-tree-slide-cursor-init t) ;Move cursor to the head of buffer
      (setq org-tree-slide-modeline-display 'lighter)
      (setq org-tree-slide-skip-done nil)
      (setq org-tree-slide-skip-comments t)
      (setq org-tree-slide-activate-message
            (concat "Starting Org presentation. "
                    "Use arrow keys to navigate the slides."))
      (setq org-tree-slide-deactivate-message "Ended presentation.")
      (message "Custom `org-tree-slide' profile: ON"))

    (defvar conf:writegood-mode-state nil
      "Variable to store the state of `writegood-mode'.")

    (defun conf:org-tree-slide-start ()
      "Set up the frame for the slideshow."
      (interactive)
      (when (fboundp 'writegood-mode)
        (setq conf:writegood-mode-state writegood-mode)
        (writegood-mode -1))
      ;; (flyspell-mode -1)
      (conf:org-tree-slide-set-profile)
      (org-toggle-inline-images))

    (defun conf:org-tree-slide-stop()
      "Undo the frame setup for the slideshow."
      (interactive)
      (when (and (fboundp 'writegood-mode)
                 conf:writegood-mode-state)
        (writegood-mode 1)
        (setq conf:writegood-mode-state nil))
      ;; (flyspell-mode 1)
      ;; (hide-mode-line-mode -1)
      (org-remove-inline-images))

    (defun conf:org-tree-slide-text-scale-reset ()
      "Reset time scale to `modi/org-tree-slide-text-scale'."
      (interactive)
      (text-scale-set conf:org-tree-slide-text-scale))

    (defun conf:org-tree-slide-text-scale-inc1 ()
      "Increase text scale by 1."
      (interactive)
      (text-scale-increase 1))

    (defun conf:org-tree-slide-text-scale-dec1 ()
      "Decrease text scale by 1."
      (interactive)
      (text-scale-decrease 1)))
  :hook ((org-tree-slide-play-hook . conf:org-tree-slide-start)
         (org-tree-slide-stop-hook . conf:org-tree-slide-stop)))

org-tanglesync

(leaf org-tanglesync
  :straight t
  :bind (("C-c M-i" . org-tanglesync-process-buffer-interactive)
         ("C-c M-a" . org-tanglesync-process-buffer-automatic))
  :setq (org-tanglesync-default-diff-action . :external)
  :custom (org-tanglesync-watch-files . '("~/.dots/README.org"))
  :hook ((org-mode . org-tanglesync-mode)
         ((prog-mode text-mode) . org-tanglesync-watch-mode)))

pass

(leaf password-store
  :straight t
  :setq (password-store-password-length . 30))

(leaf pass
  :straight t
  :require t
  :commands pass
  :init
  (progn
    (defun my/pass-insert-generated (entry)
      "Same as pass-insert-generated but with my own template."
      (interactive (list (read-string "Password entry: ")))
      (when (or (not (seq-contains (password-store-list) entry))
                (yes-or-no-p "Erase existing entry with same name? "))
        (let ((password (shell-command-to-string
                         (format "pwgen --secure --symbols %s"
                                 password-store-password-length))))
          (password-store-insert
           entry
           (format "%s--\nusername: %s\nurl: https://%s\n"
                   password
                   user-mail-address
                   entry))
          (password-store-edit entry)
          (pass-update-buffer)))))
  :config (advice-add #'pass-insert-generated :override #'my/pass-insert-generated))

(leaf auth-source
  ;; :straight nil
  :setq ((auth-source-debug . t)
         (auth-source-do-cache . nil)))

(leaf auth-source-pass
  :straight t
  :require t
  :after auth-source
  :setq (auth-sources . '(password-store)))

pdf-tools

(leaf pdf-tools
  :straight t
  :leaf-defer nil
  :mode ("\\.[pP][dD][fF]\\'" . pdf-view-mode)
  :magic ("%PDF" . pdf-view-mode)
  :bind (pdf-view-mode-map
         ("<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-line-or-next-page)
         ("k"  . pdf-view-previous-line-or-previous-page)
         ("e"  . pdf-view-goto-page)
         ("t"  . pdf-view-goto-label)
         ("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))
  :setq((pdf-misc-print-programm . "/usr/bin/gtklp")
        (pdf-misc-print-programm-args . (quote ("-o media=A4" "-o fitplot")))
        (pdf-view-display-size . 'fit-page)
        (pdf-view-use-imagemagick . t)
        (pdf-view-midnight-colors . '("white smoke" . "gray5")))
  :init (pdf-tools-install t t))

(leaf org-pdftools
  :straight t
  :after (org)
  :commands org-pdfview-open
  :setq (org-pdftools-search-string-separator . "??")
  :config
  (org-link-set-parameters "pdftools"
                           :follow #'org-pdftools-open
                           :complete #'org-pdftools-complete-link
                           :store #'org-pdftools-store-link
                           :export #'org-pdftools-export)
  (delete '("\\.pdf\\'" . default) org-file-apps)
  ;; org links to pdf files are opened in pdf-view-mode
  (add-to-list 'org-file-apps '("\\.pdf\\'" . (lambda (_file link) (org-pdftools-open link))))
  ;; support for links to specific pages
  (add-to-list 'org-file-apps '("\\.pdf::\\([[:digit:]]+\\)\\'" . (lambda (_file link) (org-pdftools-open link))))
  :hook (org-store-link-functions . org-pdftools-store-link))

(leaf org-noter-pdftools
  :straight org-pdftools
  :after (org-noter))

pkgbuil

(leaf pkgbuild-mode
  :straight t
  :mode "PKGBUILD\\'")

ebuild

(leaf ebuild-mode
  :straight t)

po-mode

(leaf po-mode
  :straight t
  :commands po-mode
  :config
  ;; Fuente: https://www.emacswiki.org/emacs/PoMode
  (defun po-wrap ()
    "Filter current po-mode buffer through `msgcat' tool to wrap all lines."
    (interactive)
    (if (eq major-mode 'po-mode)
        (let ((tmp-file (make-temp-file "po-wrap."))
              (tmp-buf (generate-new-buffer "*temp*")))
          (unwind-protect
              (progn
                (write-region (point-min) (point-max) tmp-file nil 1)
                (if (zerop
                     (call-process
                      "msgcat" nil tmp-buf t (shell-quote-argument tmp-file)))
                    (let ((saved (point))
                          (inhibit-read-only t))
                      (delete-region (point-min) (point-max))
                      (insert-buffer-substring tmp-buf)
                      (goto-char (min saved (point-max))))
                  (with-current-buffer tmp-buf
                    (error (buffer-string)))))
            (kill-buffer tmp-buf)
            (delete-file tmp-file)))))

  (defun po-guess-language ()
    "Return the language related to this PO file."
    (save-excursion
      (goto-char (point-min))
      (re-search-forward po-any-msgstr-block-regexp)
      (goto-char (match-beginning 0))
      (if (re-search-forward
           "\n\"Language: +\\(.+\\)\\\\n\"$"
           (match-end 0) t)
          (po-match-string 1))))

  (defadvice po-edit-string (around setup-spell-checking (string type expand-tabs) activate)
    "Set up spell checking in subedit buffer."
    (let ((po-language (po-guess-language)))
      ad-do-it
      (if po-language
          (progn
            (ispell-change-dictionary po-language)
            (turn-on-flyspell)
            (flyspell-buffer))))))

(add-hook 'po-subedit-mode-hook
          (lambda ()
            (make-local-variable 'split-height-threshold)
            (make-local-variable 'split-width-threshold)
            (setq split-height-threshold 1
                  split-width-threshold nil)))

presentation

(leaf presentation
  :straight t
  :config (global-set-key (kbd "<M-f5>") (lambda ()
                                           (interactive)
                                           (if presentation-mode
                                               (presentation-mode 0)
                                             (presentation-mode 1))
                                           (toggle-frame-fullscreen))))

proced

(leaf proced
  :straight t
  :bind ("C-x p" . proced)
  :if (or (string-equal system-type "gnu/linux")
          (string-equal system-type "gnu/kfreebsd"))
  :pre-setq ((proced-tree-flag . t)
             (proced-auto-update-flag . t)))

shell

(leaf terminal-here
  :straight t
  :bind (("C-<f5>" . terminal-here-launch)
         ("C-<f6>" . terminal-here-project-launch))
  :config (setq terminal-here-terminal-command (list "urxvt" "-name" "ETmux" "-e" (concat conf:bin-dir "tmx"))))

ssh

(leaf ssh
  :hook (ssh-mode-hook . (lambda ()
                           (setq ssh-directory-tracking-mode t)
                           (shell-dirtrack-mode t)
                           (setq dirtrackp nil))))

(leaf ssh-config-mode
  :straight t
  :mode (("/\\.ssh/config\\'" . ssh-config-mode)
         ("/sshd?_config\\'" . ssh-config-mode)
         ("/known_hosts\\'" . ssh-known-hosts-mode)
         ("/authorized_keys2?\\'" . ssh-authorized-keys-mode))
  :hook (ssh-config-mode-hook . turn-on-font-lock))

sudo

(leaf su
  :straight (su
             :type git
             :host github
             :repo "PythonNut/su.el")
  :hook (emacs-startup-hook))

undo

(leaf undo-fu-session
  :straight t
  :pre-setq `((undo-fu-session-incompatible-files . '("/COMMIT_EDITMSG\\'" "/git-rebase-todo\\'"))
              (undo-fu-session-directory . ,(concat conf:cache-dir "undo-fu"))
              (undo-fu-session-compression . t))
  :hook (after-init-hook . global-undo-fu-session-mode))

vlf

(leaf vlf-setup
  :straight vlf
  :setq (vlf-application . 'dont-ask))

vpn

(leaf ovpn-mode
  :straight t
  :setq (ovpn-mode-base-directory . "/media/data/Project/vpn"))

which-key

(leaf which-key
  :straight t
  :diminish which-key-mode
  :setq (which-key-sort-order . 'which-key-key-order-alpha)
  :hook (emacs-startup-hook . which-key-mode))

xrdb

(leaf xrdb-mode
  :straight (xrdb-mode
             :type git
             :host github
             :repo "arkhan/xrdb-mode")
  :mode (("\\.Xdefaults$" . xrdb-mode)
         ("\\.Xenvironment$" . xrdb-mode)
         ("\\$Xresources$" . xrdb-mode)
         (".*\\.ad$" . xrdb-mode)
         (".*\\.x?rdb$" . xrdb-mode))
  :hook (xrdb-mode-hook . (lambda ()
                            (setq comment-start "! "))))

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published