Edison Ibáñez ae85d5e627 WIP Update 4 years ago
..
snippets 6f13b2ece1 WIP Doom 5 years ago
README.org ae85d5e627 WIP Update 4 years ago

README.org

Config

init.el


(doom! :completion
       (company +auto
                +childframe)
       (ivy +childframe
            +prescient)

       :ui
       doom-dashboard
       doom-quit
       hl-todo
       indent-guides
       modeline
       nav-flash
       neotree
       ophints
       (popup +all
              +defaults)
       (pretty-code +pragmata-pro)
       unicode
       vc-gutter
       window-select
       workspaces

       :editor
       file-templates
       (format +onsave)
       multiple-cursors
       parinfer
       rotate-text
       snippets

       :emacs
       dired
       electric
       vc

       :term
       term

       :tools
       ansible
       docker
       editorconfig
       eval
       flycheck
       (flyspell +hunspell)
       (lookup +docsets)
       lsp
       magit
       make
       (pass +auth)
       pdf
       rgb
       tmux
       upload

       :lang
       data
       emacs-lisp
       (javascript +lsp)
       latex
       (org +attach
            +babel
            +capture
            +export
            +habit
            +protocol
            +rest)
       (python +lsp)
       rest
       (sh +zsh)

       :app
       (write +langtool)

       :collab

       :config
       (default +bindings +smartparens))

Auto Tangle


(defun tangle-init-async ()
  "If the current buffer is 'README.org' the code-blocks are tangled."
  (when (or (equal (buffer-file-name) (expand-file-name (concat doom-private-dir "README.org")))
            (equal (buffer-file-name) (expand-file-name "~/.dots/doom/README.org")))
    (let ((prog-mode-hook nil))
      (async-shell-command "sh -c \"~/.emacs.d/bin/org-tangle ~/.doom.d/README.org\"" "*Messages*"))))

(add-hook 'after-save-hook 'tangle-init-async)

Lang


(setq current-language-environment "Spanish"
      org-export-default-language "es")

Doom


(setq doom-projectile-fd-binary "fd"
      confirm-kill-emacs nil)

Editor

Company


 (after! company
   (setq company-idle-delay 0
         company-show-numbers t
         company-minimum-prefix-length 1
         company-tooltip-limit 14
         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-frontends '(company-pseudo-tooltip-frontend
                             company-echo-metadata-frontend)))

Highlight


(package! hl-line :disable t)

Move-dup

Packages


(package! move-dup)

Config


(use-package! move-dup
  :defer t
  :diminish move-dup-mode
  :bind (("S-M-<up>" . md/move-lines-up)
         ("S-M-<down>" . md/move-lines-down)
         ("C-M-<up>" . md/duplicate-up)
         ("C-M-<down>" . md/duplicate-down))
  :init (global-move-dup-mode))

Snnipets

Packages


(package! org-sync-snippets)

Config


(use-package! org-sync-snippets
  :init (add-hook 'yas-after-reload-hook 'org-sync-snippets-org-to-snippets)
  :config (setq org-sync-snippets-snippets-dir +snippets-dir
                org-sync-snippets-org-snippets-file (concat +snippets-dir "snippets.org")))

UI

Cursor


(setq-default cursor-type '(hbar . 2))
(setq x-stretch-cursor t)

(use-package! frame
  :config
  (defun set-cursor-hook (frame)
    (modify-frame-parameters
     frame (list (cons 'cursor-color "white"))))
  (add-hook 'after-make-frame-functions 'set-cursor-hook))

(add-to-list 'default-frame-alist
             '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist
             '(ns-appearance . dark))

Fringe


(fringe-mode nil)

Font


(setq doom-font (font-spec :family "PragmataPro Mono Liga" :pixelsize 13.5))

Imenu

Package


(package! imenu-list)

Config


(use-package! imenu-list
  :init
  (set-popup-rule! "^\\*Ilist"
    :slot -1 :vslot -1 :size 35 :side 'left :ttl 0)
  (setq imenu-list-focus-after-activation t))

(map! :leader "o i" #'imenu-list-smart-toggle)

Ivy


(after! ivy-posframe
  (setq ivy-posframe-hide-minibuffer nil
        ivy-fixed-height-minibuffer nil
        ivy-posframe-parameters `((min-width . ,(window-width))
                                  (min-height . ,ivy-height)
                                  (internal-border-width . 0))
        ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-window-bottom-left))))

(after! counsel
  (setq counsel-find-file-at-point t
        counsel-rg-base-command "rg -uuu -S -g '!/volumes' -g '!/backups' -g '!/.git' --no-heading --line-number --color never %s ."))

Line Numbers


(setq display-line-numbers-type nil)

Maximized


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

Modeline


(after! doom-modeline
  (defun conf:doom-modeline--make-xpm-filter-args (args)
    "Force function to use `doom-modeline-height'.
     Instead of the calculation done in `doom-modeline-refresh-bars'.
     The minimum height is set to `frame-char-height' + 2."
    (list (car args) (cadr args) (max (+ (frame-char-height) 2) doom-modeline-height)))

  (advice-add 'doom-modeline--make-xpm :filter-args #'conf:doom-modeline--make-xpm-filter-args)

  (setq doom-modeline-icon nil
        doom-modeline-height 12
        doom-modeline-env-enable-python nil))

Neotree


(use-package! shrink-path)

(after! neotree
  (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 'neotree
        neo-dont-be-alone t
        neo-persist-show 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" "_build" "deps"))
  (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))

Pretty Code


;; (defvar +pretty-code-extra-ligatures
;;   '(("==" . ?\u2261)
;;     ("!=" . ?\u2260)
;;     (">=" . ?\u2265)
;;     ("<=" . ?\u2264)))

(setq-default prettify-symbols-alist
              (append prettify-symbols-alist
                      +pretty-code-extra-ligatures))

Theme


(package! vibrant-ink-theme
  :recipe (:host github :repo "arkhan/vibrant-ink-theme"))

(setq doom-theme 'vibrant-ink)

Which-key


(package! which-key-posframe)

 (use-package! which-key-posframe
   :config
   (setq which-key-posframe-poshandler 'posframe-poshandler-frame-bottom-left-corner
         which-key-posframe-border-width 0)
   (which-key-posframe-mode))

Lang

Empty

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

LSP

Config


(after! lsp-mode
  (setq lsp-eldoc-render-all nil
        lsp-print-io nil
        lsp-inhibit-message t
        lsp-message-project-root-warning t
        lsp-auto-guess-root t
        lsp-prefer-flymake nil))

Nginx

Packages

(package! nginx-mode) ;;(package! company-nginx)

Config

(use-package! nginx-mode :mode ("/nginx/sites-\\(?:available\\|enabled\\)/" . nginx-mode))

;;(use-package! company-nginx ;; :hook (nginx-mode . company-nginx-keywords))

Org

Packages


(package! org-tree-slide)
(package! org-super-agenda)
(package! org-sidebar
  :recipe (:host github :repo "alphapapa/org-sidebar"))
(package! secretaria)

Config


(after! org
  (set-popup-rule! "^ \\*Agenda"
    :slot -1 :vslot -1 :size #'+popup-shrink-to-fit :side 'right :ttl 0)

  (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:")))

  (setq org-image-actual-width nil))

;; https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-org.el#L1581
(use-package! org-tree-slide
  :config
  (setq org-tree-slide--lighter " Slide")

  (defvar conf:org-tree-slide-text-scale 4
    "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
          org-tree-slide-slide-in-effect nil
          org-tree-slide-heading-emphasis t
          org-tree-slide-cursor-init t ;Move cursor to the head of buffer
          org-tree-slide-modeline-display 'lighter
          org-tree-slide-skip-done nil
          org-tree-slide-skip-comments t
          org-tree-slide-activate-message (concat "Starting Org presentation. "
                                                  "Use arrow keys to navigate the slides.")
          org-tree-slide-deactivate-message "Ended presentation.")
    (message "Custom `org-tree-slide' profile: ON"))

  (conf:org-tree-slide-set-profile)

  (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)
    ;;(internal-show-cursor (selected-window) nil)
    ;;(toggle-read-only)
    (toggle-frame-fullscreen)
    (org-display-inline-images)
    (hide-mode-line-mode 1)
    (text-scale-set conf:org-tree-slide-text-scale))
  (add-hook 'org-tree-slide-play-hook #'conf:org-tree-slide-start)

  (defun conf:org-tree-slide-stop()
    "Undo the frame setup for the slideshow."
    (interactive)
    ;;(internal-show-cursor (selected-window) t)
    ;;(toggle-read-only)
    (toggle-frame-fullscreen)
    (org-remove-inline-images)
    (hide-mode-line-mode -1)
    (text-scale-set 0))
  (add-hook 'org-tree-slide-stop-hook #'conf:org-tree-slide-stop)

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

  (bind-keys
   :map org-tree-slide-mode-map
   ("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)))

(use-package! org-super-agenda
  :config
  (let ((org-super-agenda-groups))
       '((:log t)  ; Automatically named "Log"
         (:name "Schedule"
                :time-grid t)
         (:name "Today"
                :scheduled today)
         (:habit t)
         (:name "Due today"
                :deadline today)
         (:name "Overdue"
                :deadline past)
         (:name "Due soon"
                :deadline future)
         (:name "Unimportant"
                :todo ("SOMEDAY" "MAYBE" "CHECK" "TO-READ" "TO-WATCH")
                :order 100)
         (:name "Waiting..."
                :todo "WAITING"
                :order 98)
         (:name "Scheduled earlier"
                :scheduled past)))
  (org-agenda-list))

(use-package! org-sidebar
  :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 <=)
                                  (scheduled <=)
                                  (date = 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)))))
  (use-package! secretaria
    :config
    (add-hook 'after-init-hook #'secretaria-unknown-time-always-remind-me)))

Python

Packages


(package! lsp-python-ms
  :recipe (:host github :repo "andrew-christianson/lsp-python-ms"))
(package! pyenv-mode)
(package! pyenv-mode-auto)
(package! py-isort)
(package! pip-requirements)

Config


(set-pretty-symbols! 'python-mode
  :lambda "lambda"
  :not "not"
  :in "in"
  :not-in "not in"
  :and "and" :or "or")

(use-package! lsp-python-ms
  :demand
  :hook (python-mode . lsp))

(use-package! pyenv-mode
  :hook (python-mode . pyenv-mode))
(use-package! pyenv-mode-auto)

(use-package! py-isort
  :config (setq py-isort-options '("--lines=100"))
  :hook (before-save . py-isort-before-save))

(use-package! pip-requirements
  :hook (pip-requirements-mode . pip-requirements-auto-complete-setup))

PO


(use-package! po-mode
  :mode ("\\.po\\'" . 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))))))

Polymode

Packges


(package! polymode)

Config


(use-package! polymode
  :config
  (setq polymode-prefix-key (kbd "C-c n"))
  (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 . poly-python-sql-mode))

SQL

Packages


(package! sqlup-mode)
(package! sql-indent)

Config


(use-package! sqlup-mode
  :bind ("C-c u" . sqlup-capitalize-keywords-in-region)
  :init
  (add-hook 'sql-mode-hook 'sqlup-mode)
  (add-hook 'edbi:sql-mode-hook 'sqlup-mode)
  (add-hook 'sql-interactive-mode-hook 'sqlup-mode))

(use-package! sql-indent
  :after sql
  :bind (:map sql-mode-map (("C-c \\" . sql-indent-buffer))))

Xml


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

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

(use-package! nxml-mode
  :mode (("\\.plist\\'" . nxml-mode)
         ("\\.rss\\'"   . nxml-mode)
         ("\\.svg\\'"   . nxml-mode)
         ("\\.xml\\'"   . nxml-mode)
         ("\\.xsd\\'"   . nxml-mode)
         ("\\.xslt\\'"  . nxml-mode)
         ("\\.pom$"     . nxml-mode))
  :config
  (setq nxml-slash-auto-complete-flag t
        nxml-auto-insert-xml-declaration-flag t)
  (add-to-list 'magic-mode-alist '("<\\?xml" . nxml-mode))
  (mapc
   (lambda (pair)
     (if (or (eq (cdr pair) 'xml-mode)
             (eq (cdr pair) 'sgml-mode))
         (setcdr pair 'nxml-mode)))
   auto-mode-alist)

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

  (define-key nxml-mode-map (kbd "C-x f") 'pretty-print-xml-buffer))

Tools

Anzu


(use-package! anzu
  :defer t
  :bind (("M-%" . anzu-query-replace)
         ("C-M-%" . anzu-query-replace-regexp))
  :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))))

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

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

BugHunter

Packages


(package! bug-hunter)

Config


(use-package! bug-hunter
  :commands (bug-hunter-file bug-hunter-init-file))

Calendar

Packages


(package! org-caldav)
(package! calfw)
(package! calfw-org)

Config


(use-package! org-caldav
  :bind ("<f6>" . org-caldav-sync)
  :config
  (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")

  (setq 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-save-directory (concat doom-cache-dir "dav")
        org-caldav-show-sync-results nil
        org-caldav-url "https://cloud.disroot.org/remote.php/dav/calendars")
  (make-directory org-caldav-save-directory :parents)
  (setq org-caldav-backup-file (concat org-caldav-save-directory "caldav-backup.org")))


(use-package! calfw
  :config
  (setq cfw:org-overwrite-default-keybinding t
        cfw:display-calendar-holidays nil
        calendar-week-start-day 1)
  (map! :leader "o f" #'cfw:open-org-calendar))

(use-package! calfw-org)

Docker

Packages


(package! docker-compose-mode)

Config


(use-package! docker-compose-mode
  :mode ("docker-compose.*\.yml\\'" . docker-compose-mode))

COMMENT Format

Packages


(package! apheleia
  :recipe (:host github :repo "raxod502/apheleia"))

Config


(use-package!  apheleia
  :init (apheleia-global-mode +1))

Flyspell


(add-hook! flyspell
   (setq-default 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)
    (message "Dictionary switched from %s to %s" dic change)))

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

(map! "<f7>" #'flyspell-mode!
      (:after flyspell
        :map flyspell-mode-map
        "M-i" #'switch-dictionary
        "C-M-'" #'flyspell-correct-word-generic))

i3wm

Packages


(package! i3wm-config-mode
  :recipe (:host github :repo "Alexander-Miller/i3wm-Config-Mode"))

Config


  (use-package! i3wm-config-mode)

Terminal

Packages


(package! terminal-here)

Config


(use-package! terminal-here
  :bind (("C-<f5>" . terminal-here-launch)
         ("C-<f6>" . terminal-here-project-launch))
  :config (setq terminal-here-terminal-command (list "urxvtcd" "-e" "tmx")))
(after! term
  (custom-set-faces
   '(term ((t (:inherit default :foreground "#ffffff"))))
   '(term-color-black ((t (:background "#000000" :foreground "#31363b"))))
   '(term-color-blue ((t (:background "#2980b9" :foreground "#0099ff"))))
   '(term-color-green ((t (:background "#218058" :foreground "#27ae60"))))
   '(term-color-magenta ((t (:background "#8e44ad" :foreground "#af81ff"))))
   '(term-color-red ((t (:background "#c0392b" :foreground "#f44f4f"))))
   '(term-color-white ((t (:background "#acada1" :foreground "#cfd0c2"))))
   '(term-color-yellow ((t (:background "#fdbc4b" :foreground "#fdbc4b"))))))

COMMENT mu4e

Packages


(when (executable-find "mu")
  (package! mu4e-alert)
  (package! mu4e-maildirs-extension))
(package! link-hint)

Config


(use-package! link-hint
  :bind (("C-c l o" . link-hint-open-link)
         ("C-c l c" . link-hint-copy-link)))

(when (executable-find "mu")
  (use-package! mu4e
    :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)))

    (defadvice mu4e-quit (after mu4e-close-and-push activate)
      "Despues de salir de mu4e ejecutamos un script para subir los cambios al buzon de correo y para también restaurar la disposición de ventanas"
      (start-process "pushmail" "*pushmail-mbsync*" "mbsync" "-a" "--push")
      (when (get-register :mu4e-fullscreen)
        (jump-to-register :mu4e-fullscreen)))
    :init
    (require 'mu4e-contrib)
    (setq mail-user-agent 'mu4e-user-agent
          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
          mu4e-attachment-dir  "~/Descargas"
          mu4e-auto-retrieve-keys t
          mu4e-compose-context-policy 'ask
          mu4e-compose-dont-reply-to-self 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 nil
          mu4e-headers-leave-behavior 'ignore
          mu4e-headers-visible-lines 8
          mu4e-headers-fields '((:date . 25)
                                (:flags . 6)
                                (:from . 22)
                                (:subject . nil))
          mu4e-view-prefer-html t
          mu4e-html2text-command "w3m -dump -T text/html -cols 72 -o display_link_number=true -o auto_image=false -o display_image=true -o ignore_null_img_alt=true"
          mu4e-maildir "~/.mail"
          mu4e-view-show-images t
          sendmail-program "msmtp"
          mu4e-get-mail-command "mbsync -aV")

    (defun mu4e-message-maildir-matches (msg rx)
      (when rx
        (if (listp rx)
            ;; If rx is a list, try each one for a match
            (or (mu4e-message-maildir-matches msg (car rx))
                (mu4e-message-maildir-matches msg (cdr rx)))
          ;; Not a list, check rx
          (string-match rx (mu4e-message-field msg :maildir)))))

    (defun choose-msmtp-account ()
      (if (message-mail-p)
          (save-excursion
            (let*
                ((from (save-restriction
                         (message-narrow-to-headers)
                         (message-fetch-field "from")))
                 (account
                  (cond
                   ((string-match "arkhan@disroot.org" from) "Personal")
                   ((string-match "edison@disroot.org" from) "Work")
                   ((string-match "arkhan.xxx@gmail.com" from) "Gmail"))))
              (setq message-sendmail-extra-arguments (list '"-a" account))))))

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

    (add-hook 'mu4e-compose-mode-hook 'flyspell-mode)

    (setq mu4e-contexts
          `( ,(make-mu4e-context
               :name "Personal"
               :enter-func (lambda () (mu4e-message "Switch to the Personal context"))
               :match-func (lambda (msg)
                             (when msg
                               (mu4e-message-maildir-matches msg "^/Personal")))
               :leave-func (lambda () (mu4e-clear-caches))
               :vars '((user-mail-address     . "arkhan@disroot.org")
                       (user-full-name        . "Edison Ibáñez")
                       (mu4e-sent-folder      . "/Personal/Sent")
                       (mu4e-drafts-folder    . "/Personal/Drafts")
                       (mu4e-trash-folder     . "/Personal/Trash")
                       (mu4e-refile-folder    . "/Personal/Archive")))
             ,(make-mu4e-context
               :name "Work"
               :enter-func (lambda () (mu4e-message "Switch to the Work context"))
               :match-func (lambda (msg)
                             (when msg
                               (mu4e-message-maildir-matches msg "^/Work")))
               :leave-func (lambda () (mu4e-clear-caches))
               :vars '((user-mail-address     . "edison@disroot.org")
                       (user-full-name        . "Edison Ibáñez")
                       (mu4e-sent-folder      . "/Work/Sent")
                       (mu4e-drafts-folder    . "/Work/Drafts")
                       (mu4e-trash-folder     . "/Work/Trash")
                       (mu4e-refile-folder    . "/Work/Archive")))
             ,(make-mu4e-context
               :name "Gmail"
               :enter-func (lambda () (mu4e-message "Switch to the Gmail context"))
               :match-func (lambda (msg)
                             (when msg
                               (mu4e-message-maildir-matches msg "^/Gmail")))
               :leave-func (lambda () (mu4e-clear-caches))
               :vars '((user-mail-address     . "arkhan.xxx@gmail.com")
                       (user-full-name        . "Edison Ibáñez")
                       (mu4e-sent-folder      . "/Gmail/Sent Mail")
                       (mu4e-trash-folder     . "/Gmail/Trash")
                       (mu4e-refile-folder    . "/Gmail/All Mail")
                       (mu4e-drafts-folder    . "/Gmail/Drafts")))))

    (add-hook 'message-send-mail-hook 'choose-msmtp-account)
    (run-at-time nil (* 60 5) 'mu4e-update-mail-and-index t)

    (bind-key "C-c c" 'org-mu4e-store-and-capture mu4e-headers-mode-map)
    (bind-key "C-c c" 'org-mu4e-store-and-capture mu4e-view-mode-map))

  (use-package! mu4e-alert
    :init
    (add-hook 'after-init-hook #'mu4e-alert-enable-notifications)
    (add-hook 'after-init-hook #'mu4e-alert-enable-mode-line-display)
    (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))

  (use-package! mu4e-maildirs-extension
    :after mu4e
    :config (mu4e-maildirs-extension))
  (map! :leader
        (:prefix-map ("M" . "mu4e")
          :desc "Open email app" "M" #'mu4e
          :desc "Compose email"  "c" #'mu4e-compose-new)))

Pass


(use-package! auth-source
  :init (setq auth-source-debug t
              auth-source-do-cache nil))

PKGBUILD

Packages


(package! pkgbuild-mode)

Config


(use-package! pkgbuild-mode
  :mode "PKGBUILD\\'")

Robot


(package! robot-mode
  :recipe (:host github :repo "wingyplus/robot-mode"))

(use-package! robot-mode)

VLF

Packages


(package! vlf)

Config


(use-package! vlf-setup
  :init (setq vlf-application 'dont-ask))

Tramp

(after! tramp (setq tramp-default-method "scp" tramp-debug-buffer t tramp-verbose 10) (tramp-set-completion-function "ssh" '((tramp-parse-sconfig "/etc/ssh_config") (tramp-parse-sconfig "~/.ssh/config"))))

xrdb

Packages


(package! xrdb-mode
  :recipe (:host github :repo "arkhan/xrdb-mode"))

Config


  (use-package! xrdb-mode
    :mode (("\\.Xdefaults$" . xrdb-mode)
           ("\\Xdefaults$" . xrdb-mode)
           ("\\.Xenvironment$" . xrdb-mode)
           ("\\Xenvironment$" . xrdb-mode)
           ("\\.Xresources$" . xrdb-mode)
           ("\\Xresources$" . xrdb-mode)
           (".*\\.ad$" . xrdb-mode)
           (".*\\.x?rdb$" . xrdb-mode))
    :config
    (add-hook 'xrdb-mode-hook (lambda () (setq comment-start "! "))))