Compare commits

..

2 Commits

Author SHA1 Message Date
earnest ma 3d6356bb02
gpg/ git over ssh 2022-04-13 12:21:36 -04:00
earnest ma c735cfa42f
cargo 2022-04-13 12:14:53 -04:00
41 changed files with 199 additions and 1015 deletions

View File

@ -1,4 +0,0 @@
# Do not edit this file. To specify the files to encrypt, create your own
# .gitattributes file in the directory where your files are.
* !filter !diff
*.gpg binary

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
+mail.el filter=git-crypt diff=git-crypt
.mbsyncrc filter=git-crypt diff=git-crypt

157
Brewfile
View File

@ -1,123 +1,32 @@
tap "b3z/small"
tap "cooklang/tap"
tap "gitea/tap", "https://gitea.com/gitea/homebrew-gitea"
tap "gromgit/fuse"
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-fonts"
tap "homebrew/services"
tap "homebrew/core"
tap "railwaycat/emacsmacport"
tap "zegervdv/zathura"
brew "ansible"
brew "black"
brew "yamllint"
brew "ansible-lint"
brew "libtiff"
brew "webp"
brew "jpeg-xl"
brew "open-mpi"
brew "openblas"
brew "arpack"
brew "autoconf"
brew "automake"
brew "bandcamp-dl"
brew "bat"
brew "pkg-config"
brew "python@3.9"
brew "clang-format"
brew "cmake"
brew "coreutils"
brew "curl"
brew "direnv"
brew "dos2unix"
brew "editorconfig"
brew "ghostscript"
brew "exa"
brew "fd"
brew "unbound"
brew "leptonica"
brew "libarchive"
brew "pango"
brew "rubberband"
brew "sdl2"
brew "tesseract"
brew "ffmpeg"
brew "netpbm"
brew "fswatch"
brew "fzf"
brew "ghq"
brew "git"
brew "git-crypt"
brew "git-gui"
brew "gsettings-desktop-schemas"
brew "glib-networking"
brew "gnupg"
brew "gpgme"
brew "gnuplot"
brew "go"
brew "gobject-introspection"
brew "graphicsmagick"
brew "gtk+3"
brew "gtk4"
brew "libsoup"
brew "py3cairo"
brew "pygobject3"
brew "gstreamer"
brew "helix"
brew "htop"
brew "hugo"
brew "libheif"
brew "imagemagick"
brew "isync"
brew "python@3.10"
brew "jsonschema"
brew "just"
brew "lychee"
brew "mailutils"
brew "mercurial"
brew "meson"
brew "vapoursynth"
brew "yt-dlp"
brew "mpv"
brew "msmtp"
brew "mu"
brew "nano"
brew "neovim"
brew "node"
brew "onefetch"
brew "openjdk"
brew "openjdk@17"
brew "pandoc"
brew "php@7.4"
brew "pinentry-mac"
brew "virtualenv"
brew "poetry"
brew "poppler"
brew "pympress"
brew "qt@5"
brew "pyright"
brew "python-tk@3.11"
brew "r"
brew "rbenv"
brew "restic"
brew "python@3.9"
brew "ripgrep"
brew "rsync"
brew "rust-analyzer"
brew "rustup-init"
brew "sdl2_image"
brew "sdl2_mixer"
brew "sdl2_ttf"
brew "shellcheck"
brew "stow"
brew "tmux"
brew "w3m"
brew "wakatime-cli"
brew "yarn"
brew "zoxide"
brew "zsh"
brew "gitea/tap/tea"
brew "railwaycat/emacsmacport/emacs-mac"
cask "activate"
cask "alt-tab"
cask "alacritty"
cask "authy"
cask "buckets"
cask "calibre"
@ -130,72 +39,16 @@ cask "gpg-suite"
cask "hiddenbar"
cask "iina"
cask "imageoptim"
cask "iterm2"
cask "jellyfin-media-player"
cask "joplin"
cask "keka"
cask "lagrange"
cask "maccy"
cask "mactex"
cask "mouse-fix"
cask "nextcloud"
cask "obs"
cask "obsidian"
cask "pocket-casts"
cask "pycharm"
cask "qbittorrent"
cask "rectangle"
cask "skim"
cask "spotify"
cask "syntax-highlight"
cask "the-unarchiver"
cask "thunderbird"
cask "visual-studio-code"
cask "todoist"
cask "zoom"
vscode "aaronduino.gemini"
vscode "arrterian.nix-env-selector"
vscode "bbenoist.Nix"
vscode "bierner.docs-view"
vscode "CharlieGerard.pride-vscode-themes"
vscode "dracula-theme.theme-dracula"
vscode "EditorConfig.EditorConfig"
vscode "floookay.vscode-wpm-monitor"
vscode "FordLabs.flux"
vscode "funketh.pride-themes"
vscode "golang.go"
vscode "hangxingliu.vscode-systemd-support"
vscode "icrawl.discord-vscode"
vscode "jdinhlife.gruvbox"
vscode "kahole.magit"
vscode "leighlondon.eml"
vscode "lmcarreiro.vscode-smart-column-indenter"
vscode "marchrock.vscode-ghq"
vscode "mattn.Lisp"
vscode "mhutchie.git-graph"
vscode "ms-azuretools.vscode-docker"
vscode "ms-python.isort"
vscode "ms-python.python"
vscode "ms-python.vscode-pylance"
vscode "ms-vscode-remote.remote-ssh"
vscode "ms-vscode-remote.remote-ssh-edit"
vscode "ms-vscode.makefile-tools"
vscode "ms-vscode.remote-explorer"
vscode "ms-vsliveshare.vsliveshare"
vscode "nico-castell.linux-desktop-file"
vscode "redhat.java"
vscode "Rubymaniac.vscode-direnv"
vscode "rust-lang.rust-analyzer"
vscode "tamasfe.even-better-toml"
vscode "technosophos.vscode-make"
vscode "timonwong.shellcheck"
vscode "usernamehw.errorlens"
vscode "VisualStudioExptTeam.intellicode-api-usage-examples"
vscode "VisualStudioExptTeam.vscodeintellicode"
vscode "vscjava.vscode-java-debug"
vscode "vscjava.vscode-java-dependency"
vscode "vscjava.vscode-java-pack"
vscode "vscjava.vscode-java-test"
vscode "vscjava.vscode-maven"
vscode "WakaTime.vscode-wakatime"
vscode "yzhang.markdown-all-in-one"
vscode "zeshuaro.vscode-python-poetry"

