Skip to content

gopar/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emacs Configuration

My Emacs Configuration as an org file cause I wanna be like the cool kids 😎

NOTE

This is a mess, unorganized but it works for me. No plan to clean this up. This config will most likely not work for you since its made for me. We are all different. Thanks for coming to my Ted Talk

Recommended Packages/Snippets to Have As Early as Possible

(setq load-prefer-newer t)
(use-package no-littering :ensure t :demand t)

Built-Ins

Going to configure all the built in packages first And any third party lib that are related to it will go under them.

Emacs Defaults

Customizing some things that should be defaults ¯\_(ツ)_/¯

;; Customize default emacs
(use-package emacs
  :ensure nil
  :defer
  :hook ((after-init . pending-delete-mode)
         (after-init . toggle-frame-maximized)
         (after-init . (lambda () (scroll-bar-mode -1)))
         (after-init . (lambda () (window-divider-mode -1)))
         (prog-mode . (lambda () (setq-local show-trailing-whitespace t))))
  :custom
  ;; flash the frame to represent a bell.
  (visible-bell t)
  (enable-recursive-minibuffers t)
  (debugger-stack-frame-as-list t)
  (narrow-to-defun-include-comments t)
  (use-short-answers t)
  (confirm-nonexistent-file-or-buffer nil)
  ;; Dont Treat manual switching of buffers the same as programatic
  (switch-to-buffer-obey-display-actions nil)
  (switch-to-buffer-in-dedicated-window nil)
  (window-sides-slots '(3 0 3 3))
  ;; Sentences end with 1 space not 2
  (sentence-end-double-space nil)
  ;; make cursor the width of the character it is under
  ;; i.e. full width of a TAB
  (x-stretch-cursor t)
  ;; Stop cursor from going into minibuffer prompt text
  (minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt))
  (history-delete-duplicates t)
  ;; Completion stuff for consult
  (completion-ignore-case t)
  (read-buffer-completion-ignore-case t)
  (completion-cycle-threshold nil)
  (tab-always-indent 'complete)
  (use-dialog-box nil) ; Lets be consistent and use minibuffer for everyting
  (scroll-conservatively 100)
  (frame-inhibit-implied-resize t)
  (custom-file "~/.emacs.d/ignoreme.el")

  :config
  (load custom-file)
  (when (eq system-type 'darwin)
    (setq mac-option-key-is-meta nil
          mac-command-key-is-meta t
          mac-command-modifier 'meta
          mac-option-modifier 'none)
    )
  (setq-default c-basic-offset 4
                c-default-style "linux"
                indent-tabs-mode nil
                fill-column 120
                tab-width 4)
  ;; Replaced in favor for `use-short-answers`
  ;; (fset 'yes-or-no-p 'y-or-n-p)
  (prefer-coding-system 'utf-8)
  ;; Uppercase is same as lowercase
  (define-coding-system-alias 'UTF-8 'utf-8)
  ;; Enable some commands
  (put 'upcase-region 'disabled nil)
  (put 'downcase-region 'disabled nil)
  (put 'erase-buffer 'disabled nil)
  (put 'list-timers 'disabled nil)
  ;; C-x n <key> useful stuff
  (put 'narrow-to-region 'disabled nil)
  (tool-bar-mode -1)
  (menu-bar-mode -1)
  (command-query 'save-buffers-kill-terminal "Do you really want to kill emacs?")

  :bind (("C-z" . nil)
         ("C-x C-z" . nil)
         ("C-x C-k RET" . nil)
         ("RET" . newline-and-indent)
         ("C-j" . newline)
         ("M-\\" . cycle-spacing)
         ("C-x \\" . align-regexp)
         ("C-x C-b" . ibuffer)
         ("M-u" . upcase-dwim)
         ("M-l" . downcase-dwim)
         ("M-c" . capitalize-dwim)
         ("C-S-k" . gopar/delete-line-backward)
         ("C-k" . gopar/delete-line)
         ("M-d" . gopar/delete-word)
         ("<M-backspace>" . gopar/backward-delete-word)
         ("M-e" . gopar/next-sentence)
         ("M-a" . gopar/last-sentence)
         (";" . gopar/easy-underscore)
         ("C-x k" . (lambda () (interactive) (bury-buffer)))
         ("C-x C-k" . (lambda () (interactive) (kill-buffer))))

  :init
  (defun gopar/copy-filename-to-kill-ring ()
    (interactive)
    (kill-new (buffer-file-name))
    (message "Copied to file name kill ring"))

  (defun gopar/easy-underscore (arg)
    "Convert all inputs of semicolon to an underscore.
If given ARG, then it will insert an acutal semicolon."
    (interactive "P")
    (if arg
        (insert ";")
      (insert "_")))

  (defun easy-camelcase (arg)
    (interactive "c")
    ;; arg is between a-z
    (cond ((and (>= arg 97) (<= arg 122))
           (insert (capitalize (char-to-string arg))))
          ;; If it's a new line
          ((= arg 13)
           (newline-and-indent))
          ((= arg 59)
           (insert ";"))
          ;; We probably meant a key command, so lets execute that
          (t (call-interactively
              (lookup-key (current-global-map) (char-to-string arg))))))

  ;; Stolen from https://emacs.stackexchange.com/a/13096/8964
  (defun gopar/reload-dir-locals-for-current-buffer ()
    "Reload dir locals for the current buffer"
    (interactive)
    (let ((enable-local-variables :all))
      (hack-dir-local-variables-non-file-buffer)))

  (defun gopar/delete-word (arg)
    "Delete characters forward until encountering the end of a word.
With argument, do this that many times.
This command does not push text to `kill-ring'."
    (interactive "p")
    (delete-region
     (point)
     (progn
       (forward-word arg)
       (point))))

  (defun gopar/backward-delete-word (arg)
    "Delete characters backward until encountering the beginning of a word.
With argument, do this that many times.
This command does not push text to `kill-ring'."
    (interactive "p")
    (gopar/delete-word (- arg)))

  (defun gopar/delete-line ()
    "Delete text from current position to end of line char.
This command does not push text to `kill-ring'."
    (interactive)
    (delete-region
     (point)
     (progn (end-of-line 1) (point)))
    (delete-char 1))

  (defadvice gopar/delete-line (before kill-line-autoreindent activate)
    "Kill excess whitespace when joining lines.
If the next line is joined to the current line, kill the extra indent whitespace in front of the next line."
    (when (and (eolp) (not (bolp)))
      (save-excursion
        (forward-char 1)
        (let ((start (point)))
          (skip-chars-forward " \t")
          (delete-region start (point))
          (insert " ")))))

  (defun gopar/delete-line-backward ()
    "Delete text between the beginning of the line to the cursor position.
This command does not push text to `kill-ring'."
    (interactive)
    (let (p1 p2)
      (setq p1 (point))
      (beginning-of-line 1)
      (setq p2 (point))
      (delete-region p1 p2)))

  (defun gopar/next-sentence ()
    "Move point forward to the next sentence.
Start by moving to the next period, question mark or exclamation.
If this punctuation is followed by one or more whitespace
characters followed by a capital letter, or a '\', stop there. If
not, assume we're at an abbreviation of some sort and move to the
next potential sentence end"
    (interactive)
    (re-search-forward "[.?!]")
    (if (looking-at "[    \n]+[A-Z]\\|\\\\")
        nil
      (gopar/next-sentence)))

  (defun gopar/list-git-authors-for-file ()
    "Display all the authors for a given file.
If file is not in a git repo or file is not a real file (aka buffer), then do nothing."
    (interactive)
    (let* ((file (buffer-file-name))
           (root (when (vc-root-dir) (expand-file-name (vc-root-dir))))
           (file (when (and file root) (s-chop-prefix root file))))
      (when (and root file)
        (message (format "Contributors for %s:\n%s" file (shell-command-to-string
          (format "git shortlog HEAD -s -n %s" file)))))))

  (defun gopar/last-sentence ()
    "Does the same as 'gopar/next-sentence' except it goes in reverse"
    (interactive)
    (re-search-backward "[.?!][   \n]+[A-Z]\\|\\.\\\\" nil t)
    (forward-char))

  (defun gopar/add-env-vars ()
    "Setup environment variables that I will need."
    (load-file "~/.emacs.d/etc/eshell/set_env.el")
    (setq-default eshell-path-env (getenv "PATH"))
    (setenv "ANTHROPIC_API_KEY" (auth-source-pick-first-password :host "api.anthropic.com"))

    (setq exec-path (append exec-path
                            `("/usr/local/bin"
                              "/usr/bin"
                              "/usr/sbin"
                              "/sbin"
                              "/bin"
                              "/Users/gopar/.nvm/versions/node/v22.14.0/bin"
                              )
                            (split-string (getenv "PATH") ":")))
    (setenv "PATH" (concat "/Users/gopar/.nvm/versions/node/v22.14.0/bin:" (getenv "PATH")))))

Diary

(use-package calendar
  :ensure nil
  :defer
  :mode ("\\diary\\'" . diary-mode)
  :custom
  (diary-file (concat user-emacs-directory "etc/diary"))
  (diary-display-function 'ignore)
  (calendar-mark-diary-entries-flat t)
  (diary-comment-start ";;")
  (diary-comment-end ""))

Org Mode

Org

Main configuration

(use-package org
  :defer
  :custom
  (org-agenda-include-diary t)
  ;; Where the org files live
  (org-directory "~/.emacs.d/org/")
  ;; Where archives should go
  (org-archive-location (concat (expand-file-name "~/.emacs.d/org/private/org-roam/gtd/archives.org") "::"))
  ;; Make sure we see syntax highlighting
  (org-src-fontify-natively t)
  (org-tag-alist '(("emacs" . ?e)
                   ("car" . ?c)
                   ("home" . ?o)
                   ("project" . ?p)
                   ("fun" . ?f)
                   ("health" . ?h)
                   ("misc" . ?i)
                   ("tv" . ?t)
                   ("money" . ?m)))
  ;; I dont use it for subs/super scripts
  (org-use-sub-superscripts nil)
  ;; Should everything be hidden?
  (org-startup-folded t)
  (org-M-RET-may-split-line '((default . nil)))
  ;; Hide stars
  (org-hide-leading-stars t)
  (org-hide-emphasis-markers nil)
  ;; Show as utf-8 chars
  (org-pretty-entities t)
  ;; put timestamp when finished a todo
  (org-log-done 'time)
  ;; timestamp when we reschedule
  (org-log-reschedule t)
  ;; Don't indent the stars
  (org-startup-indented nil)
  (org-list-allow-alphabetical t)
  (org-image-actual-width nil)
  ;; Save notes into log drawer
  (org-log-into-drawer t)
  ;;
  (org-fontify-whole-heading-line t)
  (org-fontify-done-headline t)
  ;;
  (org-fontify-quote-and-verse-blocks t)
  ;; See down arrow instead of "..." when we have subtrees
  ;; (org-ellipsis "⤵")
  ;; catch invisible edit
  ( org-catch-invisible-edits 'show-and-error)
  ;; Only useful for property searching only but can slow down search
  (org-use-property-inheritance t)
  ;; Count all children TODO's not just direct ones
  (org-hierarchical-todo-statistics nil)
  ;; Unchecked boxes will block switching the parent to DONE
  (org-enforce-todo-checkbox-dependencies t)
  ;; Don't allow TODO's to close without their dependencies done
  (org-enforce-todo-dependencies t)
  (org-track-ordered-property-with-tag t)
  ;; Where should notes go to? Dont even use them tho
  (org-default-notes-file (concat org-directory "notes.org"))
  ;; The right side of | indicates the DONE states
  (org-todo-keywords
   '((sequence "TODO(t)" "NEXT(n)" "IN-PROGRESS(i!)" "WAITING(w!)" "|" "DONE(d!)" "CANCELED(c!)" "DELEGATED(p!)")))
  ;; Needed to allow helm to compute all refile options in buffer
  (org-outline-path-complete-in-steps nil)
  (org-deadline-warning-days 2)
  (org-log-redeadline t)
  (org-log-reschedule t)
  ;; Repeat to previous todo state
  ;; If there was no todo state, then dont set a state
  (org-todo-repeat-to-state t)
  ;; Refile options
  (org-refile-use-outline-path 'file)
  (org-refile-allow-creating-parent-nodes 'confirm)
  (org-refile-targets '(("~/.emacs.d/org/private/org-roam/gtd/gtd.org" :maxlevel . 3)
                        ("~/.emacs.d/org/private/org-roam/gtd/someday.org" :level . 1)
                        ("~/.emacs.d/org/private/org-roam/gtd/tickler.org" :maxlevel . 1)
                        ("~/.emacs.d/org/private/org-roam/gtd/repeat.org" :maxlevel . 1)
                        ))
  ;; Lets customize which modules we load up
  (org-modules '(;; ol-eww
                 ;; Stuff I've enabled below
                 org-habit
                 ;; org-checklist
                 ))
  (org-special-ctrl-a/e t)
  (org-insert-heading-respect-content t)
  :hook ((org-mode . org-indent-mode)
         (org-mode . org-display-inline-images))
  :custom-face
  (org-scheduled-previously ((t (:foreground "orange"))))
  :config
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((sql . t)
     (sqlite . t)
     (python . t)
     (java . t)
     ;; (cpp . t)
     (C . t)
     (emacs-lisp . t)
     (shell . t)))
  ;; Save history throughout sessions
  (org-clock-persistence-insinuate))

Org Tempo

(use-package org-tempo
  :after org
  :config
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("p" . "src python"))
  (add-to-list 'org-structure-template-alist '("j" . "src java"))
  (add-to-list 'org-structure-template-alist '("k" . "src kotlin"))
  (add-to-list 'org-structure-template-alist '("sh" . "src sh")))

Org Clock

(use-package org-clock
  :after org
  :custom
  ;; Save clock history accross emacs sessions (read var for required info)
  (org-clock-persist t)
  ;; If idle for more than 15 mins, resolve by asking what to do with clock
  (org-clock-idle-time 15)
  ;; Don't show current clocked in task
  (org-clock-clocked-in-display nil)
  ;; Show more clocking history
  (org-clock-history-length 10)
  ;; Include running time in clock reports
  (org-clock-report-include-clocking-task t)
  ;; Put all clocking info int the "CLOCKING" drawer
  (org-clock-into-drawer "CLOCKING")
  ;; Setup default clocktable summary
  (org-clock-clocktable-default-properties
   '(:maxlevel 2 :scope file :formula % ;; :properties ("Effort" "Points")
               :sort (5 . ?t) :compact t :block today))
  :bind (:map global-map
              ("C-c j" . (lambda () (interactive) (org-clock-goto)))
              :map org-mode-map
              ("C-c C-x r" . (lambda () (interactive) (org-clock-report)))))

Org Agenda

(use-package org-agenda
  :defer
  :commands org-agenda
  :bind (("C-c a" . org-agenda))
  :hook ((org-agenda-finalize . hl-line-mode)
         (org-agenda-finalize . org-agenda-entry-text-mode))
  :custom
  (org-agenda-current-time-string (if (and (display-graphic-p)
           (char-displayable-p ?←)
           (char-displayable-p ?─))
      "⬅️ now"
    "now - - - - - - - - - - - - - - - - - - - - - - - - -"))
  (org-agenda-timegrid-use-ampm t)
  (org-agenda-tags-column 0)
  (org-agenda-window-setup 'only-window)
  (org-agenda-restore-windows-after-quit t)
  (org-agenda-log-mode-items '(closed clock state))
  (org-agenda-time-grid '((daily today require-timed)
                          (600 800 1000 1200 1400 1600 1800 2000)
                          " ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"))
  ;; (org-agenda-start-with-log-mode '(closed clock state))
  (org-agenda-files "~/.emacs.d/org/agenda-files.org")
  ;; (org-agenda-todo-ignore-scheduled 'future)
  ;; TODO entries that can't be marked as done b/c of children are shown as dimmed in agenda view
  (org-agenda-dim-blocked-tasks 'invisible)
  ;; Start the week view on whatever day im on
  (org-agenda-start-on-weekday nil)
  ;; How to identify stuck/non-stuck projects
  ;; Projects are identified by the 'project' tag and its always the first level
  ;; Next any of these todo keywords means it's not a stuck project
  ;; 3rd, theres no tags that I use to identify a stuck Project
  ;; Finally, theres no special text that signify a non-stuck project
  (org-stuck-projects
   '("+project+LEVEL=1"
     ("IN-PROGRESS" "WAITING" "DONE" "CANCELED" "DELEGATED")
     nil
     ""))
  (org-agenda-prefix-format
   '((agenda . " %-4e %i %-12:c%?-12t% s ")
     (todo . " %i %-10:c %-5e %(gopar/get-schedule-or-deadline-if-available)")
     (tags . " %i %-12:c")
     (search . " %i %-12:c")))
  ;; Lets define some custom cmds in agenda menu
  (org-agenda-custom-commands
   '(("h" "Agenda and Home tasks"
      ((agenda "" ((org-agenda-span 1)))
       (todo "IN-PROGRESS")
       (todo "WAITING")
       (tags-todo "inbox|break")
       (todo "NEXT"))
      ((org-agenda-sorting-strategy '(time-up habit-up priority-down category-up))))

     ("i" "In-Progress Tasks"
      ((todo "IN-PROGRESS|WAITING")
       (agenda ""))
      ((org-agenda-sorting-strategy '(time-up habit-up priority-down category-up))))

     ("g" "Goals: 12 Week Year"
      ((agenda "")
       (todo "IN-PROGRESS|WAITING"))
      ((org-agenda-sorting-strategy '(time-up habit-up priority-down category-up))
       (org-agenda-tag-filter-preset '("+12WY"))
       (org-agenda-start-with-log-mode '(closed clock state))
       (org-agenda-archives-mode t)
       ))

     ("r" "Weekly Review"
      ((agenda "" ((org-agenda-span 14)))
       (todo))
      ((org-agenda-sorting-strategy '(time-up habit-up category-up priority-down ))
       (org-agenda-files "~/.emacs.d/org/weekly-reivew-agenda-files.org")
       ;; (org-agenda-include-diary nil)
       ))))
  :init
  ;; Originally from here: https://stackoverflow.com/a/59001859/2178312
  (defun gopar/get-schedule-or-deadline-if-available ()
    (let ((scheduled (org-get-scheduled-time (point)))
          (deadline (org-get-deadline-time (point))))
      (if (not (or scheduled deadline))
          (format "🗓️ ")
        "   "))))

Org Capture

(use-package org-capture
  :bind (("C-c c" . org-capture))
  :commands org-capture
  :custom
  ;; dont create a bookmark when calling org-capture
  (org-capture-bookmark nil)
  ;; also don't create bookmark in other things
  (org-bookmark-names-plist nil)
  (org-capture-templates
   '(
     ("c" "Inbox" entry (file "~/.emacs.d/org/private/org-roam/gtd/inbox.org")
      "* TODO %?\n:PROPERTIES:\n:DATE_ADDED: %u\n:END:")
     ("p" "Project" entry (file "~/.emacs.d/org/private/org-roam/gtd/gtd.org")
      "* %? [%] :project: \n:PROPERTIES: \n:TRIGGER: next-sibling todo!(NEXT) scheduled!(copy)\n:ORDERED: t \n:DATE_ADDED: %u\n:END:\n** TODO Add entry")
     ("t" "Tickler" entry (file "~/.emacs.d/org/private/org-roam/gtd/tickler.org")
      "* TODO %? \nSCHEDULED: %^{Schedule}t\n:PROPERTIES:\n:DATE_ADDED: %u\n:END:\n")
     ("k" "Contact" entry (file "~/.emacs.d/org/private/org-roam/references/contacts.org")
      "* %? \n%U
:PROPERTIES:
:EMAIL:
:PHONE:
:NICKNAME:
:NOTE:
:ADDRESS:
:BIRTHDAY:
:Blog:
:END:"))))

Org OL

(use-package ol
  :after org
  :custom
  (org-link-shell-confirm-function 'y-or-n-p)
  (org-link-elisp-confirm-function 'y-or-n-p))

Org Src

(use-package org-src
  :after org
  :custom
  (org-src-preserve-indentation nil)
  ;; Don't ask if we already have an open Edit buffer
  (org-src-ask-before-returning-to-edit-buffer nil)
  (org-edit-src-content-indentation 0))

Ob Core

(use-package ob-core
  :after org
  :custom
  ;; Don't ask every time when I run a code block
  (org-confirm-babel-evaluate nil))

Org Habit

(use-package org-habit
  :after org
  :custom
  (org-habit-graph-column 45))

Org indent

(use-package org-indent
  :ensure nil
  :after org
  :diminish
  :custom
  (org-indent-mode-turns-on-hiding-stars nil))

I know this isn’t built in but putting it here w/ org mode stuff

(use-package org-pomodoro
  :ensure t
  :after org
  :bind (("<f12>" . org-pomodoro))
  :hook ((org-pomodoro-started . gopar/load-window-config-and-close-home-agenda)
         (org-pomodoro-finished . gopar/save-window-config-and-show-home-agenda))
  :custom
  (org-pomodoro-manual-break t)
  (org-pomodoro-short-break-length 20)
  (org-pomodoro-long-break-length 30)
  (org-pomodoro-length 60)
  :init
  (defun gopar/home-pomodoro ()
    (interactive)
    (setopt org-pomodoro-length 25
          org-pomodoro-short-break-length 5))

  (defun gopar/work-pomodoro ()
    (interactive)
    (setopt org-pomodoro-length 60
          org-pomodoro-short-break-length 20))

  (defun gopar/save-window-config-and-show-home-agenda ()
    (interactive)
    (window-configuration-to-register ?`)
    (delete-other-windows)
    (org-save-all-org-buffers)
    (org-agenda nil "h"))

  (defun gopar/load-window-config-and-close-home-agenda ()
    (interactive)
    (org-save-all-org-buffers)
    (shell-command "shortcuts run 'Emacs Pomodoro'")
    (jump-to-register ?`)))
(use-package org-roam
  :ensure t
  :defer
  ;; :after org
  ;; :hook (org-mode . org-roam-db-autosync-mode)
  :commands (org-roam-node-find)
  :custom
  (org-roam-directory (expand-file-name "~/.emacs.d/org/private/org-roam"))
  (org-roam-db-location (expand-file-name "~/.emacs.d/org/private/org-roam.db"))
  (org-roam-capture-templates
   '(("d" "default" plain "%?"
      :target (file+head "./references/${slug}.org" "#+title: ${title}\n")
      :unnarrowed t)))
  (org-roam-dailies-directory (expand-file-name "~/.emacs.d/org/private/journal/"))
  (org-roam-dailies-capture-templates
   `(("d" "daily" plain (file "/Users/gopar/.emacs.d/org/templates/dailies-daily.template")
      :target (file+head "daily/%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))

     ("w" "weekly" plain (file "/Users/gopar/.emacs.d/org/templates/dailies-weekly.template")
      :target (file+head "weekly/%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))

     ("m" "monthly" plain (file "/Users/gopar/.emacs.d/org/templates/dailies-monthly.template")
      :target (file+head "monthly/%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))))

  :bind (:map global-map
              (("C-c n i" . org-roam-node-insert)
               ("C-c n f" . org-roam-node-find)
               ("C-c n g" . org-roam-graph)
               ("C-c n n" . org-roam-capture)
               ("C-c n d" . org-roam-dailies-capture-today)
               ("C-c n s" . consult-org-roam-search))))
(use-package org-modern
  :ensure t
  :after org
  :custom
  (org-modern-hide-stars nil)
  (org-modern-fold-stars '(("" . "") ("" . "") ("" . "") ("" . "") ("" . "")))
  :hook
  (org-mode . org-modern-mode)
  (org-agenda-finalize . org-modern-agenda))

Org Modern Indent

(use-package org-modern-indent
  :ensure t
  :after org
  :vc (:url "https://github.com/jdtsmith/org-modern-indent/" :rev :newsest)
  :init
  (add-hook 'org-mode-hook #'org-modern-indent-mode 90))

Org Annotate File

;; Belongs from the org-contrib pkg?
(use-package org-annotate-file
  :ensure nil
  :load-path "lisp/org"
  :defer
  ;; :hook (prog-mode)
  :custom
  (org-annotate-file-add-search t)
  (org-annotate-file-storage-file (concat user-emacs-directory "var/.org-annotate-file.org"))
  :bind (:map prog-mode-map
              ("C-c C-s" . gopar/org-annotate-file)
         :map python-mode-map
              ("C-c C-s" . gopar/org-annotate-file)
         :map python-ts-mode-map
              ("C-c C-s" . gopar/org-annotate-file)
         :map web-mode-map
              ("C-c C-s" . gopar/org-annotate-file))
  :init
  (defun gopar/org-annotate-file (&optional arg)
    "Annotate current line.
When called with a prefix aurgument, it will open annotations file."
    (interactive "P")
    (require 'org-annotate-file)
    (let* ((root (projectile-project-root))
           (org-annotate-file-storage-file
            (if root
                (format "%s.org-annotate.org" root)
              org-annotate-file-storage-file)))
      (if arg
          (find-file org-annotate-file-storage-file)
        (org-annotate-file)))))

Org Misc

(defun gopar/daily-log ()
  "Insert a new daily log entry with the current date."
  (interactive)
  (goto-char (point-max))
  (org-insert-heading-respect-content)
  (insert (format-time-string "[%Y-%m-%d %a]") "\n")
  (insert "- Accomplishments:\n")
  (insert "  - Task 1\n")
  (insert "  - Task 2\n")
  (insert "- Challenges:\n")
  (insert "  - Issue 1\n")
  (insert "  - Issue 2\n")
  (insert "- Learnings:\n")
  (insert "  - Insight 1\n")
  (insert "  - Insight 2\n")
  (insert "- Plans for Tomorrow:\n")
  (insert "  - Task 1\n")
  (insert "  - Task 2\n"))

(defalias 'gopar/journal-eng-entry 'gopar/daily-log)

Eshell

Some of the following are stolen from https://github.com/manateelazycat/aweshell

(use-package eshell
  :ensure nil
  :defer t
  :hook ((eshell-directory-change . gopar/sync-dir-in-buffer-name)
         (eshell-mode . gopar/eshell-specific-outline-regexp)
         (eshell-mode . gopar/eshell-setup-keybinding)
         (eshell-banner-load . (lambda ()
                                 (setopt eshell-banner-message
                                       (concat (shell-command-to-string "fortune -s | cowsay") "\n\n"))))
         (eshell-mode . (lambda ()
                          (setq-local completion-styles '(basic)) ; maybe emacs21?
                          (setq-local corfu-count 10)
                          (setq-local corfu-auto nil)
                          (setq-local corfu-preview-current nil)
                          (setq-local completion-at-point-functions '(pcomplete-completions-at-point cape-file)))))
  :custom
  (eshell-scroll-to-bottom-on-input t)
  (eshell-highlight-prompt t)
  (eshell-history-size 1024)
  (eshell-hist-ignoredups t)
  (eshell-input-filter 'gopar/eshell-input-filter)
  (eshell-cd-on-directory t)
  (eshell-list-files-after-cd nil)
  (eshell-pushd-dunique t)
  (eshell-last-dir-unique t)
  (eshell-last-dir-ring-size 32)
  :config
  (advice-add #'eshell-add-input-to-history
                :around
                #'gopar/adviced-eshell-add-input-to-history)

  :init
  (defun gopar/eshell-setup-keybinding ()
    ;; Workaround since bind doesn't work w/ eshell??
    (define-key eshell-mode-map (kbd "C-c >") 'gopar/eshell-redirect-to-buffer)
    (define-key eshell-hist-mode-map (kbd "M-r") 'consult-history))

  (defun gopar/adviced-eshell-add-input-to-history (orig-fun &rest r)
      "Cd to relative paths aren't that useful in history. Change to absolute paths."
      (require 'seq)
      (let* ((input (nth 0 r))
             (args (progn
                     (set-text-properties 0 (length input) nil input)
                     (split-string input))))
        (if (and (equal "cd" (nth 0 args))
                 (not (seq-find (lambda (item)
                                  ;; Don't rewrite "cd /ssh:" in history.
                                  (string-prefix-p "/ssh:" item))
                                args))
                 (not (seq-find (lambda (item)
                                  ;; Don't rewrite "cd -" in history.
                                  (string-equal "-" item))
                                args)))
            (apply orig-fun (list (format "cd %s"
                                          (expand-file-name (concat default-directory
                                                                    (nth 1 args))))))
          (apply orig-fun r))))

  (defun gopar/eshell-input-filter (input)
    "Do not save on the following:
       - empty lines
       - commands that start with a space, `ls`/`l`/`lsd`"
    (and
     (eshell-input-filter-default input)
     (eshell-input-filter-initial-space input)
     (not (string-prefix-p "ls " input))
     (not (string-prefix-p "lsd " input))
     (not (string-prefix-p "l " input))))

  (defun eshell/cat-with-syntax-highlighting (filename)
    "Like cat(1) but with syntax highlighting.
Stole from aweshell"
    (let ((existing-buffer (get-file-buffer filename))
          (buffer (find-file-noselect filename)))
      (eshell-print
       (with-current-buffer buffer
         (if (fboundp 'font-lock-ensure)
             (font-lock-ensure)
           (with-no-warnings
             (font-lock-fontify-buffer)))
         (let ((contents (buffer-string)))
           (remove-text-properties 0 (length contents) '(read-only nil) contents)
           contents)))
      (unless existing-buffer
        (kill-buffer buffer))
      nil))
  (advice-add 'eshell/cat :override #'eshell/cat-with-syntax-highlighting)

  (defun gopar/sync-dir-in-buffer-name ()
    "Update eshell buffer to show directory path.
Stolen from aweshell."
    (let* ((root (projectile-project-root))
           (root-name (projectile-project-name root)))
      (if root-name
          (rename-buffer (format "*eshell %s* %s" root-name (s-chop-prefix root default-directory)) t)
        (rename-buffer (format "*eshell %s*" default-directory) t))))

  (defun gopar/eshell-redirect-to-buffer (buffer)
    "Auto create command for redirecting to buffer."
    (interactive (list (read-buffer "Redirect to buffer: ")))
    (insert (format " >>> #<%s>" buffer)))

(defun gopar/eshell-specific-outline-regexp ()
  (setq-local outline-regexp eshell-prompt-regexp)))
(use-package eshell-syntax-highlighting
  :ensure t
  :after eshell
  :hook (eshell-first-time-mode . eshell-syntax-highlighting-global-mode)
  :init
  (defface eshell-syntax-highlighting-invalid-face
    '((t :inherit diff-error))
    "Face used for invalid Eshell commands."
    :group 'eshell-syntax-highlighting))
(use-package eshell-git-prompt
  :after eshell
  :ensure t)

(use-package powerline-with-venv
  :ensure nil
  :after eshell-git-prompt
  :load-path "lisp/themes/powerline-with-venv"
  :config
  (add-to-list 'eshell-git-prompt-themes
               '(powerline-plus eshell-git-prompt-powerline-venv eshell-git-prompt-powerline-regexp))
  (eshell-git-prompt-use-theme 'powerline-plus))
(use-package capf-autosuggest
  :ensure t
  :hook ((eshell-mode . capf-autosuggest-mode))
  :custom
  (capf-autosuggest-dwim-next-line nil))
(use-package eshell-bookmark
  :ensure t
  :after eshell
  :hook (eshell-mode . eshell-bookmark-setup))

Python

Run on every fresh virtualenv install pip install jedi epc importmagic ruff mypy coverage pytest-cov pytest

I get some weird auto completion in inferior python shell mode when I leave the default completion function. Lets just have in buffer completion

(use-package python
  :ensure nil
  :bind (:map python-mode-map
              ("C-c C-p" . nil)
              ("C-c C-e" . nil)
              ("C-c C-s" . nil)
              ("C-c C-z" . gopar/run-python)
         :map python-ts-mode-map
              ("C-c C-p" . nil)
              ("C-c C-e" . nil)
              ("C-c C-s" . nil)
              ("C-c C-z" . gopar/run-python))
  :hook ((python-ts-mode . (lambda ()
                          (setq-local forward-sexp-function nil)
                          (make-local-variable 'python-shell-virtualenv-root)
                          (setq-local comment-inline-offset 2)
                          (setq-local completion-at-point-functions
                                      '(cape-file
                                        ;; python-completion-at-point
                                        gopar/cape-yasnippet-keyword-dabbrev
                                        gopar/cape-dict-only-in-strings
                                        gopar/cape-dict-only-in-comments
                                        ))))
         (inferior-python-mode . (lambda ()
                                   (setq-local completion-at-point-functions '(t)))))

  :init
  (defun gopar/run-python ()
    "Wrapper function for `run-python` that checks if the current project is a Django project."
    (interactive)
    (let* ((manage-directory (locate-dominating-file default-directory "manage.py"))
           (default-directory (or manage-directory default-directory)))
      (if manage-directory
          (run-python (format "python manage.py shell_plus" manage-directory) python-shell-dedicated 0)
        (run-python (python-shell-calculate-command) python-shell-dedicated 0))))
  :custom
  (python-shell-dedicated 'project)
  (python-shell-interpreter "python")
  (python-shell-interpreter-args "")
  (python-forward-sexp-function nil)
  (python-shell-completion-native-disabled-interpreters '("python" "pypy")))

Virtualenv

Handy mode that takes care of envs for me. Downside is that I have to explicitly set where to find venvs instead of auto finding them

(use-package virtualenvwrapper
  :ensure t
  :after eshell
  :hook (eshell-first-time-mode . venv-initialize-eshell))

Pyvenv

I’m keeping this function around since it’s convineint to be able to create venvs from `pyvenv-create` and then do `venv-workon` in dir locals.

(use-package pyvenv
  :ensure t
  :defer
  :commands (pyvenv-create)
  )
(use-package ruff-format
  :ensure t
  :defer
  :hook ((python-mode python-ts-mode) . gopar/enable-ruff-if-found)
  :init
  (defun gopar/enable-ruff-if-found ()
    "Format the current buffer using the 'ruff` program, if available."
    (interactive)
    (if (executable-find "ruff")
        (ruff-format-on-save-mode))))

Required Jedi to work properly

(use-package pydoc
  :ensure t
  :defer
  :bind (:map python-mode-map
              ("C-c C-d" . gopar/pydoc-at-point))
  :init
  (add-to-list 'display-buffer-alist
            '("^\\*pydoc" display-buffer-in-side-window
              (slot . 1)
              (side . right)
              (window-parameters . ((no-delete-other-windows . t)))
              (dedicated . t)
              ;; (window-width . 80)
              ))

  (defun gopar/pydoc-at-point ()
    "Display pydoc in a dedicated window.
Calling `gopar/pydoc-at-point' displays the pydoc in a new dedicated window.
Calling `C-u gopar/pydoc-at-point' closes the dedicated window."
    (interactive)
    (let ((default-directory (file-name-directory (buffer-file-name))))
      (if (not (eq current-prefix-arg nil))
          (when (get-buffer-window "*pydoc*")
            (delete-window (get-buffer-window "*pydoc*")))
        (pydoc-at-point)
        (set-window-dedicated-p (get-buffer-window "*pydoc*") t)))))

Pip Requirements

(use-package pip-requirements
  :ensure t
  :defer
  :hook (pip-requirements-mode . (lambda () (focus-mode -1)))
  )

Kotlin

(use-package kotlin-mode :ensure t :defer)

Tree Sitter

(use-package treesit
  :ensure nil
  :defer
  :custom
  (treesit-font-lock-level 2))

Tree Sitter Auto Magic

(use-package treesit-auto
  :ensure t
  :hook (emacs-startup . global-treesit-auto-mode)
  :custom
  (treesit-auto-install 'prompt)
  :config
  (treesit-auto-add-to-auto-mode-alist 'all))

Flycheck Kotlin

(use-package flycheck-kotlin
  :ensure t
  :defer
  :hook (kotlin-mode . (lambda () (flycheck-mode 1) (flycheck-kotlin-setup))))

GUD (Debugger)

(use-package gud
  :ensure nil
  :defer
  :custom
  (gud-pdb-command-name "PYTHONBREAKPOINT=pdb.set_trace python -m pdb"))

Compile

(use-package compile
  :ensure nil
  :defer
  :custom
  (compilation-scroll-output 'first-error)
  (compilation-ask-about-save nil)
  (compilation-always-kill t)
  (compilation-max-output-line-length nil)
  (compilation-buffer-name-function 'gopar/compilation-buffer-name-function)
  :hook (compilation-mode . hl-line-mode)
  :config
  (defun gopar/compilation-buffer-name-function (compilation-mode)
    "Rename buffer to whatever command was used.
eg. *python main.py*"
    (concat "*" (downcase compilation-mode)
          (when (projectile-project-p) (concat " " (projectile-project-name))) "* "
          compile-command))

  ; from enberg on #emacs
  (add-hook 'compilation-finish-functions
            (lambda (buf str)
              (if (null (string-match ".*exited abnormally.*" str))
                  ;;no errors, make the compilation window go away in a few seconds
                  (progn
                    (run-at-time
                     "1 sec" nil 'delete-windows-on
                     (buffer-name))
                    (message "No Compilation Errors!"))))))
(use-package fancy-compilation
  :ensure t
  :after compile
  :config
  (fancy-compilation-mode)
  :custom
  (fancy-compilation-override-colors nil)
  (fancy-compilation-scroll-output 'first-error))

For TDD development

(use-package recompile-on-save
  :ensure t
  :after compile
  :config
  (recompile-on-save-advice compile)
  :init
  ;; Hide the buffer message that pops up after running advice on compile
  (add-to-list 'display-buffer-alist
             '("^\\*Compile-Log"
               (display-buffer-no-window)
               (allow-no-window . t))))

Winner

Window Management

(use-package winner
  :ensure nil
  :commands (winner-undo winner-redo)
  :hook emacs-startup
  :custom
  (winner-boring-buffers '("*Completions*" "*Help*" "*Apropos*"
                           "*Buffer List*" "*info*" "*Compile-Log*")))

Window

(use-package window
  :ensure nil
  :defer
  :custom
  (recenter-positions '(middle top bottom)))

Frame

(use-package frame
  :ensure nil
  :defer
  :hook (emacs-startup . window-divider-mode)
  :custom-face
  (window-divider ((t (:foreground "gold"))))
  :custom
  (window-divider-default-places t))

Midnight

(use-package midnight
  :ensure nil
  :defer 30
  :custom
  (clean-buffer-list-delay-general 0)
  (clean-buffer-list-delay-special 0)
  (clean-buffer-list-kill-regexps '("\\`\\*Man " "\\`\\*helpful" "\\`\\magit")))

Executeable

(use-package executable
  :ensure nil
  :defer
  :hook (after-save . executable-make-buffer-file-executable-if-script-p))

Jinx Spelling

If on new system, might need to install enchant and pkg-config

(use-package jinx
  :ensure t
  :defer
  :hook (after-init . global-jinx-mode)
  :bind (("C-." . jinx-correct)
         ("C-," . jinx-next)
         :map jinx-mode-map
         ("M-$" . nill)
         ))

Dictionary

Look up word at point using dict.org in readme/text/org-mode buffers

(use-package dictionary
  :defer
  :ensure nil
  :bind (:map text-mode-map
              ("M-." . dictionary-lookup-definition)
         :map org-mode-map
              ("M-." . dictionary-lookup-definition)
         :map dictionary-mode-map
              ("M-." . dictionary-lookup-definition)
         :map eww-mode-map
         ("M-." . dictionary-lookup-definition))
  :init
  (add-to-list 'display-buffer-alist
               '("^\\*Dictionary\\*" display-buffer-in-side-window
                 (side . left)
                 (window-width . 50)))
  :custom
  (dictionary-server "dict.org"))

Minibuffer

(use-package minibuffer
  :ensure nil
  :defer t)

Time

(use-package time
  :ensure nil
  :defer t
  :custom
  (world-clock-time-format "%A %d %B %r %Z")
  (display-time-day-and-date t)
  (display-time-default-load-average nil)
  (display-time-mail-string "")
  (zoneinfo-style-world-list
  '(("America/Los_Angeles" "Sacramento, CA")
    ("America/New_York" "Buffalo, NY")
    ("America/Chicago" "Tulsa, OK")
    ("America/Chicago" "Chicago, IL")
    ("Asia/Tokyo" "Tokyo")
    ("Europe/Madrid" "Barcelona"))))

Proced

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

Browse URL

(use-package browse-url
  :ensure nil
  :defer t
  :custom
  ;; Emacs can't find browser binaries
  (browse-url-chrome-program "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
  (browse-url-firefox-program "/Applications/Firefox.app/Contents/MacOS/firefox")
  ;; Neat trick to open that route to different places
  (browse-url-firefox-new-window-is-tab t)
  ;; Default to using eww for browsing
  (browse-url-browser-function 'eww-browse-url)
  (browse-url-handlers '(;; Work urls
                         ("teams\\.microsoft\\.com"  . browse-url-chrome)
                         ("outlook\\.office365\\.com" . browse-url-chrome)
                         ("*.\\.atlassian\\.net" . browse-url-chrome)
                         ;; Anything with summit will be considered work related
                         ("summit" . browse-url-chrome)
                         ;; Personal urls
                         (".*youtube\\.com"        . browse-url-firefox)
                         (".*"                    . eww-browse-url)))
  :config
  (put 'browse-url-handlers 'safe-local-variable (lambda (x) t))
  (put 'browse-url-browser-function 'safe-local-variable (lambda (x) t)))

Eww

(use-package eww
  :defer t
  :hook (eww-after-render . shrface-mode)
  :custom
  (eww-auto-rename-buffer 'title)
  (eww-browse-url-new-window-is-tab nil)
  :config
  (require 'shrface))

Ewnium

(use-package ewnium
  :ensure nil
  :defer
  :load-path "lisp/eww"
  :hook (eww-mode . ewnium-mode))

SHR

(use-package shrface
  :ensure t
  :defer t
  :bind (:map eww-mode-map
              ("M-g o" . shrface-headline-consult)
              ("C-c C-o" . shrface-occur))
  :config
  (shrface-basic)
  (shrface-trial)
  ;; (shrface-default-keybindings)
  (setopt shrface-href-versatile t))
(use-package shr-tag-pre-highlight
  :ensure t
  :after shr
  :config
  (add-to-list 'shr-external-rendering-functions
               '(pre . shr-tag-pre-highlight)))

Prog Mode

(use-package prog-mode
  :ensure nil
  :defer
  :hook ((prog-mode . subword-mode)
         (prog-mode . hl-line-mode)
         (prog-mode . (lambda () (setq-local fill-column 120)))))

Which Function

(use-package which-func
  :ensure nil
  :defer
  :hook (prog-mode . which-function-mode))

Projectile

(use-package projectile
  :ensure
  :defer t
  :commands (projectile-project-root projectile-switch-project)
  ;; :hook (after-init . projectile-mode)
  :bind-keymap
  ("C-c p" . projectile-command-map)
  :bind (:map projectile-command-map
              ("x a" . gopar/projectile-run-aider)
              ("b" . consult-project-buffer)
              ("s r" . consult-ripgrep)
              ("s g" . consult-grep))

  :custom
  (projectile-indexing-method 'hybrid)  ;; Not sure if this still needed?
  (projectile-per-project-compilation-buffer nil)
  :config
  (setq frame-title-format '(:eval (if (projectile-project-root) (projectile-project-root) "%b")))
  (advice-add 'projectile--run-project-cmd :override #'gopar/projectile--run-project-cmd)

  (defun gopar/projectile-run-aider (&optional arg)
    (interactive "P")
    (gopar/projectile--aider arg t))

  (defun gopar/projectile--aider (&optional new-process other-window)
    "Invoke `aider' in the project's root.

Use argument NEW-PROCESS to indicate creation of a new process instead.
Use argument OTHER-WINDOW to indentation whether the buffer should
be displayed in a different window.

Switch to the project specific term buffer if it already exists."
    (let* ((project (projectile-acquire-root))
           (buffer (projectile-generate-process-name "aider" new-process project))
           (vterm-buffer-name-string nil))
      (unless (require 'vterm nil 'noerror)
        (error "Package 'vterm' is not available"))
      (if (buffer-live-p (get-buffer buffer))
          (if other-window
              (switch-to-buffer-other-window buffer)
            (switch-to-buffer buffer))
        (projectile-with-default-dir project
          (if other-window
              (vterm-other-window buffer)
            (vterm buffer))

          (vterm-send-string
           (mapconcat 'identity
                      `("aider"
                        "--architect"
                        "--model"
                        "claude-3-7-sonnet-latest"
                        "--editor-model"
                        "claude-3-5-sonnet-latest"
                        "--weak-model"
                        "claude-3-5-haiku-latest"
                        ;; "--no-auto-accept-architect"
                        "--analytics-disable"
                        "--no-auto-commits"
                        "--no-dirty-commits"
                        "--no-attribute-author"
                        "--no-attribute-committer"
                        "--no-auto-lint"
                        ;; "--cache-prompts"
                        ;; "--no-stream"
                        "--watch-files"
                        "--notifications"
                        "--notifications-command \"say 'Aider is ready'\""
                        ,(if (file-exists-p (concat project "CONVENTIONS.md"))
                            (concat "--read " project "CONVENTIONS.md")
                          ""))
                      " "))
        (vterm-send-return)))))

  ;; :init
  ;; Redefinig with my changes since projectil overwrites `compilation-buffer-name-function`
  (cl-defun gopar/projectile--run-project-cmd
      (command command-map &key show-prompt prompt-prefix save-buffers use-comint-mode)
    "Run a project COMMAND, typically a test- or compile command.

Cache the COMMAND for later use inside the hash-table COMMAND-MAP.

Normally you'll be prompted for a compilation command, unless
variable `compilation-read-command'.  You can force the prompt
by setting SHOW-PROMPT.  The prompt will be prefixed with PROMPT-PREFIX.

If SAVE-BUFFERS is non-nil save all projectile buffers before
running the command.

The command actually run is returned."
    (let* ((project-root (projectile-project-root))
           (default-directory (projectile-compilation-dir))
           (command (projectile-maybe-read-command show-prompt
                                                   command
                                                   prompt-prefix)))
      (when command-map
        (puthash default-directory command command-map)
        (let ((hist (projectile--get-command-history project-root)))
          (cond
           ((eq projectile-cmd-hist-ignoredups t)
            (unless (string= (car-safe (ring-elements hist)) command)
              (ring-insert hist command)))
           ((eq projectile-cmd-hist-ignoredups 'erase)
            (let ((idx (ring-member hist command)))
              (while idx
                (ring-remove hist idx)
                (setq idx (ring-member hist command))))
            (ring-insert hist command))
           (t (ring-insert hist command)))))
      (when save-buffers
        (save-some-buffers (not compilation-ask-about-save)
                           (lambda ()
                             (projectile-project-buffer-p (current-buffer)
                                                          project-root))))
      (when projectile-per-project-compilation-buffer
        (setq compilation-buffer-name-function #'projectile-compilation-buffer-name)
        (setq compilation-save-buffers-predicate #'projectile-current-project-buffer-p))
      (unless (file-directory-p default-directory)
        (mkdir default-directory))
      (projectile-run-compilation command use-comint-mode)
      command))
  )

Repeat Mode

Allows repeating via `C-x z` (pressing z multiple times keeps repeating) or by pressing last keybinding of previous command

(use-package repeat
  :ensure nil
  :hook (after-init . repeat-mode)
  :custom
  (repeat-too-dangerous '(kill-this-buffer))
  (repeat-exit-timeout 5))

Save Place

(use-package saveplace
  :ensure nil
  :hook (after-init . save-place-mode))

Save History

(use-package savehist
  :ensure nil
  :hook (after-init . savehist-mode)
  :custom
  (savehist-additional-variables '(abbrev-minor-mode-table-alist)))

Grep

(use-package grep
  :ensure nil
  :defer
  :config
  (setopt grep-find-ignored-directories (append grep-find-ignored-directories '(".mypy_cache" ".pytest_cache" "htmlcov"))))

ripgrep (rg)

(use-package rg
  :ensure t
  :defer
  :hook (rg-mode . rg-save-search))

wgrep

(use-package wgrep-ag :ensure t :defer)

Code Completion

A collection of packages that act as ‘smart’ completion in which really are not :) Also includes displaying of them

(use-package vertico
  :ensure t
  :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)
  :init
  (vertico-mode)
  (setopt vertico-cycle t))

(use-package vertico-multiform
  :ensure nil
  :hook (after-init . vertico-multiform-mode)
  :init
  (setopt vertico-multiform-commands
          '((consult-line (:not posframe))
            (consult-xref (:not posframe))
            (gopar/consult-line (:not posframe))
            (consult-line-thing-at-point (:not posframe))
            (consult-ag (:not posframe))
            (consult-ripgrep (:not posframe))
            (consult-grep (:not posframe))
            (consult-imenu (:not posframe))
            (consult-outline (:not posframe))
            (consult-yank-pop (:not posframe))
            (consult-imenu-multi (:not posframe))
            (consult-yasnippet (:not posframe))
            (t posframe))))

;; just for looks
(use-package vertico-posframe
  :ensure t
  :hook (after-init . vertico-posframe-mode)
  :custom
  (vertico-posframe-parameters
   '((left-fringe . 8)
     (right-fringe . 8))))

(use-package dabbrev
  :defer t
  :custom
  (dabbrev-upcase-means-case-search t)
  (dabbrev-check-all-buffers nil)
  (dabbrev-check-other-buffers t)
  (dabbrev-friend-buffer-function 'dabbrev--same-major-mode-p)
  (dabbrev-ignored-buffer-regexps '("\\.\\(?:pdf\\|jpe?g\\|png\\)\\'")))

(use-package corfu
  :ensure t
  ;; Originally, I liked the idea of `corfu-send` but this makes it behave
  ;; in way that is different from 'fish' shell. So lets disable and see
  ;; how we feel about it in the future
  ;; :bind (:map corfu-map
  ;;             ("RET" . corfu-send))
  :custom
  (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  (corfu-auto t)                 ;; Enable auto completion
  (corfu-on-exact-match 'insert) ;; Insert when there's only one match
  (corfu-quit-no-match t)        ;; Quit when ther is no match
  :init
  (global-corfu-mode)

  (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)
                (bound-and-true-p vertico--input)
                (eq (current-local-map) read-passwd-map))
      ;; (setq-local corfu-auto nil) ;; Enable/disable auto completion
      (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
                  corfu-popupinfo-delay nil)
      (corfu-mode 1)))

  (add-hook 'minibuffer-setup-hook #'corfu-enable-always-in-minibuffer 1))

(use-package cape
  :ensure t
  :bind ("C-c SPC" . cape-dabbrev)
  :custom
  (cape-dict-case-replace nil)
  :init
  (setopt cape-dabbrev-min-length 2
          cape-dabbrev-check-other-buffers 'cape--buffers-major-mode)

  (defun gopar/cape-dict-only-in-comments ()
    (cape-wrap-inside-comment 'cape-dict))

  (defun gopar/cape-dict-only-in-strings ()
    (cape-wrap-inside-string 'cape-dict))

  (defun gopar/cape-yasnippet-keyword-dabbrev ()
    (cape-wrap-super #'yasnippet-capf #'cape-keyword #'cape-dabbrev))

  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'gopar/cape-yasnippet-keyword-dabbrev)
  (add-to-list 'completion-at-point-functions #'gopar/cape-dict-only-in-strings)
  (add-to-list 'completion-at-point-functions #'gopar/cape-dict-only-in-comments))

(use-package orderless
  :ensure t
  :after consult
  :custom
  (completion-styles '(orderless basic initials flex))
  (completion-category-overrides '((file (styles basic partial-completion)))))

(use-package consult
  :ensure
  :commands (gopar/consult-line consult-buffer consult-bookmark consult-theme consult-line-thing-at-point)
  :bind (("C-s" . gopar/consult-line)
         ("C-c m" . consult-man)
         ("C-c i" . consult-info)
         ("C-c M-x" . consult-mode-command)
         ;; C-x bindings in `ctl-x-map'
         ("C-x b" . consult-buffer)                ;; orig. switch-to-buffer
         ("C-x M-:" . consult-complex-command)     ;; orig. repeat-complex-command
         ("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
         ("C-x t b" . consult-buffer-other-tab)    ;; orig. switch-to-buffer-other-tab
         ("C-x r b" . consult-bookmark)
         ("C-x r s" . consult-register-store)
         ("C-x r i" . consult-register)

         ;; Custom M-# bindings for fast register access
         ("M-#" . consult-register-load)
         ("M-'" . consult-register-store)          ;; orig. abbrev-prefix-mark (unrelated)
         ("C-M-#" . consult-register)

         ;; M-g bindings in `goto-map'
         ("M-g e" . consult-compile-error)
         ("M-g f" . consult-flycheck)               ;; Alternative: consult-flycheck
         ("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 in `search-map'
         ("M-s d" . consult-find)
         ("M-s c" . 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 k" . consult-keep-lines)
         ("M-s f" . consult-focus-lines)

         ;; Random bindings
         ("C-z" . consult-theme)
         ("M-y" . consult-yank-pop)

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

         :map minibuffer-local-map
         ("M-s" . consult-history)                 ;; orig. next-matching-history-element
         ("M-r" . consult-history))

  :config
  (setopt consult-project-function (lambda (_) (projectile-project-root)))
  (setopt xref-show-xrefs-function #'consult-xref
          xref-show-definitions-function #'consult-xref)
  (setopt consult-narrow-key "<")
  (setopt consult-line-start-from-top nil)
  (consult-customize
   consult-line
   :add-history (seq-some #'thing-at-point '(region symbol)))

  (defalias 'consult-line-thing-at-point 'consult-line)

  (consult-customize
   consult-line-thing-at-point
   :initial (thing-at-point 'symbol))

  (defun gopar/consult-line (&optional arg)
    "Start consult search with selected region if any.
If used with a prefix, it will search all buffers as well."
    (interactive "p")
    (let ((cmd (if current-prefix-arg '(lambda (arg) (consult-line-multi t arg)) 'consult-line)))
      (if (use-region-p)
          (let ((regionp (buffer-substring-no-properties (region-beginning) (region-end))))
            (deactivate-mark)
            (funcall cmd regionp))
        (funcall cmd "")))))

(use-package consult-flycheck :ensure t :defer t :commands consult-flycheck)

(use-package consult-org-roam
  :ensure t
  :after org-roam
  :custom
  (consult-org-roam-grep-func #'consult-ripgrep)
  ;; Configure a custom narrow key for `consult-buffer'
  (consult-org-roam-buffer-narrow-key ?r)
  ;; Display org-roam buffers right after non-org-roam buffers
  ;; in consult-buffer (and not down at the bottom)
  (consult-org-roam-buffer-after-buffers nil)
  :config
  ;; Eventually suppress previewing for certain functions
  (consult-customize
   consult-org-roam-forward-links
   :preview-key (kbd "M-.")))

(use-package marginalia
  :ensure
  :init
  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode))

;; (use-package embark
;;   :ensure t
;;   :defer
;;   :bind (("C-." . embark-act)))

;; (use-package embark-consult
;;   :ensure t
;;   :after embark)

pcomplete

(use-package pcmpl-args
  :ensure t
  :hook (eshell-first-time-mode . gopar/add-pcmpl-custom-commands)
  :init
  (defun gopar/add-pcmpl-custom-commands ()
                                     (dolist (command '("lsd" "pip3" "docker" "docker-compose" "ffmpeg"))
                                       (let ((alias-name (intern (concat "pcomplete/" command))))
                                         (eval `(defalias ',alias-name 'pcmpl-args-pcomplete-on-help))))

                                     (dolist (command '())
                                       (let ((alias-name (intern (concat "pcomplete/" command))))
                                         (eval `(defalias ',alias-name 'pcmpl-args-pcomplete-on-man))))

                                     (defalias 'pcomplete/pip 'pcomplete/pip3)))

(use-package pcmpl-homebrew :ensure t :after eshell)

Dumb Jump

A basic ‘go to’ functionality that works really well. So I don’t need LSP

(use-package dumb-jump
  :ensure t
  :defer
  :custom
  (dumb-jump-prefer-searcher 'ag)
  (dumb-jump-force-searcher 'ag)
  (dumb-jump-selector 'completing-read)
  (dumb-jump-default-project "~/work")
  :init
  (add-hook 'xref-backend-functions #'dumb-jump-xref-activate))

Xref

(use-package xref
  :ensure nil
  :defer t
  :init
  (defun gopar/xref-backend-html-template ()
    "Xref backend for jumping to HTML template definitions."
    (when (and (thing-at-point 'filename t) (string-suffix-p ".html" (thing-at-point 'filename t)))
      'gopar-html-template))

  (cl-defmethod xref-backend-identifier-at-point ((_backend (eql gopar-html-template)))
    (thing-at-point 'filename t))

  (cl-defmethod xref-backend-definitions ((_backend (eql gopar-html-template)) identifier)
    (let ((path (cl-find-if (lambda (x) (string-match-p identifier x))
                            (projectile-project-files (projectile-project-root)))))
      (when path
        (list (xref-make identifier (xref-make-file-location (format "%s%s" (projectile-project-root) path) 1 0))))))
  (add-hook 'xref-backend-functions #'gopar/xref-backend-html-template))

Eglot

(use-package eglot
  :ensure t
  :defer
  :hook
  (eglot-managed-mode . (lambda ()
                          (setq xref-backend-functions '(gopar/xref-backend-html-template eglot-xref-backend dumb-jump-xref-activate t))))
  :bind (:map projectile-command-map
              ("R" . eglot-rename))
  :config
  (add-to-list 'eglot-stay-out-of 'flymake))

Web Mode

(use-package web-mode
  :ensure t
  :defer
  :init
  (setq-default web-mode-code-indent-offset 2)
  (setopt web-mode-engines-alist '(("django"    . "\\.html\\'")))
  (setq web-mode-content-types-alist '(("jsx"  . "\\.js[x]?\\'")))
  (setopt web-mode-extra-snippets
      '(("django" . (("ifelif"  . "{% if | %}\n\n{% elif %}\n\n{% else %}\n\n{% endif %}")
                     ("ifelse"  . "{% if | %}\n\n{% else %}\n\n{% endif %}")
                     ("include" . "{% include \"|\" %}")
                     ("extends" . "{% extends \"|\" %}")))))

  :hook (web-mode . (lambda ()
                      (highlight-indentation-mode -1)
                      (electric-pair-local-mode -1)))
  :custom
  (web-mode-script-padding 0)
  (web-mode-enable-html-entities-fontification t)
  (web-mode-enable-element-content-fontification t)
  (web-mode-enable-current-element-highlight t)
  (web-mode-enable-current-column-highlight t)
  (web-mode-markup-indent-offset 2)
  (web-mode-css-indent-offset 2)
  (web-mode-sql-indent-offset 2)
  :mode (;; ("\\.vue\\'" . web-mode)
         ("\\.html\\'" . web-mode)
         ("\\.js[x]?\\'" . web-mode)
         ))

Emmet-mode

(use-package emmet-mode
  :ensure t
  :defer t
  :config
  (defun emmet-jsx-supported-mode? ()
    "Is the current mode we're on enabled for jsx class attribute expansion?"
    (or (member major-mode emmet-jsx-major-modes)
        (and (string= major-mode "web-mode") (string= web-mode-content-type "jsx"))))
  :hook (web-mode . emmet-mode))

TypeScript

(use-package typescript-mode
  :ensure t
  :defer
  :bind (:map typescript-mode-map
              (";" . easy-camelcase))
  :custom
  (typescript-indent-level 2))

Markdown

(use-package markdown-mode
  :defer t
  :ensure t
  :bind (:map markdown-mode-map
              ("M-." . dictionary-lookup-definition)))

Dockerfile

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

YAML

(use-package yaml-mode
  :ensure t
  :defer)

Rainbow mode

Color the string of whatever color code they are holding

(use-package rainbow-mode
  :defer
  :ensure t
  :hook (prog-mode . rainbow-mode))

Alert

(use-package alert
  :ensure t
  :defer
  :custom
  (alert-default-style 'message)
  (alert-fade-time 5))

Which Key

(use-package which-key
  :ensure nil
  :hook (after-init . which-key-mode)
  :custom
  (which-key-idle-delay 2))

Helpful

(use-package helpful
  :ensure t
  :hook (helpful-mode . view-mode)
  :defer
  :bind (("C-h f" . helpful-callable)
         ("C-h v" . helpful-variable)
         ("C-h k" . helpful-key)))

Corral

(use-package corral
  :ensure t
  :defer
  :bind (("M-9" . corral-parentheses-backward)
         ("M-0" . corral-parentheses-forward)
         ("M-[" . corral-brackets-backward)
         ("M-]" . corral-brackets-forward)
         ("M-\"" . corral-single-quotes-backward)
         ("M-'" . corral-single-quotes-forward)))

Highlight Indentation

(use-package highlight-indentation
  :ensure t
  :defer
  :hook ((prog-mode . highlight-indentation-mode)
         (prog-mode . highlight-indentation-current-column-mode)))

Highlight TODO

(use-package hl-todo
  :ensure t
  :defer t
  :hook (prog-mode . hl-todo-mode))

Move Text

(use-package move-text
  :ensure t
  :defer
  :init (move-text-default-bindings))

Iedit

(use-package iedit
  :ensure t
  :defer
  :commands iedit-mode
  :bind (("C-c o" . iedit-mode))
  :custom
  (iedit-toggle-key-default (kbd "C-c o"))
  (iedit-auto-narrow t)
  (iedit-auto-save-occurrence-in-kill-ring nil))

Expand Region

(use-package expand-region
  :ensure t
  :defer
  :bind (("C-\\" . er/expand-region)))

So Long

(use-package so-long
  :ensure nil
  :hook (after-init . global-so-long-mode))

Avy

(use-package avy
  :ensure t
  :defer
  :bind (("M-g c" . avy-goto-char-2)
         ("M-g g" . avy-goto-line)
         ("M-g w" . avy-goto-word-1)))

All The Icons

(use-package all-the-icons
  :ensure t
  :defer
  :if (display-graphic-p))

(use-package all-the-icons-completion
  :ensure t
  :defer
  :hook (marginalia-mode . #'all-the-icons-completion-marginalia-setup)
  :init
  (all-the-icons-completion-mode))

Ibuffer

;; Ibuffer Icons sets it's own local buffer format and overrides the =ibuffer-formats= variable.
;; So in order for ibuffer-vc to work, I have to include it in the icons-buffer format -_-
(use-package all-the-icons-ibuffer
  :ensure t
  :defer
  :custom
  (all-the-icons-ibuffer-formats
   `((mark modified read-only locked vc-status-mini
           ;; Here you may adjust by replacing :right with :center or :left
           ;; According to taste, if you want the icon further from the name
           " " ,(if all-the-icons-ibuffer-icon
                    '(icon 2 2 :left :elide)
                  "")
           ,(if all-the-icons-ibuffer-icon
                (propertize " " 'display `(space :align-to 8))
              "")
           (name 18 18 :left :elide)
           " " (size-h 9 -1 :right)
           " " (mode+ 16 16 :left :elide)
           " " (vc-status 16 16 :left)
           " " vc-relative-file)
     (mark " " (name 16 -1) " " filename)))

  :hook (ibuffer-mode . all-the-icons-ibuffer-mode))

;; https://github.com/purcell/ibuffer-vc/blob/master/ibuffer-vc.el
(use-package ibuffer-vc
  :ensure t
  :defer
  :hook (ibuffer . (lambda ()
                     (ibuffer-vc-set-filter-groups-by-vc-root)
                     (unless (eq ibuffer-sorting-mode 'alphabetic)
                       (ibuffer-do-sort-by-vc-status)
                       ;; (ibuffer-do-sort-by-alphabetic)
                       )
                     )))

Webjump

(use-package webjump
  :defer
  :ensure nil
  :bind ("C-x /" . webjump)
  :config
  (setopt webjump-sites '(("DuckDuckGo" . [simple-query "html.duckduckgo.com" "html.duckduckgo.com/html?q=" ""])
                          ("Django Query" . [simple-query "html.duckduckgo.com" "html.duckduckgo.com/html?q=django+" ""])
                          ("Django Rest Framework DRF" . "https://www.django-rest-framework.org/")
                          ("Django Classy Docs" . [simple-query "https://ccbv.co.uk/" "https://duckduckgo.com/?q=" "+site%3Ahttps%3A%2F%2Fccbv.co.uk&t=h_&ia=web" ])
                          ("DRF Classy Docs" . [simple-query "https://www.cdrf.co/" "https://duckduckgo.com/?t=h_&q=" "+site%3Ahttps%3A%2F%2Fwww.cdrf.co%2F"])))
  :config
  ;; Redefine read string so that we can have pre selected input
  (defun webjump-read-string (prompt)
    (let ((input (read-string (concat prompt ": ") (if (use-region-p) (buffer-substring-no-properties (region-beginning) (region-end)) nil))))
      (if (webjump-null-or-blank-string-p input) nil input))))

RFC Browsing

(use-package rfc-mode
  :defer
  :ensure t)

Electric Pair

(use-package elec-pair
  :ensure nil
  :defer
  :hook (after-init . electric-pair-mode))

Version Control

(use-package magit
  :ensure t
  :commands magit-get-current-branch
  :defer
  :bind ("C-x g" . magit)
  :hook (magit-mode . magit-wip-mode)
  :custom
  (magit-diff-refine-hunk 'all)
  (magit-process-finish-apply-ansi-colors t)
  (magit-format-file-function #'magit-format-file-all-the-icons)
  :init
  (setopt magit-process-finish-apply-ansi-colors t)
  (defun magit/undo-last-commit (number-of-commits)
    "Undoes the latest commit or commits without loosing changes"
    (interactive "P")
    (let ((num (if (numberp number-of-commits)
                   number-of-commits
                 1)))
      (magit-reset-soft (format "HEAD^%d" num)))))

;; Part of magit
(use-package git-commit
  :ensure nil
  :after magit
  :hook (git-commit-setup . gopar/auto-insert-jira-ticket-in-commit-msg)
  :custom
  (git-commit-summary-max-length 80)
  :init
  (defun gopar/auto-insert-jira-ticket-in-commit-msg ()
    (let ((has-ticket-title (string-match "^[A-Z]+-[0-9]+" (magit-get-current-branch)))
          (words (s-split-words (magit-get-current-branch))))
      (if has-ticket-title
          (insert (format "[%s-%s] " (car words) (car (cdr words))))))))

(use-package git-gutter
  :ensure t
  :hook (after-init . global-git-gutter-mode))

Parens

(use-package paren
  :ensure nil
  :hook (after-init . show-paren-mode)
  :custom
  (show-paren-style 'mixed)
  (show-paren-context-when-offscreen t))

Battery

(use-package battery
  :ensure nil
  :hook (after-init . display-battery-mode))

Yasnippet

;; After adding or updating a snippet run:
;; =M-x yas-recompile-all=
;; =M-x yas-reload-all=
(use-package yasnippet
  :ensure t
  :defer
  :hook ((prog-mode . yas-minor-mode)
         (org-mode . yas-minor-mode)
         (fundamental-mode . yas-minor-mode)
         (text-mode . yas-minor-mode)
         (eshell-mode . yas-minor-mode)
         ;; (after-init . yas-reload-all)
         ))

Actual Snippets

(use-package yasnippet-snippets
  :ensure t
  :defer)

To use as a super capf with a few others

(use-package yasnippet-capf
  :ensure t
  :defer t
  :vc (:url "https://github.com/elken/yasnippet-capf" :rev :newsest)
  )

Consult Yasnippet

(use-package consult-yasnippet
  :ensure t
  :after yasnippet
  :bind (:map yas-minor-mode-map
              ("C-c C-SPC" . consult-yasnippet)))
(use-package dashboard
  :ensure t
  :custom
  (dashboard-startup-banner 'logo)
  (dashboard-center-content t)
  (dashboard-show-shortcuts nil)
  (dashboard-set-heading-icons t)
  (dashboard-icon-type 'all-the-icons)
  (dashboard-set-file-icons t)
  (dashboard-projects-backend 'projectile)
  (dashboard-items '(
                     (vocabulary)
                     (recents . 5)
                     (bookmarks . 5)
                     ;; (monthly-balance)
                     ))
  (dashboard-item-generators '(;; (monthly-balance . gopar/dashboard-ledger-monthly-balances)
                              (vocabulary . gopar/dashboard-insert-vocabulary)
                              (recents . dashboard-insert-recents)
                              (bookmarks . dashboard-insert-bookmarks)
                              ))
  :init
  (defun gopar/dashboard-insert-vocabulary (list-size)
    (dashboard-insert-heading "Word of the Day:"
                              nil
                              (all-the-icons-faicon "newspaper-o"
                                                    :height 1.2
                                                    :v-adjust 0.0
                                                    :face 'dashboard-heading))
    (insert "\n")
    (let ((random-line nil)
          (lines nil))
      (with-temp-buffer
        (insert-file-contents (concat user-emacs-directory "words"))
        (goto-char (point-min))
        (setq lines (split-string (buffer-string) "\n" t))
        (setq random-line (nth (random (length lines)) lines))
        (setq random-line (string-join (split-string random-line) " ")))
      (insert "    " random-line)))

  (defun gopar/dashboard-ledger-monthly-balances (list-size)
    (interactive)
    (dashboard-insert-heading "Monthly Balance:"
                              nil
                              (all-the-icons-faicon "money"
                                                    :height 1.2
                                                    :v-adjust 0.0
                                                    :face 'dashboard-heading))
    (insert "\n")
    (let* ((categories '("Expenses:Food:Restaurants"
                         "Expenses:Food:Groceries"
                         "Expenses:Misc"))
           (current-month (format-time-string "%Y/%m"))
           (journal-file (expand-file-name "~/personal/finances/main.dat"))
           (cmd (format "ledger bal --flat --monthly --period %s %s -f %s"
                        current-month
                        (mapconcat 'identity categories " ")
                        journal-file)))

      (insert (shell-command-to-string cmd))))
  :config
  (dashboard-setup-startup-hook))

Display Fill Column

Collides with compact-docstrings so turning off for programming modes

(use-package display-fill-column-indicator
  :ensure nil
  :hook (;; (python-mode . display-fill-column-indicator-mode)
         (org-mode . display-fill-column-indicator-mode))
  )

Dired

(use-package dired
  :ensure nil
  :defer
  :hook ((dired-mode . dired-hide-details-mode)
         (dired-mode . hl-line-mode))
  :custom
  (dired-do-revert-buffer t)
  (dired-auto-revert-buffer t)
  (delete-by-moving-to-trash t)
  (dired-mouse-drag-files t)
  (dired-dwim-target t)
  ;; (dired-guess-shell-alist-user)
  (dired-listing-switches "-AlhoF --group-directories-first"))

(use-package all-the-icons-dired
  :ensure t
  :defer
  :hook (dired-mode . all-the-icons-dired-mode)
  :custom
  (all-the-icons-dired-monochrome nil))

(use-package files
  :ensure nil
  :defer t
  :custom
  (insert-directory-program "gls") ; Will not work if system does not have GNU gls installed
  ;; Don't have backup
  (backup-inhibited t)
  ;; Don't save anything.
  (auto-save-default nil)
  ;; If file doesn't end with a newline on save, automatically add one.
  (require-final-newline t)
  ;; Switch to view-mode when in read-only mode
  (view-read-only t)
  :config
  (add-to-list 'auto-mode-alist '("Pipfile" . conf-toml-mode)))

Dired Subtree

(use-package dired-subtree
  :ensure t
  :after dired
  :bind (:map dired-mode-map
              ("<tab>" . dired-subtree-toggle)
              ("<C-tab>" . dired-subtree-cycle)
              ("<backtab>" . dired-subtree-remove) ;; Shift + Tab
              ))

Replace/Occur

(use-package replace
  :ensure nil
  :defer
  :custom
  (list-matching-lines-default-context-lines 0)
  (list-matching-lines-face nil)
  :bind (("C-c C-o" . gopar/occur-definitions)
         :map occur-mode-map
         ("n" . occur-next)
         ("p" . occur-prev))
  :init
  (add-to-list 'display-buffer-alist
               '("\\*Occur"
                 display-buffer-in-side-window
                 (side . left)
                 (slot . 1)
                 (dedicated . t)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (window-width . 30)))

  (defun gopar/occur-definitions ()
    "Show all the function/method/class definitions for the current language."
    (interactive)
    (cond
     ((eq major-mode 'emacs-lisp-mode)
      (occur "\(defun"))
     ((or (eq major-mode 'python-mode) (eq major-mode 'python-ts-mode))
      (occur "^\s*\\(\\(async\s\\|\\)def\\|class\\)\s"))
     ;; If no matching, then just do regular occur
     (t (call-interactively 'occur)))))

Occur-x

Only really used to remove lines to the right of margin.

Can honestly just rip out relevant part to remove lines vs installing this library

(use-package occur-x
  :ensure t
  :hook (occur-mode . turn-on-occur-x-mode)
  :custom
  (occur-linenumbers-in-margin 'none)
  :config
  (defun occur-x--linenums-to-margin()
    "Custom function that overwrites library default to completely remove lines"
    (save-excursion
      (when (not (equal occur-linenumbers-in-margin 'none))
        (occur-x--set-margin))
      (goto-char (point-min))
      (forward-line 1)
      (let ((inhibit-read-only t)
            (context (cadr occur-revert-arguments))
            width side)
        (if (equal occur-linenumbers-in-margin 'right-margin)
            (setq width right-margin-width
                  side 'right-margin)
          (setq width left-margin-width
                side 'left-margin))
        (while (not (eobp))
          (if (looking-at "^\s*\\([0-9]+\\):")
              (if (equal occur-linenumbers-in-margin 'none)
                  (delete-region (point) (match-end 0))
                (let ((n (propertize
                          (format (format "%%%ds" width) (match-string 1))
                          'face 'occur-margin-face))
                      (o (make-overlay (point) (point))))
                  (delete-region (point) (match-end 0))
                  (overlay-put o 'before-string
                               (propertize " " 'display
                                           `((margin ,side) ,n)))))
            (if (and context (looking-at "^\s+:"))
                (delete-region (point) (match-end 0))))
          (forward-line 1)))))
  )

Ansi Color

(use-package ansi-color
  :ensure nil
  :defer
  :hook (compilation-filter . ansi-color-compilation-filter)
  :init
  (defvar gopar-ansi-escape-re
    (rx (or ?\233 (and ?\e ?\[))
        (zero-or-more (char (?0 . ?\?)))
        (zero-or-more (char ?\s ?- ?\/))
        (char (?@ . ?~))))

  (defun gopar/nuke-ansi-escapes (beg end)
    (save-excursion
      (goto-char beg)
      (while (re-search-forward gopar-ansi-escape-re end t)
        (replace-match ""))))

  (defun gopar/compilation-nuke-ansi-escapes ()
    (toggle-read-only)
    (gopar/nuke-ansi-escapes (point-min) (point-max))
    (toggle-read-only))

  ;; https://stackoverflow.com/questions/3072648/cucumbers-ansi-colors-messing-up-emacs-compilation-buffer
  (defun gopar/colorize-compilation-buffer ()
    "Colorize the output from compile buffer"
    (read-only-mode -1)
    (ansi-color-apply-on-region (point-min) (point-max))
    (read-only-mode 1)))

JS

(use-package js
  :defer
  :bind (:map js-mode-map
              (";" . easy-camelcase)

              :map js-jsx-mode-map
              (";" . easy-camelcase))
  :custom
  (js-indent-level 2)
  (js-jsx-indent-level 2))

Vue

(use-package vue-mode
  :ensure t
  :defer
  :hook ((vue-mode . flycheck-mode)
         (vue-mode . (lambda () (jinx-mode -1))))
  :init
  (add-hook 'mmm-mode-hook
            (lambda ()
              (set-face-background 'mmm-default-submode-face nil)))
  :config
  (setopt mmm-submode-decoration-level 0))

Pulse

(use-package pulse
  :ensure nil
  :defer
  :init
  (defun pulse-line (&rest _)
    "Pulse the current line."
    (pulse-momentary-highlight-one-line (point)))

  (dolist (command '(scroll-up-command
                     scroll-down-command
                     windmove-left
                     windmove-right
                     windmove-up
                     windmove-down
                     move-to-window-line-top-bottom
                     recenter-top-bottom
                     other-window))
    (advice-add command :after #'pulse-line)))

Mouse Scroll

For my mouse that also has left - right mouse scroll

(use-package mwheel
  :ensure nil
  :defer
  :custom
  (mouse-wheel-tilt-scroll t)
  (mouse-wheel-scroll-amount-horizontal 2)
  (mouse-wheel-flip-direction t))

Whitespace

(use-package whitespace
  :ensure nil
  :defer
  :hook (before-save . whitespace-cleanup)
  :custom
  (whitespace-line-column nil))

Auto revert

(use-package autorevert
  :ensure nil
  :defer
  :hook (emacs-startup . global-auto-revert-mode))

Simple

Built in package that holds a few goodies

(use-package simple
  :ensure nil
  :defer
  :hook ((makefile-mode . indent-tabs-mode)
         (fundamental-mode . delete-selection-mode)
         (fundamental-mode . auto-fill-mode)
         (org-mode . auto-fill-mode))
  :custom
  (save-interprogram-paste-before-kill nil)
  (kill-do-not-save-duplicates t)
  (kill-read-only-ok t)
  (kill-transform-function 'substring-no-properties)
  (yank-excluded-properties t)

  ;; Shell related things
  (shell-command-prompt-show-cwd t)

  :init
  (defun gopar/pulse-current-region (&rest _)
  "Pulse the current implicit or active region."
  (if mark-active
      (pulse-momentary-highlight-region (region-beginning) (region-end))
    (pulse-momentary-highlight-region (mark) (point))))

  (advice-add #'kill-ring-save :before #'gopar/pulse-current-region))

Neotree

Here since treemacs keeps on breaking, and this is backup. Works pretty well

(use-package neotree
  :ensure t
  :bind ("<f5>" . neotree-toggle)
  :hook (emacs-startup . neotree)
  :custom
  (neo-theme 'icons)
  (neo-smart-open t)
  (neo-autorefresh t)
  (neo-window-width 35)
  (neo-toggle-window-keep-p t)
  ;; takes too long to update on first try
  ;; (neo-vc-integration '(face char))
  (neo-show-hidden-files nil)
  (neo-display-action '(gopar/neo-display-fn))
  :init
  (defun gopar/neo-display-fn (buffer _alist)
    (let ((window-pos (if (eq neo-window-position 'left) 'left 'right)))
      (display-buffer-in-side-window buffer `((side . ,window-pos)
                                              (inhibit-same-window . t)
                                              (dedicated . t)
                                              (window-parameters
                                               (no-delete-other-windows . t)
                                               (no-other-window . t)))))))

Dizze

Unfortunately need this: davidmiller/dizzee#5

Sooo I manually copied the PR fix into the init section. Sigh.

(use-package dizzee
  :ensure t
  :defer)

String Inflection

(use-package string-inflection
  :ensure t
  :defer
  :commands string-inflection-insert
  :bind (("C-;" . gopar/string-inflection-cycle-auto))
  :init
  (defun string-inflection-web-mode-function (str)
    "foo_bar => fooBar => Foo_Bar => FOO_BAR => fooBar"
    (cond
     ((string-inflection-underscore-p str)
      (string-inflection-camelcase-function str))
     ((string-inflection-camelcase-p str)
      (string-inflection-pascal-case-function str))
     ((string-inflection-pascal-case-p str)
      (string-inflection-upcase-function str))
     (t
      (string-inflection-camelcase-function str))))

  (defun string-inflection-web-mode-style-cycle ()
    "foo_bar => FOO_BAR => FooBar => foo_bar"
    (interactive)
    (string-inflection--single-or-region #'string-inflection-web-mode-function))

  (defun gopar/string-inflection-cycle-auto ()
    "Switching by major mode."
    (interactive)
    (cond
     ((eq major-mode 'emacs-lisp-mode)
      (string-inflection-all-cycle))

     ((or (eq major-mode 'python-mode) (eq major-mode 'python-ts-mode))
      (string-inflection-python-style-cycle))

     ((or (eq major-mode 'js-mode)
          (eq major-mode 'vue-mode)
          (eq major-mode 'java-mode)
          (eq major-mode 'typescript-mode))
      (string-inflection-java-style-cycle))

     ((eq major-mode 'nxml-mode)
      (string-inflection-java-style-cycle))

     ((eq major-mode 'hy-mode)
      (string-inflection-kebab-case))

     ((eq major-mode 'web-mode)
      (string-inflection-web-mode-style-cycle))

     (t
      (string-inflection-ruby-style-cycle)))))

String Edit

Only available in 29 or higher

(use-package string-edit
  :ensure nil
  :defer
  :init
  (defun gopar/replace-str-at-point (new-str)
    (let ((bounds (bounds-of-thing-at-point 'string)))
      (when bounds
        (delete-region (car bounds) (cdr bounds))
        (insert new-str))))

  (defun gopar/edit-string-at-point ()
    (interactive)
    (let ((string (thing-at-point 'string t)))
      (string-edit "String at point:" string 'gopar/replace-str-at-point :abort-callback (lambda ()
                     (exit-recursive-edit)
                     (message "Aborted edit"))))))

Compact Docstring

(use-package compact-docstrings
  :ensure t
  :defer
  :hook (prog-mode . compact-docstrings-mode)
  :custom
  (compact-docstrings-only-doc-blocks nil))

Transient

(use-package transient
  :ensure t
  :defer
  :bind ("C-M-o" . windows-transient-window)
  :config
  (transient-define-prefix windows-transient-window ()
   "Display a transient buffer showing useful window manipulation bindings."
    [["Resize"
     ("}" "h+" enlarge-window-horizontally :transient t)
     ("{" "h-" shrink-window-horizontally :transient t)
     ("^" "v+" enlarge-window :transient t)
     ("V" "v-" shrink-window :transient t)]
     ["Split"
    ("v" "vertical" (lambda ()
       (interactive)
       (split-window-right)
       (windmove-right)) :transient t)
    ("x" "horizontal" (lambda ()
       (interactive)
       (split-window-below)
       (windmove-down)) :transient t)]
    ["Misc"
     ("b" "Balance Windows" balance-windows :transient t)
     ("z" "undo" (lambda ()
                  (interactive)
                  (winner-undo)
                  (setq this-command 'winner-undo)) :transient t)
    ("Z" "redo" winner-redo :transient t)]]
    [["Move"
    ("h" "" windmove-left :transient t)
    ("j" "" windmove-down :transient t)
    ("l" "" windmove-right :transient t)
    ("k" "" windmove-up :transient t)]
    ["Swap"
     ("s" "Swap" ace-swap-window)]
    ["Delete"
    ("dh" "" windmove-delete-left :transient t)
    ("dj" "" windmove-delete-down :transient t)
    ("dl" "" windmove-delete-right :transient t)
    ("dk" "" windmove-delete-up :transient t)
    ("D" "This" delete-window :transient t)]
    ]))

Ace Window

(use-package ace-window :ensure t :defer t)

Vterm

Set up directory tracking: https://github.com/akermu/emacs-libvterm?tab=readme-ov-file#vterm-buffer-name-string

(use-package vterm
  :ensure t
  :defer
  :bind (:map vterm-mode-map ("C-q" . vterm-send-next-key))
  :custom
  (vterm-buffer-name-string "*vterm %s*")
  (vterm-max-scrollback 100000)
  :config
  (add-to-list 'vterm-keymap-exceptions "C--")
  (add-to-list 'vterm-keymap-exceptions "M--")
  (add-to-list 'vterm-keymap-exceptions "C-M--")
  ;; Doesn't seem to work??
  ;; (add-to-list 'vterm-keymap-exceptions "C-M-o")
  )

Exec From Shell

(use-package exec-path-from-shell
  :ensure t
  :init
  (setq exec-path-from-shell-arguments nil)
  (setq exec-path-from-shell-variables '("PATH" "MANPATH" "SSH_AUTH_SOCK" "NVM_DIR" "HOMEBREW_NO_AUTO_UPDATE"))
  (exec-path-from-shell-initialize))
(use-package devdocs
  :ensure t
  :defer
  :bind ("C-c M-d" . gopar/devdocs-lookup)
  :init
  (add-to-list 'display-buffer-alist
               '("\\*devdocs\\*"
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 3)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (dedicated . t)))

  (defun gopar/devdocs-lookup (&optional ask-docs)
    "Light wrapper around `devdocs-lookup` which pre-populates the function input with thing at point"
    (interactive "P")
    (let ((query (thing-at-point 'symbol t)))
      (devdocs-lookup ask-docs query)))


  :hook (((python-mode python-ts-mode) . (lambda () (setq-local devdocs-current-docs
                                      '("django~4.2" "django_rest_framework" "python~3.11" "postgresql~12"))))
         (web-mode . (lambda () (setq-local devdocs-current-docs '("vue~3"
                                                                   "vue_router~4"
                                                                   "javascript"
                                                                   "typescript"
                                                                   "vitest"
                                                                   "moment"
                                                                   "tailwindcss"
                                                                   "html"
                                                                   "css"))))
         ((typescript-mode typescript-ts-mode) . (lambda () (setq-local devdocs-current-docs '("vue~3"
                                                                          "vue_router~4"
                                                                          "javascript"
                                                                          "typescript"
                                                                          "vitest"
                                                                          "moment"))))))

Link Hint

(use-package link-hint
  :ensure t
  :defer)

Flycheck

(use-package flycheck
  :ensure
  :defer
  :hook (((python-mode python-ts-mode) . flycheck-mode))
  :bind (:map projectile-command-map
         ("l" . flycheck-list-errors))
  :init
  ;; (setq fit-window-to-buffer-horizontally t)
  ;; (setq window-resize-pixelwise t)
  (setopt window-sides-vertical t)
  (add-to-list 'display-buffer-alist
               '("\\*Flycheck errors\\*"
                 display-buffer-in-side-window
                 (side . bottom)
                 (slot . 0)
                 (no-delete-other-windows . t)
                 (window-height . .33)))
  :custom
  (flycheck-flake8rc '(".flake8" "setup.cfg" "tox.ini" "pyproject.toml")))

AI Stuff

(use-package chatgpt-shell
  :ensure t
  :commands (chatgpt-shell--primary-buffer chatgpt-shell chatgpt-shell-prompt-compose)
  :bind (("C-x m" . chatgpt-shell)
         ("C-c C-e" . chatgpt-shell-prompt-compose)
         (:map chatgpt-shell-mode-map
               (("RET" . newline)
                ("M-RET" . shell-maker-submit)
                ("M-." . dictionary-lookup-definition)))
         (:map eshell-mode-map
               ("C-c C-e" . chatgpt-shell-prompt-compose)))
  :hook ((chatgpt-shell-mode . (lambda () (setq-local completion-at-point-functions nil)))
         (eshell-first-time-mode . chatgpt-shell-add-??-command-to-eshell))
  :init
  (setenv "ANTHROPIC_API_KEY" (auth-source-pick-first-password :host "api.anthropic.com"))
  (setq shell-maker-root-path (concat user-emacs-directory "var/"))
  (add-to-list 'display-buffer-alist
               '("\\*chatgpt"
                 display-buffer-in-side-window
                 (side . right)
                 (slot . 0)
                 (window-parameters . ((no-delete-other-windows . t)))
                 (dedicated . t)))
  (setq chatgpt-shell-model-version "o3-mini")
  :custom
  (chatgpt-shell-system-prompt nil ;; 2
                               )
  (chatgpt-shell-highlight-blocks t)
  (shell-maker-prompt-before-killing-buffer nil)
  (chatgpt-shell-openai-key
   (auth-source-pick-first-password :host "api.openai.com"))
  (chatgpt-shell-transmitted-context-length 5)
  (chatgpt-shell-model-versions '("gpt-4o-2024-08-06")))

Dall-E

(use-package dall-e-shell
  :ensure t
  :defer
  :bind (:map dall-e-shell-mode-map
               (("RET" . newline)
               ("M-RET" . shell-maker-submit)))
  :custom
  (dall-e-shell-openai-key
      (auth-source-pick-first-password :host "api.openai.com"))
  (dall-e-shell-image-size "1024x1024")
  (dall-e-shell-image-output-directory "~/Downloads/dall_e_output/"))

Aidermacs

(use-package aidermacs
  :ensure t
  :bind (("M-g a" . aidermacs-transient-menu)
         :map aidermacs-vterm-mode-map
         ("M-RET" . aidermacs-vterm-send-return)
         )
  :init
  (setopt aidermacs-vterm-use-theme-colors nil)
  :custom
  ; This doens't work along with M-RET. Need to open ticket
  (aidermacs-vterm-multiline-newline-key "RET")
  (aidermacs-use-architect-mode t)
  (aidermacs-show-diff-after-change nil)
  (aidermacs-auto-accept-architect t)
  (aidermacs-backend 'vterm)
  (aidermacs-watch-files t)
  (aidermacs-extra-args `(
                        "--analytics-disable"
                        "--no-auto-commits"
                        "--no-dirty-commits"
                        "--no-attribute-author"
                        "--no-attribute-committer"
                        "--no-auto-lint"
                        "--notifications"
                        "--notifications-command \"say 'Aider is ready'\""
                        ,(if (file-exists-p (concat (projectile-acquire-root) "CONVENTIONS.md"))
                            (concat "--read " (projectile-acquire-root) "CONVENTIONS.md")
                          "")))
  (aidermacs-architect-model "claude-3-7-sonnet-latest")
  (aidermacs-editor-model "claude-3-5-sonnet-latest")
  (aidermacs-weak-model "claude-3-5-haiku-latest")
  (aidermacs-default-model "sonnet"))

Better UI for Modeline. Need to install fonts first by doing this

M-x all-the-icons-install-fonts
(use-package doom-modeline
  :ensure t
  :hook (emacs-startup . doom-modeline-mode)
  :config (column-number-mode 1)
  :custom
  (doom-modeline-height 30)
  (doom-modeline-window-width-limit nil)
  (doom-modeline-buffer-file-name-style 'truncate-with-project)
  (doom-modeline-minor-modes nil)
  (doom-modeline-enable-word-count nil)
  (doom-modeline-buffer-encoding nil)
  (doom-modeline-buffer-modification-icon t)
  (doom-modeline-env-python-executable "python")
  ;; needs display-time-mode to be one
  (doom-modeline-time t)
  (doom-modeline-vcs-max-length 50)
  )

Doom Themes

Use Doom Themes since they have built in support for Solaire Mode

(use-package doom-themes
  :ensure t
  :custom
  (doom-gruvbox-brighter-comments t)
  :config
  ;; Global settings (defaults)
  (setopt doom-themes-enable-bold t    ; if nil, bold is universally disabled
          doom-themes-enable-italic t) ; if nil, italics is universally disabled

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config)
  ;; Corrects (and improves) org-mode's native fontification.
  (doom-themes-org-config))
(use-package fill-function-arguments
  :ensure t
  :defer
  :bind (:map prog-mode-map
              ("M-q" . fill-function-arguments-dwim)))
(use-package ssh-config-mode
  :ensure t
  :defer)
(use-package hide-mode-line
  :ensure t
  :defer
  :hook (;; (eshell-mode . hide-mode-line-mode)
         ;; (vterm-mode . hide-mode-line-mode)
         ;; (occur-mode . hide-mode-line-mode)
         (neotree-mode . hide-mode-line-mode)))

Sqlite

Built in sqlite viewer in emacs Additional goodies can be found here: https://xenodium.com/further-sqlite-mode-extensions/

(use-package sqlite-mode
  :ensure nil
  :defer
  :bind (:map sqlite-mode-map
              ("n" . next-line)
              ("p" . previous-line)))

SQL Mode

Shells for db’s

(use-package sql
  :ensure nil
  :defer
  :custom
  (sql-sqlite-options '("-header" "-box")))

Keycast

Display keystors in mode line. Useful for when making videos

(use-package keycast
  :ensure t
  :defer
  :custom
  (keycast-mode-line-format "%k%c%R ")
  (keycast-substitute-alist
   '((keycast-log-erase-buffer nil nil)
     (transient-update         nil nil)
     (self-insert-command "." "Typing…")
     (org-self-insert-command "." "Typing…")
     (mwheel-scroll nil nil)
     (mouse-movement-p nil nil)
     (mouse-event-p nil nil))))

Dot Env Mode

(use-package dotenv-mode
  :ensure t
  :defer
  :hook (dotenv-mode . (lambda () (focus-mode -1)))
  :mode ("\\.env\\..*\\'" . dotenv-mode))

Dot Env Hide

(use-package dotenv-hide
  :load-path "lisp/modes/dotenv-hide"
  :hook (dotenv-mode . dotenv-hide-mode))
(use-package focus
  :ensure t
  :defer
  :hook ((prog-mode . focus-mode)
         (docker-ts-mode . (lambda () (focus-mode -1)))
         (typescript-ts-mode . (lambda () (focus-mode -1)))
         (web-mode . (lambda () (focus-mode -1)))))

Fretboard

Guitar stuff

(use-package fretboard
  :ensure t
  :defer t
  :commands fretboard
  :custom
  (fretboard-fret-count 20))
(use-package circadian
  :ensure t
  :init
  (setq calendar-latitude (string-to-number (auth-source-pick-first-password :host "emacs.solar.latitude"))
        calendar-longitude (string-to-number (auth-source-pick-first-password :host "emacs.solar.longtitude")))
  :config
  (setq circadian-themes '((:sunrise . modus-operandi-tinted)
                           (:sunset  . modus-vivendi-tinted)))
  (circadian-setup))

Popper

(use-package popper
  :ensure t
  :defer
  :bind (("C--"   . popper-toggle)
         ("M--"   . popper-cycle)
         ("C-M--" . popper-toggle-type))
  :hook ((emacs-startup . popper-mode)
         (emacs-startup . popper-echo-mode))
  :custom
  (popper-display-control t)
  (popper-group-function 'popper-group-by-directory)
  (popper-reference-buffers
   '("\\*Messages\\*"
     "Output\\*$"
     "\\*Async Shell Command\\*"
     "\\*Warnings\\*"
     helpful-mode
     help-mode
     eshell-mode
     vterm-mode
     world-clock-mode
     eww-buffers-mode
     compilation-mode)))

1st Party Modes

Stuff I’ve made for myself that are modes

Pair Programming

(defvar gopar-pair-programming nil)
(defun gopar/pair-programming ()
  "Poor mans minor mode for setting up things that i like to make pair programming easier."
  (interactive)
  (if gopar-pair-programming
      (progn
        ;; Don't use global line numbers mode since it will turn on in other modes that arent programming
        (dolist (buffer (buffer-list))
          (with-current-buffer buffer
            (when (derived-mode-p 'prog-mode)
              (display-line-numbers-mode -1))))
        (remove-hook 'prog-mode-hook 'display-line-numbers-mode)
        (setq gopar-pair-programming nil))

    (progn
      ;; display line numbers
      (dolist (buffer (buffer-list))
        (with-current-buffer buffer
          (when (derived-mode-p 'prog-mode)
            (display-line-numbers-mode 1))))
      (add-hook 'prog-mode-hook 'display-line-numbers-mode)

      (neotree)
      (setq gopar-pair-programming t))))

Boolcase

(use-package boolcase
  :load-path "lisp/modes/boolcase"
  :hook ((python-mode python-ts-mode) . boolcase-mode))

Vim Navigation

Poor mans Vim Emulation for read only files

(use-package vim-navigation
  :ensure nil
  :defer t
  :hook (view-mode . enable/disable-vim-nav)
  :init
  (define-minor-mode vim-navigation-mode
    "Minimal vim–like movement mode."
    :keymap (let ((map (make-sparse-keymap)))
              (define-key map (kbd "j") 'next-line)
              (define-key map (kbd "k") 'previous-line)
              (define-key map (kbd "h") 'backward-char)
              (define-key map (kbd "l") 'forward-char)
              (define-key map (kbd "k") 'previous-line)
              (define-key map (kbd "gg") 'beginning-of-buffer)
              (define-key map (kbd "G")  'end-of-buffer)
              (define-key map (kbd "d") 'scroll-up-command)
              (define-key map (kbd "u") 'scroll-down-command)
              map))
  (defun enable/disable-vim-nav ()
    (if view-mode
        (vim-navigation-mode 1)
      (vim-navigation-mode -1))))

YouTube

Functions that are handy for setting up recording in youtube

(defvar gopar/orginal-font-height nil)
(defvar gopar/youtube-font-height 220)
(defun gopar/youtube-setup ()
  (when (null gopar/orginal-font-height)
    (setq gopar/orginal-font-height (face-attribute 'default :height)))

  (set-face-attribute 'default nil :height gopar/youtube-font-height)
  (set-frame-size (selected-frame) 143 40)

  (delete-other-windows)
  (display-time-mode -1)
  (type-break-mode -1)
  (keycast-header-line-mode)
  (let ((dashboard-items '((vocabulary) (bookmarks . 5)))
        (dashboard-banner-logo-title "✨ Memberships are available. Thank you for the support! ✨"))
    (dashboard-open)))

(defun gopar/youtube-setup-emacs-goodies-series ()
  (interactive)
  (consult-theme 'doom-shades-of-purple)
  (gopar/youtube-setup))

(defun gopar/youtube-setup-python-series ()
  (interactive)
  (consult-theme 'doom-nord-aurora)
  (gopar/youtube-setup))

(defun gopar/youtube-setup-refactor-series ()
  (interactive)
  (consult-theme 'haki)
  (gopar/youtube-setup))

(defun gopar/youtube-setup-design-patterns-series ()
  (interactive)
  (consult-theme 'manoj-dark)
  (gopar/youtube-setup))

Private

Things that I want to keep private/out of git

(use-package private
  :load-path "lisp"
  :commands (gopar/random-friend)
  )

End

;; (progn
;;   (add-to-list 'default-frame-alist `(font . "Hack 16"))
;;   (set-face-attribute 'default nil :font "Hack 16"))
(progn
  (add-to-list 'default-frame-alist `(font . "IBM Plex Mono 16"))
  (set-face-attribute 'default nil :font "IBM Plex Mono 16"))

;;; Local Variables: *** ;;; eval: (add-hook ‘after-save-hook #’org-babel-tangle nil t) *** ;;; End: ***

About

My Secret Sauce

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published