17 Commits

11 changed files with 443 additions and 52 deletions

View File

@@ -3,40 +3,58 @@
;; Place your private configuration here! Remember, you do not need to run 'doom
;; sync' after modifying this file!
;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets.
;; clients, file templates and snippets. It is optional.
(setq user-full-name "Max Regan"
user-mail-address "mgregan2@gmail.com")
;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
;; are the three important ones:
;; Doom exposes five (optional) variables for controlling fonts in Doom:
;;
;; + `doom-font'
;; + `doom-variable-pitch-font'
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
;; - `doom-font' -- the primary font to use
;; - `doom-variable-pitch-font' -- a non-monospace font (where applicable)
;; - `doom-big-font' -- used for `doom-big-font-mode'; use this for
;; presentations or streaming.
;; - `doom-unicode-font' -- for unicode glyphs
;; - `doom-serif-font' -- for the `fixed-pitch-serif' face
;;
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
;; font string. You generally only need these two:
;; (setq doom-font (font-spec :family "monospace" :size 12 :weight 'semi-light)
;; doom-variable-pitch-font (font-spec :family "sans" :size 13))
;; See 'C-h v doom-font' for documentation and more examples of what they
;; accept. For example:
;;
;;(setq doom-font (font-spec :family "Fira Code" :size 12 :weight 'semi-light)
;; doom-variable-pitch-font (font-spec :family "Fira Sans" :size 13))
;;
;; If you or Emacs can't find your font, use 'M-x describe-font' to look them
;; up, `M-x eval-region' to execute elisp code, and 'M-x doom/reload-font' to
;; refresh your font settings. If Emacs still can't find your font, it likely
;; wasn't installed correctly. Font issues are rarely Doom issues!
;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. This is the default:
(setq doom-theme 'doom-one)
;; If you use `org' and don't want your org files in the default location below,
;; change `org-directory'. It must be set before org loads!
(setq org-directory "~/org/")
(setq doom-theme 'doom-1337)
;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
(setq display-line-numbers-type t)
;; If you use `org' and don't want your org files in the default location below,
;; change `org-directory'. It must be set before org loads!
(setq org-directory "~/org/")
;; Here are some additional functions/macros that could help you configure Doom:
;; Whenever you reconfigure a package, make sure to wrap your config in an
;; `after!' block, otherwise Doom's defaults may override your settings. E.g.
;;
;; (after! PACKAGE
;; (setq x y))
;;
;; The exceptions to this rule:
;;
;; - Setting file/directory variables (like `org-directory')
;; - Setting variables which explicitly tell you to set them before their
;; package is loaded (see 'C-h v VARIABLE' to look up their documentation).
;; - Setting doom variables (which start with 'doom-' or '+').
;;
';; Here are some additional functions/macros that will help you configure Doom.
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
@@ -49,6 +67,83 @@
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;; Alternatively, use `C-h o' to look up a symbol (functions, variables, faces,
;; etc).
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.
(after! lsp-ui
;; sideline is super noisy
(setq lsp-ui-sideline-enable nil))
(after! org-journal
(setq org-journal-dir "~/org/journal/"))
(after! counsel
(ivy-rich-mode 1)
(all-the-icons-ivy-rich-mode 1))
(use-package! mgr-gitlab
:load-path "lisp/mgr-gitlab"
:ensure t
:config
(setq gitlab-host "https://gitlab.maxregan.me"
gitlab-token-id (if (file-exists-p mgr-gitlab-token-file)
(with-temp-buffer
(insert-file-contents mgr-gitlab-token-file)
(string-trim (buffer-string)))
nil)
dashboard-projects-backend 'projectile
dashboard-items '((mgr-gitlab-gitlab-projects . 10)
(recents . 5)
(agenda . 5)
(projects . 5))))
(use-package! persp-mode
:config
(setq persp-emacsclient-init-frame-behaviour-override "main"))
;; Hey doom, +ivy/compile is worse, give me projectile-compile-project back
(define-key (current-global-map) [remap projectile-compile-project] 'projectile-compile-project)
(use-package! denote
:config (setq denote-known-keywords '("meta" "emacs")
denote-directory "~/notes/denote"))
(use-package! uniquify
:config
(setq uniquify-buffer-name-style 'post-forward))
(use-package! clipetty
:config (global-clipetty-mode 1))
(use-package! vterm
:config
(push '("magit" magit) vterm-eval-cmds)
(push '("compile" compile) vterm-eval-cmds))
(use-package! with-editor
:config
(add-hook 'shell-mode-hook 'with-editor-export-editor)
(add-hook 'eshell-mode-hook 'with-editor-export-editor)
(add-hook 'term-exec-hook 'with-editor-export-editor)
(add-hook 'vterm-exec-hook 'with-editor-export-editor))
;; Utils for pinning buffers in windows. This is useful for compilation and shells.
(defun dedicate-window ()
(interactive)
(set-window-dedicated-p (get-buffer-window) t))
(defun undedicate-window ()
(interactive)
(set-window-dedicated-p (get-buffer-window) nil))
(defun disable-format-on-save ()
(interactive)
(format-all-mode -1))
;; Load optional site-specific config (e.g. work profiles)
(if (file-exists-p "~/.doom-site/config.el")
(load-file "~/.doom-site/config.el"))

View File

@@ -4,8 +4,8 @@
;; in. Remember to run 'doom sync' after modifying it!
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;; documentation. There you'll find a "Module Index" link where you'll find
;; a comprehensive list of Doom's modules and what flags they support.
;; documentation. There you'll find a link to Doom's Module Index where all
;; of our modules are listed, including what flags they support.
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;; 'C-c c k' for non-vim users) to view its documentation. This works on
@@ -15,6 +15,7 @@
;; directory (for easy access to its source code).
(doom! :input
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
;;chinese
;;japanese
;;layout ; auie,ctsrnm is the superior home row
@@ -29,9 +30,12 @@
: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
;;(emoji +unicode) ; 🙂
;;doom-dashboard ; a nifty splash screen for Emacs
;;doom-quit ; DOOM quit-message prompts when you quit Emacs
(emoji
+unicode
+github
+ascii) ; 🙂
hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
;;hydra
;;indent-guides ; highlighted indent columns
@@ -43,17 +47,17 @@
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
;;tabs ; a tab bar for Emacs
treemacs ; a project drawer, like neotree but cooler
;;unicode ; extended unicode support for various languages
;;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
window-select ; visually switch windows
workspaces ; tab emulation, persistence & separate workspaces
;;zen ; distraction-free coding or writing
:editor
;;(evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files
;; file-templates ; auto-snippets for empty files
fold ; (nigh) universal code folding
;;(format +onsave) ; automated prettiness
;;god ; run Emacs commands without modifier keys
@@ -66,7 +70,7 @@
word-wrap ; soft wrapping with language-aware indent
:emacs
dired ; making dired pretty [functional]
(dire + icons) ; making dired pretty [functional]
electric ; smarter, keyword-based electric-indent
;;ibuffer ; interactive buffer management
undo ; persistent, smarter undo for your inevitable mistakes
@@ -89,12 +93,12 @@
debugger ; FIXME stepping through code, to help you add bugs
;;direnv
docker
;;editorconfig ; let someone else argue about tabs vs spaces
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 ; navigate your code and its documentation
;;lsp ; M-x vscode
lsp ; M-x vscode
magit ; a git porcelain for Emacs
make ; run make tasks from Emacs
;;pass ; password manager for nerds
@@ -104,23 +108,24 @@
;;taskrunner ; taskrunner for all your projects
;;terraform ; infrastructure as code
;;tmux ; an API for interacting with tmux
;;tree-sitter ; syntax and parsing, sitting in a tree...
;;upload ; map local to remote projects via ssh/ftp
:os
(:if IS-MAC macos) ; improve compatibility with macOS
;;tty ; improve the terminal Emacs experience
(tty +osc) ; improve the terminal Emacs experience
:lang
;;agda ; types of types of types of types...
;;beancount ; mind the GAAP
cc ; C > C++ == 1
(cc +lsp) ; C > C++ == 1
;;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
;;(dart +flutter) ; paint ui and not much else
(dart +flutter) ; paint ui and not much else
;;dhall
;;elixir ; erlang done right
;;elm ; care for a cup of TEA?
@@ -134,6 +139,7 @@
;;fstar ; (dependent) types and (monadic) effects and Z3
;;gdscript ; the language you waited for
;;(go +lsp) ; the hipster dialect
;;(graphql +lsp) ; Give queries a REST
;;(haskell +lsp) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ; a language you can depend on
@@ -161,7 +167,7 @@
;;rest ; Emacs as a REST client
;;rst ; ReST in peace
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
;;rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
;;scala ; java, but good
;;(scheme +guile) ; a fully conniving family of lisps
sh ; she sells {ba,z,fi}sh shells on the C xor
@@ -170,7 +176,7 @@
;;swift ; who asked for emoji variables?
;;terra ; Earth and Moon in alignment for performance.
;;web ; the tubes
;;yaml ; JSON, but readable
yaml ; JSON, but readable
;;zig ; C, but simpler
:email
@@ -189,3 +195,7 @@
:config
;;literate
(default +bindings +smartparens))
;; Load optional site-specific config (e.g. work profiles)
(if (file-exists-p "~/.doom-site/init.el")
(load-file "~/.doom-site/init.el"))

View File

@@ -0,0 +1,99 @@
;;; mgr-gitlab.el --- Description -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 Max Regan
;;
;; Author: Max Regan <https://github.com/reganmax>
;; Maintainer: Max Regan <reganmax@amazon.com>
;; Created: March 17, 2022
;; Modified: March 17, 2022
;; Version: 0.0.1
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
;; Homepage: https://github.com/reganmax/mgr-gitlab
;; Package-Requires: ((emacs "27.1"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Description: My personal configuration for Gitlab
;;
;;; Code:
(require 'gitlab)
(require 'dashboard)
(require 'projectile)
(require 'seq)
(defvar mgr-gitlab-project-path "~/repos/" "The location into which gitlab projects will be cloned.")
(defvar mgr-gitlab-token-file "~/.gitlab_token" "The location into which gitlab projects will be cloned.")
(defun mgr-gitlab-list-remote-project-names ()
"Return a list of all of the project names on the remote server."
(seq-map (lambda (el) (alist-get 'name el)) (gitlab-list-all-projects)))
(defun mgr-gitlab-list-local-project-names ()
"Return a list of all of the project names in the mgr-gitlab-project-path."
(seq-remove #'file-directory-p (directory-files mgr-gitlab-project-path)))
(defun mgr-gitlab--get-project-by-name (name)
"Return the alist for the project named NAME."
(seq-find (lambda (el) (string-equal (alist-get 'name el) name)) (gitlab-list-projects)))
(defun mgr-gitlab--get-id-for-name (name)
"Return an ID for a given project NAME."
(alist-get 'id (mgr-gitlab--get-project-by-name name)))
(defun mgr-gitlab-clone (name)
"Clone the project NAME."
;; TODO: Clone with API token, if there is one
(interactive
(list (completing-read "Project: " (mgr-gitlab-list-remote-project-names))))
(let* ((url (mgr-gitlab--get-url-by-name name))
(dest mgr-gitlab-project-path))
(setf magit-clone-set-remote.pushDefault t)
(magit-clone-regular url dest nil)))
(defun mgr-gitlab-clone-all ()
"Clone all projects in Gitlab, iteratively."
(interactive)
(seq-do (lambda (name)
(if (not (seq-contains-p (mgr-gitlab-list-local-project-names) name))
(progn
(message (format "Cloning %s..." name))
(mgr-gitlab-clone name))
(message (format "Skipping %s." name))))
(mgr-gitlab-list-remote-project-names)))
(defun mgr-gitlab--get-url-by-name (name)
"Return a fixed-up repository url for the given project NAME.
This also fixes up the capitalization in the project name that
gitlab so kindly removes."
(let* ((repo (mgr-gitlab--get-project-by-name name))
(orig-url (alist-get 'http_url_to_repo repo)))
(concat (mapconcat 'identity (butlast (split-string orig-url "/")) "/")
"/"
name
".git")))
(defun mgr-gitlab-dashboard-insert-gitlab-projects (list-size)
"A custom dashboard.el widget to display LIST-SIZE gitlab projects."
(dashboard-insert-section
"Gitlab Projects:"
(cl-map 'list (lambda (el) (alist-get 'name el)) (gitlab-list-all-projects))
list-size
'projects
"P"
`(lambda (&rest _)
(let ((dir (concat mgr-gitlab-project-path ,el)))
(if (not (file-directory-p dir))
(mgr-gitlab-clone ,el))
(magit-status (concat mgr-gitlab-project-path ,el))))
(format "%s" el)))
(add-to-list 'dashboard-item-generators '(mgr-gitlab-gitlab-projects . mgr-gitlab-dashboard-insert-gitlab-projects))
(ert-deftest mgr-gitlab-clone-test ()
"Tests that mgr-gitlab can clone a repo"
(mgr-gitlab-clone "IotButton"))
(provide 'mgr-gitlab)

View File

@@ -11,7 +11,7 @@
;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
;; https://github.com/radian-software/straight.el#the-recipe-format
;(package! another-package
; :recipe (:host github :repo "username/repo"))
@@ -34,7 +34,7 @@
;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
;; our package manager can't deal with; see radian-software/straight.el#279)
;(package! builtin-package :recipe (:branch "develop"))
;; Use `:pin' to specify a particular commit to install.
@@ -49,12 +49,14 @@
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;(unpin! t)
(package! org-journal)
;; required for mgr-gitlab
(package! gitlab)
(package! all-the-icons-ivy-rich)
(package! paredit)
(package! denote)
(package! git-auto-commit-mode)
;; Testing
(package! dashboard)
;; Load optional site-specific config (e.g. work profiles)
(if (file-exists-p "~/.doom-site/init.el")
(load-file "~/.doom-site/init.el"))

View File

@@ -4,6 +4,23 @@
# See https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables
stages:
- test
variables:
GIT_SUBMODULE_STRATEGY: recursive
DOOMDIR: ./.doom.d
EMACSDIR: ./.emacs.d
DOOMLOCALDIR: ./.emacs.d/local
test-emacs:
stage: test
image: ubuntu:22.04
before_script:
- apt-get update
- apt-get install -y emacs-nox git
- yes | ./.emacs.d/bin/doom install || true
script:
- ./.mgr_config/tests/test-emacs.sh
sast:
stage: test
include:

View File

@@ -73,8 +73,18 @@ prompt_function() {
PS1="\$(prompt_function)"
# Add doom emacs to path
export PATH=$PATH:$HOME/.emacs.d/bin/
export EDITOR="emacs"
export VISUAL="emacs"
# Special sauce for better vterm integration in emacs
if [[ "$INSIDE_EMACS" = 'vterm' ]] \
&& [[ -n ${EMACS_VTERM_PATH} ]] \
&& [[ -f ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh ]]; then
source ${EMACS_VTERM_PATH}/etc/emacs-vterm-bash.sh
alias find-file="vterm_cmd find-file"
alias magit="vterm_cmd magit"
fi

54
.mgr_config/bin/py Normal file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import argparse
import sys
from pathlib import Path
source = " ".join(sys.argv[1:])
INPUT_SRC_NAME = "<py-input>"
global_vars = {}
local_vars = {}
py_env_conf = Path.home() / ".py-env.py"
if py_env_conf.exists():
with open(Path.home() / ".py-env.py") as f:
code = compile(f.read(), "py-env.py", "exec")
exec(code)
try:
code = compile(source, INPUT_SRC_NAME, "eval")
val = eval(code)
# If it's a string, just print it
if type(val) == str:
print(val)
exit(0)
# If it's not iterable, just print it
try:
it = iter(val)
except TypeError as e:
if val is not None:
print(val)
exit(0)
# It's iterable, print each element as a line
try:
for item in val:
print(item)
exit(0)
except Exception as e:
e.args = ("Failed to print all elements",) + e.args
raise
except (SyntaxError, NameError) as e:
pass
try:
code = compile(source, INPUT_SRC_NAME, "exec")
exec(code)
except (SyntaxError, NameError) as e:
e.args = ("Invalid Python code",) + e.args
raise e

View File

@@ -21,6 +21,7 @@ if [[ $NEEDS_GIT_DIR != 0 ]]; then
git-home remote add origin https://gitlab.maxregan.me/max/configs.git
git-home branch master --set-upstream-to origin/master
git-home config status.showUntrackedFiles no
git-home submodule update --init --recursive
fi
echo "Checking out configs."

View File

@@ -0,0 +1,10 @@
gitlab_start_log_section() {
NAME="$1"
HEADER="$2"
echo -e "\e[0Ksection_start:`date +%s`:${NAME}\r\e[0K${HEADER}"
}
gitlab_end_log_section() {
NAME="$1"
echo -e "\e[0Ksection_end:`date +%s`:${NAME}\r\e0K"
}

17
.mgr_config/tests/test-emacs.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/bash
set -e -o pipefail
SRC_ROOT="$(dirname "${BASH_SOURCE}")"
source "$SRC_ROOT/gitlab-utils.sh"
# Load emacs
gitlab_start_log_section "test_init" "Running Emacs"
emacs --batch --debug-init -l ./.emacs.d/init.el
gitlab_end_log_section "test_init"
# Run tests
gitlab_start_log_section "run_unit_tests" "Running Unit Tests"
emacs --batch --debug-init -l ert -l ./.emacs.d/init.el -f ert-run-tests-batch-and-exit
gitlab_end_log_section "run_unit_tests"

76
.py-env.py Normal file
View File

@@ -0,0 +1,76 @@
import itertools
import json
import operator
import os
import sys
import yaml
from functools import partial, reduce
from math import *
from pathlib import Path
from itertools import chain
try:
from tabulate import tabulate
except ImportError:
pass
try:
import rich
from rich import inspect, print as pp
except ImportError:
pass
# Always write heavyweight/blocking code in this file lazily to keep startup
# time short. In the same vein, be careful not to consume stdin unless an object
# in this file is called or iterated upon, e.g. stdin_str()
# Returns a lazily-evaluable map which executes multiple map functions
def maps(items, *map_funs):
it = items
for func in map_funs:
it = map(func, it)
return it
# Returns a lazily-evaluable filter which executes multiple predicate functions
def filters(items, *pred_funs):
it = items
for pred in pred_funs:
it = filter(pred, it)
return it
# Concatenate two items, there's likely a safer way to do this to avoid summing ints
concat = lambda a, b: "".join([a, b])
# Joins an interable of strings
join = "".join
# Return an iterable for file. This doesn't close the handle, but for this
# little scripting interface this is fine.
def read(filename):
return open(filename, "r")
def read_str(filename):
return concats(read(filename))
stdin_str = sys.stdin.read
# An iterable which yields the characters of stdin
stdin = (c for l in sys.stdin for c in l)
# An iterable which yields the lines of stdin
lines = map(str.strip, sys.stdin)
# An iterable which yields integers supplied via stdin lines
ints = map(int, lines)
# An iterable which yields the bytes of stdin
byts = map(lambda x: bytes(x, "utf-8"), stdin) # better name? 'bytes' is taken
jr = json.loads
jw = json.dumps
yr = lambda x: yaml.load(x, Loader=yaml.SafeLoader)
yw = yaml.dump
pwd = Path.cwd()