Minor fixes to work better with demonstrating hamacs
This commit is contained in:
parent
d816725afc
commit
23efcd2a26
9 changed files with 232 additions and 120 deletions
97
ha-demos.org
97
ha-demos.org
|
@ -2,7 +2,7 @@
|
|||
#+author: Howard X. Abrams
|
||||
#+date: 2024-10-18
|
||||
#+filetags: emacs hamacs
|
||||
#+lastmod: [2024-10-19 Sat]
|
||||
#+lastmod: [2024-10-24 Thu]
|
||||
|
||||
A literate programming file for creating and running demonstrations
|
||||
|
||||
|
@ -114,8 +114,8 @@ Instead of executing a sequence of demonstration steps, demonstrations key on
|
|||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(define-ha-demo ha-simple-demo
|
||||
(:head "New Demonstration" :i 0) (message "Howdy")
|
||||
(:head "New Demonstration" :i 1) (message "Hi there"))
|
||||
(:heading "New Demonstration" :i 0) (message "Howdy")
|
||||
(:heading "New Demonstration" :i 1) (message "Hi there"))
|
||||
|
||||
(global-set-key (kbd "<f6>") 'ha-simple-demo)
|
||||
(global-set-key (kbd "<f5>") 'org-present-next)
|
||||
|
@ -136,7 +136,7 @@ To make the contents of the expression easier to write, the =define-ha-demo= as
|
|||
(define-demo demo1
|
||||
(:buffer \"demonstrations.py\") (message \"In a buffer\")
|
||||
(:mode 'dired-mode) (message \"In a dired\")
|
||||
(:head \"Raven Civilizations\" (message \"In an org file\")))
|
||||
(:heading \"Raven Civilizations\" (message \"In an org file\")))
|
||||
|
||||
Calling `(demo1)' displays a message based on position of the
|
||||
point in a particular buffer or place in a heading in an Org file.
|
||||
|
@ -151,7 +151,7 @@ To make the contents of the expression easier to write, the =define-ha-demo= as
|
|||
(interactive)
|
||||
(let ((state (list :buffer (buffer-name)
|
||||
:mode major-mode
|
||||
:head (when (eq major-mode 'org-mode)
|
||||
:heading (when (eq major-mode 'org-mode)
|
||||
(org-get-heading)))))
|
||||
(cond
|
||||
,@(seq-map (lambda (tf-pair)
|
||||
|
@ -214,7 +214,7 @@ Let’s test:
|
|||
'(:a 1 :i 5) '((:a 1) (:b 2) (:c 3))))))
|
||||
#+END_SRC
|
||||
|
||||
But can I check if I have triggered a state once before? Let’s keep track of the /states/ that have returned true before, in a hash table where the key is the /state/ (a list of =:buffer=, =:mode=, =:head=, etc.) and the /value/ is the number of times triggered at that state:
|
||||
But can I check if I have triggered a state once before? Let’s keep track of the /states/ that have returned true before, in a hash table where the key is the /state/ (a list of =:buffer=, =:mode=, =:heading=, etc.) and the /value/ is the number of times triggered at that state:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar ha-demo-prev-state (make-hash-table :test 'equal)
|
||||
|
@ -239,6 +239,91 @@ Let’s create a function that could accept a list of /triggering keys/, and the
|
|||
(not (seq-difference triggers state)))
|
||||
#+END_SRC
|
||||
|
||||
* Demonstration Support
|
||||
What sort of functions will I often be doing?
|
||||
|
||||
** Display File
|
||||
Displaying a File with:
|
||||
- On the side or covering the entire frame
|
||||
- Larger font size
|
||||
- Modeline or no modeline
|
||||
- Going to a particular text or line
|
||||
- Moving the cursor to the top or middle of the buffer window
|
||||
|
||||
All options? Should I use Common Lisp’s =cl-defun= for the keyword parameters?
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(cl-defun ha-demo-show-file (filename &key position size modeline
|
||||
line heading shift commands)
|
||||
"Show a file, FILENAME, in a buffer based on keyed parameters.
|
||||
POSITION can be 'full 'right or 'below and positions the window.
|
||||
SIZE is an integer for the font size based on the default size.
|
||||
MODELINE is shown if non-line, default is to hide it.
|
||||
LINE is either a line number or a regular expression to match.
|
||||
SHIFT is the number of lines above the point to show, in case
|
||||
the LINE shouldn't be at the top of the window.
|
||||
|
||||
COMMANDS is a lambda expression that can contain any other
|
||||
instructions to happen to the buffer display."
|
||||
(unless position
|
||||
(setq position :right))
|
||||
|
||||
;; Step 1: Create a window
|
||||
(pcase position
|
||||
('full )
|
||||
('right (progn (split-window-horizontally) (other-window 1)))
|
||||
('below (progn (split-window-vertically) (other-window 1))))
|
||||
;; We could do :left and :top by not doing the other window bit...
|
||||
|
||||
;; Step 2: Load the file
|
||||
(find-file filename)
|
||||
(goto-char (point-min))
|
||||
|
||||
;; Step 3: Increase the font size
|
||||
(when size
|
||||
(text-scale-set size))
|
||||
|
||||
(when line
|
||||
(if (integerp line)
|
||||
(goto-line line)
|
||||
(re-search-forward line nil t)))
|
||||
|
||||
(when heading
|
||||
(re-search-forward (rx bol (one-or-more "*") (one-or-more space)
|
||||
(literal heading))
|
||||
nil t))
|
||||
|
||||
;; If SHIFT is positive integer, left that many line above point,
|
||||
;; otherwise don't do anything to leave it in the middle.
|
||||
;; If SHIFT is null, move it to the top of the buffer window:
|
||||
(if shift
|
||||
(when (integerp shift)
|
||||
(recenter-top-bottom shift))
|
||||
(recenter-top-bottom 0))
|
||||
|
||||
(unless modeline
|
||||
(setq-local mode-line-format nil))
|
||||
|
||||
(when commands (funcall commands))
|
||||
)
|
||||
|
||||
(funcall (lambda () (message "Hello")))
|
||||
#+END_SRC
|
||||
|
||||
Let try it all together:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(ha-demo-show-file "ha-config.org" :position 'right :size 1 :modeline nil :line 418 :shift 4)
|
||||
#+END_SRC
|
||||
|
||||
Or:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(ha-demo-show-file "ha-config.org" :modeline t
|
||||
:heading "Text Expanders"
|
||||
:commands (lambda () (jinx-mode -1)))
|
||||
#+END_SRC
|
||||
|
||||
* Technical Artifacts :noexport:
|
||||
Let's =provide= a name so we can =require= this file:
|
||||
|
||||
|
|
63
ha-email.org
63
ha-email.org
|
@ -64,6 +64,11 @@ To use these, we set the =:noweb yes= (to pull in the /name/ of the code block)
|
|||
smtpmail-smtp-server "smtp.gmail.com"
|
||||
smtpmail-smtp-service 587)
|
||||
#+end_src
|
||||
* Sending Mail
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(require 'smtpmail)
|
||||
#+END_SRC
|
||||
|
||||
* Installation and Basic Configuration
|
||||
To begin, we need the code. On Ubuntu, this is:
|
||||
#+begin_src shell :tangle no
|
||||
|
@ -304,9 +309,9 @@ The following option is supported here:
|
|||
exclude_tags=deleted;spam;
|
||||
#+end_src
|
||||
*** Maildir compatibility configuration
|
||||
The following option is supported here:
|
||||
This section support the following option:
|
||||
|
||||
- =synchronize_flags= :: Valid values are true and false. If true, then the following maildir flags (in message filenames) will be synchronized with the corresponding notmuch tags:
|
||||
- =synchronize_flags= :: Valid values are true and false. If true, then notmuch synchronizing the following maildir flags (in message filenames) with the corresponding notmuch tags:
|
||||
|
||||
| Flag | Tag |
|
||||
|------+---------------------------------------------|
|
||||
|
@ -325,7 +330,7 @@ The =notmuch new= command will notice flag changes in filenames and update tags,
|
|||
|
||||
That should complete the Notmuch configuration.
|
||||
** =pre-new=
|
||||
Then we need a shell script called when beginning a retrieval, =pre-new= that simply calls =mbsync= to download all the messages:
|
||||
We call this shell script when beginning a retrieval, =pre-new= that calls =mbsync= to download all the messages:
|
||||
|
||||
#+begin_src shell :tangle ~/.mail/.notmuch/hooks/pre-new :shebang "#!/bin/bash"
|
||||
# More info about hooks: https://notmuchmail.org/manpages/notmuch-hooks-5/
|
||||
|
@ -344,11 +349,9 @@ And a =post-new= hook based on a filtering scheme that mimics the Hey.com workfl
|
|||
# Based On: https://gist.githubusercontent.com/frozencemetery/5042526/raw/57195ba748e336de80c27519fe66e428e5003ab8/post-new
|
||||
# Note: We now tangle this file from ~/src/hamacs/ha-email.org
|
||||
#
|
||||
# Install this by moving this file to <maildir>/.notmuch/hooks/post-new
|
||||
# NOTE: you need to define your maildir in the vardiable nm_maildir (just a few lines below in this script)
|
||||
# Also create empty files for:
|
||||
# 1. thefeed.db (things you want to read every once in a while)
|
||||
# 2. spam.db (things you never want to see)
|
||||
# Create empty files for:
|
||||
# 1. thefeed.db (mail you want to read every once in a while)
|
||||
# 2. spam.db (mail you never want to see)
|
||||
# 3. screened.db (your inbox)
|
||||
# 4. ledger.db (papertrail)
|
||||
# in the hooks folder.
|
||||
|
@ -422,8 +425,6 @@ do
|
|||
done
|
||||
timer_end "Screened"
|
||||
|
||||
# Projects...
|
||||
|
||||
timer_start "Old-Projects"
|
||||
notmuch tag +old-project 'subject:/.*howardabrams\/node-mocks-http/'
|
||||
notmuch tag +old-project 'subject:/.*Pigmice2733/'
|
||||
|
@ -434,12 +435,12 @@ notmuch tag +screened 'subject:[Web]'
|
|||
echo "Completing not-much 'post-new' script"
|
||||
#+end_src
|
||||
* Hey
|
||||
I originally took the following configuration from [[https://youtu.be/wuSPssykPtE][Vedang Manerikar's video]], along with [[https://gist.github.com/vedang/26a94c459c46e45bc3a9ec935457c80f][the code]]. The ideas brought out were to mimic the hey.com email workflow, and while not bad, I thought that maybe I could improve upon it slowly over time.
|
||||
I originally took the following configuration from [[https://youtu.be/wuSPssykPtE][Vedang Manerikar's video]], along with [[https://gist.github.com/vedang/26a94c459c46e45bc3a9ec935457c80f][the code]]. The ideas brought out were to mimic the hey.com email workflow, and while not bad, I thought I could improve it over time.
|
||||
|
||||
To allow me to keep Vedang's and my code side-by-side in the same Emacs variable state, I have renamed the prefix to =hey-=, however, if you are looking to steal my code, you may want to revisit the source.
|
||||
To allow me to keep Vedang's and my code side-by-side in the same Emacs variable state, I have renamed the prefix to =hey-=, buf, if you are looking to steal my code, you may want to revisit the original source.
|
||||
** Default Searches
|
||||
|
||||
A list of pre-defined searches act like "Folder buttons" at the top to quickly see files that match those /buckets/:
|
||||
A list of pre-defined searches act like "Folder buttons" at the top to see files that match those /buckets/:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package notmuch
|
||||
|
@ -451,6 +452,7 @@ A list of pre-defined searches act like "Folder buttons" at the top to quickly s
|
|||
(:name "Previously Seen"
|
||||
:query "tag:screened AND NOT tag:unread"
|
||||
:key "I")
|
||||
(:name "Sent" :query "tag:sent")
|
||||
(:name "Unscreened"
|
||||
:query "tag:inbox AND tag:unread AND NOT tag:screened AND NOT date:..14d AND NOT tag:thefeed AND NOT tag:/ledger/ AND NOT tag:old-project"
|
||||
:key "s")
|
||||
|
@ -479,7 +481,7 @@ A list of pre-defined searches act like "Folder buttons" at the top to quickly s
|
|||
#+end_src
|
||||
** Helper Functions
|
||||
|
||||
With good bucket definitions, we should be able to scan the mail quickly and deal with the entire lot of them:
|
||||
With good bucket definitions, we should be able to scan the mail and deal with the entire lot:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun hey-notmuch-archive-all ()
|
||||
|
@ -495,7 +497,7 @@ With good bucket definitions, we should be able to scan the mail quickly and dea
|
|||
(hey-notmuch-archive-all))
|
||||
|
||||
(defun hey-notmuch-search-delete-and-archive-thread ()
|
||||
"Archive the currently selected thread. Add the deleted tag as well."
|
||||
"Archive the selected thread. Add the deleted tag as well."
|
||||
(interactive)
|
||||
(notmuch-search-add-tag '("+deleted"))
|
||||
(notmuch-search-archive-thread))
|
||||
|
@ -540,9 +542,12 @@ NO-DISPLAY is sent forward to `notmuch-search'."
|
|||
|
||||
(defun hey-notmuch-tag-by-from (tag-changes &optional beg end refresh)
|
||||
"Apply TAG-CHANGES to all emails from the sender of the current thread.
|
||||
BEG and END provide the region, but are ignored. They are defined
|
||||
since `notmuch-search-interactive-tag-changes' returns them. If
|
||||
REFRESH is true, refresh the buffer from which we started the
|
||||
|
||||
While defined (since `notmuch-search-interactive-tag-changes'
|
||||
returns them), this function ignores BEG and END (for the
|
||||
region).
|
||||
|
||||
If REFRESH is true, refresh the buffer from which we started the
|
||||
search."
|
||||
(interactive (notmuch-search-interactive-tag-changes))
|
||||
(let ((this-buf (current-buffer)))
|
||||
|
@ -550,9 +555,9 @@ search."
|
|||
;; This is a dirty hack since I can't find a way to run a
|
||||
;; temporary hook on `notmuch-search' completion. So instead of
|
||||
;; waiting on the search to complete in the background and then
|
||||
;; making tag-changes on it, I will just sleep for a short amount
|
||||
;; of time. This is generally good enough and works, but is not
|
||||
;; guaranteed to work every time. I'm fine with this.
|
||||
;; making tag-changes on it, I sleep for a short amount of time.
|
||||
;; This is generally good enough and works, but is not guaranteed
|
||||
;; to work every time. I'm fine with this.
|
||||
(sleep-for 0.5)
|
||||
(notmuch-search-tag-all tag-changes)
|
||||
(when refresh
|
||||
|
@ -573,8 +578,8 @@ We based the Hey buckets on notmuch databases, we combine the =hey-notmuch-add-a
|
|||
"For the email at point, move the sender of that email to the feed.
|
||||
This means:
|
||||
1. All new email should go to the feed and skip the inbox altogether.
|
||||
2. All existing email should be updated with the tag =thefeed=.
|
||||
3. All existing email should be removed from the inbox."
|
||||
2. All existing email updated with the tag `thefeed'.
|
||||
3. All existing email removed from the inbox."
|
||||
(interactive)
|
||||
(hey-notmuch-add-addr-to-db (hey-notmuch-search-find-from)
|
||||
(format "%s/thefeed.db" notmuch-hooks-dir))
|
||||
|
@ -584,8 +589,8 @@ This means:
|
|||
"For the email at point, move the sender of that email to the papertrail.
|
||||
This means:
|
||||
1. All new email should go to the papertrail and skip the inbox altogether.
|
||||
2. All existing email should be updated with the tag =ledger/TAG-NAME=.
|
||||
3. All existing email should be removed from the inbox."
|
||||
2. All existing email updated with the tag `ledger/TAG-NAME'.
|
||||
3. All existing email removed from the inbox."
|
||||
(interactive "sTag Name: ")
|
||||
(hey-notmuch-add-addr-to-db (format "%s %s"
|
||||
tag-name
|
||||
|
@ -597,8 +602,8 @@ This means:
|
|||
(defun hey-notmuch-move-sender-to-screened ()
|
||||
"For the email at point, move the sender of that email to Screened Emails.
|
||||
This means:
|
||||
1. All new email should be tagged =screened= and show up in the inbox.
|
||||
2. All existing email should be updated to add the tag =screened=."
|
||||
1. All new email tagged `screened' and show up in the inbox.
|
||||
2. All existing email updated to add the tag `screened'."
|
||||
(interactive)
|
||||
(hey-notmuch-add-addr-to-db (hey-notmuch-search-find-from)
|
||||
(format "%s/screened.db" notmuch-hooks-dir))
|
||||
|
@ -759,3 +764,7 @@ 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
|
||||
|
||||
# Local Variables:
|
||||
# jinx-local-words: "notmuch"
|
||||
# End:
|
||||
|
|
|
@ -73,12 +73,14 @@ If any program wants to pause the output through the =$PAGER= variable, well, we
|
|||
#+end_src
|
||||
** Argument Completion
|
||||
Shell completion uses the flexible =pcomplete= mechanism internally, which allows you to program the completions per shell command. To know more, check out this [[https://www.masteringemacs.org/article/pcomplete-context-sensitive-completion-emacs][blog post]], about how to configure =pcomplete= for git commands. The [[https://github.com/JonWaltman/pcmpl-args.el][pcmpl-args]] package extends =pcomplete= with completion support for more commands, like the Fish and other modern shells. I love how a package can gives benefits without requiring learning anything.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package pcmpl-args)
|
||||
#+end_src
|
||||
Note that this will work with =shell-command= as well.
|
||||
** Better Command Line History
|
||||
On [[http://www.reddit.com/r/emacs/comments/1zkj2d/advanced_usage_of_eshell/][this discussion]] a little gem for using IDO to search back through the history, instead of =M-R= to prompt for the history.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun eshell-insert-history ()
|
||||
"Displays the eshell history to select and insert back into your eshell."
|
||||
|
|
34
ha-evil.org
34
ha-evil.org
|
@ -91,31 +91,39 @@ I’m not a long term VI user, and I generally like /easy keys/, e.g. ~w~, have
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package evil
|
||||
:config
|
||||
(require 'evil-commands)
|
||||
(evil-define-key '(normal visual motion operator) 'global
|
||||
:config (require 'evil-commands)
|
||||
(evil-define-key
|
||||
'(normal visual motion operator) 'global
|
||||
"w" 'evil-forward-WORD-begin
|
||||
"W" 'evil-forward-word-begin
|
||||
"e" 'evil-forward-WORD-end
|
||||
"E" 'evil-forward-word-end
|
||||
"E" 'evil-forward-word-end)
|
||||
#+END_SRC
|
||||
|
||||
;; This may be an absolute heresy to most VI users,
|
||||
;; but I'm Evil and really, I use M-x and SPC instead.
|
||||
;; Besides, I don't know any : colon commands...
|
||||
":" 'evil-repeat-find-char-reverse)
|
||||
The ~b~ key bindings seems to need their own call, and I’m not sure why I can’t include it in the ~w~ and ~e~ bindings.
|
||||
|
||||
;; The `b' key seems to need its own configuration setting:
|
||||
(evil-define-key '(normal visual motion operator) 'global
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(evil-define-key
|
||||
'(normal visual motion operator) 'global
|
||||
"b" 'evil-backward-WORD-begin)
|
||||
(evil-define-key '(normal visual motion operator) 'global
|
||||
"B" 'evil-backward-word-begin))
|
||||
;; Note that evil-backward-word-end is on the `g e':
|
||||
(evil-define-key
|
||||
'(normal visual motion operator) 'global
|
||||
"B" 'evil-backward-word-begin)
|
||||
#+end_src
|
||||
|
||||
In other words, with the above settings in place, ~w~ and ~e~ should jump from front to back of the entire line, but ~W~ and ~E~ should stop as /subword/:
|
||||
- =word-subword-subword=
|
||||
- =word_subword_subword=
|
||||
|
||||
Note I don’t bind =evil-backward-word-end= with a single key, but bind it to ~g e~ below.
|
||||
|
||||
While an absolute heresy to most VI users, I'm Evil and use ~M-x~ and ~SPC~ instead of ~:~ for running commands. I bind the ~:~ as a reverse of the ~;~ which continues the search from ~f~ and ~t~:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(evil-define-key
|
||||
'(normal visual motion operator) 'global
|
||||
":" 'evil-repeat-find-char-reverse))
|
||||
#+END_SRC
|
||||
|
||||
This clever hack from [[https://manueluberti.eu//emacs/2022/10/16/back-last-edit/][Manuel Uberti]] got me finding these useful bindings:
|
||||
- ~g ;~ :: [[help:goto-last-change][goto-last-change]]
|
||||
- ~g ,~ :: [[help:goto-last-change-reverse][goto-last-change-reverse]]
|
||||
|
|
|
@ -59,12 +59,12 @@ The =org-indent-indentation-per-level=, which defaults to =2= doesn’t really w
|
|||
:custom-face (org-indent ((t (:inherit fixed-pitch)))))
|
||||
#+end_src
|
||||
|
||||
Finally, let’s add frame borders and window dividers:
|
||||
The following adds frame borders and window dividers to give space between window buffers. Do I need this when my Org files indent the text? Dunno, but it makes the view more pleasant.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(modify-all-frames-parameters
|
||||
'((right-divider-width . 20)
|
||||
(internal-border-width . 20)))
|
||||
'((right-divider-width . 2)
|
||||
(internal-border-width . 10)))
|
||||
|
||||
(dolist (face '(window-divider
|
||||
window-divider-first-pixel
|
||||
|
|
64
ha-org.org
64
ha-org.org
|
@ -283,7 +283,15 @@ Came up with a great way to search a project for Org-specific files, and wrote [
|
|||
(ha-leader "f o" '("load org" . org-find-file)))
|
||||
#+end_src
|
||||
|
||||
Now that my paragraphs in an org file are on a single line, I could use =rg= (or some other =grep= program), but being able to use an /indexed search system/, like [[https://ss64.com/osx/mdfind.html][mdfind]] on Macos, or [[https://www.lesbonscomptes.com/recoll/][recoll]] on Linux, gives better results than line-oriented search systems. Let’s create operating-system functions the command line for searching:
|
||||
Now that my paragraphs in an org file are on a single line, I could use =rg= (or some other =grep= program), but being able to use an /indexed search system/, like [[https://ss64.com/osx/mdfind.html][mdfind]] on Macos, or [[https://www.lesbonscomptes.com/recoll/][recoll]] on Linux, gives better results than line-oriented search systems.
|
||||
|
||||
While =mdfind= is builtin to MacOS, we need to install =recoll=:
|
||||
|
||||
#+BEGIN_SRC sh
|
||||
sudo apt install -y recoll
|
||||
#+END_SRC
|
||||
|
||||
Let’s create operating-system functions the command line for searching:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-search-notes--macos (phrase path)
|
||||
|
@ -322,9 +330,12 @@ This function calls the above-mentioned operating-system-specific functions, but
|
|||
#+end_src
|
||||
Let’s see it in action:
|
||||
#+begin_src emacs-lisp :tangle no :results replace
|
||||
(ha-search-notes--files "openstack grafana" '("~/Notes"))
|
||||
(ha-search-notes--files "bread" '("~/personal"))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: ':3:common/rclinit.cpp:391::Recoll 1.36.1 + Xapian 1.4.22 [/home/howard/.recoll]'
|
||||
|
||||
Returns this string:
|
||||
#+begin_example
|
||||
"'/Users/howard.abrams/Notes/Sprint-2022-25.org' '/Users/howard.abrams/Notes/Sprint-2022-03.org' '/Users/howard.abrams/Notes/Sprint-2020-45.org' '/Users/howard.abrams/Notes/Sprint-2022-09.org' '/Users/howard.abrams/Notes/Sprint-2022-05.org' '/Users/howard.abrams/Notes/Sprint-2022-01.org' '/Users/howard.abrams/Notes/Sprint-2022-19.org'"
|
||||
|
@ -384,14 +395,6 @@ And turn on ALL the languages:
|
|||
(plantuml . t)))
|
||||
#+end_src
|
||||
|
||||
The [[https://github.com/isamert/corg.el][corg project]] does completing feature for all the block header values. To do this, type ~M-Tab~ (not just regular ~Tab~).
|
||||
|
||||
#+begin_src emacs-lisp :results list :hlines yes
|
||||
(use-package corg
|
||||
:straight (:host github :repo "isamert/corg.el")
|
||||
:hook (org-mode . 'corg-setup))
|
||||
#+end_src
|
||||
|
||||
*** Searching Literate Files
|
||||
A noweb definition, e.g. =<<something-something>>= could /jump/ to the =#name= definition.
|
||||
Since [[https://github.com/BurntSushi/ripgrep][ripgrep]] is pretty fast, I’ll call it instead of attempting to build a [[https://stackoverflow.com/questions/41933837/understanding-the-ctags-file-format][CTAGS]] table. Oooh, the =rg= takes a =—json= option, which makes it easier to parse.
|
||||
|
@ -470,7 +473,21 @@ And let’s try this:
|
|||
#+end_src
|
||||
|
||||
*** Graphviz
|
||||
The [[https://graphviz.org/][graphviz project]] can be written in org blocks, and then rendered as an image:
|
||||
Using the [[https://graphviz.org/][graphviz project]], create charts with /textual instructions/ (code), and then rendered as an image. First setup Graphviz configuration using [[https://github.com/ppareit/graphviz-dot-mode][graphviz-dot-mode]]:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package graphviz-dot-mode
|
||||
:mode "\\.dot\\'"
|
||||
:init
|
||||
(setq tab-width 4
|
||||
graphviz-dot-indent-width 2
|
||||
graphviz-dot-auto-indent-on-newline t
|
||||
graphviz-dot-auto-indent-on-braces t
|
||||
graphviz-dot-auto-indent-on-semi t))
|
||||
#+end_src
|
||||
|
||||
Next, add it to org-babel:
|
||||
|
||||
#+name: ob-graphviz
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(add-to-list 'org-src-lang-modes '("dot" . "graphviz-dot"))
|
||||
|
@ -547,7 +564,7 @@ Here is a sequence diagram example to show how is looks/works:
|
|||
#+attr_org: :width 800px
|
||||
[[file:ha-org-plantuml-example.png]]
|
||||
*** Pikchr
|
||||
No, not Pikachu, but close. The [[https://pikchr.org/home/doc/trunk/homepage.md][Pikchr project]] is similar to Graphviz and Plantuml, but makes the boxes more positional and really allows one to place things more precisely. Yet another steep learning curve.
|
||||
No, not Pikachu, but close. Unlike Graphviz and Plantuml, the [[https://pikchr.org/home/doc/trunk/homepage.md][Pikchr project]] makes boxes more positional and allows one to place the parts more precisely. Yet another steep learning curve.
|
||||
|
||||
Not sure if anyone has made a /package/, so we need to download and build locally:
|
||||
#+begin_src sh :dir ~/bin
|
||||
|
@ -556,17 +573,18 @@ Not sure if anyone has made a /package/, so we need to download and build locall
|
|||
gcc -DPIKCHR_SHELL -o ~/bin/pikchr ~/bin/pikchr.c -lm # to build the pikchr command-line tool
|
||||
#+end_src
|
||||
|
||||
Of course, since we are dealing with Emacs, any good idea will be assimilated. Johann Klähn created [[https://github.com/kljohann/pikchr-mode][pikchr-mode]]:
|
||||
Of course, since we are dealing with Emacs, where we assimilate any good idea. Johann Klähn created [[https://github.com/kljohann/pikchr-mode][pikchr-mode]]:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package pikchr-mode
|
||||
:straight (:local-repo "~/src/pikchr-mode")
|
||||
;; :straight (:host github :repo "kljohann/pikchr-mode")
|
||||
:custom
|
||||
(pikchr-executable "~/bin/pikchr"))
|
||||
#+end_src
|
||||
|
||||
Let’s see this in action:
|
||||
#+begin_src pikchr :file ha-org-pikchr-01.svg :results file :exports both
|
||||
#+begin_src pikchr :file ha-org-pikchr-01.png :results file :exports both
|
||||
bgcolor = 0x1d2021
|
||||
fgcolor = 0xeeeeee
|
||||
line; box "Hello," "World!"; arrow
|
||||
|
@ -600,7 +618,9 @@ We edit the code with [[https://github.com/abrochard/mermaid-mode][mermaid-mode]
|
|||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package mermaid-mode
|
||||
:config
|
||||
(setq mermaid-mmdc-location "/opt/homebrew/bin/mmdc"))
|
||||
(setq mermaid-mmdc-location (if (file-exists-p "/opt/homebrew")
|
||||
"/opt/homebrew/bin/mmdc"
|
||||
"/usr/local/bin/mmdc")))
|
||||
#+END_SRC
|
||||
|
||||
We can make Mermaid diagrams in Emacs Org files using [[https://github.com/arnm/ob-mermaid][ob-mermaid]]:
|
||||
|
@ -608,7 +628,7 @@ We can make Mermaid diagrams in Emacs Org files using [[https://github.com/arnm/
|
|||
#+BEGIN_SRC emacs-lisp
|
||||
(use-package ob-mermaid
|
||||
:config
|
||||
(setq ob-mermaid-cli-path "/opt/homebrew/bin/mmdc"))
|
||||
(setq ob-mermaid-cli-path mermaid-mmdc-location))
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC mermaid :file ha-org-mermaid.png :theme dark :background-color transparent
|
||||
|
@ -752,18 +772,6 @@ I have a special version of tweaked [[file:elisp/ox-confluence.el][Confluence ex
|
|||
"o E" '("to confluence" . ox-export-to-confluence)))
|
||||
#+end_src
|
||||
|
||||
And Graphviz configuration using [[https://github.com/ppareit/graphviz-dot-mode][graphviz-dot-mode]]:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package graphviz-dot-mode
|
||||
:mode "\\.dot\\'"
|
||||
:init
|
||||
(setq tab-width 4
|
||||
graphviz-dot-indent-width 2
|
||||
graphviz-dot-auto-indent-on-newline t
|
||||
graphviz-dot-auto-indent-on-braces t
|
||||
graphviz-dot-auto-indent-on-semi t))
|
||||
#+end_src
|
||||
|
||||
*** HTML Style
|
||||
|
||||
I’m 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]]:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: python-src-block
|
||||
# key: #sp
|
||||
# key: <sp
|
||||
# --
|
||||
#+BEGIN_SRC python
|
||||
$0
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Loading…
Reference in a new issue