General Emacs settings

Variables Set QOL

(setq inhibit-startup-screen t)
(setq inhibit-startup-echo-area-message t)
(setq-default line-spacing 6)
(setq ffap-machine-p-known 'reject)
(setq lsp-disabled-clients (list 'omnisharp 'semgrep-ls))

(defvar is-windows (string-equal system-type "windows-nt"))
(defvar home-dir (expand-file-name "~"))
(defvar em-dir (concat home-dir "/.emacs.d/"))
(setq user-emacs-directory em-dir)
(setq default-directory (expand-file-name "~/"))
;;This is for using Mono with C# and Unity support
;;(setenv "FrameworkPathOverride" "")
;;(setenv "DOTNET_ROLL_FORWARD_TO_PRERELEASE" "0")
(setenv "DOTNET_ROOT" (concat home-dir "/.dotnet"))
;; (setq exec-path (split-string (getenv "PATH") ":"))
;; (setenv "PATH" (concat
;;                  "/opt/netcoredbg/:"
;;                  home-dir "/.cargo/bin:"
;;                  home-dir "/.dotnet/:"
;;                  home-dir "/.dotnet/tools/:"
;;                  home-dir "/.cargo/bin:" (getenv "PATH")))
(exec-path-from-shell-initialize)
(add-to-list 'load-path (concat em-dir "lisp/"))
(add-to-list 'load-path (concat em-dir "lisp/ts-fold"))
;;(add-to-list 'load-path (concat em-dir "lisp/exwm-workspace-group"))

(setq
  transient-mark-mode t ;; enable visual feedback on selections
  visual-line-mode t
  scroll-step 1 ;; scroll line by line
  confirm-kill-emacs nil ;; don't kill emacs without prompt
  require-final-newline t
  save-interprogram-paste-before-kill t
  undo-limit (eval-when-compile (* 32 1024 1024))
  undo-strong-limit (eval-when-compile (* 15 1024 1024))
  undo-outer-limit (eval-when-compile (* 50 1024 1024))
  ;; scroll comp output
  compilation-scroll-output 1
  compilation-window-height 10
  apropos-do-all t
  mouse-yank-at-point t
  visible-bell t
  ring-bell-function 'ignore
  load-prefer-newer t
  ediff-window-setup-function 'ediff-setup-windows-plain
  ;; completion
  completion-auto-help t

  ;; buffer encoding
  buffer-file-coding-system 'utf-8-unix
  default-file-name-coding-system 'utf-8-unix
  default-keyboard-coding-system 'utf-8-unix
  default-process-coding-system '(utf-8-unix . utf-8-unix)
  default-sendmail-coding-system 'utf-8-unix
  default-terminal-coding-system 'utf-8-unix
  lsp-tailwindcss-add-on-mode t
  lsp-tailwindcss-major-modes
  '(rjsx-mode web-mode html-mode css-mode typescript-mode svelte-mode)

  ;; custom file
  custom-file (concat em-dir "custom.el"))

(add-to-list 'default-frame-alist '(fullscreen . maximized))
;; put backup files in single directory
(defvar backup-file-dir (concat em-dir "backup/"))
(setq
  backup-directory-alist `(("." . ,backup-file-dir))
  make-backup-files t    ; make backups
  backup-by-copying t    ; Don't delink hardlinks
  version-control t      ; Use version numbers on backups
  delete-old-versions t  ; Automatically delete excess backups
  kept-new-versions 10    ; how many of the newest versions to keep
  kept-old-versions 2    ; and how many of the old
  delete-by-moving-to-trash t ; obvs
  ;;make-backup-file-name-function 'my-backup-file-name ;custom backup func
  )

;; use y or n instead of yes or not
(fset 'yes-or-no-p 'y-or-n-p)

;; set gui window size
(if (window-system)
  (set-frame-size (selected-frame) 148 41))


;; Shorter buffer name
(setq frame-title-format
  '((:eval (if (buffer-file-name)
             (abbreviate-file-name (buffer-file-name))
             "%b"))))

;;no wrap lines
(set-default 'truncate-lines t)
;; save place in files
(save-place-mode 1)
(setq save-place-file (concat em-dir "saved-places"))
;; replace highlighted text when possible
(delete-selection-mode t)
;; font-lock mode enables syntax highlighting
(global-font-lock-mode 1)
;; disable gui
(tool-bar-mode -1)
(menu-bar-mode -1)
(if (boundp 'scroll-bar-mode)
  (scroll-bar-mode -1))
;; Parenthesis matching
(show-paren-mode 1)
;; highlight current line
(global-hl-line-mode t)
(global-auto-revert-mode t)
;; Get rid of a lot of warning noise
(setq warning-minimum-log-level :error)
;; Show line numbers in all modes
;;(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(global-display-line-numbers-mode)

Shell Command

(setq shell-file-name "/usr/bin/zsh")
(setenv "SHELL" shell-file-name)
(setq terminal-name "xfce4-terminal")
;; (add-hook 'shell-mode-hook 'ansi-color-for-comint-mode-on)

Font Faces

;; ;;(defvar family ())
(setq big-size 120)
(setq little-size 120)
(if (display-graphic-p)
  (progn
    (set-face-attribute 'default nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height little-size
      )
    (set-face-attribute 'variable-pitch nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height little-size)
    (set-face-attribute 'fixed-pitch nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height little-size
      :weight 'thin))
  (progn
    (set-face-attribute 'default nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height big-size
      )
    (set-face-attribute 'variable-pitch nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height big-size)
    (set-face-attribute 'fixed-pitch nil
      :family "BigBlueTerm437 Nerd Font Propo"
      :height big-size)))

Guarantee we are using the same packages across systems

;;
;; get melpa packages in package.el
;;
(require 'package)
(setq package-archives '(("melpa" . "https://melpa.org/packages/")
                          ("gnu-devel" . "https://elpa.gnu.org/devel/")
                          ))
(package-initialize)

(require 'cl)

(defvar my-packages
  '( less-css-mode ace-jump-mode flyspell ggtags
     yaml-mode whitespace-cleanup-mode popup ag ispell yaml-mode
     groovy-mode groovy-imports smartparens syntax-subword magit
     python-mode scss-mode  projectile auto-complete rjsx-mode
     flx-ido idomenu ido-vertical-mode ido-completing-read+ ess
     gradle-mode ace-window auto-package-update rainbow-mode pug-mode
     flycheck web-mode expand-region shackle golden-ratio
     golden-ratio-scroll-screen dired-quick-sort smart-mode-line
     package-lint ert shut-up aggressive-indent json-mode dash
     smex pcre2el comment-tags typescript-mode go-mode go-autocomplete
     lsp-mode yasnippet flycheck use-package org-bullets rustic flycheck-rust
     exwm esup eglot helm org-books ox-hugo org-present helm-posframe
     alert org-alert magit-todos org-super-agenda gruvbox-theme
     gdscript-mode dap-mode org-wild-notifier org-kanban multiple-cursors
     ;; theme
     gruvbox-theme)
  "A list of packages to ensure are installed at launch.")

(defun my-packages-installed-p ()
  (loop for p in my-packages
    when (not (package-installed-p p)) do (return nil)
    finally (return t)))

(unless (my-packages-installed-p)
  ;; check for new packages (package versions)
  (package-refresh-contents)
  ;; install the missing packages
  (dolist (p my-packages)
    (when (not (package-installed-p p))
      (package-install p))))

;; color theme
(setq custom-safe-themes t)
(load-theme 'gruvbox-dark-hard t)
;; auto update packages every 14 days
;; (require 'auto-package-update)
;; (auto-package-update-maybe)
;; (setq auto-package-update-interval 14)

Ease of use Functions

;;
;; Functions
;;
(defun my--smart-register-save (register)
  "Allow for copying text or point to register if region is active"
  (interactive "c")
  (if (region-active-p)
    (copy-to-register register (region-beginning) (region-end) nil t)
    (point-to-register register)))

(defun clear-registers ()
  (interactive)
  (setq register-alist ()))

(defun my--smart-register-load (register)
  "Paste text or jump to point"
  (interactive "c")
  (let ((register-value (get-register register)))
    (if register-value
      (cond ((markerp register-value) (jump-to-register register))
        ((and (listp register-value) (window-configuration-p (car register-value))) (jump-to-register register))
        (t (insert (get-register register)))))))

(defun my--smart-register-save-or-load (register)
  "Use register if assigned or store value if empty"
  (interactive "c")
  (let ((register-value (get-register register)))
    (cond
      ((char-equal register 24) (pop-global-mark))
      ((char-equal register 11) (clear-registers))
      (register-value (my--smart-register-load register))
      (t (my--smart-register-save register)))))

;; set Ctrl-a to jump between beginning of line and beginning of code
(defun my--smart-beginning-of-line ()
  "Move point to `beginning-of-line'. If repeat command it cycle
position between `back-to-indentation' and `beginning-of-line'."
  (interactive "^")
  (if (eq last-command 'my--smart-beginning-of-line)
    (if (= (line-beginning-position) (point))
      (back-to-indentation)
      (beginning-of-line))
    (back-to-indentation)))

(defun my--smart-end-of-line ()
  "Move point to `end-of-line'. If repeat command it cycle
position between last non-whitespace and `end-of-line'."
  (interactive "^")
  (if (and (eq last-command 'my--smart-end-of-line)
        (= (line-end-position) (point)))
    (skip-syntax-backward " " (line-beginning-position))
    (end-of-line)))

(defun no-action ()
  "Dummy function that does nothing"
  (interactive "^"))

(defun sudo-find-file ()
  "File file as root."
  (interactive)
  (let ((root-file "/sudo:root@localhost:"))
    (find-file (concat root-file
                 (helm-read-file-name "Find file (as su): ")))))

(defun kill-other-buffers ()
  "Kill all buffers but the current one. Don't mess with special buffers."
  (interactive)
  (dolist (buffer (buffer-list))
    (unless (or (eql buffer (current-buffer)) (not (buffer-file-name buffer)))
      (kill-buffer buffer))))

(defun my-read-file-to-string (filename)
  (with-temp-buffer
    (insert-file-contents filename)
    (buffer-substring-no-properties (point-min) (point-max))))

(global-set-key (kbd "C-x O") (lambda ()
                                (interactive)
                                (other-window -1)))


(defun replace-element-in-list (elem-src elem-dst ls &optional times comparison-fn)
  (setq times (or times (length ls)))
  (mapcar
    (lambda (item)
      (cond
        ((and (> times 0)
           (funcall (or comparison-fn #'eq) item elem-src))
          (cl-decf times)
          elem-dst)
        (t
          item)))
    ls))

(defun modify-element-in-list (elem-index elem-newvalue ls)
  (setq i -1)
  (mapcar
    (lambda (item)
      (cl-incf i)
      (cond
        ((= i elem-index) elem-newvalue)
        (t item)))
    ls))

Setup my global keybinds in a minor mode

;; defines key overrides
(defvar my-keys-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-a") 'my--smart-beginning-of-line)
    (define-key map (kbd "C-e") 'my--smart-end-of-line)
    (define-key map (kbd "C-t") 'no-action) ;get rid of char swapping
    ;;(define-key map (kbd "C-x C-b") 'helm-mini)
    (define-key map (kbd "C-x b") 'helm-mini)
    ;;(define-key map (kbd "C-x C-b") 'no-action) ;get rid of buffer lists
    ;;(define-key map (kbd "M-j") (lambda () (interactive) (join-line -1)))
    (define-key map (kbd "M-/") 'hippie-expand)
    (define-key map (kbd "C-=") 'undo-redo)
    (define-key map (kbd "C--") 'undo-only)
    (define-key map (kbd "C-s") 'isearch-forward-regexp)
    (define-key map (kbd "C-r") 'isearch-backward-regexp)
    (define-key map (kbd "C-M-s") 'isearch-forward)
    (define-key map (kbd "C-M-r") 'isearch-backward)
    (define-key map (kbd "C-c C-v") 'hs-toggle-hiding)
    ;;(define-key map (kbd "C-S-O") 'helm-mini)
    (define-key map (kbd "C-S-R") 'projectile-find-file)
    (define-key map (kbd "C-S-f") 'projectile-ag)
    (define-key map (kbd "C-c k") 'kill-other-buffers)
    (define-key map (kbd "C-x C-r") 'sudo-find-file)
    (define-key map (kbd "C-<tab>") 'completion-at-point)
    (define-key map (kbd "C-z") 'completion-at-point) ;; remove annoying suspend-frame
    (define-key map (kbd "C-x C-x") 'my--smart-register-save-or-load)
    (define-key map (kbd "C-d") 'delete-forward-char)
    (define-key map (kbd "<mouse-8>") 'xref-go-back)
    (define-key map (kbd "<mouse-2>") 'xref-find-definitions)
    (define-key map (kbd "<f5>") 'dap-debug-last)
    (define-key map (kbd "<f6>") 'dap-ui-continue)
    map)
  "my-keys-minor-mode keymap.")

(define-minor-mode my-keys-minor-mode
  "A minor mode so that my key settings override annoying major modes."
  :init-value t
  :global t
  :lighter nil)

(my-keys-minor-mode 1)

Setup my style across all files

;;
;; Personal style
;;

;; disable tabs, use spaces
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(defvaralias 'c-basic-offset 'tab-width)
(setq lisp-indent-offset 2)
(setq css-indent-offset 2)
(setq web-indent-offset 2)
(set-default 'tab-always-indent 'complete)

Configurations of specific packages

Ace Jump

;; ace jump mode
(define-key global-map (kbd "C-c SPC") 'ace-jump-mode)
(define-key global-map (kbd "M-p") 'ace-window)
(autoload 'ace-jump-mode "ace-jump-mode")
(autoload 'ace-jump-mode-pop-mark "ace-jump-mode")
(autoload 'ace-window "ace-window")
(with-eval-after-load "ace-jump-mode"
  (ace-jump-mode-enable-mark-sync))

AG and Projectile

;; ignored files for ag-search and projectile
(defvar ignored-dirs
  '("*.gradle/"
     "*gradle/"
     "*.settings/"
     "*build/"
     "*lib/"
     "*libs/"
     "*bower_components/"
     "*tinymce/"
     "*bootstrap/"
     "*.git/"
     "*media/"
     "*images/"
     "*img/"
     "*dist/"
     "/main-application/uploads/"
     "*fontello/"
     "*node_modules/"))

(require 'ag)
(with-eval-after-load "ag"
  (setq ag-resuse-window nil)
  (setq ag-reuse-buffers t)
  (setq-default ag-ignore-list (append ignored-dirs '("*.log" "*.csv" "*.min.*" "#*#"))))


;; projectile stuff
;;(load-file (expand-file-name "~/dev/projectile/projectile.el"))
(require 'projectile)
(with-eval-after-load "projectile"
  (setq projectile-mode-line
    ;;'(:eval (format " Proj[%s]" (projectile-project-name)))
    "Projectile"
    )
  ;;(setq projectile-mode-line nil)
  ;; set find-file to C-O (done in my-keys-minor-mode)
  (setq projectile-completion-system 'ido)
  ;;(setq projectile-indexing-method 'native)
  (setq projectile-indexing-method 'alien)
  (setq projectile-enable-caching t)
  (setq projectile-require-project-root nil)
  (setq projectile-verbose nil)

  (setq projectile-globally-ignored-file-suffixes
    '(".png"
       ".pdf"
       ".class"
       ".gif"
       ".jpg"
       ".eot"
       ".ttf"
       ".woff"
       ".woff2"
       ".xlsx"
       ".doc"
       ".docx"
       ".jar"
       ".project"
       ".classpath"
       ".zip"
       ".tern-project"
       ".kml"
       ".kmz"
       ".min.js"
       ".min.css"))
  (setq projectile-globally-ignored-files
    (append '("GRTAGS"
               "GPATH"
               "GTAGS"
               "TAGS")
      projectile-globally-ignored-files))
  (setq projectile-globally-ignored-directories
    (append ignored-dirs
      projectile-globally-ignored-directories)))
(projectile-mode 1)

Autocomplete

We’re shutting off autocomplete for now

;; (autoload 'auto-complete-mode "auto-complete")
;; (ac-config-default)
;; (global-auto-complete-mode nil)
;; (with-eval-after-load "auto-complete"
;;   (setq ac-trigger-key "TAB"
;;     ;;ac-use-overriding-local-map t
;;     ))
;; (add-hook 'prog-mode-hook 'auto-complete-mode)

Colorize Compilation


;; colorize compilation output
(require 'ansi-color)
(defun colorize-compilation-buffer ()
  (toggle-read-only)
  (ansi-color-apply-on-region (point-min) (point-max))
  (toggle-read-only))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)

Magit-todo

(magit-todos-mode t)

CPP Mode

 (add-hook 'c++-mode-hook 'lsp)
(setenv "PATH" (concat home-dir "/.emacs.d/.cache/lsp/clangd/bin/:"
                 (getenv "PATH")))
     (setq exec-path (split-string (getenv "PATH") ":"))
(setq lsp-clients-clangd-executable (concat home-dir "/.emacs.d/.cache/lsp/clangd/bin/clangd"))
(setq lsp-clients-clangd-library-directories `("/usr" ,(concat home-dir "/.emacs.d/.cache/lsp/clangd/lib/clang/19")))

C-Sharp

;; (use-package csharp
;;   :hook eglot)

ChatGPT

(use-package chatgpt
  :bind ("C-c q" . chatgpt-query)
  :config
  (setenv "OPENAI_API_KEY" "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"))

Dired

;; DIRED setup
(autoload 'dired "dired")
(with-eval-after-load "dired"
  (require 'dired-x)
  ;;(require 'dired-quick-sort)
  (setq ls-lisp-use-insert-directory-program t
    ;;dired-omit-files (concat dired-omit-files "\\|^\\.\\.?$")
    dired-listing-switches "-Faho --color=auto --group-directories-first --sort=time")
  ;;(dired-quick-sort-setup)
  (add-hook 'dired-mode-hook
    (lambda ()
      (dired-hide-details-mode)
      (dired-sort-toggle-or-edit)
      ;;(dired-omit-mode)
      )))

Flycheck

;; syntax checker
(use-package flycheck
  :bind (:map flycheck-mode-map
          ("C-c C-c l" . flycheck-list-errors))
  :config
  (setq flycheck-check-syntax-automatically '(mode-enabled save idle-change)) ;;newline
  (setq flycheck-idle-change-delay 30)
  (setq flycheck-flake8rc "~/.flake8")
  (setq flycheck-python-flake8-executable "flake8")
  ;;  (flycheck-add-mode 'javascript-eslint 'js2-mode)
  (flycheck-add-mode 'javascript-eslint 'js-mode)
  (flycheck-add-mode 'typescript-tslint 'typescript-mode)
  (flycheck-add-mode 'javascript-eslint 'js-jsx-mode)
  (flycheck-add-mode 'javascript-eslint 'rjsx-mode)
  (flycheck-add-mode 'go-build 'go-mode)
  (flycheck-add-mode 'groovy 'groovy-mode)
  (flycheck-add-mode 'html-tidy 'web-mode)
  (flycheck-add-mode 'python-flake8 'python-mode)
  (add-hook 'js-mode-hook 'flycheck-mode)
  (add-hook 'js-jsx-mode-hook 'flycheck-mode)
  (add-hook 'rjsx-mode 'flycheck-mode)
  (add-hook 'groovy-mode-hook 'flycheck-mode)
  (add-hook 'web-mode-hook 'flycheck-mode)
  (add-hook 'typescript-mode-hook 'flycheck-mode)
  (add-hook 'go-mode-hook 'flycheck-mode)
  (add-hook 'python-mode-hook 'flycheck-mode)
  ;;(add-hook 'prog-mode-hook 'flycheck-mode)
  ;;(add-hook 'js2-mode-hook 'flycheck-mode)
  ;;(remove-hook 'rust-mode-hook 'flycheck-mode)
  :ensure)


;; jsx mode
(autoload 'rjsx-mode "rjsx-mode")
(add-to-list 'auto-mode-alist '("\\.react.js" . rjsx-mode))
(add-to-list 'auto-mode-alist '("\\.jsx" . rjsx-mode))

Flyspell

;; flyspell
(autoload 'flyspell-mode "flyspell")
(with-eval-after-load "flyspell"
  (setq flyspell-issue-message-flag nil)
  (setq-default ispell-program-name "aspell"))
(add-hook 'org-mode-hook 'flyspell-mode)
(add-hook 'text-mode-hook 'flyspell-mode)
(autoload 'flyspell-delay-command "flyspell" "Delay on command." t)
(autoload 'tex-mode-flyspell-verify "flyspell" "" t)

;; columns
(column-number-mode 1)

Gnus Mail-client

(use-package gnus

  ;; :bind (("$" . gnus-summary-mark-as-spam))
  :config
  (setq gnus-use-cache nil
    message-alternative-emails "J.Kenyon@orinarygizmos.com"))

Godot

(use-package gdscript-mode
    :config
    (add-hook 'gdscript-mode-hook 'lsp))

Golden Ratio

;; (require 'expand-region)
;; (global-set-key (kbd "C-=") 'er/expand-region)


(require 'golden-ratio)
;; add ace-window jump to trigger commands
(nconc golden-ratio-extra-commands '(ace-window))
;;(setq golden-ratio-auto-scale t)
(golden-ratio-mode 0)

(require 'golden-ratio-scroll-screen)
(global-set-key [remap scroll-down-command] 'golden-ratio-scroll-screen-down)
(global-set-key [remap scroll-up-command] 'golden-ratio-scroll-screen-up)
(setq golden-ratio-exclude-modes '(org-mode))

Groovy

;; groovy mode
;;(load-file (expand-file-name "~/dev/groovy-emacs-modes/groovy-mode.el"))
(autoload 'groovy-mode "groovy-mode")
(with-eval-after-load "groovy-mode"
  (setq groovy-highlight-assignments t))
(add-to-list 'auto-mode-alist '("\\.groovy\\'" . groovy-mode))
(add-to-list 'auto-mode-alist '("\\.gradle\\'" . groovy-mode))
(add-hook 'groovy-mode-hook 'groovy-imports-scan-file)

Helm

Main Config

;;(require 'helm-config)
(require 'helm)
;; The default "C-x c" is quite close to "C-x C-c", which quits Emacs.
;; Changed to "C-c h". Note: We must set "C-c h" globally, because we
;; cannot change `helm-command-prefix-key' once `helm-config' is loaded.
(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))
(with-eval-after-load 'tramp-cache (setq tramp-cache-read-persistent-data t))
(with-eval-after-load 'auth-source (setq auth-source-save-behavior nil))
(define-key global-map [remap find-file] 'helm-find-files)
(define-key global-map [remap occur] 'helm-occur)
(define-key global-map [remap list-buffers] 'helm-buffers-list)
(define-key global-map [remap dabbrev-expand] 'helm-dabbrev)
(define-key global-map [remap execute-extended-command] 'helm-M-x)
(define-key global-map [remap apropos-command] 'helm-apropos)
(define-key global-map [remap read-file-name] 'helm-read-file-name)


(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action) ; rebind tab to run persistent action
(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action) ; make TAB work in terminal
(define-key helm-map (kbd "C-z")  'helm-select-action) ; list actions using C-z

(when (executable-find "curl")
  (setq helm-google-suggest-use-curl-p t))

(setq helm-split-window-in-side-p           t ; open helm buffer inside current window, not occupy whole other window
  helm-move-to-line-cycle-in-source     t ; move to end or beginning of source when reaching top or bottom of source.
  helm-ff-search-library-in-sexp        t ; search for library in `require' and `declare-function' sexp.
  helm-scroll-amount                    8 ; scroll 8 lines other window using M-<next>/M-<prior>
  helm-ff-file-name-history-use-recentf t
  helm-echo-input-in-header-line t)

(helm-autoresize-mode 1)
(set-face-attribute 'helm-source-header nil :height 0.6)
(setq helm-display-header-line nil
  helm-autoresize-max-height 30
  helm-autoresize-min-height 30)

(global-set-key (kbd "C-x C-i") 'helm-imenu-in-all-buffers)
(unless (boundp 'completion-in-region-function)
  (define-key lisp-interaction-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point)
  (define-key emacs-lisp-mode-map       [remap completion-at-point] 'helm-lisp-completion-at-point))

(setq helm-source-imenu-all nil)
(setq helm-imenu-in-all-buffers-separate-sources t)
(setq helm-imenu-extra-modes '(org-mode org))

Org Helm

(require 'helm-org)
;;(helm-org-capture-templates)
;;(helm-org-in-buffer-headings)

(define-advice helm--completion-in-region (:around (helm-fun origfun start end collection &optional predicate) temporary-helm-crm-separator-for-tags)
  (setq tcrmds helm-crm-default-separator)
  ;; If the last command was any of these values, we're looking at tags most likely
  (when (or (member last-command '(org-capture org-ctrl-c-ctrl-c org-set-tags org-set-tags-command))
          ;;This is a workaround for completions when you've already started typing.
          (and (eq this-command 'crm-complete)
            (eq major-mode 'org-mode))
          ;; This is probably the only thing we really need, but it doesn't handle custom "Tags" prompts
          (and (active-minibuffer-window)
            (eq "Tags: " (minibuffer-prompt))))
    (setq helm-crm-default-separator ":"))
  ;; Call the original Helm Completion function with all the original arguments
  (funcall helm-fun  origfun start end collection predicate)
  (setq helm-crm-default-separator tcrmds))

Activate Helm

(helm-mode 1)

Hide/Show Minor Mode

;; hide/show (keybind in my-keys)
;; (remove-hook 'prog-mode-hook 'hs-minor-mode)

Inkle Mode

(use-package ink-mode
  :mode "\\.ink\\'"
  :config
  (setq ink-inklecate-path "inklecate"))

Javascript

;; JS mode
(autoload 'js-mode "js")
(with-eval-after-load "js"
  (setq
    ;;js-language-version 200
    js-indent-level 2
    js-expr-indent-offset 4
    js-paren-indent-offset 4
    js-indent-first-init 'dynamic
    js-switch-indent-offset 2
    ;; only works in emacs 26+
    js-chain-indent t
    js-indent-align-list-continuation nil))
(add-to-list 'auto-mode-alist '("\\.js\\'" . js-mode))

(add-to-list 'org-src-lang-modes '("inline-js" . javascript)) ;; js2 if you're fancy
(defvar org-babel-default-header-args:inline-js
  '((:results . "html")
     (:exports . "results")))
(defun org-babel-execute:inline-js (body _params)
  (format "<script type=\"text/javascript\">\n%s\n</script>" body))

(add-to-list 'org-src-lang-modes '("inline-js-script" . javascript)) ;; js2 if you're fancy
(defvar org-babel-default-header-args:inline-js-script
  '((:results . "html")
     (:exports . "results")))
(defun org-babel-execute:inline-js-script (body _params)
  (format "<script type=\"text/javascript\" src=\"%s\"></script>" body))

(add-to-list 'org-src-lang-modes '("raw-html" . html))
(defvar org-babel-default-header-args:raw-html
  '((:results . "html")
     (:exports . "results")))
(defun org-babel-execute:raw-html (body _params)
  (format "%s" body))

Kotlin

(setenv "ANDROID_HOME" (concat home-dir "/Android/Sdk"))
(setenv "JAVA_HOME" "")

JSON

(autoload 'json-mode "json-mode")
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode))

eglot

;; (add-hook 'eglot--managed-mode-hook (lambda () (flymake-mode -1)))
;; (use-package eglot
;;   :config
;;   (add-to-list 'eglot-server-programs
;;     '(svelte-mode . ("svelteserver" "--stdio"))))

LSP

;; LSP-Mode integration with Rust Analyzer
(use-package lsp-mode
  :ensure
  :commands lsp
  :config
  (setq read-process-output-max (* 5 1024 1024))
  (setq gc-cons-threshold (* 10 1024 1024))
  (setq
    lsp-signature-function 'lsp-signature-posframe
    lsp-signature-auto-activate '(:on-server-request))
  :custom
  ;; what to use when checking on-save. "check" is default, I prefer clippy
  (lsp-rust-analyzer-cargo-watch-command "clippy")
  (lsp-rust-show-warnings t)
  (lsp-rust-clippy-preference "on")
  (lsp-eldoc-render-all nil)
  (lsp-idle-delay 0.6)
  (lsp-rust-analyzer-server-display-inlay-hints t))

(add-hook 'csharp-mode-hook 'lsp)
(add-hook 'lsp-mode-hook 'format-all-mode)
(setq lsp-ui-doc-enable nil)

;; (use-package lsp-ui
;;   :ensure
;;   :commands lsp-ui-mode
;;   :custom
;;   (lsp-ui-peek-always-show nil)
;;   (lsp-ui-sideline-show-hover nil)
;;   (lsp-ui-doc-enable t))

Magit

;; git stuff
(require 'magit)
(global-set-key (kbd "C-x g") 'magit-status)
(setq
  magit-completing-read-function 'magit-builtin-completing-read
  ;; don't put "origin-" in front of new branch names by default
  magit-default-tracking-name-function 'magit-default-tracking-name-branch-only
  ;; open magit status in same window as current buffer
  magit-status-buffer-switch-function 'switch-to-buffer
  ;; highlight word/letter changes in hunk diffs
  magit-diff-refine-hunk t
  ;; ask me to save buffers
  magit-save-some-buffers t
  ;; pop the process buffer if we're taking a while to complete
  magit-process-popup-time 10
  ;; ask me if I want a tracking upstream
  magit-set-upstream-on-push 'askifnotset)

Markdown Mode

(use-package markdown-mode
  :ensure t
  :commands (markdown-mode gfm-mode)
  :mode (("README\\.md\\'" . gfm-mode)
          ("\\.md\\'" . markdown-mode)
          ("\\.markdown\\'" . markdown-mode))
  :init (setq markdown-command "multimarkdown"))

(use-package markdown-preview-mode
  :ensure t
  :if (boundp 'mdcommand)
  :init
                                        ;(setq markdown-preview-auto-open nil)
  :custom
  (markdown-preview-ws-port 9697)
  (markdown-preview-http-port 9696)
  (markdown-preview-host "127.0.0.1")
  (markdown-preview-http-host "127.0.0.1"))
(setq markdown-preview-stylesheets (list "https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css"))

TODO Multiple Cursors

(require 'multiple-cursors)

Notifications

Install dunst for notifications to work

;; (dbus-init-bus :session)
(setq alert-default-style 'libnotify)
(require 'org-wild-notifier)
;; Turn on deadline alerts for the day
(org-wild-notifier-mode)
(org-wild-notifier-check)

(setq
  org-wild-notifier-alert-time '(20)
  ;; Title of notifications
  org-wild-notifier-notification-title "Agenda"
  ;; Notifications icon
  org-wild-notifier-notification-icon nil
  ;;; Org keyword based whitelist. You’ll get notified only about events specified by this variable
  org-wild-notifier-keyword-whitelist '("TODO")
  ;; Org keyword based blacklist. You’ll never be notified about events specified by this variable
  org-wild-notifier-keyword-blacklist nil
  ;; Org tags based whitelist. You’ll get notified only about events specified by this variable
  org-wild-notifier-tags-whitelist '("InProgress")
  ;; Org tags based blacklist. You’ll never be notified about events specified by this variable
  org-wild-notifier-tags-blacklist nil
  ;; Property which adds additional notifications
  org-wild-notifier-alert-times-property 'WILD_NOTIFIER_NOTIFY_BEFORE)

Org

Base Config

;;org modes
(defun org-update-targets ()
  (interactive)
  (setq org-refile-targets `((org-agenda-files :maxlevel . 5) (nil . (:maxlevel . 5)) (,(org-buffer-list 'files) :maxlevel . 5))))
(use-package org-bullets
  :after org)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
(setq org-bullets-bullet-list '("◉" "⁑" "⁂" "❖" "✮" "✱" "✸"))
(setq org-directory "~/notes/")
(setq org-mode-dir "~/notes/")
(use-package org
  :config
  (setq org-deadline-warning-days 7)
  (setq org-log-done t)
  ;;General Org Settings
  (setq org-imenu-depth 4)
  (setq org-html-validation-link nil)
  (setq org-src-window-setup 'current-window)
  (setq org-startup-indented t)
  (setq org-startup-with-inline-images nil)
  (setq org-image-actual-width '(100))
  (setq org-startup-with-latex-preview nil)
  (setq org-attach-use-inheritance t)
  (setq org-agenda-clockreport-parameter-plist '(:link t :maxlevel 3 :step week :stepskip0 t :fileskip0 t :tcolumns 3))
  (setq org-log-into-drawer t)
  (setq org-duration-format 'h:mm)
  ;; Grab any org file for the agenda as long as it doesn't have a '#' in the name
  ;;   '#' is used for backup files, which we do not want
  (setq org-agenda-files (directory-files org-mode-dir t "^[0-9a-zA-Z-_]+?.org"))
  ;;  (setq org-agenda-files (lambda () (push (current-buffer) (directory-files org-mode-dir t "^[0-9a-zA-Z-_]+?.org"))))
  (setq org-refile-targets `((org-agenda-files :maxlevel . 5) (nil . (:maxlevel . 5)) (,(org-buffer-list 'files) :maxlevel . 5)))
  (setq org-refile-use-outline-path 'file)
  (setq org-outline-path-complete-in-steps nil)
  (setq org-refile-allow-creating-parent-nodes t)
  (setq org-file-apps '((auto-mode . "xdg-open %s")
                         (directory . emacs)
                         ("\\.mm\\'" . default)
                         ("\\.x?html?\\'" . default)
                         ("\\.pdf\\'" . "xdg-open %s")))
  (setq org-todo-keywords
    '((sequence "TODO" "InProgress" "REVIEW" "DONE")))
  (global-set-key (kbd "C-c l") #'org-store-link)
  (global-set-key (kbd "C-c a") #'org-agenda)
  (global-set-key (kbd "C-c c") #'org-capture)
  (global-set-key (kbd "C-c s") #'org-search-view)

  (org-defkey org-mode-map (kbd "C-c C-d") 'org-babel-tangle-project)
  (org-defkey org-mode-map (kbd "C-c C-v +") 'org-babel-tangle-append)
  (org-defkey org-mode-map (kbd "C-c d") 'org-deadline)
  (org-defkey org-mode-map (kbd "C-c C-'") 'my/prompt-for-clock-hours)
  (org-defkey org-mode-map (kbd "M-RET") 'org-insert-subheading)
  (org-defkey org-mode-map (kbd "C-M-<return>") 'org-insert-item)

  (setq org-deck-directories "~/deck/")

  (defun org-babel-tangle-append ()
    "Append source code block at point to its tangle file.
        The command works like `org-babel-tangle' with prefix arg
        but `delete-file' is ignored."
    (interactive)
    (cl-letf (((symbol-function 'delete-file) #'ignore))
      (org-babel-tangle '(4))))

  (defun org-babel-tangle-project ()
    "Collect all the code blocks into their respective files"
    (interactive)
    (org-babel-tangle-file (buffer-file-name)))

  (define-advice org-refile
    (:before (&rest _args) update-refile-targets)
    (setq org-refile-targets
      `((org-agenda-files :maxlevel . 5)
         (nil . (:maxlevel . 5))
         (,(org-buffer-list 'files) :maxlevel . 5))))
  (define-advice org-agenda
    (:before (&rest _args) set-current-file-in-agenda)
    (if (and (eq major-mode 'org-mode)
          (buffer-file-name)
          (not (member (buffer-file-name) (directory-files org-mode-dir t "^[0-9a-zA-Z-_]+?.org"))))
      (setq org-agenda-files (list (buffer-file-name)))
      (setq org-agenda-files (directory-files org-mode-dir t "^[0-9a-zA-Z-_]+?.org"))))
  ;; Use the stylesheets for code colors and not my emacs environment
  (setq org-html-htmlize-output-type 'css)
  (setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)

  (setq org-use-property-inheritance t)
  (defun org-entry-properties-inherit-deadline (orig-fun &optional pom which)
    "Call ORIG-FUN with POM, but if WHICH is `DEADLINE' do it recursively."

    (if (string= which "DEADLINE")
      (org-with-point-at pom
        (let (value)
          (while (not (or (setq value (funcall orig-fun (point) which))
                        (not (org-up-heading-safe)))))
          value)
        (funcall orig-fun pom which))))
  (advice-add 'org-entry-properties :around #'org-entry-properties-inherit-deadline)

  (add-to-list 'auto-mode-alist '("\\.org\\'" . org-mode))
  (require 'org-kanban))

Babel

(org-babel-do-load-languages
 'org-babel-load-languages
 '((emacs-lisp . t) (dot . t))) ; this line activates dot

Org Agenda Commands

(setq org-agenda-custom-commands
  `(
     ("n" "Agenda and all TODOs"
       ((agenda "" ((org-agenda-span 1)))
         (alltodo "") ("agenda.ics")))
     ("d" "Today's Agenda and TODOs"
       (( tags-todo "+PRIORITY=\"A\"")

         (agenda "" ((org-agenda-span 1)))))))

(defun ll/org/agenda/color-headers-with (tag col)
  "Color agenda lines matching TAG with color COL."
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward tag nil t)
    (unless (find-in-line "\\[#[A-Z]\\]")
      (let ((todo-end (or (ll/org/agenda/find-todo-word-end)
                          (point-at-bol)))
            (tags-beginning (or (find-in-line " :" t)
                                (point-at-eol))))
        (add-text-properties todo-end
                             tags-beginning
                             `(face ,col))))))

(defun find-in-line (needle &optional beginning count)
  "Find the position of the start of NEEDLE in the current line.
  If BEGINNING is non-nil, find the beginning of NEEDLE in the current
  line. If COUNT is non-nil, find the COUNT'th occurrence from the left."
  (save-excursion
    (beginning-of-line)
    (let ((found (re-search-forward needle (point-at-eol) t count)))
      (if beginning
          (match-beginning 0)
        found))))
(defun ll/org/agenda/find-todo-word-end ()
  (reduce (lambda (a b) (or a b))
          (mapcar #'find-in-line '("TODO" "DONE"))))

(defun ll/org/colorize-headings ()
  ;; Color all headings with :pers: tan
  (ll/org/agenda/color-headers-with ":BugFix:" '(:foreground "tan" :background "gray25" :weight bold))
  ;; and :work: blue
  (ll/org/agenda/color-headers-with ":Feature:" '(:foreground "lightblue" :background "gray10"))
  (beginning-of-buffer))
(add-hook 'org-agenda-finalize-hook #'ll/org/colorize-headings)

Org Books

(require 'org-books)
(setq org-books-file (concat org-mode-dir "books.org"))
(define-key global-map "\C-cbu" 'org-books-add-url)
(define-key global-map "\C-cbl" (lambda () (interactive)(org-books-visit-book-log)))

Org Capture Templates

;;org templates
(setq org-capture-templates
  `(
     ("t" "TODO")
     ("tw" "TODO Work" entry (file+olp+datetree ,(concat org-mode-dir "work.org"))
       "* TODO %^{Title}\n\n%?")
     ("tl" "TODO Life" entry (file+olp+datetree ,(concat org-mode-dir "life.org"))
       "* TODO %^{Title}\n\n  %?")
     ("tb" "Blog Post" entry (file+olp+datetree ,(concat org-mode-dir "blog.org"))
       "* EMPTY %^{Title}\nSCHEDULED: %^{Date to Post}t
:PROPERTIES:\n:EXPORT_FILE_NAME: %^{File Name}.html
:EXPORT_HUGO_CUSTOM_FRONT_MATTER: :type %^{Post Type|post|page}
:EXPORT_HUGO_AUTO_SET_LASTMOD: t
:END:  \n\n %?")

     ("w" "Wish List")
     ("wt" "Trip" entry (file+olp+datetree) ,(concat org-mode-dir "life.org") "* %^{Where?} \nDate: %^{When should we go?}t\n")

     ("d" "Drill" entry (file+headline ,(concat org-mode-dir "notes.org") "Drill Questions")
       "* %^{Title|Unnamed} :drill: \n# Date Entered: %u\n%?\n\n** Answer\n%x")

     ("df" "Drill Factoid" entry (file+headline ,(concat org-mode-dir "notes.org") "Drill Questions")
       "* %^{Title|Factoid} :drill: \n# Date Entered: %u\n%x%?")

     ("p" "Protocol" entry (file+headline ,(concat org-mode-dir "notes.org") "Unsorted")
       "* UNFILED %^{Title|Capture_%u} \nDate: %u\n #+BEGIN_QUOTE\n%x%i\n#+END_QUOTE\n\n\n%?")

     ("L" "Protocol Link" entry (file+headline ,(concat org-mode-dir "notes.org") "Unsorted")
       "* %? [[%:link][%:description]] \nCaptured On: %U\n%i\n%x")

     ("n" "Default template" entry (file+olp+datetree ,(concat org-mode-dir "notes.org"))
       "* %^{Title}\n\n%?")

     ("b" "Books")
     ("bb" "Add Book" plain (file ,(concat org-mode-dir "books.org"))
       "%(call-interactively 'org-books-add-book )" :immediate-finish t)

     ("i" "Inline Captures")


     ("s" "Code [snippets]")
     ("sr" "[r]ust" entry (file ,(concat org-mode-dir "snippets.org"))
       "* %^{Snippet Summary?}  %(org-set-tags \"Code\")\n#+begin_src rust :tangle \"src/%^{File?|main.rs}\" :mkdirp yes :comments both \n%?\n#+end_src "
       :jump-to-captured t)
     ("st" "[t]oml" entry (file ,(concat org-mode-dir "snippets.org"))
       "* %^{Snippet Summary?}  %(org-set-tags \"Code\")\n#+begin_src conf-toml :tangle \"%^{File?|Cargo.toml} :comments both\" \n%?\n#+end_src "
       :jump-to-captured t)
     ("sb" "[b]ash" entry (file ,(concat org-mode-dir "snippets.org"))
       "* %^{Snippet Summary?}  %(org-set-tags \"Code\")\n#+begin_src bash \n %? \n#+end_src "
       :jump-to-captured t)
     ("m" "Current Capture Test"
       entry (file "notes.org")
       "* :TAG1:%^g\n%?"
       :time-prompt "t"
       :immediate-finish "f"
       :jump-to-captured "t"
       :unnarrowed "f"
       )
  ))

Org Drill

(setq
  org-drill-scope 'agenda
  org-drill-save-buffers-after-drill-sessions-p nil
  org-drill-adjust-intervals-for-early-and-late-repetitions-p t)

Org Clock Functions

TODO Update the function to format the output the way we want

TODO Add the ability for custom time stamps

Code

(require 'org-clock)
(defun jk/collect-time-entries-by-time (tstart tend depth)
  "Collect all CLOCK: entries and get the associated note"
  (let ((re (concat "^\\(\\*+[ \t]*.*\\)\\|^[ \t]*"
              org-clock-string
              "[ \t]*\\(?:\\(\\[.*?\\]\\)-+\\(\\[.*?\\]\\)\\|=>[ \t]+\\([0-9]+\\):\\([0-9]+\\)\\)"))
         (tstart (org-time-string-to-seconds tstart))
         (tend (org-time-string-to-seconds tend))
         headings timelst results)
    (save-excursion
      (goto-char (point-min))
      ;; Collect the entries
      (cl-block time-entries
        (while (re-search-forward re nil t)
          (cond
            ((match-end 1)
              (setq tmphd (org-heading-components)
                lvl (car tmphd)
                title (nth 4 tmphd)
                tags (nth 5 tmphd))
              (cond
                ((> lvl (length headings))
                  (setq headings  (nconc headings `(,title))))
                ((= lvl (length headings))
                  (setf (nth (1- lvl) headings) title))
                ((< lvl (length headings))
                  (setq headings (cl-subseq headings 0 lvl))
                  (setf (nth (1- lvl) headings) title))))
            ((match-end 3)
              (let*
                ((date (match-string-no-properties 2))
                  (ts (save-match-data (org-time-string-to-seconds
                                        (match-string-no-properties 2))))
                  (te (save-match-data (org-time-string-to-seconds
                                         (match-string-no-properties 3))))
                  (minutes (nth 1 (seconds-to-time (/ (- te ts) 60))))
                  (note-start-pos (line-beginning-position 2))
                  (note-end-pos (line-end-position 2))
                  (note (save-excursion
                          (save-match-data
                            (forward-line)
                            (re-search-forward (concat "^[ \t]*\\(" org-clock-string "\\)\\|^[ \t]*\\([0-9a-zA-Z].*\\)\\|\\(.*\\)") note-end-pos t)
                            (cond
                              ;; We only want lines that start with an AlphaNumeric Character (No headings or properties)
                              ;; And no CLOCK: lines
                              ((match-end 1) "")
                              ((match-end 2) (match-string-no-properties 2))
                              (t ""))))))
                (if (and (< tstart te) (> tend ts))
                  (setq results (nconc results (list `(,lvl ,title ,date ,headings ,minutes ,note)))))))))))
    results))

(defun org-dblock-write:ces-report (params)
  "Fill in a dynamic timesheet for Complete EDI Systems"
  (let* ((tstart (plist-get params :tstart))
          (tend (plist-get params :tend))
          (depth (or (plist-get params :depth) 2))
          (table (jk/collect-time-entries-by-time
                   tstart tend depth)))
    (insert (format "#+CAPTION: Timesheet for CES\n"))
    (insert "| Headline | Date | Hours | Note |\n|------\n")
    (let* ((totaltime 0)
            headers)
      (pcase-dolist (`(,lvl ,title ,date ,headings ,minutes ,note) table)
        (dotimes (i (min lvl depth))
          (when (not (eq (nth i headers) (nth i headings)))
            (insert (format "| %s[[*%s][%s]] | | | |\n"
                    (org-clocktable-indent-string (+ 1 i))
                    (nth i headings)
                      (nth i headings)))
            (cond ((> (length headers) i)
                    (setf (nth i headers) (nth i headings)))
              (t (setq headers (nconc headers (list (nth i headings))))))))

        (setq totaltime (+ totaltime minutes))
        (insert (format "| %s | %s | %s | %s |\n"
                  (concat (org-clocktable-indent-string lvl)
                    (format "[[*%s][%s]]" title title))
                  date
                  (org-duration-from-minutes minutes)
                  (org-shorten-string note 50)
                  )))
      (insert (format "|----\n| | TOTAL TIME| *%s* |" (org-duration-from-minutes totaltime))))
    (search-backward "Headline")
    (org-table-align)))

(defun my/prompt-for-clock-hours (date hours note)
  (interactive (list (org-read-date) (read-number "Hours: ") (read-string "Note: ")))
  (let* ((marker (or (org-get-at-bol 'org-marker)
                   (org-agenda-new-marker)))
          (buffer (marker-buffer marker)))
    (org-with-remote-undo buffer
      (with-current-buffer buffer
        (save-excursion
          (let* ((log-start (org-log-beginning t))
                  (d (org-parse-time-string date))
                  (ts (encode-time d))
                  (te (encode-time (modify-element-in-list 2 (+ hours (nth 2 d)) d))))
            (goto-char log-start)
            (insert "CLOCK:")
            (org-insert-time-stamp ts 'with-hm 'inactive)
            (insert "--")
            (org-insert-time-stamp te 'with-hm 'inactive)
            (save-excursion
              (insert "\n" note "\n"))
            (org-ctrl-c-ctrl-c)))))))

Org Styles FontThemeOrgStyle


(require 'org-faces)

;; Hide emphasis markers on formatted text
(setq org-hide-emphasis-markers t)

;; Resize Org headings
(dolist (face '((org-level-1 . 1.2)
                 (org-level-2 . 1.1)
                 (org-level-3 . 1.0)
                 (org-level-4 . 1.0)
                 (org-level-5 . 1.0)
                 (org-level-6 . 1.0)
                 (org-level-7 . 1.0)
                 (org-level-8 . 1.0))
  (set-face-attribute (car face) nil :family "BigBlueTerm437 Nerd Font Propo" :width 'ultra-expanded :height (cdr face)))

;; Make the document title a bit bigger
;; (set-face-attribute 'org-document-title nil :family "Jetbrains Mono" :weight 'bold :height 1.3)

;; Make sure certain org faces use the fixed-pitch face when variable-pitch-mode is on
(set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
(set-face-attribute 'org-table nil :inherit 'fixed-pitch)
(set-face-attribute 'org-formula nil :inherit 'fixed-pitch)
(set-face-attribute 'org-code nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
(set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
(set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
;; Set a blank header line string to create blank space at the top
(setq header-line-format "%f")

Org Movies

Once I get some time, I’d like to track the movies I want to watch, or have watched, here.

Org Present

(defun dw/org-present-prepare-slide ()
  (org-overview)
  (org-show-entry)
  (org-show-children))

(defun dw/org-present-hook ()
  (setq-local face-remapping-alist '((default (:height 1.5) variable-pitch)
                                      (header-line (:height 4.5) variable-pitch)
                                      (org-document-title (:height 1.75) org-document-title)
                                      (org-code (:height 1.55) org-code)
                                      (org-verbatim (:height 1.55) org-verbatim)
                                      (org-block (:height 1.25) org-block)
                                      (org-block-begin-line (:height 0.7) org-block)))
  (setq header-line-format nil)
  (org-display-inline-images)
  ;; Center the presentation and wrap lines
  (visual-fill-column-mode 1)
  (visual-line-mode 1)
  (dw/org-present-prepare-slide))

(defun dw/org-present-quit-hook ()
  ;;(setq-local face-remapping-alist '((default variable-pitch default)))
  (setq header-line-format nil)
  (org-present-small)
  (org-remove-inline-images)
  ;; Center the presentation and wrap lines
  (visual-fill-column-mode 0)
  (visual-line-mode 0))

(defun dw/org-present-prev ()
  (interactive)
  (org-present-prev)
  (dw/org-present-prepare-slide))

(defun dw/org-present-next ()
  (interactive)
  (org-present-next)
  (dw/org-present-prepare-slide)
  (when (fboundp 'live-crafter-add-timestamp)
    (live-crafter-add-timestamp (substring-no-properties (org-get-heading t t t t)))))

(use-package org-present
  :bind ( :map org-present-mode-keymap
          ("C-c C-n" . dw/org-present-next)
          ("C-c C-p" . dw/org-present-prev))
  :init
  (add-hook 'org-present-mode-quit-hook #'dw/org-present-quit-hook)
  :hook dw/org-present)

Org Super Agenda

(setq org-super-agenda-groups
  '(
     ;; (:name "Ignore Blog stuff"
     ;;  :discard (:file-path "blog-pers.org"
     ;;             :file-path "blog-ink.org"
     ;;             :file-path "blog-og.org"))

     (:name "Active Tasks"
       :todo "InProgress")
     (:name "On Deck"
       :todo "TODO")
     (:name "Pending Review"
       :todo "REVIEW")
     (:name "Done"
       :todo "Done")
     ;; (:name "Important"
     ;;   :priority "A")

     ;; (:name "Next"
     ;;   :priority "B")
     ;; (:name "Later"
     ;;   :priority "C")
     ;; (:name "Wishlist"
     ;;   :todo ("WANT"))
     ;; (:name "Learning"
     ;;   :tag "Learning")

     (:name "Uncategorized"
       :auto-todo t)))

(setq org-agenda-skip-scheduled-if-deadline-is-shown t)
(setq org-agenda-skip-deadline-prewarning-if-scheduled t)
(setq org-agenda-todo-ignore-deadlines -1)
(setq org-agenda-todo-ignore-deadlines 1)

(org-super-agenda-mode)
;; (org-defkey org-agenda-mode-map (kbd "'") 'my/prompt-for-clock-hours)

Ox Hugo


(use-package ox-hugo
  :ensure t
  :pin melpa
  :after ox)

Python

;; python
(autoload 'python-mode "python")
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(with-eval-after-load "python"
  ;; (setq python-indent-offset 4)
  (define-key python-mode-map (kbd "DEL") nil))

R

;; R mode
(autoload 'ess-site "ess")
(add-to-list 'auto-mode-alist '("\\.R\\'" . R-mode))

Recent Files

;; ;; add recently opened files to the menu
(require 'recentf)
(setq recentf-max-saved-items 200
  recentf-max-menu-items 20)
(recentf-mode 1)

Rust

Base Config

;; Rust Setup
(use-package rustic
  :after org
  :bind (:map rustic-mode-map
          ("M-j" . lsp-enable-imenu)
          ("M-?" . lsp-references-exclude-definition)
          ("C-c C-c a" . lsp-execute-code-action)
          ("C-c C-c r" . lsp-rename)
          ("M-." . lsp-find-definition))

  :init
  (add-hook 'rustic-mode-hook #'my-rustic-hook)
  (setq rustic-babel-auto-wrap-main nil)
  ;; comment to enable rustfmt on save
  (setq rustic-format-trigger nil)
  (setq lsp-rust-analyzer-cargo-watch-command "clippy")
  (setq rustic-lsp-client 'lsp-mode)
  (setq rustic-cargo-test-exec-command "test")
  (setq rustic-test-args "--nocapture")
  ;; (setq rustic-lsp-setup-p nil)
  (defun my-rustic-hook ()
    ;;(push 'rustic-clippy flycheck-checkers)
    ;; so that run C-c C-c C-r works without having to confirm
    (if (buffer-file-name) (setq-local buffer-save-without-query t))))

Org Babel Tangle with Rust

I am proud of this bit. On opening the org-src edit buffer, it reads the tangled file and deletes the part that is in the block we’re editing. This gives the LSP engine, eglot in our case, the necessary data for completions.

The real beauty is that the file block is hidden with narrowing and not saved when the code block we’re editing is saved or closed

;; Make sure rustic gets activated in the org-src block
(defun org-babel-edit-prep:rust (babel-info)
  ;; This gets the second item in the "babel-info" list, which holds the code in the original src block
  (setq-local src-code (nth 1 babel-info))
  (setq-local buffer-file-name (expand-file-name (->> babel-info caddr (alist-get :tangle))))
  (setq-local buffer-src-code (replace-regexp-in-string src-code "" (my-read-file-to-string (buffer-file-name))))
  (goto-char (point-max))
  (insert buffer-src-code)
  (narrow-to-region (point-min) (+ (point-min) (length src-code)))
  (rustic-mode)
  (org-src-mode))

(defun my-delete-hidden-text ()
  "Remove all text that would be revealed by a call to `widen'"
  (-let [p-start (point-max)]
    (widen)
    (delete-region p-start (point-max))))

(define-advice org-edit-src-exit
  (:before (&rest _args) remove-src-block)
  (when (eq major-mode 'rustic-mode)
    (my-delete-hidden-text)))

(define-advice org-edit-src-save
  (:before (&rest _args) remove-src-block)
  (when (eq major-mode 'rustic-mode)
    (my-delete-hidden-text)))

(defun org-babel-detangle-all ()
  (interactive)
  (setq slst '())
  (org-babel-map-src-blocks ()
    (if-let
      ((detangle-file-name (car (cdr (car (read-from-string (concat "(" header-args ")"))))))
       (emp (not (member detangle-file-name slst))))
      (progn
        (message "Detangled: %s" detangle-file-name)
        (add-to-list 'slst detangle-file-name)
        (org-babel-detangle detangle-file-name)))))

(define-key global-map "\M-d" 'org-babel-detangle-all)

Execute rust in org-mode

This section isn’t well done and needs more work.

;; (defalias 'org-babel-execute:rust #'org-babel-execute:my-rust)
;; (defun org-babel-execute:my-rust (body params)
;;   "Execute a block of Rust code with org-babel.
;;    Overwritting the default function to work out of the current project

;; If called while there's a live Rust babel process, ask user whether to
;; kill the running process."
;;   (let ((p (get-process rustic-babel-process-name)))
;;     (if (process-live-p p)
;;       (progn
;;         (rustic-process-kill-p p t)
;;         nil)
;;       (let* ((default-directory (expand-file-name "."))
;;               (project (expand-file-name "."))
;;               (dir (setq rustic-babel-dir (expand-file-name project)))
;;               (output-file (cdr (assq :tangle params)))
;;               (main-p (cdr (assq :main params)))
;;               (main (expand-file-name "main.rs" (concat dir "/src")))
;;               (wrap-main (cond ((string= main-p "yes") t)
;;                            ((string= main-p "no") nil)
;;                            (t rustic-babel-auto-wrap-main)))
;;               (include-blocks (cdr (assq :include params)))
;;               (use-blocks (cdr (assq :use params))))
;;         ;;(make-directory (file-name-directory main) t)
;;         ;; (rustic-babel-cargo-toml dir params)
;;         ;; (when use-blocks
;;         ;;  (rustic-babel-generate-modules dir use-blocks))
;;         (setq rustic-info (org-babel-get-src-block-info))
;;         (setq rustic-babel-params params)

;;         (rustic-with-spinner rustic-babel-spinner
;;           (make-spinner rustic-spinner-type t 10)
;;           '(rustic-babel-spinner (":Executing " (:eval (spinner-print rustic-babel-spinner))))
;;           (spinner-start rustic-babel-spinner))

;;         (let ((default-directory dir)
;;                (toolchain (cdr (assq :toolchain params))))
;;           ;; (write-region
;;           ;;   (concat
;;           ;;     "#![allow(unused)]\n"
;;           ;;     (if use-blocks (rustic-babel-insert-mod use-blocks) "")
;;           ;;     (if include-blocks (rustic-babel-include-blocks include-blocks) "")
;;           ;;     (if wrap-main (rustic-babel-ensure-main-wrap body) body))
;;           ;;  nil output-file nil 0)
;;           (org-babel-tangle-file (buffer-file-name))
;;           (rustic-babel-eval dir toolchain)
;;           (setq rustic-babel-src-location
;;             (set-marker (make-marker) (point) (current-buffer)))
;;           project)))))

Shackle


(require 'shackle)
;;(setq shackle-default-rule '(:select t))
(setq shackle-rules
  '((compilation-mode :noselect t)
     ("*Ido Completions*" :noselect t :other t :inhibit-window-quit t)
     ("*eshell*" :select t :same t)
     ("*Shell Command Output*" :noselect t)
     ("*shell*" :select t :same t)
     ("*Messages*" :noselect t :inhibit-window-quit t :other t)
     ("*Metahelp*" :select t :same t)
     ("*Help*" :select t :same t :inhibit-window-quit t)
     ("*Completions*" :noselect t :other t :inhibit-window-quit t)
     ("*Warnings*" :noselect t :other t :inhibit-window-quit t)
     ("*Compile-Log*" :noselect t :other t :inhibit-window-quit t)
     ("*lsp-error*" :noselect t :other t)
     ("*rust-analyzer*" :noselect t :other t)
     ("*rust-analyzer::stderr*" :noselect t :other t)
     ("*rustic-compilation*" :noselect t :other t)
     ("*ag search*" :other t)
     ;; (magit-status-mode :select t :inhibit-window-quit t :same t)
     ;; (magit-log-mode :select t :inhibit-window-quit t :same t)
     ;;projectile search
     ;;("^\\*ag search text\\:.*" :regexp t :select t :inhibit-window-quit t :same t)
     ))
(shackle-mode 1)

Smart ModeLine

(use-package smart-mode-line
  :init
  (smart-mode-line-enable))

Smart Parens

;; - layout stuff
(autoload 'smartparens-mode "smartparens")
(with-eval-after-load "smartparens"
  (require 'smartparens-config))
(add-hook 'prog-mode-hook 'smartparens-mode)

smex

(require 'smex)
(smex-initialize)
;;(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)
;; This is your old M-x.
(global-set-key (kbd "C-c M-x") 'execute-extended-command)

Tramp

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

Typescript

;; typescript
(autoload 'typescript-mode "typescript-mode")
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-mode))
(add-hook 'typescript-mode-hook
  (lambda () (setq-local flycheck-disabled-checkers '(javascript-eslint))))
(with-eval-after-load "typescript-mode"
  (setq typescript-indent-level 2))

Uniquify

;; make unique names of tabs and shit
;;(require 'uniquify)

Web

(autoload 'web-mode "web-mode")
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'" . web-mode))
(with-eval-after-load "web-mode"
  (setq web-mode-markup-indent-offset 2
    web-mode-enable-auto-expanding t
    web-mode-enable-current-element-highlight t
    web-mode-auto-close-style 2))
(add-hook 'web-mode-hook (lambda () (smartparens-mode -1)))

Whitespace Mode


;; whitespace mode y'all
;; whitespace mode conflicts with highlight-indent-guides-mode
(autoload 'whitespace-mode "whitespace-mode")
(with-eval-after-load "whitespace"
  ;; disable highlighting lines over certain limit
  (setq whitespace-line-column -1)
  ;;space-mark newline-mark
  (setq whitespace-style (quote (face lines-tail trailing tabs tab-mark)))
  ;; need to set this for special font cache I guess (https://debbugs.gnu.org/cgi/bugreport.cgi?bug=25148)
  (setq inhibit-compacting-font-caches t)
  (setq whitespace-display-mappings
    ;; all numbers are unicode codepoint in decimal. e.g. (insert-char 182 1)
    '(
       (space-mark 32 [183] [46]) ; SPACE 32 「 」, 183 MIDDLE DOT 「·」, 46 FULL STOP 「.」
       (newline-mark 10 [182 10]) ; LINE FEED,
       (tab-mark 9 [9655 9] [92 9]) ; tab
       )))
;;(global-whitespace-mode t)
;;(add-hook 'prog-mode-hook 'whitespace-mode)


;;(global-whitespace-cleanup-mode 1)
(autoload 'whitespace-cleanup-mode "whitespace-cleanup-mode")
(add-hook 'prog-mode-hook 'whitespace-cleanup-mode)

Yasnippet

(use-package yasnippet
  :ensure
  :config
  (yas-reload-all)
  (add-hook 'prog-mode-hook 'yas-minor-mode)
  (add-hook 'text-mode-hook 'yas-minor-mode))

(defun company-yasnippet-or-completion ()
  (interactive)
  (or (do-yas-expand)
    (company-complete-common)))

(defun check-expansion ()
  (save-excursion
    (if (looking-at "\\_>") t
      (backward-char 1)
      (if (looking-at "\\.") t
        (backward-char 1)
        (if (looking-at "::") t nil)))))

(defun do-yas-expand ()
  (let ((yas/fallback-behavior 'return-nil))
    (yas/expand)))

(defun tab-indent-or-complete ()
  (interactive)
  (if (minibufferp)
    (minibuffer-complete)
    (if (or (not yas/minor-mode)
          (null (do-yas-expand)))
      (company-indent-or-complete-common "P"))))

;;(use-package wgsl-mode)

DAP Mode

(require 'dap-mode)
(require 'dap-netcore)
(setq dap-auto-configure-features '(sessions locals breakpoints expressions controls))
(dap-ui-controls-mode 1)
(dap-ui-mode 1)
;; enables mouse hover support
(dap-tooltip-mode 1)
;; use tooltips for mouse hover
;; if it is not enabled `dap-mode' will use the minibuffer.
(tooltip-mode 1)

(add-hook 'dap-mode-hook
  (lambda () (local-set-key (kbd "M-o") 'dap-debug-last)))
(add-hook 'dap-mode-hook
  (lambda () (local-set-key (kbd "M-i") 'dap-debug)))
(add-hook 'dap-mode-hook
  (lambda () (local-set-key (kbd "M-q") 'dap-disconnect)))