Compare commits

..

1 commit

Author SHA1 Message Date
Howard Abrams
f8f2be92ff Mostly works.
Magit and other parts, don't.
2025-09-09 11:19:16 -07:00
30 changed files with 405 additions and 522 deletions

View file

@ -8,15 +8,6 @@ A literate programming file for bootstraping my Emacs Configuration.
#+begin_src emacs-lisp :exports none
;;; bootstrap.el --- file for bootstraping my Emacs Configuration
;;
;; ██████████
;; ░░███░░░░░█
;; ░███ █ ░ █████████████ ██████ ██████ █████
;; ░██████ ░░███░░███░░███ ░░░░░███ ███░░███ ███░░
;; ░███░░█ ░███ ░███ ░███ ███████ ░███ ░░░ ░░█████
;; ░███ ░ █ ░███ ░███ ░███ ███░░███ ░███ ███ ░░░░███
;; ██████████ █████░███ █████░░████████░░██████ ██████
;; ░░░░░░░░░░ ░░░░░ ░░░ ░░░░░ ░░░░░░░░ ░░░░░░ ░░░░░░
;; © 2021-2023 Howard X. Abrams
;; Licensed under a Creative Commons Attribution 4.0 International License.
;; See http://creativecommons.org/licenses/by/4.0/
@ -36,8 +27,6 @@ A literate programming file for bootstraping my Emacs Configuration.
* Introduction
This file contains all the variable definitions and library loading for the other files in my project.
I'm installing everything using the [[https://github.com/raxod502/straight.el#getting-started][straight.el]] for package installation and management. This is initialization code configured in [[file:initialize][initialize]], and calls to =use-package= now accepts a =:straight= parameter that allows me to retrieve special versions of some packages.
See the details in [[https://dev.to/jkreeftmeijer/emacs-package-management-with-straight-el-and-use-package-3oc8][this essay]].
* Initial Settings
@ -107,7 +96,7 @@ Getting tired off all the packages that I load spewing a bunch of warnings that
The following packages come with Emacs, but seems like they still need loading:
#+begin_src emacs-lisp
(use-package cl-lib
:straight (:type built-in)
:init (defun first (elt) (car elt))
:commands (first))

View file

@ -28,8 +28,11 @@ A literate programming file configuring critical applications.
Can we call the following /applications/? I guess.
* Git and Magit
Can not live without [[https://magit.vc/][Magit]], a Git porcelain for Emacs. I stole the bulk of this work from Doom Emacs.
#+begin_src emacs-lisp
(use-package magit)
(use-package magit
:load-path "~/.emacs.d/repos/magit"
;; See https://github.com/magit/magit/wiki/Emacsclient for why we need to set:
:custom (with-editor-emacsclient-executable "emacsclient")
@ -87,7 +90,7 @@ Can not live without [[https://magit.vc/][Magit]], a Git porcelain for Emacs. I
** VC Diff Highlight
The [[https://github.com/dgutov/diff-hl][diff-hl project]], while more active, has more features than the [[https://github.com/syohex/emacs-git-gutter-fringe][git-gutter-fringe]] project.
#+BEGIN_SRC emacs-lisp
#+BEGIN_SRC emacs-lisp :tangle no
(use-package diff-hl
:custom
(diff-hl-side 'right)
@ -100,7 +103,7 @@ The [[https://github.com/dgutov/diff-hl][diff-hl project]], while more active, h
Turning on the mode, as well as binding some new /leader/ keys:
#+BEGIN_SRC emacs-lisp
#+BEGIN_SRC emacs-lisp :tangle no
(use-package diff-hl
:config
(global-diff-hl-mode)
@ -121,7 +124,7 @@ Turning on the mode, as well as binding some new /leader/ keys:
This project (and others) can use repeat mode, but
#+BEGIN_SRC emacs-lisp
#+BEGIN_SRC emacs-lisp :tangle no
(repeat-mode)
#+END_SRC
@ -214,7 +217,7 @@ The crucial parts of this helper function are that we "wash" the result using =a
The functions below depend on [[help:magit-thing-at-point][magit-thing-at-point]], and this depends on the [[https://sr.ht/~pkal/compat/][compat]] library, so lets grab that stuff:
#+begin_src emacs-lisp :tangle no
(use-package compat
:straight (:host github :repo "emacs-straight/compat"))
;; :vc (:url "https://github.com/emacs-straight/compat"))
(use-package magit-section
:commands magit-thing-at-point)
@ -310,7 +313,7 @@ Using the [[https://github.com/emacsmirror/gist][gist package]] to write code sn
The gist project depends on the [[https://github.com/sigma/gh.el][gh library]]. There seems to be a problem with it.
#+begin_src emacs-lisp :tangle no
(use-package gh
:straight (:host github :repo "sigma/gh.el"))
;; :vc (:url "https://github.com/sigma/gh.el"))
#+end_src
** Forge
@ -408,6 +411,7 @@ Web pages look pretty good with EWW, but I'm having difficulty getting it to ren
#+begin_src emacs-lisp
(use-package eww
:after major-mode-hydra
:init
(setq browse-url-browser-function 'eww-browse-url
browse-url-secondary-browser-function 'browse-url-default-browser
@ -506,7 +510,8 @@ Make my EWW browsers /look/ like an Org file with the [[https://github.com/cheny
#+begin_src emacs-lisp
(use-package shrface
:straight (:host github :repo "chenyanming/shrface")
;; :vc (:url "https://github.com/chenyanming/shrface")
:after major-mode-hydra
:config
(shrface-basic)
;; (shrface-trial)
@ -641,7 +646,7 @@ Instead I use Emacs' built-in directory lister (which accepts the standard, =dir
#+begin_src emacs-lisp
(use-package ls-lisp
:straight (:type built-in)
:config
(setq ls-lisp-use-insert-directory-program nil
dired-listing-switches
@ -652,7 +657,7 @@ And [[https://www.masteringemacs.org/article/dired-shell-commands-find-xargs-rep
#+begin_src emacs-lisp
(use-package dired-x
:straight (:type built-in))
)
#+end_src
The advantage of =dired-x= is the ability to have [[https://www.emacswiki.org/emacs/DiredExtra#Dired_X][shell command guessing]] when selecting one or more files, and running a shell command on them with ~!~ or ~&~.
@ -666,7 +671,7 @@ The [[https://github.com/alexluigit/dirvish][dirvish]] project aims to make a pr
Im beginning with dirvish to use the [[https://github.com/alexluigit/dirvish/blob/main/docs/CUSTOMIZING.org][sample configuration]] and change it:
#+begin_src emacs-lisp :tangle no
(use-package dirvish
:straight (:host github :repo "alexluigit/dirvish")
;; :vc (:url "https://github.com/alexluigit/dirvish")
:init (dirvish-override-dired-mode)
:custom
@ -872,6 +877,8 @@ The [[Evil Collection][evil-collection]] package adds the following keybindings:
Id like write notes in org files that link to the PDFs (and maybe visa versa), using the [[https://github.com/weirdNox/org-noter][org-noter]] package:
#+begin_src emacs-lisp
(use-package org-noter
:load-path "/User/howard.abrams/.emacs.d/repos/org-noter"
:after major-mode-hydra
:config
(major-mode-hydra-define org-noter-doc-mode-map nil
("Notes"

View file

@ -31,7 +31,7 @@ The following applications are not needed. I alternate between trying to /stay i
Glad to see the 2FA feature is working on the [[https://codeberg.org/martianh/mastodon.el][mastodon.el]] project, and even more glad to see the great birdland diaspora arrive in the land of the toots.
#+begin_src emacs-lisp
(use-package mastodon
:straight (:host codeberg :repo "martianh/mastodon.el")
;; :vc (:url "https://codeberg.org/martianh/mastodon.el")
:init
(setq mastodon-instance-url "https://pdx.social"
mastodon-active-user "howard"))
@ -41,7 +41,7 @@ I would like a dedicate perspective to Mastodon, and I would like a leader key s
#+begin_src emacs-lisp
(use-package mastodon
:config
(ha-leader "a m" `("mastodon" . ,(lambda () (interactive) (ha-tab-bar-new "mastodon" #'mastodon))))
(ha-leader "a m" `("mastodon" . ,(ha-app-perspective "mastodon" #'mastodon)))
(defun ha-mastodon-scroll-or-more ()
"Scroll a window, and at the end, get more entries in timeline."
@ -55,33 +55,33 @@ I would like a dedicate perspective to Mastodon, and I would like a leader key s
:config
(major-mode-hydra-define mastodon-mode nil
("Timelines"
(("u" mastodon-tl-update "update")
("F" mastodon-tl-get-federated-timeline "Federated")
("H" mastodon-tl-get-home-timeline "Home")
("L" mastodon-tl-get-local-timeline "Local")
("T" mastodon-tl-get-tag-timeline "Hashtag"))
(("u" mastodon-tl--update "update")
("F" mastodon-tl--get-federated-timeline "Federated")
("H" mastodon-tl--get-home-timeline "Home")
("L" mastodon-tl--get-local-timeline "Local")
("T" mastodon-tl--get-tag-timeline "Hashtag"))
"Specials"
(("M" mastodon-notifications--get-mentions "Mentions")
("N" mastodon-notifications-get "Notifications")
("A" mastodon-tl-followed-tags-timeline "All Tags")
("S" mastodon-profile-view-bookmarks "Saved bookmarks")
("O" mastodon-profile-my-profile "My Profile"))
("A" mastodon-tl--followed-tags-timeline "All Tags")
("S" mastodon-profile--view-bookmarks "Saved bookmarks")
("O" mastodon-profile--my-profile "My Profile"))
"Post"
(("c" mastodon-toot "Compose toot")
("e" mastodon-toot-edit-toot-at-point "Edit toot")
("t" mastodon-tl-thread "Read thread")
("r" mastodon-toot-reply "Reply")
("m" mastodon-tl-dm-user "Direct Msg")
("d" mastodon-toot-delete-toot "Delete"))
("e" mastodon-toot--edit-toot-at-point "Edit toot")
("t" mastodon-tl--thread "Read thread")
("r" mastodon-toot--reply "Reply")
("m" mastodon-tl--dm-user "Direct Msg")
("d" mastodon-toot--delete-toot "Delete"))
"Toot"
(("f" mastodon-toot-toggle-favourite "Favorite")
("b" mastodon-toot-toggle-boost "Boost")
("s" mastodon-toot-toggle-bookmark "Save")
("y" mastodon-toot-copy-toot-url "Copy URL")
("Y" mastodon-toot-copy-toot-text "Copy text"))
(("f" mastodon-toot--toggle-favourite "Favorite")
("b" mastodon-toot--toggle-boost "Boost")
("s" mastodon-toot--toggle-bookmark "Save")
("y" mastodon-toot--copy-toot-url "Copy URL")
("Y" mastodon-toot--copy-toot-text "Copy text"))
"Navigation"
(("n" mastodon-tl-next-tab-item "next" :color pink)
("p" mastodon-tl-previous-tab-item "previous" :color pink)
(("n" mastodon-tl--next-tab-item "next" :color pink)
("p" mastodon-tl--previous-tab-item "previous" :color pink)
("," ha-mastodon-scroll-or-more "...more" :color pink))))))
#+end_src
@ -95,7 +95,7 @@ Lets turn on non-fixed-width fonts to make everything easier to read:
Yet another encrypted chat/VoIP client-server, but unlike Signal and Telegram, [[matrix.org][Matrix]] is act ually open source. In other words, a project for nerds. Well be using Alphapapas latest [[https://github.com/alphapapa/ement.el][ement]] project.
#+begin_src emacs-lisp
(use-package ement
:straight (:host github :repo "alphapapa/ement.el")
;; :vc (:url "https://github.com/alphapapa/ement.el")
:config
(major-mode-hydra-define ement-room-mode (:quit-key "q")
("Send"
@ -175,7 +175,7 @@ I'm thinking the [[https://zevlg.github.io/telega.el/][Telega package]] would be
(when (fboundp 'evil-insert-state)
(add-hook 'telega-chat-mode-hook 'evil-insert-state))
(ha-leader "a t" `("telega" . ,(lambda () (interactive) (ha-tab-bar-new "telega" #'telega)))))
(ha-leader "a t" `("telega" . ,(ha-app-perspective "telega" #'telega))))
#+end_src
For some reason, you need [[https://github.com/Fanael/rainbow-identifiers][rainbow-identifiers]] to work, oh, I guess the docs state this.
@ -189,7 +189,7 @@ Been working on my [[https://gitlab.com/howardabrams/emacs-rpgdm][RPG DM project
#+begin_src emacs-lisp
(when (f-directory? "~/src/emacs-rpgdm")
(use-package rpgdm
:straight (:local-repo "~/src/emacs-rpgdm")
:load-path "~/src/emacs-rpgdm"
:commands (rpgdm-mode rpgdm-tables-load)
:init (setq rpgdm-base (expand-file-name "~/src/emacs-rpgdm"))
:config (ha-leader "t D" '("rpg dm" . rpgdm-mode))))
@ -199,7 +199,7 @@ Working on my new replacement of my DM code:
#+begin_src emacs-lisp
(when (f-directory? "~/src/emacs-rpgtk")
(use-package rpgtk
:straight (:local-repo "~/src/emacs-rpgtk")
:load-path "~/src/emacs-rpgtk"
:after hydra
;; :commands (rpgtk-mode rpgtk-tables-load rpgtk-dice rpgtk-message)
:custom
@ -217,7 +217,7 @@ And my [[https://gitlab.com/howardabrams/emacs-ironsworn][new Ironsworn project]
(when (f-directory? "~/src/emacs-ironsworn")
(use-package rpgdm-ironsworn
:after rpgdm
:straight (:local-repo "~/src/emacs-ironsworn")
:load-path "~/src/emacs-ironsworn"
:init
(setq rpgdm-ironsworn-project (expand-file-name "~/src/emacs-ironsworn")
;; Ignore org links that call my RPG functions:
@ -234,7 +234,7 @@ Why not? Lets see if the [[https://github.com/isamert/empv.el][empv]] project
What else?
#+begin_src emacs-lisp
(use-package empv
:straight (:host github :repo "isamert/empv.el")
;; :vc (:url "https://github.com/isamert/empv.el")
:general (ha-leader
"a p" '(empv-map :wk "play music")))
#+end_src

View file

@ -233,7 +233,7 @@ And for even quicker work, we can have special scripts tied to special keybindin
The [[https://gitlab.com/aimebertrand/org-mac-link][org-mac-link]] project makes it easy to tell Emacs to retrieve information from other apps, e.g. the URL of the opened tab in Firefox.
#+begin_src emacs-lisp
(use-package org-mac-link
:straight (:host gitlab :repo "aimebertrand/org-mac-link")
;; :vc (:url "https://gitlab.com/aimebertrand/org-mac-link")
:config
(ha-leader "i" '("insert app info" . org-mac-link-get-link)))
#+end_src

View file

@ -146,7 +146,8 @@ After reading [[https://irreal.org/blog/?p=12139][Jon Sanders essay]] as well
#+begin_src emacs-lisp
(use-package emacs-everywhere
:straight (:host github :repo "tecosaur/emacs-everywhere"))
;; :vc (:url "https://github.com/tecosaur/emacs-everywhere")
)
#+end_src
This package /called outside of Emacs/, so I bound a keybinding to iCanHazShortcut:
@ -225,7 +226,6 @@ When I push changes to my files to Gerrit and other code review, I dont want
The [[https://www.emacswiki.org/emacs/RecentFiles][recentf]] feature has been in Emacs for a long time, but it has a problem with Tramp, as we need to turn off the cleanup feature that attempts to =stat= all the files and remove them from the =recent= accessed list if they are readable. The requires recentf to open up a remote files which blocks Emacs at the most inopportune times… like when trying to reboot the machine.
#+begin_src emacs-lisp
(use-package recentf
:straight (:type built-in)
:config
(setq recentf-auto-cleanup 'never) ;; disable before we start recentf!
(recentf-mode 1))
@ -336,10 +336,13 @@ The [[https://github.com/minad/vertico][vertico]] package puts the completing re
(use-package vertico
:config (vertico-mode))
#+end_src
My issue with Vertico is when calling =find-file=, the Return key opens =dired=, instead of inserting the directory at point. This package addresses this:
#+begin_src emacs-lisp
#+begin_src emacs-lisp :tangle no
(use-package vertico-directory
:straight (el-patch :files ("~/.emacs.d/straight/repos/vertico/extensions/vertico-directory.el"))
:load-path "~/.emacs.d/repos/vertigo/extensions"
;; :straight (:files ("~/.emacs.d/straight/repos/vertico/extensions/vertico-directory.el"))
;; More convenient directory navigation commands
:bind (:map vertico-map
("RET" . vertico-directory-enter)
@ -380,7 +383,7 @@ How does it compare? Once upon a time, I enjoyed typing ~plp~ for =package-list-
#+begin_src emacs-lisp
(use-package fussy
;; :straight (:host github :repo "jojojames/fussy")
;; ;; :vc (:url "https://github.com/jojojames/fussy")
:config
(push 'fussy completion-styles)
(setq completion-category-defaults nil
@ -571,7 +574,7 @@ The [[https://github.com/minad/cape][Cape project]] deliver particular [[help:co
#+BEGIN_SRC emacs-lisp :tangle no
(use-package cape
:straight (:host github :repo "minad/cape")
;; :vc (:url "https://github.com/minad/cape")
:init
(setq completion-at-point-functions (list #'cape-emoji)))
#+END_SRC
@ -592,10 +595,11 @@ After using [[http://company-mode.github.io/][company]] for my completion back-
#+begin_src emacs-lisp
(use-package corfu
;; :vc (:url "https://github.com/minad/corfu")
:custom
(corfu-cycle t)
(corfu-separator ?\s)
:init
:config
(global-corfu-mode))
#+end_src
*** Snippets
@ -673,7 +677,7 @@ As I've mentioned [[http://www.howardism.org/Technical/Emacs/beep-for-emacs.html
'libnotify)))
(use-package beep
:straight (:local-repo "~/src/hamacs/elisp")
:load-path "~/src/hamacs/elisp"
:hook (after-init . ha-random-startup-message)
:commands (beep-when-finished beep-when-run-too-long)
:config
@ -926,13 +930,14 @@ Since I wasnt using all the features that [[https://github.com/bbatsov/projec
(ha-leader
"p" '(:ignore t :which-key "projects")
"p W" '("initialize workspace" . ha-workspace-initialize)
"p p" '("switch project" . ha-tab-bar-new-project)
"p n" '("new project space" . ha-project-persp)
"p !" '("run cmd in project root" . project-shell-command)
"p &" '("run cmd async" . project-async-shell-command)
"p a" '("add new project" . project-remember-projects-under)
"p d" '("dired" . project-dired)
"p k" '("kill project buffers" . project-kill-buffers)
"p p" '("switch project" . project-switch-project)
"p x" '("remove known project" . project-forget-project)
"p f" '("find file" . project-find-file)
@ -946,139 +951,204 @@ Since I wasnt using all the features that [[https://github.com/bbatsov/projec
"p s" '("project shell" . project-shell)))
#+end_src
** Workspaces
A /workspace/ (at least to me) requires a quick jump to a collection of buffer windows organized around a project or task. Later versions of Emacs use [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Tab-Bars.html][Tab Bars]] which group windows and buffers in a perspective. The code that follows is a Poor Persons Workspace package. Also lets dive into the end section of [[https://www.masteringemacs.org/article/demystifying-emacs-window-manager][Mickey Petersen's essay]] on the subject.
A /workspace/ (at least to me) requires a quick jump to a collection of buffer windows organized around a project or task. For this, I'm basing my work on the [[https://github.com/nex3/perspective-el][perspective.el]] project.
Couple notes:
- Function, =tab-bar-switch-to-tab=, switches or /creates/ a tab. We will always use this.
- We can switch to a tab by number with =tab-bar-select-tab=
#+BEGIN_SRC emacs-lisp
(setq tab-bar-show 1 ; hide bar if <= 1 tabs open
tab-bar-close-button-show nil ; hide tab close / X button
tab-bar-new-tab-choice "*dashboard*" ; buffer to show in new tabs
tab-bar-tab-hints t ; show tab numbers
tab-bar-button-relief 0
tab-bar-button-margin '(40 . 1)
;; Jump to a tab by numbers (see the keybindings set later):
tab-bar-select-tab-modifiers '(super control))
#+END_SRC
Ive struggled to /programmatically/ create sane workspaces, so lets just save them off:
#+BEGIN_SRC emacs-lisp
(desktop-save-mode 1)
#+END_SRC
New workspace is a tab with a specific name that opens up a specific buffer or application. My motive for such a complicated function allows me to pre-create tabs with already running applications or files.
I build a Hydra to dynamically list the current projects as well as select the project.
To do this, we need a way to generate a string of the perspectives in alphabetical order:
#+begin_src emacs-lisp
(defun ha-tab-bar-new (name &optional bff)
"Create a new tab with a NAME.
With a non-nil IFF, call IFF as a function or switch
to the IFF buffer or the files listed."
(interactive "sWorkspace Name: ")
(tab-bar-switch-to-tab name)
(when bff
(cond
((listp bff) (find-file (car bff))
(dolist (f (cdr bff))
(split-window-right)
(find-file f)))
((fboundp bff) (call-interactively bff))
((bufferp bff) (switch-to-buffer bff)))))
(defun ha--persp-label (num names)
"Return string of numbered elements.
NUM is the starting number and NAMES is a list of strings."
(when names
(concat
(format " %d: %s%s" ; Shame that the following doesn't work:
num ; (propertize (number-to-string num) :foreground "#00a0")
(car names) ; Nor does surrounding the number with underbars.
(if (equal (car names) (persp-name (persp-curr))) "*" ""))
(ha--persp-label (1+ num) (cdr names)))))
(defun ha-persp-labels ()
"Return a string of numbered elements from a list of names."
(ha--persp-label 1 (sort (hash-table-keys (perspectives-hash)) 's-less?)))
#+end_src
Create a new tab associated with a project:
Build the hydra as well as configure the =perspective= project.
#+begin_src emacs-lisp
(defun ha-tab-bar-new-project (project-dir)
"Create a new tab/workspace based on a project.
The project is defined by the PROJECT-DIR directory."
(interactive (list (completing-read "Project: " (project-known-project-roots))))
(let ((name (project-name (project-current nil project-dir)))
(default-directory project-dir))
(ha-tab-bar-new name)
(project-switch-project project-dir)))
(use-package perspective
:custom
(persp-modestring-short t)
(persp-show-modestring t)
:config
(setq persp-suppress-no-prefix-key-warning t)
(persp-mode)
(defhydra hydra-workspace-leader (:color blue :hint nil) "
Workspaces- %s(ha-persp-labels)
_n_: new project _r_: rename _a_: add buffer _l_: load worksp
_]_: next worksp _d_: delete _b_: goto buffer _s_: save worksp
_[_: previous _W_: init all _k_: remove buffer _`_: to last worksp "
("TAB" persp-switch-quick)
("RET" persp-switch)
("`" persp-switch-last)
("1" (persp-switch-by-number 1))
("2" (persp-switch-by-number 2))
("3" (persp-switch-by-number 3))
("4" (persp-switch-by-number 4))
("5" (persp-switch-by-number 5))
("6" (persp-switch-by-number 6))
("7" (persp-switch-by-number 7))
("8" (persp-switch-by-number 8))
("9" (persp-switch-by-number 9))
("0" (persp-switch-by-number 0))
("n" ha-project-persp)
("N" persp-switch)
("]" persp-next :color pink)
("[" persp-prev :color pink)
("d" persp-kill)
("W" ha-workspace-initialize)
("a" persp-add-buffer)
("b" persp-switch-to-buffer)
("k" persp-remove-buffer)
("K" persp-kill-buffer)
("m" persp-merge)
("u" persp-unmerge)
("i" persp-import)
("r" persp-rename)
("s" persp-state-save)
("l" persp-state-load)
("w" ha-switch-to-special) ; The most special perspective
("q" nil)
("C-g" nil)))
#+end_src
If we close a tab that is a project, we want to close all the buffers associated with it. I wouldnt do this if it wasnt so easy to re-create them:
Lets give it a binding:
#+begin_src emacs-lisp
(defun ha-tab-bar-delete (tab-name)
"Delete a tab, TAB-NAME, and all buffers associated with it."
(interactive
(list (completing-read "Close tab by name: "
(mapcar (lambda (tab)
(alist-get 'name tab))
(funcall tab-bar-tabs-function)))))
(dolist (buf (ha-tab-bar-buffers tab-name))
(kill-buffer buf))
(tab-bar-close-tab-by-name tab-name))
(defun ha-tab-bar-buffers (tab-name)
"Return list of buffers associated with TAB-NAME."
(seq-filter (lambda (b)
(thread-last b
(tab-bar-get-buffer-tab)
(alist-get 'name)
(string-equal tab-name)))
(buffer-list)))
(ha-leader "TAB" '("workspaces" . hydra-workspace-leader/body))
#+end_src
And some shortcut keys from the =general= project:
When called, it /can/ look like:
#+BEGIN_SRC emacs-lisp
(general-nmap :prefix "SPC"
"<tab>" '(:ignore t :which-key "workspaces")
"<tab> <tab>" '("switch" . tab-switch)
"<tab> p" '("new project" . ha-tab-bar-new-project)
"<tab> n" '("new space" . ha-tab-bar-new)
"<tab> u" '("update names" . ha-tab-bar-update-names)
"<tab> d" '("delete space" . ha-tab-bar-delete))
[[file:screenshots/projects-hydra.png]]
(global-set-key (kbd "s-C-t") 'ha-tab-bar-new)
(global-set-key (kbd "s-C-[") 'tab-bar-switch-to-prev-tab)
(global-set-key (kbd "s-C-]") 'tab-bar-switch-to-next-tab)
(tab-bar-mode 1)
#+END_SRC
I want to quickly jump, by the number shown on the tab, to that grouping. The following two functions create leader sequences with the name of the tab group:
#+BEGIN_SRC emacs-lisp
(defun ha-tab-bar-update-names ()
"Create normal-mode keybindings for the tab groupings.
This creates `SPC TAB 1' to jump to the first tab, etc."
The /special/ perspective is a nice shortcut to the one I use the most:
#+begin_src emacs-lisp
(defun ha-switch-to-special ()
"Change to the projects perspective."
(interactive)
;; Remove all previously created keybindings:
(ignore-errors
(dolist (indx (number-sequence 1 9))
(general-nmap :prefix "SPC" (format "<tab> %d" indx) nil)))
(persp-switch "projects"))
#+end_src
;; Loop through the existing tabs, create keys for each:
(seq-do-indexed 'ha-tab-bar-update-tab-keybinding (tab-bar-tabs)))
I often want a workspace dedicated to an /application/, so this function:
(defun ha-tab-bar-update-tab-keybinding (tab-deets indx)
"Create a keybinding to jump to tab described by TAB-DEETS.
The key sequence, `SPC' `TAB' then INDX."
(let ((name (alist-get 'name tab-deets)))
(general-nmap :prefix "SPC"
(format "<tab> %d" (1+ indx))
`(,name .
(lambda () (interactive) (tab-bar-select-tab ,(1+ indx)))))))
#+END_SRC
#+begin_src emacs-lisp
(defun ha-app-perspective (name func)
"Generate new perspective NAME, automatically running FUNC."
(lambda ()
(interactive)
(let ((already-started? (seq-contains-p (persp-names) name 'equal)))
(persp-switch name)
(unless already-started?
(call-interactively func)))))
#+end_src
Any time I create or delete a new tab, we can call =ha-tab-bar-update-names=:
And I can then use it like:
#+begin_src emacs-lisp :tangle no
(ha-leader "a x" `("to foobar" . ,(ha-app-perspective "foobar" #'foobar)))
#+end_src
*** Predefined Workspaces
Let's describe a list of startup project workspaces. This way, I don't need the clutter of the recent state, but also get back to a state of mental normality.
Granted, this list is essentially a list of projects that I'm currently developing, so I expect this to change often.
#+BEGIN_SRC emacs-lisp
(advice-add #'tab-bar-new-tab :after #'ha-tab-bar-update-names)
(advice-add #'tab-bar-close-tab :after #'ha-tab-bar-update-names)
(advice-add #'tab-bar-close-other-tabs :after #'ha-tab-bar-update-names)
#+begin_src emacs-lisp
(defvar ha-workspace-projects-personal nil "List of default projects with a name.")
(add-hook desktop-after-read-hook #'ha-tab-bar-update-names)
#+END_SRC
(add-to-list 'ha-workspace-projects-personal
'("projects" "~/projects" ("breathe.org" "tasks.org")))
(add-to-list 'ha-workspace-projects-personal
'("personal" "~/personal" ("general.org")))
(add-to-list 'ha-workspace-projects-personal
'("technical" "~/technical" ("ansible.org")))
(add-to-list 'ha-workspace-projects-personal
'("hamacs" "~/src/hamacs" ("README.org" "ha-config.org")))
#+end_src
Given a list of information about project-workspaces, can we create them all?
#+begin_src emacs-lisp
(defun ha-persp-exists? (name)
"Return non-nill if a perspective of NAME exists."
(when (fboundp 'perspectives-hash)
(seq-contains (hash-table-keys (perspectives-hash)) name)))
(defun ha-workspace-initialize (&optional projects)
"Precreate workspace projects from a PROJECTS list.
Each entry in the list is a list containing:
- name (as a string)
- project root directory
- a optional list of files to display"
(interactive)
(unless projects
(setq projects ha-workspace-projects-personal))
(dolist (project projects)
(seq-let (name root files) project
(unless (ha-persp-exists? name)
(message "Creating workspace: %s (from %s)" name root)
(ha-project-persp root name files))))
(persp-switch "main"))
#+end_src
Often, but not always, I want a perspective based on an actual Git repository, e.g. a project. Emacs calls these transients.
#+begin_src emacs-lisp
(defun ha-project-persp (project &optional name files)
"Create a new perspective, and then switch to the PROJECT.
If NAME is not given, then figure it out based on the name of the
PROJECT. If FILES aren't specified, then see if there is a
README. Otherwise, pull up Dired."
(interactive (list (completing-read "Project: "
(project-known-project-roots))))
(when (f-directory-p project)
(unless name
(setq name (f-filename project)))
(persp-switch name)
(let ((recent-files (thread-last recentf-list
(--filter (s-starts-with? project it))
(-take 3)))
(readme-org (f-join project "README.org"))
(readme-md (f-join project "README.md"))
(readme-rst (f-join project "README.rst")))
(cond
(files (ha--project-show-files project files))
(recent-files (ha--project-show-files project recent-files))
((f-exists? readme-org) (find-file readme-org))
((f-exists? readme-md) (find-file readme-md))
((f-exists? readme-rst) (find-file readme-rst))
(t (dired project))))))
#+end_src
When starting a new perspective, and I specify more than one file, this function splits the window horizontally for each file.
#+begin_src emacs-lisp
(defun ha--project-show-files (root files)
"Display a list of FILES in a project ROOT directory.
Each file gets its own window (so don't make the list of files
long)."
(when files
(let ((default-directory root)
(file (car files))
(more (cdr files)))
(message "Loading files from %s ... %s and %s" root file more)
(when (f-exists? file)
(find-file file))
(when more
(split-window-horizontally)
(ha--project-show-files root more)))))
#+end_src
* Pretty Good Encryption
For details on using GnuPG in Emacs, see Mickey Petersens [[https://www.masteringemacs.org/article/keeping-secrets-in-emacs-gnupg-auth-sources][GnuPG Essay]].
@ -1096,7 +1166,6 @@ Also, as [[https://www.bytedude.com/gpg-in-emacs/][bytedude]] mentions, I need t
#+begin_src emacs-lisp
(use-package epa-file
:straight (:type built-in)
:custom
(epg-debug t)
(auth-source-debug t)
@ -1106,18 +1175,22 @@ Also, as [[https://www.bytedude.com/gpg-in-emacs/][bytedude]] mentions, I need t
;; Make sure we prompt in the minibuffer for the password:
(epg-pinentry-mode 'loopback)
;; I trust my Emacs session, so I don't bother expiring my pass:
(auth-source-cache-expiry nil)
(auth-source-cache-expiry nil))
#+end_src
Need to make sure that Emacs will handle the prompts, and turn it on:
#+begin_src emacs-lisp
(use-package epa-file
:config
(setenv "GPG_AGENT_INFO" nil)
(ignore-error (epa-file-enable)))
(epa-file-enable))
#+end_src
Since I already (at this point in my file) have Org installed and running, the following code configures the encryption of certain header sections (see [[https://orgmode.org/worg/org-tutorials/encrypting-files.html][this tutorial]]). Headers with a =:crypt:tag (see =org-crypt-tag-matcher= to change it) will be encrypted.
To temporarily read an encrypted part, and call =M-x org-decrypt-entry= when the cursor is inside that section. Saving the file, will re-encrypt it.
#+begin_src emacs-lisp :tangle no
#+begin_src emacs-lisp
(use-package org
:config
(require 'org-crypt)

View file

@ -145,10 +145,12 @@ The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] proj
(string-replace "\n" "" smaller-version)))
(setq dashboard-startup-banner
;; Choose a random image from my collection of startup images:
(thread-first "~/src/hamacs/support/dashboard"
(directory-files t (rx ".png"))
(seq-random-elt)))
(if (ha-emacs-for-work?)
"~/src/hamacs/support/teal-sticker.png"
;; Choose a random image from my collection of startup images:
(thread-first "~/src/hamacs/support/dashboard"
(directory-files t (rx ".png"))
(seq-random-elt))))
(setq dashboard-banner-logo-title
(format "Emacs %s — %s"
@ -167,12 +169,12 @@ The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] proj
dashboard-set-heading-icons t
dashboard-footer-messages (list (ha--dad-joke)))
:config
(dashboard-setup-startup-hook)
;; Real shame that :config is incompatible with :hook, otherwise:
;; :hook (dashboard-after-initialize . ha-dashboard)
:config
(tab-bar-switch-to-tab "main")
(dashboard-setup-startup-hook))
(add-hook 'dashboard-after-initialize-hook 'ha-dashboard))
#+end_src
This dashboard project requires [[https://github.com/purcell/page-break-lines][page-break-lines]] (which is a nice project):
@ -262,7 +264,6 @@ The =dashboard= project hooks to [[help:emacs-startup-hook][emacs-startup-hook]]
(defun ha-dashboard ()
"Shows the extra stuff with the dashboard."
(interactive)
(tab-bar-switch-to-tab "main")
(switch-to-buffer "*dashboard*")
(setq-local mode-line-format nil)
(delete-other-windows)

View file

@ -44,8 +44,8 @@ Once I made demonstrations /within/ Emacs with my [[https://github.com/howardabr
#+begin_src emacs-lisp :tangle no
(use-package demo-it
:straight (:local-repo "~/src/demo-it")
;; :straight (:host github :repo "howardabrams/demo-it")
:load-path "~/src/demo-it"
;; :vc (:url "https://github.com/howardabrams/demo-it")
:commands (demo-it-create demo-it-start demo-it-hide-mode-line
demo-it--presentation-display-set)
:custom (demo-it--insert-test-speed :faster))
@ -194,7 +194,7 @@ With some a startup bug that I havent been able to resolve, Im not using i
#+begin_src emacs-lisp :tangle no
(use-package dslide
:straight (dslide :host github :repo "positron-solutions/dslide")
;; :vc (:url "https://github.com/positron-solutions/dslide")
:commands (dslide-deck-start dslide-deck-stop)
:custom
(dslide-start-from 'point)
@ -244,7 +244,7 @@ Call the =ha-slide-notes-update= function automatically after updating a slide.
#+BEGIN_SRC emacs-lisp :tangle no
(use-package dslide
:straight (dslide :host github :repo "positron-solutions/dslide")
;; :vc (:url "https://github.com/positron-solutions/dslide")
:commands (dslide-narrow-hook)
:hook (dslide-narrow . 'ha-slide-notes-update))
#+END_SRC
@ -256,8 +256,7 @@ The [[https://github.com/positron-solutions/moc][Master of Ceremonies]] package
(use-package default-text-scale)
(use-package moc
:straight (:type git :host github
:repo "positron-solutions/moc"))
;; :vc (:url "https://github.com/positron-solutions/moc"))
#+END_SRC
Select text, and call =moc-focus= (call =moc-focus-quit= to stop). Highlight more text, and call =moc-focus-highlight= to brighten it, or =moc-focus-obscure= to hide it.
@ -272,7 +271,7 @@ The [[https://github.com/trevorpogue/topspace][topspace]] project can pad the to
#+BEGIN_SRC emacs-lisp
(use-package topspace
:straight (:type git :host github :repo "trevorpogue/topspace"))
;; :vc (:url "https://github.com/trevorpogue/topspace"))
#+END_SRC
*** Showing Something associated with a Headline
@ -307,7 +306,7 @@ To do this, add =:DSLIDE_ACTIONS: dslide-action-highlight-paragraphs= to the pro
#+begin_src elisp emacs-lisp :tangle no
(use-package dslide
:straight (:host github :repo "positron-solutions/dslide")
;; :vc (:url "https://github.com/positron-solutions/dslide")
:config
(defclass dslide-action-highlight-paragraphs (dslide-action)
((overlays :initform nil))

View file

@ -63,14 +63,19 @@ To make the active window /more noticeable/, we /dim/ the in-active windows with
#+begin_src emacs-lisp
(use-package dimmer
:custom (dimmer-adjustment-mode :foreground)
:config
;; I get issues with Magit and Dimmer, so lets turn off this feature in certain windows:
(dimmer-configure-which-key) ; Do not dim these special windows
(dimmer-configure-hydra)
(dimmer-configure-magit)
:custom (dimmer-adjustment-mode :foreground))
#+end_src
(dimmer-mode t))
I get issues with Magic and Dimmer, so lets turn off this feature in certain windows:
#+begin_src emacs-lisp
(use-package dimmer
:config
(dimmer-configure-which-key) ; Do not dim these special windows
(dimmer-configure-hydra)
(dimmer-configure-magit)
(dimmer-mode t))
#+end_src
As an interesting alternative, check out the [[https://www.emacs.dyerdwelling.family/emacs/20240208164549-emacs-selected-window-accent-mode-now-on-melpa/][selected-window-accent]] project.
@ -81,11 +86,10 @@ either be "there or not" which resulted large jumps and large distractions.
#+BEGIN_SRC emacs-lisp
(use-package ultra-scroll
:straight (:type git :host github :repo "jdtsmith/ultra-scroll")
;; :vc (:url "https://github.com/jdtsmith/ultra-scroll")
:config
(setq scroll-conservatively 101 ; important!
pixel-scroll-precision-interpolate-page t
scroll-margin 0)
scroll-margin 0)
(ultra-scroll-mode 1))
#+END_SRC
** Find the Bloody Cursor
@ -93,7 +97,7 @@ Large screen, lots of windows, so where is the cursor? While I used to use =hl-l
#+begin_src emacs-lisp
(use-package pulsar
:straight (:host github :repo "protesilaos/pulsar")
;; :vc (:url "https://github.com/protesilaos/pulsar")
:custom
(pulsar-face 'pulsar-generic)
(pulsar-delay 0.15)
@ -155,7 +159,7 @@ Am I ever really ever satisfied with any font? I regularly change my font based
#+begin_src emacs-lisp
(use-package mixed-pitch
;; :straight (:host github :repo "jabranham/mixed-pitch")
;; ;; :vc (:url "https://github.com/jabranham/mixed-pitch")
:config
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-property-value)
(add-to-list 'mixed-pitch-fixed-pitch-faces 'org-special-keyword)
@ -385,7 +389,7 @@ This project replaces [[https://github.com/domtronn/all-the-icons.el][all-the-ic
#+BEGIN_SRC emacs-lisp
(use-package nerd-icons
:straight (nerd-icons :type git :host github :repo "rainstormstudio/nerd-icons.el")
;; :vc (:url "https://github.com/rainstormstudio/nerd-icons.el")
:custom
;; The Nerd Font you want to use in GUI defaults to fixed-font:
(nerd-icons-font-family ha-fixed-font))
@ -634,7 +638,7 @@ In code, if you drop a specific /text/ labels, we can highlight them with [[http
#+begin_src emacs-lisp
(use-package hl-todo
:straight (:host github :repo "tarsius/hl-todo")
;; :vc (:url "https://github.com/tarsius/hl-todo")
:config
(setq hl-todo-keyword-faces
`(("TODO" . ,(face-foreground 'warning))
@ -650,16 +654,14 @@ Suggests to bind some keys to =hl-todo-next= in order to jump from tag to tag, b
#+begin_src emacs-lisp
(use-package consult-todo
:straight (:host github :repo "liuyinz/consult-todo")
;; :vc (:url "https://github.com/liuyinz/consult-todo")
:init
(defconst consult-todo--narrow
'((?t . "TODO")
(?f . "FIXME")
(?n . "NOTE"))
"Mapping of narrow and keywords.")
;; :config
;; (evil-define-key '(normal) 'global "g t" '("jump todos" . consult-todo))
)
:general (:states 'normal "g t" '("jump todos" . consult-todo)))
#+end_src
* Full Size Frame
Taken from [[https://emacsredux.com/blog/2020/12/04/maximize-the-emacs-frame-on-startup/][this essay]], I figured I would start the initial frame automatically in fullscreen, but not any subsequent frames (as this could be part of the capturing system).

View file

@ -133,7 +133,7 @@ Also, let's do some basic configuration of Emacs' mail system:
Create a special mail perspective:
#+begin_src emacs-lisp
(ha-leader "a M" `("mail" . ,(ha-tab-bar-new "mail" #'notmuch)))
(ha-leader "a M" `("mail" . ,(ha-app-perspective "mail" #'notmuch)))
#+end_src
* Configuration
Do I want to sign messages by default? Nope.
@ -737,7 +737,7 @@ The idea of linking org documents to email could be nice, however, the =ol-notmu
#+begin_src emacs-lisp :tangle no
(use-package ol-notmuch
:after org
:straight (:type built-in)
:config (add-to-list 'org-modules 'ol-notmuch))
#+end_src
To use, read a message and save a link to it with ~SPC o l~. Next, in an org document, create a link with ~, l~. Now, you can return to the message from that document with ~, o~. Regardless, I may need to store a local copy when I upgrade Org.

View file

@ -30,7 +30,7 @@ If you find the documentation lacking, I [[http://www.howardism.org/Technical/Em
Tell straight to use the built-in =eshell=:
#+begin_src emacs-lisp
(use-package eshell
:straight (:type built-in)
:hook (eshell-mode . ha-eshell-setup))
#+end_src
@ -976,7 +976,7 @@ The problem with this trick is that =rx= outputs an Emacs-compatible regular exp
The [[https://github.com/joddie/pcre2el][pcre2el]] project can convert from a Lisp regular expression to a [[http://www.pcre.org/][PCRE]] (Perl Compatible Regular Expression), acceptable by [[https://github.com/BurntSushi/ripgrep][ripgrep]].
#+begin_src emacs-lisp
(use-package pcre2el
:straight (:host github :repo "joddie/pcre2el")
;; :vc (:url "https://github.com/joddie/pcre2el")
:config
(defmacro prx (&rest expressions)
"Convert the rx-compatible regular EXPRESSIONS to PCRE.
@ -1378,7 +1378,7 @@ The [[https://codeberg.org/akib/emacs-eat][Emulate a Terminal]] project provides
#+begin_src emacs-lisp :tangle no
(use-package eat
:after eshell
:straight (:repo "https://codeberg.org/akib/emacs-eat")
;; :vc (:url "https://codeberg.org/akib/emacs-eat")
:hook (eshell-load . eat-eshell-visual-command-mode))
#+end_src
@ -1787,7 +1787,7 @@ Sometimes you need to change something about the current file you are editing...
Here is where we associate all the functions and their hooks with =eshell=, through the magic of =use-package=.
#+begin_src emacs-lisp
(use-package eshell
:straight (:type built-in)
:custom (eshell-banner-message '(ha-eshell-banner))
:init
(setq eshell-error-if-no-glob t

View file

@ -402,7 +402,7 @@ Where I like to align, is on variable assignments, e.g.
If you press ~RETURN~ for the /character/ to align, =evil-lion= package simply calls the built-in [[help:align][align]] function. This function chooses a regular expression based on a list of /rules/, and aligning Lisp variables requires a complicated regular expression. Extend [[elisp:(describe-variable 'align-rules-list)][align-rules-list]]:
#+begin_src emacs-lisp
(use-package align
:straight (:type built-in)
:config
(add-to-list 'align-rules-list
`("lisp-assignments"
@ -489,8 +489,9 @@ Notes:
** Evil Jump, er Better Jump
The [[https//github.com/gilbertw1/better-jumper][better-jumper project]] replaces the [[https://github.com/bling/evil-jumper][evil-jumper project]], essentially allowing you jump back to various movements. While I already use ~g ;~ to jump to the last change, this jumps /to the jumps/ … kinda. Im having a difficult time determining /what jumps/ are remembered.
#+begin_src emacs-lisp
#+begin_src emacs-lisp :tangle no
(use-package better-jumper
;; :vc (:url "https//github.com/gilbertw1/better-jumper")
:config
(better-jumper-mode +1)

View file

@ -87,7 +87,7 @@ According to Ben Maughan and [[http://pragmaticemacs.com/emacs/to-eww-or-not-to-
And some global keys to display them in the =apps= menu:
#+begin_src emacs-lisp
(ha-leader "a f" `("feed reader" . ,(ha-tab-bar-new "elfeed" #'elfeed)))
(ha-leader "a f" `("feed reader" . ,(ha-app-perspective "elfeed" #'elfeed)))
#+end_src
* The Feeds :elfeed:
The [[https://github.com/remyhonig/elfeed-org][elfeed-org]] project configures =elfeed= to read the RSS feeds from an Org file … like this one!

View file

@ -335,8 +335,9 @@ And the collection of useful operations:
"b O" '("other" . project-switch-buffer-to-other-window)
"b i" '("ibuffer" . ibuffer)
"b I" '("ibuffer" . ibuffer-other-window)
"b k" '("persp remove" . persp-remove-buffer)
"b N" '("new" . evil-buffer-new)
"b d" '("delete" . kill-buffer)
"b d" '("delete" . persp-kill-buffer*)
"b r" '("revert" . revert-buffer)
"b s" '("save" . save-buffer)
"b S" '("save all" . evil-write-all)
@ -520,7 +521,6 @@ The goal here is toggle switches and other miscellaneous settings.
"t T" '("tramp mode" . tramp-mode)
"t v" '("visual" . visual-line-mode)
"t w" '("whitespace" . whitespace-mode)
"t <tab>" '("tab-bar" . tab-bar-mode)
"t <escape>" '(keyboard-escape-quit :which-key t)
"t C-g" '(keyboard-escape-quit :which-key t))
@ -546,10 +546,13 @@ And put it on the toggle menu:
(ha-leader "t n" '("narrow" . ha-narrow-dwim))
#+end_src
* Window Operations
While it comes with Emacs, the =tab-bar= feature keeps track of all window configurations within a tab, allowing me to revert situations where I accidentally delete all the windows.
While it comes with Emacs, I use [[https://www.emacswiki.org/emacs/WinnerMode][winner-mode]] to undo window-related changes:
#+begin_src emacs-lisp
(tab-bar-history-mode)
(use-package winner
:custom
(winner-dont-bind-my-keys t)
:config
(winner-mode +1))
#+end_src
** Ace Window
Use the [[https://github.com/abo-abo/ace-window][ace-window]] project to jump to any window you see.
@ -877,7 +880,7 @@ Remember these keys in the *Help* buffer:
Let's make Info behave a little more VI-like:
#+begin_src emacs-lisp
(use-package info
:straight (:type built-in)
:general
(:states 'normal :keymaps 'Info-mode-map
"B" 'Info-bookmark-jump

View file

@ -102,7 +102,7 @@ Quick way to start and jump to my IRC world.
And some global keys to display them:
#+begin_src emacs-lisp
(ha-leader "a i" `("irc" . ,(ha-tab-bar-new "irc" #'ha-erc)))
(ha-leader "a i" `("irc" . ,(ha-app-perspective "irc" #'ha-erc)))
#+end_src
And a quick shortcuts to call it:

View file

@ -2,7 +2,7 @@
#+author: Howard Abrams
#+date: 2024-07-07
#+filetags: emacs hamacs
#+lastmod: [2025-02-20 Thu]
#+lastmod: [2025-09-09 Tue]
A literate programming file for literate programming in Emacs Org Files.
@ -862,11 +862,13 @@ I would like to make the /filename/ more readable, I use the =s-match= again, to
#+begin_src emacs-lisp
(defun ha-hamacs-edit--file-title (file)
"Return a more readable string from FILE."
(s-with file
(s-match ha-hamacs-edit-file-to-title)
(second)
(s-replace "-" " ")
(s-titleize)))
(if file
(s-with file
(s-match ha-hamacs-edit-file-to-title)
(second)
(s-replace "-" " ")
(s-titleize))
file))
(defvar ha-hamacs-edit-file-to-title
(rx (optional (or "README-" "ha-"))

View file

@ -31,7 +31,7 @@ The RSS needs UUIDs:
#+BEGIN_SRC emacs-lisp results silent
(use-package uuidgen
:straight (:host github :repo "emacsmirror/uuidgen"))
;; :vc (:url "https://github.com/emacsmirror/uuidgen"))
(defun org-icalendar-create-uid (&rest ignored)
"Returns a UUID."
@ -42,7 +42,7 @@ While the following packages come with Emacs, they aren't necessarily loaded:
#+begin_src emacs-lisp :results silent
(use-package ox-rss
:straight (:host github :repo "emacsmirror/ox-rss"))
;; :vc (:url "https://github.com/emacsmirror/ox-rss"))
(use-package org
:config
@ -64,7 +64,7 @@ Render my code with my font colors:
Also, we need Jack, and his HTML prowess:
#+begin_src emacs-lisp
(use-package jack
:straight (:host github :repo "tonyaldon/jack")
;; :vc (:url "https://github.com/tonyaldon/jack")
:commands (jack-html))
#+end_src

View file

@ -110,7 +110,7 @@ The variable, =org-hide-emphasis-markers=, is key to pretending that Emacs can b
#+begin_src emacs-lisp
(use-package org-appear
:straight (:type git :host github :repo "awth13/org-appear")
;; :vc (:url "https://github.com/awth13/org-appear")
:init (setq org-appear-trigger 'manual)
:hook
((org-mode . (lambda ()
@ -331,7 +331,7 @@ The [[https://github.com/minad/org-modern][org-modern]] project attempts to do a
#+begin_src emacs-lisp
(use-package org-modern
:straight (:host github :repo "minad/org-modern")
;; :vc (:url "https://github.com/minad/org-modern")
:after org
:hook ((org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-agenda))
@ -367,7 +367,7 @@ According to an idea by [[https://jft.home.blog/2019/07/17/use-unicode-symbol-to
The [[https://github.com/TonCherAmi/org-padding][org-padding]] project looks places extra space before and after headers and blocks (essentially leading), to create a more word-processor-y experience. Great idea, however, I have spent a lot of extra time entering blank lines before and after my headers and blocks:
#+begin_src emacs-lisp
(use-package org-padding
:straight (:host github :repo "TonCherAmi/org-padding")
;; :vc (:url "https://github.com/TonCherAmi/org-padding")
:hook (org-mode . org-padding-mode)
:config
(setq org-padding-block-begin-line-padding '(0.5 . 0.3)

View file

@ -3,7 +3,7 @@
#+date: 2020-09-18
#+tags: emacs org
#+startup: inlineimages
#+lastmod: [2025-07-01 Tue]
#+lastmod: [2025-09-08 Mon]
A literate programming file for configuring org-mode and those files.
@ -32,7 +32,7 @@ Org is a /large/ complex beast with a gazillion settings, so I discuss these lat
#+begin_src emacs-lisp :noweb yes
(use-package org
;; TODO: Using the latest org-mode
;; :straight (:type built-in)
;;
:mode (("\\.org" . org-mode))
:init
<<variables>>
@ -278,7 +278,7 @@ Came up with a great way to search a project for Org-specific files, and wrote [
#+begin_src emacs-lisp
(use-package org-find-file
:straight nil
:config
(ha-leader "f o" '("load org" . org-find-file)))
#+end_src
@ -489,8 +489,12 @@ Need to install and configure Emacs to work with [[https://plantuml.com/][PlantU
After installing the [[https://github.com/skuro/plantuml-mode][plantuml-mode]], we need to reference the location:
#+begin_src emacs-lisp
(use-package deflate
:vc (:url "https://github.com/skuro/deflate.git"))
(use-package plantuml-mode
:straight (:host github :repo "skuro/plantuml-mode")
;; :vc (:url "https://github.com/skuro/plantuml-mode")
:after deflate
:init
(setq org-plantuml-jar-path (expand-file-name "~/bin/plantuml.jar")))
#+end_src
@ -543,8 +547,7 @@ Of course, since we are dealing with Emacs, where we assimilate any good idea. J
#+begin_src emacs-lisp
(use-package pikchr-mode
:straight (:local-repo "~/src/pikchr-mode")
;; :straight (:host github :repo "kljohann/pikchr-mode")
;; :vc (:url "https://github.com/kljohann/pikchr-mode")
:custom
(pikchr-executable "~/bin/pikchr"))
#+end_src
@ -732,7 +735,7 @@ I have a special version of tweaked [[file:elisp/ox-confluence.el][Confluence ex
#+begin_src emacs-lisp
(use-package ox-confluence
:after org
:straight nil ; Located in my "elisp" directory
; Located in my "elisp" directory
:config
(ha-leader :keymaps 'org-mode-map
"o E" '("to confluence" . ox-export-to-confluence)))
@ -743,7 +746,7 @@ I have a special version of tweaked [[file:elisp/ox-confluence.el][Confluence ex
Im not afraid of HTML, but I like the idea of doing my HTML work in a Lisp-like way using the [[https://github.com/tonyaldon/jack][jack-html project]]:
#+begin_src emacs-lisp
(use-package jack
:straight (:host github :repo "tonyaldon/jack")
;; :vc (:url "https://github.com/tonyaldon/jack")
:commands (jack-html))
#+end_src
@ -800,7 +803,7 @@ I've been working on my own [[http://www.howardism.org/Technical/Emacs/focused-w
(use-package async)
(use-package ha-focus
:straight (:type built-in)
:config
(ha-leader
"o f" '("begin focus" . ha-focus-begin)
@ -851,7 +854,7 @@ And the Emacs interface to that:
#+begin_src emacs-lisp
(use-package jinx
:straight (:host github :repo "minad/jinx" :files (:defaults "jinx-mod.c" "emacs-module.h"))
;; :vc (:url "https://github.com/minad/jinx" :files (:defaults "jinx-mod.c" "emacs-module.h"))
:hook (emacs-startup . global-jinx-mode)
:bind (("C-;" . jinx-correct-nearest)
("s-;" . jinx-correct-nearest)
@ -1250,7 +1253,7 @@ The [[https://github.com/rnkn/olivetti][olivetti project]] sets wide margins and
Trying out [[https://protesilaos.com/][Protesilaos Stavrou]]s [[https://protesilaos.com/emacs/logos][logos project]] as a replacement for [[https://github.com/joostkremers/writeroom-mode][Writeroom-mode]]:
#+begin_src emacs-lisp
(use-package logos
:straight (:host gitlab :repo "protesilaos/logos")
;; :vc (:url "https://gitlab.com/protesilaos/logos")
:init
(setq logos-outlines-are-pages t
logos-outline-regexp-alist

View file

@ -35,7 +35,7 @@ The obvious keybindings are ~M-h/j/k/l~ … but that is used … well, somewhat.
#+begin_src emacs-lisp :tangle no
(use-package spatial-navigate
:straight (:repo "https://codeberg.org/ideasman42/emacs-spatial-navigate")
;; :vc (:url "https://codeberg.org/ideasman42/emacs-spatial-navigate")
:config
(pretty-hydra-define spatial-navigate (:color amaranth :quit-key "q")
("Box"
@ -62,7 +62,7 @@ The [[https://github.com/antonj/Highlight-Indentation-for-Emacs][Highlight-Inden
#+begin_src emacs-lisp
(use-package highlight-indentation
:straight (:host github :repo "antonj/Highlight-Indentation-for-Emacs")
;; :vc (:url "https://github.com/antonj/Highlight-Indentation-for-Emacs")
:hook ((yaml-mode . highlight-indentation-mode)
(python-mode . highlight-indentation-mode)))
#+end_src
@ -119,7 +119,7 @@ Allow this mode in Org blocks:
And we hook
#+begin_src emacs-lisp
(use-package yaml-pro
:straight (:host github :repo "zkry/yaml-pro")
;; :vc (:url "https://github.com/zkry/yaml-pro")
:after yaml-mode
:hook ((yaml-mode . yaml-pro-mode)))
#+end_src
@ -224,7 +224,7 @@ Do I consider all YAML files an Ansible file needing [[https://github.com/k1LoW/
#+begin_src emacs-lisp
(use-package ansible
:straight (:host gitlab :repo "emacs-ansible/emacs-ansible")
;; :vc (:url "https://gitlab.com/emacs-ansible/emacs-ansible")
;; :mode ((rx (or "playbooks" "roles") (one-or-more any) ".y" (optional "a") "ml") . ansible-mode)
:config
(setq ansible-vault-password-file "~/.ansible-vault-passfile")
@ -242,7 +242,7 @@ Since most Ansible files are a combination of YAML and Jinja, the [[https://gith
#+BEGIN_SRC emacs-lisp
(use-package poly-ansible
:straight (:host github :repo "emacsmirror/poly-ansible")
;; :vc (:url "https://github.com/emacsmirror/poly-ansible")
:after ansible)
#+END_SRC

View file

@ -247,7 +247,7 @@ The /real problem/ is trying to remember all the [[https://github.com/clojure-em
And of course, we want to put this with org blocks:
#+begin_src emacs-lisp
(use-package ob-clojure
:straight (:type built-in)
:custom
(org-babel-clojure-backend 'cider)
:config

View file

@ -71,7 +71,11 @@ And we should extend it with the [[https://github.com/xuchunyang/elisp-demos][el
Wilfreds [[https://github.com/Wilfred/suggest.el][suggest]] function helps you find the right function. Basically, you type in the parameters of a function, and then the desired output, and it will write the function call.
#+begin_src emacs-lisp
(use-package suggest)
(use-package spinner
:vc (:url "https://github.com/Malabarba/spinner.el"))
(use-package suggest
:after spinner)
#+end_src
* Navigation
** Goto Definitions
@ -280,7 +284,7 @@ These are all good, but the primary keys I need to figure out, are the s-express
Wilfreds [[https://github.com/Wilfred/emacs-refactor/tree/master#elisp][emacs-refactor]] package can be helpful if you turn on =context-menu-mode= and …
#+begin_src emacs-lisp
(use-package emr
;; :straight (:host github :repo "Wilfred/emacs-refactor")
;; ;; :vc (:url "https://github.com/Wilfred/emacs-refactor")
:config
(pretty-hydra-define+ lisp-refactor nil
("To 𝛌"
@ -366,3 +370,4 @@ Let's =provide= a name so we can =require= this file:
#+options: num:nil toc:t todo:nil tasks:nil tags:nil date:nil
#+options: skip:nil author:nil email:nil creator:nil timestamp:nil
#+infojs_opt: view:nil toc:t ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
exit

View file

@ -60,7 +60,7 @@ The [[https://github.com/mihaimaruseac/hindent][hindent package]] looks interest
* Haskell and Org
#+begin_src emacs-lisp
(use-package ob-haskell
:straight (:type built-in)
:config
(add-to-list 'org-babel-load-languages '(haskell . t)))
#+end_src

View file

@ -267,8 +267,7 @@ The [[https://elpy.readthedocs.io/en/latest/introduction.html][Elpy Project]] ex
#+BEGIN_SRC emacs-lisp
(use-package elpy
:ensure t
:init
:config
(elpy-enable))
#+END_SRC

View file

@ -57,7 +57,7 @@ The [[https://www.nongnu.org/geiser/][geiser project]] attempts to be the interf
Do we need a Scheme work for Org Babel? According to [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-scheme.html][this document]], we just need to make sure we add the =:session= variable to start the REPL.
#+begin_src emacs-lisp
(use-package ob-scheme
:straight (:type built-in)
:config
(add-to-list 'org-babel-load-languages '(scheme . t)))
@ -122,7 +122,7 @@ While Racket, as a Scheme, should work with Geiser (below), lets also get [[h
Can we get Racket working with Org?
#+begin_src emacs-lisp
(use-package ob-racket
:straight (:host github :repo "DEADB17/ob-racket")
;; :vc (:url "https://github.com/DEADB17/ob-racket")
:after org
:config
(add-to-list 'org-babel-load-languages '(racket . t)))

View file

@ -58,7 +58,7 @@ For all programming languages, I would like to now default to absolute line numb
While Emacs has options for viewing and moving around code, sometimes, we could /collapse/ all functions, and then start to expand them one at a time. For this, we could enable the built-in [[https://www.emacswiki.org/emacs/HideShow][hide-show feature]]:
#+begin_src emacs-lisp :tangle no
(use-package hide-show
:straight (:type built-in)
:init
(setq hs-hide-comments t
hs-hide-initial-comment-block t
@ -212,7 +212,7 @@ Why use [[https://www.flycheck.org/][flycheck]] over the built-in =flymake=? Spe
#+begin_src emacs-lisp
(use-package flycheck
:straight (:host github :repo "flycheck/flycheck")
;; :vc (:url "https://github.com/flycheck/flycheck")
:init
(setq next-error-message-highlight t)
:bind (:map flycheck-error-list-mode-map
@ -400,7 +400,7 @@ However, Emacs already has the ability to download and install grammars, so foll
#+begin_src emacs-lisp
(when (treesit-available-p)
(use-package treesit
:straight (:type built-in)
:preface
(setq treesit-language-source-alist
'((bash "https://github.com/tree-sitter/tree-sitter-bash")
@ -480,7 +480,7 @@ I like [[file:ha-programming-elisp.org::*Clever Parenthesis][Clever Parenthesis]
#+begin_src emacs-lisp
(when (treesit-available-p)
(use-package combobulate
:straight (:host github :repo "mickeynp/combobulate")
;; :vc (:url "https://github.com/mickeynp/combobulate")
:after treesit
:hook ((yaml-ts-mode . combobulate-mode)
;; (css-ts-mode . combobulate-mode)
@ -730,7 +730,7 @@ The [[https://github.com/emacs-lsp/lsp-ui/blob/master/lsp-ui-imenu.el][lsp-imenu
#+begin_src emacs-lisp :tangle no
(use-package lsp-ui-imenu
:straight nil
:after lsp-ui
:config
(ha-local-leader :keymaps 'prog-mode-map
@ -1089,7 +1089,7 @@ This means, that some data like:
"data": {
"name": "Create And Wait for Service Image",
"description": "Creates a new Service Image using IMaaS",
"long_description": "This job creates a new service image with name ... blah, blah, blah",
"long_description": "This job creates a new yawxway service image with name yawxway-howard.abrams-test and docker-dev-artifactory.workday.com/dev/yawxway-service:latest docker url in development folder",
"job_id": "5e077245-0f4a-4dc9-b473-ce3ec0b811ba",
"state": "success",
"progress": "100",
@ -1296,12 +1296,12 @@ While I don't like writing them, I can't get away from them. Check out the goodi
While filename extensions work fine most of the time, I don't like to pre-pend =.sh= to the shell scripts I write, and instead, would like to associate =shell-mode= with all files in a =bin= directory:
#+begin_src emacs-lisp
(use-package sh-mode
:straight (:type built-in)
:mode (rx (or (seq ".sh" eol)
"/bin/"))
:init
(setq sh-basic-offset 4
sh-indentation 4)
(setq sh-basic-offset 2
sh-indentation 2)
:config
(ha-auto-insert-file (rx (or (seq ".sh" eol)
"/bin/"))

View file

@ -28,7 +28,7 @@ A literate configuration for accessing remote systems.
[[https://www.emacswiki.org/emacs/TrampMode][Tramp]] allows almost all Emacs features to execute on a remote system.
#+begin_src emacs-lisp
(use-package tramp
:straight (:type built-in)
:config
;; Use remote PATH on tramp (handy for eshell).
@ -42,7 +42,7 @@ A literate configuration for accessing remote systems.
Will Schenk has [[https://willschenk.com/articles/2020/tramp_tricks/][a simple extension]] to allow editing of files /inside/ a Docker container:
#+begin_src emacs-lisp
(use-package tramp
:straight (:type built-in)
:config
(push '("docker" . ((tramp-login-program "docker")
(tramp-login-args (("exec" "-it") ("%h") ("/bin/sh")))
@ -72,7 +72,7 @@ Which means, I need to put it as a link in an org file.
#+begin_src emacs-lisp
(use-package tramp-sh
:after tramp
:straight (:type built-in)
:custom (tramp-use-ssh-controlmaster-options nil))
#+end_src
* Remote Terminals
@ -159,12 +159,13 @@ While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[
#+BEGIN_SRC emacs-lisp :tangle no
(use-package eat
:straight (:host codeberg :repo "akib/emacs-eat"
:files ("*.el" ("term" "term/*.el") "*.texi"
"*.ti" ("terminfo/e" "terminfo/efo/e/*")
("terminfo/65" "terminfo/65/*")
("integration" "integration/*")
(:exclude ".dir-locals.el" "*-tests.el")))
;; :straight (:host codeberg :repo "akib/emacs-eat"
;; :files ("*.el" ("term" "term/*.el") "*.texi"
;; "*.ti" ("terminfo/e" "terminfo/efo/e/*")
;; ("terminfo/65" "terminfo/65/*")
;; ("integration" "integration/*")
;; (:exclude ".dir-locals.el" "*-tests.el")))
;; :vc (:url "https://codeberg.org/akib/emacs-eat")
:commands (eat eat-make eat-project)
:bind (:map eat-semi-char-mode-map
("C-c C-t" . ha-eat-narrow-to-shell-prompt-dwim))
@ -214,6 +215,14 @@ Let's begin by defining some variables used for communication between the functi
See =ha-ssh-add-favorite-host= for easily adding to this list.")
#+end_src
Also, let's make it easy for me to change my default shell:
#+begin_src emacs-lisp
(defvar ha-shell "bash" ;; Eat works better with Bash/Zsh
;; (string-trim (shell-command-to-string "type -p fish"))
"The executable to the shell I want to use locally.")
#+end_src
** Terminal Abstractions
Could I abstract the different ways I start terminals in Emacs? The =ha-ssh-term= starts either a [[VTerm]]
or [[Eat]] terminals, depending on what is available. This replaces (wraps) the default [[help:make-term][make-term]].
@ -224,11 +233,11 @@ or [[Eat]] terminals, depending on what is available. This replaces (wraps) the
The PROGRAM, if non-nil, is executed, otherwise, this is `ha-shell'.
STARTFILE is the initial text given to the PROGRAM, and the
SWITCHES are the command line options."
(unless program (setq program ha-shell))
(cond
((fboundp 'vterm) (progn (vterm name)
(when program
(vterm-send-string (append program switches))
(vterm-send-return))))
(vterm-send-string (append program switches))
(vterm-send-return)))
((fboundp 'eat) (progn (switch-to-buffer
(apply 'eat-make (append (list name program startfile)
switches)))

View file

@ -323,6 +323,8 @@ Lets make a /theme/:
'hamacs
`(default ((t (:foreground ,default-fg :background ,default-bg))))
`(fringe ((t :background ,default-bg)))
`(tab-bar ((t :foreground ,default-fg :background ,default-bg)))
`(tab-line ((t :foreground ,default-fg :background ,default-bg)))
`(window-divider ((t :foreground "black")))
`(cursor ((t (:foreground ,gray-10 :background ,cursor))))
`(region ((t (:background ,region))))
@ -331,11 +333,6 @@ Lets make a /theme/:
`(mode-line-active ((t (:background ,active))))
`(mode-line-inactive ((t (:background ,inactive))))
`(tab-bar ((t :foreground ,default-fg :background ,default-bg)))
`(tab-line ((t :foreground ,default-fg :background ,default-bg)))
`(tab-bar-tab ((t (:inherit variable-pitch :background ,active))))
`(tab-bar-tab-inactive ((t (:inherit variable-pitch :background ,inactive))))
`(doom-modeline-buffer-path ((t (:foreground ,almond))))
`(doom-modeline-buffer-file ((t (:foreground "white" :weight bold))))
`(doom-modeline-buffer-major-mode ((t (:foreground ,almond))))

View file

@ -23,15 +23,6 @@ gpg --homedir ~/.emacs.d/elpa/gnupg --receive-keys 066DAFCB81E42C40
cat > "$HAMACS_DEST/early-init.el" <<EOF
;;; early-init.el --- Hamacs Early Init -*- lexical-binding: t; -*-
;;
;; ▄████████ ▄▄▄▄███▄▄▄▄ ▄████████ ▄████████ ▄████████
;; ███ ███ ▄██▀▀▀███▀▀▀██▄ ███ ███ ███ ███ ███ ███
;; ███ █▀ ███ ███ ███ ███ ███ ███ █▀ ███ █▀
;; ▄███▄▄▄ ███ ███ ███ ███ ███ ███ ███
;; ▀▀███▀▀▀ ███ ███ ███▀███████████ ███ ▀███████████
;; ███ █▄ ███ ███ ███ ███ ███ ███ █▄ ███
;; ███ ███ ███ ███ ███ ███ ███ ███ ███ ▄█ ███
;; ██████████ ▀█ ███ █▀ ███ █▀ ████████▀ ▄████████▀
;;
;;; Commentary:
;;
;; This is my early Emacs configuration file. See init.el for the real
@ -78,14 +69,6 @@ echo "Created $HAMACS_DEST/early-init.el"
cat > "$HAMACS_DEST/init.el" <<EOF
;;; init.el --- Hamacs Init -*- lexical-binding: t; -*-
;;
;; :::::::::: :::: :::: ::: :::::::: ::::::::
;; :+: +:+:+: :+:+:+ :+: :+: :+: :+: :+: :+:
;; +:+ +:+ +:+:+ +:+ +:+ +:+ +:+ +:+
;; +#++:++# +#+ +:+ +#+ +#++:++#++: +#+ +#++:++#++
;; +#+ +#+ +#+ +#+ +#+ +#+ +#+
;; #+# #+# #+# #+# #+# #+# #+# #+# #+#
;; ########## ### ### ### ### ######## ########
;;
;;; Commentary:
;;
;; This is my Emacs Bootloader. Simply put, I initialize the package
@ -96,8 +79,23 @@ cat > "$HAMACS_DEST/init.el" <<EOF
(defvar hamacs-source-dir "$HAMACS_DIR" "Where we be.")
(defvar hamacs-package-repos
(file-name-concat user-emacs-directory "repos")
"Repository location for all packages.")
(defun load-path-repo (repo)
(expand-file-name repo hamacs-package-repos))
(defun hamacs-package-repos-update-load-path ()
"Update the \`load-path' with clone repositories."
(interactive)
(dolist (repo (directory-files hamacs-package-repos 'full "[A-z].*"))
(add-to-list 'load-path repo nil 'string-equal)))
(hamacs-package-repos-update-load-path)
;; Bug fixes for ORG (there always seems to be something):
(defvar native-comp-deferred-compilation-deny-list nil)
;; (defvar native-comp-deferred-compilation-deny-list nil)
;; Allow the installation of unsigned packages, but verify the
;; signature if possible:
@ -115,29 +113,7 @@ cat > "$HAMACS_DEST/init.el" <<EOF
(add-to-list 'package-archives
'("elpa-dev" . "https://elpa.gnu.org/devel/"))
;; Configure straight https://github.com/raxod502/straight.el#getting-started
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 6))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(straight-use-package 'use-package)
;; While that enables the :straight t extension to use-package, let's just have that be the default:
(use-package straight
:custom (straight-use-package-by-default t
straight-default-vc 'git))
;; See the details in https://dev.to/jkreeftmeijer/emacs-package-management-with-straight-el-and-use-package-3oc8
(setq use-package-always-ensure nil)
(use-package org
;; TODO: Using the latest org-mode

View file

@ -1,56 +0,0 @@
;; Here is a keyboard setup for an Apple Macbook keyboard to work with
;; "home row mods" where holding down keys on the home row can act like a
;; modifier, so holding down `d` and hitting `p` results in `P` being
;; entered.
;; Also includes a symbol layer accessible while holding down either
;; the `h' or `g' keys.
(defcfg
macos-dev-names-include ("Apple Internal Keyboard / Trackpad")
;; linux-dev-names-include (
;; "Microsoft Surface 045E:091C Keyboard"
;; )
)
(defsrc
` 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
caps a s d f g h j k l ; ' ret
lsft z x c v b n m , . / rsft
lctl lalt lmet spc rmet ralt
)
(defvar
tap-time 200
hold-time 200
)
(defalias
a (tap-hold $tap-time $hold-time a lmet)
s (tap-hold $tap-time $hold-time s lctl)
d (tap-hold $tap-time $hold-time d lsft)
f (tap-hold $tap-time $hold-time f lalt)
g (tap-hold $tap-time $hold-time g (layer-while-held SYMBOLS))
h (tap-hold $tap-time $hold-time h (layer-while-held SYMBOLS))
j (tap-hold $tap-time $hold-time j ralt)
k (tap-hold $tap-time $hold-time k rsft)
l (tap-hold $tap-time $hold-time l rctl)
; (tap-hold $tap-time $hold-time ; rmet)
caps (tap-hold $tap-time $hold-time esc lctl)
)
(deflayer base
` 1 2 3 4 5 6 7 8 9 0 - = bspc
tab q w e r t y u i o p [ ] \
@caps @a @s @d @f @g @h @j @k @l @; ' ret
lsft z x c v b n m , . / rsft
lctl lalt lmet spc rmet ralt
)
(deflayer SYMBOLS
_ F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 _ _ _
_ S-1 S-2 { } S-\ F16 F17 F18 F19 pgup _ _ _
_ S-3 S-4 S-9 S-0 ` left down up right pgdn _ _
_ S-5 S-6 [ ] S-` F11 F12 F13 F14 F15 _
_ _ _ _ _ _
)

View file

@ -21,7 +21,6 @@ Regardless, I keep my shell configuration conspicuously light.
Lets create the following files, and the configuration below will be injected into one of them:
- =~/.zshenv= :: Usually run for every zsh
- =~/.zprofile= :: Usually run for login shells (this includes the system-wide =/etc/zprofile=)
- =~/.zshrc= :: Run for interactive shells … default file when tangling
- =~/.zlogin= :: Run for login shells … seems to run as often as =.zshrc=
@ -44,24 +43,8 @@ Lets create the following files, and the configuration below will be injected
* Path
The all important =PATH= environment variable, needs my special =bin= directory.
#+BEGIN_SRC zsh :tangle ~/.zshenv
export PATH=$HOME/bin:$HOME/.local/bin:$PATH
#+END_SRC
My Apple Macbook screws up my =PATH= by having =/etc/profile= (that runs after my =~/.zshenv=) /pre-pend/ system directories like =/bin= and =/usr/bin= /after/ Ive set up my =PATH= environment variable. So, in my own =.zprofile= (which runs afterwards), I reverse it using the lovely =tac= program:
#+BEGIN_SRC sh :tangle ~/.zprofile :shebang #!/bin/zsh
if [[ -f /etc/zprofile ]]
then
# Reverse the PATH variable
reversed_path=$(echo $PATH | tr ':' '\n' | tac | tr '\n' ':')
# Reset the path after removing the trailing colon:
export PATH=${reversed_path%:}
# Output the reversed PATH
# echo "Reversed PATH: $reversed_path"
fi
#+BEGIN_SRC zsh :export ~/.zshenv
export PATH=$HOME/bin:/usr/local/bin:$PATH
#+END_SRC
* Options
@ -111,10 +94,7 @@ setopt MENU_COMPLETE
When using Homebrew on a Mac, we need to add its =PATH=:
#+BEGIN_SRC zsh :tangle ~/.zshenv
if [[ -d /opt/homebrew ]]
then
eval $(/opt/homebrew/bin/brew shellenv zsh)
fi
eval $(/opt/homebrew/bin/brew shellenv zsh)
#+END_SRC
This adds the following environment variables, along with expanding the =PATH=.
@ -223,16 +203,13 @@ Anything special for particular languages.
*** Python
Not overly impressed, for to get =pyenv= to work, we need to add this code:
#+BEGIN_SRC zsh :tangle ~/.zshenv
#+BEGIN_SRC zsh
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
#+END_SRC
And call the =pyenv= to initialize it:
#+BEGIN_SRC zsh
# eval "$(pyenv init --path)"
#+END_SRC
** Plugins
Configure the plugins, making sure to not use =git=, as the aliases are a pain to remember when I already have a superior Git interface in Emacs.
@ -251,7 +228,7 @@ Configure the plugins, making sure to not use =git=, as the aliases are a pain t
To have a plugin /install/, add its name to the =plugins= array variable /before/ we =source= the OMZ script:
#+begin_SRC zsh
plugins=(colorize direnv gnu-utils iterm2 macos virtualenv zbell zsh-syntax-highlighting)
plugins=(colorize direnv gnu-utils iterm2 macos pyenv virtualenv zbell zsh-syntax-highlighting)
#+END_SRC
Notice the =iterm2= plugin as well as the =macos= plugins that would be nice to figure out how to make them optionally added (although I believe they check themselves).
@ -265,26 +242,6 @@ The trick is to install some base-level plugins, and then, on my work computer,
fi
#+END_SRC
I would like to have a history /per project/, so that when I start a session for a project, my history has where I left off /for that project/ and not everything. I guess Im not the only one who [[https://github.com/ivan-cukic/zsh-per-project-history][thought of this idea]]. We first need to add his plugin to the list of supplied plugins, so do this once:
#+BEGIN_SRC zsh :tangle no
git clone https://github.com/ivan-cukic/zsh-per-project-history ~/.oh-my-zsh/plugins/per-project-history
#+END_SRC
His idea is to have a variable array, =PER_PROJECT_HISTORY_TAGS= that lists files that should identify the start of a project, and while his default seems sufficient, I am not found of the spammy message, so:
#+BEGIN_SRC zsh
declare -a PER_PROJECT_HISTORY_TAGS
export PER_PROJECT_HISTORY_TAGS=(.envrc .git)
declare -r PER_PROJECT_HISTORY_TAGS
#+END_SRC
we just need to add =per-history= to the list of plugins:
#+BEGIN_SRC zsh
plugins+=(per-project-history)
#+END_SRC
Now that Ive filled in the =plugins= variable, load OMZ and the plugins:
#+BEGIN_SRC zsh
@ -317,80 +274,6 @@ Oh use the absolute /over-the-top/ bling associated with Oh My Zshells /theme
#+END_SRC
I keep the prompt simple since all of the /gunk/ we typically put in a prompt is better placed in [[https://iterm2.com/documentation-status-bar.html][iTerm2's Status Bar]].
* Homebrew
When using Homebrew on a Mac, we need to add its =PATH= and environment variables. This is typically done by running the command:
#+BEGIN_SRC zsh :tangle no
eval $(brew shellenv zsh)
#+END_SRC
We want to add the path and environment variables into the =~/.zshenv= file, but this file should not contain any logic or code. So, lets run the command /from Emacs/, and store the results in the file.
The full script to run is:
#+BEGIN_SRC zsh :tangle no :results file :file ~/.zshenv_brew
echo '# -*- mode:sh; -*-'
if which brew >/dev/null
then
if [[ -d /opt/homebrew ]]
then
/opt/homebrew/bin/brew shellenv zsh
else
brew shellenv zsh
fi
fi
#+END_SRC
Seems that if I want the GNU versions (instead of the old ones supplied by Apple), I have to do it myself:
#+BEGIN_SRC zsh :tangle no :results file :file ~/.zshenv_gnu
echo '# -*- mode:sh; -*-'
if which brew >/dev/null
then
for PKG in binutils gettext unzip openssl texinfo mysql-client openjdk
do
if PKG_INSTALL=$(brew --prefix $PKG)
then
echo export PATH=$PKG_INSTALL/bin:'$PATH'
fi
done
for PKG in coreutils ed findutils gnu-indent gnu-sed gnu-tar grep make
do
if PKG_INSTALL=$(brew --prefix $PKG)
then
echo export PATH=$PKG_INSTALL/libexec/gnubin:'$PATH'
fi
done
fi
#+END_SRC
And linking all the GNU libraries:
#+BEGIN_SRC zsh :tangle no :results file :file ~/.zshenv_lib
echo '# -*- mode:sh; -*-'
if which brew >/dev/null
then
for PKG in readline openssl xz binutils ctags libgccjit imagemagick
do
if PKG_INSTALL=$(brew --prefix $PKG)
echo export LDFLAGS=\"-L$PKG_INSTALL/lib '$LDFLAGS'\"
echo export CPPFLAGS=\"-I$PKG_INSTALL/include '$CPPFLAGS'\"
done
echo export LDFLAGS=\"'$LDFLAGS' -L$(brew --prefix)/lib\"
echo export CPPFLAGS=\"'$CPPFLAGS' -I$(brew --prefix)/include\"
fi
#+END_SRC
And pull in all the results into the =~/.zshenv= file (why yes, this could be inlined):
#+BEGIN_SRC zsh :tangle ~/.zshenv
[[ -f $HOME/.zshenv_brew ]] && source $HOME/.zshenv_brew
[[ -f $HOME/.zshenv_gnu ]] && source $HOME/.zshenv_gnu
[[ -f $HOME/.zshenv_lib ]] && source $HOME/.zshenv_lib
#+END_SRC
* iTerm2
On Mac systems, I like the [[https://www.iterm2.com/][iTerm2 application]], and we can enable [[https://iterm2.com/documentation-shell-integration.html][shell integration]], either via the old school way, or just rely on [[https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/iterm2][the /plugin/ ]]above:
@ -441,9 +324,7 @@ While it /should/ figure out (as Emacs keybindings are the default), this is how
bindkey -e
#+END_SRC
Where be the =emacsclient=? It should, at this point, be in our path.
And how should we call it?
Where be the =emacsclient=, and how should we call it?
#+BEGIN_SRC zsh :tangle ~/.zshenv
export EMACS="emacsclient --socket-name personal"
@ -526,7 +407,7 @@ For instance:
Assuming weve installed [[https://github.com/lsd-rs/lsd][lsd]], lets make an alias for it:
#+BEGIN_SRC zsh
if which lsd >/dev/null
if whence lsd >/dev/null
then
alias ls=lsd
fi
@ -550,13 +431,6 @@ And an abstraction for transitory endpoints over SSH:
alias ossh="ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o loglevel=ERROR"
#+END_SRC
And other ones that I use:
#+BEGIN_SRC zsh
alias os=openstack
alias k=kubectl
#+END_SRC
* Final Message
For sensitive work-related environment variables, store them elsewhere, and load them:
@ -572,7 +446,6 @@ To let us know we read the =~/.zshrc= file:
#+description: A literate programming file for configuring Zshell.
#+property: header-args:zsh :tangle ~/.zshrc
#+property: header-args:sh :tangle no
#+property: header-args :results none :eval no-export :comments no mkdirp yes
#+options: num:nil toc:t todo:nil tasks:nil tags:nil date:nil
#+options: skip:nil author:nil email:nil creator:nil timestamp:nil