Skip to content

shfx/emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

.emacs.d

Synopsis

Emacs configuration files written with the help of org-mode and org-babel

Install xcode cli tools

xcode-select --install

Install Emacs with homebrew

brew tap d12frosted/emacs-plus
brew install emacs-plus@29 --with-no-frame-refocus --with-xwidgets --with-imagemagick --with-native-comp --with-savchenkovaleriy-big-sur-icon --with-poll

To start a bg service, run:

brew services start emacs-plus@29

Better package management

paradox (link)

Better list-package mode

(use-package paradox
  :custom
  (paradox-github-token t)
  :config
  (paradox-enable))

quelpa (link)

(use-package quelpa
  ;; It will install this package without using use-package
  :ensure nil
  :init
  (unless (package-installed-p 'quelpa)
    (with-temp-buffer
      (url-insert-file-contents "https://raw.githubusercontent.com/quelpa/quelpa/master/quelpa.el")
      (eval-buffer)
      (quelpa-self-upgrade)))
  :custom
  (quelpa-dir (no-littering-expand-var-file-name "quelpa/"))
  (quelpa-build-dir (expand-file-name "build" quelpa-dir))
  (quelpa-melpa-dir (expand-file-name "melpa" quelpa-dir))
  (quelpa-packages-dir (expand-file-name "packages" quelpa-dir)))

quelpa-use-package (link)

(use-package quelpa-use-package
  ;; It will install this package without using use-package
  :after quelpa
  :ensure nil
  :init
  (quelpa
   '(quelpa-use-package
     :fetcher git
     :url "https://github.com/quelpa/quelpa-use-package.git"))
  (require 'quelpa-use-package)
  (quelpa-use-package-activate-advice))

auto-minor-mode (link)

(use-package auto-minor-mode)

system-package (link)

(use-package system-packages
  :custom
  (system-packages-package-manager 'brew))

Initialiation defaults

better-defaults (link)

(use-package better-defaults
  :config
  (ido-mode 0))

async (link)

(use-package async
  :config
  (dired-async-mode 1))

auth-source

(use-package auth-source
  :no-require t
  :custom
  (auth-sources '("~/.authinfo.gpg")))

Measure startup time

(add-hook 'emacs-startup-hook
          (lambda ()
            (message "*** Emacs loaded in %s with %d garbage collections."
                     (format "%.2f seconds"
                             (float-time
                              (time-subtract after-init-time before-init-time)))
                     gcs-done)))

Starting the server if not already started

(if (and (fboundp 'server-running-p)
         (not (server-running-p)))
   (server-start))

Focus new frame

(when (featurep 'ns)
  (defun ns-raise-emacs ()
    "Raise Emacs."
    (ns-do-applescript "tell application \"Emacs\" to activate"))

  (defun ns-raise-emacs-with-frame (frame)
    "Raise Emacs and select the provided frame."
    (with-selected-frame frame
      (when (display-graphic-p)
        (ns-raise-emacs))))

  (add-hook 'after-make-frame-functions 'ns-raise-emacs-with-frame)
  (when (display-graphic-p)
    (ns-raise-emacs)))

Errors handling and ignore server errors

When running as a deamon emacs checks if custom.el is in safe place. Here were setting custom.el in /tmp dir and it will sometimes throw an errors. Here is a dirty hack.

(defadvice server-ensure-safe-dir
    (around
     my-around-server-ensure-safe-dir
     activate)
  "Ignores any errors raised from server-ensure-safe-dir"
  (ignore-errors ad-do-it))

Disable native-compile warnings when starting emacs. Warnings should not break the init of Emacs.

(setq warning-minimum-level :error)

Setting default coding system

(prefer-coding-system 'utf-8)

Setting default display and editing options

(use-package shell
  :ensure nil
  :hook
  (shell-mode . ansi-color-for-comint-mode-on))

(use-package emacs
  :ensure nil
  :custom
  (apropos-do-all t)
  (auto-save-default nil)
  (bidi-inhibit-bpa t)
  (compilation-scroll-output nil)
  (create-lockfiles nil)
  (cursor-in-non-selected-windows nil)
  (fast-but-imprecise-scrolling t)
  (ffap-machine-p-known 'reject)
  (frame-resize-pixelwise t)
  (frame-title-format nil)
  (highlight-nonselected-windows nil)
  (indent-tabs-mode nil)
  (inhibit-compacting-font-caches t)
  (inhibit-startup-echo-area-message user-login-name)
  (inhibit-startup-message t)
  (inhibit-startup-screen t)
  (left-fringe-width  16)
  (make-backup-files nil)
  (ns-right-alternate-modifier nil)
  (ns-use-proxy-icon nil)
  (pop-up-frames nil)
  (right-fringe-width  16)
  (ring-bell-function 'ignore)
  (scroll-conservatively 101)
  (scroll-margin 0)
  (scroll-preserve-screen-position t)
  (scroll-step 1)
  (show-paren-mode 1)
  (show-trailing-whitespace nil)
  (split-height-threshold 80)
  (split-width-threshold 160)
  (transient-mark-mode t)
  (use-dialog-box nil)
  (vc-handled-backends nil)
  (visible-bell t)

  :config
  (set-default 'truncate-lines t)
  (global-hl-line-mode 0)
  (set-window-margins nil 0 0)
  (electric-pair-mode 0)
  (line-number-mode 0)
  (column-number-mode 0)
  (delete-selection-mode 1)
  (global-auto-revert-mode 1)
  (menu-bar-mode 0)
  (save-place-mode 1)

  ;; Better support for files with long lines
  (setq-default bidi-paragraph-direction 'left-to-right)
  (setq-default bidi-inhibit-bpa t)
  (global-so-long-mode 1)

  (advice-add #'tty-run-terminal-initialization :override #'ignore)
  (advice-add #'display-startup-echo-area-message :override #'ignore))

(setq remote-file-name-inhibit-cache nil)
(setq vc-ignore-dir-regexp
      (format "%s\\|%s"
                    vc-ignore-dir-regexp
                    tramp-file-name-regexp))
(setq tramp-verbose 1)

(fset 'yes-or-no-p 'y-or-n-p)

;; http:https://mbork.pl/2021-11-13_y-or-n-p_but_with_RET_meaning_yes
(defconst y-or-n-p-ret-yes-map
  (let ((map (make-sparse-keymap)))
    (set-keymap-parent map y-or-n-p-map)
    (define-key map [return] 'act)
    map)
  "A keymap for y-or-n-p with RET meaning \"yes\".")

(setq y-or-n-p-map y-or-n-p-ret-yes-map)

(global-unset-key (kbd "C-x C-c"))
(global-unset-key (kbd "s-w"))
(global-unset-key (kbd "C-x C-z"))
(global-unset-key (kbd "C-<wheel-up>"))
(global-unset-key (kbd "C-<wheel-down>"))
(global-unset-key (kbd "<mouse-2>"))
(global-unset-key (kbd "s-t"))

;; TODO: find better replacement for those bindigns 
(global-set-key (kbd "<pinch>") 'ignore)
(global-set-key (kbd "<C-wheel-up>") 'ignore)
(global-set-key (kbd "<C-wheel-down>") 'ignore)

;; Make shebang (#!) file executable when saved
(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)

;; font sizes
(global-set-key
 (kbd "s-=")
 (lambda ()
   (interactive)
   (let ((old-face-attribute (face-attribute 'default :height)))
     (message (format "Changed font size to %d" (+ old-face-attribute 10)))
     (set-face-attribute 'default nil :height (+ old-face-attribute 10)))))

(global-set-key
 (kbd "s--")
 (lambda ()
   (interactive)
   (let ((old-face-attribute (face-attribute 'default :height)))
     (message (format "Changed font size to %d" (- old-face-attribute 10)))
     (set-face-attribute 'default nil :height (- old-face-attribute 10)))))

(global-set-key "\C-l" 'goto-line)
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)
(global-set-key (kbd "M-s-<right>") 'tab-next)
(global-set-key (kbd "M-s-<left>") 'tab-previous)

Comint

(use-package comint
  :ensure nil
  :config
  (add-to-list 'comint-output-filter-functions 'ansi-color-process-output))

Compiation

(defun colorize-compilation-buffer ()
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region (point-min) (point-max))))

(use-package compilation-mode
  :ensure nil
  :hook
  (compilation-filter . colorize-compilation-buffer))

Alerter - notifications for macos

(defun alerter--symbol-value (symbol)
  "Stripts keyword symbol name from a colon"
  (replace-regexp-in-string "^:" "" (symbol-name symbol)))

(defun alerter--option (args)
  "Returns a function that will generate single argument for alerter using ARGS as a string"
  (lambda (key)
    (concat "-" (alerter--symbol-value key) " " (plist-get args key))))

(setq alerter-default-args
      '(:title "Emacs" :sender "org.gnu.Emacs" :timeout "5"))

(defun alerter (message &rest args)
  "Notify user using native macOS notifications. MESSAGE will be displayed using alerter package, with additional ARGS"
  (if (executable-find "alerter")
      (let* ((args (append alerter-default-args args))
             (options (seq-filter (lambda (element) (keywordp element)) args))
             (config (mapconcat (alerter--option args) options " "))
             (cmd (concat "alerter " config " -message \"" (replace-regexp-in-string "\"" "\\\"" message  t t) "\" &")))
        (message cmd)
        (call-process-shell-command cmd))
    (error "Can't find alerter executable")))

xwidget-webkit problem with emacsclient

We need to redefine xwidget-webkit-enable-plugins variable for webkit to work properly

(if (boundp 'xwidget-webkit-enable-plugins)
      (setq xwidget-webkit-enable-plugins t)
  (defvar xwidget-webkit-enable-plugins t))

Windmove

(use-package windmove
  :ensure nil
  :init
  (windmove-default-keybindings 'super)
  (windmove-swap-states-default-keybindings (list 'super 'control))
  (winner-mode 1))

Default trash behavior

(use-package osx-trash
  :if (eq system-type 'darwin)
  :ensure-system-package macos-trash
  :init
  (osx-trash-setup)
  :custom
  (osx-trash-command "trash -F")
  (delete-by-moving-to-trash t))

System specific defaults

(when (eq system-type 'darwin)
  (defvar ls-lisp-use-insert-directory-program)
  (defvar powerline-image-apple-rgb)
  (setq ns-use-srgb-colorspace t)
  (setq powerline-image-apple-rgb t)
  (require 'ls-lisp)
  (setq ls-lisp-use-insert-directory-program nil))

Disabling suspend-frame binding

Very annoying binding, lets get rid of it.

(global-unset-key (kbd "C-z"))

Browser Url

Set build-in module defaults to handle chrome as a default browser

(use-package browse-url
  :custom
  (browse-url-browser-function 'browse-url-default-browser))

(use-package browse-url-dwim
  :config
  (browse-url-dwim-mode 1))

EasyGP Assistant

(use-package epa
  :if (eq system-type 'darwin)
  :ensure-system-package (gpg pinentry-mac)
  :custom
  (epa-file-encrypt-to '("[email protected]"))
  (password-cache-expiry (* 60 15))
  (epa-file-select-keys nil)
  (epg-pinentry-mode 'loopback))

(use-package epa
  :if (eq system-type 'gnu/linux)
  :custom
  (epa-file-encrypt-to '("[email protected]"))
  (password-cache-expiry (* 60 15))
  (epa-file-select-keys nil)
  (epg-pinentry-mode 'loopback))

when starting, we should prepare our gpg config

gpg --list-keys
echo "pinentry-program /opt/homebrew/bin/pinentry-mac" >> $HOME/.gnupg/gpg-agent.conf
gpg --expert --full-generate-key

https://alexschroeder.ch/wiki/2016-03-17_GPG_Agent_and_Emacs

Window and frame management

Pooper (link)

(use-package popper
  :ensure t ; or :straight t
  :bind (("s-§"          . popper-toggle-latest)
         ("M-§"          . popper-cycle)
         ("s-M-§"        . popper-toggle-type)
         ("s-<escape>"   . popper-toggle-latest)
         ("M-<escape>"   . popper-cycle)
         ("C-M-<escape>" . popper-toggle-type))
  :custom
  (popper-reference-buffers
   '("\\*Messages\\*"
     "Output\\*$"
     "\\*Async Shell Command\\*"
     compilation-mode
     vterm-mode
     "\\*verminal"))
  (popper-mode-line '(:eval
                      (propertize " POP " 'face 'mode-line-emphasis)))
  (popper-display-control t)
  (popper-group-function nil)
  :config
  (popper-mode +1)
  (popper-echo-mode +1))

Shackle (link)

Shackle gives you the means to put an end to popped up buffers not behaving they way you’d like them to. By setting up simple rules you can for instance make Emacs always select help buffers for you or make everything reuse your currently selected window.

(use-package shackle
  :custom
  (shackle-rules
   '(("*eshell*"               :select t   :other t)
     (flycheck-error-list-mode :select t   :align below :size 0.25)
     ("*LSP Error List*"       :select t   :align below :size 0.25)
     (compilation-mode         :select nil :align below :size 0.25)
     (messages-buffer-mode     :select t   :align below :size 0.25)
     (inferior-emacs-lisp-mode :select t   :align below :size 0.25)
     ("\\*vterminal.*"         :select t   :align below :size 0.25 :regexp t)
     (vterm-mode               :select t   :align below :size 0.25)
     (multi-vterm              :select t   :align below :size 0.25)
     ("*rg*"                   :select t   :other t)
     (" *Deletions*"           :select t   :align below :size 0.25)
     (" *Marked Files*"        :select t   :align below :size 0.25)
     ("*system-packages*"      :select t   :align below :size 0.25)
     ("*Org Select*"           :same t)
     ("*Org Note*"             :select t   :align below :size 0.33)
     ("*Org Links*"            :select t   :align below :size 0.2)
     (" *Org todo*"            :select t   :align below :size 0.2)
     ("*Man.*"                 :select t   :align below :size 0.5  :regexp t)
     ("*Org Src.*"             :select t   :align right :size 0.5  :regexp t)))
  (shackle-default-rule
   '(:select t))
  :config
  (shackle-mode t))

TabBar

(use-package tab-bar
  :ensure nil
  :custom
  ;; Do not show buttons.
  (tab-bar-new-button-show t)
  (tab-bar-close-button-show t)
  (tab-bar-tab-hints t))

TabLine

(use-package tab-line
  :ensure nil
  :custom
  (tab-line-separator " | ")
  (tab-line-close-button-show nil)
  (tab-line-new-button-show nil))

Debug Emacs

Explain Pause

(use-package explain-pause-mode
  :quelpa (explain-pause-mode :fetcher github :repo "lastquestion/explain-pause-mode"))

List filtering helpers

Vertico (link)

Some of the config is borrowed straight from Kristoffer Balintonas blog post from

(defun my/vertico-multiform-flat-toggle ()
  "Toggle between flat and reverse."
  (interactive)
  (vertico-multiform--display-toggle 'vertico-flat-mode)
  (if vertico-flat-mode
      (vertico-multiform--temporary-mode 'vertico-reverse-mode -1)
    (vertico-multiform--temporary-mode 'vertico-reverse-mode 1)))

(defun my/vertico-quick-embark (&optional arg)
  "Embark on candidate using quick keys."
  (interactive)
  (when (vertico-quick-jump)
    (embark-act arg)))

(use-package vertico
  :demand t
  :hook ((rfn-eshadow-update-overlay . vertico-directory-tidy)
         (minibuffer-setup . vertico-repeat-save))
  :bind (:map vertico-map
              ("<tab>" . vertico-insert)
              ("<escape>" . minibuffer-keyboard-quit)
              ("?" . minibuffer-completion-help)
              ("C-M-n" . vertico-next-group)
              ("C-M-p" . vertico-previous-group)
              ("M-o" . my/vertico-quick-embark)
              ("C-l" . my/vertico-multiform-flat-toggle)
              ("C-i" . vertico-quick-insert)
              ("C-o" . vertico-quick-exit)
              ("M-G" . vertico-multiform-grid)
              ("M-F" . vertico-multiform-flat)
              ("M-R" . vertico-multiform-reverse)
              ("M-U" . vertico-multiform-unobtrusive)
              ("<backspace>" . vertico-directory-delete-char)
              ("C-w" . vertico-directory-delete-word)
              ("C-<backspace>" . vertico-directory-delete-word)
              ("RET" . vertico-directory-enter))

  :custom ((vertico-resize t)
           (vertico-cycle t)
           (vertico-grid-separator "        ")
           (vertico-grid-lookahead 50)
           (vertico-buffer-display-action '(display-buffer-reuse-window))
           ;;
           (vertico-multiform-categories
            '((consult-grep buffer)
              (consult-buffer indexed)
              (imenu buffer)
              (library indexed)
              (org-roam-node indexed)))
           ;;
           (vertico-multiform-commands
            '((consult-line
               posframe
               (vertico-posframe-poshandler . posframe-poshandler-frame-top-center)
               (vertico-posframe-border-width . 10)
               (vertico-posframe-fallback-mode . vertico-buffer-mode))
              (t posframe))))
  :config
  ;; Workaround for problem with `tramp' hostname completions. This overrides
  ;; the completion style specifically for remote files! See
  ;; https://github.com/minad/vertico#tramp-hostname-completion
  (defun mw/basic-remote-try-completion (string table pred point)
    (and (vertico--remote-p string)
         (completion-basic-try-completion string table pred point)))
  (defun mw/basic-remote-all-completions (string table pred point)
    (and (vertico--remote-p string)
         (completion-basic-all-completions string table pred point)))
  (add-to-list 'completion-styles-alist
               '(basic-remote           ; Name of `completion-style'
                 mw/basic-remote-try-completion mw/basic-remote-all-completions nil))

  (vertico-mode 1)
  (vertico-multiform-mode 1))

(use-package vertico-posframe
  :after vertico
  :custom
  (vertico-posframe-parameters
      '((left-fringe . 8)
        (right-fringe . 8))))

also helpful emacs config just for vertico

(use-package emacs
  :ensure nil
  :bind
  ("s-," . (lambda () (interactive)
             (find-file (concat user-emacs-directory "README.org"))))
  :init
  (defun crm-indicator (args)
    (cons (format "[CRM%s] %s"
                  (replace-regexp-in-string
                   "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
                   crm-separator)
                  (car args))
          (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  :custom
  ;; Do not allow the cursor in the minibuffer prompt
  (minibuffer-prompt-properties
   '(read-only t cursor-intangible t face minibuffer-prompt))
  ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
  ;; Vertico commands are hidden in normal buffers.
  (read-extended-command-predicate
        #'command-completion-default-include-p)
  ;; Enable recursive minibuffers
  (enable-recursive-minibuffers nil))
(use-package recursion-indicator
  :demand t
  :config
  (recursion-indicator-mode))

Orderless (link)

(use-package orderless
  :init
  (setq completion-styles '(orderless basic)
        completion-category-defaults nil
        completion-category-overrides '((file (styles partial-completion)))))

Savehist

(use-package savehist
  :after no-littering
  :init
  (savehist-mode))

Consult (link)

;; Example configuration for Consult
(use-package consult
  :after projectile
  :demand t
  ;; Replace bindings. Lazily loaded due by `use-package'.
  :bind (;; C-c bindings (mode-specific-map)
         ("C-c h" . consult-history)
         ("C-c m" . consult-mode-command)
         ("C-c b" . consult-bookmark)
         ("C-c k" . consult-kmacro)
         ;; C-x bindings (ctl-x-map)
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
         ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
         ("C-x 5 b" . consult-buffer-other-frame)  ;; orig. switch-to-buffer-other-frame
         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)
         ;; Other custom bindings
         ("M-y" . consult-yank-pop)                ;; orig. yank-pop
         ("<help> a" . consult-apropos)            ;; orig. apropos-command
         ;; M-g bindings (goto-map)
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flymake)               ;; Alternative: consult-flycheck
         ("M-g g" . consult-goto-line)             ;; orig. goto-line
         ("M-g M-g" . consult-goto-line)           ;; orig. goto-line
         ("M-g o" . consult-outline)               ;; Alternative: consult-org-heading
         ("M-g m" . consult-mark)
         ("M-g k" . consult-global-mark)
         ("M-g i" . consult-imenu)
         ("M-g I" . consult-imenu-multi)
         ;; M-s bindings (search-map)
         ("M-s f" . consult-find)
         ("M-s F" . consult-locate)
         ("M-s g" . consult-grep)
         ("M-s G" . consult-git-grep)
         ("M-s r" . consult-ripgrep)
         ("M-s l" . consult-line)
         ("M-s L" . consult-line-multi)
         ("M-s m" . consult-multi-occur)
         ("M-s k" . consult-keep-lines)
         ("M-s u" . consult-focus-lines)
         ;; Isearch integration
         ("M-s e" . consult-isearch-history)
         :map isearch-mode-map
         ("M-e" . consult-isearch-history)         ;; orig. isearch-edit-string
         ("M-s e" . consult-isearch-history)       ;; orig. isearch-edit-string
         ("M-s l" . consult-line)                  ;; needed by consult-line to detect isearch
         ("M-s L" . consult-line-multi))           ;; needed by consult-line to detect isearch

  ;; Enable automatic preview at point in the *Completions* buffer.
  ;; This is relevant when you use the default completion UI,
  ;; and not necessary for Vertico, Selectrum, etc.

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq register-preview-delay 0.5
        register-preview-function #'sconsult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  (advice-add #'register-preview :override #'consult-register-window)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  ;;(consult-customize
  ;; consult-theme
  ;; :preview-key '(:debounce 0.2 any)
  ;; consult-ripgrep consult-git-grep consult-grep
  ;; consult-bookmark consult-recent-file consult-xref
  ;; consult--source-buffer consult--source-project-buffer consult--source-bookmark
  ;; :preview-key (kbd "M-."))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-+")

  (autoload 'projectile-project-root "projectile")
  (setq consult-project-root-function #'projectile-project-root)

  (defun consult-info-emacs ()
    "Search through Emacs info pages."
    (interactive)``
    (consult-info "emacs" "efaq" "elisp" "cl" "compat")))

Consult Projectile (link)

(use-package consult-projectile
  :demand t
  :after (consult projectile)
  :bind-keymap ("C-c p" . projectile-command-map)
  :bind (:map projectile-command-map
              ("p" . consult-projectile))
  :custom
  (projectile-switch-project-action 'consult-projectile))

Consult flycheck (link)

(use-package consult-flycheck)

Consult Dir (link)

(use-package consult-dir
  :ensure t
  :bind (("C-x C-d" . consult-dir)
         :map vertico-map
         ("C-x C-d" . consult-dir)
         ("C-x C-j" . consult-dir-jump-file)))

pcmpl-args

(use-package pcmpl-args)

Remote

Tramp

(use-package tramp
  :ensure nil
  :custom
  (tramp-inline-compress-start-size 1000)
  (tramp-copy-size-limit 10000)
  (vc-handled-backends '(Git))
  (tramp-default-method "scp")
  (tramp-use-ssh-controlmaster-options nil)
  (projectile--mode-line "Projectile")
  (tramp-verbose 1))

Packages

Displaying errors

Flycheck

(use-package flycheck
  :hook (prog-mode . flycheck-mode)
  :custom-face
  (flycheck-error ((t (:underline (:color "#e74c3c" :style wave) :background unspecified))))
  (flycheck-info ((t (:underline (:color "#b6e63e" :style wave) :background unspecified))))
  :custom
  (flycheck-idle-change-delay 0)
  (flycheck-disabled-checkers '(emacs-lisp-checkdoc)))

(use-package flycheck-rust
  :after flycheck)

Sideline

(use-package sideline
  :defines sideline-backends-right
  :custom
  (sideline-backends-left-skip-current-line t)
  (sideline-backends-right-skip-current-line t)
  (sideline-order-left 'down)
  (sideline-order-right 'up)
  (sideline-format-left "%s   ")
  (sideline-format-right "   %s")
  (sideline-priority 100)
  (sideline-display-backend-name nil))

(use-package sideline-flycheck
  :after sideline
  :hook (flycheck-mode . sideline-flycheck-setup)
  :config
  (add-to-list 'sideline-backends-right 'sideline-flycheck))

(use-package sideline-lsp
  :after sideline
  :custom
  (sideline-lsp-code-actions-prefix "")
  :config
  (add-to-list 'sideline-backends-right 'sideline-lsp))

Packages

restclient

(use-package restclient
  :defer t
  :mode (("\\.http\\'" . restclient-mode))
  :bind (:map restclient-mode-map
              ("C-c C-f" . json-mode-beautify)))

jq

(use-package jq-mode
  :after (org-mode json-mode)
  :commands (jq-mode jq-interactively)
  :mode ("\\.jq$" . js-mode)
  :bind (:map json-mode-map
              ("C-c C-j" . jq-interactively))
  :config
  (org-babel-add-langs
   ((jq . t))))

LSP Mode

(defun my/corfu-setup-lsp ()
  "Use orderless completion style with lsp-capf instead of the
  default lsp-passthrough."
  (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
        '(orderless)))

(setq lsp-use-plists "true")

(use-package lsp-mode
  :commands (lsp lsp-deferred)
  :after (corfu orderless)
  :hook
  ((lsp-mode . lsp-enable-which-key-integration)
   (lsp-completion-mode . my/corfu-setup-lsp))
  :custom
  (lsp-log-io nil)
  (lsp-file-watch-threshold 4000)
  (lsp-headerline-breadcrumb-enable nil)
  (lsp-headerline-breadcrumb-icons-enable nil)
  (lsp-headerline-breadcrumb-enable-diagnostics nil) 
  (lsp-headerline-breadcrumb-segments '(file symbols))
  (lsp-auto-guess-root t)
  (lsp-enable-file-watchers nil)
  (lsp-clients-typescript-preferences
   '(:includeCompletionsForModuleExports nil :generateReturnInDocTemplate nil))
  (lsp-clients-typescript-prefer-use-project-ts-server t)
  (lsp-completion-provider :none)
  (lsp-diagnostic-clean-after-change t)
  (lsp-diagnostics-modeline-scope :workspace)
  (lsp-eslint-working-directories `[(pattern ,(expand-file-name "Developer/*" (getenv "HOME")))])
  (lsp-enable-indentation nil)
  (lsp-enable-on-type-formatting nil)
  (lsp-javascript-display-enum-member-value-hints t)
  (lsp-javascript-format-enable nil)
  (lsp-keymap-prefix "C-c l")
  (lsp-lens-enable t)
  (lsp-typescript-format-enable nil)
  (lsp-yaml-schema-store-local-db
   (no-littering-expand-var-file-name "./lsp/lsp-yaml-schemas.json"))
  :config
  (dolist (dir '("[/\\\\]\\.ccls-cache\\'"
                 "[/\\\\]\\.mypy_cache\\'"
                 "[/\\\\]\\.pytest_cache\\'"
                 "[/\\\\]\\.cache\\'"
                 "[/\\\\]\\.clwb\\'"
                 "[/\\\\]__pycache__\\'"
                 "[/\\\\]bazel-bin\\'"
                 "[/\\\\]bazel-code\\'"
                 "[/\\\\]bazel-genfiles\\'"
                 "[/\\\\]bazel-out\\'"
                 "[/\\\\]bazel-testlogs\\'"
                 "[/\\\\]third_party\\'"
                 "[/\\\\]third-party\\'"
                 "[/\\\\]buildtools\\'"
                 "[/\\\\]out\\'"
                 "[/\\\\]build\\'"
                 "[/\\\\]dist\\'"
                 "[/\\\\].dist\\'"
                 ))
    (push dir lsp-file-watch-ignored-directories)))

(use-package lsp-ui
  :after lsp-mode
  :hook (lsp-mode . lsp-ui-mode)
  :bind
  (:map lsp-ui-mode-map
        (([remap xref-find-definitions] . lsp-ui-peek-find-definitions)
         ([remap xref-find-references]  . lsp-ui-peek-find-references)))
  :custom
  (lsp-ui-doc-enable t)
  (lsp-ui-doc-position 'at-point)
  (lsp-ui-doc-alignment 'window)
  (lsp-ui-doc-show-with-cursor nil)
  (lsp-ui-doc-show-with-mouse t)
  (lsp-ui-doc-use-childframe t)
  (lsp-ui-doc-border "windowBacekgroundColor")
  (lsp-ui-doc-include-signature t)
  (lsp-ui-doc-max-height 15)
  (lsp-ui-doc-max-width 100)
  (lsp-ui-sideline-enable nil)
  (lsp-lens-enable nil))

(use-package lsp-tailwindcss
  :custom
  (lsp-tailwindcss-add-on-mode t))

(use-package lsp-pyright
  :ensure t
  :hook (python-mode . (lambda ()
                         (require 'lsp-pyright)
                         (lsp-deferred))))

Dabbrev

(use-package dabbrev
  ;; Swap M-/ and C-M-/
  :bind (("M-/" . dabbrev-completion)
         ("C-M-/" . dabbrev-expand))
  :config
  (add-to-list 'dabbrev-ignored-buffer-regexps "\\` ")
  ;; Since 29.1, use `dabbrev-ignored-buffer-regexps' on older.
  (add-to-list 'dabbrev-ignored-buffer-modes 'doc-view-mode)
  (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))

ChatGPT

(defun shell-maker-welcome-message-ignore (config) "")

(use-package chatgpt-shell
  :custom
  ;; (chatgpt-shell-openai-key "xxx")
  ;;(chatgpt-shell-openai-key  "xxx")
  (chatgpt-shell-welcome-function 'shell-maker-welcome-message-ignore)
)

Proced

(use-package proced
  :ensure nil
  :defer t
  :custom
  (proced-enable-color-flag t)
  (proced-tree-flag t))

Copilot

(use-package copilot
  :quelpa (copilot :fetcher github
                   :repo "zerolfx/copilot.el"
                   :branch "main"
                   :files ("dist" "*.el"))
  :bind
  (:map copilot-completion-map (("<tab>" . copilot-accept-completion)
                                ("TAB" . copilot-accept-completion)
                                ("C-TAB" . 'copilot-accept-completion-by-word)
                                ("C-<tab>" . 'copilot-accept-completion-by-word)))
  ;;:hook
  ;;(prog-mode . copilot-mode)
  )

Apheleia

(use-package apheleia
  :config
  (apheleia-global-mode +1)
  (setf (alist-get 'prisma-mode apheleia-mode-alist)
      '(prettier)))

Treesitter

Enables tree-sitter in all programming languages supported. Should be loaded before any language package

(use-package treesit-auto
  :custom
  (treesit-auto-install 'prompt)
  :functions global-treesit-auto-mode
  :defines global-treesit-auto-modes
  :preface
  (defun my/ts-mode-p (mode)
    (let* ((mode-name (symbol-name mode)))
      (cond
       ((string-suffix-p "ts-mode" mode-name) t)
       (t nil))))

  (defun my/bring-previous-mode-hooks ()
    (let ((mode-name (symbol-name major-mode)))
      (if (not (my/ts-mode-p major-mode))
          (error "Current mode does not contain -ts suffix: %s" mode-name)
        (let* (
               (non-ts-mode-name      (concat (string-remove-suffix "-ts" (string-remove-suffix "-mode" mode-name)) "-mode"))
               (non-ts-mode-hook-name (concat non-ts-mode-name "-hook")))

          (if (not (intern non-ts-mode-hook-name))
              (message "There is no hook list named %s" non-ts-mode-hook-name)
            (run-hooks (intern non-ts-mode-hook-name))
            (message "Ran hook for %s" non-ts-mode-hook-name))))))

  (defun my/get-treesit-auto-modes ()
    "Extracts all available treesit auto modes"
    (unless global-treesit-auto-modes
      (error "global-treesit-auto-modes vartable does not exist, can't transfer hooks from non treesit modes"))  
    (seq-filter 'my/ts-mode-p global-treesit-auto-modes))

  :config

  (add-to-list 'treesit-auto-langs 'svelte)

  (add-to-list 'treesit-auto-recipe-list
               (make-treesit-auto-recipe
                :lang 'prisma
                :ts-mode 'prisma-ts-mode
                :remap '(prisma-mode)
                :url "https://github.com/victorhqc/tree-sitter-prisma"
                :revision "master"
                :source-dir "src"
                :ext "\\.prisma\\'"))

  (add-to-list 'treesit-auto-recipe-list
               (make-treesit-auto-recipe
                :lang 'svelte
                :ts-mode 'svelte-ts-mode
                :remap 'svelte-mode
                :url "https://github.com/Himujjal/tree-sitter-svelte"
                :source-dir "./src"
                :ext "\\.svelte\\'"))

  (treesit-auto-add-to-auto-mode-alist 'all)
  (global-treesit-auto-mode)

  ;; add lambda function hook to list of emacs hooks
  (dolist (mode (my/get-treesit-auto-modes))
    (let* ((mode-name (symbol-name mode))
           (hook-name (concat mode-name "-hook")))
      (add-hook (intern hook-name) #'my/bring-previous-mode-hooks))))

Treesit fold

(use-package treesit-fold
  :quelpa (treesit-fold :fetcher github :repo "emacs-tree-sitter/treesit-fold"))

Project Tasks

(use-package project-tasks
  :defer t

  :commands (project-tasks)

  :init
  ;; Show project-tasks when switching projects
  (add-to-list 'project-switch-commands '(project-tasks "tasks") t)
  ;; Add action to embark-file map
  (with-eval-after-load 'embark
    (define-key embark-file-map (kbd "P") #'project-tasks-in-dir))

  :custom
  ;; Set the list of tasks files
  (project-tasks-files '("tasks.org"))

  ;; Set the ignore files
  ;; (project-tasks-ignore-files '("README.org"))

  ;; Set the function to get current project dir
  ;; (project-tasks-root-func #'project-tasks-project-root)

  ;; Set the separator between file name and task name
  ;; (project-tasks-separator " -> ")
  :config
  (add-to-list 'marginalia-prompt-categories '("select task" . project-task))
  (defvar-keymap embark-project-task-actions
    :doc "Keymap for actions for project-task (when mentioned by name)."
    :parent embark-general-map
    "j" #'project-tasks-goto-task)
  (add-to-list 'embark-keymap-alist '(project-task . embark-project-task-actions))
  ;; Bind project-tasks to project keymap
  :bind
  (:map project-prefix-map ("P" . project-tasks)))

Dashboard

(use-package dashboard
  :custom
  (initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
  (dashboard-startup-banner 'logo)
  (dashboard-items '((recents  . 5)
                     (bookmarks . 5)
                     (projects . 5)
                     (agenda . 5)
                     (registers . 5)))
  (dashboard-display-icons-p t)
  (dashboard-icon-type 'all-the-icons)
  (dashboard-modify-heading-icons '((recents . "file-text")
                                    (bookmarks . "book")))
  (dashboard-set-navigator t)
  (dashboard-week-agenda t)
  ;; Format: "(icon title help action face prefix suffix)"
  (dashboard-navigator-buttons
   `((("Homepage"
       "Browse homepage"
       (lambda (&rest _) (browse-url "homepage")))
      ("Star" "Show stars" (lambda (&rest _) (show-stars)) warning)
      ("?" "" "?/h" #'show-help nil "<" ">"))
     ;; line 2
     (("linkedin"
       ""
       (lambda (&rest _) (browse-url "homepage")))
      ("" nil "Show flags" (lambda (&rest _) (message "flag")) error))))
  :config
  (dashboard-setup-startup-hook))

Bufler

(use-package bufler
  :bind
  ("C-x b" . bufler-switch-buffer)
  ("C-x C-b" . bufler-list)
  :custom
  (bufler-workspace-switch-buffer-sets-workspace t))

Eshell (link)

Eshell is a shell written entirely in Emacs-Lisp, and it replicates most of the features and commands from GNU CoreUtils and the Bourne-like shells. So by re-writing common commands like ls and cp in Emacs-Lisp, Eshell will function identically on any environment Emacs itself runs on.

(use-package eshell
  :hook
  (eshell-mode .
   (lambda ()
     (setq-local
      corfu-auto nil
      corfu-quit-at-boundary t
      corfu-quit-no-match t
      corfu-separatvor nil)
     (corfu-mode)
     (setenv "TERM" "xterm-256color")))


  :custom
  (eshell-banner-message "")
  (eshell-scroll-to-bottom-on-input 'this)
  (eshell-error-if-no-glob t)
  (eshell-hist-ignoredups t)
  (eshell-save-history-on-exit t)
  (eshell-prefer-lisp-functions nil)
  (eshell-destroy-buffer-when-process-dies t)

  :config
  (setenv "PAGER" "cat")
  (setenv "PATH"
          (concat
           "/usr/local/bin:/usr/local/sbin:"
           (getenv "PATH")))

  (defun eshell/gst (&rest args)
    (magit-status (pop args) nil)
    (eshell/echo)))

(use-package eshell-up
  :after eshell)

(use-package shrink-path
  :after eshell
  :custom
  ((eshell-prompt-regexp "^.*❯ ")
   (eshell-prompt-function
    (lambda nil
      (let ((base/dir (shrink-path-prompt default-directory)))
        (concat (propertize (car base/dir)
                            'face 'font-lock-comment-face)
                (propertize (cdr base/dir)
                            'face 'font-lock-constant-face)
                (propertize "" 'face 'eshell-prompt-face)
                ;; needed for the input text to not have prompt face
                (propertize " " 'face 'default)))))))

Toogle undecorated frame

(defun toggle-frame-maximized-undecorated ()
  (interactive)
  (let* ((frame (selected-frame))
         (on? (and (frame-parameter frame 'undecorated)
                   (eq (frame-parameter frame 'fullscreen) 'maximized)))
         (geom (frame-monitor-attribute 'geometry))
         (initial-x (first geom))
         (display-height (first (last geom))))
    (if on?
        (progn
          (set-frame-parameter frame 'undecorated nil)
          (toggle-frame-maximized))
      (progn
        (set-frame-position frame initial-x 0)
        (set-frame-parameter frame 'fullscreen 'maximized)
        (set-frame-parameter frame 'undecorated t)
        (set-frame-height frame (- display-height 26) nil t)
        (set-frame-position frame initial-x 0)))))

Scratch (link)

Scratch is an extension to Emacs that enables one to create scratch buffers that are in the same mode as the current buffer. This is notably useful when working on code in some language; you may grab code into a scratch buffer, and, by virtue of this extension, do so using the Emacs formatting rules for that language.

(use-package scratch)

Eshell Toggle (link)

Simple functionality to show/hide eshell/ansi-term (or almost any other buffer, see eshell-toggle-init-function description below) at the bottom of active window with directory of its buffer.

(use-package eshell-toggle
  :after eshell
  :bind
  ("s-`" . eshell-toggle)
  :custom
  (eshell-toggle-name-separator "")
  (eshell-toggle-size-fraction 3)
  (eshell-toggle-use-projectile-root t))

ESUP

(use-package esup)

vterm

(use-package vterm
  :custom
  (vterm-always-compile-module t))

(use-package multi-vterm
  :after vterm
  :bind (("C-c v" . multi-vterm)))

Eat - an extension to eshell

(use-package eat
  :hook
  (eshell-load . eat-eshell-visual-command-mode)
  :custom
  (eat-term-name "xterm")
  (eshell-visual-commands nil)
  :config
  (eat-eshell-mode))

Marginalia

;; Enable richer annotations using the Marginalia package
(use-package marginalia
  :demand t
  :bind (:map minibuffer-local-map
         ("M-A" . marginalia-cycle))
  :custom
  ;; (marginalia-max-relative-age)
  (marginalia-align 'right)
  :config
  (marginalia-mode))

diff-hl

(use-package diff-hl
  :commands global-diff-hl-mode
  :hook 
  ((magit-pre-refresh . diff-hl-magit-pre-refresh)
   (magit-post-refresh . diff-hl-magit-post-refresh)
   (dired-mode . diff-hl-dired-mode))
  :config
  (global-diff-hl-mode))

Editor Config (link)

EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems.

(use-package editorconfig
  :init
  (editorconfig-mode 1))

Posframe

(use-package posframe
  :ensure t)

goggles (link)

(use-package goggles
  :hook ((prog-mode text-mode) . goggles-mode)
  :custom
  (goggles-pulse t))

Expand region

(use-package expreg
  :ensure t
  :bind
  ("C-=" . expreg-expand)
  ("C--" . expreg-contract))

launchctl

(use-package launchctl)

Restart Emacs

(use-package restart-emacs)

Matching Paren Overlay

(use-package matching-paren-overlay
  :quelpa
  (matching-paren-overlay
   :fetcher git
   :url "https://codeberg.org/acdw/matching-paren-overlay.el.git"))

Nerd Icons

(use-package emacs
  :if (not (file-exists-p "~/Library/Fonts/JetBrainsMonoNerdFont-Medium.ttf"))
  :ensure nil
  :ensure-system-package font-jetbrains-mono-nerd-(format "message" format-args)ont)

(use-package emacs
  :ensure nil
  :custom-face (default ((t (:font "JetBrainsMono Nerd Font" :height 150)))))

(use-package nerd-icons
  :defines nerd-icons-regexp-icon-alist
  :custom
  (nerd-icons-color-icons t)
  :config
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("_?test\\.rb$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-red))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("_?test_helper\\.rb$" nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-dred))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("_?spec\\.rb$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-red))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("_?spec_helper\\.rb$" nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-dred))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?spec\\.ts$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-blue))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?test\\.ts$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-blue))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?spec\\.js$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-lpurple))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?test\\.js$"        nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-lpurple))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?spec\\.jsx$"       nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-blue-alt))
  (add-to-list 'nerd-icons-regexp-icon-alist
    '("-?test\\.jsx$"       nerd-icons-mdicon "nf-md-test_tube" :face nerd-icons-blue-alt)))

(use-package nerd-icons-dired
  :hook (dired-mode . nerd-icons-dired-mode))

(use-package nerd-icons-ibuffer
  :hook (ibuffer-mode . nerd-icons-ibuffer-mode))

(use-package nerd-icons-completion
  :after corfu marginalia
  :functions (nerd-icons-completion-mode nerd-icons-completion-marginalia-setup)
  :config
  (nerd-icons-completion-mode)
  (add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))

(use-package nerd-icons-corfu
  :after corfu
  :config
  (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))

(use-package treemacs-nerd-icons
  :config
  (treemacs-load-theme "nerd-icons"))

Projectile (link)

Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies (when feasible)

(use-package projectile
  :demand t
  :bind-keymap
  ("C-c p" . projectile-command-map)
  :custom
  (projectile-enable-caching nil)
  (projectile-sort-order 'recently-active)
  (projectile-project-search-path '("~/Developer/"))
  (projectile-ignored-projects `("~/"
                                 "/opt/homebrew"
                                 "/tmp/"
                                 "/private/tmp/"
                                 "~/Developer/work"
                                 ,package-user-dir))
  (projectile-track-known-projects-automatically nil)
  :config
  (projectile-mode)
  ;; Projectile is testing in the reverse order so more specific must me at the end

  (projectile-register-project-type
   'npm '("package.json")
   :compile "npm i"
   :test "npm test"
   :run "npm start"
   :test-suffix ".spec.js")

  (projectile-register-project-type
   'opera
   '("desktop/BUILD.gn" "desktop/gn_opera.py")
   :project-file "desktop/BUILD.gn"
   :run (concat "open $HOME/Developer/work/chromium/src/out/Release/Opera.app --args"
                " --allow-running-insecure-content"
                " --disable-web-security"
                " --ignore-certificate-errors"
                " --remote-debugging-port=9222"
                " --sticky-site-url-override=https://gxcorner.games"
                " --user-data-dir=$HOME/Developer/clean-profile/$(date +\"%Y-%m-%dT%H:%M:%S\")"
                " --use-mock-keychain")
   :configure "$HOME/goma/goma_ctl.py ensure_start && desktop/gn_opera.py --release product=\\\"gx\\\" use_jumbo_build=false use_remoteexec=true goma_dir=\"\\\"/Users/opera_user/goma\\\"\""
   :compile "autoninja -C chromium/src/out/Release opera"))

ibuffer-projectile (link)

(use-package ibuffer-projectile
  :hook
  (ibuffer . (lambda ()
               (ibuffer-projectile-set-filter-groups)
               (unless (eq ibuffer-sorting-mode 'alphabetic)
                 (ibuffer-do-sort-by-alphabetic)))))

Embark (link)

(defun embark-which-key-indicator ()
  "An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
  (lambda (&optional keymap targets prefix)
    (if (null keymap)
        (which-key--hide-popup-ignore-command)
      (which-key--show-keymap
       (if (eq (plist-get (car targets) :type) 'embark-become)
           "Become"
         (format "Act on %s '%s'%s"
                 (plist-get (car targets) :type)
                 (embark--truncate-target (plist-get (car targets) :target))
                 (if (cdr targets) "" "")))
       (if prefix
           (pcase (lookup-key keymap prefix 'accept-default)
             ((and (pred keymapp) km) km)
             (_ (key-binding prefix 'accept-default)))
         keymap)
       nil nil t (lambda (binding)
                   (not (string-suffix-p "-argument" (cdr binding))))))))

(defun embark-hide-which-key-indicator (fn &rest args)
  "Hide the which-key indicator immediately when using the completing-read prompter."
  (which-key--hide-popup-ignore-command)
  (let ((embark-indicators
         (remq #'embark-which-key-indicator embark-indicators)))
    (apply fn args)))

(advice-add #'embark-completing-read-prompter
            :around #'embark-hide-which-key-indicator)

(use-package embark
  :after which-key
  :demand t
  :bind
  (("s-." . embark-act)         ;; pick some comfortable binding
   ("C-;" . embark-dwim)        ;; good alternative: M-.
   ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'

  :custom
  (embark-indicators
   '(embark-which-key-indicator
     embark-highlight-indicator
     embark-isearch-highlight-indicator))

  (prefix-help-command #'embark-prefix-help-command)

  :config
  ;; Unbind help-command so completing-read interface can do it's job
  (unbind-key "C-h <help>" global-map)
  (unbind-key "C-h" help-map)
  ;;(unbind-key "C-h" ehelp-map)

  ;; Hide the mode line of the Embark live/completions buffers
  (add-to-list 'display-buffer-alist
               '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
                 nil
                 (window-parameters (mode-line-format . none)))))

highlight-global

(use-package highlight-global
  :quelpa (highlight-global :fetcher github :repo "kaushalmodi/highlight-global")
  :bind
  ("C-s-h" . highlight-global-hl-frame-toggle))

Embark Consult (link)

Consult users will also want the embark-consult package.

(use-package embark-consult
  :after (embark consult)
  :demand t
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Corfu (link)

(use-package corfu
  :demand t
  :after orderless

  :preface
  (defun corfu-enable-always-in-minibuffer ()
    "Enable Corfu in the minibuffer if Vertico/Mct are not active."
    (unless (or (bound-and-true-p mct--active) ; Useful if I ever use MCT
                (bound-and-true-p vertico--input))
      (setq-local corfu-auto nil)       ; Ensure auto completion is disabled
      (corfu-mode 1)))

  :hook (minibuffer-setup . corfu-enable-always-in-minibuffer)
  :bind (:map corfu-map
              ("C-n" . corfu-next)
              ("C-p" . corfu-previous)
              ("<escape>" . corfu-quit)
              ("<return>" . corfu-insert)
              ("M-d" . corfu-popupinfo-show)
              ("M-l" . corfu-show-location)
              ("H-SPC" . corfu-insert-separator)
              ("SPC" . corfu-insert-separator))

  :custom
  (completion-cycle-threshold nil)
  (corfu-auto t)
  (corfu-auto-delay 0)
  (corfu-auto-prefix 1)
  (corfu-count 14)
  (corfu-cycle nil)
  (corfu-echo-documentation t)
  (corfu-min-width 80)
  (corfu-max-width corfu-min-width)
  (corfu-preselect-first t)
  (corfu-preview-current t)
  (corfu-preselect 'valid)
  (corfu-separator ?\s)
  (corfu-quit-at-boundary :separator)
  (corfu-quit-no-match t)
  (corfu-scroll-margin 4)
  (corfu-popupinfo-delay '(0.3 . 0.1))
  (corfu-popupinfo-hide nil)
  (tab-always-indent 'complete)
  (tab-first-completion 'word-or-paren-or-punct)
  (read-extended-command-predicate #'command-completion-default-include-p)

  :config
  (global-corfu-mode)
  (corfu-popupinfo-mode)
  ;; The advices are only needed on Emacs 28 and older.
  (when (< emacs-major-version 29)
    ;; Silence the pcomplete capf, no errors or messages!
    (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent)

    ;; Ensure that pcomplete does not write to the buffer
    ;; and behaves as a pure `completion-at-point-function'.
    (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)))

;; Use dabbrev with Corfu!
(use-package dabbrev
  ;; Swap M-/ and C-M-/
  :bind (("M-/" . dabbrev-completion)
         ("C-M-/" . dabbrev-expand)))

Cape (link)

(use-package cape
  :bind (("C-." . completion-at-point)
         ("C-c /" . cape-dabbrev))
  :init
  (add-to-list 'completion-at-point-functions #'cape-file))

Multiple Cursors (link)

Multiple cursors for Emacs. This is some pretty crazy functionality, so yes, there are kinks. Don’t be afraid tho, I’ve been using it since 2011 with great success and much merriment.

(use-package multiple-cursors
  :hook
  (multiple-cursors-mode
   .
   (lambda ()
     (if multiple-cursors-mode
         (progn
           (message "multiple cursor on")
           (corfu-mode 0))
       (progn
         (message "multiple cursor off")
         (corfu-mode 1)))))
  :bind
  ("C->" . mc/mark-next-like-this)
  ("C-<" . mc/mark-previous-like-this))

Org

org-mode (link)

Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text syste.

(defmacro org-babel-add-langs (langs)
  `(org-babel-do-load-languages
    'org-babel-load-languages
    (append org-babel-load-languages
            ',langs)))

(defun alist-unique (alist)
  (reduce (lambda (output value)
            (let* ((key (car value))
                   (existing-value (alist-get key output)))
              (cond ((not output) (list value))
                    ((not existing-value) (append output (list value)))
                    (t output))))
          alist :initial-value nil))

(defun append-alist-unique (values alist)
  "Add unique VALUE to ALIST when car of VALUE is unique, returns ALIST otherwise"
  (alist-unique (append alist values)))

(use-package org
  :hook
  (org-mode . turn-on-auto-fill)
  :bind
  ("C-c l" . org-store-link)
  ("C-c a" . org-agenda)
  ("C-c c" . org-capture)

  :config
  (org-babel-add-langs ((emacs-lisp .  t)))
  (org-indent-mode 1)
  (custom-set-faces '(org-ellipsis ((t (:foreground "gray40" :underline nil)))))
  (org-babel-add-langs
   ((ditaa . t)))
  :custom
  (org-modules
   '(org-protocol
     org-habit
     org-mouse
     org-tempo
     org-mac-iCal
     org-panel))
  (org-blank-before-new-entry
   '((heading . t)
     (plain-list-item . nil)))
  (org-confirm-babel-evaluate
   (lambda (lang body)
     (not (string= lang "restclient"))))
  (org-hide-leading-stars t)
  (org-src-tab-acts-natively t)
  (org-startup-indented t)
  (org-startup-folded "content")
  (org-startup-with-inline-images t)
  (org-babel-min-lines-for-block-output 1)
  (org-speed-command-help t)
  (org-src-preserve-indentation t)
  (org-ellipsis "" )
  (org-pretty-entities t)
  (org-hide-emphasis-markers t)
  (org-agenda-block-separator "")
  (org-fontify-whole-heading-line nil)
  (org-fontify-done-headline t)
  (org-fontify-quote-and-verse-blocks t)
  (org-tags-column 0)
  (org-indent-indentation-per-level 0)
  (org-directory "~/Dropbox/org")
  (org-default-notes-file "notes.org")
  (org-refile-targets '((org-agenda-files :maxlevel . 1)))
  (org-refile-allow-creating-parent-nodes 'confirm)
  (org-capture-templates
   '(("a" "Appointment" entry (file  "gcal.org" )
      "* %?\n\n%^T\n\n:PROPERTIES:\n\n:END:\n\n")
     ("l" "Link" entry (file+headline "links.org" "Links")
      "* %? %^L %^g \n%T" :prepend t)
     ("b" "Blog idea" entry (file+headline "todo.org" "Blog Topics:")
      "* %?\n%T" :prepend t)
     ("t" "Todo Item" entry
      (file+headline "todo.org" "Todo")
      "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:" :prepend t :empty-lines 1)
     ("n" "Note" entry (file+headline "todo.org" "Note space")
      "* %?\n%u" :prepend t)
     ("j" "Journal" entry (file+olp+datetree "journal.org")
      "* %?\nEntered on %U\n  %i\n  %a")
     )))
(use-package org-habit
  :ensure nil)

(use-package org-starless
  :hook (org-mode . org-starless-mode)
  :quelpa (org-starless :fetcher github :repo "TonCherAmi/org-starless"))

(use-package org-tree-slide
  :custom
  (org-tree-slide-skip-outline-level 4)
  (org-tree-slide-skip-done nil)
  :config
  (global-set-key (kbd "<f8>") 'org-tree-slide-mode)
  (global-set-key (kbd "S-<f8>") 'org-tree-slide-skip-done-toggle)
  (define-key org-tree-slide-mode-map (kbd "<f9>")
    'org-tree-slide-move-previous-tree)
  (define-key org-tree-slide-mode-map (kbd "<f10>")
    'org-tree-slide-move-next-tree)
  (define-key org-tree-slide-mode-map (kbd "<f11>")
    'org-tree-slide-content)
  (org-tree-slide-narrowing-control-profile))

;; (use-package org-bullets
;;   :hook (org-mode . org-bullets-mode))

;; org-babel
(org-babel-add-langs
 ((emacs-lisp . t)
  (shell . t)))

(use-package ob-restclient
  :custom
  (org-babel-default-header-args:restclient
   '((:results . "raw")
     (:async . "yes")))
  :config
  (org-babel-add-langs
   ((restclient . t))))

(use-package ob-js
  :ensure nil
  :config
  (org-babel-add-langs
   ((js . t)))

  (add-to-list 'org-babel-tangle-lang-exts '("js" . "js")))

(use-package ob-deno
  :config
  (org-babel-add-langs
   ((deno . t))))

(use-package ob-mermaid
  :ensure-system-package (mmdc . "npm install -g @mermaid-js/mermaid-cli")
  :config
  (org-babel-add-langs
   ((mermaid . t))))

(use-package ob-async)

(use-package org-super-agenda
  :init
  :custom
  (org-super-agenda-groups
   ;; Each group has an implicit boolean OR operator between its selectors.
   '((:name "Today"        ; Optionally specify section name
            :time-grid t   ; Items that appear on the time grid
            :todo "TODAY") ; Items that have this TODO keyword
     (:name "Important"
            ;; Single arguments given alone
            :tag "bills"
            :priority "A")
     ;; Set order of multiple groups at once
     (:order-multi (2 (:name "Shopping in town"
                             ;; Boolean AND group matches items that match all subgroups
                             :and (:tag "shopping" :tag "@town"))
                      (:name "Food-related"
                             ;; Multiple args given in list with implicit OR
                             :tag ("food" "dinner"))
                      (:name "Personal"
                             :habit t
                             :tag "personal")
                      (:name "Space-related (non-moon-or-planet-related)"
                             ;; Regexps match case-insensitively on the entire entry
                             :and (:regexp ("space" "NASA")
                                           ;; Boolean NOT also has implicit OR between selectors
                                           :not (:regexp "moon" :tag "planet")))))
     ;; Groups supply their own section names when none are given
     (:todo "WAITING" :order 8)  ; Set order of this section
     (:todo ("SOMEDAY" "TO-READ" "CHECK" "TO-WATCH" "WATCHING")
            ;; Show this group at the end of the agenda (since it has the
            ;; highest number). If you specified this group last, items
            ;; with these todo keywords that e.g. have priority A would be
            ;; displayed in that group instead, because items are grouped
            ;; out in the order the groups are listed.
            :order 9)
     (:priority<= "B"
                  ;; Show this section after "Today" and "Important", because
                  ;; their order is unspecified, defaulting to 0. Sections
                  ;; are displayed lowest-number-first.
                  :order 1)
     ;; After the last group, the agenda will display items that didn't
     ;; match any of these groups, with the default order position of 99
     ))
  (org-super-agenda-mode 1))

(defun make-orgcapture-frame ()
  "Create a new frame and run org-capture."
  (interactive)
  (make-frame '((name . "remember") (width . 80) (height . 16)
                (top . 400) (left . 300)
                ;; (font . "-apple-Monaco-medium-normal-normal-*-13-*-*-*-m-0-iso10646-1")
                ))
  (select-frame-by-name "remember")
  (org-capture)
  (delete-other-windows))

(use-package yequake
  :custom
  (yequake-frames
   '(("org-capture"
      (buffer-fns . (yequake-org-capture))
      (width . 0.75)
      (height . 0.5)
      (alpha . 0.95)
      (frame-parameters . ((undecorated . t)
                           (skip-taskbar . t)
                           (sticky . t)))))))

Org Roam

(defun org-roam-node-insert-immediate (arg &rest args)
  "This will allow you to quickly create new notes for topics
you're mentioning while writing so that you can go back later and
fill those notes in with more details!"
  (interactive "P")
  (let ((args (cons arg args))
        (org-roam-capture-templates (list (append (car org-roam-capture-templates)
                                                  '(:immediate-finish t)))))
    (apply #'org-roam-node-insert args)))

(defun my/org-roam-filter-by-tag (tag-name)
  "returns a filter function for "
  (lambda (node)
    (member tag-name (org-roam-node-tags node))))

(defun my/org-roam-list-notes-by-tag (tag-name)
  "Returns list of noted with given filetag"
  (mapcar #'org-roam-node-file
          (seq-filter
           (my/org-roam-filter-by-tag tag-name)
           (org-roam-node-list))))

(defun my/org-roam-refresh-agenda-list ()
  "Refreshes the agenda list adding Project notes to the list"
  (interactive)
  (setq org-agenda-files
        (append org-agenda-files
                (my/org-roam-list-notes-by-tag "Project")
                (my/org-roam-list-notes-by-tag "Plant"))))

(defun my/org-roam-template-dir-expand (file)
  (expand-file-name (concat user-emacs-directory file)))

(use-package org-roam
  :after org
  :custom
  (org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
  (org-roam-directory "~/Dropbox/OrgRoam")
  (org-roam-completion-everywhere nil)
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n c" . org-roam-capture)
         ("C-c n I" . org-roam-node-insert-immediate)
         ;; Dailies
         ("C-c n j" . org-roam-dailies-capture-today)

         :map org-mode-map
         ("C-M-i"    . completion-at-point)

         :map org-roam-dailies-map
         ("Y" . org-roam-dailies-capture-yesterday)
         ("T" . org-roam-dailies-capture-tomorrow))

  :bind-keymap
  ("C-c n d" . org-roam-dailies-map)
  :custom-face
  (org-roam-link ((t (:foreground "#e24888" :underline t))))
  (org-roam-link-current ((t (:foreground "#e24888" :underline t))))
  :config
  (org-roam-setup)
  (require 'org-roam-dailies)
  (org-roam-db-autosync-mode)
  (my/org-roam-refresh-agenda-list)
  (setq org-roam-capture-templates
        `(("d" "default" plain
           "%?"
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n")
           :unnarrowed t)
          ("e" "elisp" plain
           (file ,(my/org-roam-template-dir-expand "etc/org-roam/templates/elisp.org"))
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: elisp\n")
           :unnarrowed t)
          ("p" "project" plain
           (file ,(my/org-roam-template-dir-expand "etc/org-roam/templates/project.org"))
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: Project\n")
           :unnarrowed t)
          ("r" "proposal" plain
           (file ,(my/org-roam-template-dir-expand "etc/org-roam/templates/proposal.org"))
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: Proposal\n")
           :unnarrowed t)
          ("f" "food" plain
           (file ,(my/org-roam-template-dir-expand "etc/org-roam/templates/food.org"))
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: Food\n")
           :unnarrowed t)
          ("t" "plant" plain
           (file ,(my/org-roam-template-dir-expand "etc/org-roam/templates/plant.org"))
           :if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n#+date: %U\n#+category: ${title}\n#+filetags: Plant\n")
           :unnarrowed t))))

(use-package websocket
  :after org-roam)

(use-package org-roam-ui
  :after (org-roam websocket)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))

Htmlize for org-mode

(use-package htmlize)

org-cliplink (link)

(use-package org-cliplink
  :bind ("C-x p i" . org-cliplink))

org-roam-ui

(use-package org-roam-ui
  :quelpa (:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
  :after org-roam
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  :hook (after-init . org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t))

Org Tidy

(use-package org-tidy
  :hook
  (org-mode . org-tidy-mode))

Org Download

(use-package org-download
  :hook (dired-mode . org-download-enable)
  :custom
  (org-download-screenshot-method "screencapture -i %s"))

Load theme

(use-package doom-themes
  :config
  (load-theme 'doom-molokai t)
  (doom-themes-org-config)
  (doom-themes-visual-bell-config)
  (doom-themes-neotree-config))

Key suffixes popup

(use-package which-key
  :init
  (which-key-mode)
  :config
  (add-to-list 'which-key-replacement-alist '(("TAB" . nil) . ("" . nil)))
  (add-to-list 'which-key-replacement-alist '(("RET" . nil) . ("" . nil)))
  (add-to-list 'which-key-replacement-alist '(("DEL" . nil) . ("" . nil)))
  (add-to-list 'which-key-replacement-alist '(("SPC" . nil) . ("" . nil)))
  :custom
  ((which-key-sort-order #'which-key-prefix-then-key-order)
   (which-key-add-column-padding 1)
   (which-key-min-display-lines 6)
   (which-key-side-window-location 'bottom)
   (which-key-side-window-max-height 0.25)
   (which-key-side-window-max-width 0.33)
   (which-key-popup-type 'side-window)
   (which-key-sort-uppercase-first nil)))

Editing forms in chrome

(use-package atomic-chrome
  :config
  (atomic-chrome-start-server))

Better help dialogs

(use-package helpful
  :bind (("C-h f"  . helpful-callable)
         ("C-h v"  . helpful-variable)
         ("C-h k"  . helpful-key)
         ("C-c C-d" . helpful-at-point)
         ("C-h k"  . helpful-key)))

Better list-package mode

(use-package paradox
  :custom
  (paradox-github-token t)
  :config
  (paradox-enable))

pnpm-mode

(use-package pnpm-mode
  :custom
  (pnpm-mode-command-prefix "C-c s-n"))

Cycling between different var notations

(use-package string-inflection
  :bind
  ("C-c C-u" . string-inflection-all-cycle))

Open dash at point

(use-package dash-at-point
  :bind
  ("C-c d" . dash-at-point)
  ("C-c e" . dash-at-point-with-docset))

Move lines using alt + arrows

(use-package move-text
  :config
  (move-text-default-bindings))

Anzu - current match / all matches in modeline

(use-package anzu
  :init
  (global-anzu-mode +1)
  :bind
  ("M-%" . anzu-query-replace)
  ("C-M-%" . anzu-query-replace-regexp))

Modeline

Doom Modeline

(use-package doom-modeline
  :custom
  (doom-modeline-hud t)
  (doom-modeline-icon t)
  (doom-modeline-major-mode-icon t)
  (doom-modeline-major-mode-color-icon t)
  (doom-modeline-buffer-state-icon t)
  (doom-modeline-buffer-modification-icon t)
  (doom-modeline-minor-modes nil)
  (doom-modeline-checker-simple-format t)
  (doom-modeline-height 30)
  :config
  (doom-modeline-mode))

Hide Modeline

Hides modeline whenever this minor mode is active

(use-package hide-mode-line
  :commands hide-mode-line-mode)

Git

magit - best git client ever

(use-package magit
  :init
  :bind ("C-x g" . magit-status)
  :hook
  (git-commit-mode . flyspell-mode)
  :custom
  (vc-handled-backends nil)
  (magit-process-finish-apply-ansi-colors t)
  (magit-refresh-status-buffer t)
  (magit-blame-goto-chunk-hook '(magit-blame-maybe-show-message))
  (magit-display-buffer-function 'magit-display-buffer-fullframe-status-v1)
  (magit-bury-buffer-function 'magit-restore-window-configuration)
  (magit-process-password-functions '(magit-process-password-auth-source))
  :config
  (remove-hook 'magit-refs-sections-hook 'magit-insert-tags)
  ;; TODO: add to magit-process-password-functions an auth source
  (transient-define-suffix magit-submodule-update-all ()
    "Update all submodules"
    :description "Update All (git submodule update --init --recursive)"
    (interactive)
    (magit-with-toplevel
      (magit-run-git-async "submodule" "update" "--init" "--recursive"))))
(use-package forge
  :after magit
  :config
  (add-to-list 'forge-alist '("gitlab.services.ams.osa" "gitlab.services.ams.osa/api/v4" "gitlab.services.ams.osa" forge-gitlab-repository))
  (add-to-list 'forge-alist '("gitlab.service.osa" "gitlab.service.osa/api/v4" "gitlab.service.osa" forge-gitlab-repository)))

magit-todos (link)

(use-package magit-todos
  :after (magit)
  :custom
  (magit-todos-exclude-globs '(".git/"))
  :config
  (magit-todos-mode 1))

Conventional Commit

(use-package conventional-commit
  :quelpa (conventional-commit :fetcher github :repo "akirak/conventional-commit.el")
  :hook
  (git-commit-mode . conventional-commit-setup))

browse-at-remote (link)

(use-package browse-at-remote
  :bind ("C-c C-g" . browse-at-remote)
  :custom
  (browse-at-remote-remote-type-regexps 
   '(
     (:host "^git\\.oslo\\.osa"               :type "oslo")
     (:host "^gitlab\\.services\\.ams\\.osa$" :type "gitlab")
     (:host "^gitlab\\.service\\.osa$"        :type "gitlab")
     (:host "^github\\.com$"                  :type "github")
     (:host "^bitbucket\\.org$"               :type "bitbucket")
     (:host "^gitlab\\.com$"                  :type "gitlab")
     (:host "^gist\\.github\\.com$"           :type "gist"))))

(defun browse-at-remote-oslo-format-url (repo-url)
  "Get a gnu formatted URL."
  (let* ((parts (split-string repo-url "/var/git" t))
   (domain (butlast parts))
   (project (car (last parts))))
    (string-join
     (append domain (list project)) "/")))

(defun browse-at-remote--format-region-url-as-oslo (repo-url location filename &optional linestart lineend)
  "URL formatter for gnu."
  (let ((repo-url (browse-at-remote-oslo-format-url repo-url)))
    (cond
     (linestart (format "%s/tree/%s?h=%s#n%d" repo-url filename location linestart))
     (t (format "%s/tree/%s?h=%s" repo-url filename location)))))

(defun browse-at-remote--format-commit-url-as-gnu (repo-url commithash)
  "Commit URL formatted for gnu"
  (format "%s/commit/?id=%s" (browse-at-remote-oslo-format-url repo-url) commithash))

gitlab-pipeline

(use-package gitlab-pipeline
  :custom
  (gitlab-pipeline-host "gitlab.services.ams.osa/api/v4"))

docker

(use-package docker
  :ensure t
  :bind ("C-c d" . docker))

hl-todo-mode (link)

(use-package hl-todo
  :config
  :hook (prog-mode . hl-todo-mode))

goto-line-preview

(use-package goto-line-preview
  :bind ([remap goto-line] . goto-line-preview)
  :config)

pulsar

(use-package pulsar
  :config
  (pulsar-global-mode 1))

unfill

(use-package unfill
  :bind ([remap fill-paragraph] . unfill-toggle))

Snippets

(use-package yasnippet
  :after lsp-mode
  :hook (prog-mode . yas-minor-mode))

(use-package yasnippet-snippets
  :after yasnippet
  :config
  (yas-reload-all))

keyfreq

(use-package keyfreq
  :custom
  (keyfreq-excluded-commands
   (list ignore
         mwheel-scroll
         self-insert-command
         forward-char
         left-char
         right-char
         backward-char
         previous-line
         next-line))
  :config
  (keyfreq-mode 1)
  (keyfreq-autosave-mode 1))

rg

ripgrep frontend

(use-package rg
  :ensure-system-package rg
  :custom
  (rg-custom-type-aliases
   '(("svelte" .    "*.svelte")
     ("ts" .    "*.tsx?")
     ("env" .    "\.env.*")))
  :config
  (rg-enable-menu))

Dired

I’ve tried ~ranger-mode~ with it’s simplier ~deer-mode~ and I must say, nothing beets good old Dired.

With some additions of course, like ~diredfl~ for colors and ~dired-quick-sort~ for better sorting with native gnu ls

(use-package dired
  :ensure nil
  :custom
  (dired-dwim-target t)
  (dired-vc-rename-file t)
  :config
  (cond ((string-equal system-type "darwin")
         (setq insert-directory-program "gls"
               dired-use-ls-dired t)
         (setq dired-listing-switches "-agho --group-directories-first"))))

(use-package diredfl
  :after dired
  :init
  (diredfl-global-mode 1))

(use-package dired-quick-sort
  :after dired
  :custom
  (ls-lisp-use-insert-directory-program t)
  :config
  (dired-quick-sort-setup))

(use-package dired-subtree
  :after dired
  :bind (:map dired-mode-map
              ("TAB" . dired-subtree-toggle)))

Prog modes

Prepare all prog modes

(use-package display-line-numbers
  :ensure nil
  :hook (prog-mode . display-line-numbers-mode)
  :custom
  (display-line-numbers-type 'relative))

prisma

(use-package prisma-mode
  :mode ("\\.prisma\\'" . prisma-mode)
  :quelpa (prisma-mode :fetcher github :repo "pimeys/emacs-prisma-mode" :branch "main")
  :hook (prisma-mode . lsp-deferred))

el

(use-package emacs-lisp
  :ensure nil
  :bind
  ((:map global-map
         ("C-x C-e" . nil))
   (:map emacs-lisp-mode-map
         ("C-x C-e" . eval-last-sexp))))

rust

(use-package rust-mode
  :after flycheck-rust
  :mode ("\\.rs" . rust-mode)
  :hook ((flycheck-mode . flycheck-rust-setup)
         (rust-mode . lsp-deferred)))

rustic

(use-package rustic)

.env

(use-package dotenv-mode
  :mode ("\\.env\\..*\\'" . dotenv-mode))

Elisp

(use-package elisp
  :ensure nil
  :mode ("\\.el\\'" . emacs-lisp-mode))

Markdown

(use-package markdown-mode
  :mode (("README\\.md\\'" . gfm-mode)
         ("\\.md\\'" . markdown-mode)
         ("\\.markdown\\'" . markdown-mode)))

(use-package grip-mode
  :bind
  (:map markdown-mode-command-map
        ("g" . grip-mode))
  :config
  (let ((credential (auth-source-user-and-password "github.com")))
    (setq grip-github-user (car credential)
          grip-github-password (cadr credential))))

(use-package edit-indirect
  :after markdown-mode)

Htmlize for org-mode

(use-package htmlize)

YAML

(use-package yaml-mode
  :mode "\\.yaml")

GO

(use-package go-mode
  :mode "\\.go"
  :config
  (add-hook 'go-mode-hook
            (lambda ()
              (add-hook 'before-save-hook 'gofmt-before-save)
              (local-set-key (kbd "M-.") 'godef-jump))))

JSON

(use-package json-mode
  :mode "\\.json$"
  :hook
  (json-mode . lsp-deferred)
  :interpreter "json"
  :config
  (setq js-indent-level 2))

CSS

(use-package css-mode
  :mode "\\.css")

SCSS

(use-package scss-mode
  :mode "\\.scss"
  :hook (scss-mode . lsp-deferred))

LUA

(use-package lua-mode
  :mode ("\\.lua"))

JS

(use-package typescript-mode
  :after (lsp-mode)
  :mode "\\.ts$"
  :hook (typescript-mode . lsp-deferred))

(use-package js2-mode
  :after (lsp-mode)
  :mode ("\\.[cm]*js$")
  :hook (js-base-mode . lsp-deferred))

(use-package eslintd-fix
  :hook ((js-base-mode) . eslintd-fix-mode))

(use-package web-mode
  :mode
  ("\\.html\\'"
   "\\.svelte\\'")
  :hook
  (web-mode . lsp-deferred)
  :custom
  (web-mode-content-types-alist
   '(("jsx" . "\\.tsx\\'")
     ("jsx" . "\\.jsx\\'")
     ("svelte" . "\\.svelte\\'")
     ("html" . "\\.html\\'")))
  (web-mode-enable-auto-indentation nil)
  (web-mode-indentation-params
   '(("lineup-args" . t)
     ("lineup-calls" . t)
     ("lineup-concats" . t)
     ("lineup-quotes" . t)
     ("lineup-ternary" . nil)
     ("case-extra-offset" . t))))

Py

(use-package python-mode
  :mode "\\.py"
  :interpreter "py"
  :hook (python-mode . lsp-deferred)
  :config
  (setq python-shell-interpreter "ipython"
        python-shell-interpreter-args "-i --simple-prompt"))

(use-package poetry
  :after python-mode
  :config
  (poetry-tracking-mode))

Dockerfile and docker-compose.yml

(use-package dockerfile-mode
  :mode "Dockerfile$")

(use-package docker-compose-mode
  :mode "docker-compose.yml.py$")

Other

(message ".emacs loaded successfully.")

(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)

About

emacs dotfiles and plugins

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published