View File

@ -1,4 +1,6 @@
earnest's public license (EMPL), v1.0.1
earnest's public license (EMPL), v1.0.0
Copyright (c) 2021-2022 earnest ma <me@earne.link>
This license gives everyone as much permission to work with this software as
possible, while protecting contributors from liability.
@ -25,8 +27,7 @@ Notices:
- You must ensure that everyone who gets a copy of any part of this software
from you, with or without changes, also gets the text of this license or a
link to <https://files.earne.link/empl>. An acknowledgement of the original
software is appreciated, but not mandatory.
link to <https://earnestma.com/projects/empl>.
If anyone notifies you in writing that you have not complied with Notices, you
can keep your license by taking all practical steps to comply within 30 days

View File

@ -1,15 +1,7 @@
# Dotfiles
These dotfiles are managed using GNU Stow and I use them on my systems running either macOS or Fedora 36 (Workstation Edition).
These dotfiles are managed using GNU Stow and I use them on my laptop running Fedora 35.
## Usage
MacOS: Install Homebrew and check the Brewfile.
Linux: Refer to [this page](https://notes.earnestma.com/notes/Linux+Computer+Setup+Guide) or the (outdated) [ansible repository](https://git.earne.link/earnestma/configs) for installing and configuring the system.
To use, clone the repository to `~/.dotfiles`, use `stow */ -[D]v` to create/ remove all the links.
# Hacks
For Git, if you have local hooks, set `core.hooksPath` to `.git/hooks`, the global ones will not be run.
Refer to my [ansible repository](https://git.earne.link/earnestma/configs) for installing and configuring the system. To use, clone the repository to `~/.dotfiles`, use `stow */ -[D]v` to create/ remove all the links.

View File

@ -1,61 +0,0 @@
#!/usr/bin/env bash
# From https://gist.github.com/dshnkao/10865f32d69e40dc591e08e3af970e9d
tmpfile=$(mktemp /tmp/ffhist.XXXXX)
cp -f ~/Library/Application\ Support/Firefox/Profiles/qdk1f64u.default-release/places.sqlite $tmpfile
DB_PATH="$tmpfile"
# Relying on rofi / fzf is a bit limited
# e.g
# umenu "places.sqlite" "rofi -dmenu --no-sort"
# umenu "places.sqlite" "fzf --no-sort --exact"
# DB_PATH=${1:?ARG 1: path to firefox database}
FINDER=fzf
# FINDER=${2:?ARG 2: fzf or rofi}
QUERY="
SELECT
url, title FROM moz_places
WHERE
url NOT LIKE '%google%search%'
ORDER BY
visit_count DESC,
last_visit_date DESC;
"
SEP="∙"
ENTRY=$(
sqlite3 "$DB_PATH" "$QUERY" | \
sed -E 's/^https?:\/\///' | \
sed -E "s/\\/?\\|/ $SEP /" | \
sed -E "s/$SEP $//" | \
$FINDER
)
URL=$( echo "$ENTRY" | sed "s/$SEP.*//g" )
if [ "$URL" = "" ]; then
exit 0
fi
# google search if input end with .
if [ "${URL: -1}" = "." ]; then
SEARCH="${URL:: -1}"
URL="google.com/search?q=$SEARCH"
fi
case $(uname) in
'Linux')
xdg-open "https://$URL"
;;
'Darwin')
open "https://$URL"
;;
esac
rm "$tmpfile"

View File

@ -1,314 +0,0 @@
#!/usr/bin/env bash
# https://github.com/ianthehenry/sd
# ecd1ab8d3fc3a829d8abfb8bf1e3722c9c99407b
__sd_join_path() {
echo "$@" | tr ' ' /
}
__sd_which() {
echo "$1"
}
__sd_cat() {
${SD_CAT:-cat} "$1"
}
__sd_edit() {
${SD_EDITOR:-${VISUAL:-${EDITOR:-vi}}} "$1"
}
__sd_directory_help() {
local target="$1"
local i file helpfile help command
local -a commands helps
if [[ -d "$target" ]]; then
helpfile="$target/help"
else
helpfile="$target.help"
fi
# in case you have `sd help` as a command alias, we don't
# want to print that when you just run "sd" by itself.
# Admittedly we don't check this in any other place, which
# could be considered a bug, but whatever it's a weird little
# hack and no one uses this.
if [[ -e "$helpfile" && ! -x "$helpfile" ]]; then
__sd_cat "$helpfile"
echo
else
command=$(basename "$target")
echo "$command commands"
echo
fi
commands=()
helps=()
for file in "$target"/*; do
if [[ ! -x "$file" ]]; then
continue
fi
command=$(basename "$file")
if [[ -d "$file" ]]; then
helpfile="$file/help"
if [[ -f "$helpfile" ]]; then
help=$(head -n1 "$helpfile")
else
help="$command commands"
fi
command="$command ..."
else
helpfile="$file.help"
if [[ -f "$helpfile" ]]; then
help=$(head -n1 "$helpfile")
else
help=$(sed -nE -e '/^#!/d' -e '/^#/{s/^# *//; p; q;}' "$file")
fi
fi
commands+=("$command")
helps+=("$help")
done
if [[ ${#commands[@]} -eq 0 ]]; then
echo "(no subcommands found)"
else
local max_length=0
local length
for command in "${commands[@]}"; do
length=${#command}
max_length=$((length > max_length ? length : max_length))
done
if [[ -n ${ZSH_EVAL_CONTEXT+x} ]]; then
set -o LOCAL_OPTIONS
# we need to ensure we have 0-indexed arrays
# in order for this loop to work properly.
# zsh doesn't support ${!commands[@]} expansion
set -o KSH_ARRAYS
fi
for ((i = 0; i < ${#commands[@]}; i++)); do
printf "%-${max_length}s -- %s\n" "${commands[i]}" "${helps[i]}"
done
fi
}
__sd_help() {
local target=$1
if [[ -d "$target" ]]; then
__sd_directory_help "$target"
elif [[ -f "$target.help" ]]; then
__sd_cat "$target.help"
else
help=$(sed -nE -e '/^#!/d' -e $':start\n /^#/{ s/^# ?//; p; \nb start\n }' "$target")
if [[ -z "$help" ]]; then
echo "there is no help for you here" >&2
exit 1
else
echo "$help"
fi
fi
}
__sd_print_template() {
if [[ -f "$1/template" ]]; then
cat "$1/template"
else
if [[ "$1" = "${SD_ROOT:-$HOME/sd}" ]]; then
cat <<EOF
#!/usr/bin/env bash
set -euo pipefail
EOF
else
__sd_print_template "$(dirname "$1")"
fi
fi
}
__sd_new() {
local script dir target body
target="$1"
shift
local -a command_path=()
for arg in "$@"; do
case "$arg" in
--new) shift; break ;;
*) command_path+=("$arg"); shift ;;
esac
done
if [[ ${#command_path[@]} -eq 0 ]]; then
echo "error: $target already exists" >&2
exit 1
fi
if [[ -f "$target" ]]; then
echo "error: command prefix $target is a regular file" >&2
exit 1
fi
body="$*"
script="$target"/"$(__sd_join_path "${command_path[@]}")"
if [[ -e "$script" ]]; then
echo "$script already exists!" >&2
exit 1
fi
dir="$(dirname "$script")"
mkdir -p "$dir"
(
__sd_print_template "$dir"
if [[ -n "$body" ]]; then
printf "\n%s\n" "$body"
fi
) >"$script"
chmod +x "$script"
if [[ -z "$body" ]]; then
__sd_edit "$script"
fi
}
__sd_new_user_help() {
root=$1
echo >&2 "error: $root not found"
echo >&2
echo >&2 "It looks like you don't have a script directory yet!"
echo >&2
echo >&2 "Get started by creating your first script:"
echo >&2
echo >&2 " sd hello --new 'echo \"Hello, sd!\"'"
echo >&2
echo >&2 "And then run it like this:"
echo >&2
echo >&2 " sd hello"
}
__sd() {
set -euo pipefail
local root=${SD_ROOT:-$HOME/sd}
if [[ -e "$root" && ! -d "$root" ]]; then
echo "error: $root is not a directory" >&2
exit 1
fi
local target=$root
local arg
while [[ $# -gt 0 ]]; do
arg="$1"
if [[ -d "$target/$arg" ]]; then
target="$target/$arg"
shift
elif [[ -f "$target/$arg" ]]; then
target="$target/$arg"
shift
break
else
break
fi
done
local found_help="false"
local found_new="false"
local found_edit="false"
local found_cat="false"
local found_which="false"
local found_really="false"
for arg in "$@"; do
case "$arg" in
--help) found_help=true ;;
--new) found_new=true ;;
--edit) found_edit=true ;;
--cat) found_cat=true ;;
--which) found_which=true ;;
--really) found_really=true ;;
esac
done
# you're allowed to run --new even if there is no
# script directory root, in order to bootstrap it
if [[ "$found_really" = "true" || "$found_new" = "false" ]]; then
if [[ ! -d "$root" ]]; then
__sd_new_user_help "$root"
exit 1
fi
fi
if [[ "$found_really" = "true" ]]; then
local -a preserved=()
for arg in "$@"; do
case "$arg" in
'--really') shift; break ;;
*) preserved+=("$arg"); shift ;;
esac
done
if [[ ${#preserved[@]} -gt 0 ]]; then
set -- "${preserved[@]}" "$@"
fi
elif [[ "$found_new" = "true" ]]; then
__sd_new "$target" "$@"
exit 0
elif [[ "$found_help" = "true" ]]; then
__sd_help "$target"
exit 0
elif [[ "$found_edit" = "true" ]]; then
__sd_edit "$target"
exit 0
elif [[ "$found_cat" = "true" ]]; then
__sd_cat "$target"
exit 0
elif [[ "$found_which" = "true" ]]; then
__sd_which "$target"
exit 0
fi
if [[ -d "$target" ]]; then
__sd_directory_help "$target"
if [[ $# -gt 0 ]]; then
echo >&2
echo "$target/$(__sd_join_path "$@") not found" >&2
exit 1
fi
elif [[ -x "$target" ]]; then
SD="$(dirname "$target")" exec "$target" "$@"
else
__sd_cat "$@"
fi
}
# If you source this file and use function-mode sd, we want to
# wrap the execution in a subshell so that set -e doesn't kill
# the interactive shell, and so that we can exec the subshell
# without destroying the interactive shell.
sd() (
__sd "$@"
)
# If you source this file, it will define the function sd,
# which you can use from your shell. If you *run* this file
# as an executable, it will just invoke that function. We
# have to do some tricks to detect that reliably on bash/zsh.
if [[ -n ${ZSH_EVAL_CONTEXT+x} ]]; then
# we are in zsh
if [[ "$ZSH_EVAL_CONTEXT" = toplevel ]]; then
__sd "$@"
fi
elif [[ -n ${BASH_SOURCE[0]+x} ]]; then
# we are in bash
if [[ "${BASH_SOURCE[0]}" = "$0" ]]; then
__sd "$@"
fi
fi

View File

@ -1,16 +0,0 @@
#!/usr/bin/env bash
# Send secrets from certain files to another trusted device.
# WILL NOT DELETE FILES, BUT WILL OVERWRITE!
set -x
if [[ -z $1 ]]; then
echo "Missing user@host to send to"
exit 2
fi
files="$HOME/.ssh $HOME/.gnupg $HOME/.wakatime.cfg"
rsync -rav \
--exclude="$HOME/.ssh/id_*" --exclude="*.sock" \
$files "${1}:"

View File

@ -1,7 +0,0 @@
#!/usr/bin/env sh
if [ -z "$1" ]; then
exit 1
fi
yt-dlp "$1" --write-subs

View File

@ -0,0 +1,20 @@
;;; ../../.dotfiles/doom/.config/doom/+elfeed.el -*- lexical-binding: t; -*-
;;; Thanks https://github.com/alrayyes/dotfiles/blob/master/emacs/.config/doom/config.org#elfeed
(use-package! elfeed
:defer t
:config
(setq elfeed-use-curl t)
(elfeed-set-timeout 36000)
(setq elfeed-protocol-ttrss-maxsize 200) ; bigger than 200 is invalid
(elfeed-protocol-enable)
(setq elfeed-feeds (list
(list "ttrss+https://earne@rss.tildeverse.org"
:password (shell-command-to-string "echo -n `pash show rss`"))))
(add-hook! 'elfeed-search-mode-hook 'elfeed-update))
(use-package! elfeed-goodies
:after elfeed
:config
(elfeed-goodies/setup))

View File

@ -1,12 +0,0 @@
;;; ../../.dotfiles/doom/.config/doom/+ess.el -*- lexical-binding: t; -*-
;; https://github.com/polymode/poly-R/issues/34
(setq polymode-lsp-integration nil)
(use-package! ess-view
:after ess
:config
(setq ess-view--spreadsheet-program "open"))
(use-package! ess-view-data
:after ess)

Binary file not shown.

View File

@ -1,36 +1,19 @@
;;; $DOOMDIR/+projects.el -*- lexical-binding: t; -*-
;;; ../../.dotfiles/doom/.config/doom/+projects.el -*- lexical-binding: t; -*-
;;; Project management
(defvar project-locations '(("~/ghq/" . 3)
("~/.dotfiles" . 0)
("~/configs" . 0))
("~/ansible" . 0))
"Where all my projects are located.
Most of them are managed using `ghq' in ~/ghq/, however there are also some
projects in other locations.")
(use-package! projectile
:init
(setq projectile-auto-discover t)
(after! projectile
(setq projectile-project-search-path project-locations))
(use-package! treemacs
:init
(setq treemacs-missing-project-action 'remove)
:config
(treemacs-project-follow-mode +1)
(treemacs-hide-gitignored-files-mode +1))
(after! treemacs
(define-key treemacs-mode-map [mouse-1] #'treemacs-single-click-expand-action))
(use-package treemacs-persp ;;treemacs-perspective if you use perspective.el vs. persp-mode
:after (treemacs persp-mode) ;;or perspective vs. persp-mode
:ensure t
:config (treemacs-set-scope-type 'Perspectives))
(after! magit
(add-hook! 'after-save-hook #'magit-after-save-refresh-status)
(setq magit-save-repository-buffers t ; ask to save modified files in repo
(setq magit-save-repository-buffers t
magit-repository-directories project-locations))
(use-package! ghq)

View File

@ -0,0 +1,12 @@
;;; ../../.dotfiles/doom/.config/doom/+smudge.el -*- lexical-binding: t; -*-
(use-package! smudge
;; Do not load and error if credentials are not set
;; if client secret is bound, then client id should be fine as well
;; in $DOOM_DIR/.local.el:
;; (setq smudge-oauth2-client-id ""
;; smudge-oauth2-client-secret "")
:if (boundp 'smudge-oauth2-client-secret)
:config
(global-smudge-remote-mode)
(map! :map smudge-mode-map "M-p" #'smudge-command-map))

View File

@ -1,67 +1,49 @@
;;; $DOOMDIR/+ui.el -*- lexical-binding: t; -*-
;;; ../../.dotfiles/doom/.config/doom/+ui.el -*- lexical-binding: t; -*-
;;; UI Adjustments
;; Font!
;; Doom exposes five (optional) variables for controlling fonts in Doom:
;;
;; - `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
(setq doom-font (font-spec :family "Jetbrains Mono" :size 13))
(if (string-match "tycho" (system-name))
(setq doom-font (font-spec :family "Jetbrains Mono" :size 18)))
;; Theme
(setq doom-theme 'doom-gruvbox)
;; Display
(setq display-line-numbers-type 'relative)
(menu-bar-mode +1) ; add back menu bar
(setq display-line-numbers-type 'relative) ; line numbers
;; slightly nicer default buffer names
(setq doom-fallback-buffer-name "► Doom"
+doom-dashboard-name "► Doom")
;; pop-ups
(setq which-key-idle-delay 0.25)
;; Frames and windows
;; Move to split window
(setq evil-vsplit-window-right t
evil-split-window-below t)
;; centaur tabs issue: https://github.com/ema2159/centaur-tabs/issues/181
(after! centaur-tabs
(centaur-tabs-group-by-projectile-project))
;; Modeline
(setq display-time-day-and-date t)
(display-time-mode +1) ; show the time
;; From Tecosaur's config: hide encoding in modeline if usual
;; show battery level (when on a laptop)
;; (unless (string-match-p "^Power N/A" (battery))
;; (display-battery-mode 1))
;; From Tecosaur's config: hide encoding when it's what's expected
(defun doom-modeline-conditional-buffer-encoding ()
"We expect the encoding to be LF UTF-8, so only show the modeline
when this is not the case"
"We expect the encoding to be LF UTF-8, so only show the modeline when this is not the case"
(setq-local doom-modeline-buffer-encoding
(unless (and (memq (plist-get (coding-system-plist buffer-file-coding-system) :category)
'(coding-category-undecided coding-category-utf-8))
(not (memq (coding-system-eol-type buffer-file-coding-system) '(1 2))))
t)))
(add-hook 'after-change-major-mode-hook #'doom-modeline-conditional-buffer-encoding)
;; https://github.com/doomemacs/doomemacs/issues/314
(after! doom-modeline
(setq doom-modeline-persp-name t))
;; pdf-tools
;; Always use midnight view with pdf-tools
(add-hook 'pdf-tools-enabled-hook 'pdf-view-midnight-minor-mode)
;; Also from Tecosaur's config (modified slightly): better window title
(setq frame-title-format
'(""
"%b" ; removed the org-roam part
(:eval
(let ((project-name (projectile-project-name)))
(unless (string= "-" project-name)
(format (if (buffer-modified-p) " ◉ %s" "  ●  %s") project-name))))))
;; emojify: Was a workaround for
;; https://github.com/iqbalansari/emacs-emojify/issues/100, but keep for
;; simplicity.
(setq emojify-download-emojis-p t)
(setq emojify-emoji-set "twemoji-v2")
(setq eros-eval-result-prefix " ") ; default =>
;; (use-package auto-dark
;; :config
;; (setq auto-dark-allow-osascript t)
;; (setq auto-dark-dark-theme 'doom-gruvbox)
;; (setq auto-dark-light-theme 'doom-gruvbox-light)
;; (auto-dark-mode t))

View File

@ -4,8 +4,6 @@
- Build: `~/.config/emacs/bin/doom sync`
- See if you're missing anything: `doom doctor`
Run `M-x nerd-icons-install-fonts` if there are problems with the modeline: <https://github.com/doomemacs/doomemacs/issues/7368>
Also check out:
- [Tecosaur's literate Doom Emacs configuration](https://github.com/tecosaur/emacs-config)

View File

@ -4,157 +4,12 @@
;; sync' after modifying this file!
(setq user-full-name "earnest ma"
user-mail-address "me@earne.link")
user-mail-address "me@earne.link"
org-directory "~/org/")
;; 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/")
(load! ".local" doom-private-dir t)
(load! ".local" doom-user-dir t)
(load! "+ui") ; theme, font, and appearance tweaks
(load! "+projects") ; project-related
(load! "+ess") ; ess, R
(load! "+mail") ; mu4e
;; Defaults
(setq-default delete-by-moving-to-trash t)
(setq undo-limit 80000000 ; 80Mb
evil-want-fine-undo t ; more history when in insert mode
evil-split-window-below t ; switch to window after creation
evil-vsplit-window-right t
evil-kill-on-visual-paste nil ; copy pasting
truncate-string-ellipsis "" ; Unicode ellispis are nicer than "...", and also save /precious/ space
password-cache-expiry nil ; don't expire
)
(global-subword-mode 1) ; Iterate through CamelCase words
(map! :leader
"b q" #'kill-buffer-and-window
"c m" #'justl-exec-recipe-in-dir)
;; speed-type
(use-package! speed-type)
;; company
(after! company
(setq company-idle-delay 0.2
company-minimum-prefix-length 3
;; doesn't show in childframe, but might be useful in terminal
company-show-quick-access 1))
(setq lsp-clients-clangd-args '("-j=3"
"--background-index"
"--clang-tidy"
"--completion-style=detailed"
"--header-insertion=never"
"--header-insertion-decorators=0"))
(after! lsp-clangd (set-lsp-priority! 'clangd 2))
;; pinentry for emacs ssh gpg
(use-package! pinentry
:init (setq epg-pinentry-mode `loopback)
(pinentry-start))
;; pandoc mode
;; use C-c / after (pandoc-mode)
(use-package! pandoc-mode)
;; Wakatime mode
(use-package! wakatime-mode
:config
(global-wakatime-mode))
;; Bind SPC s c to clear evil search
(map! :leader
:desc "Clear recent search result"
"s c" #'evil-ex-nohighlight)
(use-package! redacted)
;; :config
;; (add-hook 'redacted-mode-hook (lambda () (read-only-mode (if redacted-mode 1 -1)))))
;; disable tidy
(add-to-list '+format-on-save-disabled-modes 'web-mode :append)
;; (add-hook 'nim-mode-local-vars-hook #'lsp!)
(use-package! subed
:config
;; This assures evil does not conflict with subed keybinds.
;; https://github.com/haditim/.doom.d
(map! :map (subed-mode subed-srt-mode-map)
:n "M-p" #'subed-backward-subtitle-text
:n "M-n" #'subed-forward-subtitle-text
:leader
:desc "MPV play/pause" "<RET>" #'subed-mpv-toggle-pause))
;; NOTE I use Skim on MacOS and pdf-tools on Linux infrequently. Consider
;; "p d f modeline" from tecosaur's config
(defun open-in-pympress ()
"Open the current buffer (assumed to be a tex file that has the same name as
the compiled PDF version) in pympress."
(interactive)
(start-process "pympress" nil "pympress" (replace-regexp-in-string "\.tex" ".pdf" buffer-file-name)))
(add-hook! 'LaTeX-mode-hook #'hl-todo-mode)
(use-package! ispell
:config
(setq ispell-personal-dictionary (expand-file-name "~/.aspell.en.pws"))
(setq ispell-dictionary "en_CA"))
(use-package! w3m)
;; https://github.com/tarsius/keycast/issues/7
(use-package! keycast
:config
(define-minor-mode keycast-mode
"Show current command and its key binding in the mode line (fix for use with doom-mode-line)."
:global t
(if keycast-mode
(add-hook 'pre-command-hook 'keycast--update t)
(remove-hook 'pre-command-hook 'keycast--update)))
(add-to-list 'global-mode-string '("" keycast-mode-line)))
;; yasnippets
(setq yas-triggers-in-field t)
(use-package! edit-server
:config
(edit-server-start))
(defun assignment-ui-start()
"UI modifications when working on assignments (in Python) with long function
headers"
(interactive)
(which-function-mode +1)
(semantic-mode +1)
(semantic-stickyfunc-mode +1))
(defun assignment-ui-stop()
"Disable \'assignment-ui-start\'"
(interactive)
(which-function-mode -1)
(semantic-mode -1)
(semantic-stickyfunc-mode -1))
(setq magit-revision-show-gravatars '("^Author: " . "^Commit: "))
;; https://arjenwiersma.nl/posts/cleaning-up-lsp-mode/
(defun aw/cleanup-lsp ()
"Remove all the workspace folders from LSP"
(interactive)
(let ((folders (lsp-session-folders (lsp-session))))
(while folders
(lsp-workspace-folders-remove (car folders))
(setq folders (cdr folders)))))
(load! "+ui")
;; 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.
@ -187,3 +42,25 @@ headers"
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.
;; Defaults
(setq-default delete-by-moving-to-trash t)
(setq undo-limit 80000000 ; 80Mb
evil-want-fine-undo t ; more history when in insert mode
truncate-string-ellipsis "" ; Unicode ellispis are nicer than "...", and also save /precious/ space
password-cache-expiry nil ; don't expire
)
(global-subword-mode 1) ; Iterate through CamelCase words
(setq which-key-idle-delay 0.25)
(setq company-idle-delay 0.1)
;; speed-type
(use-package! speed-type)
;; load
(load! "+projects")
(load! "+smudge")
(load! "+elfeed")

View File

@ -15,17 +15,16 @@
;; 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
:completion
(company +childframe) ; the ultimate code completion backend
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
(vertico +icons) ; the search engine of the future
vertico ; the search engine of the future
:ui
;;deft ; notational velocity for Emacs
@ -37,14 +36,14 @@
;;hydra
indent-guides ; highlighted indent columns
ligatures ; ligatures and symbols to make your code pretty again
minimap ; show a map of the code on the side
;;minimap ; show a map of the code on the side
modeline ; snazzy, Atom-inspired modeline, plus API
nav-flash ; blink cursor line after big motions
;;neotree ; a project drawer, like NERDTree for vim
ophints ; highlight the region an operation acts on
(popup +defaults) ; tame sudden yet inevitable temporary windows
tabs ; a tab bar for Emacs
(treemacs +lsp) ; a project drawer, like neotree but cooler
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
@ -81,26 +80,25 @@
:checkers
syntax ; tasing you for every semicolon you forget
(spell +flyspell) ; tasing you for misspelling mispelling
;;(spell +flyspell) ; tasing you for misspelling mispelling
;;grammar ; tasing grammar mistake every you make
:tools
ansible
;;ansible
;;biblio ; Writes a PhD for you (citation needed)
;;debugger ; FIXME stepping through code, to help you add bugs
direnv
docker
;;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
just
lookup ; navigate your code and its documentation
(lsp +peek) ; M-x vscode
lsp ; M-x vscode
magit ; a git porcelain for Emacs
make ; run make tasks from Emacs
;;pass ; password manager for nerds
pdf ; pdf enhancements
;;pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
rgb ; creating color strings
;;taskrunner ; taskrunner for all your projects
@ -115,7 +113,7 @@
:lang
;;agda ; types of types of types of types...
;;beancount ; mind the GAAP
(cc +lsp) ; 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
@ -128,36 +126,35 @@
;;elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
;;erlang ; an elegant language for a more civilized age
(ess +lsp) ; emacs speaks statistics
;;ess ; emacs speaks statistics
;;factor
;;faust ; dsp, but you get to keep your soul
;;fortran ; in FORTRAN, GOD is REAL (unless declared INTEGER)
;;fsharp ; ML stands for Microsoft's Language
;;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
;;(go +lsp) ; the hipster dialect
;;(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
json ; At least it ain't XML
(java +lsp) ; the poster child for carpal tunnel syndrome
;;(java +lsp) ; 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
;;latex ; writing papers in Emacs has never been so fun
;;lean ; for folks with too much to prove
;;ledger ; be audit you can be
;;lua ; one-based indices? one-based indices
markdown ; writing docs for people to ignore
nim ; python + lisp at the speed of c
;;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
;;php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional
(python +lsp +pyright +poetry) ; beautiful is better than ugly
(python +poetry +lsp) ; beautiful is better than ugly
;;qt ; the 'cutest' gui framework ever
;;racket ; a DSL for DSLs
;;raku ; the artist formerly known as perl6
@ -178,7 +175,6 @@
:email
;;(mu4e +org +gmail)
(mu4e)
;;notmuch
;;(wanderlust +gmail)
@ -190,6 +186,9 @@
;;(rss +org) ; emacs as an RSS reader
;;twitter ; twitter client https://twitter.com/vnought
:personal
music
:config
;;literate
(default +bindings +smartparens))

View File

@ -0,0 +1,15 @@
;;; personal/music/config.el -*- lexical-binding: t; -*-
(use-package! playerctl
:when (executable-find "playerctl")
:config
;; keybindings
;; k prefix looks like it isn't defined, so let's borrow it for now
(map! :n "SPC k SPC" #'playerctl-play-pause-song
:n "SPC k s" #'playerctl-stop-song
:n "SPC k S" #'playerctl-status
:n "SPC k m" #'playerctl-metadata ; currently broken
:n "SPC k n" #'playerctl-next-song
:n "SPC k N" #'playerctl-seek-forward
:n "SPC k p" #'playerctl-previous-song
:n "SPC k P" #'playerctl-seek-backward))

View File

@ -0,0 +1,4 @@
;;; personal/music/doctor.el -*- lexical-binding: t; -*-
(unless (executable-find "playerctl")
(warn! "Couldn't find playerctl executable"))

View File

@ -0,0 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; personal/music/packages.el
(package! playerctl :pin "4c3a6132616fd28f902590bf6e63332e6055492b")

View File

@ -1,7 +0,0 @@
;;; tools/just/config.el -*- lexical-binding: t; -*-
(use-package! just-mode)
(use-package! justl
:config
(map! :n "e" 'justl-exec-recipe))

View File

@ -1,5 +0,0 @@
;; -*- no-byte-compile: t; -*-
;;; tools/just/packages.el
(package! just-mode :pin "d7f52eab8fa3828106f80acb1e2176e5877b7191")
(package! justl :pin "141daaa4b0dc07fe25423609dcd14441a9f2613e")

View File

@ -48,25 +48,11 @@
;(unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;(unpin! t)
(package! speed-type :pin "5ef695f7159aa1f20c7c9e55f0c39bcdacce8d21")
(package! evil-tutor)
(package! focus)
(package! ghq :pin "582bd6daa505d04c7cc06d6c82ed8aee0624bfbe")
(package! speed-type :pin "304cb8cd6c30d07577d7d864fd32858a29a73dba")
(package! pinentry)
(package! redacted)
(package! subed
:recipe (:host github :repo "sachac/subed"
:files ("subed/*.el")))
(package! cook-mode
:recipe (:host github :repo "cooklang/cook-mode"))
(package! ess-view)
(package! ess-view-data)
(package! keycast
:recipe (:host github :repo "tarsius/keycast"
:branch "main"))
(package! pandoc-mode)
(package! wakatime-mode)
(package! w3m)
(package! edit-server)
(package! auto-dark)
(package! smudge :pin "9e3488f485b7d7f3c97ebaad34ed552bb0cc228a")
(package! elfeed :pin "162d7d545ed41c27967d108c04aa31f5a61c8e16")
(package! elfeed-protocol :pin "d2e22f5506bc75dbf4ca42ac87257fd1b259dd66")
(package! elfeed-goodies :pin "6711de66c22360f80fcfd9730293e5f3d419f787")

View File

@ -1,5 +0,0 @@
# -*- mode: snippet -*-
# name: Relates-to: ...
# key: rel
# --
Relates-to: [${0}]

View File

@ -1,7 +0,0 @@
# -*- mode: snippet -*-
# name: checkmark
# uuid:
# key: checkmark
# condition: t
# --
\textcircled{$\checkmark$}

View File

@ -1,7 +0,0 @@
# -*- mode: snippet -*-
# name: emoji
# uuid: emoji
# key: emoji
# condition: t
# --
{\Large \texttwemoji{${1:emoji}}}

View File

@ -1,7 +0,0 @@
# -*- mode: snippet -*-
# name: "rightarrow"
# uuid:
# key: rarr
# condition: t
# --
\rightarrow

View File

@ -1,5 +0,0 @@
# -*- mode: snippet -*-
# name: one-to-one
# key: oto
# --
one-to-one

View File

@ -1,15 +0,0 @@
#!/usr/bin/env bash
old_kernels=($(dnf repoquery --installonly --latest-limit=-1 -q))
if [ "${#old_kernels[@]}" -eq 0 ]; then
echo "No old kernels found"
exit 0
fi
if ! dnf remove "${old_kernels[@]}"; then
echo "Failed to remove old kernels"
exit 1
fi
echo "Removed old kernels"
exit 0

View File

@ -31,17 +31,16 @@
[commit]
gpgsign = true
verbose = true
[fetch]
prune = true
[pull]
# ff = only
rebase = true
ff = only
[push]
default = current
autoSetupRemote = true
[status]
submodulesummary = true
@ -82,5 +81,3 @@
[credential]
helper = store --file ~/.config/git/credentials
[rebase]
updateRefs = true

View File

@ -1,8 +1,4 @@
#!/usr/bin/env bash
### lolcommits hook (begin) ###
LANG="en_CA.UTF-8" && PATH="$PATH:/Users/earne/.rbenv/versions/3.1.2/bin:/opt/homebrew/bin" && if [ ! -d "$GIT_DIR/rebase-merge" ] && [ "$LOLCOMMITS_CAPTURE_DISABLED" != "true" ] && [ "$HOST" = "blahaj.local" ]; then lolcommits --capture ; fi
### lolcommits hook (end) ###
COMMIT_INFO=$(git log -1 HEAD --format=reference)
[ $(uname -s) = "Linux" ] && [ -z $DISPLAY ] || notify-send 'Git commit: ' "$COMMIT_INFO" -u low
notify-send 'Git commit: ' "$COMMIT_INFO" -u low

View File

@ -2,9 +2,4 @@
# gpg-connect-agent reloadagent /bye
default-cache-ttl 86400
max-cache-ttl 86400
# pinentry-program /usr/bin/pinentry-gnome3
# macos
# pinentry-program /opt/homebrew/bin/pinentry-mac
# idk if this needs to be adjusted for macos
allow-emacs-pinentry
allow-loopback-pinentry
pinentry-program /usr/bin/pinentry-gnome3

Binary file not shown.

View File

@ -1,19 +1,26 @@
set showmatch " show matching () {}
set nocompatible
set showmatch " show matching
set ignorecase " case insensitive
set mouse=v " middle-click paste
" search: highlight, incremental
set hlsearch
set incsearch
set tabstop=4
set softtabstop=4
set expandtab
set shiftwidth=4
set autoindent
set number " current line number
set relativenumber " relative numbering
set number
set wildmode=longest,list
set cc=80
filetype plugin indent on
syntax on
set mouse=a " enable mouse click
set clipboard=unnamedplus " using system clipboard
@ -30,48 +37,25 @@ endif
call plug#begin(stdpath('data') . '/plugged')
Plug 'dracula/vim', { 'as': 'dracula' }
Plug 'tpope/vim-sensible'
Plug 'nvim-lua/plenary.nvim'
Plug 'TimUntersberger/neogit'
Plug 'tpope/vim-fugitive'
Plug 'tpope/vim-surround'
Plug 'tpope/vim-commentary'
Plug 'editorconfig/editorconfig-vim'
Plug 'wakatime/vim-wakatime'
call plug#end()
colorscheme dracula
" https://github.com/henrik/vim-reveal-in-finder/blob/master/plugin/reveal_in_finder.vim
function! s:RevealInFinder()
if filereadable(expand("%"))
let l:command = "open -R " . shellescape("%")
elseif getftype(expand("%:p:h")) == "dir"
let l:command = "open " . shellescape("%") . ":p:h"
else
let l:command = "open ."
endif
execute ":silent! !" . l:command
" For terminal Vim not to look messed up.
redraw!
endfunction
command! Reveal call <SID>RevealInFinder()
" Auto close, Ctrl-v to not do
ino " ""<left>
ino ' ''<left>
ino ( ()<left>
ino [ []<left>
ino { {}<left>
ino {<CR> {<CR>}<ESC>O
lua <<EOF
local neogit = require('neogit')
neogit.setup {
disable_commit_confirmation = true,
disable_insert_on_commit = true
}
EOF
:nmap <C-x>g :Neogit<CR>
" no ex mode
nnoremap Q <Nop>

View File

@ -47,7 +47,7 @@ foldersize(){
}
e(){
emacsclient -a "emacs" $@
emacsclient -a "" $@
}
# Easy way to create/ connect to a tmux session

View File

@ -1 +1,2 @@
. $HOME/.zprofile
. "$HOME/.cargo/env"

View File

@ -1,12 +0,0 @@
[Unit]
Description=code-server
After=network.target
[Service]
Type=exec
Environment=EXTENSIONS_GALLERY='{ "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery", "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index", "itemUrl": "https://marketplace.visualstudio.com/items", "controlUrl": "", "recommendationsUrl": "" }'
ExecStart=/usr/bin/code-server
Restart=always
[Install]
WantedBy=default.target

View File

@ -22,30 +22,15 @@ pathadd_head '/tmp/bin'
pathadd_head "$HOME/.config/emacs/bin"
if [[ $HOST == "core.envs.net" ]]; then
pathadd_tail '/envs/bin'
pathadd_head "$HOME/public_html/files/bin"
pathadd_tail '/envs/bin'
pathadd_head "$HOME/public_html/files/bin"
fi
if [[ $HOST == "tycho" ]]; then
pathadd_tail "$HOME/.wakatime"
fi
# go
pathadd_tail "$HOME/go/bin"
# rust
[ -f $HOME/.cargo/env ] && source $HOME/.cargo/env
# nim
pathadd_tail "$HOME/.nimble/bin"
# Preferences
export CALIBRE_USE_SYSTEM_THEME=0
export CALIBRE_USE_DARK_PALETTE=1
# macOS
[ -f /opt/homebrew/bin/brew ] && eval "$(/opt/homebrew/bin/brew shellenv)"
hash rbenv &>/dev/null && eval "$(rbenv init - zsh)"
export LOLCOMMITS_DELAY=2
# macOS: homebrew
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH

View File

@ -25,7 +25,7 @@ bindkey -s '^L' '^Uclear^M' # clear using alias
autoload edit-command-line; zle -N edit-command-line
bindkey '^k' edit-command-line
# bindkey -s '^f' '^Ufghq^M' # fghq from alias
bindkey -s '^f' '^Ufghq^M' # fghq from alias
# History
HISTORY_IGNORE="(ls|cd|pwd|exit|sudo reboot|history|cd -|cd ..)"
@ -41,7 +41,6 @@ setopt inc_append_history # add commands to HISTFILE in order of execution
setopt share_history # share command history data
setopt hist_find_no_dups # don't display duplicates in reverse search
setopt hist_reduce_blanks # remove superfluous blanks
setopt HIST_IGNORE_SPACE # put a space at the front and you won't record history
setopt interactivecomments # Comments in the interactive shell
setopt auto_continue # Send CONT signal automatically when disowning jobs
@ -71,15 +70,9 @@ if [[ "$HOST" == core.envs.net ]]; then
export GPG_TTY=$(tty)
fi
# tycho (which is a laptop)
#if [[ "$HOST" == tycho && -z "$DISPLAY" ]]; then
# export GPG_TTY=$(tty)
#fi
gpgtemp() {
export GPG_TTY=$(tty)
echo "remember to run gpgyeet once done..."
}
if [[ "$HOST" == tycho && -z "$DISPLAY" ]]; then
export GPG_TTY=$(tty)
fi
# pash configuration
export PASH_KEYID=BF66E5C8A1416E2A857C774CA343F43342EB6E2A
@ -103,19 +96,30 @@ pash() {
esac
}
# GPG: invalidate cache
# GPG: invalidate acahe
gpgyeet() {
echo RELOADAGENT | gpg-connect-agent
unset GPG_TTY
}
# emacs magit
magit() {
emacs --eval "(progn (magit-status) (delete-other-windows))" "$@"
emacs --eval "(progn (magit-status) (delete-other-windows))"
}
# eye candy: auto onefetch (consider if this is really needed lol)
# https://www.reddit.com/r/unixporn/comments/sxa02o/oc_neofetch_for_git_repositories/
LAST_REPO=""
cd(){
builtin cd "$@"
git rev-parse 2>/dev/null
if [ $? -eq 0 ]; then
if [ "$LAST_REPO" != $(basename $(git rev-parse --show-toplevel)) ]; then
onefetch
LAST_REPO=$(basename $(git rev-parse --show-toplevel))
fi
fi
}
# PLUGINS!
# `miniplug update`
@ -127,27 +131,9 @@ miniplug theme 'tjquillan/pastel'
miniplug load
export SD_ROOT="$HOME/.dotfiles/.sd"
export SD_CAT=bat
# auto cd must be set later
setopt AUTO_CD
# Hooks
eval "$(direnv hook zsh)"
eval "$(zoxide init zsh)"
if [[ $HOST == "blahaj.local" ]]; then
export PATH="/usr/local/opt/llvm/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/llvm/lib"
export CPPFLAGS="-I/opt/homebrew/opt/llvm/include"
# -I tells GCC where to look for header files to include
export C_INCLUDE_PATH="${C_INCLUDE_PATH}:/opt/homebrew/include"
export LIBRARY_PATH="${LIBRARY_PATH}:/opt/homebrew/lib"
fi
PATH="/Users/earne/perl5/bin${PATH:+:${PATH}}"; export PATH;
PERL5LIB="/Users/earne/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}"; export PERL5LIB;
PERL_LOCAL_LIB_ROOT="/Users/earne/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}"; export PERL_LOCAL_LIB_ROOT;
PERL_MB_OPT="--install_base \"/Users/earne/perl5\""; export PERL_MB_OPT;
PERL_MM_OPT="INSTALL_BASE=/Users/earne/perl5"; export PERL_MM_OPT;