Compare commits
6 commits
d30ae9a78b
...
c20eda48a8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c20eda48a8 | ||
|
|
82afd54a9c | ||
|
|
97e9b86026 | ||
|
|
d9f3ec8806 | ||
|
|
db51a66d8c | ||
|
|
c40a3827b3 |
15 changed files with 234 additions and 145 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
A literate programming file for bootstraping my Emacs Configuration.
|
A literate programming file for bootstraping my Emacs Configuration.
|
||||||
|
|
||||||
#+begin_src emacs-lisp :exports none
|
#+begin_src emacs-lisp :exports none
|
||||||
;;; bootstrap.el --- file for bootstraping my Emacs Configuration
|
;;; bootstrap.el --- file for bootstraping my Emacs Configuration -*- lexical-binding: t; -*-
|
||||||
;;
|
;;
|
||||||
;; ██████████
|
;; ██████████
|
||||||
;; ░░███░░░░░█
|
;; ░░███░░░░░█
|
||||||
|
|
@ -51,7 +51,7 @@ Limit garbage collection before startup and then go back to the default value (8
|
||||||
|
|
||||||
(add-hook 'emacs-startup-hook
|
(add-hook 'emacs-startup-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(setq gc-cons-threshold (* 100 1024 1024))))
|
(setq gc-cons-threshold (* 200 1024 1024))))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** OS Path and Native Compilation
|
** OS Path and Native Compilation
|
||||||
|
|
@ -167,7 +167,7 @@ Much of my more complicated code comes from my website essays and other projects
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
* Emacs Server Control
|
* Emacs Server Control
|
||||||
I actually run two instances of Emacs on some systems, where one instance has all my work-related projects, perspectives, and packages installed (like LSP), and my personal instance has other packages running (like IRC and Mail). I need a function that can make that distinction, and based on that, it will set =server-start= appropriately, so that =emacsclient= can call into the correct one.
|
I actually run two instances of Emacs on some systems, where one instance has all my work-related projects, perspectives, and packages installed (like the Language Server Protocol, LSP), and my personal instance has other packages running (like the Internet Relay Chat, IRC, and Mail). I need a function that can make that distinction, and based on that, it will set =server-start= appropriately, so that =emacsclient= can call into the correct one.
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defun ha-emacs-for-work? ()
|
(defun ha-emacs-for-work? ()
|
||||||
"Return non-nil when the Emacs instance is for work.
|
"Return non-nil when the Emacs instance is for work.
|
||||||
|
|
@ -210,7 +210,6 @@ The following /defines/ the rest of my org-mode literate files, that I load late
|
||||||
"ha-org-literate.org"
|
"ha-org-literate.org"
|
||||||
"ha-org-clipboard.org"
|
"ha-org-clipboard.org"
|
||||||
"ha-capturing-notes.org"
|
"ha-capturing-notes.org"
|
||||||
"ha-code-notes.org"
|
|
||||||
"ha-agendas.org"
|
"ha-agendas.org"
|
||||||
"ha-data.org"
|
"ha-data.org"
|
||||||
"ha-passwords.org"
|
"ha-passwords.org"
|
||||||
|
|
@ -230,6 +229,7 @@ The following /defines/ the rest of my org-mode literate files, that I load late
|
||||||
"ha-org-publishing.org"
|
"ha-org-publishing.org"
|
||||||
"ha-email.org"
|
"ha-email.org"
|
||||||
"ha-aux-apps.org"))
|
"ha-aux-apps.org"))
|
||||||
|
"ha-code-notes.org"
|
||||||
"ha-dashboard.org"))
|
"ha-dashboard.org"))
|
||||||
"List of org files that complete the hamacs project.")
|
"List of org files that complete the hamacs project.")
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
@ -241,7 +241,7 @@ The list of /hamacs/ org-formatted files stored in =ha-hamacs-files= is selectiv
|
||||||
(if (not all)
|
(if (not all)
|
||||||
ha-hamacs-files
|
ha-hamacs-files
|
||||||
|
|
||||||
(thread-last (rx ".org" string-end)
|
(thread-last (rx (not ".") (+? any) ".org" string-end)
|
||||||
(directory-files hamacs-source-dir nil)
|
(directory-files hamacs-source-dir nil)
|
||||||
(append ha-hamacs-files)
|
(append ha-hamacs-files)
|
||||||
(--filter (not (string-match (rx "README") it)))
|
(--filter (not (string-match (rx "README") it)))
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ A literate programming file configuring critical applications.
|
||||||
;; And tangle the file to recreate this one.
|
;; And tangle the file to recreate this one.
|
||||||
;;
|
;;
|
||||||
;;; Code:
|
;;; Code:
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
Can we call the following /applications/? I guess.
|
Can we call the following /applications/? I guess.
|
||||||
* Agentic Interface
|
* Agentic Interface
|
||||||
|
|
@ -158,14 +158,8 @@ And point Emacs to it:
|
||||||
|
|
||||||
(setq agent-shell-anthropic-claude-acp-command
|
(setq agent-shell-anthropic-claude-acp-command
|
||||||
(if (file-exists-p "/opt/homebrew")
|
(if (file-exists-p "/opt/homebrew")
|
||||||
(list (file-expand-wildcards "/opt/homebrew/bin/claude-agent-acp"))
|
(file-expand-wildcards "/opt/homebrew/bin/claude-agent-acp")
|
||||||
'("/usr/local/bin/claude-agent-acp")))
|
'("/usr/local/bin/claude-agent-acp"))))
|
||||||
|
|
||||||
(when (file-exists-p "~/.zshenv-work")
|
|
||||||
(setq agent-shell-anthropic-claude-environment (agent-shell-make-environment-variables
|
|
||||||
:load-env "~/.zshenv-work"))))
|
|
||||||
|
|
||||||
;; /opt/homebrew/Cellar/node/26.0.0/bin/claude-agent-acp
|
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
*** Cursor
|
*** Cursor
|
||||||
|
|
@ -227,36 +221,6 @@ And let’s make that the default now:
|
||||||
:config
|
:config
|
||||||
(setq agent-shell-preferred-agent-config (agent-shell-google-make-gemini-config)))
|
(setq agent-shell-preferred-agent-config (agent-shell-google-make-gemini-config)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
** AI Code Interface
|
|
||||||
While the =agent-shell= offers a /vibe-codey/ interface to Chatbots, the [[https://github.com/tninja/ai-code-interface.el][ai-code-interface]] offers a more /programmatic/ interface.
|
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
|
||||||
(use-package ai-code
|
|
||||||
:straight (:host github :repo "tninja/ai-code-interface.el")
|
|
||||||
:config
|
|
||||||
;; use codex as backend, other options are 'claude-code, 'gemini,
|
|
||||||
;; 'github-copilot-cli, 'opencode, 'grok, 'cursor, 'kiro,
|
|
||||||
;; 'codebuddy, 'aider, 'eca, 'agent-shell, 'claude-code-ide,
|
|
||||||
;; 'claude-code-el
|
|
||||||
(ai-code-set-backend 'gemini)
|
|
||||||
|
|
||||||
;; Enable global keybinding for the main menu
|
|
||||||
(global-set-key (kbd "C-c a") #'ai-code-menu)
|
|
||||||
|
|
||||||
;; Optional: Enable @ file completion in comments and AI sessions
|
|
||||||
(ai-code-prompt-filepath-completion-mode 1)
|
|
||||||
|
|
||||||
;; Optional: Ask AI to run test after code changes, for a tighter build-test loop
|
|
||||||
;; (setq ai-code-auto-test-type 'ask-me)
|
|
||||||
|
|
||||||
;; Optional: In AI session buffers, SPC in Evil normal state triggers the prompt-enter UI
|
|
||||||
;; (with-eval-after-load 'evil (ai-code-backends-infra-evil-setup))
|
|
||||||
|
|
||||||
;; Optional: Set up Magit integration for AI commands in Magit popups
|
|
||||||
(with-eval-after-load 'magit
|
|
||||||
(ai-code-magit-setup-transients)))
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
* Git and Magit
|
* 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.
|
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
|
#+begin_src emacs-lisp
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,22 @@ This allows me to /wax poetic/ with a parallel, but separate org file. Of course
|
||||||
|
|
||||||
If this isn’t good for you, check out [[https://github.com/agoodman42/montag][Montag]]. Same project, different approach using a single directory for all notes with [[https://www.orgroam.com/][org-roam]].
|
If this isn’t good for you, check out [[https://github.com/agoodman42/montag][Montag]]. Same project, different approach using a single directory for all notes with [[https://www.orgroam.com/][org-roam]].
|
||||||
|
|
||||||
|
Let’s create a pattern for what a notes file is, and how to recognize them:
|
||||||
|
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defconst ha-code-notes-rx (rx (optional "/")
|
||||||
|
"." (one-or-more (not "/")) "-notes.org" string-end))
|
||||||
|
|
||||||
|
(defun ha-code-notes-file (file &optional parent)
|
||||||
|
"Return a FILE's 'code notes' filename.
|
||||||
|
Prepend the PARENT if given."
|
||||||
|
(cond
|
||||||
|
((and parent (string-match-p (rx "/" string-end) parent))
|
||||||
|
(format "%s.%s-notes.org" parent file))
|
||||||
|
(parent (format "%s/.%s-notes.org" parent file))
|
||||||
|
(t (format ".%s-notes.org" file))))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
Another feature when looking at the notes in the org buffer, is to hit the same key to return to the source code file referencing the notes.
|
Another feature when looking at the notes in the org buffer, is to hit the same key to return to the source code file referencing the notes.
|
||||||
|
|
||||||
# TODO Create custom settings to override default behavior.
|
# TODO Create custom settings to override default behavior.
|
||||||
|
|
@ -109,17 +125,18 @@ This was far gnarlier than I originally thought, since IMenu only wants to /inte
|
||||||
|
|
||||||
(file qualified-name offset)"
|
(file qualified-name offset)"
|
||||||
(let* ((here (point))
|
(let* ((here (point))
|
||||||
(entry (thread-last (imenu--make-index-alist t)
|
(entry (ignore-errors
|
||||||
;; Flatten hierarchy labels with dot separators:
|
(thread-last (imenu--make-index-alist t)
|
||||||
(ha-code-notes-location--flatten-index)
|
;; Flatten hierarchy labels with dot separators:
|
||||||
;; Filter to only entries that occur after point:
|
(ha-code-notes-location--flatten-index)
|
||||||
(seq-filter (lambda (e) (<= (cdr e) here)))
|
;; Filter to only entries that occur after point:
|
||||||
;; Sort the remaining entries by position
|
(seq-filter (lambda (e) (<= (cdr e) here)))
|
||||||
;; (since out flatten-index function
|
;; Sort the remaining entries by position
|
||||||
;; doesn't guarantee the order):
|
;; (since out flatten-index function
|
||||||
(seq-sort-by #'cdr #'>)
|
;; doesn't guarantee the order):
|
||||||
;; And the first entry on the list is our goal:
|
(seq-sort-by #'cdr #'>)
|
||||||
car)))
|
;; And the first entry on the list is our goal:
|
||||||
|
car))))
|
||||||
(unless entry
|
(unless entry
|
||||||
(error "No enclosing definition found for point"))
|
(error "No enclosing definition found for point"))
|
||||||
(list (buffer-file-name)
|
(list (buffer-file-name)
|
||||||
|
|
@ -131,8 +148,8 @@ The needed /trick/ is to flatten this IMenu hierarchy using this recursive beaut
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun ha-code-notes-location--flatten-index (alist &optional prefix)
|
(defun ha-code-notes-location--flatten-index (alist &optional prefix)
|
||||||
"Flatten imenu ALIST into a list of (QUALIFIED-NAME . POSITION).
|
"Flatten imenu ALIST into a list of (NAME . POSITION).
|
||||||
Where the qualified-name matches what which-function/imenu expect.
|
Where the name matches what which-function/imenu expect.
|
||||||
|
|
||||||
For instance:
|
For instance:
|
||||||
|
|
||||||
|
|
@ -142,47 +159,115 @@ The needed /trick/ is to flatten this IMenu hierarchy using this recursive beaut
|
||||||
|
|
||||||
((\"foo_class.method_one\" ...) (\"foo_class.method_two\" ...)...)
|
((\"foo_class.method_one\" ...) (\"foo_class.method_two\" ...)...)
|
||||||
|
|
||||||
This is called recursively, so PREFIX could be a class name, or
|
Called recursively, where PREFIX could be a class name, or other higher
|
||||||
other higher abstraction."
|
abstraction when the nesting represents a real outline (Org, Markdown).
|
||||||
;; Like `mapconcat' but lets us concat into something other than a string.
|
|
||||||
;; Note that `mapcan' uses `nconc' which _mutates_ the `alist'.
|
Entries tagged with `imenu-kind' or `breadcrumb-kind' property (as Eglot
|
||||||
;; This is fine as a parameter that we then return:
|
nests a function's local variables for Python) are already a flat
|
||||||
|
namespace of functions/variables/constants, so their own names are kept
|
||||||
|
bare and not qualified by an enclosing function's name."
|
||||||
(mapcan
|
(mapcan
|
||||||
(lambda (entry)
|
(lambda (entry)
|
||||||
;; Some imenu backends (e.g. python.el) annotate names with their
|
(unless (or (null entry) (atom entry))
|
||||||
;; category, e.g. "Pair (class)" or "sum (def)". Strip that so
|
(let* ((raw-name (car entry))
|
||||||
;; names match what `which-function'/`add-log-current-defun'
|
(kind (and (stringp raw-name)
|
||||||
;; produce, and what gets stored as XREF_NAME in notes files.
|
(or (get-text-property 0 'imenu-kind raw-name)
|
||||||
(let* ((name (replace-regexp-in-string
|
(get-text-property 0 'breadcrumb-kind raw-name))))
|
||||||
(rx space "(" (one-or-more alpha) ")" string-end)
|
(name (if (stringp raw-name)
|
||||||
"" (car entry)))
|
(replace-regexp-in-string
|
||||||
(value (cdr entry))
|
(rx space "(" (one-or-more alpha) ")" string-end)
|
||||||
(qualified (if prefix (format "%s.%s" prefix name) name)))
|
"" (substring-no-properties raw-name))
|
||||||
(if (listp value)
|
(format "%s" raw-name)))
|
||||||
(ha-code-notes-location--flatten-index value qualified)
|
(value (cdr entry))
|
||||||
(list (cons qualified (if (markerp value) (marker-position value) value))))))
|
(qualified (if (and prefix (not kind)) (format "%s.%s" prefix name) name)))
|
||||||
|
(cond
|
||||||
|
;; Case 1: Nested submenu (list of alist entries). Eglot
|
||||||
|
;; never gives the container itself a position among its
|
||||||
|
;; children, as Org does; it stashes it in the
|
||||||
|
;; `imenu-region' text property instead, so recover it
|
||||||
|
;; here. Children only inherit QUALIFIED as their prefix
|
||||||
|
;; when this entry has no `imenu-kind' of its own -- i.e.
|
||||||
|
;; when the nesting is a real outline, not Eglot's flat
|
||||||
|
;; function/variable/constant tagging.
|
||||||
|
((and (listp value) (consp (car value)))
|
||||||
|
(append
|
||||||
|
(let ((region (and (stringp raw-name)
|
||||||
|
(get-text-property 0 'imenu-region raw-name))))
|
||||||
|
(when region (list (cons qualified (car region)))))
|
||||||
|
(ha-code-notes-location--flatten-index value (unless kind qualified))))
|
||||||
|
|
||||||
|
;; Case 2: Direct marker or integer position
|
||||||
|
((integer-or-marker-p value)
|
||||||
|
(list (cons qualified (if (markerp value) (marker-position value) value))))
|
||||||
|
|
||||||
|
;; Case 3: Overlay or element containing a position in car/cdr
|
||||||
|
((overlayp value)
|
||||||
|
(list (cons qualified (overlay-start value))))
|
||||||
|
|
||||||
|
((and (consp value) (integer-or-marker-p (car value)))
|
||||||
|
(list (cons qualified (if (markerp (car value))
|
||||||
|
(marker-position (car value))
|
||||||
|
(car value)))))
|
||||||
|
|
||||||
|
;; Fallback: ignore non-positional Imenu metadata entries
|
||||||
|
(t nil)))))
|
||||||
alist))
|
alist))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
This flatten feature has been a pain in my side. An org-mode formatted file works well, for instance, running the following on this document:
|
||||||
|
#+BEGIN_SRC emacs-lisp :tangle no :results replace value raw :export both :wrap example
|
||||||
|
(ha-code-notes-location--flatten-index (imenu--make-index-alist t))
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
#+RESULTS:
|
||||||
|
#+begin_example
|
||||||
|
((*Rescan* . -99) (Introduction . 946) (Helper Functions.Relative Code Locations . 3719) (Helper Functions.Org Properties . 13220) (Helper Functions . 3592) (Write a Note.Return to Source Code . 22408) (Write a Note.Fringe Indicators for Notes . 24001) (Write a Note . 17005) (Technical Artifacts . 27464))
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
But running the same expression on a Python file (via Eglot) nests the local variables and parameters of each function as children in the index, each tagged with an =imenu-kind= text property on its name, e.g. a function like this:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
(#("parse_args" 0 10 (imenu-region (1245 . 1627) imenu-kind "Function" breadcrumb-region (1245 . 1627) breadcrumb-kind "Function"))
|
||||||
|
(#("argv" 0 4 (imenu-region (1260 . 1289) imenu-kind "Variable" ...)) . 1260)
|
||||||
|
(#("parser" 0 6 (imenu-region (1365 . 1371) imenu-kind "Variable" ...)) . 1365))
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Naively flattening this treats =argv= and =parser= as if they were nested methods, producing useless entries like ~parse_args.argv~. Worse, the function itself never had its own position among its children (unlike Org, which gives a parent headline a self-pointing entry), so there was no way to jump straight to ~parse_args~ at all.
|
||||||
|
|
||||||
|
The fix: the presence of an =imenu-kind=/=breadcrumb-kind= property means the nesting is Eglot's flat function/variable/constant tagging, not a real outline -- so a child's name is never qualified by its parent's. When recursing into a nested submenu, the container's own position is recovered from its =imenu-region= text property, and the name is stripped of text properties. That turns the above into clean, bare entries for every name -- function, variable, and constant alike:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
((parse_args . 1245) (argv . 1260) (parser . 1365) (registry_credentials . 1630) ...)
|
||||||
|
#+end_example
|
||||||
|
|
||||||
Once inside a source file, we can jump to one of these /relative locations/:
|
Once inside a source file, we can jump to one of these /relative locations/:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun ha-code-notes-location-goto (file name offset)
|
(defun ha-code-notes-location-goto (file name offset)
|
||||||
"Move point to the position described by relative location.
|
"Move point to the position described by relative location.
|
||||||
|
|
||||||
FILE is the filename to load, may be nil to use current buffer.
|
FILE is the filename to load, may be nil to use current buffer.
|
||||||
NAME is a function name or other definition, e.g. ClassName.method
|
NAME is a function name or other definition, e.g. ClassName.method
|
||||||
OFFSET is the number of lines below NAME to position the point."
|
OFFSET is the number of lines below NAME to position the point."
|
||||||
(when (and file (not (equal file (buffer-file-name))))
|
(when (and file (not (equal file (buffer-file-name))))
|
||||||
(find-file-other-window file))
|
(find-file-other-window file))
|
||||||
|
|
||||||
|
(condition-case t
|
||||||
|
(ha-code-notes--location-goto name offset)
|
||||||
|
(message "Definition `%s' no longer found in %s" name file))
|
||||||
|
|
||||||
|
(ignore-errors
|
||||||
|
))
|
||||||
|
|
||||||
|
(defun ha-code-notes--location-goto (name &optional offset)
|
||||||
|
"Use `imenu' interface to goto NAME location.
|
||||||
|
If OFFSET given, move that many lines below."
|
||||||
(let* ((index (ha-code-notes-location--flatten-index (imenu--make-index-alist t)))
|
(let* ((index (ha-code-notes-location--flatten-index (imenu--make-index-alist t)))
|
||||||
(entry (assoc name index)))
|
(entry (assoc name index)))
|
||||||
(if (not entry)
|
(when entry
|
||||||
(message "Definition `%s' no longer found in %s" name file)
|
|
||||||
(goto-char (cdr entry))
|
(goto-char (cdr entry))
|
||||||
(when offset
|
(when offset
|
||||||
(forward-line offset)))))
|
(forward-line offset)))))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
To verify that this works:
|
To verify that this works:
|
||||||
|
|
@ -297,8 +382,7 @@ This function defines what the notes filename should look like, loads it in a si
|
||||||
|
|
||||||
;; Keep in mind the `orig-parent' has a final slash, so the
|
;; Keep in mind the `orig-parent' has a final slash, so the
|
||||||
;; initial . here marks it as hidden:
|
;; initial . here marks it as hidden:
|
||||||
(note-file (format "%s.%s-notes.org"
|
(note-file (ha-code-notes-file orig-base orig-parent))
|
||||||
orig-parent orig-base))
|
|
||||||
(header (which-function))
|
(header (which-function))
|
||||||
(offset (ha-code-notes-defun-rel-line)))
|
(offset (ha-code-notes-defun-rel-line)))
|
||||||
|
|
||||||
|
|
@ -322,7 +406,7 @@ Use the builtin autoinsert feature to inject a basic template at the beginning o
|
||||||
(use-package autoinsert
|
(use-package autoinsert
|
||||||
:config
|
:config
|
||||||
(define-auto-insert
|
(define-auto-insert
|
||||||
(cons (rx "/." (one-or-more (not "/")) "-notes.org" string-end) "Org Notes Template")
|
(cons ha-code-notes-rx "Org Notes Template")
|
||||||
'("Short description: "
|
'("Short description: "
|
||||||
"#+TITLE: "
|
"#+TITLE: "
|
||||||
(s-titleized-words (s-replace-regexp (rx (any "-" "_")) " "
|
(s-titleized-words (s-replace-regexp (rx (any "-" "_")) " "
|
||||||
|
|
@ -435,10 +519,7 @@ And give us keybinding that will either go to the notes (if we are in some code)
|
||||||
"Open the notes buffer, or return to the code."
|
"Open the notes buffer, or return to the code."
|
||||||
(interactive)
|
(interactive)
|
||||||
(when (buffer-file-name)
|
(when (buffer-file-name)
|
||||||
(if (string-match (rx "/." ; A hidden file
|
(if (string-match ha-code-notes-rx (buffer-file-name))
|
||||||
(one-or-more (not "/"))
|
|
||||||
"-notes.org" string-end)
|
|
||||||
(buffer-file-name))
|
|
||||||
(ha-code-notes-return)
|
(ha-code-notes-return)
|
||||||
(ha-code-notes))))
|
(ha-code-notes))))
|
||||||
|
|
||||||
|
|
@ -472,22 +553,27 @@ A code file with an associated notes file is easy to forget about. Let's mark, i
|
||||||
|
|
||||||
(defun ha-code-notes--fringe ()
|
(defun ha-code-notes--fringe ()
|
||||||
"Mark, in the fringe, every line in this buffer that has a note.
|
"Mark, in the fringe, every line in this buffer that has a note.
|
||||||
Notes live in the paired `.BASE-notes.org' file (see
|
Notes live in the paired `.BASE-notes.org' file (see
|
||||||
`ha-code-notes') as headings whose XREF property matches this
|
`ha-code-notes') as headings whose XREF property matches this
|
||||||
file, XREF_NAME names the function (inherited by subheadings from
|
file, XREF_NAME names the function (inherited by subheadings from
|
||||||
their parent), and XREF_LINE is a line offset from that function's
|
their parent), and XREF_LINE is a line offset from that function's
|
||||||
start, computed by `ha-code-notes-defun-rel-line'. We resolve each
|
start, computed by `ha-code-notes-defun-rel-line'. We resolve each
|
||||||
pair back to an absolute line via `ha-code-notes-location-goto', since the function
|
pair back to an absolute line via `ha-code-notes-location-goto', since the function
|
||||||
may have moved since the note was taken."
|
may have moved since the note was taken."
|
||||||
(mapc #'delete-overlay ha-code-notes--fringe-overlays)
|
(mapc #'delete-overlay ha-code-notes--fringe-overlays)
|
||||||
|
|
||||||
(setq ha-code-notes--fringe-overlays nil)
|
(setq ha-code-notes--fringe-overlays nil)
|
||||||
(let* ((orig-file (buffer-file-name))
|
(let* ((orig-file (buffer-file-name))
|
||||||
(note-file (and orig-file
|
(note-file (and orig-file
|
||||||
(format "%s.%s-notes.org"
|
(ha-code-notes-file
|
||||||
(file-name-directory orig-file)
|
(file-name-directory orig-file)
|
||||||
(file-name-base orig-file))))
|
(file-name-base orig-file))))
|
||||||
notes)
|
notes)
|
||||||
(when (and note-file (file-exists-p note-file))
|
;; Only run if this is an actual file AND its notes file exists:
|
||||||
|
(when (and orig-file
|
||||||
|
note-file
|
||||||
|
(file-exists-p note-file)
|
||||||
|
(not (string-match-p ha-code-notes-rx orig-file)))
|
||||||
(with-temp-buffer
|
(with-temp-buffer
|
||||||
(insert-file-contents note-file)
|
(insert-file-contents note-file)
|
||||||
(org-mode)
|
(org-mode)
|
||||||
|
|
@ -516,7 +602,7 @@ New notes and edited notes should refresh the markers too, so we hook into savin
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(defun ha-code-notes--fringe-notes-refresh-all ()
|
(defun ha-code-notes--fringe-notes-refresh-all ()
|
||||||
"Refresh fringe note markers in every buffer after saving a notes file."
|
"Refresh fringe note markers in every buffer after saving a notes file."
|
||||||
(when (string-match (rx "-notes.org" string-end) (buffer-file-name))
|
(when (string-match ha-code-notes-rx (buffer-file-name))
|
||||||
(dolist (buf (buffer-list))
|
(dolist (buf (buffer-list))
|
||||||
(with-current-buffer buf
|
(with-current-buffer buf
|
||||||
(when buffer-file-name
|
(when buffer-file-name
|
||||||
|
|
|
||||||
|
|
@ -535,17 +535,18 @@ The nerd font package takes a popular font like "Iosevka" and jams a bunch of th
|
||||||
|
|
||||||
** Symbols and Emojis
|
** Symbols and Emojis
|
||||||
|
|
||||||
Display these two symbols as one character, as using [[Ligatures]] often stretches wider, and the following are nice to be collapsed:
|
Display these two symbols as one character, as using [[Ligatures]] often stretches wider, and the following are nice to be collapsed into a single glyph:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(add-hook 'text-mode-hook (lambda ()
|
(add-hook 'text-mode-hook (lambda ()
|
||||||
(dolist (pair '(("!?" . "‽")
|
(dolist (pair '(("!?" . "‽")
|
||||||
("ae" . "æ")
|
|
||||||
("..." . "…") ; ??
|
|
||||||
("??" . "⁇")
|
("??" . "⁇")
|
||||||
;; ("<<" . "«")
|
("<<" . "«")
|
||||||
;; (">>" . "»")
|
(">>" . "»")
|
||||||
("AE" . "Æ")))
|
(":-)" . "🙂")
|
||||||
|
(":-D" . "😃")
|
||||||
|
(";-)" . "😉")
|
||||||
|
("..." . "…")))
|
||||||
(push pair prettify-symbols-alist))))
|
(push pair prettify-symbols-alist))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -366,7 +366,7 @@ This expands on my global [[file:ha-config.org::*Bookmarks][Bookmarks]]:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package bookmark-in-project
|
(use-package bookmark-in-project
|
||||||
:bindd
|
:bind
|
||||||
(("C-x r m" . bookmark-in-project-toggle)
|
(("C-x r m" . bookmark-in-project-toggle)
|
||||||
("C-x r M" . ha-bookmark-set))
|
("C-x r M" . ha-bookmark-set))
|
||||||
:config
|
:config
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#+author: Howard Abrams
|
#+author: Howard Abrams
|
||||||
#+date: 2024-07-07
|
#+date: 2024-07-07
|
||||||
#+filetags: emacs hamacs
|
#+filetags: emacs hamacs
|
||||||
#+lastmod: [2026-08-05 Wed]
|
#+lastmod: [2026-09-22 Tue]
|
||||||
|
|
||||||
A literate programming file for literate programming in Emacs Org Files.
|
A literate programming file for literate programming in Emacs Org Files.
|
||||||
|
|
||||||
|
|
@ -19,16 +19,15 @@ A literate programming file for literate programming in Emacs Org Files.
|
||||||
;;
|
;;
|
||||||
;; While obvious, GNU Emacs does not include this file or project.
|
;; While obvious, GNU Emacs does not include this file or project.
|
||||||
;;
|
;;
|
||||||
|
;; *NB:* Do not edit this file. Instead, edit the original literate file at:
|
||||||
|
;; ~/src/hamacs/ha-org-literate.org
|
||||||
|
;; Using `find-file-at-point', and tangle the file to recreate this.
|
||||||
|
;;
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
;;
|
;;
|
||||||
;; This file contains a collection of functions to easy some of the
|
;; This file contains a collection of functions to easy some of the
|
||||||
;; sharp edges when doing literate programming in Org files.
|
;; sharp edges when doing literate programming in Org files.
|
||||||
;;
|
;;
|
||||||
;; *NB:* Do not edit this file. Instead, edit the original
|
|
||||||
;; literate file at:
|
|
||||||
;; ~/src/hamacs/ha-org-literate.org
|
|
||||||
;; And tangle the file to recreate this one.
|
|
||||||
;;
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
#+end_src
|
#+end_src
|
||||||
* Introduction
|
* Introduction
|
||||||
|
|
@ -937,13 +936,9 @@ Let's =provide= a name so we can =require= this file:
|
||||||
#+DESCRIPTION: literate programming in Emacs Org Files.
|
#+DESCRIPTION: literate programming in Emacs Org Files.
|
||||||
|
|
||||||
#+PROPERTY: header-args:sh :tangle no
|
#+PROPERTY: header-args:sh :tangle no
|
||||||
#+PROPERTY: header-args:emacs-lisp :tangle yes :comments link
|
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
||||||
#+PROPERTY: header-args :results none :eval no-export :comments no mkdirp yes
|
#+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: num:nil toc:t todo:nil tasks:nil tags:nil date:nil
|
||||||
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
|
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil
|
||||||
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
#+INFOJS_OPT: view:nil toc:nil ltoc:t mouse:underline buttons:0 path:http://orgmode.org/org-info.js
|
||||||
|
|
||||||
# Local Variables:
|
|
||||||
# jinx-local-words: "parseable"
|
|
||||||
# End:
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
#+date: 2020-09-18
|
#+date: 2020-09-18
|
||||||
#+tags: emacs org
|
#+tags: emacs org
|
||||||
#+startup: inlineimages
|
#+startup: inlineimages
|
||||||
#+lastmod: [2026-08-10 Mon]
|
#+lastmod: [2026-10-09 Fri]
|
||||||
|
|
||||||
A literate programming file for configuring org-mode and those files.
|
A literate programming file for configuring org-mode and those files.
|
||||||
|
|
||||||
|
|
@ -940,7 +940,7 @@ Since the /definitions/ do not work, so let's use the [[https://github.com/abo-a
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(use-package define-word
|
(use-package define-word
|
||||||
:config
|
:config
|
||||||
(ha-leader :keymaps 'text-mode-map
|
(ha-leader
|
||||||
"s d" '(:ignore t :which-key "dictionary")
|
"s d" '(:ignore t :which-key "dictionary")
|
||||||
"s d d" '("define this word" . define-word-at-point)
|
"s d d" '("define this word" . define-word-at-point)
|
||||||
"s d a" '("define any word" . define-word)))
|
"s d a" '("define any word" . define-word)))
|
||||||
|
|
@ -1183,7 +1183,8 @@ I create a configuration file in my home directory:
|
||||||
"stop-words": false,
|
"stop-words": false,
|
||||||
"terminology": { "severity": "warning" },
|
"terminology": { "severity": "warning" },
|
||||||
"unexpanded-acronym": { "severity": "warning" },
|
"unexpanded-acronym": { "severity": "warning" },
|
||||||
"write-good": false
|
"write-good": false,
|
||||||
|
"unexpanded-acronym": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
|
||||||
|
|
@ -1498,16 +1498,6 @@ Integration with the [[https://github.com/bash-lsp/bash-language-server][Bash LS
|
||||||
#+begin_src sh
|
#+begin_src sh
|
||||||
brew install bash-language-server
|
brew install bash-language-server
|
||||||
#+end_src
|
#+end_src
|
||||||
*** Fish Shell
|
|
||||||
I think the [[https://fishshell.com/][fish shell]] is an interesting experiment (and I appreciate the basics that come with [[https://github.com/emacsmirror/fish-mode][fish-mode]]).
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(use-package fish-mode
|
|
||||||
:mode (rx ".fish" eol)
|
|
||||||
:config
|
|
||||||
(ha-auto-insert-file (rx ".fish") "fish-mode.sh")
|
|
||||||
:hook
|
|
||||||
(fish-mode . (lambda () (add-hook 'before-save-hook 'fish_indent-before-save))))
|
|
||||||
#+end_src
|
|
||||||
* Technical Artifacts :noexport:
|
* Technical Artifacts :noexport:
|
||||||
Provide a name to =require= this code.
|
Provide a name to =require= this code.
|
||||||
#+begin_src emacs-lisp :exports none
|
#+begin_src emacs-lisp :exports none
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ I'm not giving up on Eshell, but I am playing around with [[https://github.com/a
|
||||||
|
|
||||||
VTerm has an issue (at least for me) with ~M-Backspace~ not deleting the previous word, and yeah, I want to make sure that both keystrokes do the same thing.
|
VTerm has an issue (at least for me) with ~M-Backspace~ not deleting the previous word, and yeah, I want to make sure that both keystrokes do the same thing.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp :tangle no
|
||||||
(use-package vterm
|
(use-package vterm
|
||||||
:config
|
:config
|
||||||
(setq vterm-shell "zsh"
|
(setq vterm-shell "zsh"
|
||||||
|
|
@ -162,7 +162,7 @@ An odd use case I have: working in a Terminal session in one buffer window, and
|
||||||
|
|
||||||
Now, I can type: ~s-G~ (with the shift), select the line with Avy, and type ~N~ to have it copy/paste into the buffer:
|
Now, I can type: ~s-G~ (with the shift), select the line with Avy, and type ~N~ to have it copy/paste into the buffer:
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp :tangle no
|
||||||
(use-package vterm
|
(use-package vterm
|
||||||
:config
|
:config
|
||||||
(defun ha-vterm-avy-paste-line ()
|
(defun ha-vterm-avy-paste-line ()
|
||||||
|
|
@ -180,7 +180,7 @@ Now, I can type: ~s-G~ (with the shift), select the line with Avy, and type ~N~
|
||||||
** Eat
|
** Eat
|
||||||
While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[https://codeberg.org/akib/emacs-eat][Emulate a Terminal]] project (eat) is fast enough, and doesn’t require a dedicate library that requires re-compilation. While offering [[https://elpa.nongnu.org/nongnu-devel/doc/eat.html][online documentation]], I’m glad for an [[info:eat#Top][Info version]].
|
While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[https://codeberg.org/akib/emacs-eat][Emulate a Terminal]] project (eat) is fast enough, and doesn’t require a dedicate library that requires re-compilation. While offering [[https://elpa.nongnu.org/nongnu-devel/doc/eat.html][online documentation]], I’m glad for an [[info:eat#Top][Info version]].
|
||||||
|
|
||||||
#+BEGIN_SRC emacs-lisp :tangle no
|
#+BEGIN_SRC emacs-lisp
|
||||||
(use-package eat
|
(use-package eat
|
||||||
:straight (:host codeberg :repo "akib/emacs-eat"
|
:straight (:host codeberg :repo "akib/emacs-eat"
|
||||||
:files ("*.el" ("term" "term/*.el") "*.texi"
|
:files ("*.el" ("term" "term/*.el") "*.texi"
|
||||||
|
|
@ -192,6 +192,25 @@ While not as fast as [[https://github.com/akermu/emacs-libvterm][vterm]], the [[
|
||||||
:bind (:map eat-semi-char-mode-map
|
:bind (:map eat-semi-char-mode-map
|
||||||
("C-c C-t" . ha-eat-narrow-to-shell-prompt-dwim))
|
("C-c C-t" . ha-eat-narrow-to-shell-prompt-dwim))
|
||||||
:config
|
:config
|
||||||
|
;; Red:
|
||||||
|
(set-face-attribute 'eat-term-color-1 nil :foreground "#b78077")
|
||||||
|
(set-face-attribute 'eat-term-color-9 nil :foreground "#d45d4c")
|
||||||
|
;; Green:
|
||||||
|
(set-face-attribute 'eat-term-color-2 nil :foreground "#879a39")
|
||||||
|
(set-face-attribute 'eat-term-color-10 nil :foreground "#66800b")
|
||||||
|
;; Yellow:
|
||||||
|
(set-face-attribute 'eat-term-color-2 nil :foreground "#d0a215")
|
||||||
|
(set-face-attribute 'eat-term-color-10 nil :foreground "#ad8301")
|
||||||
|
;; Blue
|
||||||
|
(set-face-attribute 'eat-term-color-2 nil :foreground "#4385be")
|
||||||
|
(set-face-attribute 'eat-term-color-10 nil :foreground "#205ea6")
|
||||||
|
;; Magenta:
|
||||||
|
(set-face-attribute 'eat-term-color-2 nil :foreground "#ce5d97")
|
||||||
|
(set-face-attribute 'eat-term-color-10 nil :foreground "#a02f6f")
|
||||||
|
;; Cyan
|
||||||
|
(set-face-attribute 'eat-term-color-2 nil :foreground "#3aa99f")
|
||||||
|
(set-face-attribute 'eat-term-color-10 nil :foreground "#24837b")
|
||||||
|
|
||||||
(defun ha-eat-narrow-to-shell-prompt-dwim ()
|
(defun ha-eat-narrow-to-shell-prompt-dwim ()
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (buffer-narrowed-p) (widen) (eat-narrow-to-shell-prompt)))
|
(if (buffer-narrowed-p) (widen) (eat-narrow-to-shell-prompt)))
|
||||||
|
|
@ -214,8 +233,6 @@ What about Evil mode?
|
||||||
|
|
||||||
TODO: Like =eshell=, the Bash in an EAT terminal has a command =_eat_msg= that takes a handler, and a /message/. Then set up an alist of =eat-message-handler-alist= to decide what to do with it.
|
TODO: Like =eshell=, the Bash in an EAT terminal has a command =_eat_msg= that takes a handler, and a /message/. Then set up an alist of =eat-message-handler-alist= to decide what to do with it.
|
||||||
|
|
||||||
TODO: Need to /subtlize/ the =eat-term-color-bright-green= and other settings as it is way too garish.
|
|
||||||
|
|
||||||
Make sure you add the following for Bash:
|
Make sure you add the following for Bash:
|
||||||
|
|
||||||
#+BEGIN_SRC bash :tangle no
|
#+BEGIN_SRC bash :tangle no
|
||||||
|
|
|
||||||
14
ha-theme.org
14
ha-theme.org
|
|
@ -438,6 +438,20 @@ Let’s make a /theme/:
|
||||||
`(term-color-bright-yellow ((t (:foreground ,yellow))))
|
`(term-color-bright-yellow ((t (:foreground ,yellow))))
|
||||||
`(term-color-bright-cyan ((t (:foreground ,slate))))
|
`(term-color-bright-cyan ((t (:foreground ,slate))))
|
||||||
|
|
||||||
|
`(ansi-color-red ((t (:foreground ,red2-lt :background nil))))
|
||||||
|
`(ansi-color-green ((t (:foreground ,green-lt :background nil))))
|
||||||
|
`(ansi-color-blue ((t (:foreground ,blue-lt :background nil))))
|
||||||
|
`(ansi-color-magenta ((t (:foreground ,purple-lt :background nil))))
|
||||||
|
`(ansi-color-yellow ((t (:foreground ,yellow-lt :background nil))))
|
||||||
|
`(ansi-color-cyan ((t (:foreground ,slate :background nil))))
|
||||||
|
`(ansi-color-bright-red ((t (:foreground ,red2 :background nil))))
|
||||||
|
`(ansi-color-bright-green ((t (:foreground ,green :background nil))))
|
||||||
|
`(ansi-color-bright-blue ((t (:foreground ,blue :background nil))))
|
||||||
|
`(ansi-color-bright-magenta ((t (:foreground ,purple :background nil))))
|
||||||
|
`(ansi-color-bright-yellow ((t (:foreground ,yellow :background nil))))
|
||||||
|
`(ansi-color-bright-cyan ((t (:foreground ,slate :background nil))))
|
||||||
|
`(ansi-color-bright-black ((t (:foreground ,gray-50 :background nil))))
|
||||||
|
|
||||||
`(sh-heredoc ((t (:foreground ,almond))))
|
`(sh-heredoc ((t (:foreground ,almond))))
|
||||||
`(sh-quoted-exec ((t (:foreground ,orange2-lt))))
|
`(sh-quoted-exec ((t (:foreground ,orange2-lt))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#+author: Howard X. Abrams
|
#+author: Howard X. Abrams
|
||||||
#+date: 2025-11-24
|
#+date: 2025-11-24
|
||||||
#+filetags: emacs hamacs
|
#+filetags: emacs hamacs
|
||||||
#+lastmod: [2026-09-11 Fri]
|
#+lastmod: [2026-10-09 Fri]
|
||||||
|
|
||||||
A literate programming file for configuring Hammerspoon.
|
A literate programming file for configuring Hammerspoon.
|
||||||
|
|
||||||
|
|
@ -76,7 +76,7 @@ To create specific key bindings for starting applications, I can:
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hs.hotkey.bind({"alt", "ctrl", "shift"}, "F", function()
|
hs.hotkey.bind({"alt", "ctrl", "shift"}, "F", function()
|
||||||
hs.application.launchOrFocus("Firefox")
|
hs.application.launchOrFocus("Vivaldi")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hs.hotkey.bind({"alt", "ctrl", "shift"}, "C", function()
|
hs.hotkey.bind({"alt", "ctrl", "shift"}, "C", function()
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,8 @@ cat > "$HAMACS_DEST/init.el" <<EOF
|
||||||
(add-to-list 'package-archives
|
(add-to-list 'package-archives
|
||||||
'("elpa-dev" . "https://elpa.gnu.org/devel/"))
|
'("elpa-dev" . "https://elpa.gnu.org/devel/"))
|
||||||
|
|
||||||
|
(setq package-enable-at-startup nil)
|
||||||
|
|
||||||
;; Configure straight https://github.com/raxod502/straight.el#getting-started
|
;; Configure straight https://github.com/raxod502/straight.el#getting-started
|
||||||
|
|
||||||
(defvar bootstrap-version)
|
(defvar bootstrap-version)
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,4 @@
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
`yas-selected-text`
|
`yas-selected-text`
|
||||||
#+BEGIN_SRC `(ha-org-block-language-and)`
|
#+BEGIN_SRC `(ha-org-block-language-and)`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@
|
||||||
* Work Issues
|
* Work Issues
|
||||||
$0
|
$0
|
||||||
|
|
||||||
* Onboarding Work
|
|
||||||
See [[file:Onboarding-Work.org][Onboard-Work]] for all details.
|
|
||||||
|
|
||||||
* Distractions and Support
|
* Distractions and Support
|
||||||
Anything that doesn't fit the above goes here.
|
Anything that doesn't fit the above goes here.
|
||||||
|
|
||||||
|
|
|
||||||
31
zshell.org
31
zshell.org
|
|
@ -224,6 +224,12 @@ Using the =colorize= plugin (see [[Plugins][plugins section below]]), we customi
|
||||||
export ZSH_COLORIZE_STYLE="coffee"
|
export ZSH_COLORIZE_STYLE="coffee"
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
While we are at it, let’s make it easier to read the =ls= output:
|
||||||
|
|
||||||
|
#+BEGIN_SRC zsh
|
||||||
|
export LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=33:so=01;35:do=01;35:bd=33;01:cd=33;01:or=31;01:mi=00:su=37:sg=30:ca=00:tw=30:ow=34:st=37:ex=01;32:*.7z=01;31:*.ace=01;31:*.alz=01;31:*.apk=01;31:*.arc=01;31:*.arj=01;31:*.bz=01;31:*.bz2=01;31:*.cab=01;31:*.cpio=01;31:*.crate=01;31:*.deb=01;31:*.drpm=01;31:*.dwm=01;31:*.dz=01;31:*.ear=01;31:*.egg=01;31:*.esd=01;31:*.gz=01;31:*.jar=01;31:*.lha=01;31:*.lrz=01;31:*.lz=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.lzo=01;31:*.pyz=01;31:*.rar=01;31:*.rpm=01;31:*.rz=01;31:*.sar=01;31:*.swm=01;31:*.t7z=01;31:*.tar=01;31:*.taz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tgz=01;31:*.tlz=01;31:*.txz=01;31:*.tz=01;31:*.tzo=01;31:*.tzst=01;31:*.udeb=01;31:*.war=01;31:*.whl=01;31:*.wim=01;31:*.xz=01;31:*.z=01;31:*.zip=01;31:*.zoo=01;31:*.zst=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.jxl=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.crdownload=00;90:*.dpkg-dist=00;90:*.dpkg-new=00;90:*.dpkg-old=00;90:*.dpkg-tmp=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:*.swp=00;90:*.tmp=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
|
||||||
** Language Support
|
** Language Support
|
||||||
Anything special for particular languages.
|
Anything special for particular languages.
|
||||||
|
|
@ -486,8 +492,15 @@ The =EDITOR= variable that some programs use to edit files from the command line
|
||||||
With these variables defined, we can create simple aliases:
|
With these variables defined, we can create simple aliases:
|
||||||
|
|
||||||
#+BEGIN_SRC zsh
|
#+BEGIN_SRC zsh
|
||||||
alias e="$EDITOR"
|
if [[ -n "$INSIDE_EMACS" ]]
|
||||||
alias te="$EDITOR"
|
then
|
||||||
|
# If we are already in Emacs, no need to stall the terminal:
|
||||||
|
e() { emacsclient --eval "(find-file-other-window \"$1\")" }
|
||||||
|
te() { emacsclient --eval "(find-file \"$1\")" }
|
||||||
|
else
|
||||||
|
alias e="$EDITOR"
|
||||||
|
alias te="$EDITOR"
|
||||||
|
fi
|
||||||
alias ee="emacsclient --create-frame"
|
alias ee="emacsclient --create-frame"
|
||||||
alias eee="emacsclient --create-frame --no-wait"
|
alias eee="emacsclient --create-frame --no-wait"
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
@ -496,7 +509,7 @@ With these variables defined, we can create simple aliases:
|
||||||
|
|
||||||
To work with [[https://github.com/akermu/emacs-libvterm][VTerm in Emacs]], we need to create this function:
|
To work with [[https://github.com/akermu/emacs-libvterm][VTerm in Emacs]], we need to create this function:
|
||||||
|
|
||||||
#+BEGIN_SRC zsh
|
#+BEGIN_SRC zsh :tangle no
|
||||||
vterm_printf() {
|
vterm_printf() {
|
||||||
if [ -n "$TMUX" ] \
|
if [ -n "$TMUX" ] \
|
||||||
&& { [ "${TERM%%-*}" = "tmux" ] \
|
&& { [ "${TERM%%-*}" = "tmux" ] \
|
||||||
|
|
@ -515,7 +528,7 @@ To work with [[https://github.com/akermu/emacs-libvterm][VTerm in Emacs]], we ne
|
||||||
|
|
||||||
This allows us to execute Emacs commands:
|
This allows us to execute Emacs commands:
|
||||||
|
|
||||||
#+BEGIN_SRC zsh
|
#+BEGIN_SRC zsh :tangle no
|
||||||
vterm_cmd() {
|
vterm_cmd() {
|
||||||
local vterm_elisp
|
local vterm_elisp
|
||||||
vterm_elisp=""
|
vterm_elisp=""
|
||||||
|
|
@ -529,7 +542,7 @@ This allows us to execute Emacs commands:
|
||||||
|
|
||||||
For instance:
|
For instance:
|
||||||
|
|
||||||
#+BEGIN_SRC zsh
|
#+BEGIN_SRC zsh :tangle no
|
||||||
if [[ "$INSIDE_EMACS" = 'vterm' ]]
|
if [[ "$INSIDE_EMACS" = 'vterm' ]]
|
||||||
then
|
then
|
||||||
alias clear='vterm_printf "51;Evterm-clear-scrollback";tput clear'
|
alias clear='vterm_printf "51;Evterm-clear-scrollback";tput clear'
|
||||||
|
|
@ -540,6 +553,14 @@ For instance:
|
||||||
fi
|
fi
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
|
** Eat a Terminal
|
||||||
|
To work with [[:ha-remoting.org::*Eat][Eat]], we need to load up its integration library:
|
||||||
|
|
||||||
|
#+BEGIN_SRC zsh :tangle no
|
||||||
|
[ -n "$EAT_SHELL_INTEGRATION_DIR" ] && source "$EAT_SHELL_INTEGRATION_DIR/zsh"
|
||||||
|
#+END_SRC
|
||||||
|
|
||||||
|
The problem with the Eat integration is it prepends a =0= that doesn’t seem to signify anything useful.
|
||||||
* Aliases
|
* Aliases
|
||||||
Assuming we’ve installed [[https://github.com/lsd-rs/lsd][lsd]], let’s make an alias for it:
|
Assuming we’ve installed [[https://github.com/lsd-rs/lsd][lsd]], let’s make an alias for it:
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue