Compare commits
6 commits
4267673853
...
71168110e0
Author | SHA1 | Date | |
---|---|---|---|
|
71168110e0 | ||
|
88f2b35e3f | ||
|
45cd891452 | ||
|
f2287c59a0 | ||
|
2317cc5d37 | ||
|
d4737e5528 |
28 changed files with 352 additions and 172 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,3 +6,5 @@
|
|||
/incubate.org
|
||||
/elisp/bookmark+*.el
|
||||
/.DS_Store
|
||||
/elisp/gourmet.el
|
||||
/elisp/wd-imaas.el
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#+title: My Emacs Configuration
|
||||
#+author: Howard X. Abrams
|
||||
#+date: 2021-11-01 November
|
||||
#+tags: emacs readme
|
||||
#+date: 2021-11-01
|
||||
#+filetags: emacs readme
|
||||
#+startup: inlineimages
|
||||
|
||||
** Introduction
|
||||
I’ve crafted my Emacs configuration, I cheekily call /hamacs/, in a literate programming model, heavily inspired by my recent journey into [[https://www.youtube.com/watch?v=LKegZI9vWUU][Henrik Lissner's]] [[https://github.com/hlissner/doom-emacs][Doom Emacs]] and [[https://www.spacemacs.org/][Spacemacs]]. While I used both extensively, I decided I would /roll my own/ as Emacs people like myself, tend to be /control freaks/ (at least a little bit).
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ The [[https://github.com/syohex/emacs-git-gutter-fringe][git-gutter-fringe]] pro
|
|||
;; To have both flymake and git-gutter work, we put
|
||||
;; git-gutter on the right side:
|
||||
(git-gutter-fr:side 'right-fringe)
|
||||
(left-fringe-width 15)
|
||||
;; (left-fringe-width 15)
|
||||
(right-fringe-width 10)
|
||||
|
||||
:config
|
||||
|
@ -457,7 +457,7 @@ Web pages look pretty good with EWW, but I'm having difficulty getting it to ren
|
|||
#+end_src
|
||||
|
||||
This function allows Imenu to offer HTML headings in EWW buffers, helpful for navigating long, technical documents.
|
||||
#+begin_src emacs-lisp
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package eww
|
||||
:config
|
||||
(defun unpackaged/imenu-eww-headings ()
|
||||
|
@ -489,7 +489,7 @@ Make my EWW browsers /look/ like an Org file with the [[https://github.com/cheny
|
|||
:straight (:host github :repo "chenyanming/shrface")
|
||||
:config
|
||||
(shrface-basic)
|
||||
(shrface-trial)
|
||||
;; (shrface-trial)
|
||||
;; (shrface-default-keybindings) ; setup default keybindings
|
||||
(setq shrface-href-versatile t)
|
||||
|
||||
|
@ -500,17 +500,18 @@ Make my EWW browsers /look/ like an Org file with the [[https://github.com/cheny
|
|||
("J" shrface-headline-consult "Goto Heading")))))
|
||||
#+end_src
|
||||
|
||||
And connect it to EWW:
|
||||
The following connection to EWW throws errors now. Hrm.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package eww
|
||||
:after shrface
|
||||
:hook (eww-after-render #'shrface-mode))
|
||||
#+end_src
|
||||
|
||||
** Get Pocket
|
||||
The [[https://github.com/alphapapa/pocket-reader.el][pocket-reader]] project connects to the [[https://getpocket.com/en/][Get Pocket]] service.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package pocket-reader
|
||||
:init
|
||||
(setq org-web-tools-pandoc-sleep-time 1)
|
||||
|
|
|
@ -152,7 +152,10 @@ I'm thinking the [[https://zevlg.github.io/telega.el/][Telega package]] would be
|
|||
:config
|
||||
(setq telega-user-use-avatars nil
|
||||
telega-use-tracking-for nil ; '(any pin unread)
|
||||
telega-chat-use-markdown-formatting t
|
||||
;; Use org formatting for normal messages.
|
||||
;; Want to send the org markup without formatting?
|
||||
;; The `nil' sets that with `C-u' then Return:
|
||||
telega-chat-input-markups '("org" nil)
|
||||
telega-emoji-use-images t
|
||||
; telega-completing-read-function #'ivy-completing-read
|
||||
telega-msg-rainbow-title nil)
|
||||
|
|
|
@ -967,8 +967,25 @@ Need to make sure that Emacs will handle the prompts, and turn it on:
|
|||
:config
|
||||
(setenv "GPG_AGENT_INFO" nil)
|
||||
(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
|
||||
(use-package org
|
||||
:config
|
||||
(require 'org-crypt)
|
||||
|
||||
(org-crypt-use-before-save-magic)
|
||||
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
|
||||
;; GPG key to use for encryption
|
||||
;; Either the Key ID or set to nil to use symmetric encryption.
|
||||
(setq org-crypt-key nil))
|
||||
#+end_src
|
||||
|
||||
* Technical Artifacts :noexport:
|
||||
Let's provide a name so we can =require= this file:
|
||||
#+begin_src emacs-lisp :exports none
|
||||
|
|
|
@ -75,15 +75,21 @@ 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
|
||||
(dimmer-configure-which-key) ; Do not dim these special windows
|
||||
(dimmer-configure-hydra)
|
||||
(dimmer-configure-magit)
|
||||
|
||||
(dimmer-mode t))
|
||||
:custom (dimmer-adjustment-mode :foreground))
|
||||
#+end_src
|
||||
|
||||
I get issues with Magic and Dimmer, so let’s 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.
|
||||
* Find the Bloody Cursor
|
||||
Large screen, lots of windows, so where is the cursor? While I used to use =hl-line+=, I found that the prolific [[https://protesilaos.com/][Protesilaos Stavrou]] [[https://protesilaos.com/codelog/2022-03-14-emacs-pulsar-demo/][introduced his Pulsar project]] is just what I need. Specifically, I might /loose the cursor/ and need to have it highlighted (using ~F8~), but also, this automatically highlights the cursor line with specific /actions/ , like changing windows.
|
||||
|
|
|
@ -249,11 +249,43 @@ Bind these functions to the /local/ mode key sequence:
|
|||
(ha-leader :keymaps 'org-mode-map
|
||||
"o y" '("format yank" . ha-org-yank-clipboard)))
|
||||
#+end_src
|
||||
** Converting to Markdown
|
||||
Let's work top-down at this point with the interactive function that inserts the clipboard into the current buffer:
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-md-yank-clipboard ()
|
||||
"Yanks (pastes) the contents of the Apple Mac clipboard in an
|
||||
markdown-mode-compatible format."
|
||||
(interactive)
|
||||
(insert (ha-md-clipboard)))
|
||||
#+end_src
|
||||
|
||||
This function does the heavy lifting. Note that I will need another function to tidy up the output from =pandoc= that will be more to my liking.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-md-clipboard ()
|
||||
"Return the contents of the clipboard in markdown-mode format."
|
||||
(seq-let (type contents) (ha-get-clipboard)
|
||||
(with-temp-buffer
|
||||
(insert contents)
|
||||
(if (eq :html type)
|
||||
(shell-command-on-region (point-min) (point-max)
|
||||
"pandoc -f html -t markdown --wrap=auto --ascii --markdown-headings=atx -t gfm-raw_html" t t)
|
||||
(shell-command-on-region (point-min) (point-max)
|
||||
"pandoc -f markdown -t markdown --wrap=auto --ascii" t t))
|
||||
;; (ha-html-paste-touchup)
|
||||
(buffer-substring-no-properties (point-min) (point-max)))))
|
||||
#+end_src
|
||||
|
||||
Bind these functions to the /local/ mode key sequence:
|
||||
#+begin_src emacs-lisp
|
||||
(ha-leader :keymaps '(markdown-mode-map gfm-mode-map)
|
||||
"o y" '("format yank" . ha-md-yank-clipboard))
|
||||
#+end_src
|
||||
* Technical Artifacts :noexport:
|
||||
Let's provide a name so we can =require= this file:
|
||||
#+begin_src emacs-lisp
|
||||
(provide 'ha-org-clipboard)
|
||||
;;; ha-org-clipboard.el ends here
|
||||
(provide 'ha-org-clipboard)
|
||||
;;; ha-org-clipboard.el ends here
|
||||
#+end_src
|
||||
|
||||
#+description: A literate programming version of functions for formatting the clipboard.
|
||||
|
|
|
@ -25,33 +25,50 @@ A literate programming configuration file for extending the Journaling capabilit
|
|||
;;; Code:
|
||||
#+end_src
|
||||
* Introduction
|
||||
Using the [[https://github.com/bastibe/org-journal][org-journal]] project to easily create /daily/ journal entries:
|
||||
I used to use the [[https://github.com/bastibe/org-journal][org-journal]] project to create /daily/ journal entries, but what I like is one file per journal entry, and that project did more than I needed. I made my own.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org-journal
|
||||
:after org
|
||||
:config
|
||||
(setq org-journal-dir "~/journal"
|
||||
org-journal-date-format " "
|
||||
org-journal-time-format ""
|
||||
org-journal-file-type 'daily
|
||||
org-journal-file-format "%Y%m%d")
|
||||
My requirements are simple:
|
||||
|
||||
1. A directory of entries, =~/journal=. Each file is based on the date, e.g. =20241228= or =20130401=.
|
||||
2. A minor mode to identify a journal entry as opposed to a regular org file.
|
||||
|
||||
Where do I store these?
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar org-journal-dir (expand-file-name "~/journal")
|
||||
"Location of Journal entries, org files.")
|
||||
#+END_SRC
|
||||
|
||||
And what identifies a Journal file?
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar org-journal-rx (rx (group (= 4 digit))
|
||||
(optional "-")
|
||||
(group (= 2 digit))
|
||||
(optional "-")
|
||||
(group (= 2 digit)))
|
||||
"A regular expression that identifies journal file entries.")
|
||||
#+END_SRC
|
||||
And a function to create a new entry:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun org-journal-new-entry ()
|
||||
"Opens today's journal entry file."
|
||||
(interactive)
|
||||
(find-file (expand-file-name (format-time-string "%Y%m%d")
|
||||
org-journal-dir)))
|
||||
#+END_SRC
|
||||
|
||||
And connect files that /look/ like a Journal entry with =org-mode=:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(add-to-list 'auto-mode-alist `(,org-journal-rx . org-mode))
|
||||
#+END_SRC
|
||||
|
||||
And pull ‘er up:
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(ha-leader "f j" '("journal" . org-journal-new-entry))
|
||||
|
||||
|
||||
;; In normal Org file, I like large headers, but in my Journal,
|
||||
;; where each task is a header, I want them smaller:
|
||||
(add-hook 'org-journal-mode-hook
|
||||
(lambda ()
|
||||
(set-face-attribute 'org-level-1 nil :height 1.2)
|
||||
(set-face-attribute 'org-level-2 nil :height 1.1)
|
||||
(set-face-attribute 'org-level-3 nil :height 1.0)))
|
||||
|
||||
;; But new files could use /my formatting/ (which is different
|
||||
;; than the options available in the project):
|
||||
(ha-auto-insert-file (rx "journal/" (zero-or-more any) (= 8 digit)) "journal"))
|
||||
#+end_src
|
||||
#+END_SRC
|
||||
|
||||
This depends on the following [[file:~/.doom.d/snippets/org-journal-mode/__journal][snippet/template file]]:
|
||||
|
||||
|
@ -59,48 +76,57 @@ This depends on the following [[file:~/.doom.d/snippets/org-journal-mode/__journ
|
|||
#+title: Journal Entry- `(ha-journal-file-datestamp)`
|
||||
|
||||
$0
|
||||
|
||||
#+end_src
|
||||
|
||||
And the code to connect that template to those files:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(ha-auto-insert-file (rx "journal/" (regexp org-journal-rx)) "journal"))
|
||||
#+END_SRC
|
||||
|
||||
Note that when I create a new journal entry, I want a title that should insert a date to match the file's name, not necessarily the current date (see below).
|
||||
* Journal Filename to Date
|
||||
Since the Journal's filename represents a date, I should be able to get the "date" associated with a file.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-journal-file-date (&optional datename)
|
||||
"Returns a Lisp date-timestamp based on the format of the current filename,
|
||||
or DATENAME if given."
|
||||
"Return a Lisp date-timestamp from current filename.
|
||||
If DATENAME is given, return that timestamp."
|
||||
(unless datename
|
||||
(setq datename (buffer-file-name)))
|
||||
(setq datename (file-name-base (buffer-file-name))))
|
||||
|
||||
(let* ((datename-parser (rx (group (= 4 digit))
|
||||
(group (= 2 digit))
|
||||
(group (= 2 digit))))
|
||||
(parsed-datename (string-match datename-parser datename))
|
||||
(day (string-to-number (match-string 3 datename)))
|
||||
(month (string-to-number (match-string 2 datename)))
|
||||
(year(string-to-number (match-string 1 datename))))
|
||||
(encode-time 0 0 0 day month year)))
|
||||
(when (string-match org-journal-rx datename)
|
||||
(let ((day (string-to-number (match-string 3 datename)))
|
||||
(month (string-to-number (match-string 2 datename)))
|
||||
(year(string-to-number (match-string 1 datename))))
|
||||
(encode-time 0 0 0 day month year))))
|
||||
#+end_src
|
||||
|
||||
And some unit tests to validate this function:
|
||||
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(ert-deftest ha-journal-file-date-test ()
|
||||
(should (equal (ha-journal-file-date "20240817") '(26304 19056)))
|
||||
(should (equal (ha-journal-file-date "2024-08-17") '(26304 19056))))
|
||||
#+end_src
|
||||
Using the "date" associated with a file, we can create our standard timestamp:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun ha-journal-file-datestamp (&optional datename)
|
||||
"Return a string of the buffer's date (based on the file's name)."
|
||||
"Return date string of DATENAME if given.
|
||||
If nil, use the buffer's filename's date."
|
||||
(format-time-string "%e %b %Y (%A)" (ha-journal-file-date datename)))
|
||||
#+end_src
|
||||
|
||||
* Journal Capture
|
||||
Capturing a task (that when uncompleted, would then spillover to following days) could go to the daily journal entry. This requires a special function that opens today's journal, but specifies a non-nil prefix argument in order to inhibit inserting the heading, as =org-capture= will insert the heading.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun org-journal-find-location ()
|
||||
(org-journal-new-entry t)
|
||||
(org-narrow-to-subtree)
|
||||
(org-journal-new-entry)
|
||||
(goto-char (point-max)))
|
||||
|
||||
(defvar org-capture-templates (list))
|
||||
|
||||
(add-to-list 'org-capture-templates
|
||||
'("j" "Journal Task/Entry" plain
|
||||
(function org-journal-find-location)
|
||||
|
@ -111,16 +137,18 @@ Capturing a task (that when uncompleted, would then spillover to following days)
|
|||
Sometimes it is obvious what is the /next file/ based on the one I'm currently reading. For instance, in my journal entries, the filename is a number that can be incremented. Same with presentation files...
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun split-string-with-number (string)
|
||||
"Returns a list of three components of the string, the first is
|
||||
the text prior to any numbers, the second is the embedded number,
|
||||
and the third is the rest of the text in the string."
|
||||
(let* ((start (string-match "[0-9]+" string))
|
||||
(end (string-match "[^0-9]+" string start)))
|
||||
(if start
|
||||
(list (substring string 0 start)
|
||||
(substring string start end)
|
||||
(if end (substring string end) "")))))
|
||||
(defun split-string-with-number (str)
|
||||
"Return list of three components of string, STR.
|
||||
The first is the text prior to any numbers, The second is the
|
||||
embedded number, and the third is the rest of the text in the
|
||||
string."
|
||||
(let* ((ms (string-match (rx (one-or-more digit)) str)))
|
||||
(when ms
|
||||
(list (substring str 0 ms)
|
||||
(match-string 0 str)
|
||||
(substring str
|
||||
(+ ms
|
||||
(length (match-string 0 str))))))))
|
||||
#+end_src
|
||||
|
||||
Which means that the following defines this function:
|
||||
|
@ -170,6 +198,14 @@ And this allows us to create two simple functions that can load the "next" and "
|
|||
(interactive)
|
||||
(find-file (find-file-number-change '1-)))
|
||||
#+end_src
|
||||
|
||||
And we could bind those:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(ha-leader "f +" '("next file" . find-file-increment)
|
||||
"f -" '("previous file" . find-file-decrement))
|
||||
#+END_SRC
|
||||
|
||||
* Technical Artifacts :noexport:
|
||||
Let's =provide= a name so we can =require= this file.
|
||||
|
||||
|
|
|
@ -33,14 +33,19 @@ I like having org-mode files look more like a word processor than having it look
|
|||
Since I use ellipsis in my writing… to /change/ how org renders a collapsed heading.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq org-pretty-entities t
|
||||
org-ellipsis "⤵" ; …, ➡, ⚡, ▼, ↴, , ∞, ⬎, ⤷, ⤵
|
||||
org-agenda-breadcrumbs-separator " ❱ "
|
||||
org-catch-invisible-edits 'show-and-error
|
||||
org-special-ctrl-a/e t ; Note: Need to get this working with Evil!
|
||||
org-src-fontify-natively t ; Pretty code blocks
|
||||
org-hide-emphasis-markers t)
|
||||
(use-package org
|
||||
:config
|
||||
(setq org-pretty-entities t
|
||||
org-hide-emphasis-markers t
|
||||
org-auto-align-tags nil
|
||||
org-tags-column 0
|
||||
org-ellipsis "⤵" ; …, ➡, ⚡, ▼, ↴, , ∞, ⬎, ⤷, ⤵
|
||||
org-catch-invisible-edits 'show-and-error
|
||||
org-special-ctrl-a/e t ; Note: Need to get this working with Evil!
|
||||
org-src-fontify-natively t ; Pretty code blocks
|
||||
org-agenda-breadcrumbs-separator " ❱ "))
|
||||
#+end_src
|
||||
|
||||
Oh, and as I indent lists, they should change the /bulleting/ in a particular sequence. If I begin with an =*= asterisk, I walk down the chain, but with the dashed bullets (my default choice), I stay with dashed bullets. Numeric bullets should cycle:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
|
@ -51,10 +56,43 @@ Oh, and as I indent lists, they should change the /bulleting/ in a particular se
|
|||
The =org-indent-indentation-per-level=, which defaults to =2= doesn’t really work well with variable-width fonts, so let’s make the spaces at the beginning of the line fixed:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org
|
||||
;; TODO: Using the latest org-mode
|
||||
;; :straight (:type built-in)
|
||||
:custom-face (org-indent ((t (:inherit fixed-pitch)))))
|
||||
#+end_src
|
||||
|
||||
Finally, let’s add frame borders and window dividers:
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(modify-all-frames-parameters
|
||||
'((right-divider-width . 20)
|
||||
(internal-border-width . 20)))
|
||||
|
||||
(dolist (face '(window-divider
|
||||
window-divider-first-pixel
|
||||
window-divider-last-pixel))
|
||||
(face-spec-reset-face face)
|
||||
(set-face-foreground face (face-attribute 'default :background)))
|
||||
|
||||
(set-face-background 'fringe (face-attribute 'default :background))
|
||||
#+end_src
|
||||
|
||||
** Hide Heading Stars
|
||||
I’ve struggled with hiding the initial asterisks that denote a headline in Org.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun org-mode-hide-stars ()
|
||||
(font-lock-add-keywords
|
||||
nil
|
||||
'(("^\\*+ "
|
||||
(0 (put-text-property (match-beginning 0) (match-end 0) 'face
|
||||
(list :foreground
|
||||
(face-attribute 'default :background))))))))
|
||||
#+end_src
|
||||
|
||||
And hook this function to Org:
|
||||
#+begin_src emacs-lisp
|
||||
(use-package org
|
||||
:hook (org-mode . org-mode-hide-stars))
|
||||
#+end_src
|
||||
** Markup View
|
||||
The variable, =org-hide-emphasis-markers=, is key to pretending that Emacs can be a word processor, however, since the org markup controls aren’t viewable, I find it challenging at times, to change that. The [[https://github.com/awth13/org-appear][org-appear project]] seeks to fix this by showing the markup when the point is nearby:
|
||||
|
||||
|
@ -244,39 +282,37 @@ I really want to use the Org Beautify package, but it overrides my darker themes
|
|||
(defun ha-word-processor-fonts ()
|
||||
"Configure `org-mode' fonts and faces."
|
||||
(interactive)
|
||||
|
||||
(when window-system
|
||||
;; First step is to make all Org header levels to use the variable
|
||||
;; font, and be the same color as the default text:
|
||||
|
||||
(when window-system
|
||||
(let ((default-color (face-attribute 'default :foreground)))
|
||||
(dolist (face '(org-level-1 org-level-2 org-level-3 org-level-4
|
||||
org-level-5 org-level-6 org-level-7 org-level-8))
|
||||
org-level-5 org-level-6 org-level-7 org-level-8))
|
||||
(set-face-attribute face nil :height 1.1
|
||||
:foreground default-color :weight 'bold
|
||||
:font ha-variable-header-font))))
|
||||
:font ha-variable-header-font)))
|
||||
|
||||
;; Change the header sizes to show their level visually:
|
||||
(set-face-attribute 'org-level-1 nil :height 2.2)
|
||||
(set-face-attribute 'org-level-2 nil :height 1.8)
|
||||
(set-face-attribute 'org-level-3 nil :height 1.4)
|
||||
(set-face-attribute 'org-level-4 nil :height 1.2)
|
||||
;; Change the header sizes to show their level visually:
|
||||
(set-face-attribute 'org-level-1 nil :height 2.2)
|
||||
(set-face-attribute 'org-level-2 nil :height 1.8)
|
||||
(set-face-attribute 'org-level-3 nil :height 1.4)
|
||||
(set-face-attribute 'org-level-4 nil :height 1.2)
|
||||
|
||||
(dolist (face '(org-block org-code org-verbatim org-table org-drawer
|
||||
org-table org-formula org-special-keyword org-block
|
||||
org-property-value org-document-info-keyword))
|
||||
(set-face-attribute face nil :inherit 'fixed-pitch :height 0.9))
|
||||
(dolist (face '(org-block org-code org-verbatim org-table org-drawer
|
||||
org-table org-formula org-special-keyword org-block
|
||||
org-property-value org-document-info-keyword))
|
||||
(set-face-attribute face nil :inherit 'fixed-pitch :height 0.9))
|
||||
|
||||
;; While we are at it, let’s make sure the code blocks are using my fixed with font:
|
||||
(set-face-attribute 'org-table nil :height 1.0)
|
||||
(set-face-attribute 'org-formula nil :height 1.0)
|
||||
;; While we are at it, let’s make sure the code blocks are using my fixed with font:
|
||||
(set-face-attribute 'org-table nil :height 1.0)
|
||||
(set-face-attribute 'org-formula nil :height 1.0)
|
||||
|
||||
(set-face-attribute 'org-block-begin-line nil :height 0.9)
|
||||
(set-face-attribute 'org-block-end-line nil :height 0.8)
|
||||
(set-face-attribute 'org-block-begin-line nil :height 0.9)
|
||||
(set-face-attribute 'org-block-end-line nil :height 0.8)
|
||||
|
||||
(set-face-attribute 'org-drawer nil :height 0.8)
|
||||
(set-face-attribute 'org-property-value nil :height 0.85)
|
||||
(set-face-attribute 'org-special-keyword nil :height 0.85))
|
||||
(set-face-attribute 'org-drawer nil :height 0.8)
|
||||
(set-face-attribute 'org-property-value nil :height 0.85)
|
||||
(set-face-attribute 'org-special-keyword nil :height 0.85)))
|
||||
#+end_src
|
||||
|
||||
We call this function when we start:
|
||||
|
@ -289,11 +325,14 @@ 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")
|
||||
:hook
|
||||
((org-mode . global-org-modern-mode)
|
||||
(org-agenda-finalize . org-modern-agenda))
|
||||
:after org
|
||||
:hook ( ; (add-hook 'org-mode-hook #'org-modern-mode)
|
||||
(org-agenda-finalize . org-modern-agenda))
|
||||
:custom
|
||||
(org-modern-table nil))
|
||||
(org-modern-table nil)
|
||||
:config
|
||||
(set-face-attribute 'org-modern-symbol nil :family "Iosevka")
|
||||
(global-org-modern-mode))
|
||||
#+end_src
|
||||
|
||||
I like the smaller code blocks as well as the <2022-06-16 Thu> timestamps.
|
||||
|
|
27
ha-org.org
27
ha-org.org
|
@ -3,7 +3,7 @@
|
|||
#+date: 2020-09-18
|
||||
#+tags: emacs org
|
||||
#+startup: inlineimages
|
||||
#+lastmod: [2024-08-08 Thu]
|
||||
#+lastmod: [2024-09-02 Mon]
|
||||
|
||||
A literate programming file for configuring org-mode and those files.
|
||||
|
||||
|
@ -33,7 +33,7 @@ Org is a /large/ complex beast with a gazillion settings, so I discuss these lat
|
|||
(use-package org
|
||||
;; TODO: Using the latest org-mode
|
||||
;; :straight (:type built-in)
|
||||
:mode ("\\.org" . org-mode) ; Addresses an odd warning
|
||||
:mode (("\\.org" . org-mode))
|
||||
:init
|
||||
<<variables>>
|
||||
<<org-todo>>
|
||||
|
@ -351,6 +351,7 @@ Add a keybinding to the function:
|
|||
** Misc
|
||||
*** Babel Blocks
|
||||
I use [[https://orgmode.org/worg/org-contrib/babel/intro.html][org-babel]] (obviously) and don’t need confirmation before evaluating a block:
|
||||
|
||||
#+name: ob-configuration
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(setq org-confirm-babel-evaluate nil
|
||||
|
@ -382,6 +383,15 @@ And turn on ALL the languages:
|
|||
(css . t)
|
||||
(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.
|
||||
|
@ -899,13 +909,16 @@ Once in the dictionary buffer, acquiesce these keybindings:
|
|||
** Grammar and Prose Linting
|
||||
Flagging cliches, weak phrasing and other poor grammar choices.
|
||||
*** Writegood
|
||||
The [[https://github.com/bnbeckwith/writegood-mode][writegood-mode]] is effective at highlighting passive and weasel words, but isn’t integrated into =flycheck=:
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(use-package writegood-mode
|
||||
:hook (org-mode . writegood-mode))
|
||||
The [[https://github.com/bnbeckwith/writegood-mode][writegood-mode]] is effective at highlighting passive and weasel words.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package writegood-mode)
|
||||
#+end_src
|
||||
And it reports obnoxious messages.
|
||||
|
||||
Hrm::hook ((org-mode . writegood-mode)
|
||||
(gfm-mode . writegood-mode)
|
||||
(markdown-mode) . writegood-mode)
|
||||
|
||||
We install the =write-good= NPM:
|
||||
#+begin_src shell
|
||||
npm install -g write-good
|
||||
|
@ -957,7 +970,7 @@ And tell [[https://www.flycheck.org/][flycheck]] to use this:
|
|||
#+end_src
|
||||
*** Textlint
|
||||
The [[https://textlint.github.io/][textlint]] project comes with =flycheck=, as long as there is an executable:
|
||||
#+begin_src sh
|
||||
#+begin_src sh :results silent
|
||||
npm install -g textlint
|
||||
# And all the rules
|
||||
npm install -g textlint-rule-alex
|
||||
|
|
|
@ -1152,8 +1152,33 @@ And then we can use it. For some reason, the =pymarkdown= (which I need to use f
|
|||
:config
|
||||
(setq flycheck-markdown-pymarkdown-config ".pymarkdown.yml")
|
||||
(flycheck-may-enable-checker 'markdown-pymarkdown))
|
||||
#+end_src
|
||||
|
||||
;; defcustom flycheck-markdown-pymarkdown-config
|
||||
Ugh
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(flycheck-def-config-file-var flycheck-markdown-pymarkdown-config
|
||||
markdown-pymarkdown nil
|
||||
:package-version '(flycheck . "34"))
|
||||
|
||||
(flycheck-define-checker markdown-pymarkdown
|
||||
"Markdown checker using PyMarkdown.
|
||||
|
||||
See URL `https://pypi.org/project/pymarkdownlnt/'."
|
||||
:command ("pymarkdown"
|
||||
(config-file "--config" flycheck-markdown-pymarkdown-config)
|
||||
"scan"
|
||||
source)
|
||||
:error-patterns
|
||||
((error line-start
|
||||
(file-name) ":" line
|
||||
(? ":" column) ": " (id (one-or-more alnum))
|
||||
": " (message) line-end))
|
||||
:error-filter
|
||||
(lambda (errors)
|
||||
(flycheck-sanitize-errors
|
||||
(flycheck-remove-error-file-names "(string)" errors)))
|
||||
:modes (markdown-mode gfm-mode))
|
||||
#+end_src
|
||||
|
||||
Both the =markdown-command= and the =markdown-open-command= variables are called to render (and preview) a Markdown file (~C-c C-c o~), and calls the following scripts (which in turn, call =pandoc= as I depend on this for other org-related features):
|
||||
|
|
7
snippets/markdown-mode/callout
Normal file
7
snippets/markdown-mode/callout
Normal file
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: Hugo Callout
|
||||
# key: callout
|
||||
# --
|
||||
{{< callout type="${2:$$(yas-choose-value '("note" "warning" "hint"))}" >}}
|
||||
$0
|
||||
{{< /callout >}}
|
6
snippets/markdown-mode/figure
Normal file
6
snippets/markdown-mode/figure
Normal file
|
@ -0,0 +1,6 @@
|
|||
# key: <ss
|
||||
# name: shell
|
||||
# --
|
||||
```bash
|
||||
${0}
|
||||
```
|
|
@ -1,8 +0,0 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: header
|
||||
# key: h1
|
||||
# --
|
||||
${1:Header}
|
||||
${1:$(make-string (string-width yas-text) ?\=)}
|
||||
|
||||
$0
|
|
@ -1,8 +0,0 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: subheader
|
||||
# key: h2
|
||||
# --
|
||||
${1:Header}
|
||||
${1:$(make-string (string-width yas-text) ?\-)}
|
||||
|
||||
$0
|
|
@ -1,7 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: code-block
|
||||
# key: #s
|
||||
# key: <s
|
||||
# --
|
||||
#+begin_src $1
|
||||
#+BEGIN_SRC $1
|
||||
$0
|
||||
#+end_src
|
||||
#+END_SRC
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: emacs-lisp-code
|
||||
# key: #sl
|
||||
# key: <sl
|
||||
# --
|
||||
#+begin_src emacs-lisp
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
$0
|
||||
#+end_src
|
||||
#+END_SRC
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: emacs-lisp-test
|
||||
# key: #elt
|
||||
# name: emacs-lisp-defun
|
||||
# key: <slf
|
||||
# --
|
||||
#+begin_src emacs-lisp
|
||||
(ert-deftest $1-test ()
|
||||
(should (= $0)))
|
||||
#+end_src
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defun ${1:fun} (${2:args})
|
||||
"${3:docstring}"
|
||||
${4:(interactive${5: "${6:P}"})}
|
||||
$0)
|
||||
#+END_SRC
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# key: slv
|
||||
# name: emacs-lisp-defvar
|
||||
# key: <slv
|
||||
# --
|
||||
+begin_src emacs-lisp
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(defvar ${1:symbol} ${2:initvalue} "${3:docstring}")
|
||||
#+end_src
|
||||
#+END_SRC
|
|
@ -1,7 +1,7 @@
|
|||
# key: #elt
|
||||
# name: emacs-lisp-test
|
||||
# key: <slt
|
||||
# --
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(ert-deftest $1-test ()
|
||||
(should (= $0)))
|
||||
#+end_src
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
(ert-deftest $1-test ()
|
||||
(should (= $0)))
|
||||
#+END_SRC
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: example-block
|
||||
# key: #e
|
||||
# key: <e
|
||||
# --
|
||||
#+begin_example
|
||||
$0
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: header
|
||||
# key: header
|
||||
# name: header
|
||||
# --
|
||||
#+title: ${1:`(replace-regexp-in-string "-" " " (capitalize (file-name-nondirectory (file-name-sans-extension (buffer-file-name)))))`}
|
||||
#+author: `(user-full-name)`
|
||||
#+email: `user-mail-address`
|
||||
#+date: `(format-time-string "%Y-%m-%d %B")`
|
||||
#+tags: $2
|
||||
#+TITLE: ${1:`(s-titleized-words (s-replace-regexp (rx (any "-" "_")) " " (file-name-base (buffer-file-name))))`}
|
||||
#+AUTHOR: Howard Abrams
|
||||
#+EMAIL: howard@howardabrams.com
|
||||
#+DATE: `(format-time-string "%Y-%m-%d %a")`
|
||||
#+LASTMOD: [`(format-time-string "%Y-%m-%d %a")`]
|
||||
#+FILETAGS: ${2:personal}
|
||||
#+STARTUP: ${3:inlineimages}
|
||||
|
||||
$0
|
||||
$0
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# key: <h
|
||||
# name: org-mode http client
|
||||
# key: <h
|
||||
# --
|
||||
#+begin_src http
|
||||
${1:GET} https://grafana.dev.wdpharos.io/api/${2:dashboards/uid/klbJ6Rrnk}
|
||||
Authorization: Bearer \$\{auth-key\}
|
||||
Content-Type: application/json
|
||||
$0
|
||||
#+end_src
|
||||
#+end_src
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: name
|
||||
# key: name
|
||||
# key: <n
|
||||
# --
|
||||
#+name: ${0}
|
||||
#+NAME: $0
|
||||
|
|
7
snippets/org-mode/python-src-block
Normal file
7
snippets/org-mode/python-src-block
Normal file
|
@ -0,0 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: python-src-block
|
||||
# key: #sp
|
||||
# --
|
||||
#+BEGIN_SRC python
|
||||
$0
|
||||
#+END_SRC
|
|
@ -1,7 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: quote-block
|
||||
# key: #q
|
||||
# key: <q
|
||||
# --
|
||||
#+begin_quote
|
||||
#+BEGIN_QUOTE
|
||||
$0
|
||||
#+end_quote
|
||||
#+END_QUOTE
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
# name: section-property
|
||||
# key: prop
|
||||
# --
|
||||
:properties:
|
||||
:header-args:${1:emacs-lisp} :${2:results} ${3:silent}
|
||||
:end:
|
||||
:PROPERTIES:
|
||||
:HEADER-ARGS:${1:emacs-lisp} :${2:results} ${3:silent}
|
||||
:END:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- mode: snippet -*-
|
||||
# name: shell-script-code
|
||||
# key: #ss
|
||||
# key: <ss
|
||||
# --
|
||||
#+begin_src sh
|
||||
#+BEGIN_SRC sh
|
||||
$0
|
||||
#+end_src
|
||||
#+END_SRC
|
||||
|
|
Loading…
Reference in a new issue