refactor(users/glittershark): Rename to grfn
Rename my //users directory and all places that refer to glittershark to grfn, including nix references and documentation. This may require some extra attention inside of gerrit's database after it lands to allow me to actually push things. Change-Id: I4728b7ec2c60024392c1c1fa6e0d4a59b3e266fa Reviewed-on: https://cl.tvl.fyi/c/depot/+/2933 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in> Reviewed-by: lukegb <lukegb@tvl.fyi> Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
parent
968effb5dc
commit
6266c5d32f
362 changed files with 52 additions and 56 deletions
1420
users/grfn/emacs.d/+bindings.el
Normal file
1420
users/grfn/emacs.d/+bindings.el
Normal file
File diff suppressed because it is too large
Load diff
149
users/grfn/emacs.d/+commands.el
Normal file
149
users/grfn/emacs.d/+commands.el
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defalias 'ex! 'evil-ex-define-cmd)
|
||||
|
||||
(defun delete-file-and-buffer ()
|
||||
"Kill the current buffer and deletes the file it is visiting."
|
||||
(interactive)
|
||||
(let ((filename (buffer-file-name)))
|
||||
(when filename
|
||||
(if (vc-backend filename)
|
||||
(vc-delete-file filename)
|
||||
(progn
|
||||
(delete-file filename)
|
||||
(message "Deleted file %s" filename)
|
||||
(kill-buffer))))))
|
||||
|
||||
;;; Commands defined elsewhere
|
||||
;;(ex! "al[ign]" #'+evil:align)
|
||||
;;(ex! "g[lobal]" #'+evil:global)
|
||||
|
||||
;;; Custom commands
|
||||
;; Editing
|
||||
(ex! "@" #'+evil:macro-on-all-lines) ; TODO Test me
|
||||
(ex! "al[ign]" #'+evil:align)
|
||||
(ex! "enhtml" #'+web:encode-html-entities)
|
||||
(ex! "dehtml" #'+web:decode-html-entities)
|
||||
(ex! "mc" #'+evil:mc)
|
||||
(ex! "iedit" #'evil-multiedit-ex-match)
|
||||
(ex! "na[rrow]" #'+evil:narrow-buffer)
|
||||
(ex! "retab" #'+evil:retab)
|
||||
|
||||
(ex! "glog" #'magit-log-buffer-file)
|
||||
|
||||
;; External resources
|
||||
;; TODO (ex! "db" #'doom:db)
|
||||
;; TODO (ex! "dbu[se]" #'doom:db-select)
|
||||
;; TODO (ex! "go[ogle]" #'doom:google-search)
|
||||
(ex! "lo[okup]" #'+jump:online)
|
||||
(ex! "dash" #'+lookup:dash)
|
||||
(ex! "dd" #'+lookup:devdocs)
|
||||
(ex! "http" #'httpd-start) ; start http server
|
||||
(ex! "repl" #'+eval:repl) ; invoke or send to repl
|
||||
;; TODO (ex! "rx" 'doom:regex) ; open re-builder
|
||||
(ex! "sh[ell]" #'+eshell:run)
|
||||
(ex! "t[mux]" #'+tmux:run) ; send to tmux
|
||||
(ex! "tcd" #'+tmux:cd-here) ; cd to default-directory in tmux
|
||||
(ex! "x" #'doom/open-project-scratch-buffer)
|
||||
|
||||
;; GIT
|
||||
(ex! "gist" #'+gist:send) ; send current buffer/region to gist
|
||||
(ex! "gistl" #'+gist:list) ; list gists by user
|
||||
(ex! "gbrowse" #'+vcs/git-browse) ; show file in github/gitlab
|
||||
(ex! "gissues" #'+vcs/git-browse-issues) ; show github issues
|
||||
(ex! "git" #'magit-status) ; open magit status window
|
||||
(ex! "gstage" #'magit-stage)
|
||||
(ex! "gunstage" #'magit-unstage)
|
||||
(ex! "gblame" #'magit-blame)
|
||||
(ex! "grevert" #'git-gutter:revert-hunk)
|
||||
|
||||
;; Dealing with buffers
|
||||
(ex! "clean[up]" #'doom/cleanup-buffers)
|
||||
(ex! "k[ill]" #'doom/kill-this-buffer)
|
||||
(ex! "k[ill]all" #'+hlissner:kill-all-buffers)
|
||||
(ex! "k[ill]m" #'+hlissner:kill-matching-buffers)
|
||||
(ex! "k[ill]o" #'doom/kill-other-buffers)
|
||||
(ex! "l[ast]" #'doom/popup-restore)
|
||||
(ex! "m[sg]" #'view-echo-area-messages)
|
||||
(ex! "pop[up]" #'doom/popup-this-buffer)
|
||||
|
||||
;; Project navigation
|
||||
(ex! "a" #'projectile-toggle-between-implementation-and-test)
|
||||
(ex! "as" #'projectile-find-implementation-or-test-other-window)
|
||||
(ex! "av" #'projectile-find-implementation-or-test-other-window)
|
||||
(ex! "cd" #'+hlissner:cd)
|
||||
(cond ((featurep! :completion ivy)
|
||||
(ex! "ag" #'+ivy:ag)
|
||||
(ex! "agc[wd]" #'+ivy:ag-cwd)
|
||||
(ex! "rg" #'+ivy:rg)
|
||||
(ex! "rgc[wd]" #'+ivy:rg-cwd)
|
||||
(ex! "sw[iper]" #'+ivy:swiper)
|
||||
(ex! "todo" #'+ivy:todo))
|
||||
((featurep! :completion helm)
|
||||
(ex! "ag" #'+helm:ag)
|
||||
(ex! "agc[wd]" #'+helm:ag-cwd)
|
||||
(ex! "rg" #'+helm:rg)
|
||||
(ex! "rgc[wd]" #'+helm:rg-cwd)
|
||||
(ex! "sw[oop]" #'+helm:swoop)
|
||||
(ex! "todo" #'+helm:todo)))
|
||||
|
||||
;; Project tools
|
||||
(ex! "build" #'+eval/build)
|
||||
(ex! "debug" #'+debug/run)
|
||||
(ex! "er[rors]" #'flycheck-list-errors)
|
||||
|
||||
;; File operations
|
||||
(ex! "cp" #'+evil:copy-this-file)
|
||||
(ex! "mv" #'+evil:move-this-file)
|
||||
(ex! "rm" #'+evil:delete-this-file)
|
||||
|
||||
;; Sessions/tabs
|
||||
(ex! "sclear" #'+workspace/kill-session)
|
||||
(ex! "sl[oad]" #'+workspace:load-session)
|
||||
(ex! "ss[ave]" #'+workspace:save-session)
|
||||
(ex! "tabcl[ose]" #'+workspace:delete)
|
||||
(ex! "tabclear" #'doom/kill-all-buffers)
|
||||
(ex! "tabl[ast]" #'+workspace/switch-to-last)
|
||||
(ex! "tabload" #'+workspace:load)
|
||||
(ex! "tabn[ew]" #'+workspace:new)
|
||||
(ex! "tabn[ext]" #'+workspace:switch-next)
|
||||
(ex! "tabp[rev]" #'+workspace:switch-previous)
|
||||
(ex! "tabr[ename]" #'+workspace:rename)
|
||||
(ex! "tabs" #'+workspace/display)
|
||||
(ex! "tabsave" #'+workspace:save)
|
||||
|
||||
(ex! "scr[atch]" #'cider-scratch)
|
||||
|
||||
;; Org-mode
|
||||
(ex! "cap" #'+org-capture/dwim)
|
||||
|
||||
(evil-define-command evil-alembic-revision (args)
|
||||
(interactive "<a>")
|
||||
(apply
|
||||
#'generate-alembic-migration
|
||||
(read-string "Message: ")
|
||||
(s-split "\\s+" (or args ""))))
|
||||
(ex! "arev[ision]" #'evil-alembic-revision)
|
||||
|
||||
(evil-define-command evil-alembic-upgrade (&optional revision)
|
||||
(interactive "<a>")
|
||||
(alembic-upgrade (or revision "head")))
|
||||
|
||||
(ex! "aup[grade]" #'evil-alembic-upgrade)
|
||||
|
||||
(evil-define-command evil-alembic-downgrade (&optional revision)
|
||||
(interactive "<a>")
|
||||
(alembic-downgrade revision))
|
||||
|
||||
(ex! "adown[grade]" #'evil-alembic-downgrade)
|
||||
|
||||
(evil-define-command evil-alembic (args)
|
||||
(interactive "<a>")
|
||||
(run-alembic args))
|
||||
|
||||
(ex! "alemb[ic]" #'evil-alembic)
|
||||
|
||||
;; Elixir
|
||||
(add-hook! elixir-mode
|
||||
(ex! "AV" #'alchemist-project-toggle-file-and-tests-other-window)
|
||||
(ex! "A" #'alchemist-project-toggle-file-and-tests))
|
||||
BIN
users/grfn/emacs.d/+private.el.gpg
Normal file
BIN
users/grfn/emacs.d/+private.el.gpg
Normal file
Binary file not shown.
2
users/grfn/emacs.d/.gitignore
vendored
Normal file
2
users/grfn/emacs.d/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.authinfo.gpg
|
||||
+private.el
|
||||
37
users/grfn/emacs.d/autoload/evil.el
Normal file
37
users/grfn/emacs.d/autoload/evil.el
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
;;; /autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :feature evil)
|
||||
|
||||
;;;###autoload (autoload '+hlissner:multi-next-line "/autoload/evil" nil t)
|
||||
(evil-define-motion +hlissner:multi-next-line (count)
|
||||
"Move down 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode))))
|
||||
(evil-line-move (* 6 (or count 1)))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:multi-previous-line "/autoload/evil" nil t)
|
||||
(evil-define-motion +hlissner:multi-previous-line (count)
|
||||
"Move up 6 lines."
|
||||
:type line
|
||||
(let ((line-move-visual (or visual-line-mode (derived-mode-p 'text-mode))))
|
||||
(evil-line-move (- (* 6 (or count 1))))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:cd "/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner:cd ()
|
||||
"Change `default-directory' with `cd'."
|
||||
(interactive "<f>")
|
||||
(cd input))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:kill-all-buffers "/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner:kill-all-buffers (&optional bang)
|
||||
"Kill all buffers. If BANG, kill current session too."
|
||||
(interactive "<!>")
|
||||
(if bang
|
||||
(+workspace/kill-session)
|
||||
(doom/kill-all-buffers)))
|
||||
|
||||
;;;###autoload (autoload '+hlissner:kill-matching-buffers "/autoload/evil" nil t)
|
||||
(evil-define-command +hlissner:kill-matching-buffers (&optional bang pattern)
|
||||
"Kill all buffers matching PATTERN regexp. If BANG, only match project
|
||||
buffers."
|
||||
(interactive "<a>")
|
||||
(doom/kill-matching-buffers pattern bang))
|
||||
53
users/grfn/emacs.d/autoload/hlissner.el
Normal file
53
users/grfn/emacs.d/autoload/hlissner.el
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
;;; autoload/hlissner.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun +hlissner/install-snippets ()
|
||||
"Install my snippets from https://github.com/hlissner/emacs-snippets into
|
||||
private/hlissner/snippets."
|
||||
(interactive)
|
||||
(doom-fetch :github "hlissner/emacs-snippets"
|
||||
(expand-file-name "snippets" (doom-module-path :private 'hlissner))))
|
||||
|
||||
;;;###autoload
|
||||
(defun +hlissner/yank-buffer-filename ()
|
||||
"Copy the current buffer's path to the kill ring."
|
||||
(interactive)
|
||||
(if-let* ((filename (or buffer-file-name (bound-and-true-p list-buffers-directory))))
|
||||
(message (kill-new (abbreviate-file-name filename)))
|
||||
(error "Couldn't find filename in current buffer")))
|
||||
|
||||
(defmacro +hlissner-def-finder! (name dir)
|
||||
"Define a pair of find-file and browse functions."
|
||||
`(progn
|
||||
(defun ,(intern (format "+hlissner/find-in-%s" name)) ()
|
||||
(interactive)
|
||||
(let ((default-directory ,dir)
|
||||
projectile-project-name
|
||||
projectile-require-project-root
|
||||
projectile-cached-buffer-file-name
|
||||
projectile-cached-project-root)
|
||||
(call-interactively (command-remapping #'projectile-find-file))))
|
||||
(defun ,(intern (format "+hlissner/browse-%s" name)) ()
|
||||
(interactive)
|
||||
(let ((default-directory ,dir))
|
||||
(call-interactively (command-remapping #'find-file))))))
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-templates "autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-templates "autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! templates +file-templates-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-snippets "autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-snippets "autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! snippets +hlissner-snippets-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-dotfiles "autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-dotfiles "autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! dotfiles (expand-file-name ".dotfiles" "~"))
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-emacsd "autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-emacsd "autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! emacsd doom-emacs-dir)
|
||||
|
||||
;;;###autoload (autoload '+hlissner/find-in-notes "autoload/hlissner" nil t)
|
||||
;;;###autoload (autoload '+hlissner/browse-notes "autoload/hlissner" nil t)
|
||||
(+hlissner-def-finder! notes +org-dir)
|
||||
17
users/grfn/emacs.d/clocked-in-elt.el
Normal file
17
users/grfn/emacs.d/clocked-in-elt.el
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
(load (expand-file-name "init" (or (getenv "EMACSDIR")
|
||||
(expand-file-name
|
||||
"../.emacs.d"
|
||||
(file-name-directory (file-truename load-file-name))))))
|
||||
|
||||
(require 'org-clock)
|
||||
(require 'org-element)
|
||||
|
||||
(let ((item (or org-clock-marker
|
||||
(car org-clock-history))))
|
||||
(when item
|
||||
(with-current-buffer (marker-buffer item)
|
||||
(goto-char (marker-position item))
|
||||
(let ((element (org-element-at-point)))
|
||||
(when (eq 'headline (car element))
|
||||
(message "%s" (plist-get (cadr element) :raw-value)))))))
|
||||
52
users/grfn/emacs.d/clojure.el
Normal file
52
users/grfn/emacs.d/clojure.el
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defun clojure-thing-at-point-setup ()
|
||||
(interactive)
|
||||
;; Used by cider-find-dwim to parse the symbol at point
|
||||
(setq-local
|
||||
thing-at-point-file-name-chars
|
||||
(concat thing-at-point-file-name-chars
|
||||
"><!?")))
|
||||
|
||||
(defun +grfn/clojure-setup ()
|
||||
;; (flycheck-select-checker 'clj-kondo)
|
||||
(push 'clojure-cider-kibit flycheck-disabled-checkers)
|
||||
(push 'clojure-cider-eastwood flycheck-disabled-checkers)
|
||||
(push 'clojure-cider-typed flycheck-disabled-checkers)
|
||||
)
|
||||
|
||||
(after! clojure-mode
|
||||
(define-clojure-indent
|
||||
(PUT 2)
|
||||
(POST 2)
|
||||
(GET 2)
|
||||
(PATCH 2)
|
||||
(DELETE 2)
|
||||
(context 2)
|
||||
(checking 3)
|
||||
(match 1)
|
||||
(domonad 0)
|
||||
(describe 1)
|
||||
(before 1)
|
||||
(it 2))
|
||||
|
||||
(add-hook 'clojure-mode-hook #'clojure-thing-at-point-setup)
|
||||
(add-hook 'clojure-mode-hook #'+grfn/clojure-setup))
|
||||
|
||||
(use-package! flycheck-clojure
|
||||
;; :disabled t
|
||||
:after (flycheck cider)
|
||||
:config
|
||||
(flycheck-clojure-setup))
|
||||
|
||||
(after! clj-refactor
|
||||
(setq cljr-magic-requires :prompt
|
||||
cljr-clojure-test-declaration "[clojure.test :refer :all]"
|
||||
cljr-cljc-clojure-test-declaration"#?(:clj [clojure.test :refer :all]
|
||||
:cljs [cljs.test :refer-macros [deftest is testing]])"
|
||||
)
|
||||
(add-to-list
|
||||
'cljr-magic-require-namespaces
|
||||
'("s" . "clojure.spec.alpha")))
|
||||
|
||||
(set-popup-rule! "^\\*cider-test-report" :size 0.4)
|
||||
299
users/grfn/emacs.d/company-sql.el
Normal file
299
users/grfn/emacs.d/company-sql.el
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
;;; Commentary:
|
||||
;;; TODO
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'emacsql)
|
||||
(require 'emacsql-psql)
|
||||
(require 'dash)
|
||||
(require 's)
|
||||
(require 'cl-lib)
|
||||
|
||||
;;; Config
|
||||
|
||||
(defvar-local company-sql-db-host "localhost"
|
||||
"Host of the postgresql database to query for autocomplete information")
|
||||
|
||||
(defvar-local company-sql-db-port 5432
|
||||
"Port of the postgresql database to query for autocomplete information")
|
||||
|
||||
(defvar-local company-sql-db-user "postgres"
|
||||
"Username of the postgresql database to query for autocomplete information")
|
||||
|
||||
(defvar-local company-sql-db-name nil
|
||||
"PostgreSQL database name to query for autocomplete information")
|
||||
|
||||
;;; DB Connection
|
||||
|
||||
(defvar-local company-sql/connection nil)
|
||||
|
||||
(defun company-sql/connect ()
|
||||
(unless company-sql/connection
|
||||
(setq-local company-sql/connection
|
||||
(emacsql-psql company-sql-db-name
|
||||
:hostname company-sql-db-host
|
||||
:username company-sql-db-user
|
||||
:port (number-to-string company-sql-db-port))))
|
||||
company-sql/connection)
|
||||
|
||||
;;; Utils
|
||||
|
||||
(defmacro comment (&rest _))
|
||||
|
||||
(defun ->string (x)
|
||||
(cond
|
||||
((stringp x) x)
|
||||
((symbolp x) (symbol-name x))))
|
||||
|
||||
(defun alist-get-equal (key alist)
|
||||
"Like `alist-get', but uses `equal' instead of `eq' for comparing keys"
|
||||
(->> alist
|
||||
(-find (lambda (pair) (equal key (car pair))))
|
||||
(cdr)))
|
||||
|
||||
;;; Listing relations
|
||||
|
||||
(cl-defun company-sql/list-tables (conn)
|
||||
(with-timeout (3)
|
||||
(-map (-compose 'symbol-name 'car)
|
||||
(emacsql conn
|
||||
[:select [tablename]
|
||||
:from pg_catalog:pg_tables
|
||||
:where (and (!= schemaname '"information_schema")
|
||||
(!= schemaname '"pg_catalog"))]))))
|
||||
|
||||
(cl-defun company-sql/list-columns (conn)
|
||||
(with-timeout (3)
|
||||
(-map
|
||||
(lambda (row)
|
||||
(propertize (symbol-name (nth 0 row))
|
||||
'table-name (nth 1 row)
|
||||
'data-type (nth 2 row)))
|
||||
(emacsql conn
|
||||
[:select [column_name
|
||||
table_name
|
||||
data_type]
|
||||
:from information_schema:columns]))))
|
||||
|
||||
;;; Keywords
|
||||
|
||||
(defvar company-postgresql/keywords
|
||||
(list
|
||||
"a" "abort" "abs" "absent" "absolute" "access" "according" "action" "ada" "add"
|
||||
"admin" "after" "aggregate" "all" "allocate" "also" "alter" "always" "analyse"
|
||||
"analyze" "and" "any" "are" "array" "array_agg" "array_max_cardinality" "as"
|
||||
"asc" "asensitive" "assertion" "assignment" "asymmetric" "at" "atomic" "attach"
|
||||
"attribute" "attributes" "authorization" "avg" "backward" "base64" "before"
|
||||
"begin" "begin_frame" "begin_partition" "bernoulli" "between" "bigint" "binary"
|
||||
"bit" "bit_length" "blob" "blocked" "bom" "boolean" "both" "breadth" "by" "c"
|
||||
"cache" "call" "called" "cardinality" "cascade" "cascaded" "case" "cast"
|
||||
"catalog" "catalog_name" "ceil" "ceiling" "chain" "char" "character"
|
||||
"characteristics" "characters" "character_length" "character_set_catalog"
|
||||
"character_set_name" "character_set_schema" "char_length" "check" "checkpoint"
|
||||
"class" "class_origin" "clob" "close" "cluster" "coalesce" "cobol" "collate"
|
||||
"collation" "collation_catalog" "collation_name" "collation_schema" "collect"
|
||||
"column" "columns" "column_name" "command_function" "command_function_code"
|
||||
"comment" "comments" "commit" "committed" "concurrently" "condition"
|
||||
"condition_number" "configuration" "conflict" "connect" "connection"
|
||||
"connection_name" "constraint" "constraints" "constraint_catalog"
|
||||
"constraint_name" "constraint_schema" "constructor" "contains" "content"
|
||||
"continue" "control" "conversion" "convert" "copy" "corr" "corresponding" "cost"
|
||||
"count" "covar_pop" "covar_samp" "create" "cross" "csv" "cube" "cume_dist"
|
||||
"current" "current_catalog" "current_date" "current_default_transform_group"
|
||||
"current_path" "current_role" "current_row" "current_schema" "current_time"
|
||||
"current_timestamp" "current_transform_group_for_type" "current_user" "cursor"
|
||||
"cursor_name" "cycle" "data" "database" "datalink" "date"
|
||||
"datetime_interval_code" "datetime_interval_precision" "day" "db" "deallocate"
|
||||
"dec" "decimal" "declare" "default" "defaults" "deferrable" "deferred" "defined"
|
||||
"definer" "degree" "delete" "delimiter" "delimiters" "dense_rank" "depends"
|
||||
"depth" "deref" "derived" "desc" "describe" "descriptor" "detach"
|
||||
"deterministic" "diagnostics" "dictionary" "disable" "discard" "disconnect"
|
||||
"dispatch" "distinct" "dlnewcopy" "dlpreviouscopy" "dlurlcomplete"
|
||||
"dlurlcompleteonly" "dlurlcompletewrite" "dlurlpath" "dlurlpathonly"
|
||||
"dlurlpathwrite" "dlurlscheme" "dlurlserver" "dlvalue" "do" "document" "domain"
|
||||
"double" "drop" "dynamic" "dynamic_function" "dynamic_function_code" "each"
|
||||
"element" "else" "empty" "enable" "encoding" "encrypted" "end" "end-exec"
|
||||
"end_frame" "end_partition" "enforced" "enum" "equals" "escape" "event" "every"
|
||||
"except" "exception" "exclude" "excluding" "exclusive" "exec" "execute" "exists"
|
||||
"exp" "explain" "expression" "extension" "external" "extract" "false" "family"
|
||||
"fetch" "file" "filter" "final" "first" "first_value" "flag" "float" "floor"
|
||||
"following" "for" "force" "foreign" "fortran" "forward" "found" "frame_row"
|
||||
"free" "freeze" "from" "fs" "full" "function" "functions" "fusion" "g" "general"
|
||||
"generated" "get" "global" "go" "goto" "grant" "granted" "greatest" "group"
|
||||
"grouping" "groups" "handler" "having" "header" "hex" "hierarchy" "hold" "hour"
|
||||
"id" "identity" "if" "ignore" "ilike" "immediate" "immediately" "immutable"
|
||||
"implementation" "implicit" "import" "in" "include" "including" "increment"
|
||||
"indent" "index" "indexes" "indicator" "inherit" "inherits" "initially" "inline"
|
||||
"inner" "inout" "input" "insensitive" "insert" "instance" "instantiable"
|
||||
"instead" "int" "integer" "integrity" "intersect" "intersection" "interval"
|
||||
"into" "invoker" "is" "isnull" "isolation" "join" "k" "key" "key_member"
|
||||
"key_type" "label" "lag" "language" "large" "last" "last_value" "lateral" "lead"
|
||||
"leading" "leakproof" "least" "left" "length" "level" "library" "like"
|
||||
"like_regex" "limit" "link" "listen" "ln" "load" "local" "localtime"
|
||||
"localtimestamp" "location" "locator" "lock" "locked" "logged" "lower" "m" "map"
|
||||
"mapping" "match" "matched" "materialized" "max" "maxvalue" "max_cardinality"
|
||||
"member" "merge" "message_length" "message_octet_length" "message_text" "method"
|
||||
"min" "minute" "minvalue" "mod" "mode" "modifies" "module" "month" "more" "move"
|
||||
"multiset" "mumps" "name" "names" "namespace" "national" "natural" "nchar"
|
||||
"nclob" "nesting" "new" "next" "nfc" "nfd" "nfkc" "nfkd" "nil" "no" "none"
|
||||
"normalize" "normalized" "not" "nothing" "notify" "notnull" "nowait" "nth_value"
|
||||
"ntile" "null" "nullable" "nullif" "nulls" "number" "numeric" "object"
|
||||
"occurrences_regex" "octets" "octet_length" "of" "off" "offset" "oids" "old"
|
||||
"on" "only" "open" "operator" "option" "options" "or" "order" "ordering"
|
||||
"ordinality" "others" "out" "outer" "output" "over" "overlaps" "overlay"
|
||||
"overriding" "owned" "owner" "p" "pad" "parallel" "parameter" "parameter_mode"
|
||||
"parameter_name" "parameter_ordinal_position" "parameter_specific_catalog"
|
||||
"parameter_specific_name" "parameter_specific_schema" "parser" "partial"
|
||||
"partition" "pascal" "passing" "passthrough" "password" "path" "percent"
|
||||
"percentile_cont" "percentile_disc" "percent_rank" "period" "permission"
|
||||
"placing" "plans" "pli" "policy" "portion" "position" "position_regex" "power"
|
||||
"precedes" "preceding" "precision" "prepare" "prepared" "preserve" "primary"
|
||||
"prior" "privileges" "procedural" "procedure" "procedures" "program" "public"
|
||||
"publication" "quote" "range" "rank" "read" "reads" "real" "reassign" "recheck"
|
||||
"recovery" "recursive" "ref" "references" "referencing" "refresh" "regr_avgx"
|
||||
"regr_avgy" "regr_count" "regr_intercept" "regr_r2" "regr_slope" "regr_sxx"
|
||||
"regr_sxy" "regr_syy" "reindex" "relative" "release" "rename" "repeatable"
|
||||
"replace" "replica" "requiring" "reset" "respect" "restart" "restore" "restrict"
|
||||
"result" "return" "returned_cardinality" "returned_length"
|
||||
"returned_octet_length" "returned_sqlstate" "returning" "returns" "revoke"
|
||||
"right" "role" "rollback" "rollup" "routine" "routines" "routine_catalog"
|
||||
"routine_name" "routine_schema" "row" "rows" "row_count" "row_number" "rule"
|
||||
"savepoint" "scale" "schema" "schemas" "schema_name" "scope" "scope_catalog"
|
||||
"scope_name" "scope_schema" "scroll" "search" "second" "section" "security"
|
||||
"select" "selective" "self" "sensitive" "sequence" "sequences" "serializable"
|
||||
"server" "server_name" "session" "session_user" "set" "setof" "sets" "share"
|
||||
"show" "similar" "simple" "size" "skip" "smallint" "snapshot" "some" "source"
|
||||
"space" "specific" "specifictype" "specific_name" "sql" "sqlcode" "sqlerror"
|
||||
"sqlexception" "sqlstate" "sqlwarning" "sqrt" "stable" "standalone" "start"
|
||||
"state" "statement" "static" "statistics" "stddev_pop" "stddev_samp" "stdin"
|
||||
"stdout" "storage" "strict" "strip" "structure" "style" "subclass_origin"
|
||||
"submultiset" "subscription" "substring" "substring_regex" "succeeds" "sum"
|
||||
"symmetric" "sysid" "system" "system_time" "system_user" "t" "table" "tables"
|
||||
"tablesample" "tablespace" "table_name" "temp" "template" "temporary" "text"
|
||||
"then" "ties" "time" "timestamp" "timezone_hour" "timezone_minute" "to" "token"
|
||||
"top_level_count" "trailing" "transaction" "transactions_committed"
|
||||
"transactions_rolled_back" "transaction_active" "transform" "transforms"
|
||||
"translate" "translate_regex" "translation" "treat" "trigger" "trigger_catalog"
|
||||
"trigger_name" "trigger_schema" "trim" "trim_array" "true" "truncate" "trusted"
|
||||
"type" "types" "uescape" "unbounded" "uncommitted" "under" "unencrypted" "union"
|
||||
"unique" "unknown" "unlink" "unlisten" "unlogged" "unnamed" "unnest" "until"
|
||||
"untyped" "update" "upper" "uri" "usage" "user" "user_defined_type_catalog"
|
||||
"user_defined_type_code" "user_defined_type_name" "user_defined_type_schema"
|
||||
"using" "vacuum" "valid" "validate" "validator" "value" "values" "value_of"
|
||||
"varbinary" "varchar" "variadic" "varying" "var_pop" "var_samp" "verbose"
|
||||
"version" "versioning" "view" "views" "volatile" "when" "whenever" "where"
|
||||
"whitespace" "width_bucket" "window" "with" "within" "without" "work" "wrapper"
|
||||
"write" "xml" "xmlagg" "xmlattributes" "xmlbinary" "xmlcast" "xmlcomment"
|
||||
"xmlconcat" "xmldeclaration" "xmldocument" "xmlelement" "xmlexists" "xmlforest"
|
||||
"xmliterate" "xmlnamespaces" "xmlparse" "xmlpi" "xmlquery" "xmlroot" "xmlschema"
|
||||
"xmlserialize" "xmltable" "xmltext" "xmlvalidate" "year" "yes" "zone"))
|
||||
|
||||
;;; Company backend
|
||||
|
||||
(cl-defun company-postgresql/candidates (prefix conn)
|
||||
(-filter
|
||||
(apply-partially #'s-starts-with? prefix)
|
||||
(append (-map (lambda (s)
|
||||
(propertize s 'company-postgresql-annotation "table"))
|
||||
|
||||
(-map (lambda (s)
|
||||
(propertize s 'company-postgresql-annotation
|
||||
(format "%s.%s %s"
|
||||
(get-text-property 0 'table-name s)
|
||||
s
|
||||
(->
|
||||
(get-text-property 0 'data-type s)
|
||||
(->string)
|
||||
(upcase)))))
|
||||
(company-sql/list-columns conn))
|
||||
(-map (lambda (s)
|
||||
(propertize s 'company-postgresql-annotation "keyword"))
|
||||
company-postgresql/keywords)))))
|
||||
|
||||
(defun company-postgresql (command &optional arg &rest _)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-postgresql))
|
||||
(init (company-sql/connect))
|
||||
(prefix (company-grab-symbol))
|
||||
(annotation
|
||||
(get-text-property 0 'company-postgresql-annotation arg))
|
||||
(candidates (company-postgresql/candidates
|
||||
arg
|
||||
(company-sql/connect)))
|
||||
(duplicates t)
|
||||
(ignore-case t)))
|
||||
|
||||
;;; org-babel company sql
|
||||
|
||||
(defvar-local org-company-sql/connections
|
||||
())
|
||||
|
||||
(defun org-company-sql/connect (conn-params)
|
||||
(or (alist-get-equal conn-params org-company-sql/connections)
|
||||
(let ((conn (apply 'emacsql-psql conn-params)))
|
||||
(add-to-list 'org-company-sql/connections (cons conn-params conn))
|
||||
conn)))
|
||||
|
||||
(defun org-company-sql/in-sql-source-block-p ()
|
||||
(let ((org-elt (org-element-at-point)))
|
||||
(and (eq 'src-block (car org-elt))
|
||||
(equal "sql" (plist-get (cadr org-elt)
|
||||
:language)))))
|
||||
|
||||
(defun org-company-sql/parse-cmdline (cmdline)
|
||||
(let* ((lexed (s-split (rx (one-or-more blank)) cmdline))
|
||||
(go (lambda (state tokens)
|
||||
(if (null tokens) ()
|
||||
(let ((token (car tokens))
|
||||
(tokens (cdr tokens)))
|
||||
(if (null state)
|
||||
(if (s-starts-with? "-" token)
|
||||
(funcall go token tokens)
|
||||
(cons token (funcall go state tokens)))
|
||||
(cons (cons state token) ; ("-h" . "localhost")
|
||||
(funcall go nil tokens)))))))
|
||||
(opts (funcall go nil lexed)))
|
||||
opts))
|
||||
|
||||
(defun org-company-sql/source-block-conn-params ()
|
||||
(let* ((block-info (org-babel-get-src-block-info))
|
||||
(params (caddr block-info))
|
||||
(cmdline (alist-get :cmdline params))
|
||||
(parsed (org-company-sql/parse-cmdline cmdline))
|
||||
(opts (-filter #'listp parsed))
|
||||
(positional (-filter #'stringp parsed))
|
||||
(host (alist-get-equal "-h" opts))
|
||||
(port (or (alist-get-equal "-p" opts)
|
||||
"5432"))
|
||||
(dbname (or (alist-get-equal "-d" opts)
|
||||
(car positional)))
|
||||
(username (or (alist-get-equal "-U" opts)
|
||||
(cadr positional))))
|
||||
(list dbname
|
||||
:hostname host
|
||||
:username username
|
||||
:port port)))
|
||||
|
||||
(defun org-company-sql/connection-for-source-block ()
|
||||
(org-company-sql/connect
|
||||
(org-company-sql/source-block-conn-params)))
|
||||
|
||||
|
||||
(defun company-ob-postgresql (command &optional arg &rest _)
|
||||
(interactive (list 'interactive))
|
||||
(cl-case command
|
||||
(interactive (company-begin-backend 'company-ob-postgresql))
|
||||
(prefix (and (org-company-sql/in-sql-source-block-p)
|
||||
(company-grab-symbol)))
|
||||
(annotation (get-text-property 0 'company-postgresql-annotation arg))
|
||||
(candidates
|
||||
(company-postgresql/candidates
|
||||
arg
|
||||
(org-company-sql/connection-for-source-block)))
|
||||
(duplicates t)
|
||||
(ignore-case t)))
|
||||
|
||||
;;;
|
||||
|
||||
(provide 'company-sql)
|
||||
1109
users/grfn/emacs.d/config.el
Normal file
1109
users/grfn/emacs.d/config.el
Normal file
File diff suppressed because it is too large
Load diff
39
users/grfn/emacs.d/cpp.el
Normal file
39
users/grfn/emacs.d/cpp.el
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
|
||||
(load! "google-c-style")
|
||||
|
||||
(after! flycheck
|
||||
(add-to-list 'flycheck-disabled-checkers 'c/c++-gcc)
|
||||
(add-to-list 'flycheck-disabled-checkers 'c/c++-clang))
|
||||
|
||||
(defun +grfn/cpp-setup ()
|
||||
(when (s-starts-with?
|
||||
"/home/grfn/code/depot/third_party/nix"
|
||||
(buffer-file-name))
|
||||
(setq lsp-clients-clangd-executable "/home/grfn/code/depot/users/grfn/emacs.d/nix-clangd.sh"
|
||||
lsp-clients-clangd-args nil)
|
||||
(google-set-c-style)
|
||||
(lsp)
|
||||
(add-to-list 'flycheck-disabled-checkers 'c/c++-gcc)
|
||||
(add-to-list 'flycheck-disabled-checkers 'c/c++-clang)))
|
||||
|
||||
(add-hook 'c++-mode-hook #'+grfn/cpp-setup)
|
||||
|
||||
(use-package! protobuf-mode)
|
||||
|
||||
(use-package! clang-format+
|
||||
:config
|
||||
(add-hook 'c-mode-common-hook #'clang-format+-mode))
|
||||
|
||||
(map!
|
||||
(:map c++-mode-map
|
||||
:leader
|
||||
(:n "/ i" #'counsel-semantic-or-imenu)))
|
||||
|
||||
(comment
|
||||
(setq
|
||||
lsp-clients-clangd-executable
|
||||
"/home/grfn/code/depot/third_party/nix/clangd.sh"
|
||||
lsp-clients-clangd-args nil)
|
||||
)
|
||||
28
users/grfn/emacs.d/email.el
Normal file
28
users/grfn/emacs.d/email.el
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(after! notmuch
|
||||
(setq notmuch-saved-searches
|
||||
'((:name "inbox" :query "tag:inbox tag:important not tag:trash" :key "i")
|
||||
(:name "flagged" :query "tag:flagged" :key "f")
|
||||
(:name "sent" :query "tag:sent" :key "s")
|
||||
(:name "drafts" :query "tag:draft" :key "d")
|
||||
|
||||
(:name "work" :query "tag:inbox and tag:important and path:work/**"
|
||||
:key "w")
|
||||
(:name "personal" :query "tag:inbox and tag:important and path:personal/**"
|
||||
:key "p"))
|
||||
message-send-mail-function 'message-send-mail-with-sendmail)
|
||||
|
||||
(add-hook! notmuch-message-mode-hook #'notmuch-company-setup))
|
||||
|
||||
(setq notmuch-saved-searches
|
||||
'((:name "inbox" :query "tag:inbox tag:important not tag:trash" :key "i")
|
||||
(:name "flagged" :query "tag:flagged" :key "f")
|
||||
(:name "sent" :query "tag:sent" :key "s")
|
||||
(:name "drafts" :query "tag:draft" :key "d")
|
||||
|
||||
(:name "work" :query "tag:inbox and tag:important and path:work/**"
|
||||
:key "w")
|
||||
(:name "personal" :query "tag:inbox and tag:important and path:personal/**"
|
||||
:key "p"))
|
||||
message-send-mail-function 'message-send-mail-with-sendmail)
|
||||
99
users/grfn/emacs.d/github-org.el
Normal file
99
users/grfn/emacs.d/github-org.el
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'ghub)
|
||||
|
||||
(defun grfn/alist->plist (alist)
|
||||
(->> alist
|
||||
(-mapcat (lambda (pair)
|
||||
(list (intern (concat ":" (symbol-name (car pair))))
|
||||
(cdr pair))))))
|
||||
|
||||
;;;
|
||||
|
||||
(cl-defstruct pull-request url number title author repository)
|
||||
|
||||
(defun grfn/query-pulls (query)
|
||||
(let ((resp (ghub-graphql "query reviewRequests($query: String!) {
|
||||
reviewRequests: search(
|
||||
type:ISSUE,
|
||||
query: $query,
|
||||
first: 100
|
||||
) {
|
||||
issueCount
|
||||
nodes {
|
||||
... on PullRequest {
|
||||
url
|
||||
number
|
||||
title
|
||||
author {
|
||||
login
|
||||
... on User { name }
|
||||
}
|
||||
repository {
|
||||
name
|
||||
owner { login }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}" `((query . ,query)))))
|
||||
(->> resp
|
||||
(alist-get 'data)
|
||||
(alist-get 'reviewRequests)
|
||||
(alist-get 'nodes)
|
||||
(-map
|
||||
(lambda (pr)
|
||||
(apply
|
||||
#'make-pull-request
|
||||
(grfn/alist->plist pr)))))))
|
||||
|
||||
(defun grfn/requested-changes ())
|
||||
|
||||
(defun grfn/pull-request->org-headline (format-string level pr)
|
||||
(check-type format-string string)
|
||||
(check-type level integer)
|
||||
(check-type pr pull-request)
|
||||
(s-format (concat (make-string level ?*) " " format-string)
|
||||
'aget
|
||||
`((author . ,(or (->> pr (pull-request-author) (alist-get 'name))
|
||||
"no author"))
|
||||
(owner . ,(->> pr (pull-request-repository)
|
||||
(alist-get 'owner)
|
||||
(alist-get 'login)))
|
||||
(repo . ,(->> pr (pull-request-repository) (alist-get 'name)))
|
||||
(pr-link . ,(org-make-link-string
|
||||
(pull-request-url pr)
|
||||
(pull-request-title pr)))
|
||||
(today . ,(format-time-string "%Y-%m-%d %a")))))
|
||||
|
||||
(defun grfn/org-headlines-from-review-requests (level)
|
||||
"Create org-mode headlines at LEVEL from all review-requested PRs on Github"
|
||||
(interactive "*nLevel: ")
|
||||
(let* ((prs (grfn/query-pulls
|
||||
"is:open is:pr review-requested:glittershark archived:false"))
|
||||
(text (mapconcat
|
||||
(apply-partially
|
||||
#'grfn/pull-request->org-headline
|
||||
"TODO Review ${author}'s PR on ${owner}/${repo}: ${pr-link} :pr:
|
||||
SCHEDULED: <${today}>"
|
||||
level) prs "\n")))
|
||||
(save-mark-and-excursion
|
||||
(insert text))
|
||||
(org-align-tags 't)))
|
||||
|
||||
(defun grfn/org-headlines-from-requested-changes (level)
|
||||
"Create org-mode headlines at LEVEL from all PRs with changes requested
|
||||
on Github"
|
||||
(interactive "*nLevel: ")
|
||||
(let* ((prs (grfn/query-pulls
|
||||
(concat "is:pr is:open author:glittershark archived:false "
|
||||
"sort:updated-desc review:changes-requested")))
|
||||
(text (mapconcat
|
||||
(apply-partially
|
||||
#'grfn/pull-request->org-headline
|
||||
"TODO Address review comments on ${pr-link} :pr:
|
||||
SCHEDULED: <${today}>"
|
||||
level) prs "\n")))
|
||||
(save-mark-and-excursion
|
||||
(insert text))
|
||||
(org-align-tags 't)))
|
||||
151
users/grfn/emacs.d/google-c-style.el
Normal file
151
users/grfn/emacs.d/google-c-style.el
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
;;; google-c-style.el --- Google's C/C++ style for c-mode
|
||||
|
||||
;; Keywords: c, tools
|
||||
|
||||
;; google-c-style.el is Copyright (C) 2008 Google Inc. All Rights Reserved.
|
||||
;;
|
||||
;; It is free software; you can redistribute it and/or modify it under the
|
||||
;; terms of either:
|
||||
;;
|
||||
;; a) the GNU General Public License as published by the Free Software
|
||||
;; Foundation; either version 1, or (at your option) any later version, or
|
||||
;;
|
||||
;; b) the "Artistic License".
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Provides the google C/C++ coding style. You may wish to add
|
||||
;; `google-set-c-style' to your `c-mode-common-hook' after requiring this
|
||||
;; file. For example:
|
||||
;;
|
||||
;; (add-hook 'c-mode-common-hook 'google-set-c-style)
|
||||
;;
|
||||
;; If you want the RETURN key to go to the next line and space over
|
||||
;; to the right place, add this to your .emacs right after the load-file:
|
||||
;;
|
||||
;; (add-hook 'c-mode-common-hook 'google-make-newline-indent)
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; For some reason 1) c-backward-syntactic-ws is a macro and 2) under Emacs 22
|
||||
;; bytecode cannot call (unexpanded) macros at run time:
|
||||
(eval-when-compile (require 'cc-defs))
|
||||
|
||||
;; Wrapper function needed for Emacs 21 and XEmacs (Emacs 22 offers the more
|
||||
;; elegant solution of composing a list of lineup functions or quantities with
|
||||
;; operators such as "add")
|
||||
(defun google-c-lineup-expression-plus-4 (langelem)
|
||||
"Indents to the beginning of the current C expression plus 4 spaces.
|
||||
|
||||
This implements title \"Function Declarations and Definitions\"
|
||||
of the Google C++ Style Guide for the case where the previous
|
||||
line ends with an open parenthese.
|
||||
|
||||
\"Current C expression\", as per the Google Style Guide and as
|
||||
clarified by subsequent discussions, means the whole expression
|
||||
regardless of the number of nested parentheses, but excluding
|
||||
non-expression material such as \"if(\" and \"for(\" control
|
||||
structures.
|
||||
|
||||
Suitable for inclusion in `c-offsets-alist'."
|
||||
(save-excursion
|
||||
(back-to-indentation)
|
||||
;; Go to beginning of *previous* line:
|
||||
(c-backward-syntactic-ws)
|
||||
(back-to-indentation)
|
||||
(cond
|
||||
;; We are making a reasonable assumption that if there is a control
|
||||
;; structure to indent past, it has to be at the beginning of the line.
|
||||
((looking-at "\\(\\(if\\|for\\|while\\)\\s *(\\)")
|
||||
(goto-char (match-end 1)))
|
||||
;; For constructor initializer lists, the reference point for line-up is
|
||||
;; the token after the initial colon.
|
||||
((looking-at ":\\s *")
|
||||
(goto-char (match-end 0))))
|
||||
(vector (+ 4 (current-column)))))
|
||||
|
||||
;;;###autoload
|
||||
(defconst google-c-style
|
||||
`((c-recognize-knr-p . nil)
|
||||
(c-enable-xemacs-performance-kludge-p . t) ; speed up indentation in XEmacs
|
||||
(c-basic-offset . 2)
|
||||
(indent-tabs-mode . nil)
|
||||
(c-comment-only-line-offset . 0)
|
||||
(c-hanging-braces-alist . ((defun-open after)
|
||||
(defun-close before after)
|
||||
(class-open after)
|
||||
(class-close before after)
|
||||
(inexpr-class-open after)
|
||||
(inexpr-class-close before)
|
||||
(namespace-open after)
|
||||
(inline-open after)
|
||||
(inline-close before after)
|
||||
(block-open after)
|
||||
(block-close . c-snug-do-while)
|
||||
(extern-lang-open after)
|
||||
(extern-lang-close after)
|
||||
(statement-case-open after)
|
||||
(substatement-open after)))
|
||||
(c-hanging-colons-alist . ((case-label)
|
||||
(label after)
|
||||
(access-label after)
|
||||
(member-init-intro before)
|
||||
(inher-intro)))
|
||||
(c-hanging-semi&comma-criteria
|
||||
. (c-semi&comma-no-newlines-for-oneline-inliners
|
||||
c-semi&comma-inside-parenlist
|
||||
c-semi&comma-no-newlines-before-nonblanks))
|
||||
(c-indent-comments-syntactically-p . t)
|
||||
(comment-column . 40)
|
||||
(c-indent-comment-alist . ((other . (space . 2))))
|
||||
(c-cleanup-list . (brace-else-brace
|
||||
brace-elseif-brace
|
||||
brace-catch-brace
|
||||
empty-defun-braces
|
||||
defun-close-semi
|
||||
list-close-comma
|
||||
scope-operator))
|
||||
(c-offsets-alist . ((arglist-intro google-c-lineup-expression-plus-4)
|
||||
(func-decl-cont . ++)
|
||||
(member-init-intro . ++)
|
||||
(inher-intro . ++)
|
||||
(comment-intro . 0)
|
||||
(arglist-close . c-lineup-arglist)
|
||||
(topmost-intro . 0)
|
||||
(block-open . 0)
|
||||
(inline-open . 0)
|
||||
(substatement-open . 0)
|
||||
(statement-cont
|
||||
.
|
||||
(,(when (fboundp 'c-no-indent-after-java-annotations)
|
||||
'c-no-indent-after-java-annotations)
|
||||
,(when (fboundp 'c-lineup-assignments)
|
||||
'c-lineup-assignments)
|
||||
++))
|
||||
(label . /)
|
||||
(case-label . +)
|
||||
(statement-case-open . +)
|
||||
(statement-case-intro . +) ; case w/o {
|
||||
(access-label . /)
|
||||
(innamespace . 0))))
|
||||
"Google C/C++ Programming Style.")
|
||||
|
||||
;;;###autoload
|
||||
(defun google-set-c-style ()
|
||||
"Set the current buffer's c-style to Google C/C++ Programming
|
||||
Style. Meant to be added to `c-mode-common-hook'."
|
||||
(interactive)
|
||||
(make-local-variable 'c-tab-always-indent)
|
||||
(setq c-tab-always-indent t)
|
||||
(c-add-style "Google" google-c-style t))
|
||||
|
||||
;;;###autoload
|
||||
(defun google-make-newline-indent ()
|
||||
"Sets up preferred newline behavior. Not set by default. Meant
|
||||
to be added to `c-mode-common-hook'."
|
||||
(interactive)
|
||||
(define-key c-mode-base-map "\C-m" 'newline-and-indent)
|
||||
(define-key c-mode-base-map [ret] 'newline-and-indent))
|
||||
|
||||
(provide 'google-c-style)
|
||||
;;; google-c-style.el ends here
|
||||
128
users/grfn/emacs.d/grid.el
Normal file
128
users/grfn/emacs.d/grid.el
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 's)
|
||||
|
||||
(defun grfn/all-match-groups (s)
|
||||
(loop for n from 1
|
||||
for x = (match-string n s)
|
||||
while x
|
||||
collect x))
|
||||
|
||||
(defun projectile-grid-ff (path &optional ask)
|
||||
"Call `find-file' function on PATH when it is not nil and the file exists.
|
||||
If file does not exist and ASK in not nil it will ask user to proceed."
|
||||
(if (or (and path (file-exists-p path))
|
||||
(and ask (yes-or-no-p
|
||||
(s-lex-format
|
||||
"File does not exists. Create a new buffer ${path} ?"))))
|
||||
(find-file path)))
|
||||
|
||||
(defun projectile-grid-goto-file (filepath &optional ask)
|
||||
"Find FILEPATH after expanding root. ASK is passed straight to `projectile-grid-ff'."
|
||||
(projectile-grid-ff (projectile-expand-root filepath) ask))
|
||||
|
||||
(defun projectile-grid-choices (ds)
|
||||
"Uses `projectile-dir-files' function to find files in directories.
|
||||
The DIRS is list of lists consisting of a directory path and regexp to filter files from that directory.
|
||||
Optional third element can be present in the DS list. The third element will be a prefix to be placed before
|
||||
the filename in the resulting choice.
|
||||
Returns a hash table with keys being short names (choices) and values being relative paths to the files."
|
||||
(loop with hash = (make-hash-table :test 'equal)
|
||||
for (dir re prefix) in ds do
|
||||
(loop for file in (projectile-dir-files (projectile-expand-root dir)) do
|
||||
(when (string-match re file)
|
||||
(puthash
|
||||
(concat (or prefix "")
|
||||
(s-join "/" (grfn/all-match-groups file)))
|
||||
(concat dir file)
|
||||
hash)))
|
||||
finally return hash))
|
||||
|
||||
(defmacro projectile-grid-find-resource (prompt dirs &optional newfile-template)
|
||||
"Presents files from DIRS with PROMPT to the user using `projectile-completing-read'.
|
||||
If users chooses a non existant file and NEWFILE-TEMPLATE is not nil
|
||||
it will use that variable to interpolate the name for the new file.
|
||||
NEWFILE-TEMPLATE will be the argument for `s-lex-format'.
|
||||
The bound variable is \"filename\"."
|
||||
`(lexical-let ((choices (projectile-grid-choices ,dirs)))
|
||||
(projectile-completing-read
|
||||
,prompt
|
||||
(hash-table-keys choices)
|
||||
:action
|
||||
(lambda (c)
|
||||
(let* ((filepath (gethash c choices))
|
||||
(filename c)) ;; so `s-lex-format' can interpolate FILENAME
|
||||
(if filepath
|
||||
(projectile-grid-goto-file filepath)
|
||||
(when-let ((newfile-template ,newfile-template))
|
||||
(projectile-grid-goto-file
|
||||
(funcall newfile-template filepath)
|
||||
;; (cond
|
||||
;; ((functionp newfile-template) (funcall newfile-template filepath))
|
||||
;; ((stringp newfile-template) (s-lex-format newfile-template)))
|
||||
t))))))))
|
||||
|
||||
(defun projectile-grid-find-model ()
|
||||
"Find a model."
|
||||
(interactive)
|
||||
(projectile-grid-find-resource
|
||||
"model: "
|
||||
'(("python/urbint_lib/models/"
|
||||
"\\(.+\\)\\.py$")
|
||||
("python/urbint_lib/"
|
||||
"\\(.+\\)/models/\\(.+\\).py$"))
|
||||
(lambda (filename)
|
||||
(pcase (s-split "/" filename)
|
||||
(`(,model)
|
||||
(s-lex-format "python/urbint_lib/models/${model}.py"))
|
||||
(`(,app ,model)
|
||||
(s-lex-format "python/urbint_lib/${app}/models/${model}.py"))))))
|
||||
|
||||
(defun projectile-grid-find-repository ()
|
||||
"Find a repository."
|
||||
(interactive)
|
||||
(projectile-grid-find-resource
|
||||
"repository: "
|
||||
'(("python/urbint_lib/repositories/"
|
||||
"\\(.+\\)\\.py$")
|
||||
("python/urbint_lib/"
|
||||
"\\(.+\\)/repositories/\\(.+\\).py$"))
|
||||
(lambda (filename)
|
||||
(pcase (s-split "/" filename)
|
||||
(`(,repository)
|
||||
(s-lex-format "python/urbint_lib/repositories/${repository}.py"))
|
||||
(`(,app ,repository)
|
||||
(s-lex-format "python/urbint_lib/${app}/repositories/${repository}.py"))))))
|
||||
|
||||
(defun projectile-grid-find-controller ()
|
||||
"Find a controller."
|
||||
(interactive)
|
||||
(projectile-grid-find-resource
|
||||
"controller: "
|
||||
'(("backend/src/grid/api/controllers/"
|
||||
"\\(.+\\)\\.py$")
|
||||
("backend/src/grid/api/apps/"
|
||||
"\\(.+\\)/controllers/\\(.+\\).py$"))
|
||||
(lambda (filename)
|
||||
(pcase (s-split "/" filename)
|
||||
(`(,controller)
|
||||
(s-lex-format "backend/src/grid/api/controllers/${controller}.py"))
|
||||
(`(,app ,controller)
|
||||
(s-lex-format "backend/src/grid/api/apps/${app}/controllers/${controller}.py"))))))
|
||||
|
||||
(setq projectile-grid-mode-map
|
||||
(let ((map (make-keymap)))
|
||||
(map!
|
||||
(:map map
|
||||
(:leader
|
||||
(:desc "Edit..." :prefix "e"
|
||||
:desc "Model" :n "m" #'projectile-grid-find-model
|
||||
:desc "Controller" :n "c" #'projectile-grid-find-controller
|
||||
:desc "Repository" :n "r" #'projectile-grid-find-repository))))
|
||||
map))
|
||||
|
||||
(define-minor-mode projectile-grid-mode
|
||||
"Minor mode for finding files in GRID"
|
||||
:init-value nil
|
||||
:lighter " GRID"
|
||||
:keymap projectile-grid-mode-map)
|
||||
234
users/grfn/emacs.d/init.el
Normal file
234
users/grfn/emacs.d/init.el
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(doom! :completion
|
||||
company ; the ultimate code completion backend
|
||||
;;helm ; the *other* search engine for love and life
|
||||
;;ido ; the other *other* search engine...
|
||||
ivy ; a search engine for love and life
|
||||
|
||||
:ui
|
||||
;;deft ; notational velocity for Emacs
|
||||
doom ; what makes DOOM look the way it does
|
||||
;doom-dashboard ; a nifty splash screen for Emacs
|
||||
doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||||
;fill-column ; a `fill-column' indicator
|
||||
hl-todo ; highlight TODO/FIXME/NOTE tags
|
||||
;;indent-guides ; highlighted indent columns
|
||||
modeline ; snazzy, Atom-inspired modeline, plus API
|
||||
nav-flash ; blink the current line after jumping
|
||||
;;neotree ; a project drawer, like NERDTree for vim
|
||||
ophints ; highlight the region an operation acts on
|
||||
(popup ; tame sudden yet inevitable temporary windows
|
||||
+all ; catch all popups that start with an asterix
|
||||
+defaults) ; default popup rules
|
||||
ligatures ; replace bits of code with pretty symbols
|
||||
;;tabbar ; FIXME an (incomplete) tab bar for Emacs
|
||||
;;treemacs ; a project drawer, like neotree but cooler
|
||||
unicode ; extended unicode support for various languages
|
||||
vc-gutter ; vcs diff in the fringe
|
||||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||||
window-select ; visually switch windows
|
||||
workspaces ; tab emulation, persistence & separate workspaces
|
||||
|
||||
:editor
|
||||
(evil +everywhere); come to the dark side, we have cookies
|
||||
file-templates ; auto-snippets for empty files
|
||||
fold ; (nigh) universal code folding
|
||||
;;(format +onsave) ; automated prettiness
|
||||
;;lispy ; vim for lisp, for people who dont like vim
|
||||
multiple-cursors ; editing in many places at once
|
||||
;;parinfer ; turn lisp into python, sort of
|
||||
rotate-text ; cycle region at point between text candidates
|
||||
snippets ; my elves. They type so I don't have to
|
||||
word-wrap
|
||||
|
||||
:emacs
|
||||
(dired ; making dired pretty [functional]
|
||||
;;+ranger ; bringing the goodness of ranger to dired
|
||||
;;+icons ; colorful icons for dired-mode
|
||||
)
|
||||
electric ; smarter, keyword-based electric-indent
|
||||
;;eshell ; a consistent, cross-platform shell (WIP)
|
||||
;;term ; terminals in Emacs
|
||||
vc ; version-control and Emacs, sitting in a tree
|
||||
(undo +tree)
|
||||
|
||||
:tools
|
||||
;;ansible
|
||||
;;debugger ; FIXME stepping through code, to help you add bugs
|
||||
;;direnv
|
||||
docker
|
||||
;;editorconfig ; let someone else argue about tabs vs spaces
|
||||
;; ein ; tame Jupyter notebooks with emacs
|
||||
(eval +overlay) ; run code, run (also, repls)
|
||||
gist ; interacting with github gists
|
||||
(lookup ; helps you navigate your code and documentation
|
||||
+docsets) ; ...or in Dash docsets locally
|
||||
lsp
|
||||
;;macos ; MacOS-specific commands
|
||||
magit ; a git porcelain for Emacs
|
||||
make ; run make tasks from Emacs
|
||||
pass ; password manager for nerds
|
||||
pdf ; pdf enhancements
|
||||
;;prodigy ; FIXME managing external services & code builders
|
||||
;;rgb ; creating color strings
|
||||
;;terraform ; infrastructure as code
|
||||
;;tmux ; an API for interacting with tmux
|
||||
;;upload ; map local to remote projects via ssh/ftp
|
||||
;;wakatime
|
||||
;;vterm ; another terminals in Emacs
|
||||
|
||||
:checkers
|
||||
syntax ; tasing you for every semicolon you forget
|
||||
; spell ; tasing you for misspelling mispelling
|
||||
|
||||
:lang
|
||||
agda ; types of types of types of types...
|
||||
;;assembly ; assembly for fun or debugging
|
||||
cc ; C/C++/Obj-C madness
|
||||
clojure ; java with a lisp
|
||||
common-lisp ; if you've seen one lisp, you've seen them all
|
||||
; coq ; proofs-as-programs
|
||||
;;crystal ; ruby at the speed of c
|
||||
;;csharp ; unity, .NET, and mono shenanigans
|
||||
data ; config/data formats
|
||||
erlang ; an elegant language for a more civilized age
|
||||
elixir ; erlang done right
|
||||
;;elm ; care for a cup of TEA?
|
||||
emacs-lisp ; drown in parentheses
|
||||
;;ess ; emacs speaks statistics
|
||||
;;go ; the hipster dialect
|
||||
;; (haskell +intero) ; a language that's lazier than I am
|
||||
haskell ; a language that's lazier than I am
|
||||
;;hy ; readability of scheme w/ speed of python
|
||||
idris ;
|
||||
;;(java +meghanada) ; the poster child for carpal tunnel syndrome
|
||||
javascript ; all(hope(abandon(ye(who(enter(here))))))
|
||||
julia ; a better, faster MATLAB
|
||||
;;kotlin ; a better, slicker Java(Script)
|
||||
latex ; writing papers in Emacs has never been so fun
|
||||
;;ledger ; an accounting system in Emacs
|
||||
lua ; one-based indices? one-based indices
|
||||
markdown ; writing docs for people to ignore
|
||||
;;nim ; python + lisp at the speed of c
|
||||
nix ; I hereby declare "nix geht mehr!"
|
||||
;;ocaml ; an objective camel
|
||||
(org ; organize your plain life in plain text
|
||||
+dragndrop ; drag & drop files/images into org buffers
|
||||
+attach ; custom attachment system
|
||||
+babel ; running code in org
|
||||
+capture ; org-capture in and outside of Emacs
|
||||
+export ; Exporting org to whatever you want
|
||||
;; +habit ; Keep track of your habits
|
||||
+present ; Emacs for presentations
|
||||
+pretty
|
||||
+brain
|
||||
+protocol) ; Support for org-protocol:// links
|
||||
;;perl ; write code no one else can comprehend
|
||||
;;php ; perl's insecure younger brother
|
||||
;;plantuml ; diagrams for confusing people more
|
||||
purescript ; javascript, but functional
|
||||
(python +lsp) ; beautiful is better than ugly
|
||||
;;qt ; the 'cutest' gui framework ever
|
||||
racket ; a DSL for DSLs
|
||||
rest ; Emacs as a REST client
|
||||
;;ruby ; 1.step do {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||||
rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||||
;;scala ; java, but good
|
||||
(sh +fish) ; she sells (ba|z|fi)sh shells on the C xor
|
||||
;;solidity ; do you need a blockchain? No.
|
||||
;;swift ; who asked for emoji variables?
|
||||
;;terra ; Earth and Moon in alignment for performance.
|
||||
;;web ; the tubes
|
||||
;;vala ; GObjective-C
|
||||
|
||||
;; Applications are complex and opinionated modules that transform Emacs
|
||||
;; toward a specific purpose. They may have additional dependencies and
|
||||
;; should be loaded late.
|
||||
:app
|
||||
;;(email +gmail) ; emacs as an email client
|
||||
irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
twitter ; twitter client https://twitter.com/vnought
|
||||
;;(write ; emacs as a word processor (latex + org + markdown)
|
||||
;; +wordnut ; wordnet (wn) search
|
||||
;; +langtool) ; a proofreader (grammar/style check) for Emacs
|
||||
|
||||
:email
|
||||
;; (mu4e +gmail)
|
||||
notmuch
|
||||
|
||||
:collab
|
||||
;;floobits ; peer programming for a price
|
||||
;;impatient-mode ; show off code over HTTP
|
||||
|
||||
:config
|
||||
;; For literate config users. This will tangle+compile a config.org
|
||||
;; literate config in your `doom-private-dir' whenever it changes.
|
||||
;;literate
|
||||
|
||||
;; The default module sets reasonable defaults for Emacs. It also
|
||||
;; provides a Spacemacs-inspired keybinding scheme and a smartparens
|
||||
;; config. Use it as a reference for your own modules.
|
||||
(default +bindings +smartparens))
|
||||
(custom-set-variables
|
||||
;; custom-set-variables was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(doom-big-font-mode nil)
|
||||
'(flycheck-javascript-flow-args nil)
|
||||
'(org-agenda-files
|
||||
'("/home/griffin/notes/personal.org" "/home/griffin/notes/2020-01-27-data-pipeline-deploy-mismatch.org" "/home/griffin/notes/architecture.org" "/home/griffin/notes/cooking.org" "/home/griffin/notes/culture-survey.org" "/home/griffin/notes/dir-structure.org" "/home/griffin/notes/dnd.org" "/home/griffin/notes/inbox.org" "/home/griffin/notes/misc-todo.org" "/home/griffin/notes/nix-talk.org" "/home/griffin/notes/notes.org" "/home/griffin/notes/one-on-one.org" "/home/griffin/notes/work.org" "/home/griffin/notes/xanthous.org" "/home/griffin/notes/xgboost.org"))
|
||||
'(safe-local-variable-values
|
||||
'((intero-stack-yaml . "/home/griffin/code/mlem/stack.yaml")
|
||||
(elisp-lint-indent-specs
|
||||
(if-let* . 2)
|
||||
(when-let* . 1)
|
||||
(let* . defun)
|
||||
(nrepl-dbind-response . 2)
|
||||
(cider-save-marker . 1)
|
||||
(cider-propertize-region . 1)
|
||||
(cider-map-repls . 1)
|
||||
(cider--jack-in . 1)
|
||||
(cider--make-result-overlay . 1)
|
||||
(insert-label . defun)
|
||||
(insert-align-label . defun)
|
||||
(insert-rect . defun)
|
||||
(cl-defun . 2)
|
||||
(with-parsed-tramp-file-name . 2)
|
||||
(thread-first . 1)
|
||||
(thread-last . 1))
|
||||
(checkdoc-package-keywords-flag)
|
||||
(cider-jack-in-default . "shadow-cljs")
|
||||
(projectile-project-root . "/home/griffin/code/urb/grid/backend/src")
|
||||
(python-pytest-executable . "/home/griffin/code/urb/grid/backend/src/.venv/bin/pytest"))))
|
||||
(custom-set-faces
|
||||
;; custom-set-faces was added by Custom.
|
||||
;; If you edit it by hand, you could mess it up, so be careful.
|
||||
;; Your init file should contain only one such instance.
|
||||
;; If there is more than one, they won't work right.
|
||||
'(default ((((class color) (min-colors 89)) (:foreground "#657b83" :background "#fdf6e3"))))
|
||||
'(agda2-highlight-bound-variable-face ((t nil)))
|
||||
'(agda2-highlight-coinductive-constructor-face ((t (:foreground "#b58900"))))
|
||||
'(agda2-highlight-datatype-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-dotted-face ((t nil)))
|
||||
'(agda2-highlight-error-face ((t (:foreground "#dc322f" :underline t))))
|
||||
'(agda2-highlight-field-face ((t (:foreground "#dc322f"))))
|
||||
'(agda2-highlight-function-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-incomplete-pattern-face ((t (:background "#cb4b16" :foreground "#002b36"))))
|
||||
'(agda2-highlight-inductive-constructor-face ((t (:foreground "#859900"))))
|
||||
'(agda2-highlight-keyword-face ((t (:foreground "#859900"))))
|
||||
'(agda2-highlight-module-face ((t (:foreground "#b58900"))))
|
||||
'(agda2-highlight-number-face ((t (:foreground "#6c71c4"))))
|
||||
'(agda2-highlight-operator-face ((t nil)))
|
||||
'(agda2-highlight-postulate-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-primitive-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-primitive-type-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-record-face ((t (:foreground "#268bd2"))))
|
||||
'(agda2-highlight-string-face ((t (:foreground "#2aa198"))))
|
||||
'(agda2-highlight-symbol-face ((((background "#fdf6e3")) (:foreground "#586e75"))))
|
||||
'(agda2-highlight-termination-problem-face ((t (:background "#cb4b16" :foreground "#002b36"))))
|
||||
'(agda2-highlight-typechecks-face ((t (:background "#2aa198" :foreground "#002b36"))))
|
||||
'(agda2-highlight-unsolved-constraint-face ((t (:background "#eee8d5"))))
|
||||
'(agda2-highlight-unsolved-meta-face ((t (:background "#eee8d5")))))
|
||||
125
users/grfn/emacs.d/irc.el
Normal file
125
users/grfn/emacs.d/irc.el
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'erc)
|
||||
(require 'alert)
|
||||
|
||||
(defun irc-connect ()
|
||||
(interactive)
|
||||
(let ((pw (s-trim (shell-command-to-string "pass irccloud/freenode")))
|
||||
(gnutls-verify-error nil))
|
||||
(erc-tls :server "bnc.irccloud.com"
|
||||
:port 6697
|
||||
:nick "grfn"
|
||||
:password (concat "bnc@"
|
||||
(s-trim (shell-command-to-string "hostname"))
|
||||
":"
|
||||
pw))))
|
||||
|
||||
|
||||
(defgroup erc-alert nil
|
||||
"Alert me using alert.el for important ERC messages"
|
||||
:group 'erc)
|
||||
|
||||
(defcustom erc-noise-regexp
|
||||
"\\(Logging in:\\|Signing off\\|You're now away\\|Welcome back\\)"
|
||||
"This regexp matches unwanted noise."
|
||||
:type 'regexp
|
||||
:group 'erc)
|
||||
|
||||
(setq tvl-enabled? t)
|
||||
|
||||
(defun disable-tvl-notifications ()
|
||||
(interactive)
|
||||
(setq tvl-enabled? nil))
|
||||
|
||||
(defun enable-tvl-notifications ()
|
||||
(interactive)
|
||||
(setq tvl-enabled? t))
|
||||
|
||||
(defun erc-alert-important-p (info)
|
||||
(let ((message (plist-get info :message))
|
||||
(erc-message (-> info (plist-get :data) (plist-get :message)))
|
||||
(erc-channel (-> info (plist-get :data) (plist-get :channel))))
|
||||
(and erc-message
|
||||
(not (or (string-match "^\\** *Users on #" message)
|
||||
(string-match erc-noise-regexp
|
||||
message)))
|
||||
(or (and tvl-enabled?
|
||||
(string-equal erc-channel "##tvl"))
|
||||
(string-match "grfn" message)))))
|
||||
|
||||
(comment
|
||||
last-info
|
||||
erc-noise-regexp
|
||||
(setq tvl-enabled? nil)
|
||||
)
|
||||
|
||||
(defun my-erc-hook (&optional match-type nick message)
|
||||
"Shows a notification, when user's nick was mentioned.
|
||||
If the buffer is currently not visible, makes it sticky."
|
||||
(setq last-message message)
|
||||
(if (or (null match-type) (not (eq match-type 'fool)))
|
||||
(let (alert-log-messages)
|
||||
(alert (or message (buffer-string))
|
||||
:severity (if (string-match "grfn" (or message ""))
|
||||
'high 'low)
|
||||
:title (or nick (buffer-name))
|
||||
:data `(:message ,(or message (buffer-string))
|
||||
:channel ,(or nick (buffer-name)))))))
|
||||
|
||||
(add-hook 'erc-text-matched-hook 'my-erc-hook)
|
||||
(add-hook 'erc-insert-modify-hook 'my-erc-hook)
|
||||
|
||||
(defun my-erc-define-alerts (&rest ignore)
|
||||
;; Unless the user has recently typed in the ERC buffer, highlight the fringe
|
||||
(alert-add-rule
|
||||
:status '(buried visible idle)
|
||||
:severity '(moderate high urgent)
|
||||
:mode 'erc-mode
|
||||
:predicate
|
||||
#'(lambda (info)
|
||||
(and (not (eq (current-buffer) (plist-get info :buffer)))
|
||||
(string-match "grfn:" (plist-get info :message))))
|
||||
:persistent
|
||||
#'(lambda (info)
|
||||
;; If the buffer is buried, or the user has been idle for
|
||||
;; `alert-reveal-idle-time' seconds, make this alert
|
||||
;; persistent. Normally, alerts become persistent after
|
||||
;; `alert-persist-idle-time' seconds.
|
||||
(memq (plist-get info :status) '(buried idle)))
|
||||
:style 'message
|
||||
:continue t)
|
||||
|
||||
(alert-add-rule
|
||||
:status 'buried
|
||||
:mode 'erc-mode
|
||||
:predicate #'erc-alert-important-p
|
||||
:style 'libnotify
|
||||
:append t)
|
||||
|
||||
(alert-add-rule
|
||||
:status 'buried
|
||||
:mode 'erc-mode
|
||||
:predicate #'erc-alert-important-p
|
||||
:style 'message
|
||||
:append t)
|
||||
|
||||
(alert-add-rule
|
||||
:mode 'erc-mode
|
||||
:predicate #'erc-alert-important-p
|
||||
:style 'log
|
||||
:append t)
|
||||
|
||||
(alert-add-rule :mode 'erc-mode :style 'ignore :append t))
|
||||
|
||||
(add-hook 'erc-connect-pre-hook 'my-erc-define-alerts)
|
||||
|
||||
(defun fix-irc-message (msg)
|
||||
(let ((msg (s-trim msg)))
|
||||
(if (string-equal msg ":q") "" msg)))
|
||||
|
||||
(advice-add #'erc-user-input :filter-return #'fix-irc-message)
|
||||
|
||||
(comment
|
||||
(my-erc-define-alerts)
|
||||
)
|
||||
38
users/grfn/emacs.d/lisp.el
Normal file
38
users/grfn/emacs.d/lisp.el
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defun grfn/sly-panettone ()
|
||||
(interactive)
|
||||
(sly
|
||||
(concat
|
||||
(s-trim
|
||||
(shell-command-to-string
|
||||
"nix-build -o sbcl -E 'with import ~/code/depot {}; nix.buildLisp.sbclWith [web.panettone]'"))
|
||||
"/bin/sbcl")))
|
||||
|
||||
(defun grfn/setup-lisp ()
|
||||
(interactive)
|
||||
(unless paxedit-mode (paxedit-mode 1))
|
||||
(rainbow-delimiters-mode)
|
||||
(flycheck-mode -1))
|
||||
|
||||
(add-hook 'common-lisp-lisp-mode-hook #'grfn/setup-lisp)
|
||||
|
||||
(defun sly-run-tests ()
|
||||
(interactive)
|
||||
;; TODO: handle other test frameworks
|
||||
(let ((orig-window (get-buffer-window)))
|
||||
(sly-eval '(fiveam:run!))
|
||||
(funcall-interactively #'sly-mrepl-sync)
|
||||
(select-window orig-window)))
|
||||
|
||||
(map!
|
||||
(:map sly-mode-map
|
||||
:n "g \\" #'sly-mrepl-sync
|
||||
:n "g d" #'sly-edit-definition
|
||||
:n "K" #'sly-documentation
|
||||
:n "g SPC" #'sly-compile-and-load-file
|
||||
:n "g RET" #'sly-run-tests)
|
||||
|
||||
(:map sly-mrepl-mode-map
|
||||
"C-k" #'sly-mrepl-previous-prompt
|
||||
"C-r" #'isearch-backward))
|
||||
7
users/grfn/emacs.d/nix-clangd.sh
Executable file
7
users/grfn/emacs.d/nix-clangd.sh
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
CLANGD_FLAGS=--compile-commands-dir=/home/grfn/builds/tvix \
|
||||
nix-shell /home/grfn/code/depot \
|
||||
-A third_party.nix \
|
||||
--run nix-clangd
|
||||
30
users/grfn/emacs.d/nix.el
Normal file
30
users/grfn/emacs.d/nix.el
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defun nix-buffer-type ()
|
||||
"Returns:
|
||||
|
||||
'home-manager, if the current buffer is a home-manager module
|
||||
'nixos, if the current buffer is a nixos module
|
||||
nil, if none of the above are the case"
|
||||
(when buffer-file-name
|
||||
(pcase buffer-file-name
|
||||
((rx (0+ nonl) "system/home" (0+ nonl) ".nix" eos)
|
||||
'home-manager)
|
||||
((rx (0+ nonl) "system/system" (0+ nonl) ".nix" eos)
|
||||
'nixos))))
|
||||
|
||||
(defun set-nix-compile-command ()
|
||||
"Set the compile command for the current buffer based on the type of nix
|
||||
buffer it is, per `nix-buffer-type'"
|
||||
(interactive)
|
||||
(when-let ((btype (nix-buffer-type)))
|
||||
(setq-local
|
||||
compile-command
|
||||
(case btype
|
||||
('home-manager "home-manager switch")
|
||||
('nixos "sudo nixos-rebuild switch")))))
|
||||
|
||||
(add-hook 'nix-mode-hook #'set-nix-compile-command)
|
||||
|
||||
(map! (:map nix-mode-map
|
||||
(:n "g SPC" #'compile)))
|
||||
188
users/grfn/emacs.d/org-alerts.el
Normal file
188
users/grfn/emacs.d/org-alerts.el
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 's)
|
||||
(require 'dash)
|
||||
(require 'alert)
|
||||
(require 'org-agenda)
|
||||
|
||||
|
||||
(defvar grfn/org-alert-interval 300
|
||||
"Interval in seconds to recheck and display deadlines.")
|
||||
|
||||
|
||||
(defvar grfn/org-alert-notification-title "*org*"
|
||||
"Title to be sent with notify-send.")
|
||||
|
||||
(defvar grfn/org-alert-headline-regexp "\\(Sched.+:.+\\|Deadline:.+\\)"
|
||||
"Regexp for headlines to search in agenda buffer.")
|
||||
|
||||
(defun grfn/org-alert--strip-prefix (headline)
|
||||
"Remove the scheduled/deadline prefix from HEADLINE."
|
||||
(replace-regexp-in-string ".*:\s+" "" headline))
|
||||
|
||||
|
||||
(defun grfn/org-alert--unique-headlines (regexp agenda)
|
||||
"Return unique headlines from the results of REGEXP in AGENDA."
|
||||
(let ((matches (-distinct (-flatten (s-match-strings-all regexp agenda)))))
|
||||
(--map (grfn/org-alert--strip-prefix it) matches)))
|
||||
|
||||
|
||||
(defun grfn/org-alert--get-headlines ()
|
||||
"Return the current org agenda as text only."
|
||||
(with-temp-buffer
|
||||
(let ((org-agenda-sticky nil)
|
||||
(org-agenda-buffer-tmp-name (buffer-name)))
|
||||
(ignore-errors (org-agenda-list nil "TODAY" 1))
|
||||
(grfn/org-alert--unique-headlines
|
||||
grfn/org-alert-headline-regexp
|
||||
(buffer-substring-no-properties (point-min) (point-max))))))
|
||||
|
||||
(defun grfn/parse-range-string (str)
|
||||
(when
|
||||
(string-match (rx (group (repeat 2 (any digit))
|
||||
":"
|
||||
(repeat 2 (any digit)))
|
||||
(optional
|
||||
(and
|
||||
"-"
|
||||
(group (repeat 2 (any digit))
|
||||
":"
|
||||
(repeat 2 (any digit))))))
|
||||
str)
|
||||
(list
|
||||
(org-read-date nil t
|
||||
(match-string 1 str))
|
||||
(when-let ((et (match-string 2 str))) (org-read-date nil t et)))))
|
||||
|
||||
(defun grfn/start-time-from-range-string (str)
|
||||
(pcase-let ((`(,start-time . _) (grfn/parse-range-string str)))
|
||||
start-time))
|
||||
|
||||
(comment
|
||||
(org-agenda-list nil "TODAY" 1)
|
||||
|
||||
(grfn/org-alert--get-headlines)
|
||||
(setq --src
|
||||
(with-temp-buffer
|
||||
(let ((org-agenda-sticky nil)
|
||||
(org-agenda-buffer-tmp-name (buffer-name)))
|
||||
(ignore-errors (org-agenda-list nil "TODAY" 1))
|
||||
(buffer-substring-no-properties (point-min) (point-max)))))
|
||||
|
||||
(setq --entries
|
||||
(with-temp-buffer
|
||||
(let ((inhibit-redisplay t)
|
||||
(org-agenda-sticky nil)
|
||||
(org-agenda-buffer-tmp-name (buffer-name))
|
||||
(org-agenda-buffer-name (buffer-name))
|
||||
(org-agenda-buffer (current-buffer)))
|
||||
(org-agenda-get-day-entries
|
||||
(cadr (org-agenda-files nil 'ifmode))
|
||||
(calendar-gregorian-from-absolute
|
||||
(time-to-days (org-read-date nil t "TODAY")))))))
|
||||
|
||||
(loop for k in (text-properties-at 0 (car --entries))
|
||||
by #'cddr
|
||||
collect k)
|
||||
|
||||
(--map (substring-no-properties (get-text-property 0 'txt it)) --entries)
|
||||
(--map (get-text-property 0 'time it) --entries)
|
||||
(current-time)
|
||||
|
||||
(format-time-string "%R" (org-read-date nil t "10:00-11:00"))
|
||||
|
||||
(grfn/start-time-from-range-string "10:00")
|
||||
|
||||
(current-time-string (org-read-date nil t "10:00-11:00"))
|
||||
|
||||
(todo-state
|
||||
org-habit-p
|
||||
priority
|
||||
warntime
|
||||
ts-date
|
||||
date
|
||||
type
|
||||
org-hd-marker
|
||||
org-marker
|
||||
face
|
||||
undone-face
|
||||
help-echo
|
||||
mouse-face
|
||||
done-face
|
||||
org-complex-heading-regexp
|
||||
org-todo-regexp
|
||||
org-not-done-regexp
|
||||
dotime
|
||||
format
|
||||
extra
|
||||
time
|
||||
level
|
||||
txt
|
||||
breadcrumbs
|
||||
duration
|
||||
time-of-day
|
||||
org-lowest-priority
|
||||
org-highest-priority
|
||||
tags
|
||||
org-category)
|
||||
|
||||
(propertize)
|
||||
|
||||
--src
|
||||
)
|
||||
|
||||
|
||||
(defun grfn/org-alert--headline-complete? (headline)
|
||||
"Return whether HEADLINE has been completed."
|
||||
(--any? (s-starts-with? it headline) org-done-keywords-for-agenda))
|
||||
|
||||
|
||||
(defun grfn/org-alert--filter-active (deadlines)
|
||||
"Remove any completed headings from the provided DEADLINES."
|
||||
(-remove 'grfn/org-alert--headline-complete? deadlines))
|
||||
|
||||
|
||||
(defun grfn/org-alert--strip-states (deadlines)
|
||||
"Remove the todo states from DEADLINES."
|
||||
(--map (s-trim (s-chop-prefixes org-todo-keywords-for-agenda it)) deadlines))
|
||||
|
||||
|
||||
(defun grfn/org-alert-check ()
|
||||
"Check for active, due deadlines and initiate notifications."
|
||||
(interactive)
|
||||
;; avoid interrupting current command.
|
||||
(unless (minibufferp)
|
||||
(save-window-excursion
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(let ((active (grfn/org-alert--filter-active (grfn/org-alert--get-headlines))))
|
||||
(dolist (dl (grfn/org-alert--strip-states active))
|
||||
(alert dl :title grfn/org-alert-notification-title))))))
|
||||
(when (get-buffer org-agenda-buffer-name)
|
||||
(ignore-errors
|
||||
(with-current-buffer org-agenda-buffer-name
|
||||
(org-agenda-redo t))))))
|
||||
|
||||
|
||||
(defun grfn/org-alert-enable ()
|
||||
"Enable the notification timer. Cancels existing timer if running."
|
||||
(interactive)
|
||||
(grfn/org-alert-disable)
|
||||
(run-at-time 0 grfn/org-alert-interval 'grfn/org-alert-check))
|
||||
|
||||
|
||||
(defun grfn/org-alert-disable ()
|
||||
"Cancel the running notification timer."
|
||||
(interactive)
|
||||
(dolist (timer timer-list)
|
||||
(if (eq (elt timer 5) 'grfn/org-alert-check)
|
||||
(cancel-timer timer))))
|
||||
|
||||
|
||||
|
||||
(provide 'grfn/org-alert)
|
||||
;;; grfn/org-alert.el ends here
|
||||
179
users/grfn/emacs.d/org-config.el
Normal file
179
users/grfn/emacs.d/org-config.el
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defun notes-file (f)
|
||||
(concat org-directory (if (string-prefix-p "/" f) "" "/") f))
|
||||
|
||||
(defun grfn/org-project-tag->key (tag)
|
||||
(s-replace-regexp "^project__" "" tag))
|
||||
|
||||
(defun grfn/org-project-tag->name (tag)
|
||||
(s-titleized-words
|
||||
(s-join " " (s-split "_" (grfn/org-project-tag->key tag)))))
|
||||
|
||||
(defun grfn/org-project-tag->keys (tag)
|
||||
(s-join "" (cons "p"
|
||||
(-map (lambda (s) (substring-no-properties s 0 1))
|
||||
(s-split "_" (grfn/org-project-tag->key tag))))))
|
||||
|
||||
(defun grfn/org-projects->agenda-commands (project-tags)
|
||||
(loop for tag in project-tags
|
||||
collect `(,(grfn/org-project-tag->keys tag)
|
||||
,(grfn/org-project-tag->name tag)
|
||||
tags-todo
|
||||
,tag)))
|
||||
|
||||
(defun grfn/org-projects ()
|
||||
(loop for (tag) in
|
||||
(org-global-tags-completion-table
|
||||
(directory-files-recursively "~/notes" "\\.org$"))
|
||||
when (s-starts-with-p "project__" tag)
|
||||
collect tag))
|
||||
|
||||
(comment
|
||||
(grfn/org-projects->agenda-commands (grfn/org-projects))
|
||||
)
|
||||
|
||||
(setq
|
||||
org-directory (expand-file-name "~/notes")
|
||||
+org-dir (expand-file-name "~/notes")
|
||||
org-default-notes-file (concat org-directory "/inbox.org")
|
||||
+org-default-todo-file (concat org-directory "/inbox.org")
|
||||
org-agenda-files (directory-files-recursively
|
||||
"~/notes" "\\.org$")
|
||||
org-refile-targets '((org-agenda-files :maxlevel . 3))
|
||||
org-outline-path-complete-in-steps nil
|
||||
org-refile-use-outline-path t
|
||||
org-file-apps `((auto-mode . emacs)
|
||||
(,(rx (or (and "." (optional "x") (optional "htm") (optional "l") buffer-end)
|
||||
(and buffer-start "http" (optional "s") "://")))
|
||||
. "firefox %s")
|
||||
(,(rx ".pdf" buffer-end) . "apvlv %s")
|
||||
(,(rx "." (or "png"
|
||||
"jpg"
|
||||
"jpeg"
|
||||
"gif"
|
||||
"tif"
|
||||
"tiff")
|
||||
buffer-end)
|
||||
. "feh %s"))
|
||||
org-log-done 'time
|
||||
org-archive-location "~/notes/trash::* From %s"
|
||||
org-cycle-separator-lines 2
|
||||
org-hidden-keywords '(title)
|
||||
org-tags-column -130
|
||||
org-ellipsis "⤵"
|
||||
org-imenu-depth 9
|
||||
org-capture-templates
|
||||
`(("t" "Todo" entry
|
||||
(file +org-default-todo-file)
|
||||
"* TODO %?\n%i"
|
||||
:kill-buffer t)
|
||||
|
||||
("m" "Email" entry
|
||||
(file +org-default-todo-file)
|
||||
"* TODO [%l[%:subject]] :email:\n%i")
|
||||
|
||||
("n" "Notes" entry
|
||||
(file +org-default-todo-file)
|
||||
"* %U %?\n%i"
|
||||
:prepend t
|
||||
:kill-buffer t)
|
||||
|
||||
("c" "Task note" entry
|
||||
(clock)
|
||||
"* %U %?\n%i[%l[Context]]\n"
|
||||
:kill-buffer t
|
||||
:unnarrowed t)
|
||||
|
||||
("p" "Projects")
|
||||
("px" "Xanthous" entry
|
||||
(file+headline ,(notes-file "xanthous.org") "Backlog")
|
||||
"* TODO %?\nContext %a\nIn task: %K")
|
||||
("pt" "Tvix" entry
|
||||
(file+headline ,(notes-file "tvix.org") "Tvix TODO")
|
||||
"* TODO %?\nContext %a\nIn task: %K")
|
||||
("pw" "Windtunnel" entry
|
||||
(file+headline ,(notes-file "windtunnel.org") "Tasks")
|
||||
"* TODO %i%?\nContext: %a\nIn task: %K")
|
||||
|
||||
("d" "Data recording")
|
||||
)
|
||||
|
||||
org-capture-templates-contexts
|
||||
`(("px" ((in-file . "/home/griffin/code/xanthous/.*"))))
|
||||
|
||||
org-deadline-warning-days 1
|
||||
org-agenda-skip-scheduled-if-deadline-is-shown 'todo
|
||||
org-todo-keywords '((sequence "TODO(t)" "ACTIVE(a)" "|" "DONE(d)" "RUNNING(r)")
|
||||
(sequence "NEXT(n)" "WAITING(w)" "LATER(l)" "|" "CANCELLED(c)"))
|
||||
org-agenda-custom-commands
|
||||
`(("S" "Sprint Tasks" tags-todo "sprint")
|
||||
("i" "Inbox" tags "inbox")
|
||||
("r" "Running jobs" todo "RUNNING")
|
||||
("w" "@Work" tags-todo "@work")
|
||||
("n" . "Next...")
|
||||
("np" "Next Sprint" tags-todo "next_sprint|sprint_planning")
|
||||
|
||||
("p" . "Project...")
|
||||
,@(grfn/org-projects->agenda-commands (grfn/org-projects)))
|
||||
|
||||
org-agenda-dim-blocked-tasks nil
|
||||
org-enforce-todo-dependencies nil
|
||||
|
||||
org-babel-clojure-backend 'cider)
|
||||
|
||||
(defun +grfn/org-setup ()
|
||||
(setq-local truncate-lines -1)
|
||||
(line-number-mode -1))
|
||||
|
||||
(add-hook 'org-mode-hook #'+grfn/org-setup)
|
||||
|
||||
(defun +grfn/insert-work-template ()
|
||||
(interactive)
|
||||
(goto-char (point-min))
|
||||
(forward-line)
|
||||
(insert "#+TODO: TODO(t) NEXT(n) ACTIVE(a) | DONE(d) PR(p) RUNNING(r) TESTING(D)
|
||||
#+TODO: BLOCKED(b) BACKLOG(l) PROPOSED(o) | CANCELLED(c)
|
||||
#+FILETAGS: @work
|
||||
#+FILETAGS: @work
|
||||
#+PROPERTY: Effort_ALL 0 4:00 8:00 12:00 20:00 32:00
|
||||
#+PROPERTY: ESTIMATE_ALL 0 1 2 3 5 8
|
||||
#+PROPERTY: STORY-TYPE_ALL Feature Bug Chore
|
||||
#+PROPERTY: NOBLOCKING t
|
||||
#+COLUMNS: %TODO %40ITEM(Task) %17EFFORT(Estimated){:} %CLOCKSUM(Time Spent) %17STORY-TYPE(Type) %TAGS"))
|
||||
|
||||
(defun +grfn/insert-org-template ()
|
||||
(interactive)
|
||||
(pcase (buffer-file-name)
|
||||
((s-contains "/work/") (+grfn/insert-work-template))))
|
||||
|
||||
;;; TODO: this doesn't work?
|
||||
(define-auto-insert "\\.org?$" #'grfn/insert-org-template t)
|
||||
|
||||
(defun forge--post-submit-around---link-pr-to-org-item
|
||||
(orig)
|
||||
(let ((cb (funcall orig)))
|
||||
(lambda (value headers status req)
|
||||
(prog1 (funcall cb value headers status req)
|
||||
(grfn/at-org-clocked-in-item
|
||||
(let ((url (alist-get 'html_url value))
|
||||
(number (alist-get 'number value)))
|
||||
(org-set-property
|
||||
"pull-request"
|
||||
(org-make-link-string
|
||||
url
|
||||
(format "%s/%s/%d"
|
||||
(->> value
|
||||
(alist-get 'base)
|
||||
(alist-get 'repo)
|
||||
(alist-get 'name))
|
||||
(->> value
|
||||
(alist-get 'base)
|
||||
(alist-get 'repo)
|
||||
(alist-get 'owner)
|
||||
(alist-get 'login))
|
||||
number)))))))))
|
||||
|
||||
(advice-add
|
||||
#'forge--post-submit-callback
|
||||
:around #'forge--post-submit-around---link-pr-to-org-item)
|
||||
181
users/grfn/emacs.d/org-gcal.el
Normal file
181
users/grfn/emacs.d/org-gcal.el
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'aio)
|
||||
(require 'parse-time)
|
||||
|
||||
(setq-local lexical-binding t)
|
||||
(setq plstore-cache-passphrase-for-symmetric-encryption t)
|
||||
|
||||
(defvar gcal-client-id)
|
||||
(defvar gcal-client-secret)
|
||||
|
||||
(defvar google-calendar-readonly-scope
|
||||
"https://www.googleapis.com/auth/calendar.readonly")
|
||||
|
||||
(defvar events-file "/home/grfn/notes/events.org")
|
||||
|
||||
(defun google--get-token (scope client-id client-secret)
|
||||
(oauth2-auth-and-store
|
||||
"https://accounts.google.com/o/oauth2/v2/auth"
|
||||
"https://oauth2.googleapis.com/token"
|
||||
scope
|
||||
client-id
|
||||
client-secret))
|
||||
|
||||
(cl-defun google--request (url &key method params scope)
|
||||
(let ((p (aio-promise))
|
||||
(auth-token (google--get-token scope gcal-client-id gcal-client-secret)))
|
||||
(oauth2-refresh-access auth-token)
|
||||
(oauth2-url-retrieve
|
||||
auth-token
|
||||
url
|
||||
(lambda (&rest _)
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "^$")
|
||||
(let ((resp (json-parse-buffer :object-type 'alist)))
|
||||
(aio-resolve p (lambda () resp))))
|
||||
nil
|
||||
(or method "GET")
|
||||
params)
|
||||
p))
|
||||
|
||||
(cl-defun list-events (&key min-time max-time)
|
||||
(google--request
|
||||
(concat
|
||||
"https://www.googleapis.com/calendar/v3/calendars/griffin@urbint.com/events"
|
||||
"?timeMin=" (format-time-string "%Y-%m-%dT%T%z" min-time)
|
||||
"&timeMax=" (format-time-string "%Y-%m-%dT%T%z" max-time))
|
||||
:scope google-calendar-readonly-scope))
|
||||
|
||||
|
||||
(defun last-week-events ()
|
||||
(list-events :min-time (time-subtract
|
||||
(current-time)
|
||||
(seconds-to-time
|
||||
(* 60 60 24 7)))
|
||||
:max-time (current-time)))
|
||||
|
||||
(defun next-week-events ()
|
||||
(list-events :min-time (current-time)
|
||||
:max-time (time-add
|
||||
(current-time)
|
||||
(seconds-to-time
|
||||
(* 60 60 24 7)))))
|
||||
|
||||
(defun attending-event? (event)
|
||||
(let* ((attendees (append (alist-get 'attendees event) nil))
|
||||
(self (--find (alist-get 'self it) attendees)))
|
||||
(equal "accepted" (alist-get 'responseStatus self))))
|
||||
|
||||
(defun event->org-headline (event level)
|
||||
(cl-flet ((make-time
|
||||
(key)
|
||||
(when-let ((raw-time (->> event (alist-get key) (alist-get 'dateTime))))
|
||||
(format-time-string
|
||||
(org-time-stamp-format t)
|
||||
(parse-iso8601-time-string raw-time)))))
|
||||
(if-let ((start-time (make-time 'start))
|
||||
(end-time (make-time 'end)))
|
||||
(s-format
|
||||
"${headline} [[${htmlLink}][${summary}]] :event:
|
||||
${startTime}--${endTime}
|
||||
:PROPERTIES:
|
||||
${location-prop}
|
||||
:EVENT: ${htmlLink}
|
||||
:END:
|
||||
|
||||
${description}"
|
||||
(function
|
||||
(lambda (k m)
|
||||
(or (alist-get (intern k) m)
|
||||
(format "key not found: %s" k))))
|
||||
(append
|
||||
event
|
||||
`((headline . ,(make-string level ?*))
|
||||
(startTime . ,start-time)
|
||||
(endTime . ,end-time)
|
||||
(location-prop
|
||||
. ,(if-let ((location (alist-get 'location event)))
|
||||
(s-lex-format ":LOCATION: ${location}")
|
||||
"")))))
|
||||
"")))
|
||||
|
||||
(comment
|
||||
(alist-get 'foo nil)
|
||||
)
|
||||
|
||||
(defun write-events (events)
|
||||
(with-current-buffer (find-file-noselect events-file)
|
||||
(save-mark-and-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(erase-buffer)
|
||||
(goto-char (point-min))
|
||||
(insert "#+TITLE: Events")
|
||||
(newline) (newline)
|
||||
(prog1
|
||||
(loop for event in (append events nil)
|
||||
when (attending-event? event)
|
||||
do
|
||||
(insert (event->org-headline event 1))
|
||||
(newline)
|
||||
sum 1)
|
||||
(org-align-tags t))))))
|
||||
|
||||
(defun +grfn/sync-events ()
|
||||
(interactive)
|
||||
(let* ((events (alist-get 'items (aio-wait-for (next-week-events))))
|
||||
(num-written (write-events events)))
|
||||
(message "Successfully wrote %d events" num-written)))
|
||||
|
||||
(comment
|
||||
((kind . "calendar#event")
|
||||
(etag . "\"3174776941020000\"")
|
||||
(id . "SNIP")
|
||||
(status . "confirmed")
|
||||
(htmlLink . "https://www.google.com/calendar/event?eid=SNIP")
|
||||
(created . "2020-04-01T13:30:09.000Z")
|
||||
(updated . "2020-04-20T13:14:30.510Z")
|
||||
(summary . "SNIP")
|
||||
(description . "SNIP")
|
||||
(location . "SNIP")
|
||||
(creator
|
||||
(email . "griffin@urbint.com")
|
||||
(self . t))
|
||||
(organizer
|
||||
(email . "griffin@urbint.com")
|
||||
(self . t))
|
||||
(start
|
||||
(dateTime . "2020-04-01T12:00:00-04:00")
|
||||
(timeZone . "America/New_York"))
|
||||
(end
|
||||
(dateTime . "2020-04-01T12:30:00-04:00")
|
||||
(timeZone . "America/New_York"))
|
||||
(recurrence .
|
||||
["RRULE:FREQ=WEEKLY;UNTIL=20200408T035959Z;BYDAY=WE"])
|
||||
(iCalUID . "SNIP")
|
||||
(sequence . 0)
|
||||
(attendees .
|
||||
[((email . "griffin@urbint.com")
|
||||
(organizer . t)
|
||||
(self . t)
|
||||
(responseStatus . "accepted"))
|
||||
((email . "SNIP")
|
||||
(displayName . "SNIP")
|
||||
(responseStatus . "needsAction"))])
|
||||
(extendedProperties
|
||||
(private
|
||||
(origRecurringId . "309q48kc1dihsvbi13pnlimb5a"))
|
||||
(shared
|
||||
(origRecurringId . "309q48kc1dihsvbi13pnlimb5a")))
|
||||
(reminders
|
||||
(useDefault . t)))
|
||||
|
||||
(require 'icalendar)
|
||||
|
||||
(icalendar--convert-recurring-to-diary
|
||||
nil
|
||||
"RRULE:FREQ=WEEKLY;UNTIL=20200408T035959Z;BYDAY=WE"
|
||||
)
|
||||
|
||||
)
|
||||
96
users/grfn/emacs.d/org-query.el
Normal file
96
users/grfn/emacs.d/org-query.el
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'org)
|
||||
(require 'org-agenda)
|
||||
(require 'inflections)
|
||||
|
||||
(defun grfn/org-agenda-entry->element (agenda-entry)
|
||||
;; ???
|
||||
())
|
||||
|
||||
(defun org-elements-agenda-match (match &optional todo-only)
|
||||
(setq match
|
||||
(propertize match 'inherited t))
|
||||
(with-temp-buffer
|
||||
(let ((inhibit-redisplay (not debug-on-error))
|
||||
(org-agenda-sticky nil)
|
||||
(org-agenda-buffer-tmp-name (buffer-name))
|
||||
(org-agenda-buffer-name (buffer-name))
|
||||
(org-agenda-buffer (current-buffer))
|
||||
(matcher (org-make-tags-matcher match))
|
||||
result)
|
||||
(org-agenda-prepare (concat "TAGS " match))
|
||||
(setq match (car matcher)
|
||||
matcher (cdr matcher))
|
||||
(dolist (file (org-agenda-files nil 'ifmode)
|
||||
result)
|
||||
(catch 'nextfile
|
||||
(org-check-agenda-file file)
|
||||
(when-let ((buffer (if (file-exists-p file)
|
||||
(org-get-agenda-file-buffer file)
|
||||
(error "No such file %s" file))))
|
||||
(with-current-buffer buffer
|
||||
(unless (derived-mode-p 'org-mode)
|
||||
(error "Agenda file %s is not in Org mode" file))
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(if (eq buffer org-agenda-restrict)
|
||||
(narrow-to-region org-agenda-restrict-begin
|
||||
org-agenda-restrict-end)
|
||||
(widen))
|
||||
(setq result
|
||||
(append result (org-scan-tags
|
||||
'agenda
|
||||
matcher
|
||||
todo-only))))))))))))
|
||||
|
||||
(defun grfn/num-inbox-items ()
|
||||
(length (org-elements-agenda-match "inbox" t)))
|
||||
|
||||
(defun grfn/num-inbox-items-message ()
|
||||
(let ((n (grfn/num-inbox-items)))
|
||||
(unless (zerop n)
|
||||
(format "%d %s"
|
||||
n
|
||||
(if (= 1 n) "item" "items")))))
|
||||
|
||||
(defmacro grfn/at-org-clocked-in-item (&rest body)
|
||||
`(when (org-clocking-p)
|
||||
(let ((m org-clock-marker))
|
||||
(with-current-buffer (marker-buffer m)
|
||||
(save-mark-and-excursion
|
||||
(goto-char m)
|
||||
(org-back-to-heading t)
|
||||
,@body)))))
|
||||
|
||||
(defun grfn/org-element-clocked-in-task ()
|
||||
(grfn/at-org-clocked-in-item
|
||||
(org-element-at-point)))
|
||||
|
||||
(comment
|
||||
(grfn/org-element-clocked-in-task)
|
||||
(org-element-property :title (grfn/org-element-clocked-in-task))
|
||||
)
|
||||
|
||||
(defun grfn/minutes->hours:minutes (minutes)
|
||||
(format "%d:%02d"
|
||||
(floor (/ minutes 60))
|
||||
(mod minutes 60)))
|
||||
|
||||
(comment
|
||||
(grfn/minutes->hours:minutes 1) ; => "0:01"
|
||||
(grfn/minutes->hours:minutes 15) ; => "0:15"
|
||||
(grfn/minutes->hours:minutes 130) ; => "2:10"
|
||||
)
|
||||
|
||||
(defun grfn/org-current-clocked-in-task-message ()
|
||||
(if (org-clocking-p)
|
||||
(format "(%s) [%s]"
|
||||
(org-element-property :title (grfn/org-element-clocked-in-task))
|
||||
(grfn/minutes->hours:minutes
|
||||
(org-clock-get-clocked-time)))
|
||||
""))
|
||||
|
||||
(comment
|
||||
(grfn/org-current-clocked-in-task-message)
|
||||
)
|
||||
156
users/grfn/emacs.d/packages.el
Normal file
156
users/grfn/emacs.d/packages.el
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; private/grfn/packages.el
|
||||
|
||||
(package! moody)
|
||||
|
||||
;; Editor
|
||||
(package! solarized-theme)
|
||||
(package! fill-column-indicator)
|
||||
(package! flx)
|
||||
(package! general
|
||||
:recipe (:host github :repo "noctuid/general.el"))
|
||||
(package! fill-column-indicator)
|
||||
(package! writeroom-mode)
|
||||
(package! dash)
|
||||
(package! w3m)
|
||||
(package! rainbow-mode)
|
||||
(package! string-inflection)
|
||||
|
||||
;;; Org
|
||||
(package! org-clubhouse
|
||||
:recipe (:host file
|
||||
:local-repo "~/code/org-clubhouse"))
|
||||
(package! org-alert)
|
||||
(package! ob-http)
|
||||
(package! ob-ipython)
|
||||
(package! ob-async)
|
||||
(package! org-recent-headings)
|
||||
(package! org-sticky-header)
|
||||
(package! gnuplot)
|
||||
(package! gnuplot-mode)
|
||||
|
||||
;; Presentation
|
||||
(package! epresent)
|
||||
(package! org-tree-slide)
|
||||
(package! ox-reveal)
|
||||
|
||||
;; Slack etc
|
||||
(package! slack)
|
||||
(package! alert)
|
||||
|
||||
;; Git
|
||||
(package! evil-magit)
|
||||
(package! marshal)
|
||||
(package! forge)
|
||||
(package!
|
||||
github-review
|
||||
:recipe
|
||||
(:host github
|
||||
:repo "charignon/github-review"
|
||||
:files ("github-review.el")))
|
||||
|
||||
;; Elisp
|
||||
(package! dash)
|
||||
(package! dash-functional)
|
||||
(package! s)
|
||||
(package! request)
|
||||
(package! predd
|
||||
:recipe (:host github :repo "skeeto/predd"))
|
||||
(package! aio)
|
||||
|
||||
;; Haskell
|
||||
(package! lsp-haskell)
|
||||
(package! counsel-etags)
|
||||
|
||||
;;; LSP
|
||||
(package! lsp-mode)
|
||||
(package! lsp-ui :recipe (:host github :repo "emacs-lsp/lsp-ui"))
|
||||
(package! company-lsp)
|
||||
(package! lsp-treemacs)
|
||||
(package! dap-mode)
|
||||
|
||||
;; Rust
|
||||
(package! rustic :disable t)
|
||||
;; (package! racer :disable t)
|
||||
(package! cargo)
|
||||
|
||||
;; Lisp
|
||||
(package! paxedit)
|
||||
|
||||
;; Javascript
|
||||
(package! flow-minor-mode)
|
||||
(package! flycheck-flow)
|
||||
(package! company-flow)
|
||||
(package! prettier-js)
|
||||
|
||||
;; GraphQL
|
||||
(package! graphql-mode)
|
||||
|
||||
;; Haskell
|
||||
(package! lsp-mode)
|
||||
(package! lsp-ui)
|
||||
(package! lsp-haskell)
|
||||
(package! company-lsp)
|
||||
;; (package! lsp-imenu)
|
||||
|
||||
;; Clojure
|
||||
(package! flycheck-clojure)
|
||||
|
||||
;; SQL
|
||||
(package! sqlup-mode)
|
||||
(package! emacsql)
|
||||
(package! emacsql-psql)
|
||||
|
||||
;;; Python
|
||||
(package! pyimport)
|
||||
;; (package! yapfify)
|
||||
(package! blacken)
|
||||
|
||||
|
||||
;;; Desktop interaction
|
||||
(package! counsel-spotify)
|
||||
|
||||
;;; Dhall
|
||||
(package! dhall-mode)
|
||||
|
||||
;;; Kubernetes
|
||||
(package! kubernetes)
|
||||
(package! kubernetes-evil)
|
||||
(package! k8s-mode)
|
||||
|
||||
;;; Stack Exchange
|
||||
(package! sx)
|
||||
|
||||
;;; Nix
|
||||
(package! nix-update
|
||||
:recipe (:host github
|
||||
:repo "glittershark/nix-update-el"))
|
||||
(package! direnv)
|
||||
|
||||
;;; Email
|
||||
(package! mu4e)
|
||||
|
||||
;;; Sequence diagrams
|
||||
(package! wsd-mode
|
||||
:recipe (:host github
|
||||
:repo "josteink/wsd-mode"))
|
||||
|
||||
;;; logic?
|
||||
(package! metal-mercury-mode
|
||||
:recipe (:host github
|
||||
:repo "ahungry/metal-mercury-mode"))
|
||||
(package! flycheck-mercury)
|
||||
|
||||
(package! terraform-mode)
|
||||
(package! company-terraform)
|
||||
|
||||
(package! jsonnet-mode)
|
||||
|
||||
;;;
|
||||
(package! znc
|
||||
:recipe (:host github
|
||||
:repo "sshirokov/ZNC.el"))
|
||||
|
||||
;;; cpp
|
||||
(package! protobuf-mode)
|
||||
(package! clang-format+)
|
||||
37
users/grfn/emacs.d/rust.el
Normal file
37
users/grfn/emacs.d/rust.el
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.rs$" . rust-mode))
|
||||
|
||||
(defun grfn/rust-setup ()
|
||||
(interactive)
|
||||
|
||||
(push '(?> . ("<" . ">")) evil-surround-pairs-alist)
|
||||
(push '(?< . ("< " . " >")) evil-surround-pairs-alist)
|
||||
|
||||
(setq lsp-rust-server 'rust-analyzer)
|
||||
(setq-local whitespace-line-column 100
|
||||
fill-column 100)
|
||||
(setq rust-format-show-buffer nil)
|
||||
(setq lsp-rust-analyzer-import-merge-behaviour "last"
|
||||
lsp-rust-analyzer-cargo-watch-command "clippy"
|
||||
lsp-ui-doc-enable t)
|
||||
(rust-enable-format-on-save)
|
||||
(lsp))
|
||||
|
||||
(add-hook 'rust-mode-hook #'grfn/rust-setup)
|
||||
|
||||
(map!
|
||||
(:map rust-mode-map
|
||||
:n "g RET" #'cargo-process-current-file-tests
|
||||
:n "g R" #'lsp-find-references
|
||||
(:localleader
|
||||
"m" #'lsp-rust-analyzer-expand-macro)))
|
||||
|
||||
(comment
|
||||
(flycheck-get-next-checkers 'lsp)
|
||||
(flycheck-add-next-checker)
|
||||
(flycheck-get-next-checkers 'lsp)
|
||||
)
|
||||
|
||||
(set-company-backend! 'rust-mode
|
||||
'(:separate company-capf company-yasnippet))
|
||||
61
users/grfn/emacs.d/show-matching-paren.el
Normal file
61
users/grfn/emacs.d/show-matching-paren.el
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
;;; https://with-emacs.com/posts/ui-hacks/show-matching-lines-when-parentheses-go-off-screen/
|
||||
|
||||
;; we will call `blink-matching-open` ourselves...
|
||||
(remove-hook 'post-self-insert-hook
|
||||
#'blink-paren-post-self-insert-function)
|
||||
;; this still needs to be set for `blink-matching-open` to work
|
||||
(setq blink-matching-paren 'show)
|
||||
|
||||
(let ((ov nil)) ; keep track of the overlay
|
||||
(advice-add
|
||||
#'show-paren-function
|
||||
:after
|
||||
(defun show-paren--off-screen+ (&rest _args)
|
||||
"Display matching line for off-screen paren."
|
||||
(when (overlayp ov)
|
||||
(delete-overlay ov))
|
||||
;; check if it's appropriate to show match info,
|
||||
;; see `blink-paren-post-self-insert-function'
|
||||
(when (and (overlay-buffer show-paren--overlay)
|
||||
(not (or cursor-in-echo-area
|
||||
executing-kbd-macro
|
||||
noninteractive
|
||||
(minibufferp)
|
||||
this-command))
|
||||
(and (not (bobp))
|
||||
(memq (char-syntax (char-before)) '(?\) ?\$)))
|
||||
(= 1 (logand 1 (- (point)
|
||||
(save-excursion
|
||||
(forward-char -1)
|
||||
(skip-syntax-backward "/\\")
|
||||
(point))))))
|
||||
;; rebind `minibuffer-message' called by
|
||||
;; `blink-matching-open' to handle the overlay display
|
||||
(cl-letf (((symbol-function #'minibuffer-message)
|
||||
(lambda (msg &rest args)
|
||||
(let ((msg (apply #'format-message msg args)))
|
||||
(setq ov (display-line-overlay+
|
||||
(window-start) msg ))))))
|
||||
(blink-matching-open))))))
|
||||
|
||||
(defun display-line-overlay+ (pos str &optional face)
|
||||
"Display line at POS as STR with FACE.
|
||||
|
||||
FACE defaults to inheriting from default and highlight."
|
||||
(let ((ol (save-excursion
|
||||
(goto-char pos)
|
||||
(make-overlay (line-beginning-position)
|
||||
(line-end-position)))))
|
||||
(overlay-put ol 'display str)
|
||||
(overlay-put ol 'face
|
||||
(or face '(:inherit default :inherit highlight)))
|
||||
ol))
|
||||
|
||||
(setq show-paren-style 'paren
|
||||
show-paren-delay 0.03
|
||||
show-paren-highlight-openparen t
|
||||
show-paren-when-point-inside-paren nil
|
||||
show-paren-when-point-in-periphery t)
|
||||
(show-paren-mode 1)
|
||||
227
users/grfn/emacs.d/slack-snippets.el
Normal file
227
users/grfn/emacs.d/slack-snippets.el
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'dash)
|
||||
(require 'dash-functional)
|
||||
(require 'request)
|
||||
|
||||
;;;
|
||||
;;; Configuration
|
||||
;;;
|
||||
|
||||
(defvar slack/token nil
|
||||
"Legacy (https://api.slack.com/custom-integrations/legacy-tokens) access token")
|
||||
|
||||
(defvar slack/include-public-channels 't
|
||||
"Whether or not to inclue public channels in the list of conversations")
|
||||
|
||||
(defvar slack/include-private-channels 't
|
||||
"Whether or not to inclue public channels in the list of conversations")
|
||||
|
||||
(defvar slack/include-im 't
|
||||
"Whether or not to inclue IMs (private messages) in the list of conversations")
|
||||
|
||||
(defvar slack/include-mpim nil
|
||||
"Whether or not to inclue multi-person IMs (multi-person private messages) in
|
||||
the list of conversations")
|
||||
|
||||
;;;
|
||||
;;; Utilities
|
||||
;;;
|
||||
|
||||
(defmacro comment (&rest _body)
|
||||
"Comment out one or more s-expressions"
|
||||
nil)
|
||||
|
||||
(defun ->list (vec) (append vec nil))
|
||||
|
||||
(defun json-truthy? (x) (and x (not (equal :json-false x))))
|
||||
|
||||
;;;
|
||||
;;; Generic API integration
|
||||
;;;
|
||||
|
||||
(defvar slack/base-url "https://slack.com/api")
|
||||
|
||||
(defun slack/get (path params &optional callback)
|
||||
"params is an alist of query parameters"
|
||||
(let* ((params-callback (if (functionp params) `(() . ,params) (cons params callback)))
|
||||
(params (car params-callback)) (callback (cdr params-callback))
|
||||
(params (append `(("token" . ,slack/token)) params))
|
||||
(url (concat (file-name-as-directory slack/base-url) path)))
|
||||
(request url
|
||||
:type "GET"
|
||||
:params params
|
||||
:parser 'json-read
|
||||
:success (cl-function
|
||||
(lambda (&key data &allow-other-keys)
|
||||
(funcall callback data))))))
|
||||
|
||||
(defun slack/post (path params &optional callback)
|
||||
(let* ((params-callback (if (functionp params) `(() . ,params) (cons params callback)))
|
||||
(params (car params-callback)) (callback (cdr params-callback))
|
||||
(url (concat (file-name-as-directory slack/base-url) path)))
|
||||
(request url
|
||||
:type "POST"
|
||||
:data (json-encode params)
|
||||
:headers `(("Content-Type" . "application/json")
|
||||
("Authorization" . ,(format "Bearer %s" slack/token)))
|
||||
:success (cl-function
|
||||
(lambda (&key data &allow-other-keys)
|
||||
(funcall callback data))))))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Specific API endpoints
|
||||
;;;
|
||||
|
||||
;; Users
|
||||
|
||||
(defun slack/users (cb)
|
||||
"Returns users as (id . name) pairs"
|
||||
(slack/get
|
||||
"users.list"
|
||||
(lambda (data)
|
||||
(->> data
|
||||
(assoc-default 'members)
|
||||
->list
|
||||
(-map (lambda (user)
|
||||
(cons (assoc-default 'id user)
|
||||
(assoc-default 'real_name user))))
|
||||
(-filter #'cdr)
|
||||
(funcall cb)))))
|
||||
|
||||
(comment
|
||||
(slack/get
|
||||
"users.list"
|
||||
(lambda (data) (setq response-data data)))
|
||||
|
||||
(slack/users (lambda (data) (setq --users data)))
|
||||
|
||||
)
|
||||
|
||||
;; Conversations
|
||||
|
||||
(defun slack/conversation-types ()
|
||||
(->>
|
||||
(list (when slack/include-public-channels "public_channel")
|
||||
(when slack/include-private-channels "private_channel")
|
||||
(when slack/include-im "im")
|
||||
(when slack/include-mpim "mpim"))
|
||||
(-filter #'identity)
|
||||
(s-join ",")))
|
||||
|
||||
(defun channel-label (chan users-alist)
|
||||
(cond
|
||||
((json-truthy? (assoc-default 'is_channel chan))
|
||||
(format "#%s" (assoc-default 'name chan)))
|
||||
((json-truthy? (assoc-default 'is_im chan))
|
||||
(let ((user-id (assoc-default 'user chan)))
|
||||
(format "Private message with %s" (assoc-default user-id users-alist))))
|
||||
((json-truthy? (assoc-default 'is_mpim chan))
|
||||
(->> chan
|
||||
(assoc-default 'purpose)
|
||||
(assoc-default 'value)))))
|
||||
|
||||
(defun slack/conversations (cb)
|
||||
"Calls `cb' with (id . '((label . \"label\") '(topic . \"topic\") '(purpose . \"purpose\"))) pairs"
|
||||
(slack/get
|
||||
"conversations.list"
|
||||
`(("types" . ,(slack/conversation-types))
|
||||
("exclude-archived" . "true"))
|
||||
(lambda (data)
|
||||
(setq --data data)
|
||||
(slack/users
|
||||
(lambda (users)
|
||||
(->> data
|
||||
(assoc-default 'channels)
|
||||
->list
|
||||
(-map
|
||||
(lambda (chan)
|
||||
(cons (assoc-default 'id chan)
|
||||
`((label . ,(channel-label chan users))
|
||||
(topic . ,(->> chan
|
||||
(assoc-default 'topic)
|
||||
(assoc-default 'value)))
|
||||
(purpose . ,(->> chan
|
||||
(assoc-default 'purpose)
|
||||
(assoc-default 'value)))))))
|
||||
(funcall cb)))))))
|
||||
|
||||
(comment
|
||||
(slack/get
|
||||
"conversations.list"
|
||||
'(("types" . "public_channel,private_channel,im,mpim"))
|
||||
(lambda (data) (setq response-data data)))
|
||||
|
||||
(slack/get
|
||||
"conversations.list"
|
||||
'(("types" . "im"))
|
||||
(lambda (data) (setq response-data data)))
|
||||
|
||||
(slack/conversations
|
||||
(lambda (convos) (setq --conversations convos)))
|
||||
|
||||
)
|
||||
|
||||
;; Messages
|
||||
|
||||
(cl-defun slack/post-message
|
||||
(&key text channel-id (on-success #'identity))
|
||||
(slack/post "chat.postMessage"
|
||||
`((text . ,text)
|
||||
(channel . ,channel-id)
|
||||
(as_user . t))
|
||||
on-success))
|
||||
|
||||
(comment
|
||||
|
||||
(slack/post-message
|
||||
:text "hi slackbot"
|
||||
:channel-id slackbot-channel-id
|
||||
:on-success (lambda (data) (setq resp data)))
|
||||
|
||||
)
|
||||
|
||||
;;;
|
||||
;;; Posting code snippets to slack
|
||||
;;;
|
||||
|
||||
(defun prompt-for-channel (cb)
|
||||
(slack/conversations
|
||||
(lambda (conversations)
|
||||
(ivy-read
|
||||
"Select channel: "
|
||||
;; TODO want to potentially use purpose / topic stuff here
|
||||
(->> conversations
|
||||
(-filter (lambda (c) (assoc-default 'label (cdr c))))
|
||||
(-map (lambda (chan) (let ((label (assoc-default 'label (cdr chan)))
|
||||
(id (car chan)))
|
||||
(propertize label 'channel-id id)))))
|
||||
:history 'slack/channel-history
|
||||
:action (lambda (selected)
|
||||
(let ((channel-id (get-text-property 0 'channel-id selected)))
|
||||
(funcall cb channel-id)
|
||||
(message "Sent message to %s" selected))))))
|
||||
nil)
|
||||
|
||||
(comment
|
||||
(prompt-for-channel #'message)
|
||||
(->> --convos
|
||||
(-filter (lambda (c) (assoc-default 'label (cdr c))))
|
||||
(-map (lambda (chan) (let ((label (assoc-default 'label (cdr chan)))
|
||||
(id (car chan)))
|
||||
(propertize label 'channel-id id)))))
|
||||
|
||||
(->> --convos (car) (cdr) (assoc-default 'label))
|
||||
)
|
||||
|
||||
(defun slack-send-code-snippet (&optional snippet-text)
|
||||
(interactive
|
||||
(list (buffer-substring-no-properties (mark) (point))))
|
||||
(prompt-for-channel
|
||||
(lambda (channel-id)
|
||||
(slack/post-message
|
||||
:text (format "```\n%s```" snippet-text)
|
||||
:channel-id channel-id))))
|
||||
|
||||
(provide 'slack-snippets)
|
||||
24
users/grfn/emacs.d/slack.el
Normal file
24
users/grfn/emacs.d/slack.el
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(after! slack
|
||||
(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))
|
||||
|
||||
(require 'slack)
|
||||
(setq slack-buffer-emojify 't
|
||||
slack-prefer-current-team 't
|
||||
slack-thread-also-send-to-room nil)
|
||||
|
||||
(set-popup-rule! "^\\*Slack"
|
||||
:quit nil
|
||||
:select t
|
||||
:side 'bottom
|
||||
:ttl nil
|
||||
:size 0.5)
|
||||
|
||||
(add-hook #'slack-message-buffer-mode-hook
|
||||
(lambda () (toggle-truncate-lines -1)))
|
||||
|
||||
(map! (:map slack-message-buffer-mode-map
|
||||
:n "q" #'delete-window))
|
||||
5
users/grfn/emacs.d/snippets/haskell-mode/annotation
Normal file
5
users/grfn/emacs.d/snippets/haskell-mode/annotation
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# key: ann
|
||||
# name: annotation
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# ANN ${1:module} ("${2:HLint: ignore ${3:Reduce duplication}}" :: String) #-}
|
||||
26
users/grfn/emacs.d/snippets/haskell-mode/benchmark-module
Normal file
26
users/grfn/emacs.d/snippets/haskell-mode/benchmark-module
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# key: bench
|
||||
# name: benchmark-module
|
||||
# expand-env: ((yas-indent-line (quote fixed)))
|
||||
# --
|
||||
--------------------------------------------------------------------------------
|
||||
module ${1:`(if (not buffer-file-name) "Module"
|
||||
(let ((name (file-name-sans-extension (buffer-file-name)))
|
||||
(case-fold-search nil))
|
||||
(if (cl-search "bench/" name)
|
||||
(replace-regexp-in-string "/" "."
|
||||
(replace-regexp-in-string "^\/[^A-Z]*" ""
|
||||
(car (last (split-string name "src")))))
|
||||
(file-name-nondirectory name))))`} ( benchmark, main ) where
|
||||
--------------------------------------------------------------------------------
|
||||
import Bench.Prelude
|
||||
--------------------------------------------------------------------------------
|
||||
import ${1:$(s-chop-suffix "Bench" yas-text)}
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
main :: IO ()
|
||||
main = defaultMain [benchmark]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
benchmark :: Benchmark
|
||||
benchmark = bgroup "${1:$(->> yas-text (s-chop-suffix "Bench") (s-split ".") -last-item)}" [bench "something dumb" $ nf (1 +) (1 :: Int)]
|
||||
5
users/grfn/emacs.d/snippets/haskell-mode/header
Normal file
5
users/grfn/emacs.d/snippets/haskell-mode/header
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# key: hh
|
||||
# name: header
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
--------------------------------------------------------------------------------$2
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# key: gen
|
||||
# name: Hedgehog Generator
|
||||
# expand-env: ((yas-indent-line (quote fixed)))
|
||||
# --
|
||||
gen${1:Foo} :: Gen $1
|
||||
gen$1 = do
|
||||
$2
|
||||
pure $1{..}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: Hedgehog Property
|
||||
# key: hprop
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
hprop_${1:somethingIsAlwaysTrue} :: Property
|
||||
hprop_$1 = property $ do
|
||||
${2:x} <- forAll ${3:Gen.int $ Range.linear 1 100}
|
||||
${4:x === x}
|
||||
8
users/grfn/emacs.d/snippets/haskell-mode/hlint
Normal file
8
users/grfn/emacs.d/snippets/haskell-mode/hlint
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: hlint
|
||||
# uuid:
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# key: hlint
|
||||
# condition: t
|
||||
# --
|
||||
{-# ANN module ("Hlint: ignore $1" :: String) #- }
|
||||
4
users/grfn/emacs.d/snippets/haskell-mode/import-i
Normal file
4
users/grfn/emacs.d/snippets/haskell-mode/import-i
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# key: i
|
||||
# name: import-i
|
||||
# --
|
||||
import ${1:Prelude}
|
||||
6
users/grfn/emacs.d/snippets/haskell-mode/inl
Normal file
6
users/grfn/emacs.d/snippets/haskell-mode/inl
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: inl
|
||||
# key: inl
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# INLINE $1 #-}
|
||||
5
users/grfn/emacs.d/snippets/haskell-mode/inline
Normal file
5
users/grfn/emacs.d/snippets/haskell-mode/inline
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# key: inline
|
||||
# name: inline
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# INLINE $1 #-}
|
||||
6
users/grfn/emacs.d/snippets/haskell-mode/language pragma
Normal file
6
users/grfn/emacs.d/snippets/haskell-mode/language pragma
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: language pragma
|
||||
# key: lang
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# LANGUAGE $1 #-}
|
||||
7
users/grfn/emacs.d/snippets/haskell-mode/lens.field
Normal file
7
users/grfn/emacs.d/snippets/haskell-mode/lens.field
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: lens.field
|
||||
# key: lens
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
${1:field} :: Lens' ${2:Source} ${3:Target}
|
||||
$1 = lens _${4:sourceField} $ \\${2:$(-> yas-text s-word-initials s-downcase)} ${4:$(-> yas-text s-word-initials s-downcase)} -> ${2:$(-> yas-text s-word-initials s-downcase)} { _$4 = ${4:$(-> yas-text s-word-initials s-downcase)} }
|
||||
32
users/grfn/emacs.d/snippets/haskell-mode/module
Normal file
32
users/grfn/emacs.d/snippets/haskell-mode/module
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# -*- mode: snippet -*-
|
||||
# key: module
|
||||
# name: module
|
||||
# condition: (= (length "module") (current-column))
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# contributor: Luke Hoersten <luke@hoersten.org>
|
||||
# --
|
||||
--------------------------------------------------------------------------------
|
||||
-- |
|
||||
-- Module : $1
|
||||
-- Description : $2
|
||||
-- Maintainer : Griffin Smith <grfn@urbint.com>
|
||||
-- Maturity : ${3:Draft, Usable, Maintained, OR MatureAF}
|
||||
--
|
||||
-- $4
|
||||
--------------------------------------------------------------------------------
|
||||
module ${1:`(if (not buffer-file-name) "Module"
|
||||
(let ((name (file-name-sans-extension (buffer-file-name)))
|
||||
(case-fold-search nil))
|
||||
(if (or (cl-search "src/" name)
|
||||
(cl-search "test/" name))
|
||||
(replace-regexp-in-string "/" "."
|
||||
(replace-regexp-in-string "^\/[^A-Z]*" ""
|
||||
(car (last (split-string name "src")))))
|
||||
(file-name-nondirectory name))))`}
|
||||
(
|
||||
) where
|
||||
--------------------------------------------------------------------------------
|
||||
import Prelude
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
$0
|
||||
6
users/grfn/emacs.d/snippets/haskell-mode/shut up, hlint
Normal file
6
users/grfn/emacs.d/snippets/haskell-mode/shut up, hlint
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: shut up, hlint
|
||||
# key: dupl
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
|
||||
22
users/grfn/emacs.d/snippets/haskell-mode/test-module
Normal file
22
users/grfn/emacs.d/snippets/haskell-mode/test-module
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: test-module
|
||||
# key: test
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
{-# LANGUAGE ApplicativeDo #-}
|
||||
--------------------------------------------------------------------------------
|
||||
module ${1:`(if (not buffer-file-name) "Module"
|
||||
(let ((name (file-name-sans-extension (buffer-file-name)))
|
||||
(case-fold-search nil))
|
||||
(if (cl-search "test/" name)
|
||||
(replace-regexp-in-string "/" "."
|
||||
(replace-regexp-in-string "^\/[^A-Z]*" ""
|
||||
(car (last (split-string name "src")))))
|
||||
(file-name-nondirectory name))))`} where
|
||||
--------------------------------------------------------------------------------
|
||||
import Test.Prelude
|
||||
import qualified Hedgehog.Gen as Gen
|
||||
import qualified Hedgehog.Range as Range
|
||||
--------------------------------------------------------------------------------
|
||||
import ${1:$(s-chop-suffix "Test" yas-text)}
|
||||
--------------------------------------------------------------------------------
|
||||
6
users/grfn/emacs.d/snippets/haskell-mode/undefined
Normal file
6
users/grfn/emacs.d/snippets/haskell-mode/undefined
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: undefined
|
||||
# key: u
|
||||
# expand-env: ((yas-indent-line 'fixed) (yas-wrap-around-region 'nil))
|
||||
# --
|
||||
undefined$1
|
||||
4
users/grfn/emacs.d/snippets/js2-mode/action-type
Normal file
4
users/grfn/emacs.d/snippets/js2-mode/action-type
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# key: at
|
||||
# name: action-type
|
||||
# --
|
||||
export const ${1:FOO_BAR$(->> yas-text s-upcase (s-replace-all '(("-" . "_") (" " . "_"))))}: '${3:ns}/${1:$(-> yas-text s-dashed-words)}' = '$3/${1:$(-> yas-text s-dashed-words)}'$5
|
||||
7
users/grfn/emacs.d/snippets/js2-mode/before
Normal file
7
users/grfn/emacs.d/snippets/js2-mode/before
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: before
|
||||
# key: bef
|
||||
# --
|
||||
before(function() {
|
||||
$1
|
||||
})
|
||||
7
users/grfn/emacs.d/snippets/js2-mode/context
Normal file
7
users/grfn/emacs.d/snippets/js2-mode/context
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: context
|
||||
# key: context
|
||||
# --
|
||||
context('$1', function() {
|
||||
$2
|
||||
})
|
||||
6
users/grfn/emacs.d/snippets/js2-mode/describe
Normal file
6
users/grfn/emacs.d/snippets/js2-mode/describe
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# key: desc
|
||||
# name: describe
|
||||
# --
|
||||
describe('$1', () => {
|
||||
$2
|
||||
})
|
||||
5
users/grfn/emacs.d/snippets/js2-mode/expect
Normal file
5
users/grfn/emacs.d/snippets/js2-mode/expect
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: expect
|
||||
# key: ex
|
||||
# --
|
||||
expect($1).$2
|
||||
6
users/grfn/emacs.d/snippets/js2-mode/function
Normal file
6
users/grfn/emacs.d/snippets/js2-mode/function
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# key: f
|
||||
# name: function
|
||||
# --
|
||||
function $1($2) {
|
||||
$3
|
||||
}
|
||||
6
users/grfn/emacs.d/snippets/js2-mode/header
Normal file
6
users/grfn/emacs.d/snippets/js2-mode/header
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: header
|
||||
# key: hh
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
# --
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
7
users/grfn/emacs.d/snippets/js2-mode/it
Normal file
7
users/grfn/emacs.d/snippets/js2-mode/it
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: it
|
||||
# key: it
|
||||
# --
|
||||
it('$1', () => {
|
||||
$2
|
||||
})
|
||||
5
users/grfn/emacs.d/snippets/js2-mode/it-pending
Normal file
5
users/grfn/emacs.d/snippets/js2-mode/it-pending
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: it-pending
|
||||
# key: xi
|
||||
# --
|
||||
it('$1')$0
|
||||
12
users/grfn/emacs.d/snippets/js2-mode/module
Normal file
12
users/grfn/emacs.d/snippets/js2-mode/module
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# key: module
|
||||
# name: module
|
||||
# expand-env: ((yas-indent-line (quote fixed)))
|
||||
# condition: (= (length "module") (current-column))
|
||||
# --
|
||||
/**
|
||||
* @fileOverview $1
|
||||
* @name ${2:`(file-name-nondirectory (buffer-file-name))`}
|
||||
* @author Griffin Smith
|
||||
* @license Proprietary
|
||||
*/
|
||||
$3
|
||||
7
users/grfn/emacs.d/snippets/js2-mode/record
Normal file
7
users/grfn/emacs.d/snippets/js2-mode/record
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: record
|
||||
# key: rec
|
||||
# --
|
||||
export default class $1 extends Record({
|
||||
$2
|
||||
}) {}
|
||||
7
users/grfn/emacs.d/snippets/js2-mode/test
Normal file
7
users/grfn/emacs.d/snippets/js2-mode/test
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: test
|
||||
# key: test
|
||||
# --
|
||||
test('$1', () => {
|
||||
$2
|
||||
})
|
||||
12
users/grfn/emacs.d/snippets/nix-mode/fetchFromGitHub
Normal file
12
users/grfn/emacs.d/snippets/nix-mode/fetchFromGitHub
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: fetchFromGitHub
|
||||
# uuid:
|
||||
# key: fetchFromGitHub
|
||||
# condition: t
|
||||
# --
|
||||
fetchFromGitHub {
|
||||
owner = "$1";
|
||||
repo = "$2";
|
||||
rev = "$3";
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
}
|
||||
16
users/grfn/emacs.d/snippets/nix-mode/pythonPackage
Normal file
16
users/grfn/emacs.d/snippets/nix-mode/pythonPackage
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# key: pypkg
|
||||
# name: pythonPackage
|
||||
# condition: t
|
||||
# --
|
||||
${1:pname} = buildPythonPackage rec {
|
||||
name = "\${pname}-\${version}";
|
||||
pname = "$1";
|
||||
version = "${2:1.0.0}";
|
||||
src = fetchPypi {
|
||||
inherit pname version;
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
};
|
||||
propagatedBuildInputs = with pythonSelf; [
|
||||
$3
|
||||
];
|
||||
};
|
||||
7
users/grfn/emacs.d/snippets/nix-mode/sha256
Normal file
7
users/grfn/emacs.d/snippets/nix-mode/sha256
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: sha256
|
||||
# uuid:
|
||||
# key: sha256
|
||||
# condition: t
|
||||
# --
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
6
users/grfn/emacs.d/snippets/org-mode/SQL source block
Normal file
6
users/grfn/emacs.d/snippets/org-mode/SQL source block
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# key: sql
|
||||
# name: SQL source block
|
||||
# --
|
||||
#+BEGIN_SRC sql ${1::async}
|
||||
$2
|
||||
#+END_SRC
|
||||
13
users/grfn/emacs.d/snippets/org-mode/combat
Normal file
13
users/grfn/emacs.d/snippets/org-mode/combat
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: combat
|
||||
# uuid:
|
||||
# key: combat
|
||||
# condition: t
|
||||
# --
|
||||
| | initiative | max hp | current hp | status | |
|
||||
|-------------+------------+--------+------------+--------+------|
|
||||
| Barty Barty | | | | | <--- |
|
||||
| Hectoroth | | | | | |
|
||||
| Xanadu | | | | | |
|
||||
| Aurora | | | | | |
|
||||
| EFB | | | | | |
|
||||
5
users/grfn/emacs.d/snippets/org-mode/date
Normal file
5
users/grfn/emacs.d/snippets/org-mode/date
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# key: date
|
||||
# name: date.org
|
||||
# --
|
||||
[`(format-time-string "%Y-%m-%d")`]$0
|
||||
5
users/grfn/emacs.d/snippets/org-mode/date-time
Normal file
5
users/grfn/emacs.d/snippets/org-mode/date-time
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: date-time
|
||||
# key: dt
|
||||
# --
|
||||
[`(format-time-string "%Y-%m-%d %H:%m:%S")`]
|
||||
7
users/grfn/emacs.d/snippets/org-mode/description
Normal file
7
users/grfn/emacs.d/snippets/org-mode/description
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: description
|
||||
# key: desc
|
||||
# --
|
||||
:DESCRIPTION:
|
||||
$1
|
||||
:END:
|
||||
5
users/grfn/emacs.d/snippets/org-mode/nologdone
Normal file
5
users/grfn/emacs.d/snippets/org-mode/nologdone
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: nologdone
|
||||
# key: nologdone
|
||||
# --
|
||||
#+STARTUP: nologdone$0
|
||||
6
users/grfn/emacs.d/snippets/org-mode/python source block
Normal file
6
users/grfn/emacs.d/snippets/org-mode/python source block
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# key: py
|
||||
# name: Python source block
|
||||
# --
|
||||
#+BEGIN_SRC python
|
||||
$0
|
||||
#+END_SRC
|
||||
6
users/grfn/emacs.d/snippets/org-mode/reveal
Normal file
6
users/grfn/emacs.d/snippets/org-mode/reveal
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# key: reveal
|
||||
# name: reveal
|
||||
# condition: t
|
||||
# --
|
||||
#+ATTR_REVEAL: :frag ${1:roll-in}
|
||||
$0
|
||||
7
users/grfn/emacs.d/snippets/org-mode/transaction
Normal file
7
users/grfn/emacs.d/snippets/org-mode/transaction
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: transaction
|
||||
# key: begin
|
||||
# --
|
||||
BEGIN;
|
||||
$0
|
||||
ROLLBACK;
|
||||
5
users/grfn/emacs.d/snippets/python-mode/add_column
Normal file
5
users/grfn/emacs.d/snippets/python-mode/add_column
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: add_column
|
||||
# key: op.add_column
|
||||
# --
|
||||
op.add_column('${1:table}', sa.Column('${2:name}', sa.${3:String()}))$0
|
||||
15
users/grfn/emacs.d/snippets/python-mode/decorate
Normal file
15
users/grfn/emacs.d/snippets/python-mode/decorate
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: decorate
|
||||
# uuid:
|
||||
# key: decorate
|
||||
# condition: t
|
||||
# --
|
||||
def wrap(inner):
|
||||
@wraps(inner)
|
||||
def wrapped(*args, **kwargs):
|
||||
ret = inner(*args, **kwargs)
|
||||
return ret
|
||||
|
||||
return wrapped
|
||||
|
||||
return wrap
|
||||
7
users/grfn/emacs.d/snippets/python-mode/dunder
Normal file
7
users/grfn/emacs.d/snippets/python-mode/dunder
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: dunder
|
||||
# uuid:
|
||||
# key: du
|
||||
# condition: t
|
||||
# --
|
||||
__$1__$0
|
||||
7
users/grfn/emacs.d/snippets/python-mode/name
Normal file
7
users/grfn/emacs.d/snippets/python-mode/name
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: name
|
||||
# uuid:
|
||||
# key: name
|
||||
# condition: t
|
||||
# --
|
||||
__name__
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# key: exec
|
||||
# name: op.get_bind.execute
|
||||
# --
|
||||
op.get_bind().execute(
|
||||
"""
|
||||
`(progn (sqlup-mode) "")`$1
|
||||
""")
|
||||
7
users/grfn/emacs.d/snippets/python-mode/pdb
Normal file
7
users/grfn/emacs.d/snippets/python-mode/pdb
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: pdb
|
||||
# uuid:
|
||||
# key: pdb
|
||||
# condition: t
|
||||
# --
|
||||
import pdb; pdb.set_trace()
|
||||
5
users/grfn/emacs.d/snippets/rust-mode/#[macro_use]
Normal file
5
users/grfn/emacs.d/snippets/rust-mode/#[macro_use]
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# key: macro_use
|
||||
# name: #[macro_use]
|
||||
# --
|
||||
#[macro_use]
|
||||
${1:extern crate} ${2:something};$0
|
||||
10
users/grfn/emacs.d/snippets/rust-mode/async test
Normal file
10
users/grfn/emacs.d/snippets/rust-mode/async test
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: async test
|
||||
# uuid:
|
||||
# key: atest
|
||||
# condition: t
|
||||
# --
|
||||
#[tokio::test(threaded_scheduler)]
|
||||
async fn ${1:test_name}() {
|
||||
`%`$0
|
||||
}
|
||||
10
users/grfn/emacs.d/snippets/rust-mode/benchmark
Normal file
10
users/grfn/emacs.d/snippets/rust-mode/benchmark
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: benchmark
|
||||
# uuid:
|
||||
# key: bench
|
||||
# condition: t
|
||||
# --
|
||||
#[bench]
|
||||
fn ${1:benchmark_name}(b: &mut Bencher) {
|
||||
`%`b.iter(|| $0);
|
||||
}
|
||||
10
users/grfn/emacs.d/snippets/rust-mode/proptest
Normal file
10
users/grfn/emacs.d/snippets/rust-mode/proptest
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: proptest
|
||||
# uuid:
|
||||
# key: proptest
|
||||
# condition: t
|
||||
# --
|
||||
#[proptest]
|
||||
fn ${1:test_name}($2) {
|
||||
`%`$0
|
||||
}
|
||||
9
users/grfn/emacs.d/snippets/rust-mode/tests
Normal file
9
users/grfn/emacs.d/snippets/rust-mode/tests
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# key: tests
|
||||
# name: test module
|
||||
# --
|
||||
#[cfg(test)]
|
||||
mod ${1:tests} {
|
||||
use super::*;
|
||||
|
||||
$0
|
||||
}
|
||||
5
users/grfn/emacs.d/snippets/snippet-mode/indent
Normal file
5
users/grfn/emacs.d/snippets/snippet-mode/indent
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: indent
|
||||
# key: indent
|
||||
# --
|
||||
# expand-env: ((yas-indent-line 'fixed))
|
||||
5
users/grfn/emacs.d/snippets/sql-mode/count(*) group by
Normal file
5
users/grfn/emacs.d/snippets/sql-mode/count(*) group by
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: count(*) group by
|
||||
# key: countby
|
||||
# --
|
||||
SELECT count(*), ${1:column} FROM ${2:table} GROUP BY $1;
|
||||
11
users/grfn/emacs.d/snippets/terraform-mode/variable
Normal file
11
users/grfn/emacs.d/snippets/terraform-mode/variable
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: variable
|
||||
# uuid:
|
||||
# key: var
|
||||
# condition: t
|
||||
# --
|
||||
variable "${1:name}" {
|
||||
type = ${2:string}
|
||||
${3:default = ${4:default}}
|
||||
}
|
||||
$0
|
||||
5
users/grfn/emacs.d/snippets/text-mode/date
Normal file
5
users/grfn/emacs.d/snippets/text-mode/date
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# name: date
|
||||
# key: date
|
||||
# --
|
||||
`(format-time-string "%Y-%m-%d")`$0
|
||||
192
users/grfn/emacs.d/splitjoin.el
Normal file
192
users/grfn/emacs.d/splitjoin.el
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'dash)
|
||||
(load! "utils")
|
||||
|
||||
;;;
|
||||
;;; Vars
|
||||
;;;
|
||||
|
||||
(defvar +splitjoin/split-callbacks '()
|
||||
"Alist mapping major mode symbol names to lists of split callbacks")
|
||||
|
||||
(defvar +splitjoin/join-callbacks '()
|
||||
"Alist mapping major mode symbol names to lists of join callbacks")
|
||||
|
||||
|
||||
|
||||
;;;
|
||||
;;; Definition macros
|
||||
;;;
|
||||
|
||||
(defmacro +splitjoin/defsplit (mode name &rest body)
|
||||
`(setf
|
||||
(alist-get ',name (alist-get ,mode +splitjoin/split-callbacks))
|
||||
(λ! () ,@body)))
|
||||
|
||||
(defmacro +splitjoin/defjoin (mode name &rest body)
|
||||
`(setf
|
||||
(alist-get ',name (alist-get ,mode +splitjoin/join-callbacks))
|
||||
(λ! () ,@body)))
|
||||
|
||||
;;;
|
||||
;;; Commands
|
||||
;;;
|
||||
|
||||
(defun +splitjoin/split ()
|
||||
(interactive)
|
||||
(when-let (callbacks (->> +splitjoin/split-callbacks
|
||||
(alist-get major-mode)
|
||||
(-map #'cdr)))
|
||||
(find-if #'funcall callbacks)))
|
||||
|
||||
(defun +splitjoin/join ()
|
||||
(interactive)
|
||||
(when-let (callbacks (->> +splitjoin/join-callbacks
|
||||
(alist-get major-mode)
|
||||
(-map #'cdr)))
|
||||
(find-if #'funcall callbacks)))
|
||||
|
||||
|
||||
;;;
|
||||
;;; Splits and joins
|
||||
;;; TODO: this should probably go in a file-per-language
|
||||
;;;
|
||||
|
||||
(+splitjoin/defjoin
|
||||
'elixir-mode
|
||||
join-do
|
||||
(let* ((function-pattern (rx (and (zero-or-more whitespace)
|
||||
"do"
|
||||
(zero-or-more whitespace)
|
||||
(optional (and "#" (zero-or-more anything)))
|
||||
eol)))
|
||||
(end-pattern (rx bol
|
||||
(zero-or-more whitespace)
|
||||
"end"
|
||||
(zero-or-more whitespace)
|
||||
eol))
|
||||
(else-pattern (rx bol
|
||||
(zero-or-more whitespace)
|
||||
"else"
|
||||
(zero-or-more whitespace)
|
||||
eol))
|
||||
(lineno (line-number-at-pos))
|
||||
(line (thing-at-point 'line t)))
|
||||
(when-let ((do-start-pos (string-match function-pattern line)))
|
||||
(cond
|
||||
((string-match-p end-pattern (get-line (inc lineno)))
|
||||
(modify-then-indent
|
||||
(goto-line-char do-start-pos)
|
||||
(insert ",")
|
||||
(goto-char (line-end-position))
|
||||
(insert ": nil")
|
||||
(line-move 1)
|
||||
(delete-line))
|
||||
t)
|
||||
|
||||
((string-match-p end-pattern (get-line (+ 2 lineno)))
|
||||
(modify-then-indent
|
||||
(goto-line-char do-start-pos)
|
||||
(insert ",")
|
||||
(goto-char (line-end-position))
|
||||
(insert ":")
|
||||
(join-line t)
|
||||
(line-move 1)
|
||||
(delete-line))
|
||||
t)
|
||||
|
||||
((and (string-match-p else-pattern (get-line (+ 2 lineno)))
|
||||
(string-match-p end-pattern (get-line (+ 4 lineno))))
|
||||
(modify-then-indent
|
||||
(goto-line-char do-start-pos)
|
||||
(insert ",")
|
||||
(goto-char (line-end-position))
|
||||
(insert ":")
|
||||
(join-line t)
|
||||
(goto-eol)
|
||||
(insert ",")
|
||||
(join-line t)
|
||||
(goto-eol)
|
||||
(insert ":")
|
||||
(join-line t)
|
||||
(line-move 1)
|
||||
(delete-line))
|
||||
t)))))
|
||||
|
||||
(comment
|
||||
(string-match (rx (and bol
|
||||
"if "
|
||||
(one-or-more anything)
|
||||
","
|
||||
(zero-or-more whitespace)
|
||||
"do:"
|
||||
(one-or-more anything)
|
||||
","
|
||||
(zero-or-more whitespace)
|
||||
"else:"
|
||||
(one-or-more anything)))
|
||||
"if 1, do: nil, else: nil")
|
||||
|
||||
)
|
||||
|
||||
(+splitjoin/defsplit
|
||||
'elixir-mode
|
||||
split-do-with-optional-else
|
||||
(let* ((if-with-else-pattern (rx (and bol
|
||||
(one-or-more anything)
|
||||
","
|
||||
(zero-or-more whitespace)
|
||||
"do:"
|
||||
(one-or-more anything)
|
||||
(optional
|
||||
","
|
||||
(zero-or-more whitespace)
|
||||
"else:"
|
||||
(one-or-more anything)))))
|
||||
(current-line (get-line)))
|
||||
(when (string-match if-with-else-pattern current-line)
|
||||
(modify-then-indent
|
||||
(assert (goto-regex-on-line ",[[:space:]]*do:"))
|
||||
(delete-char 1)
|
||||
(assert (goto-regex-on-line ":"))
|
||||
(delete-char 1)
|
||||
(insert "\n")
|
||||
(when (goto-regex-on-line-r ",[[:space:]]*else:")
|
||||
(delete-char 1)
|
||||
(insert "\n")
|
||||
(assert (goto-regex-on-line ":"))
|
||||
(delete-char 1)
|
||||
(insert "\n"))
|
||||
(goto-eol)
|
||||
(insert "\nend"))
|
||||
t)))
|
||||
|
||||
(comment
|
||||
(+splitjoin/defsplit 'elixir-mode split-def
|
||||
(let ((function-pattern (rx (and ","
|
||||
(zero-or-more whitespace)
|
||||
"do:")))
|
||||
(line (thing-at-point 'line t)))
|
||||
(when-let (idx (string-match function-pattern line))
|
||||
(let ((beg (line-beginning-position))
|
||||
(orig-line-char (- (point) (line-beginning-position))))
|
||||
(save-mark-and-excursion
|
||||
(goto-line-char idx)
|
||||
(delete-char 1)
|
||||
(goto-line-char (string-match ":" (thing-at-point 'line t)))
|
||||
(delete-char 1)
|
||||
(insert "\n")
|
||||
(goto-eol)
|
||||
(insert "\n")
|
||||
(insert "end")
|
||||
(evil-indent beg (+ (line-end-position) 1))))
|
||||
(goto-line-char orig-line-char)
|
||||
t))))
|
||||
|
||||
(+splitjoin/defjoin
|
||||
'elixir-mode
|
||||
join-if-with-else
|
||||
(let* ((current-line (thing-at-point 'line)))))
|
||||
|
||||
(provide 'splitjoin)
|
||||
75
users/grfn/emacs.d/sql-strings.el
Normal file
75
users/grfn/emacs.d/sql-strings.el
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
;;; https://www.emacswiki.org/emacs/StringAtPoint
|
||||
(defun ourcomments-string-or-comment-bounds-1 (what)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(let* ((here (point))
|
||||
;; Fix-me: when on end-point, how to handle that and which should be last hit point?
|
||||
(state (parse-partial-sexp (point-min) (1+ here)))
|
||||
(type (if (nth 3 state)
|
||||
'string
|
||||
(if (nth 4 state)
|
||||
'comment)))
|
||||
(start (when type (nth 8 state)))
|
||||
end)
|
||||
(unless start
|
||||
(setq state (parse-partial-sexp (point-min) here))
|
||||
(setq type (if (nth 3 state)
|
||||
'string
|
||||
(if (nth 4 state)
|
||||
'comment)))
|
||||
(setq start (when type (nth 8 state))))
|
||||
(unless (or (not what)
|
||||
(eq what type))
|
||||
(setq start nil))
|
||||
(if (not start)
|
||||
(progn
|
||||
(goto-char here)
|
||||
nil)
|
||||
(setq state (parse-partial-sexp (1+ start) (point-max)
|
||||
nil nil state 'syntax-table))
|
||||
(setq end (point))
|
||||
(goto-char here)
|
||||
(cons start end)))))
|
||||
|
||||
(defun ourcomments-bounds-of-string-at-point ()
|
||||
"Return bounds of string at point if any."
|
||||
(ourcomments-string-or-comment-bounds-1 'string))
|
||||
|
||||
(put 'string 'bounds-of-thing-at-point 'ourcomments-bounds-of-string-at-point)
|
||||
|
||||
(defun -sanitize-sql-string (str)
|
||||
(->> str
|
||||
(downcase)
|
||||
(s-trim)
|
||||
(replace-regexp-in-string
|
||||
(rx (or (and string-start (or "\"\"\""
|
||||
"\""))
|
||||
(and (or "\"\"\""
|
||||
"\"")
|
||||
string-end)))
|
||||
"")
|
||||
(s-trim)))
|
||||
|
||||
(defun sql-string-p (str)
|
||||
"Returns 't if STR looks like a string literal for a SQL statement"
|
||||
(setq str (-sanitize-sql-string str))
|
||||
(or (s-starts-with? "select" str)))
|
||||
|
||||
;;; tests
|
||||
|
||||
(require 'ert)
|
||||
|
||||
(ert-deftest sanitize-sql-string-test ()
|
||||
(should (string-equal "select * from foo;"
|
||||
(-sanitize-sql-string
|
||||
"\"\"\"SELECT * FROM foo;\n\n\"\"\""))))
|
||||
|
||||
(ert-deftest test-sql-string-p ()
|
||||
(dolist (str '("SELECT * FROM foo;"
|
||||
"select * from foo;"))
|
||||
(should (sql-string-p str)))
|
||||
|
||||
(dolist (str '("not a QUERY"))
|
||||
(should-not (sql-string-p str))))
|
||||
24
users/grfn/emacs.d/terraform.el
Normal file
24
users/grfn/emacs.d/terraform.el
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(add-hook 'terraform-mode-hook #'terraform-format-on-save-mode)
|
||||
|
||||
(defun packer-format-buffer ()
|
||||
(interactive)
|
||||
(let ((buf (get-buffer-create "*packer-fmt*")))
|
||||
(if (zerop (call-process "packer" nil buf nil "fmt" (buffer-file-name)))
|
||||
(revert-buffer t t t)
|
||||
(message "packer fmt failed: %s" (with-current-buffer buf (buffer-string))))))
|
||||
|
||||
(define-minor-mode packer-format-on-save-mode
|
||||
"Run packer-format-buffer before saving the current buffer"
|
||||
:lighter nil
|
||||
(if packer-format-on-save-mode
|
||||
(add-hook 'before-save-hook #'packer-format-buffer nil t)
|
||||
(remove-hook 'before-save-hook #'packer-format-buffer t)))
|
||||
|
||||
(defun maybe-init-packer ()
|
||||
(interactive)
|
||||
(when (s-ends-with-p ".pkr" (file-name-base (buffer-file-name)))
|
||||
(packer-format-on-save-mode)))
|
||||
|
||||
(add-hook 'hcl-mode-hook #'maybe-init-packer)
|
||||
68
users/grfn/emacs.d/tests/splitjoin_test.el
Normal file
68
users/grfn/emacs.d/tests/splitjoin_test.el
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
;;; private/grfn/tests/splitjoin_test.el -*- lexical-binding: t; -*-
|
||||
|
||||
(require 'ert)
|
||||
;; (load! 'splitjoin)
|
||||
;; (load! 'utils)
|
||||
; (require 'splitjoin)
|
||||
|
||||
;;; Helpers
|
||||
|
||||
(defvar *test-buffer* nil)
|
||||
(make-variable-buffer-local '*test-buffer*)
|
||||
|
||||
(defun test-buffer ()
|
||||
(when (not *test-buffer*)
|
||||
(setq *test-buffer* (get-buffer-create "test-buffer")))
|
||||
*test-buffer*)
|
||||
|
||||
(defmacro with-test-buffer (&rest body)
|
||||
`(with-current-buffer (test-buffer)
|
||||
,@body))
|
||||
|
||||
(defun set-test-buffer-mode (mode)
|
||||
(let ((mode (if (functionp mode) mode
|
||||
(-> mode symbol-name (concat "-mode") intern))))
|
||||
(assert (functionp mode))
|
||||
(with-test-buffer (funcall mode))))
|
||||
|
||||
(defmacro set-test-buffer-contents (contents)
|
||||
(with-test-buffer
|
||||
(erase-buffer)
|
||||
(insert contents)))
|
||||
|
||||
(defun test-buffer-contents ()
|
||||
(with-test-buffer (substring-no-properties (buffer-string))))
|
||||
|
||||
(defmacro assert-test-buffer-contents (expected-contents)
|
||||
`(should (equal (string-trim (test-buffer-contents))
|
||||
(string-trim ,expected-contents))))
|
||||
|
||||
(defmacro should-join-to (mode original-contents expected-contents)
|
||||
`(progn
|
||||
(set-test-buffer-mode ,mode)
|
||||
(set-test-buffer-contents ,original-contents)
|
||||
(with-test-buffer (+splitjoin/join))
|
||||
(assert-test-buffer-contents ,expected-contents)))
|
||||
|
||||
(defmacro should-split-to (mode original-contents expected-contents)
|
||||
`(progn
|
||||
(set-test-buffer-mode ,mode)
|
||||
(set-test-buffer-contents ,original-contents)
|
||||
(with-test-buffer (+splitjoin/split))
|
||||
(assert-test-buffer-contents ,expected-contents)))
|
||||
|
||||
(defmacro should-splitjoin (mode joined-contents split-contents)
|
||||
`(progn
|
||||
(should-split-to ,mode ,joined-contents ,split-contents)
|
||||
(should-join-to ,mode ,split-contents ,joined-contents)))
|
||||
|
||||
;;; Tests
|
||||
|
||||
;; Elixir
|
||||
(ert-deftest elixir-if-splitjoin-test ()
|
||||
(should-splitjoin 'elixir
|
||||
"if predicate?(), do: result"
|
||||
"if predicate?() do
|
||||
result
|
||||
end"))
|
||||
|
||||
115
users/grfn/emacs.d/themes/grfn-solarized-light-theme.el
Normal file
115
users/grfn/emacs.d/themes/grfn-solarized-light-theme.el
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
(require 'solarized)
|
||||
(eval-when-compile
|
||||
(require 'solarized-palettes))
|
||||
|
||||
;; (defun grfn-solarized-theme ()
|
||||
;; (custom-theme-set-faces
|
||||
;; theme-name
|
||||
;; `(font-lock-doc-face ((,class (:foreground ,s-base1))))
|
||||
;; `(font-lock-preprocessor-face ((,class (:foreground ,red))))
|
||||
;; `(font-lock-keyword-face ((,class (:foreground ,green))))
|
||||
|
||||
;; `(elixir-attribute-face ((,class (:foreground ,blue))))
|
||||
;; `(elixir-atom-face ((,class (:foreground ,cyan))))))
|
||||
|
||||
(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")
|
||||
|
||||
|
||||
(deftheme grfn-solarized-light "The light variant of Griffin's solarized theme")
|
||||
|
||||
(setq grfn-solarized-faces
|
||||
'("Griffin's solarized theme customization"
|
||||
(custom-theme-set-faces
|
||||
theme-name
|
||||
`(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))))
|
||||
|
||||
`(elixir-attribute-face ((t (:foreground ,+solarized-blue))))
|
||||
`(elixir-atom-face ((t (:foreground ,+solarized-cyan))))
|
||||
`(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))))
|
||||
|
||||
`(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))))
|
||||
|
||||
`(haskell-operator-face ((t (:foreground ,+solarized-green))))
|
||||
`(haskell-keyword-face ((t (:foreground ,+solarized-cyan))))
|
||||
|
||||
`(org-drawer ((t (:foreground ,+solarized-s-base1
|
||||
:bold t)))))))
|
||||
|
||||
(solarized-with-color-variables
|
||||
'light 'grfn-solarized-light solarized-light-color-palette-alist)
|
||||
|
||||
(provide-theme 'grfn-solarized-light)
|
||||
114
users/grfn/emacs.d/utils.el
Normal file
114
users/grfn/emacs.d/utils.el
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
|
||||
;; Elisp Extras
|
||||
|
||||
(defmacro comment (&rest _body)
|
||||
"Comment out one or more s-expressions"
|
||||
nil)
|
||||
|
||||
(defun inc (x) "Returns x + 1" (+ 1 x))
|
||||
(defun dec (x) "Returns x - 1" (- x 1))
|
||||
|
||||
(defun average (ns)
|
||||
"Arithmetic mean of xs"
|
||||
(if (null ns) nil
|
||||
(/ (apply #'+ ns)
|
||||
(length ns))))
|
||||
|
||||
(comment
|
||||
(average (list 1 2 3 4))
|
||||
)
|
||||
|
||||
;;
|
||||
;; Text editing utils
|
||||
;;
|
||||
|
||||
;; Reading strings
|
||||
|
||||
(defun get-char (&optional point)
|
||||
"Get the character at the given `point' (defaulting to the current point),
|
||||
without properties"
|
||||
(let ((point (or point (point))))
|
||||
(buffer-substring-no-properties point (+ 1 point))))
|
||||
|
||||
(defun get-line (&optional lineno)
|
||||
"Read the line number `lineno', or the current line if `lineno' is nil, and
|
||||
return it as a string stripped of all text properties"
|
||||
(let ((current-line (line-number-at-pos)))
|
||||
(if (or (not lineno)
|
||||
(= current-line lineno))
|
||||
(thing-at-point 'line t)
|
||||
(save-mark-and-excursion
|
||||
(line-move (- lineno (line-number-at-pos)))
|
||||
(thing-at-point 'line t)))))
|
||||
|
||||
(defun get-line-point ()
|
||||
"Get the position in the current line of the point"
|
||||
(- (point) (line-beginning-position)))
|
||||
|
||||
;; Moving in the file
|
||||
|
||||
(defun goto-line-char (pt)
|
||||
"Moves the point to the given position expressed as an offset from the start
|
||||
of the line"
|
||||
(goto-char (+ (line-beginning-position) pt)))
|
||||
|
||||
(defun goto-eol ()
|
||||
"Moves to the end of the current line"
|
||||
(goto-char (line-end-position)))
|
||||
|
||||
(defun goto-regex-on-line (regex)
|
||||
"Moves the point to the first occurrence of `regex' on the current line.
|
||||
Returns nil if the regex did not match, non-nil otherwise"
|
||||
(when-let ((current-line (get-line))
|
||||
(line-char (string-match regex current-line)))
|
||||
(goto-line-char line-char)))
|
||||
|
||||
(defun goto-regex-on-line-r (regex)
|
||||
"Moves the point to the *last* occurrence of `regex' on the current line.
|
||||
Returns nil if the regex did not match, non-nil otherwise"
|
||||
(when-let ((current-line (get-line))
|
||||
(modified-regex (concat ".*\\(" regex "\\)"))
|
||||
(_ (string-match modified-regex current-line))
|
||||
(match-start (match-beginning 1)))
|
||||
(goto-line-char match-start)))
|
||||
|
||||
(comment
|
||||
(progn
|
||||
(string-match (rx (and (zero-or-more anything)
|
||||
(group "foo" "foo")))
|
||||
"foofoofoo")
|
||||
(match-beginning 1)))
|
||||
|
||||
;; Changing file contents
|
||||
|
||||
(defun delete-line ()
|
||||
"Remove the line at the current point"
|
||||
(delete-region (line-beginning-position)
|
||||
(inc (line-end-position))))
|
||||
|
||||
(defmacro modify-then-indent (&rest body)
|
||||
"Modify text in the buffer according to body, then re-indent from where the
|
||||
cursor started to where the cursor ended up, then return the cursor to where
|
||||
it started."
|
||||
`(let ((beg (line-beginning-position))
|
||||
(orig-line-char (- (point) (line-beginning-position))))
|
||||
(atomic-change-group
|
||||
(save-mark-and-excursion
|
||||
,@body
|
||||
(evil-indent beg (+ (line-end-position) 1))))
|
||||
(goto-line-char orig-line-char)))
|
||||
|
||||
(pcase-defmacro s-starts-with (prefix)
|
||||
`(pred (s-starts-with-p ,prefix)))
|
||||
|
||||
(pcase-defmacro s-contains (needle &optional ignore-case)
|
||||
`(pred (s-contains-p ,needle
|
||||
,@(when ignore-case (list ignore-case)))))
|
||||
|
||||
(comment
|
||||
(pcase "foo"
|
||||
((s-contains "bar") 1)
|
||||
((s-contains "o") 2))
|
||||
)
|
||||
24
users/grfn/emacs.d/vterm.el
Normal file
24
users/grfn/emacs.d/vterm.el
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
;;; -*- lexical-binding: t; -*-
|
||||
|
||||
(defun require-vterm ()
|
||||
(add-to-list
|
||||
'load-path
|
||||
(concat
|
||||
(s-trim
|
||||
(shell-command-to-string
|
||||
"nix-build --no-out-link ~/code/depot -A third_party.emacs.vterm"))
|
||||
"/share/emacs/site-lisp/elpa/vterm-20200515.1412"))
|
||||
(require 'vterm))
|
||||
|
||||
(defun +grfn/vterm-setup ()
|
||||
(hide-mode-line-mode)
|
||||
(setq-local evil-collection-vterm-send-escape-to-vterm-p t))
|
||||
|
||||
(add-hook 'vterm-mode-hook #'+grfn/vterm-setup)
|
||||
|
||||
(map! (:map vterm-mode-map
|
||||
"<C-escape>" #'evil-normal-state))
|
||||
|
||||
(comment
|
||||
(require-vterm)
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue