Change-Id: I171e06f67abec2ccc60ec0ff444d7d5b0378485d Reviewed-on: https://cl.tvl.fyi/c/depot/+/5436 Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
		
			
				
	
	
		
			1121 lines
		
	
	
	
		
			33 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
			
		
		
	
	
			1121 lines
		
	
	
	
		
			33 KiB
		
	
	
	
		
			EmacsLisp
		
	
	
	
	
	
| ;;; -*- lexical-binding: t; -*-
 | ||
| 
 | ||
| ;; I've swapped these keys on my keyboard
 | ||
| (setq x-super-keysym 'alt
 | ||
|       x-alt-keysym   'meta)
 | ||
| 
 | ||
| (setq user-mail-address "root@gws.fyi"
 | ||
|       user-full-name    "Griffin Smith")
 | ||
| 
 | ||
| (let ((font-family (pcase system-type
 | ||
|                      ('darwin "MesloLGSDZ NF")
 | ||
|                      ('gnu/linux "Meslo LGSDZ Nerd Font"))))
 | ||
|   (setq doom-font (font-spec :family font-family :size 14)
 | ||
|         doom-big-font (font-spec :family font-family :size 24)
 | ||
|         doom-big-font-increment 5
 | ||
|         doom-variable-pitch-font (font-spec :family font-family)
 | ||
|         doom-unicode-font (font-spec :family font-family)))
 | ||
| 
 | ||
| (require 's)
 | ||
| 
 | ||
| (undefine-key! :keymaps 'doom-leader-map "/")
 | ||
| 
 | ||
| (load! "utils")
 | ||
| (load! "company-sql")
 | ||
| (load! "show-matching-paren")
 | ||
| (load! "irc")
 | ||
| (load! "github-org")
 | ||
| (load! "org-gcal")
 | ||
| (load! "grid")
 | ||
| (load! "nix")
 | ||
| (load! "email")
 | ||
| (load! "cpp")
 | ||
| (load! "lisp")
 | ||
| (load! "clojure")
 | ||
| (load! "rust")
 | ||
| (load! "terraform")
 | ||
| 
 | ||
| (require 'tvl)
 | ||
| 
 | ||
| (add-hook! elixir-mode
 | ||
|   (require 'flycheck-credo)
 | ||
|   (setq flycheck-elixir-credo-strict t)
 | ||
|   (flycheck-credo-setup)
 | ||
| 
 | ||
|   (require 'flycheck-mix) (flycheck-mix-setup)
 | ||
| 
 | ||
|   (require 'flycheck-dialyxir) (flycheck-dialyxir-setup)
 | ||
| 
 | ||
|   (flycheck-mode))
 | ||
| 
 | ||
| (setq +solarized-s-base03    "#002b36"
 | ||
|       +solarized-s-base02    "#073642"
 | ||
|       ;; emphasized content
 | ||
|       +solarized-s-base01    "#586e75"
 | ||
|       ;; primary content
 | ||
|       +solarized-s-base00    "#657b83"
 | ||
|       +solarized-s-base0     "#839496"
 | ||
|       ;; comments
 | ||
|       +solarized-s-base1     "#93a1a1"
 | ||
|       ;; background highlight light
 | ||
|       +solarized-s-base2     "#eee8d5"
 | ||
|       ;; background light
 | ||
|       +solarized-s-base3     "#fdf6e3"
 | ||
| 
 | ||
|       ;; Solarized accented colors
 | ||
|       +solarized-yellow    "#b58900"
 | ||
|       +solarized-orange    "#cb4b16"
 | ||
|       +solarized-red       "#dc322f"
 | ||
|       +solarized-magenta   "#d33682"
 | ||
|       +solarized-violet    "#6c71c4"
 | ||
|       +solarized-blue      "#268bd2"
 | ||
|       +solarized-cyan      "#2aa198"
 | ||
|       +solarized-green     "#859900"
 | ||
| 
 | ||
|       ;; Darker and lighter accented colors
 | ||
|       ;; Only use these in exceptional circumstances!
 | ||
|       +solarized-yellow-d  "#7B6000"
 | ||
|       +solarized-yellow-l  "#DEB542"
 | ||
|       +solarized-orange-d  "#8B2C02"
 | ||
|       +solarized-orange-l  "#F2804F"
 | ||
|       +solarized-red-d     "#990A1B"
 | ||
|       +solarized-red-l     "#FF6E64"
 | ||
|       +solarized-magenta-d "#93115C"
 | ||
|       +solarized-magenta-l "#F771AC"
 | ||
|       +solarized-violet-d  "#3F4D91"
 | ||
|       +solarized-violet-l  "#9EA0E5"
 | ||
|       +solarized-blue-d    "#00629D"
 | ||
|       +solarized-blue-l    "#69B7F0"
 | ||
|       +solarized-cyan-d    "#00736F"
 | ||
|       +solarized-cyan-l    "#69CABF"
 | ||
|       +solarized-green-d   "#546E00"
 | ||
|       +solarized-green-l "#B4C342")
 | ||
| 
 | ||
| (defcustom theme-overrides nil
 | ||
|   "Association list of override faces to set for different custom themes.")
 | ||
| 
 | ||
| (defadvice load-theme (after theme-set-overrides activate)
 | ||
|   (dolist (theme-settings theme-overrides)
 | ||
|     (let ((theme (car theme-settings))
 | ||
|           (faces (cadr theme-settings)))
 | ||
|       (if (member theme custom-enabled-themes)
 | ||
|           (progn
 | ||
|             (dolist (face faces)
 | ||
|               (custom-theme-set-faces theme face)))))))
 | ||
| 
 | ||
| (defun alist-set (alist-symbol key value)
 | ||
|   "Set VALUE of a KEY in ALIST-SYMBOL."
 | ||
|   (set alist-symbol (cons (list key value) (assq-delete-all key (eval alist-symbol)))))
 | ||
| 
 | ||
| (comment
 | ||
|  (custom-theme-set-faces 'grfn-solarized-light
 | ||
|                          `(font-lock-doc-face
 | ||
|                            ((t (:foreground ,+solarized-s-base1)))))
 | ||
| 
 | ||
| +solarized-s-base1
 | ||
| (custom-theme-)
 | ||
|  (custom-face-get-current-spec 'font-lock-doc-face)
 | ||
| 
 | ||
|  )
 | ||
| 
 | ||
| (alist-set 'theme-overrides 'grfn-solarized-light
 | ||
|            `((font-lock-doc-face ((t (:foreground ,+solarized-s-base1))))
 | ||
|              (font-lock-preprocessor-face ((t (:foreground ,+solarized-red))))
 | ||
|              (font-lock-keyword-face ((t (:foreground ,+solarized-green :bold nil))))
 | ||
|              (font-lock-builtin-face ((t (:foreground ,+solarized-s-base01
 | ||
|                                                       :bold t))))
 | ||
| 
 | ||
|              (elixir-attribute-face ((t (:foreground ,+solarized-blue))))
 | ||
|              (elixir-atom-face ((t (:foreground ,+solarized-cyan))))
 | ||
|              (linum ((t (:background ,+solarized-s-base2 :foreground ,+solarized-s-base1))))
 | ||
|              (line-number ((t (:background ,+solarized-s-base2 :foreground ,+solarized-s-base1))))
 | ||
|              (line-number-current-line ((t (:background ,+solarized-s-base2 :foreground ,+solarized-s-base1))))
 | ||
| 
 | ||
|              (haskell-operator-face ((t (:foreground ,+solarized-green))))
 | ||
|              (haskell-keyword-face ((t (:foreground ,+solarized-cyan))))
 | ||
| 
 | ||
|              (org-drawer ((t (:foreground ,+solarized-s-base1
 | ||
|                               :bold t))))))
 | ||
| 
 | ||
| (setq solarized-use-variable-pitch nil
 | ||
|       solarized-scale-org-headlines nil
 | ||
|       solarized-use-less-bold t)
 | ||
| 
 | ||
| (add-to-list 'custom-theme-load-path "~/.doom.d/themes")
 | ||
| (load-theme 'grfn-solarized-light t)
 | ||
| 
 | ||
| (defface haskell-import-face `((t (:foreground ,+solarized-magenta))) "")
 | ||
| 
 | ||
| (setq doom-theme 'grfn-solarized-light)
 | ||
| ; (setq doom-theme 'doom-solarized-light)
 | ||
| 
 | ||
| (add-hook! doom-post-init
 | ||
|   (set-face-attribute 'bold nil :weight 'ultra-light)
 | ||
|   (set-face-bold 'bold nil)
 | ||
|   (enable-theme 'grfn-solarized-light))
 | ||
| 
 | ||
| (defun rx-words (&rest words)
 | ||
|   (rx-to-string
 | ||
|    `(and symbol-start (group (or ,@words)) symbol-end)))
 | ||
| 
 | ||
| (font-lock-add-keywords
 | ||
|  'elixir-mode
 | ||
|  `((,(rx-words "def"
 | ||
|                "defp"
 | ||
|                "test"
 | ||
|                "describe"
 | ||
|                "property"
 | ||
|                "defrecord"
 | ||
|                "defmodule"
 | ||
|                "defstruct"
 | ||
|                "defdelegate"
 | ||
|                "defprotocol"
 | ||
|                "defimpl"
 | ||
|                "use"
 | ||
|                "import"
 | ||
|                "alias"
 | ||
|                "require"
 | ||
|                "assert"
 | ||
|                "refute"
 | ||
|                "assert_raise")
 | ||
|     .
 | ||
|     'font-lock-preprocessor-face)))
 | ||
| 
 | ||
| (font-lock-add-keywords
 | ||
|  'elixir-mode
 | ||
|  `((,(rx-words "def"
 | ||
|                "defp"
 | ||
|                "test"
 | ||
|                "describe"
 | ||
|                "property"
 | ||
|                "defrecord"
 | ||
|                "defmodule"
 | ||
|                "defstruct"
 | ||
|                "defdelegate"
 | ||
|                "use"
 | ||
|                "import"
 | ||
|                "alias"
 | ||
|                "require"
 | ||
|                "assert"
 | ||
|                "refute"
 | ||
|                "assert_raise")
 | ||
|     .
 | ||
|     'font-lock-preprocessor-face)))
 | ||
| 
 | ||
| (font-lock-add-keywords
 | ||
|  'haskell-mode
 | ||
|  `((,(rx-words "import") . 'haskell-import-face)))
 | ||
| 
 | ||
| ;; (font-lock-add-keywords
 | ||
| ;;  'haskell-mode
 | ||
| ;;  `((,(rx "-- |") . 'haskell-keyword-face)))
 | ||
| 
 | ||
| 
 | ||
| ;; (load-file (let ((coding-system-for-read 'utf-8))
 | ||
| ;;                 (shell-command-to-string "agda-mode locate")))
 | ||
| 
 | ||
| (defvar +grfn-dir (file-name-directory load-file-name))
 | ||
| (defvar +grfn-snippets-dir (expand-file-name "snippets/" +grfn-dir))
 | ||
| 
 | ||
| ;;
 | ||
| (load! "+bindings")
 | ||
| (load! "+commands")
 | ||
| (load! "cpp")
 | ||
| 
 | ||
| 
 | ||
| (add-to-list 'load-path "/home/grfn/code/org-tracker")
 | ||
| (require 'org-tracker)
 | ||
| (use-package! org-tracker
 | ||
|   :hook (org-mode . org-tracker-mode)
 | ||
|   :config
 | ||
|   (setq org-tracker-state-alist '(("INBOX" . "Inbox")
 | ||
|                                   ("BACKLOG" . "Backlog")
 | ||
|                                   ("TODO" . "Selected for Development")
 | ||
|                                   ("ACTIVE" . "In Progress")
 | ||
|                                   ("PR" . "Code Review")
 | ||
|                                   ("DONE" . "Done"))
 | ||
|         org-tracker-username "griffin@readyset.io"
 | ||
|         org-tracker-claim-ticket-on-status-update '("ACTIVE" "PR" "DONE")
 | ||
|         org-tracker-create-stories-with-labels 'existing)
 | ||
| 
 | ||
|   (defun org-tracker-headlines-from-assigned-to-me (level)
 | ||
|     (interactive "*nLevel: ")
 | ||
|     (funcall-interactively
 | ||
|      #'org-tracker-headlines-from-search
 | ||
|      level
 | ||
|      "assignee = currentUser() and statusCategory = 2")))
 | ||
| 
 | ||
| (load! "+private")
 | ||
| 
 | ||
| (require 'dash)
 | ||
| 
 | ||
| (use-package! predd)
 | ||
| 
 | ||
| 
 | ||
| ;;
 | ||
| ;; Global config
 | ||
| ;;
 | ||
| 
 | ||
| (setq doom-modeline-buffer-file-name-style 'relative-to-project
 | ||
|       doom-modeline-modal-icon nil
 | ||
|       doom-modeline-github t)
 | ||
| 
 | ||
| ;;
 | ||
| ;; Modules
 | ||
| ;;
 | ||
| 
 | ||
| (after! smartparens
 | ||
|   ;; Auto-close more conservatively and expand braces on RET
 | ||
|   (let ((unless-list '(sp-point-before-word-p
 | ||
|                        sp-point-after-word-p
 | ||
|                        sp-point-before-same-p)))
 | ||
|     (sp-pair "'"  nil :unless unless-list)
 | ||
|     (sp-pair "\"" nil :unless unless-list))
 | ||
|   (sp-pair "{" nil :post-handlers '(("||\n[i]" "RET") ("| " " "))
 | ||
|            :unless '(sp-point-before-word-p sp-point-before-same-p))
 | ||
|   (sp-pair "(" nil :post-handlers '(("||\n[i]" "RET") ("| " " "))
 | ||
|            :unless '(sp-point-before-word-p sp-point-before-same-p))
 | ||
|   (sp-pair "[" nil :post-handlers '(("| " " "))
 | ||
|            :unless '(sp-point-before-word-p sp-point-before-same-p)))
 | ||
| 
 | ||
| ;; feature/snippets
 | ||
| (after! yasnippet
 | ||
|   ;; Don't use default snippets, use mine.
 | ||
|   (setq yas-snippet-dirs
 | ||
|         (append (list '+grfn-snippets-dir)
 | ||
|                 (delq 'yas-installed-snippets-dir yas-snippet-dirs))))
 | ||
| 
 | ||
| (after! company
 | ||
|   (setq company-idle-delay 0.2
 | ||
|         company-minimum-prefix-length 1))
 | ||
| 
 | ||
| (setq doom-modeline-height 12)
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| ;; Should really figure out which of these is correct, eventually
 | ||
| 
 | ||
| (setq +solarized-s-base03    "#002b36"
 | ||
|       +solarized-s-base02    "#073642"
 | ||
|       ;; emphasized content
 | ||
|       +solarized-s-base01    "#586e75"
 | ||
|       ;; primary content
 | ||
|       +solarized-s-base00    "#657b83"
 | ||
|       +solarized-s-base0     "#839496"
 | ||
|       ;; comments
 | ||
|       +solarized-s-base1     "#93a1a1"
 | ||
|       ;; background highlight light
 | ||
|       +solarized-s-base2     "#eee8d5"
 | ||
|       ;; background light
 | ||
|       +solarized-s-base3     "#fdf6e3"
 | ||
| 
 | ||
|       ;; Solarized accented colors
 | ||
|       +solarized-yellow    "#b58900"
 | ||
|       +solarized-orange    "#cb4b16"
 | ||
|       +solarized-red       "#dc322f"
 | ||
|       +solarized-magenta   "#d33682"
 | ||
|       +solarized-violet    "#6c71c4"
 | ||
|       +solarized-blue      "#268bd2"
 | ||
|       +solarized-cyan      "#2aa198"
 | ||
|       +solarized-green     "#859900"
 | ||
| 
 | ||
|       ;; Darker and lighter accented colors
 | ||
|       ;; Only use these in exceptional circumstances!
 | ||
|       +solarized-yellow-d  "#7B6000"
 | ||
|       +solarized-yellow-l  "#DEB542"
 | ||
|       +solarized-orange-d  "#8B2C02"
 | ||
|       +solarized-orange-l  "#F2804F"
 | ||
|       +solarized-red-d     "#990A1B"
 | ||
|       +solarized-red-l     "#FF6E64"
 | ||
|       +solarized-magenta-d "#93115C"
 | ||
|       +solarized-magenta-l "#F771AC"
 | ||
|       +solarized-violet-d  "#3F4D91"
 | ||
|       +solarized-violet-l  "#9EA0E5"
 | ||
|       +solarized-blue-d    "#00629D"
 | ||
|       +solarized-blue-l    "#69B7F0"
 | ||
|       +solarized-cyan-d    "#00736F"
 | ||
|       +solarized-cyan-l    "#69CABF"
 | ||
|       +solarized-green-d   "#546E00"
 | ||
|       +solarized-green-l "#B4C342")
 | ||
| 
 | ||
| (set-cursor-color +solarized-s-base02)
 | ||
| 
 | ||
| (after! doom-theme
 | ||
|   (set-face-foreground 'font-lock-doc-face +solarized-s-base1)
 | ||
|   (set-face-foreground 'org-block +solarized-s-base00)
 | ||
|   (set-face-foreground 'slack-message-output-header +solarized-s-base01)
 | ||
|   (set-face-attribute 'slack-message-output-header nil :underline nil)
 | ||
|   (set-face-attribute 'slack-message-output-text nil :height 1.0)
 | ||
|   )
 | ||
| 
 | ||
| (after! solarized-theme
 | ||
|   (set-face-foreground 'font-lock-doc-face +solarized-s-base1)
 | ||
|   (set-face-foreground 'org-block +solarized-s-base00)
 | ||
| 
 | ||
|   (set-face-foreground 'slack-message-output-header +solarized-s-base01)
 | ||
|   (set-face-attribute 'slack-message-output-header nil :underline nil)
 | ||
|   (set-face-attribute 'slack-message-output-text nil :height 1.0)
 | ||
|   )
 | ||
| 
 | ||
| (after! evil
 | ||
|   (setq evil-shift-width 2))
 | ||
| 
 | ||
| (after! org
 | ||
|   (load! "org-query")
 | ||
|   (load! "org-config"))
 | ||
| 
 | ||
| (after! magit
 | ||
|   (setq git-commit-summary-max-length 50))
 | ||
| 
 | ||
| (after! ivy
 | ||
|   ;; (setq ivy-re-builders-alist
 | ||
|   ;;       '((t . ivy--regex-fuzzy)))
 | ||
|   )
 | ||
| 
 | ||
| (add-hook 'before-save-hook 'delete-trailing-whitespace)
 | ||
| 
 | ||
| (after! paxedit
 | ||
|   (add-hook! emacs-lisp-mode #'paxedit-mode)
 | ||
|   (add-hook! clojure-mode #'paxedit-mode)
 | ||
|   (add-hook! common-lisp-mode #'paxedit-mode))
 | ||
| 
 | ||
| (require 'haskell)
 | ||
| 
 | ||
| (let ((m-symbols
 | ||
|       '(("`mappend`" . "⊕")
 | ||
|         ("<>"        . "⊕")
 | ||
|         ("`elem`"   . "∈")
 | ||
|         ("`notElem`" . "∉"))))
 | ||
|   (dolist (item m-symbols) (add-to-list 'haskell-font-lock-symbols-alist item)))
 | ||
| 
 | ||
| (setq haskell-font-lock-symbols t)
 | ||
| 
 | ||
| 
 | ||
| (add-hook! haskell-mode
 | ||
|   ;; (intero-mode)
 | ||
|   (lsp-mode)
 | ||
|   ;; (flycheck-add-next-checker
 | ||
|   ;;  'intero
 | ||
|   ;;  'haskell-hlint)
 | ||
|   (set-fill-column 80)
 | ||
|   (setq evil-shift-width 2))
 | ||
| 
 | ||
| (auth-source-pass-enable)
 | ||
| 
 | ||
| (require 'fill-column-indicator)
 | ||
| ;;; * Column Marker
 | ||
| (defun sanityinc/fci-enabled-p () (symbol-value 'fci-mode))
 | ||
| 
 | ||
| (defvar sanityinc/fci-mode-suppressed nil)
 | ||
| (make-variable-buffer-local 'sanityinc/fci-mode-suppressed)
 | ||
| 
 | ||
| (defadvice popup-create (before suppress-fci-mode activate)
 | ||
|   "Suspend fci-mode while popups are visible"
 | ||
|   (let ((fci-enabled (sanityinc/fci-enabled-p)))
 | ||
|     (when fci-enabled
 | ||
|       (setq sanityinc/fci-mode-suppressed fci-enabled)
 | ||
|       (turn-off-fci-mode))))
 | ||
| 
 | ||
| (defadvice popup-delete (after restore-fci-mode activate)
 | ||
|   "Restore fci-mode when all popups have closed"
 | ||
|   (when (and sanityinc/fci-mode-suppressed
 | ||
|              (null popup-instances))
 | ||
|     (setq sanityinc/fci-mode-suppressed nil)
 | ||
|     (turn-on-fci-mode)))
 | ||
| 
 | ||
| 
 | ||
| ;;; Javascript
 | ||
| 
 | ||
| (require 'smartparens)
 | ||
| 
 | ||
| (setq js-indent-level 2)
 | ||
| 
 | ||
| (require 'prettier-js)
 | ||
| (after! prettier-js
 | ||
|   (add-hook! rjsx-mode #'prettier-js-mode)
 | ||
|   (add-hook! js2-mode  #'prettier-js-mode)
 | ||
|   (add-hook! json-mode #'prettier-js-mode)
 | ||
|   (add-hook! css-mode  #'prettier-js-mode))
 | ||
| 
 | ||
| (remove-hook 'js2-mode-hook 'tide-setup t)
 | ||
| 
 | ||
| ;; Set this to the mode you use, I use rjsx-mode
 | ||
| (add-hook 'rjsx-mode-hook #'flow/set-flow-executable t)
 | ||
| 
 | ||
| 
 | ||
| ;; Auto-format Haskell on save, with a combination of hindent + brittany
 | ||
| 
 | ||
| ; (define-minor-mode brittany-haskell-mode
 | ||
| ;   :init-value nil
 | ||
| ;   :group 'haskell
 | ||
| ;   :lighter "Brittany-Haskell"
 | ||
| ;   :keymap '()
 | ||
| ;   )
 | ||
| 
 | ||
| 
 | ||
| (require 'alert)
 | ||
| (setq alert-default-style 'libnotify)
 | ||
| 
 | ||
| ;; (setq slack-buffer-function #'switch-to-buffer)
 | ||
| 
 | ||
| (setq projectile-test-suffix-function
 | ||
|       (lambda (project-type)
 | ||
|         (case project-type
 | ||
|           ('haskell-stack "Test")
 | ||
|           ('npm ".test")
 | ||
|           (otherwise (projectile-test-suffix project-type)))))
 | ||
| 
 | ||
| (setq projectile-create-missing-test-files 't)
 | ||
| 
 | ||
| (setq grfn/jira-refs-re
 | ||
|       (rx line-start
 | ||
|           (or "Refs" "Fixes")
 | ||
|           ": "
 | ||
|           "ENG-" (one-or-more digit)
 | ||
|           line-end))
 | ||
| 
 | ||
| (defun grfn/add-jira-reference-to-commit-message ()
 | ||
|   (interactive)
 | ||
|   (when-let* ((jira-id (grfn/org-clocked-in-jira-ticket-id)))
 | ||
|     (save-excursion
 | ||
|       (save-match-data
 | ||
|         (goto-char (point-min))
 | ||
|         ;; Don't add one if we've already got one
 | ||
|         (unless (search-forward-regexp grfn/jira-refs-re nil t)
 | ||
|           (or
 | ||
|            (and
 | ||
|             (search-forward-regexp (rx line-start "Change-Id:") nil t)
 | ||
|             (forward-line -1))
 | ||
|            (and
 | ||
|             (search-forward-regexp (rx line-start "# Please enter") nil t)
 | ||
|             (forward-line -2)))
 | ||
|           (insert (format "\nRefs: %s" jira-id)))))))
 | ||
| 
 | ||
| (defun grfn/switch-jira-refs-fixes ()
 | ||
|   (interactive)
 | ||
|   (save-excursion
 | ||
|     (save-match-data
 | ||
|       (if (not (search-forward-regexp grfn/jira-refs-re nil t))
 | ||
|           (message "Could not find reference to JIRA ticket")
 | ||
|         (goto-char (point-at-bol))
 | ||
|         (save-restriction
 | ||
|           (narrow-to-region (point-at-bol)
 | ||
|                             (point-at-eol))
 | ||
|           (or
 | ||
|            (and (search-forward "Refs" nil t)
 | ||
|                 (replace-match "Fixes"))
 | ||
|            (and (search-forward "Fixes" nil t)
 | ||
|                 (replace-match "Refs"))))))))
 | ||
| 
 | ||
| (after! magit
 | ||
|   (map! :map magit-mode-map
 | ||
|         ;; :n "] ]" #'magit-section-forward
 | ||
|         ;; :n "[ [" #'magit-section-backward
 | ||
|         )
 | ||
| 
 | ||
|   (define-suffix-command magit-commit-wip ()
 | ||
|     (interactive)
 | ||
|     (magit-commit-create '("-m" "wip")))
 | ||
| 
 | ||
|   (transient-append-suffix
 | ||
|     #'magit-commit
 | ||
|     ["c"]
 | ||
|     (list "W" "Commit WIP" #'magit-commit-wip))
 | ||
| 
 | ||
|   (define-suffix-command magit-reset-head-back ()
 | ||
|     (interactive)
 | ||
|     (magit-reset-mixed "HEAD~"))
 | ||
| 
 | ||
|   (define-suffix-command magit-reset-head-previous ()
 | ||
|     (interactive)
 | ||
|     (magit-reset-mixed "HEAD@{1}"))
 | ||
| 
 | ||
|   (transient-append-suffix
 | ||
|     #'magit-reset
 | ||
|     ["f"]
 | ||
|     (list "b" "Reset HEAD~"    #'magit-reset-head-back))
 | ||
|   (transient-append-suffix
 | ||
|     #'magit-reset
 | ||
|     ["f"]
 | ||
|     (list "o" "Reset HEAD@{1}" #'magit-reset-head-previous))
 | ||
| 
 | ||
|   (defun magit-read-org-tracker-branch-name ()
 | ||
|     (when-let ((issue-id (org-tracker-clocked-in-issue-id)))
 | ||
|       (let ((desc
 | ||
|              (magit-read-string-ns
 | ||
|               (format "Issue description (to go after gs/%s/)"
 | ||
|                       issue-id))))
 | ||
|         (format "gs/%s/%s" issue-id desc))))
 | ||
| 
 | ||
|   (defun magit-read-org-tracker-branch-args ()
 | ||
|     (if-let ((issue-id (org-tracker-clocked-in-issue-id)))
 | ||
|         (let ((start-point (magit-read-starting-point
 | ||
|                             "Create and checkout branch for Tracker issue"
 | ||
|                             nil
 | ||
|                             "origin/master")))
 | ||
|           (if (magit-rev-verify start-point)
 | ||
|               (when-let ((desc (magit-read-org-tracker-branch-name)))
 | ||
|                 (list desc start-point))
 | ||
|             (user-error "Not a valid starting point: %s" choice)))
 | ||
|       (user-error "No currently clocked-in tracker issue")))
 | ||
| 
 | ||
|   (transient-define-suffix magit-checkout-org-tracker-branch (branch start-point)
 | ||
|     (interactive (magit-read-org-tracker-branch-args))
 | ||
|     (magit-branch-and-checkout branch start-point))
 | ||
| 
 | ||
|   (transient-define-suffix magit-rename-org-tracker-branch (old new)
 | ||
|     (interactive
 | ||
|      (let ((branch (magit-read-local-branch "Rename branch")))
 | ||
|        (list branch (magit-read-org-tracker-branch-name))))
 | ||
|     (when (and old new)
 | ||
|       (magit-branch-rename old new)))
 | ||
| 
 | ||
|   (transient-append-suffix
 | ||
|     #'magit-branch
 | ||
|     ["c"]
 | ||
|     (list "C" "Checkout Tracker branch" #'magit-checkout-org-tracker-branch))
 | ||
|   (transient-append-suffix
 | ||
|     #'magit-branch
 | ||
|     ["c"]
 | ||
|     (list "M" "Rename branch to Tracker ticket" #'magit-rename-org-tracker-branch))
 | ||
| 
 | ||
|   )
 | ||
| 
 | ||
| (add-hook 'git-commit-setup-hook #'grfn/add-jira-reference-to-commit-message)
 | ||
| (map! (:map git-commit-mode-map
 | ||
|        "C-c C-f" #'grfn/switch-jira-refs-fixes))
 | ||
| 
 | ||
| ;; (defun grfn/split-window-more-sensibly (&optional window)
 | ||
| ;;   (let ((window (or window (selected-window))))
 | ||
| ;;     (or (and (window-splittable-p window)
 | ||
| ;;              ;; Split window vertically.
 | ||
| ;;              (with-selected-window window
 | ||
| ;;                (split-window-right)))
 | ||
| ;;         (and (window-splittable-p window t)
 | ||
| ;;              ;; Split window horizontally.
 | ||
| ;;              (with-selected-window window
 | ||
| ;;                (split-window-right)))
 | ||
| ;;         (and (eq window (frame-root-window (window-frame window)))
 | ||
| ;;              (not (window-minibuffer-p window))
 | ||
| ;;              ;; If WINDOW is the only window on its frame and is not the
 | ||
| ;;              ;; minibuffer window, try to split it vertically disregarding
 | ||
| ;;              ;; the value of `split-height-threshold'.
 | ||
| ;;              (let ((split-height-threshold 0))
 | ||
| ;;                (when (window-splittable-p window)
 | ||
| ;;                  (with-selected-window window
 | ||
| ;;                    (split-window-below))))))))
 | ||
| 
 | ||
| (use-package! lsp-mode
 | ||
|   :after (:any haskell-mode)
 | ||
|   :config
 | ||
|   (setq lsp-response-timeout 60)
 | ||
|   :hook
 | ||
|   (haskell-mode . lsp-mode))
 | ||
| 
 | ||
| (use-package! lsp-ui
 | ||
|   :after lsp-mode
 | ||
|   :config
 | ||
|   (defun +grfn/lsp-ui-doc-frame-hook (frame window)
 | ||
|     (set-frame-font (if doom-big-font-mode doom-big-font doom-font)
 | ||
|                     nil (list frame)))
 | ||
|   (setq lsp-ui-flycheck-enable t
 | ||
|         lsp-ui-doc-header nil
 | ||
|         lsp-ui-doc-position 'top
 | ||
|         lsp-ui-doc-alignment 'window
 | ||
|         lsp-ui-doc-frame-hook '+grfn/lsp-ui-doc-frame-hook
 | ||
|         lsp-ui-doc-max-width 150
 | ||
|         lsp-ui-doc-max-height 13)
 | ||
|   (setq imenu-auto-rescan t)
 | ||
|   (set-face-background 'lsp-ui-doc-background +solarized-s-base2)
 | ||
|   (set-face-background 'lsp-face-highlight-read +solarized-s-base2)
 | ||
|   (set-face-background 'lsp-face-highlight-write +solarized-s-base2)
 | ||
|   :hook
 | ||
|   (lsp-mode . lsp-ui-mode)
 | ||
|   (lsp-ui-mode . flycheck-mode))
 | ||
| 
 | ||
| (use-package! company-lsp
 | ||
|   :after (lsp-mode lsp-ui)
 | ||
|   :config
 | ||
|   (add-to-list #'company-backends #'company-lsp)
 | ||
|   (setq company-lsp-async t))
 | ||
| 
 | ||
| (defun +grfn/haskell-mode-setup ()
 | ||
|   (interactive)
 | ||
|   (flymake-mode -1)
 | ||
|   (add-to-list 'flycheck-disabled-checkers 'haskell-ghc)
 | ||
| 
 | ||
|   (flycheck-remove-next-checker 'lsp 'haskell-ghc)
 | ||
|   (flycheck-add-next-checker 'lsp '(warning . haskell-hlint))
 | ||
| 
 | ||
|   ;; If there’s a 'hie.sh' defined locally by a project
 | ||
|   ;; (e.g. to run HIE in a nix-shell), use it…
 | ||
|   (when-let ((project-dir (locate-dominating-file default-directory "hie.sh")))
 | ||
|     (cl-flet
 | ||
|         ((which (cmd)
 | ||
|                 (s-trim
 | ||
|                  (shell-command-to-string
 | ||
|                   (concat
 | ||
|                    "nix-shell "
 | ||
|                    (expand-file-name "shell.nix" project-dir)
 | ||
|                    " --run \"which " cmd "\" 2>/dev/null")))))
 | ||
|       (setq-local
 | ||
|        lsp-haskell-process-path-hie (expand-file-name "hie.sh" project-dir)
 | ||
|        haskell-hoogle-command (which "hoogle"))))
 | ||
|   ;; … and only then setup the LSP.
 | ||
|   (lsp))
 | ||
| 
 | ||
| (defun never-flymake-mode (orig &rest args)
 | ||
|   (when (and (bound-and-true-p flymake-mode))
 | ||
|     (funcall orig 0)
 | ||
|     (message "disabled flymake-mode")))
 | ||
| (advice-add #'flymake-mode :around #'never-flymake-mode)
 | ||
| 
 | ||
| (defun +grfn/wrap-lsp-haskell-process (argv)
 | ||
|   (let* ((project-dir (locate-dominating-file
 | ||
|                        (buffer-file-name)
 | ||
|                        "hie.yaml"))
 | ||
|          (shell-dot-nix (expand-file-name "shell.nix" project-dir)))
 | ||
|     ;; (when (string-equal default-directory "/home/grfn/code/depot")
 | ||
|     ;;   (debug))
 | ||
|     (message "%s %s %s %s"
 | ||
|              (buffer-file-name)
 | ||
|              default-directory
 | ||
|              project-dir
 | ||
|              shell-dot-nix)
 | ||
|     (if (file-exists-p shell-dot-nix)
 | ||
|         `("bash" "-c"
 | ||
|           ,(format "cd %s && nix-shell %s --run '%s'"
 | ||
|                    project-dir
 | ||
|                    shell-dot-nix
 | ||
|                    (s-join " " argv)))
 | ||
|       argv)))
 | ||
| 
 | ||
| (use-package! lsp-haskell
 | ||
|   :after (lsp-mode lsp-ui haskell-mode)
 | ||
|   ;; :hook
 | ||
|   ;; (haskell-mode . lsp-haskell-enable)
 | ||
|   :config
 | ||
|   (setq lsp-haskell-process-path-hie "haskell-language-server-wrapper"
 | ||
|         lsp-haskell-process-args-hie
 | ||
|         '("-d" "-l" "/tmp/hie.log" "+RTS" "-M4G" "-H1G" "-K4G" "-A16M" "-RTS")
 | ||
|         lsp-haskell-process-wrapper-function
 | ||
|         #'+grfn/wrap-lsp-haskell-process)
 | ||
|   (add-hook 'haskell-mode-hook #'+grfn/haskell-mode-setup 't))
 | ||
| 
 | ||
| (use-package! lsp-imenu
 | ||
|   :after (lsp-mode lsp-ui)
 | ||
|   :hook
 | ||
|   (lsp-after-open . lsp-enable-imenu))
 | ||
| 
 | ||
| ;; (use-package! counsel-etags
 | ||
| ;;   :ensure t
 | ||
| ;;   :init
 | ||
| ;;   (add-hook 'haskell-mode-hook
 | ||
| ;;             (lambda ()
 | ||
| ;;               (add-hook 'after-save-hook
 | ||
| ;;                         'counsel-etags-virtual-update-tags 'append 'local)))
 | ||
| ;;   :config
 | ||
| ;;   (setq counsel-etags-update-interval 60)
 | ||
| ;;   ;; (push "build" counsel-etags-ignore-directories)
 | ||
| ;;   )
 | ||
| 
 | ||
| ;; (use-package! evil-magit
 | ||
| ;;   :after (magit))
 | ||
| 
 | ||
| (use-package! writeroom-mode)
 | ||
| 
 | ||
| (use-package! graphql-mode)
 | ||
| 
 | ||
| 
 | ||
| (require 'whitespace)
 | ||
| (setq whitespace-style '(face lines-tail))
 | ||
| (global-whitespace-mode t)
 | ||
| (add-hook 'org-mode-hook (lambda ()  (whitespace-mode -1)) t)
 | ||
| 
 | ||
| (set-face-foreground 'whitespace-line +solarized-red)
 | ||
| (set-face-attribute 'whitespace-line nil :underline 't)
 | ||
| 
 | ||
| ;; (set-face-background 'ivy-posframe +solarized-s-base3)
 | ||
| ;; (set-face-foreground 'ivy-posframe +solarized-s-base01)
 | ||
| 
 | ||
| (let ((base03    "#002b36")
 | ||
|       (base02    "#073642")
 | ||
|       (base01    "#586e75")
 | ||
|       (base00    "#657b83")
 | ||
|       (base0     "#839496")
 | ||
|       (base1     "#93a1a1")
 | ||
|       (base2     "#eee8d5")
 | ||
|       (base3     "#fdf6e3")
 | ||
|       (yellow    "#b58900")
 | ||
|       (orange    "#cb4b16")
 | ||
|       (red       "#dc322f")
 | ||
|       (magenta   "#d33682")
 | ||
|       (violet    "#6c71c4")
 | ||
|       (blue      "#268bd2")
 | ||
|       (cyan      "#2aa198")
 | ||
|       (green     "#859900"))
 | ||
|   (custom-set-faces
 | ||
|    `(agda2-highlight-keyword-face ((t (:foreground ,green))))
 | ||
|    `(agda2-highlight-string-face ((t (:foreground ,cyan))))
 | ||
|    `(agda2-highlight-number-face ((t (:foreground ,violet))))
 | ||
|    `(agda2-highlight-symbol-face ((((background ,base3)) (:foreground ,base01))))
 | ||
|    `(agda2-highlight-primitive-type-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-bound-variable-face ((t nil)))
 | ||
|    `(agda2-highlight-inductive-constructor-face ((t (:foreground ,green))))
 | ||
|    `(agda2-highlight-coinductive-constructor-face ((t (:foreground ,yellow))))
 | ||
|    `(agda2-highlight-datatype-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-field-face ((t (:foreground ,red))))
 | ||
|    `(agda2-highlight-function-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-module-face ((t (:foreground ,yellow))))
 | ||
|    `(agda2-highlight-postulate-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-primitive-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-record-face ((t (:foreground ,blue))))
 | ||
|    `(agda2-highlight-dotted-face ((t nil)))
 | ||
|    `(agda2-highlight-operator-face ((t nil)))
 | ||
|    `(agda2-highlight-error-face ((t (:foreground ,red :underline t))))
 | ||
|    `(agda2-highlight-unsolved-meta-face ((t (:background ,base2))))
 | ||
|    `(agda2-highlight-unsolved-constraint-face ((t (:background ,base2))))
 | ||
|    `(agda2-highlight-termination-problem-face ((t (:background ,orange :foreground ,base03))))
 | ||
|    `(agda2-highlight-incomplete-pattern-face ((t (:background ,orange :foreground ,base03))))
 | ||
|    `(agda2-highlight-typechecks-face ((t (:background ,cyan :foreground ,base03))))))
 | ||
| 
 | ||
| 
 | ||
| (after! cider
 | ||
|   (setq cider-prompt-for-symbol nil
 | ||
|         cider-font-lock-dynamically 't
 | ||
|         cider-save-file-on-load 't)
 | ||
|   )
 | ||
| 
 | ||
| (comment
 | ||
|  (setq elt (+org-clocked-in-element))
 | ||
| 
 | ||
|  (eq 'headline (car elt))
 | ||
|  (plist-get (cadr elt) :raw-value)
 | ||
|  )
 | ||
| 
 | ||
| (defun +org-headline-title (headline)
 | ||
|   (when (eq 'headline (car elt))
 | ||
|     (plist-get (cadr elt) :raw-value)))
 | ||
| 
 | ||
| ;; (setq +ligatures-extra-symbols
 | ||
| ;;       (append +ligatures-extra-symbols
 | ||
| ;;               '(:equal     "≡"
 | ||
| ;;                 :not-equal "≠"
 | ||
| ;;                 :is        "≣"
 | ||
| ;;                 :isnt      "≢"
 | ||
| ;;                 :lte       "≤"
 | ||
| ;;                 :gte       "≥"
 | ||
| ;;                 :subseteq  "⊆"
 | ||
| ;;                 )))
 | ||
| 
 | ||
| ;; (after! python
 | ||
| ;;   (set-pretty-symbols! 'python-mode :merge t
 | ||
| ;;     :equal      "=="
 | ||
| ;;     :not-equal "!="
 | ||
| ;;     :lte "<="
 | ||
| ;;     :gte ">="
 | ||
| ;;     :is  "is"
 | ||
| ;;     :isnt "is not"
 | ||
| ;;     :subseteq "issubset"
 | ||
| 
 | ||
| ;;     ;; doom builtins
 | ||
| 
 | ||
| ;;     ;; Functional
 | ||
| ;;     :def "def"
 | ||
| ;;     :lambda "lambda"
 | ||
| ;;     ;; Types
 | ||
| ;;     :null "None"
 | ||
| ;;     :true "True" :false "False"
 | ||
| ;;     :int "int" :str "str"
 | ||
| ;;     :float "float"
 | ||
| ;;     :bool "bool"
 | ||
| ;;     :tuple "tuple"
 | ||
| ;;     ;; Flow
 | ||
| ;;     :not "not"
 | ||
| ;;     :in "in" :not-in "not in"
 | ||
| ;;     :and "and" :or "or"
 | ||
| ;;     :for "for"
 | ||
| ;;     :return "return" :yield "yield"))
 | ||
| 
 | ||
| (use-package! sqlup-mode
 | ||
|   :hook
 | ||
|   (sql-mode-hook . sqlup-mode)
 | ||
|   (sql-interactive-mode-hook . sqlup-mode))
 | ||
| 
 | ||
| (use-package! emacsql)
 | ||
| (use-package! emacsql-psql
 | ||
|   :after (emacsql))
 | ||
| 
 | ||
| (use-package! pyimport
 | ||
|   :after (python))
 | ||
| 
 | ||
| (use-package! blacken
 | ||
|   :after (python)
 | ||
|   :init
 | ||
|   (add-hook #'python-mode-hook #'blacken-mode)
 | ||
|   :config
 | ||
|   (setq blacken-only-if-project-is-blackened t
 | ||
|         blacken-allow-py36 t
 | ||
|         blacken-line-length 100))
 | ||
| 
 | ||
| (after! python
 | ||
|   (defun +python-setup ()
 | ||
|     (setq-local fill-column 100
 | ||
|                 whitespace-line-column 100
 | ||
|                 flycheck-disabled-checkers '(python-flake8)
 | ||
|                 flycheck-checker 'python-pylint))
 | ||
| 
 | ||
|   (add-hook #'python-mode-hook #'+python-setup)
 | ||
|   (add-hook #'python-mode-hook #'lsp)
 | ||
|   (remove-hook #'python-mode-hook #'pipenv-mode))
 | ||
| 
 | ||
| ; (use-package! w3m
 | ||
| ;   :config
 | ||
| ;   (setq browse-url-browser-function
 | ||
| ;         `(("^https://app.clubhouse.io.*" . browse-url-firefox)
 | ||
| ;           ("^https://github.com.*" . browse-url-firefox)
 | ||
| ;           (".*" . browse-url-firefox))))
 | ||
| 
 | ||
| (use-package! ob-http
 | ||
|   :config
 | ||
|   (add-to-list 'org-babel-load-languages '(http . t)))
 | ||
| 
 | ||
| ;; (use-package! ob-ipython
 | ||
| ;;   :after (pyimport)
 | ||
| ;;   :config
 | ||
| ;;   (add-to-list 'org-babel-load-languages '(ipython . t))
 | ||
| ;;   (setq ob-ipython-command
 | ||
|         ;; "/home/griffin/code/urb/ciml-video-classifier/bin/jupyter"))
 | ||
| 
 | ||
| (use-package! counsel-spotify)
 | ||
| 
 | ||
| (after! counsel
 | ||
|   (map! [remap counsel-org-capture] #'org-capture
 | ||
|         [remap org-capture] #'org-capture))
 | ||
| 
 | ||
| (remove-hook 'doom-first-input-hook #'evil-snipe-mode)
 | ||
| 
 | ||
| (use-package! rainbow-mode)
 | ||
| 
 | ||
| (use-package! org-alert
 | ||
|   :disabled t
 | ||
|   :config
 | ||
|   (org-alert-enable)
 | ||
|   (setq alert-default-style 'libnotify
 | ||
|         org-alert-headline-title "org"))
 | ||
| 
 | ||
| (use-package! ob-async)
 | ||
| 
 | ||
| (use-package! org-recent-headings
 | ||
|   :config
 | ||
|   (map! :n "SPC n r" #'org-recent-headings-ivy))
 | ||
| 
 | ||
| (use-package! org-sticky-header
 | ||
|   :after (org)
 | ||
|   :hook (org-mode-hook . org-sticky-header-mode)
 | ||
|   :config
 | ||
|   (setq-default org-sticky-header-heading-star "●"))
 | ||
| 
 | ||
| (enable-theme 'grfn-solarized-light)
 | ||
| 
 | ||
| ;;; this needs to be *after the theme*, or else I get no agenda items.
 | ||
| ;;; whuuu??
 | ||
| (load! "org-config")
 | ||
| 
 | ||
| 
 | ||
| ;;; word-char
 | ||
| (add-hook! prog-mode
 | ||
|   (modify-syntax-entry ?_ "w"))
 | ||
| 
 | ||
| (add-hook! lisp-mode
 | ||
|   (modify-syntax-entry ?- "w"))
 | ||
| 
 | ||
| (after! flycheck
 | ||
|   (put 'flycheck-python-pylint-executable 'safe-local-variable (lambda (_) t))
 | ||
|   (setq flycheck-error-list-minimum-level 'warn
 | ||
|         flycheck-navigation-minimum-level 'warn))
 | ||
| 
 | ||
| (defvar alembic-command "alembic"
 | ||
|   "Command to execute when running alembic")
 | ||
| 
 | ||
| (defvar alembic-dir-fun (lambda () default-directory)
 | ||
|   "Reference to a function whose return value will be used as the directory to
 | ||
|   run Alembic in")
 | ||
| 
 | ||
| (put 'alembic-command 'safe-local-variable (lambda (_) t))
 | ||
| (put 'alembic-dir-fun 'safe-local-variable (lambda (_) t))
 | ||
| 
 | ||
| (defun make-alembic-command (args)
 | ||
|   (if (functionp alembic-command)
 | ||
|       (funcall alembic-command args)
 | ||
|     (concat alembic-command " " args)))
 | ||
| 
 | ||
| (defun +grfn/extract-alembic-migration-name (output)
 | ||
|   (unless (string-match (rx (0+ anything) "Generating "
 | ||
|                             (group (one-or-more (not (syntax whitespace))))
 | ||
|                             " ..." (one-or-more (syntax whitespace)) "done"
 | ||
|                             (0+ anything))
 | ||
|                         output)
 | ||
|     (user-error "Error: %s" output))
 | ||
|   (match-string-no-properties 1 output))
 | ||
| 
 | ||
| (defun -run-alembic (args)
 | ||
|   (let* ((default-directory (funcall alembic-dir-fun))
 | ||
|          (command (make-alembic-command args))
 | ||
|          ;; (format "nix-shell --run 'alembic %s'" args)
 | ||
|          ;; (format "%s %s" alembic-command args)
 | ||
|          (res
 | ||
|           (with-temp-buffer
 | ||
|             (cons
 | ||
|              (shell-command command t)
 | ||
|              (s-replace-regexp
 | ||
|               "^.*Nix search path entry.*$" ""
 | ||
|               (buffer-string)))))
 | ||
|          (exit-code (car res))
 | ||
|          (out (cdr res)))
 | ||
|     ;; (if (= 0 exit-code)
 | ||
|     ;;     out
 | ||
|     ;;   (error "Error running %s: %s" command out))
 | ||
|     out
 | ||
|     ))
 | ||
| 
 | ||
| (comment
 | ||
|  --exit-code
 | ||
|  --bs
 | ||
|  )
 | ||
| 
 | ||
| (defun run-alembic (args)
 | ||
|   (interactive "sAlembic command: ")
 | ||
|   (message "%s" (-run-alembic args)))
 | ||
| 
 | ||
| (defun generate-alembic-migration (msg &rest args)
 | ||
|   (interactive "sMessage: ")
 | ||
|   (->
 | ||
|    (format "revision %s -m \"%s\""
 | ||
|            (s-join " " args)
 | ||
|            msg)
 | ||
|    (-run-alembic)
 | ||
|    (+grfn/extract-alembic-migration-name)
 | ||
|    (find-file-other-window)))
 | ||
| 
 | ||
| (cl-defun alembic-upgrade (&optional revision &key namespace)
 | ||
|   (interactive "sRevision: ")
 | ||
|   (let ((default-directory (funcall alembic-dir-fun)))
 | ||
|     (run-alembic (format "%s upgrade %s"
 | ||
|                          (if namespace (concat "-n " namespace) "")
 | ||
|                          (or revision "head")))))
 | ||
| 
 | ||
| (defun alembic-downgrade (revision)
 | ||
|   (interactive "sRevision: ")
 | ||
|   (let ((default-directory (funcall alembic-dir-fun)))
 | ||
|     (run-alembic (format "downgrade %s" (or revision "head")))))
 | ||
| 
 | ||
| (use-package! gnuplot)
 | ||
| (use-package! gnuplot-mode :after gnuplot)
 | ||
| (use-package! string-inflection)
 | ||
| 
 | ||
| (after! anaconda-mode
 | ||
|   ;; (set-company-backend! 'anaconda-mode #'company-yasnippet)
 | ||
|   )
 | ||
| 
 | ||
| ;; (add-hook! python-mode
 | ||
| ;;   (capf))
 | ||
| 
 | ||
| (cl-defstruct pull-request url number title author repository)
 | ||
| 
 | ||
| (defun grfn/num-inbox-items ()
 | ||
|   (length (org-elements-agenda-match "inbox" t)))
 | ||
| 
 | ||
| (use-package! dhall-mode
 | ||
|   :mode "\\.dhall\\'")
 | ||
| 
 | ||
| (use-package! github-review
 | ||
|   :after forge)
 | ||
| 
 | ||
| (after! forge
 | ||
|   (set-popup-rule!
 | ||
|     "^\\*forge"
 | ||
|     :size 0.75))
 | ||
| 
 | ||
| (defun grfn/org-add-db-connection-params ()
 | ||
|   (interactive)
 | ||
|   (ivy-read
 | ||
|    "DB to connect to: "
 | ||
|    (-map (lambda (opts)
 | ||
|            (propertize (symbol-name (car opts))
 | ||
|                        'header-args (cdr opts)))
 | ||
|          db-connection-param-options)
 | ||
|    :require-match t
 | ||
|    :action
 | ||
|    (lambda (opt)
 | ||
|      (let ((header-args (get-text-property 0 'header-args opt)))
 | ||
|        (org-set-property "header-args" header-args)))))
 | ||
| 
 | ||
| (use-package! kubernetes
 | ||
|   :commands (kubernetes-overview))
 | ||
| 
 | ||
| (use-package! k8s-mode
 | ||
|   :hook (k8s-mode . yas-minor-mode))
 | ||
| 
 | ||
| (use-package! sx)
 | ||
| 
 | ||
| ;; (use-package! nix-update
 | ||
| ;;   :config
 | ||
| ;;   (map! (:map nix-mode-map
 | ||
| ;;           (:leader
 | ||
| ;;             :desc "Update fetcher" :nv #'nix-update-fetch))))
 | ||
| 
 | ||
| 
 | ||
| (after! lsp-haskell
 | ||
|   (lsp-register-client
 | ||
|    (make-lsp--client
 | ||
|     :new-connection (lsp-stdio-connection (lambda () (lsp-haskell--hie-command)))
 | ||
|     :major-modes '(haskell-mode)
 | ||
|     :server-id 'hie
 | ||
|     ;; :multi-root t
 | ||
|     ;; :initialization-options 'lsp-haskell--make-init-options
 | ||
|     )
 | ||
|    )
 | ||
|   )
 | ||
| 
 | ||
| (solaire-global-mode -1)
 | ||
| 
 | ||
| (use-package! wsd-mode)
 | ||
| 
 | ||
| (use-package! metal-mercury-mode)
 | ||
| (use-package! flycheck-mercury
 | ||
|   :after (metal-mercury-mode flycheck-mercury))
 | ||
| 
 | ||
| (use-package! direnv
 | ||
|   :config (direnv-mode))
 | ||
| 
 | ||
| (after! erc
 | ||
|   ;; (setq erc-autojoin-channels-alist '(("freenode.net" "#nixos" "#haskell" "##tvl")))
 | ||
|   )
 | ||
| 
 | ||
| (defun evil-disable-insert-state-bindings ()
 | ||
|   evil-disable-insert-state-bindings)
 | ||
| 
 | ||
| ;; (use-package! terraform-mode)
 | ||
| ;; (use-package! company-terraform
 | ||
| ;;   :after terraform-mode
 | ||
| ;;   :config (company-terraform-init))
 | ||
| 
 | ||
| (use-package! znc
 | ||
|   :config
 | ||
|   (setq znc-servers
 | ||
|         '(("znc.gws.fyi" 5000 t
 | ||
|            ((freenode "glittershark" "Ompquy"))))))
 | ||
| 
 | ||
| (use-package! jsonnet-mode
 | ||
|   :config
 | ||
|   (map!
 | ||
|    (:map jsonnet-mode-map
 | ||
|     (:n "g SPC" #'jsonnet-eval-buffer))))
 | ||
| 
 | ||
| (add-to-list 'safe-local-variable-values
 | ||
|              '(truncate-lines . t))
 | ||
| 
 | ||
| (set-popup-rule!
 | ||
|   "^\\*gud-"
 | ||
|   :quit nil)
 |