From 38fb532b09caa3184200299b41c2d9d9d578a2ac Mon Sep 17 00:00:00 2001 From: Howard Abrams Date: Tue, 9 Nov 2021 17:28:58 -0800 Subject: [PATCH] General org enhancements --- elisp/org-annotate-file.el | 133 +++++++++++++++++++++++++++++++++++ ha-config.org | 2 + ha-org-sprint.org | 12 ++-- ha-org.org | 7 ++ snippets/org-mode/code-block | 7 ++ 5 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 elisp/org-annotate-file.el create mode 100644 snippets/org-mode/code-block diff --git a/elisp/org-annotate-file.el b/elisp/org-annotate-file.el new file mode 100644 index 0000000..3900029 --- /dev/null +++ b/elisp/org-annotate-file.el @@ -0,0 +1,133 @@ +;;; org-annotate-file.el --- Annotate a file with org syntax + +;; Copyright (C) 2008 Philip Jackson + +;; Author: Philip Jackson +;; Version: 0.2 + +;; This file is not currently part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program ; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This is yet another implementation to allow the annotation of a +;; file without modification of the file itself. The annotation is in +;; org syntax so you can use all of the org features you are used to. + +;; To use you might put the following in your .emacs: +;; +;; (require 'org-annotate-file) +;; (global-set-key (kbd "C-c C-l") 'org-annotate-file) +;; +;; To change the location of the annotation file: +;; +;; (setq org-annotate-file-storage-file "~/annotated.org") +;; +;; Then when you visit any file and hit C-c C-l you will find yourself +;; in an org buffer on a headline which links to the file you were +;; visiting, e.g: + +;; * ~/org-annotate-file.el + +;; Under here you can put anything you like, save the file +;; and next time you hit C-c C-l you will hit those notes again. +;; +;; To put a subheading with a text search for the current line set +;; `org-annotate-file-add-search` to non-nil value. Then when you hit +;; C-c C-l (on the above line for example) you will get: + +;; * ~/org-annotate-file.el +;; ** `org-annotate-file-add-search` to non-nil value. Then whe... + +;; Note that both of the above will be links. + +(require 'org) + +(defvar org-annotate-file-storage-file "~/.org-annotate-file.org" + "File in which to keep annotations.") + +(defvar org-annotate-file-add-search nil + "If non-nil then add a link as a second level to the actual +location in the file") + +(defvar org-annotate-file-always-open t + "non-nil means always expand the full tree when you visit +`org-annotate-file-storage-file'.") + +(defvar org-annotate-file-make-relative nil + "non-nil means make all path links relative between file being annotated and file containing annotations.") + +(defun org-annotate-file-prettyfy-desc (string) + "Strip starting and ending whitespace and replace any chars +after the 60th with '...'" + (let ((replace-map '(("^[ \t]*" . "") + ("[ \t]*$" . "") + ("^\\(.\\{60\\}\\).*" . "\\1...")))) + (dolist (replace replace-map) + (when (string-match (car replace) string) + (setq string (replace-match (cdr replace) nil nil string)))) + string)) + +(defun org-annotate-file () + "Put a section for the current file into your annotation file" + (interactive) + (unless (buffer-file-name) + (error "This buffer has no associated file.")) + (org-annotate-file-show-section)) + +(defun org-annotate-file-show-section (&optional buffer) + "Visit the buffer named `org-annotate-file-storage-file' and +show the relevant section" + (let* ((filename (if (not org-annotate-file-make-relative) + (abbreviate-file-name (or buffer (buffer-file-name))) + (file-relative-name (or buffer (buffer-file-name)) (file-name-directory org-annotate-file-storage-file)))) + (line (buffer-substring-no-properties (point-at-bol) (point-at-eol))) + (link (org-make-link-string (concat "file:" filename))) + (search-link (org-make-link-string + (concat "file:" filename "::" line) + (org-annotate-file-prettyfy-desc line)))) + (with-current-buffer (find-file org-annotate-file-storage-file) + (unless (eq major-mode 'org-mode) + (org-mode)) + (goto-char (point-min)) + (widen) + (when org-annotate-file-always-open + (show-all)) + (unless (search-forward-regexp + (concat "^* " (regexp-quote link)) nil t) + (org-annotate-file-add-upper-level link)) + (beginning-of-line) + (org-narrow-to-subtree) + ;; deal with a '::' search if need be + (when org-annotate-file-add-search + (unless (search-forward-regexp + (concat "^** " (regexp-quote search-link)) nil t) + (org-annotate-file-add-second-level search-link)))))) + +(defun org-annotate-file-add-upper-level (link) + (goto-char (point-min)) + (call-interactively 'org-insert-heading) + (insert link)) + +(defun org-annotate-file-add-second-level (link) + (goto-char (point-at-eol)) + (call-interactively 'org-insert-subheading) + (insert link)) + +(provide 'org-annotate-file) +;;; org-annotate-file.el ends here + diff --git a/ha-config.org b/ha-config.org index a7299fb..9031e04 100644 --- a/ha-config.org +++ b/ha-config.org @@ -325,6 +325,8 @@ Let's try this general "space" prefix by defining some top-level operations, inc "X" 'org-capture "L" 'org-store-link "RET" 'bookmark-jump + "a" '(:ignore t :which-key "apps") + "o" '(:ignore t :which-key "org/open") "m" '(:ignore t :which-key "mode")) #+END_SRC And ways to stop the system: diff --git a/ha-org-sprint.org b/ha-org-sprint.org index 72fd0f2..cf9b2e3 100644 --- a/ha-org-sprint.org +++ b/ha-org-sprint.org @@ -282,10 +282,14 @@ So what that means, is given a particular date, I should expect to be able to fi Daily note-taking goes into my sprint file notes, so this interactive function makes an easy global short-cut key. #+BEGIN_SRC emacs-lisp -(defun sprint-current-find-file (&optional date) - "Load the `org-mode' note associated with my current sprint." - (interactive) - (find-file (sprint-current-file date))) + (defun sprint-current-find-file (&optional date) + "Load the `org-mode' note associated with my current sprint." + (interactive) + (let ((filename (sprint-current-file date))) + (setq org-main-file filename + org-annotate-file-storage-file filename) + (add-to-list 'org-agenda-files filename) + (find-file filename))) #+END_SRC The /name/ and /nickname/ of the sprint will be used in the =#+TITLE= section, and it looks something like: =Sprint 2019-07 (darling-dadu)= diff --git a/ha-org.org b/ha-org.org index e75607c..22a213d 100644 --- a/ha-org.org +++ b/ha-org.org @@ -280,6 +280,13 @@ To make the snippets more context aware, this predicate (plist-get (cadr (org-element-at-point)) :language))) #+END_SRC ** Keybindings +Keybindings available to all file buffers: +#+BEGIN_SRC emacs-lisp +(ha-leader + "o l" '("store link" . org-store-link) + "o x" '("org capture" . org-capture) + "o c" '("clock out" . org-clock-out)) +#+END_SRC Bindings specific to org files: #+BEGIN_SRC emacs-lisp (general-evil-define-key 'normal org-mode-map diff --git a/snippets/org-mode/code-block b/snippets/org-mode/code-block new file mode 100644 index 0000000..272c8b9 --- /dev/null +++ b/snippets/org-mode/code-block @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: code-block +# key: