From e91b21782dbcc20e7a6ce877dbaceee1d7def72c Mon Sep 17 00:00:00 2001 From: niklauz Date: Sun, 16 May 2010 08:51:20 -0400 Subject: [PATCH] publish --- .envrc | 9 + .github/workflows/pages.yaml | 127 + .gitignore | 46 + .gitlab-ci.yml | 30 + control.org | 12645 +++++++++++++++++++++++++++++++++ 5 files changed, 12857 insertions(+) create mode 100644 .envrc create mode 100644 .github/workflows/pages.yaml create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100755 control.org diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..fcdf790 --- /dev/null +++ b/.envrc @@ -0,0 +1,9 @@ +# -*- mode: envrc -*- + + +PATH_add .artifacts/published_apps + +#use flake .assets/nix + +## EOF + diff --git a/.github/workflows/pages.yaml b/.github/workflows/pages.yaml new file mode 100644 index 0000000..55fcc36 --- /dev/null +++ b/.github/workflows/pages.yaml @@ -0,0 +1,127 @@ +image: nixery.dev/shell/nix/git/gnugrep/wget/emacs + +pages: + variables: + HOME: ${PWD} + RAPPORT_EMACS__URI_LIBDIR: "${PWD}" + RAPPORT__URI_VAULT: "${PWD}" + RAPPORT__URI_VAULT_CFGS: "${PWD}" + + script: + - wget 'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el' + - emacs --batch -Q --eval '(setq org-confirm-babel-evaluate nil)' --file=control.org -f org-mode --load htmlize.el -f org-html-export-to-html --kill + - mkdir public + - mv control.html public/index.html + artifacts: + paths: + # The folder that contains the files to be exposed at the Page URL + - public + rules: + # This ensures that only pushes to the default branch will trigger a pages deploy + - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH +# --- --- --- +name: GitHub Actions Demo +run-name: ${{ github.actor }} is testing out GitHub Actions πŸš€ +on: [push] +jobs: + Explore-GitHub-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "πŸŽ‰ The job was automatically triggered by a ${{ github.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" + - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." + - name: Check out repository code + uses: actions/checkout@v4 + - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." + - run: echo "πŸ–₯️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ github.workspace }} + - run: echo "🍏 This job's status is ${{ job.status }}." +# --- --- --- +name: CI + +# ... + +jobs: + build: + name: Test + runs-on: ubuntu-latest + steps: + - name: render-site + run: + + - name: Setup Pages + if: github.ref == 'refs/heads/public' + uses: actions/configure-pages@v3 + + - name: Upload Artifact + if: github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v1 + with: + # location of the coverage artifacts + path: "./coverage" + + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Run Tests + run: + + - name: Setup Pages + if: github.ref == 'refs/heads/main' + uses: actions/configure-pages@v3 + + - name: Upload Artifact + if: github.ref == 'refs/heads/main' + uses: actions/upload-pages-artifact@v1 + with: + # location of the coverage artifacts + path: "./coverage" + + deploy-coverage: + if: github.ref == 'refs/heads/public' + runs-on: ubuntu-latest + needs: test + + permissions: + pages: write + id-token: write + + environment: + # environment created automatically by GitHub + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 + +# --- --- --- +name: github-pages-publish +on: + push: + branches: [ public ] +jobs: + github-pages-publish: + runs-on: ubuntu-latest + container: + image: nixery.dev/shell/nix/git/gnugrep/wget/emacs + steps: + - name: Check for dockerenv file + run: (ls /.dockerenv && echo Found dockerenv) || (echo No dockerenv) + - name: fetch a recent htmlize + run: wget 'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el' + - name: render using ox-html + run: emacs --batch -Q --eval '(setq org-confirm-babel-evaluate nil)' --file=control.org -f org-mode --load htmlize.el -f org-html-export-to-html --kill + - name: + run: mkdir public + - name: asdf + run: mv control.html public/index.html + - name: Deploy GH Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d7692af --- /dev/null +++ b/.gitignore @@ -0,0 +1,46 @@ +!.gitignore +*.asc +*.cache +*.db +*.el +*.eld +*.elc +*.gpg +*.html +*.o +*.org_archive +*.out +*.plstore +*.pyc +*.stats +*\#* +*~ +.DS_Store +.artifacts/* +.cache/* +.cask +.directory +.direnv +.envrc +.fuse_hidden* +.history +.history/* +.org-id-locations +.rapport.d +.svn +.vscode/* +/.fuse_hidden* +GPATH +GRTAGS +GTAGS +TAGS +auto-save-list/* +eln-cache/* +elpa +history +server/* +straight/* +tmp/* +url/* +var/* +~$* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..a07e418 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +stages: +- test +sast: + stage: test +include: +- template: Security/SAST.gitlab-ci.yml + +# ----- ----- ----- ----- ----- # + +image: nixery.dev/shell/nix/git/gnugrep/wget/emacs + +pages: + variables: + HOME: ${PWD} + RAPPORT_EMACS__URI_LIBDIR: "${PWD}" + RAPPORT__URI_VAULT: "${PWD}" + RAPPORT__URI_VAULT_CFGS: "${PWD}" + + script: + - wget 'https://raw.githubusercontent.com/hniksic/emacs-htmlize/master/htmlize.el' + - emacs --batch -Q --eval '(setq org-confirm-babel-evaluate nil)' --file=control.org -f org-mode --load htmlize.el -f org-html-export-to-html --kill + - mkdir public + - mv control.html public/index.html + artifacts: + paths: + # The folder that contains the files to be exposed at the Page URL + - public + rules: + # This ensures that only pushes to a matching branch will trigger a pages deploy + - if: $CI_COMMIT_REF_NAME == 'public' \ No newline at end of file diff --git a/control.org b/control.org new file mode 100755 index 0000000..13cf5b5 --- /dev/null +++ b/control.org @@ -0,0 +1,12645 @@ +#!/usr/bin/env nix-shell +# -*- mode: org -*- +#+begin_comment +# ,HINT: It seems nix-shell only supports one '--run' on one line so all logic and setup needs to squish into a single gnarly one-line shell invocation. +# ,HINT: Options (ie. 'RAPPORT_EMACS__OPT_*') are encoded as binary switches, such that DAEMON (10) and GUI (01) to elide logical nesting. +# ,HINT: If RAPPORT_EMACS__OPT_GUI is set, respect it, if it's not set run a TUI if a terminal is detected and a GUI if it isn't. +# ,TODO: the 'yes' command was added to the line below as a dirty-hack for testing purposes and should be removed as soon as feasible +#! nix-shell --run " export RAPPORT_EMACS__URI_INITDIR=${RAPPORT_EMACS__URI_INITDIR:-$HOME/.emacs.d} ; export RAPPORT_EMACS__URI_LIBDIR=${RAPPORT_EMACS__URI_LIBDIR:-${RAPPORT_EMACS__URI_LIBDIRS[0]:-$RAPPORT_EMACS__URI_INITDIR/.rapport.d}} ; if [ $(realpath ${RAPPORT_EMACS__URI_INITDIR}) != $(realpath ${HOME}/.emacs.d) ] ;then export RAPPORT_EMACS__OPT_ARGS+=' --init-directory='${RAPPORT_EMACS__URI_INITDIR}' ' ;fi ; if [ -f ${RAPPORT_EMACS__URI_INITDIR}/early-init.el ] && [ -f ${RAPPORT_EMACS__URI_LIBDIR}/rapport-core-emacsearlyinit.el ] && [ -f ${RAPPORT_EMACS__URI_INITDIR}/rapport-core-tangle.el ] ;then : ;else export RAPPORT_EMACS__URI_CONTROL=${RAPPORT_EMACS__URI_CONTROL:-${RAPPORT_EMACS__URI_INITDIR}/control.org} ; emacs --batch -Q --file ${RAPPORT_EMACS__URI_CONTROL} --eval ' (setq org-confirm-babel-evaluate nil)' -f org-babel-tangle --kill ;fi ; export RAPPORT_EMACS__CMD=([0]='emacs -nw' [1]='nohup emacs ' [2]='emacsclient -t' [3]='nohup emacsclient -c ') ; typeset -i __IDX=0 ; if [[ ${RAPPORT_EMACS__OPT_DAEMON} =~ ^[yYtT] ]] ;then __IDX+=2 ;fi ; if [[ -z ${RAPPORT_EMACS__OPT_GUI+x} ]] && [[ ! -t 0 ]] || [[ ${RAPPORT_EMACS__OPT_GUI} =~ ^[yYtT] ]] ;then __IDX+=1 ;fi ; echo ' (rapport)::Emacs $>>' ${RAPPORT_EMACS__CMD[${__IDX}]} ${RAPPORT_EMACS__OPT_ARGS}'<<$' ; [[ ${RAPPORT_EMACS__OPT_DEBUG} =~ ^[tTyY] ]] && for i in RAPPORT_EMACS__URI_{CONTROL,INITDIR,LIBDIR} ; do echo -e ' (rapport)::Emacs \\t '$i' \\t == \\t '${!i}'' ; done ; ${RAPPORT_EMACS__CMD[${__IDX}]} ${RAPPORT_EMACS__OPT_ARGS}" +# ,HINT: pin nixpkgs to a specific release (branch "nixpkgs-23.11" circa 20240514) to improve reproducibility and avoid spurious builds. +#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/23.11.tar.gz +# #! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/44072e24566c5bcc0b7aa9178a0104f4cfffab19.tar.gz +# ,HINT: add the https://app.cachix.org/cache/nix-community as a build-cache for 'nix-community' projects, including emacs-overlay. Recommended: pre-install and enable cachix +#! nix-shell -p cachix --option extra-trusted-public-keys "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" --option extra-trusted-substituters "https://nix-community.cachix.org" +# ,HINT: install (and if necessary, build) a pre-release version of Emacs (v30.0.50, circa 20240514) using the 'emacs-overlay' +#! nix-shell -p "with (import { overlays = [ (import (builtins.fetchTarball https://github.com/nix-community/emacs-overlay/archive/14922c0e5074b5532ab003cd0fa6b9003c666045.tar.gz )) ];}) ; pkgs.emacs-git" +#! nix-shell -p git git-secret direnv pandoc skim doit ncurses6 sqlite dtach +#,HINT: adds human language support, TODO: switch to aspell or jinx (via enchant) +#! nix-shell -p hunspell hunspellDicts.en_US enchant +# ,HINT: adds data mgmt, analysis, and visualization tools +#! nix-shell -p htmlq gnuplot ditaa plantuml +# ,HINT: adds Project Mgmt tools +#! nix-shell -p taskjuggler +# ,HINT: adds vterm support (req'd for lib and shim-compile, gcc and gnumake also reqd) +#! nix-shell -p cmake libvterm-neovim +# ,HINT: adds C, CPP support +#! nix-shell -p global gcc gnumake +# ,HINT: adds Python/LSP support (via https://emacs-lsp.github.io/lsp-pyright/) +#! nix-shell -p pyright rye pdm black mypy poetry +# ,HINT: adds Rust/LSP support (via https://emacs-lsp.github.io/lsp-mode/page/lsp-rust-analyzer/) +#! nix-shell -p cargo rust-analyzer rustup rustc rustfmt rust-script +# ,HINT: adds Terraform/LSP support (via https://emacs-lsp.github.io/lsp-mode/page/lsp-terraform-ls/) +#! nix-shell -p terraform-ls +# ,HINT: (wip) Kubernetes/LSP support (via https://emacs-lsp.github.io/lsp-mode/page/lsp-yaml/) +#! nix-shell -p kubectl krew kubectl-doctor kubectl-tree kubectx yaml-language-server +# ,HINT: adds Bash/LSP support (via https://emacs-lsp.github.io/lsp-bash/) ,WIP: bash-language-server +#! nix-shell -p shellcheck bash_unit bashate beautysh +# ,HINT: adds Nix/LSP support (via https://emacs-lsp.github.io/lsp-nix-nil/) +#! nix-shell -p nil +# ,HINT: adds Guile Scheme/LSP support (via https://emacs-lsp.github.io/lsp-nix-nil/) +#! nix-shell -p guile guile-hall akku +#,HINT: Multimedia Support: ffmpeg for Whisper.el (Spx2Txt), et al +#! nix-shell -p ffmpeg mpv +#,HINT: System Integration Utilities +#! nix-shell -p zoxide +#,HINT: Nix Integration and Utilities +#! nix-shell -p nixfmt alejandra +# ,HINT: The above shebang lines are using nix-shell to document and instantiate system packages which extend Emacs functionality. +#+end_comment +#+STARTUP: overview hideblocks indent nonum align inlineimages fnadjust entitiespretty +#+OPTIONS: ^:{} author:nil broken-links:t creator:nil d:nil email:nil H:6 num:nil prop:nil stat:nil tags:nil timestamp:nil todo:done tex:t +# ,HINT: in this file we use SELECT_TAGS for it's special-case effect, which prevents the 'nix-shell' shebang appearing in exports +#+SELECT_TAGS: export +#+CATEGORY: rapport_Emacs + +# ## HTML Export Systems ## + +# ReadTheOrg +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: + +# +# #+INFOJS_OPT: view:showall toc:nil buttons:nil +# #+HTML_HEAD_EXTRA: +# #+HTML_HEAD: +# #+HTML_HEAD: + + +# Provide Global Presets for Org-Babel +#+PROPERTY: header-args :eval never-export :comments both +#+PROPERTY: header-args:ditaa :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) "--" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) "-buffer--" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil ".png") :cmdline "-r -s 0.8" +#+PROPERTY: header-args:dot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) "--" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) "-buffer--" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil ".png") +#+PROPERTY: header-args:plantuml :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) "--" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) "-buffer--" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat "." (or (bound-and-true-p plantuml-output-type) "svg"))) :cmdline "-quiet -darkmode" +#+PROPERTY: header-args:gnuplot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) "--" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) "-buffer--" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat "." (or (bound-and-true-p gnuplot-image-format) "png"))) + + +#+TITLE: Rapport Emacs +#+SUBTITLE: /an Amiable and Literate Companion/ +#+FILETAGS: proj@rapport_emacs + +* Synopsis :export: +:PROPERTIES: +:ID: 6536620C-D1CB-480B-9263-A25033D02865 +:END: + - An Emacs project in the *Rapport* initiative. + - An opinionated and shareable experimentation in an optimal Emacs experience. + +* /Advisement/ :noexport: +:PROPERTIES: +:ID: 22d52f9e-bb77-411b-87ad-d1c01123f72a +:END: + +* /Introduction/ :export: +:PROPERTIES: +:ID: 450B2CEA-4A5F-4D34-A912-754760994352 +:END: +** Foreword +:PROPERTIES: +:ID: D20685C5-0B11-45C4-B139-7D0D87946E0D +:END: + + - What is Rapport? + #+begin_quote +From The Collaborative International Dictionary of English v.0.48 [gcide]: + +Rapport \Rap*port"\ (r[a^]p*p[=o]rt"; F. r[.a]`p[^o]r"), n. [F., + fr. rapporter to bring again or back, to refer; pref. re- re- + + apporter to bring, L. apportare. Cf. Report.] + Relation; proportion; conformity; correspondence; accord. + [1913 Webster] + + 'T is obvious what rapport there is between the + conceptions and languages in every country. --Sir W. + Temple. + [1913 Webster] + + En` rap`port" ([aum]N` r[.a]`p[^o]r") [F.], in accord, + harmony, or sympathy; having a mutual, especially a + private, understanding; in hypnotism, in that relation of + sympathy which permits influence or communication. + [1913 Webster] + +From WordNet (r) 3.0 (2006) [wn]: + +rapport + n 1: a relationship of mutual understanding or trust and + agreement between people [syn: rapport, resonance] + + #+end_quote + - What is Emacs? + #+begin_quote +From The Free On-line Dictionary of Computing (30 December 2018) [foldoc]: + +Emacs +GNU Emacs + + /ee'maks/ (Editing MACroS, or Extensible MACro + System, GNU Emacs) A popular screen editor for Unix and + most other operating systems. + #+end_quote + + - for More Rapport with Emacs Org-Mode [[[https://rapport1.gitlab.io/emacs][rtd]]|[[https://gitlab.com/rapport1/emacs.git][git]]] + - tasks and features are planned at https://coherent.atlassian.net/browse/EMACS + - many personal configuration details, (including an extensive =customize= file), are stored separately + - so cloning and running this repo alone will not yield exactly my same config + - I'm interested in removing this incogruency, (to the extent thats possible), in order to make it easier for people to reference and copy this config. + - this configuration is inspired by the content and organization of a number of great thinkers and system designers.[fn:1] + - Where =nix-shell= is available, the =control.org= file may be directly executed to dynamically load Emacs, support libraries, and tools with a single invocation. + - This is a good example of the strange and fascinating useful of Nix. This method bring it's own runtime, including Emacs, which means that =control.org= is executable to run Rapport Emacs, even when Emacs isn't already installed. + + +** Motivation +/It's important to understand that Emacs wasn't my first choice./ + +All I knew was what I wanted - a tool for note-taking with these criteria: +- *Ubiquitous* (cross-platform, available where I need it, inexpensive such that I can afford and recommend it without disadvantage) +- *Stable* (with future-proof data formats, adequate governance) +- *Adaptable* (supportive of various workflows, rapid knowledge capture organization and retrieval) +- *Durable* (vibrant and supportive community, annihilation-resistant, charismatic-leader resistant) + +There were (and always will be) lots [[https://en.wikipedia.org/wiki/Comparison_of_note-taking_software][of]] [[https://en.wikipedia.org/wiki/Comparison_of_integrated_development_environments][other]] [[https://en.wikipedia.org/wiki/Comparison_of_text_editors][choices]], (RIP [[https://en.wikipedia.org/wiki/Google_Buzz][Google Buzz]]) that seemed like far more obvious candidates. + +I was nascently aware of Emacs of course but just as readily dismissed it as unsuitably arcane. + +Over a course of time and trial, I gradually came to understand that what was missing from my list of criteria - what flowed between them and fastened them, was *freedom*. + +Startlingly and certainly my awareness shifted, and as I reappraised Emacs in this new light I appreciated that it merited more than a second look. + +/*Freedom* is the guarantor, the primacy, the fastener through which these myriad expressions are bound./ + +#+begin_comment +Consequently I freshly weighted for freedom in my comparative evaluations of candidate solution. + +Ironically, the best choice for me was only apparent after accepting the clarity that accompanies a more rigorous criteria and selective approach. + +It wasn't the obvious right answer, but the various failures of the preceding tools were instructive and granted me second sight to certain risks to judge Emacs for the fatal flaws that it lacked, alongside it's more conspicuous characteristics. The Rapport Emacs project started in 2010 as a personal Emacs configuration and has evolved continuously since then. +#+end_comment + +** Prologue :noexport: +*** Bootstrap Build-time Snippets, Configs, and Functionality using Org-Babel :noexport: +:PROPERTIES: +:header-args:emacs-lisp: :results value :eval yes :cache yes :noweb yes :comments noweb :exports none +:ID: D857267B-E5D8-4DB8-A852-EE83B2840804 +:END: +These org-babel source block functions are available in a naive and minimalistic tangle context, as encountered during the pre-flight-check activities in the initialization activities in Rapport's =nix shell= =shebang= and start-up configs. In other words they are used only to create the Rapport Emacs config, but are intentionally absent from that config. + + +- *on Sources* + + - https://emacs.stackexchange.com/questions/51399/org-babel-tangle-with-function-in-header-arguments + - http://doc.endlessparentheses.com/Fun/org-sbe.html + +- *on =Org-Babel= Functions* + + - (opt.) disable confirmation for =org-babel=, included soley for convenience while working interactively. + #+begin_src emacs-lisp + (setq org-confirm-babel-evaluate nil) + #+end_src + + - to provide behavior approximate to =#'rapport-emacs-uri-get-uri-libdirs= + #+name: rapport-sbe--get-libdirs + #+begin_src emacs-lisp +(let* + ((from-var (when (and + (bound-and-true-p rapport-emacs-uri-libdirs) + (listp rapport-emacs-uri-libdirs)) + rapport-emacs-uri-libdirs)) + (from-env-libdir (getenv "RAPPORT_EMACS__URI_LIBDIR")) + (from-env-libdir (when (stringp from-env-libdir) + (list from-env-libdir))) + (from-env-libdirs (getenv "RAPPORT_EMACS__URI_LIBDIRS")) + (from-env-libdirs (when (stringp from-env-libdirs) + (split-string from-env-libdirs nil t))) + (from-runtime-default (getenv "RAPPORT_EMACS__URI_INITDIR")) + (from-runtime-default (when (stringp from-runtime-default) + (list (expand-file-name ".rapport.d" from-runtime-default)))) + (from-buildtime-default (list (expand-file-name ".rapport.d" user-emacs-directory)))) + (delete-dups + (remove nil + (append + from-var + from-env-libdir + from-env-libdirs + from-runtime-default + from-buildtime-default)))) + #+end_src + + - to provide behavior approximate to =#'rapport-fn-featureset-get-uri-libdir= + #+name: rapport-sbe--get-libdir + #+begin_src emacs-lisp + (car (read (org-sbe rapport-sbe--get-libdirs))) + #+end_src + + - to provide behavior approximate to =#'rapport-fn-featureset-get-uri-initdir= + #+name: rapport-sbe--get-initdir + #+begin_src emacs-lisp +(or (bound-and-true-p rapport-emacs-uri-initdir) + (and (stringp (getenv "RAPPORT_EMACS__URI_INITDIR")) + (expand-file-name (getenv "RAPPORT_EMACS__URI_INITDIR"))) + (when (functionp '(rapport-fn-featureset-get-uri-initdir)) + (rapport-fn-featureset-get-uri-initdir)) + (expand-file-name user-emacs-directory)) + #+end_src + + - memoize the location of Rapport Emacs's control file. Typically this is =~/.emacs.d/control.org=. + #+name: rapport-sbe--get-control-file + #+begin_src emacs-lisp + (or (bound-and-true-p rapport-emacs-uri-control) + (let ((from-env (getenv "RAPPORT_EMACS__URI_CONTROL"))) + (when (stringp from-env) from-env)) + buffer-file-name) + #+end_src + +*on =noweb= Snippets* + - mutate ='load-path= to add an appropriate directory for Rapport features + #+NAME: rapport-noweb-elisp--add-libdir-to-load-path + #+begin_src emacs-lisp + (add-to-list 'load-path (or (getenv "RAPPORT_EMACS__URI_LIBDIR") ;; runtime config + "<>")) ;; buildtime config + #+end_src + + - setup render-time variable =rapport-emacs-uri-control=, to support successive re-tangles, (particularly when working with custom INITDIR and LIBDIR directories) + #+NAME: rapport-noweb-elisp--setup-control-variable + #+begin_src emacs-lisp + (setq-default rapport-emacs-uri-control "<>") + #+end_src + - setup render-time variable =rapport-emacs-uri-initdir=, to support successive re-tangles, (particularly when working with custom INITDIR and LIBDIR directories) + #+NAME: rapport-noweb-elisp--setup-initdir-variable + #+begin_src emacs-lisp + (setq-default rapport-emacs-uri-initdir "<>") + #+end_src + - setup render-time variable =rapport-emacs-uri-libdir=, to support successive re-tangles, (particularly when working with custom INITDIR and LIBDIR directories) + #+NAME: rapport-noweb-elisp--setup-libdir-variable + #+begin_src emacs-lisp + (setq-default rapport-emacs-uri-libdir "<>") + #+end_src + + +*** Early Initialization, =early-init.el= :noexport:provide@core_emacsearlyinit#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "early-init.el" (org-sbe rapport-sbe--get-initdir)) :mkdirp t +:header-args:emacs-lisp+: :results value :eval yes :cache yes :noweb yes :comments noweb :exports none +:ID: 7B1DFD0E-6CBA-47F3-B62E-7D04B49D2FC8 +:END: + +setup Emacs's early init + +#+begin_src emacs-lisp + ;; register the location of Rapport Emacs's Control file + <> + ;; register the location of Rapport Emacs's Init dir + <> + ;; register the location of Rapport Emacs's Lib dir + <> + + ;; register the location of "require-able" Rapport feature-files + <> + + (require 'rapport-core-emacsearlyinit) +#+end_src + +*** Initialization, =init.el= :provide@core_emacsinit#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "init.el" (org-sbe rapport-sbe--get-initdir)) :mkdirp t +:header-args:emacs-lisp+: :results value :eval yes :cache yes :noweb yes :comments noweb :exports none +:ID: 26D927F5-6454-4A69-84C4-1EB801D80417 +:END: + +setup Emacs initialization + +#+begin_src emacs-lisp + <> + (require 'rapport-core-emacsinit) +#+end_src + +* /Chapter/ *0*, Establish Rapport :export:provide@core#rapport: + +** Rapport Core + +*** Early Initialization, =early-init.el= :provide@rapport_core_emacsearlyinit: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-emacsearlyinit.el" (org-sbe rapport-sbe--get-libdir)) :mkdirp t +:header-args:emacs-lisp+: :noweb yes :comments both +:ID: 3ACD1E59-7039-452B-8EB4-80666D1A2EE3 +:END: + +setup Emacs's early init + +#+begin_src emacs-lisp + ;; Initialization Speed Hacks + (let* + ((gc-cons-threshold-orig 800000) ;; The default value is 800,000 bytes (aka 800k). + (gc-cons-threshold-startup (* 1024 1000 500)) ;; During the value is bumped up to 512 MB during initialization. + (gc-cons-percentage-adjusted 0.4)) ;; The value to use after Emacs is initialized. + (progn + ;; Make startup faster by reducing the frequency of garbage collection and then use a hook to measure Emacs startup time. + (setq + gc-cons-threshold gc-cons-threshold-startup ;; Number of bytes of consing between garbage collections. + gc-cons-threshold most-positive-fixnum ;; Very large threshold for garbage collector during init + package-enable-at-startup nil) ;; We'll use elpaca + + ;; Reset the garbage collector limit after init process has ended (8Mo) + `(add-hook 'after-init-hook + (lambda () + (setq gc-cons-threshold ,gc-cons-threshold-orig + gc-cons-percentage ,gc-cons-percentage-adjusted))))) + + + ;; Lightweight Start-Up + ;; - No site-wide run-time initializations. + (setq site-run-file nil) + ;; - No site-wide default library + (setq inhibit-default-init t) + + + ;; register the location of "require-able" Rapport feature-files, (including build-time defaults) + <> + ;; register the location of "require-able" Rapport feature-files, (including build-time defaults) + <> + + ;; load Rapport's FeatureSet + ;; ,NB: it's helpful for this to be the first feature loaded to support defining feature sets and inhibits. + (require 'rapport-core-featureset) + ;; register the location of "require-able" Rapport feature-files, (including runtime config) + (add-to-list 'load-path (rapport-fn-featureset-get-uri-libdir)) + ;; load Tangle Rapport data and functions. + (rapport-fn-featureset-load-preset 'tangle-during-earlyinit) + ;; ,NB: In the event that 'tangle-during-earlyinit is inhibited, the tangle operation is skipped. + (when (functionp 'rapport-fn-tangle-files-maybe) + ;; tangle if needed to render updates. + (rapport-fn-tangle-files-maybe)) + + ;; Now that any needed tangling has happened, we'll continue on to load the remaining (potentially updated) early-init portions of Rapport. + + ;; ,NOTICE: + ;; The 'rapport-core-featureset and 'rapport-core-tangle are + ;; loaded prior to the tangle and won't include updates from the + ;; tangle. To mitigate the potential and risk of incorrect behavior + ;; as a result of mixing pre-tangle and post-tangle versions, these + ;; features are/should generally minimize interdependencies and + ;; mutability. Re-tangling and restarting is recommended for a + ;; comprehensively updated Rapport Emacs. + + ;; Set the presumed (rapport-fn-context-get-label) naively based on early-init available system information. + (rapport-fn-featureset-load-preset 'context-during-earlyinit) + + ;; Native Compilation + ;; - Path to look-aside compilation directory. This specificity protects against spurious rebuilds when swapping emacs version or sharing a cache. + ;; ,TODO: this references some Rapport variables before they're set by Emacs's initialization. It uses safe fall-backs but perhaps we can improve this? + (setq native-comp-eln-load-path (list + ;; approx. "~/.uris/.vault-var/emacs/eln-cache/-//custom---context" + (expand-file-name + (format "%s" (or (when (functionp 'rapport-fn-context-get-label) + (rapport-fn-context-get-label)) + ".unset-label")) + (expand-file-name + (format "emacs-%s" emacs-version) + (expand-file-name + (string-replace "/" "+" (format "%s-%s" (car (split-string system-configuration "-")) system-type)) + (expand-file-name "eln-cache" (or + (bound-and-true-p rapport-uri-vault-var-emacs) + (when (getenv "RAPPORT__URI_VAULT_VAR") + (expand-file-name "emacs" (getenv "RAPPORT__URI_VAULT_VAR"))) + (bound-and-true-p no-littering-var-directory) + (when (file-directory-p "~/.uris/.vault-var/emacs") + "~/.uris/.vault-var/emacs") + (when (stringp (getenv "RAPPORT_EMACS__URI_INITDIR")) + (getenv "RAPPORT_EMACS__URI_INITDIR")) + user-emacs-directory))))) + ;; end list + )) + + ;; - Use the Newer Source if the Byte-Compiled files are older + (setq load-prefer-newer t) + + + ;; present simple start-up stats to Messages buffer + (add-hook 'after-init-hook + (lambda () (message " (rapport) Ready in %s with %d garbage collections." + (format "%.2f seconds" (float-time (time-subtract after-init-time before-init-time))) + gcs-done))) + + + ;; load early-init portions of Rapport configs + (rapport-fn-featureset-load-preset 'earlyinit) + + + ;; + (provide 'rapport-core-emacsearlyinit) +#+end_src + +*** Initialization, =init.el= :provide@rapport_core_emacsinit: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-emacsinit.el" (org-sbe rapport-sbe--get-libdir)) :mkdirp t +:header-args:emacs-lisp+: :noweb yes :comments both +:ID: 26D927F5-6454-4A69-84C4-1EB801D80417 +:END: + +setup Emacs initialization + +#+begin_src emacs-lisp + ;;; init.el --- Emacs init file used to bootstrap packages and configurations. + ;;; Commentary: + ;;; Code: + + ;;(package-initialize) + + ;; Display Rapport's startup/readiness time. + (message " (rapport) ::core|emacsinit:: starting ...") + + + ;; Simplify and Tidy Interface + (setq-default + auto-save-list-file-prefix nil ;; Initially disabled to avoid spurious auto-save creation in 'user-emacs-directory. + inhibit-startup-screen t + initial-scratch-message "") + + + ;; Suppress Specious, Spurious and Otherwise Inconsequential Start-Up Warning Messages + (setq-default + ;max-lisp-eval-depth (* 1600 10000) + native-comp-async-report-warnings-errors 'silent ; Suppress Native-Comp and Other Innocuous Warnings + ad-redefinition-action 'accept ; Silence warnings for redefinition + custom-unlispify-menu-entries nil ; Prefer kebab-case for titles + custom-unlispify-tag-names nil ; Prefer kebab-case for symbols + native-comp-async-report-warnings-errors 'silent ; Skip compilation error buffers + read-process-output-max (* 1024 1024) ; Increase read size per process + ;; end-of-list + ) + + + ;; Initialization Speed Hacks + (let* + ((gc-cons-threshold-orig 800000) ;; The default value is 800,000 bytes (aka 800k). + (gc-cons-threshold-startup (* 1024 1000 500)) ;; During the value is bumped up to 512 MB during initialization. + (gc-cons-percentage-adjusted 0.4)) ;; The value to use after Emacs is initialized. + (progn + ;; Make startup faster by reducing the frequency of garbage collection and then use a hook to measure Emacs startup time. + (setq gc-cons-threshold ;; Number of bytes of consing between garbage collections. + gc-cons-threshold-startup) + ;; Reset the default + `(add-hook 'emacs-startup-hook + (lambda () + (setq gc-cons-threshold ,gc-cons-threshold-orig + gc-cons-percentage ,gc-cons-percentage-adjusted))))) + + + ;; + (require 'rapport-core-featureset) + (rapport-fn-featureset-load-preset 'init) + + ;; initiate Emacs Performance Reporting + ;; https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/ + (if (bound-and-true-p rapport-emacs-opt-profiler) + (add-hook 'after-init-hook #'(lambda () (profiler-start rapport-emacs-opt-profiler)) 't) + (message " (rapport) nfo: profiling not enabled")) + + + ;; enable loading rapport configuration from environment variables + (defcustom rapport-emacs-opt-featureset-load-custom-from-env nil "") + (defcustom rapport-emacs-opt-featureset-load-presets-from-env t "") + + ;; + (add-hook 'after-init-hook (lambda () + ;; ,HINT: load the default 'afterinit preset + (rapport-fn-featureset-load-preset 'afterinit) + ;; ,HINT: discover and register the listing of additional loadable featuresets from the "rapport" directory + (when + (or (bound-and-true-p rapport-emacs-opt-featureset-inhibit-discovery-at-startup) + (and + (stringp (getenv "RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_DISCOVERY_AT_STARTUP")) + (string-match "^[yYtT]" (getenv "RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_DISCOVERY_AT_STARTUP")))) + (message (format " (rapport) ::core|emacsinit:: registered %s featureset-presets via discovery." + (length (rapport-fn-featureset-add-presets-from-discovery))))) + ;; ,HINT: this will load lisp-formatted featureset data during after-init, may require featureset discovery as a pre-req if the featureset preset isn't defined by default. + ;; ,EXAMPLE: export RAPPORT_EMACS__OPT_FEATURESET_LOAD_CUSTOM='((acculturations) (editors . (humans)) (endeavors . (teams projects campaigns practices)) (correspondences) (eminences) (charms . (baubles glamours))))' + (when (and (bound-and-true-p rapport-emacs-opt-featureset-load-custom-from-env) + (<= 1 (length (string-trim (getenv "RAPPORT_EMACS__OPT_FEATURESET_LOAD_CUSTOM"))))) + (let* + ((custom-featureset (read-from-string (getenv "RAPPORT_EMACS__OPT_FEATURESET_LOAD_CUSTOM"))) + (custom-featureset (if (consp custom-featureset) custom-featureset nil))) + (when custom-featureset + (and + (rapport-fn-featureset-load custom-featureset) + (message " (rapport) ::core|emacsinit:: registered featureset presets via discovery."))))) + ;; ,HINT: this will load a list of whitespace-delimited feature presets during after-init, may require featureset discovery as a pre-req if the featureset preset isn't defined by default. + ;; ,EXAMPLE: export RAPPORT_EMACS__OPT_FEATURESET_LOAD_PRESETS='researcher &rapport-acculturations-concepts' + (when (and (bound-and-true-p rapport-emacs-opt-featureset-load-presets-from-env) + (<= 1 (length (string-trim (getenv "RAPPORT_EMACS__OPT_FEATURESET_LOAD_PRESETS"))))) + (let* + ((feature-presets (string-split (getenv "RAPPORT_EMACS__OPT_FEATURESET_LOAD_PRESETS")))) + (when feature-presets (mapcar #'rapport-fn-featureset-load-preset feature-presets)))) + ;; close-lambda + )) + + + ;; + (provide 'rapport-core-emacsinit) + ;; init.el ends here +#+end_src + +*** Feature Set Management :provide@rapport_core_featureset: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-featureset.el" (org-sbe rapport-sbe--get-libdir)) :noweb yes +:ID: FBADC216-53E9-4425-8ADC-8362DF40443B +:END: + +#+begin_src emacs-lisp + ;; ,NB: the 'xtrialx' featureset is included in discovery but excluded from the '&everything' preset, so that it's never loaded implicitly + (require 'subr-x) ;; ,HINT: needed for #'string-join + ;; + (defcustom rapport-featureset-discovered-presets-fmt "&" "") + (defcustom rapport-featureset-filename-rx-parts '("rapport-" ".*" ".el" "$") "") + (defcustom rapport-featureset-filename-rx (string-join rapport-featureset-filename-rx-parts) "") + ;; auxilliary features + (defcustom rapport-featureset-auxdirs-discovered-presets-fmt "+" "") + (defcustom rapport-featureset-auxdirs-filename-rx-parts '("rapport-" ".*" ".el" "$") "") + (defcustom rapport-featureset-auxdirs-filename-rx (string-join rapport-featureset-auxdirs-filename-rx-parts) "") + + ;; ,TODO: is there a robust way to fetch (rather than hard-code) this value during early-init + (defcustom rapport-featureset-presets + `( + ;; start-up and initialization presets + (tangle-during-earlyinit . ((core . tangle))) + (context-during-earlyinit . ((core . context))) + (earlyinit . ((core . (context featureset functions variables pkgs)))) + (init . ((core . (context featureset functions variables pkgs org sysint customize)))) + (afterinit . ( + (editors . (sysnav switchboard text org)) + (endeavors . (forges workspaces tasks)) + (charms . (glamours)) + )) + ;; supplemental use-case presets + (mediakit . ( + (acculturations) + (endeavors . (practices)) + (acculturations . (infowebs media)) + (charms) + )) + (swdev . ( + (editors . (swdev)) + (endeavors . (practices teams)) + (acculturations . (infowebs media)) + )) + (devops . ( + (editors . (infradev)) + (endeavors . (practices teams)) + (acculturations . (infowebs)) + (coherence) + )) + (researcher . ( + (editors . (data humans)) + (acculturations) + (coherence) + (correspondences) + ;?; eminences + )) + (manager . ( + (acculturations) + (editors . (humans)) + (endeavors . (teams projects campaigns practices)) + (correspondences) + (eminences) + (charms . (baubles glamours)) + )) + (executive . ( + (endeavors . (teams projects campaigns practices composure)) + (acculturations) + (correspondences) + (eminences) + (charms . (baubles glamours)) + )) + ;; do-nothing case + (nil . nil)) + "List of Rapport Modules to load. Inspipred by org-modules. + The format is a named, ordered traversal list. (eg. '(key . (step1 . (step2))) ) ... which may also be written '(key step1 step2) becuase the underlying repesentation is identical. + NOTE: The initial/default value for this variable may be expected to change when the Emacs Customization file is loaded, (potentially as a result of loading the 'rapport-core-customize feature)." + :group 'rapport) + ;; + (defun rapport-fn-featureset-get-uri-initdir () "Get the path to the directory used by Rapport Emacs during initialization. Note: Uses a tangled insert from the 'rapport-sbe--get-initdir Org-mode Source Block in the Control file." + <>) + ;; + (defun rapport-fn-featureset-get-uri-control () "Get the path to the file used by Rapport Emacs to control it's configuration and execution during build. Note: Uses a tangled insert from the 'rapport-sbe--get-control Org-mode Source Block in the Control file." + <>) + ;; + (defun rapport-fn-featureset-get-uri-libdirs () + "Get an ordered list of all valid Rapport LIBDIR paths. Note: Uses a tangled insert from the 'rapport-sbe--get-libdirs Org-mode Source Block in the Control file. " + <>) + ;; + (defun rapport-fn-featureset-get-uri-libdir () "The primary LIBDIR path. Typically this is the 'car of LIBDIRS." + (or (bound-and-true-p rapport-emacs-uri-libdir) + (car (rapport-fn-featureset-get-uri-libdirs)))) + ;; + (defun rapport-fn-featureset-decorate-preset-key (key &optional key-decorate-fmt) "" + (let* + ((default-fmt "%s") + ;; ,HINT: convert key from symbol to string + (key (string-trim + (or (and (symbolp key) (symbol-name key)) + (and (stringp key) key)))) + ;; ,HINT: lookup fmt to use, either passed in, or set via Customization, else use 'default-fmt + (key-decorate-fmt (string-trim + (or (bound-and-true-p key-decorate-fmt) + (bound-and-true-p rapport-featureset-discovered-presets-fmt) + default-fmt))) + ;; ,HINT: ensure that key-decorate-fmt includes one format-string (eg "%s") for the key to be interpolated. Where absent, append it. + (key-decorate-fmt (or (and (string-match default-fmt key-decorate-fmt) + key-decorate-fmt) + (string-join `(,key-decorate-fmt "%s"))))) + (intern + (cond + ;; ,HINT: if there's no decoration in the format string, skip formatting and return the intern + ((string-equal key-decorate-fmt default-fmt) key) + (t (format key-decorate-fmt key)))))) + ;; + (defun rapport-fn-featureset-derive-preset-key-from-file (uri &optional key-decorate-fmt) "" + (let* + ((strip-prefix (car rapport-featureset-filename-rx-parts)) + (split-sep "-") + (file-basename (file-name-base uri)) + (key (rapport-fn-featureset-decorate-preset-key file-basename)) + (file-kebab (string-remove-prefix strip-prefix file-basename)) + (feat-parts-str (split-string file-kebab split-sep)) + (feat-parts-sym (mapcar 'intern feat-parts-str))) + (cons key (list feat-parts-sym)))) + ;; + (defun rapport-fn-featureset-list-feature-files (&optional dir) "" + (let + ((dir (or (bound-and-true-p dir) + (rapport-fn-featureset-get-uri-libdir)))) + (directory-files dir t rapport-featureset-filename-rx))) + ;; + (defun rapport-fn-featureset-reduce-set (unimplemented) "") + ;; + (defun rapport-fn-featureset-discovery (&optional dir) "" + (let* + ((dir (or (bound-and-true-p dir) + (rapport-fn-featureset-get-uri-libdir))) + (files (rapport-fn-featureset-list-feature-files dir)) + (sets (mapcar 'rapport-fn-featureset-derive-preset-key-from-file files))) + ;; let-body + sets)) + ;; + (defun rapport-fn-featureset-add-presets-from-discovery () "" + (interactive) + (mapcar (lambda (set) (add-to-list 'rapport-featureset-presets set)) (rapport-fn-featureset-discovery))) + ;; + (defun rapport-fn-featureset-remove-presets-from-discovery () "" + (interactive) + (mapcar (lambda (set) (setq rapport-featureset-presets (remove set rapport-featureset-presets))) (rapport-fn-featureset-discovery))) + ;; + (defun rapport-fn-featureset-filter-keys-by-regex (&optional match action presets) + "regex, (opt) op: one of include or exclude, (opt) presets" + (let* + ((default-match ".*") + (match (or (and (stringp (bound-and-true-p match)) match) + default-match)) + (actions-alist '((include-match #'when) + (exclude-match #'unless))) + (valid-actions (mapcar 'car actions-alist)) + (default-action (car valid-actions)) + (action (or (and (bound-and-true-p action) + (car (member action valid-actions))) + default-action)) + (presets (or (bound-and-true-p presets) + (rapport-fn-featureset-discovery))) + (action-fn (car (alist-get action actions-alist)))) + ;; ,TODO: refactor to use funcall w/ the cdr from the selected action-alist + (remove nil + (mapcar (lambda (entry) + (cond + ((eq action 'include-match) (when (string-match-p match (symbol-name (car entry))) entry)) + ((eq action 'exclude-match) (unless (string-match-p match (symbol-name (car entry))) entry)))) + presets)))) + ;; + (defun rapport-fn-featureset-add-preset-everything (&optional key) + "optional string KEY, defaults to 'everything. + Notably, components for 'xtrialx are intentionally not included in this definition of everything." + (interactive) + (let* + ((key (if (and (bound-and-true-p key) (stringp key)) + key + (concat rapport-featureset-discovered-presets-fmt "everything")))) + (add-to-list 'rapport-featureset-presets + `(,(intern key) . ,(mapcar 'cadr + ;; remove xtrialx to exclude it from the definition of the 'everything preset + (rapport-fn-featureset-filter-keys-by-regex "xtrial" 'exclude-match (rapport-fn-featureset-discovery))))))) + ;; + (defun rapport-fn-featureset-presets (&optional key) "" + (cdr (assoc key rapport-featureset-presets))) + ;; + (defun rapport-fn-featureset-presets-list () "" + (mapcar 'car rapport-featureset-presets)) + ;; + (defun rapport-fn-featureset-load (&optional featureset) + "declare the startup ingredients and order for starting Rapport Emacs" + (mapcar (lambda (featureset) + (cond + ;; ,example: 'featname + ((symbolp featureset) + (require (intern (format "%s-%s" "rapport" featureset)))) + ;; ,example: '(featname) + ;; ,example: '(featname . nil) + ((and (consp featureset) (null (cdr featureset))) + (require (intern (format "%s-%s" "rapport" (car featureset))))) + ;; ,example: '(featname . symbvar) + ((and (consp featureset) (null (null (cdr featureset))) (null (listp (cdr featureset))) (symbolp (cdr featureset))) + (require (intern (format "%s-%s-%s" "rapport" (car featureset) (cdr featureset))))) + ;; ,example: '(featname symbvar1 symbvar2 symbvar3) + ;; ,example: '(featname . '(symbvar1 symbvar2 symbvar3) + ((and (consp featureset) (null (null (cdr featureset))) (listp (cdr featureset))) + (mapcar (lambda (x) (require (intern (format "%s-%s-%s" "rapport" (car featureset) x)))) (cdr featureset))))) + (or (bound-and-true-p featureset) (bound-and-true-p rapport-emacs-featureset-requested) nil))) + ;;;###autoload + (defun rapport-fn-featureset-load-preset (key) + "preset key must already exist as a top-level symbol in the variable 'rapport-featureset-presets. + This function is a convenience wrapper on top of functions 'rapport-fn-featureset-load and 'rapport-fn-featureset-presets." + (interactive (list (intern (completing-read "Select a Preset: " (rapport-fn-featureset-presets-list))))) + (let* + ((valid-keys (rapport-fn-featureset-presets-list)) + (inhibits-from-cfgs (when (and (bound-and-true-p rapport-emacs-opt-featureset-inhibit-presets) + (listp rapport-emacs-opt-featureset-inhibit-presets) + (<= 1 (length rapport-emacs-opt-featureset-inhibit-presets))) + rapport-emacs-opt-featureset-inhibit-presets)) + (inhibits-from-env (when (stringp (getenv "RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_PRESETS")) + (split-string (getenv "RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_PRESETS")))) + (inhibits (remove nil (append inhibits-from-env inhibits-from-cfgs))) + (key (cond ((stringp key) (intern key)) + ((listp key) (car key)) + (t key))) + (key-valid-type-p (symbolp key)) + (key-valid-membership-p (member key valid-keys)) + (key-valid-inhibit-p (null (member (symbol-name key) inhibits))) + (key-valid-p (and key-valid-type-p key-valid-membership-p key-valid-inhibit-p))) + + (cond + ;; the special cases + ((string-equal "nil" (symbol-name key)) (message " (rapport) ::core|featureset:: requested special-case preset-key 'nil' which is a no-op, and doesn't loads anything.")) + + ;; the error cases + ((not key-valid-type-p) (message " (rapport) ::core|featureset:: invalid-type for variable 'key (expected: symbol).")) + ((not key-valid-membership-p) (message (format " (rapport) ::core|featureset:: value for variable `'key `'%s not found in #'(rapport-fn-featureset-presets-list) ." (symbol-name key)))) + ((not key-valid-inhibit-p) (message (format " (rapport) ::core|featureset:: inhibited preset %s from loading due to inhibit envVar config '%s'" (symbol-name key) inhibits))) + + ;; the success case + (key-valid-p (progn + (rapport-fn-featureset-load (rapport-fn-featureset-presets key)) + (message (format " (rapport) ::core|featureset:: loaded preset '%s'" key)))) + ;; the canary case + (t (message " (rapport) unhandled case encountered"))))) + + + ;; Update listing of Rapport presets to include dynamically discovered features + (add-hook 'after-init #'rapport-fn-featureset-add-presets-from-discovery) + ;; Add special-case preset 'everything to load all Rapport features + (add-hook 'after-init #'rapport-fn-featureset-add-preset-everything) + + + ;; + (provide 'rapport-core-featureset) +#+end_src + +*** Determine Context Label :provide@rapport_core_context: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-context.el" (org-sbe rapport-sbe--get-libdir)) :mkdirp t +:ID: CA4F239F-A30F-4F51-8E0B-F933980DEAAA +:END: + +#+begin_src emacs-lisp +;; Set the custom-file path based on the first file found from a ranked list of generated candidate paths. +(defcustom rapport-context-custom-label nil + "most of the time, this value should remain 'nil. To fetch the value for Rapport's context-label, please use the '(rapport-fn-context-get-label) function instead. This variable should only be used as an indirect override, not as a way to retrieve this value." + :group 'rapport :type '(file :must-match t)) + +;; +(defun rapport-fn-context-candidate-label-list () "" + (or (bound-and-true-p rapport-context-custom-label) + (remove nil (list + (format "custom-%s-%s-context" (string-replace "." "+" system-name) user-login-name) + (format "custom-%s--context" user-login-name) + (format "custom---context"))))) +;; +(defun rapport-fn-context-candidate-confdir-list () "" + (remove nil + (delete-dups + (list + ;; ,example: ~/.vault/cfgs/emacs + (and (bound-and-true-p rapport-uri-vault-cfgs-emacs) + (file-directory-p rapport-uri-vault-cfgs-emacs) + rapport-uri-vault-cfgs-emacs) + ;; ,example: ~/.vault/cfgs/emacs + (and (bound-and-true-p rapport-uri-vault-cfgs) + (file-directory-p (expand-file-name "emacs" rapport-uri-vault-cfgs)) + (expand-file-name "emacs" rapport-uri-vault-cfgs)) + ;; + (and (not (null (getenv "RAPPORT__URI_VAULT_CFGS"))) + (file-directory-p (getenv "RAPPORT__URI_VAULT_CFGS")) + (file-directory-p (expand-file-name "emacs" (getenv "RAPPORT__URI_VAULT_CFGS"))) + (expand-file-name "emacs" (getenv "RAPPORT__URI_VAULT_CFGS"))) + ;; + (and (bound-and-true-p rapport-uri-vault) + (file-directory-p (expand-file-name "emacs" (expand-file-name "cfgs" rapport-uri-vault))) + (expand-file-name "emacs" (expand-file-name "cfgs" rapport-uri-vault))) + ;; + (and (not (null (getenv "RAPPORT__URI_VAULT"))) + (file-directory-p (getenv "RAPPORT__URI_VAULT")) + (file-directory-p (expand-file-name "emacs" (expand-file-name "cfgs" (getenv "RAPPORT__URI_VAULT")))) + (expand-file-name "emacs" (expand-file-name "cfgs" (getenv "RAPPORT__URI_VAULT")))) + ;; + (and (not (null (getenv "HOME"))) + (file-directory-p (getenv "HOME")) + (file-directory-p (expand-file-name "emacs" (expand-file-name "cfgs" (expand-file-name ".vault" (getenv "HOME"))))) + (expand-file-name "emacs" (expand-file-name "cfgs" (expand-file-name ".vault" (getenv "HOME"))))) + ;; + (expand-file-name "" user-emacs-directory))))) +;; ,TODO: unimplemented +;;;###autoload +(defun rapport-fn-context-discover () "return a cons of '( uri . label )" + (let + ((candidate_labels_lst (rapport-fn-context-candidate-label-list)) + (candidate_confdirs_lst (rapport-fn-context-candidate-confdir-list))) + ;; prefer the best label across valid confdirs locations, inputs are sorted so we'll return on the first match. + (catch 'match + (mapcar (lambda (label) + (mapcar (lambda (confdir) + (when (file-readable-p (format "%s.el" (expand-file-name label confdir))) + (throw 'match (cons (format "%s.el" (expand-file-name label confdir)) label)))) + candidate_confdirs_lst)) + candidate_labels_lst) + ;; if no existing files are found, return a generic fallback label value, "custom---context.el" + (cons + (expand-file-name (format "%s.el" (car (last candidate_labels_lst))) (car (last candidate_confdirs_lst))) + (car (last candidate_labels_lst)))))) +;;;###autoload +(defun rapport-fn-context-get-label () + "Return the context-label string after generating a ranked-list and selecting the most desirable best-available-match (or fall-back) option. The best-available-match calculation is based on a system scan of config names. It's possible, likely, and even intended for the returned selection to change over time to become more tightly matched and more highly specified. This function is used in the determination of the path/filename for the 'custom-file variable, taken from the first match of a contextually derived ranked list. System, User, label used to distinguish and designate among various configs, paths, and other variables. Perhaps most notably used with 'custom-file' and session-persistence variables. Taken from the first match of a contextually derived ranked list." + (interactive) + (or (bound-and-true-p rapport-context-custom-label) + (cdr (rapport-fn-context-discover)))) + +;;;###autoload +(defun rapport-fn-context-get-uri () + "Return the URI to the presumptive 'custom-file'" + (car (rapport-fn-context-discover))) + + +;; +(provide 'rapport-core-context) +#+end_src + +*** Conditional Tangle :provide@rapport_core_tangle: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-tangle.el" (org-sbe rapport-sbe--get-libdir)) +:ID: 5A1DA63B-54B0-41F1-84B7-4EA70CC6719E +:END: + +#+begin_src emacs-lisp +;; +(defcustom rapport-tangle-files-map + `((,(rapport-fn-featureset-get-uri-control) . ,(list + (expand-file-name "early-init.el" (rapport-fn-featureset-get-uri-initdir)) + (expand-file-name "init.el" (rapport-fn-featureset-get-uri-initdir)) + (expand-file-name "rapport-acculturations-concepts.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-acculturations-media.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-acculturations-infowebs.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-acculturations.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-charms-baubles.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-charms-glamours.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-charms-hints.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-charms-jests.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-charms.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-coherence.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-context.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-customize.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-emacsearlyinit.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-emacsinit.el" (rapport-fn-featureset-get-uri-libdir)) + ;(expand-file-name "rapport-core-entrypoints.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-featureset.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-functions.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-measurements.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-org.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-pkgs.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-sysint.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-tangle.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-core-variables.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-correspondences.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-data.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-data2viz.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-humans.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-infradev.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-org.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-swdev.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-switchboard.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-sysnav.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors-text.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-editors.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-eminences.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-campaigns.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-composure.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-forges.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-practices.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-projects.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-tasks.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-teams.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors-workspaces.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-endeavors.el" (rapport-fn-featureset-get-uri-libdir)) + (expand-file-name "rapport-miscellany.el" (rapport-fn-featureset-get-uri-libdir)) + ;; end-of-list + ))) + "The as an associative list of Rapport Tangle Source files and their Expected Tangle files." + :group 'rapport :type '(set (file :must-match t))) +;; +(defun rapport-fn-tangle-source-files-list (&optional files-map) + "Paths to the Rapport Tangle Source Files." + (mapcar (lambda (x) (expand-file-name "" x)) + (mapcar 'car (or (bound-and-true-p files-map) + rapport-tangle-files-map)))) +;; +(defun rapport-fn-tangle-target-files-expected (source-uri) "" + (let + ((source-uri (or (and (bound-and-true-p source-uri) + (file-readable-p source-uri) + source-uri)))) + (cdr (assoc source-uri rapport-tangle-files-map)))) +;; +(defun rapport-fn-tangle-wanted-p (source-uri) + "if source-uri is newer than it's corresponding target-uri, then flag for tangle by returning non-nil. source-uri must be in the list returned by #'rapport-fn-tangle-source-files-list" + (let* + ((source-uri (and (bound-and-true-p source-uri) + (member source-uri (rapport-fn-tangle-source-files-list)) + source-uri)) + (source-mtime (file-attribute-modification-time (file-attributes source-uri))) + (tangle-targets (rapport-fn-tangle-target-files-expected source-uri))) + (catch 'tangle-wanted + ;; loop while there are targets and no tangle requests + (mapcar + (lambda (target) + (or + (and (not (file-readable-p target)) ;; if it doesn't exist + (message (format " (rapport) ::core|tangle:: requesting retangle of %s (because %s doesn't exist)" source-uri target)) + (throw 'tangle-wanted source-uri)) + (and (time-less-p (file-attribute-modification-time (file-attributes target)) source-mtime) ;; if it's newer than it's source + (message (format " (rapport) ::core|tangle:: requesting retangle of %s (because it's newer than %s)" source-uri target)) + (throw 'tangle-wanted source-uri)) + (message (format " (rapport) ::core|tangle:: skipping retangle of %s (wasn't needed for %s)" source-uri target)))) + tangle-targets) + nil))) +;; +(defun rapport-fn-tangle-maybe (&optional source-uri) "" + (let ((source-uri (or (bound-and-true-p source-uri) + (rapport-fn-featureset-get-uri-control)))) + (when (rapport-fn-tangle-wanted-p source-uri) + (message (format " (rapport) ::core|tangle:: tangling %s " (file-name-nondirectory source-uri))) + (message "\t--->> //--- \n\t exit-code: %s \n\t---// <<--- " + (with-temp-buffer + (add-to-list 'exec-path "/usr/local/bin") + (add-to-list 'exec-path "c:/ProgramData/chocolatey") + (call-process-shell-command (format "%s --batch -Q -l org --eval '(setq org-confirm-babel-evaluate nil)' -l ob-tangle %s -f org-babel-tangle --kill" + (executable-find "emacs") source-uri) + nil '(t t) nil)))))) + + + ;;;###autoload +(defun rapport-fn-tangle-files-maybe () "" + (interactive) + (mapcar (lambda (source-uri) (rapport-fn-tangle-maybe source-uri)) + (rapport-fn-tangle-source-files-list))) + + + +;; The function =rapport-fn-tangle-maybe= tangles a single source URI if it is newer than its corresponding target URIs. It first checks if the source URI is valid and in the list of tangle source files. If so, it checks the modification time of the source URI and compares it to the modification time of the corresponding target URIs. If any target URI is newer than the source URI, it requests a retangle of the source URI. + +;; If a retangle is requested, the function calls Emacs to tangle the source URI using the command =emacs --batch -Q -l org --eval '(setq org-confirm-babel-evaluate nil)' -l ob-tangle -f org-babel-tangle --kill=. The output of the tangle process is displayed in the message buffer. + +;; The function =rapport-fn-tangle-files-maybe= tangles all source URIs in the list of tangle source files. It is typically called interactively, but can also be called programmatically. + +;; +(provide 'rapport-core-tangle) +#+end_src + +*** Define Functions :provide@rapport_core_functions: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-functions.el" (org-sbe rapport-sbe--get-libdir)) +:ID: 20F393B2-F7FD-4E18-9C12-D086B0CBE5C0 +:END: + +#+begin_src emacs-lisp + ;;; Required Libraries + (require 'subr-x) ;; needed by '(rapport-fn-file-to-feature . (string-remove-prefix)) + + + ;; + (defun rapport-fn-file-to-feature (uri) + "Generate a feature symbol from URI in support of dynamically discovered features." + (intern (replace-regexp-in-string "\\." "-" (string-remove-prefix "." (file-name-base uri))))) + ;; + (defun rapport-fn-feature-to-file (sym) + "Generate a URI from a feature symbol in support of dynamically discovered features." + (expand-file-name (format ".%s.%s.%s.el" + (car (split-string (symbol-name sym) "-")) + (nth 1 (split-string (symbol-name sym) "-")) + (string-join (cddr (split-string (symbol-name sym) "-")) "-")) + rapport-uri-rapport)) + + ;; + ;; (defun rapport/org/tangle-by-tag () "" + ;; (catch 'tag (mapc (lambda (x) (when (string-match "^tangle#" x 0 t) (throw 'tag (string-remove-prefix "tangle#" x)))) (split-string (nth 5 (org-heading-components)) ":" t)))) + + + ;; + (defun rapport-fn-current-time-as-string () + "Return a string of the current time." + (concat + (format-time-string "%Y-%m-%dT%H%M%SZ%z"))) + + ;; + (defun rapport/doct/append (oct) (mapc (lambda (x) (add-to-list 'org-capture-templates x)) oct)) + + + ;; + (provide 'rapport-core-functions) +#+end_src + +*** Control Variables :provide@rapport_core_variables: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-variables.el" (org-sbe rapport-sbe--get-libdir)) +:ID: FE12F899-396E-4DE6-AAFF-BE2DBD9CDF93 +:END: + +#+begin_src emacs-lisp + +;; Set top-level features to On or Off. +(defcustom rapport-emacs-opt-load-custom-file (or (getenv "RAPPORT_EMACS__OPT_LOAD_CUSTOM_FILE") t) + "Load the local custom file." + :group 'rapport :type '(boolean)) + +(defcustom rapport-emacs-opt-theme (or (getenv "RAPPORT_EMACS__OPT_THEME") "ef-trio-dark") + "A name used to selectively match theming configuration presets defined in Rapport." + :group 'rapport :type '(string)) +(defcustom rapport-emacs-opt-modeline (or (getenv "RAPPORT_EMACS__OPT_MODELINE") "lambda") + "A name used to selectively match theming configuration presets defined in Rapport." + :group 'rapport :type '(string)) +(defcustom rapport-emacs-opt-org-modified + (let* + ((option-from-env (getenv "RAPPORT_EMACS__OPT_ORG_MODIFIED")) + (option-from-env (and (stringp (bound-and-true-p option-from-env)) + (car (member-ignore-case option-from-env + '("agenda" "buffer"))))) + (option-from-env (when option-from-env (intern option-from-env)))) + option-from-env) + "Enable Modification TS tracking for Headings in Org-Mode." + :group 'rapport :type '(radio + (const :tag "Agenda" 'agenda) + (const :tag "Buffer" 'buffer) + (const :tag "Tag" 'tag) + (const :tag "None" 'nil))) + +;; TODO: +(defcustom rapport-emacs-opt-profiler + (let* + ((profiler-option-from-env (getenv "RAPPORT_EMACS__OPT_PROFILER")) + (profiler-option-from-env (and (stringp (bound-and-true-p profiler-option-from-env)) + (car (member-ignore-case profiler-option-from-env + '("cpu" "mem" "cpu+mem"))))) + (profiler-option-from-env (when profiler-option-from-env (intern profiler-option-from-env)))) + profiler-option-from-env) + "Profile the init-aux file." + :group 'rapport :type '(radio + (const :tag "None" 'nil) + (const :tag "CPU" 'cpu) + (const :tag "Memory" 'mem) + (const :tag "Both CPU and Memory" 'cpu+mem))) + + +(defcustom rapport-emacs-opt-debug-on-error + (let* + ((debugger-option-from-env (getenv "RAPPORT_EMACS__OPT_DEBUG_ON_ERROR")) + (debugger-option-from-env (and + (bound-and-true-p debugger-option-from-env) + (stringp debugger-option-from-env) + (numberp (string-match-p "^[tTyY]" debugger-option-from-env))))) + debugger-option-from-env) + "Enable Debug on Error for troubleshooting purposes." + :group 'rapport :type '(boolean)) +(setq-default debug-on-error rapport-emacs-opt-debug-on-error) + + + ;;; Rapport Path (aka URI) Variables for Import Locations. + +(defcustom rapport-uri-emacsdotd + (file-truename + (or user-emacs-directory + (file-name-directory buffer-file-name))) + "Location of the Emacs Directory." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-rapport (rapport-fn-featureset-get-uri-libdir) "" :group 'rapport :type '(directory)) + +(defcustom rapport-uri-vault (or (getenv "RAPPORT__URI_VAULT") + (expand-file-name ".vault" "~")) + "Location of the root directory for personal data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-uris (or (getenv "RAPPORT__URI_VAULT_URIS") + "~/.uris" ;; ,TODO: this option is valid only-if: it's a symlink that points to a location somewhere in rapport-uri-vault, else 'nil + (expand-file-name (format ".vault-uris.%s" system-name) (expand-file-name "uris" rapport-uri-vault))) + "Location of the navigational links directory for personal, system, and project data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-apps (or (getenv "RAPPORT__URI_VAULT_APPS") + (expand-file-name "apps" rapport-uri-vault)) + "Location of the personal executables directory for personal applications." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs (or (getenv "RAPPORT__URI_VAULT_DOCS") + (expand-file-name "docs" rapport-uri-vault)) + "Location of the documents directory for personal data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-calendars (expand-file-name "calendars" rapport-uri-vault-docs) + "Location of the directory for Concept documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-concepts (expand-file-name "concepts" rapport-uri-vault-docs) + "Location of the directory for Concept documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-contacts (expand-file-name "contacts" rapport-uri-vault-docs) + "Location of the directory for Contact documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-status (expand-file-name ".status" rapport-uri-vault-docs) + "Location of the directory for Status documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-tasks (expand-file-name "tasks" rapport-uri-vault-docs) + "Location of the directory for Task documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-media (expand-file-name "media" rapport-uri-vault-docs) + "Location of the directory for Media documents, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-docs-practices (expand-file-name "practices" rapport-uri-vault-docs) + "Location of the directory for Practices documents and workspaces, (typically within the personal documents directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-var (or (getenv "RAPPORT__URI_VAULT_VAR") + (file-truename (expand-file-name ".vault-var" rapport-uri-vault-uris))) + "Location of the var/tmp directory for personal data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-var-emacs (expand-file-name "emacs" rapport-uri-vault-var) + "Location of the var/tmp directory for Emacs data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs (or (getenv "RAPPORT__URI_VAULT_CFGS") + (expand-file-name "cfgs" rapport-uri-vault)) + "Location of the root directory for personal data." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs-emacs (expand-file-name "emacs" (expand-file-name "cfgs" rapport-uri-vault)) + "Location of the Emacs configuration directory, (typicall within the personal data directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs-emacs-apps (expand-file-name "apps" rapport-uri-vault-cfgs-emacs) + "Location of the config directory for Emacs applications, (typically within the Emacs configuration directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs-emacs-apps-org (expand-file-name "org" rapport-uri-vault-cfgs-emacs-apps) + "Location of the config directory for Org-Mode, (typically within the Emacs applications directory)." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs-emacs-apps-org-setupfile (concat "~/" (file-relative-name (expand-file-name "org-setupfile" rapport-uri-vault-cfgs-emacs-apps-org) "~")) + "Location of the default 'org-setupfile for bootstrapping Org-Mode files with configs." + :group 'rapport :type '(directory)) +(defcustom rapport-uri-vault-cfgs-emacs-pkgs (expand-file-name "pkgs" rapport-uri-vault-cfgs-emacs) + "" + :group 'rapport :type '(directory)) + +(provide 'rapport-core-variables) +#+end_src + +** Package and Dependency Management :provide@core_pkgs#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-pkgs.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** Introductory Setup +:PROPERTIES: +:ID: 0F366E5E-13F8-4F78-B698-06FAA1A83CA2 +:END: + +#+begin_src emacs-lisp +;; pre-requisite features +(require 'rapport-core-context) +(require 'rapport-core-featureset) +(require 'rapport-core-functions) +(require 'rapport-core-variables) + +;; +(defconst rapport-emacs-opt-pkgs-mgmt + (let* + ((valid-values '( + elpaca + straight + )) ;; previously this supported using 'elpaca and/or 'straight . As of 2024 and for the forseeable future only 'elpaca is supported + (default-value (list (car valid-values))) + (errlog_msg_fmt " (rapport) ::core|pkgs:: [WARN] the input value '%s' for 'rapport-emacs-opt-pkgs-mgmt taken from environment variable '%s', was skipped becuase it failed a '%s' validation check") + (from-env-lookup-keyword "RAPPORT_EMACS__OPT_PKGS_MGMT") + (input-from-env (getenv from-env-lookup-keyword)) + (input-from-env (when (stringp input-from-env) + (split-string input-from-env))) + (input-from-env-type-valid? (when (listp input-from-env))) + ;; ,HINT: remove any non-strings or zero length strings and convert list items from string to symbol + (input-from-env (when input-from-env-type-valid? + (remove nil (mapcar (lambda (x) + (if (and (stringp x) (length> x 0)) + (intern x) + (message (format errlog_msg_fmt x input-from-env-lookup-keyword "non-zero-length")))) + input-from-env)))) + (input-from-env-value-valid? (and input-from-env-type-valid? + (remove nil + (mapcar (lambda (x) (car (member x valid-values))) input-from-env))))) + (or input-from-env-value-valid? default-value)) + "A precedence-ordered list of package management features to enable. The first entry is used as the primary, and any other entries in the list are taken as supplemental features or modifying behaviors. For example if 'elpaca is the first in the list and 'straight is the second, then 'elpaca will be setup as the primary package manager and 'straight will be installed using 'elpaca. If the list contains only one entry, 'elpaca for example, then elpaca would be setup to manage packages and straight support would be ommited. This has some implications because Rapport seeks to harmoniously support more than one package management system, so to prevent errors within a config that makes reference to multiple systems, any unused (non-primary and non-supplemental) systems will be partially or innocously declared as no-ops to prevent spurious errors from undefined references to keywords and functions.") + + +;; +(defun rapport-fn-pkgs-get-builds-dir (&optional basedir) + (let* + ((basedir (or (bound-and-true-p basedir) + (and (bound-and-true-p rapport-emacs-opt-pkgs-mgmt) + (bound-and-true-p rapport-uri-vault-var-emacs) + (expand-file-name (symbol-name (car rapport-emacs-opt-pkgs-mgmt)) rapport-uri-vault-var-emacs)) + user-emacs-directory))) + (expand-file-name + (string-replace "/" "+" + (format "build_v%s-%s-%s" emacs-version (car (split-string system-configuration "-")) system-type)) + basedir))) + +;; designate pre-configs for elpaca +(when (member 'elpaca rapport-emacs-opt-pkgs-mgmt) + (defconst elpaca-directory (expand-file-name "elpaca" rapport-uri-vault-var-emacs)) + (defconst elpaca-builds-directory (rapport-fn-pkgs-get-builds-dir elpaca-directory)) + (defconst elpaca-repos-directory (expand-file-name "repos" elpaca-directory)) + ;; set a fall-back value if unset by elpaca distribution + (when (or (not (bound-and-true-p elpaca-core-date)) + (equal elpaca-core-date '(-1))) + (setq-default elpaca-core-date '(20240101))) + ;; ensure 'elpaca is added to load-path + (add-to-list 'load-path (expand-file-name "elpaca" (if (file-exists-p (expand-file-name "elpaca.el" (expand-file-name "elpaca" elpaca-builds-directory))) elpaca-builds-directory elpaca-repos-directory)))) + +;; designate pre-configs for straight +(when (member 'straight rapport-emacs-opt-pkgs-mgmt) + (defconst straight-base-dir rapport-uri-vault-var-emacs) + (defconst straight-build-dir (rapport-fn-pkgs-get-builds-dir (expand-file-name "straight" rapport-uri-vault-var-emacs)))) +#+end_src + +*** Package Management w/ =elpaca.el= :feature_preview: + +**** Install and configure =elpaca= +:PROPERTIES: +:ID: A2FF1C1D-3A44-4783-AA08-82A29FEF8DEB +:END: +#+begin_src emacs-lisp +(when (equal (car rapport-emacs-opt-pkgs-mgmt) 'elpaca) + ;; + ;;; elpaca.el --- emacs package manager + ;;; Commentary: + ;;; Code: + (defvar elpaca-installer-version 0.7) + ;; (defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory)) + ;; (defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory)) + ;; (defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory)) + (defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git" + :ref nil :depth 1 + :files (:defaults "elpaca-test.el" (:exclude "extensions")) + :build (:not elpaca--activate-package))) + (let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory)) + (build (expand-file-name "elpaca/" elpaca-builds-directory)) + (order (cdr elpaca-order)) + (default-directory repo)) + (add-to-list 'load-path (if (file-exists-p build) build repo)) + (unless (file-exists-p repo) + (make-directory repo t) + (when (< emacs-major-version 28) (require 'subr-x)) + (condition-case-unless-debug err + (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*")) + ((zerop (apply #'call-process `("git" nil ,buffer t "clone" + ,@(when-let ((depth (plist-get order :depth))) + (list (format "--depth=%d" depth) "--no-single-branch")) + ,(plist-get order :repo) ,repo)))) + ((zerop (call-process "git" nil buffer t "checkout" + (or (plist-get order :ref) "--")))) + (emacs (concat invocation-directory invocation-name)) + ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch" + "--eval" "(byte-recompile-directory \".\" 0 'force)"))) + ((require 'elpaca)) + ((elpaca-generate-autoloads "elpaca" repo))) + (progn (message "%s" (buffer-string)) (kill-buffer buffer)) + (error "%s" (with-current-buffer buffer (buffer-string)))) + ((error) (warn "%s" err) (delete-directory repo 'recursive)))) + (unless (require 'elpaca-autoloads nil t) + (require 'elpaca) + (elpaca-generate-autoloads "elpaca" repo) + (load "./elpaca-autoloads"))) + (add-hook 'after-init-hook #'elpaca-process-queues) + ;; ,ORIG: (elpaca `(,@elpaca-order)) + ;; ,WARN: the above expands to the below. The two should be interchangable, but _seem_ not to be ... ? + (elpaca '(elpaca :repo "https://github.com/progfolio/elpaca.git" :ref nil :files (:defaults "elpaca-test.el" (:exclude "extensions")) :build (:not elpaca--activate-package))) + (elpaca-wait) + ;; + (progn)) +#+end_src + +**** setup =elpaca= as the default package-fulfillment system for =use-package= +:PROPERTIES: +:ID: 352F2259-6C79-4244-82AF-651800B64A14 +:END: + #+begin_src emacs-lisp +;; for systems which cannot create symlinks: +(when (member system-type '(cygwin haiku ms-dos windows-nt)) + (with-eval-after-load 'elpaca + (elpaca-no-symlink-mode))) + +;; +;; +;; use 'elpaca to install and pre-reqs of 'use-package +(elpaca bind-key) +(elpaca-wait) +;; Install 'use-package using 'elpaca +(elpaca use-package + (progn + ;; https://gitlab.com/rapport1/emacsdotd/-/issues/167 + ;; 20200121_NGa eval "always-defer" for faster and more incremental start-up + (setq use-package-always-defer t) + ;; ,ref: https://github.com/progfolio/elpaca/issues/255#issuecomment-1939076449 + (setq use-package-always-ensure t) + ;; enable use-package-statistics + (setq use-package-compute-statistics t))) +(elpaca-wait) +;; Enable elpaca via the ':ensure use-package keyword. +(elpaca elpaca-use-package + (progn + (elpaca-use-package-mode) + ;; Assume 'elpaca package fulfillment unless otherwise specified. + (setq elpaca-use-package-by-default t))) +;; sync-action before proceeding +(elpaca-wait) +;; +;; + + +;; +(add-hook + ;; NB: When using Elpaca, add configuration which rely on + ;; after-init-hook, emacs-startup-hook, etc to + ;; 'elpaca-after-init-hook so it runs after Elpaca has + ;; activated all queued packages. + (if (featurep 'elpaca) 'elpaca-after-init-hook 'after-init-hook) + (lambda nil (rapport-fn-featureset-load-presets 'afterinit))) + +;; prevents `elpaca-after-init-hook` from running more than once. +;; ,ref: https://github.com/progfolio/elpaca/wiki/after-init-hook%3F-emacs-startup-hook%3F +(add-hook 'after-init-hook + (lambda () + (setq elpaca-after-init-time (or elpaca-after-init-time (current-time))) + (elpaca-wait))) + + #+end_src + +*** COMMENT Package Management w/ =straight.el= :risk@abandoned_feature:ARCHIVE: +:PROPERTIES: +:ID: 61EEC764-7659-460E-84CC-6F83FFBD0785 +:END: +Setup =straight.el= for use =use-package= +- We use https://github.com/raxod502/straight.el as Emacs Package Manager +- This feature includes support for installing and using use-package via straight.el + +#+begin_src emacs-lisp + (when (equal (car rapport-emacs-opt-pkgs-mgmt) 'straight) + ;; + ;; designate a custom straight path + + ;; (setq straight-base-dir rapport-uri-vault-var-emacs) + ;; (setq straight-build-dir + ;; (string-replace "/" "+" (format "build_v%s-%s-%s" emacs-version (car (split-string system-configuration "-")) system-type))) + + ;; speed-up straight bootstrap, https://github.com/raxod502/straight.el/issues/726 + (with-eval-after-load 'exec-path-from-shell + (setq straight-check-for-modifications '(watchexec))) + (setq straight-check-for-modifications 'nil) + + ;; bootstrap + (defvar bootstrap-version) + (let ((bootstrap-file + ;; ,NB: modified to enable detecting an elpaca installed straight too + (if (file-exists-p (expand-file-name "straight/repos/straight/bootstrap.el" straight-base-dir)) + (expand-file-name "straight/repos/straight/bootstrap.el" straight-base-dir) + (expand-file-name "straight/repos/straight.el/bootstrap.el" straight-base-dir))) + (bootstrap-version 5)) + (unless (file-exists-p bootstrap-file) + (with-current-buffer + (url-retrieve-synchronously + "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" + 'silent 'inhibit-cookies) + (goto-char (point-max)) + (eval-print-last-sexp))) + (load bootstrap-file nil 'nomessage)) + ;; + (progn)) +#+end_src +**** install =elpaca= using =straight.el= + #+begin_src emacs-lisp + (when (and (equal (car rapport-emacs-opt-pkgs-mgmt) 'straight) + (member 'elpaca (cdr rapport-emacs-opt-pkgs-mgmt))) + (straight-use-package 'elpaca) + (progn)) + #+end_src +*** extend =use-package= with Configs and Add-Ons +:PROPERTIES: +:ID: 74E1517A-4846-45A9-AE69-F962C2908EA1 +:END: +**** COMMENT mollify undefined =use-package= package managed keywords :risk@deprecated_by_upstream:ARCHIVE: +#+begin_src emacs-lisp + ;; ,HINT: neuter any unused use-package keywords or function definitions + ;; - Prevents errors when definining multiple co-existing pkg-mgr configs w/i use-package + ;; - eg. creating empty functions to prevent "function definition is void" errors + (unless (and (bound-and-true-p use-package-keywords) + (listp use-package-keywords)) + (defvar use-package-keywords nil)) + (unless (member 'straight features) + (add-to-list 'use-package-keywords :straight t) ;; appended to the end of the list for lower processing precedence + (defun use-package-handler/:straight (NAME KEYWORD ARGS REST STATE))) + (unless (member 'elpaca features) + (add-to-list 'use-package-keywords :elpaca t) ;; appended to the end of the list for lower processing precedence + (defun use-package-handler/:elpaca (NAME KEYWORD ARGS REST STATE)) + (defun elpaca-wait nil)) +#+end_src +**** supplemental integration configs for Rapport package management, using =use-package= +:PROPERTIES: +:ID: 5FC95612-3932-4683-B905-6B013C1A81F1 +:END: + #+begin_src emacs-lisp +;; use the :ensure-system-package keyword w/i use-package +(use-package use-package-ensure-system-package :after (:all elpaca) :hook elpaca) +;; use the :delight keyword to manage mode-line +(use-package delight :after (:all elpaca) :hook elpaca) + +;; 'hydra is required by 'use-package-hydra and 'major-mode-hydra +(use-package hydra :after (:all elpaca) :hook elpaca) +;; setup the :hydra keyword using the same arguments as defhydra +(use-package use-package-hydra :after (:all elpaca hydra) :hook hydra) +;; add =major-mode-hydra= ,, https://github.com/jerrypnz/major-mode-hydra.el +(use-package major-mode-hydra + :after (:all elpaca hydra use-package-hydra) + :hook (use-package-hydra) + :bind ("C-c M-@" . major-mode-hydra) + :config (progn)) + + +;; Opportunisticly Use Native-Comp (feat: speed-ups) +;; ,ref: https://emacs.stackexchange.com/questions/185/can-i-avoid-outdated-byte-compiled-elisp-files/186 +;; (use-package auto-compile +;; :init +;; (setq load-prefer-newer t) +;; :custom +;; (auto-compile-on-load-mode t) +;; :config +;; (progn)) + +;; sync-action before proceeding +(elpaca-wait) + #+end_src + +**** COMMENT establish Common and Native Libraries via Package Mgmt :cause@stop_obviated_by_improvements:deprecation_candidate:ARCHIVE: +:PROPERTIES: +:ID: B1C67A8F-AC3B-442E-ACD2-A2179D774F86 +:END: + +These package definitions are moved earlier into the initialization to preempt their loading as dependency, from built-in sources, (and outside of the package-managers perview). + +#+begin_src emacs-lisp +;; Packages are mentioned here only to be registered, to ensure that +;; they're available at a controlled definition if called for later by other packages. + +;; They should not be demanded, required, or activated here since +;; they'll be loaded automatically before they're needed. + + +;; basic pre-requisites, ensure these native libraries are loaded via the pkg-manager +(use-package s :after (:all elpaca) :hook elpaca) +(use-package git :after (:all s elpaca) :hook elpaca) +(use-package compat :after (:all elpaca) :hook elpaca) +(use-package xref :after (:all elpaca) :hook elpaca) +(use-package seq :after (:all elpaca) :hook elpaca) ;; https://elpa.gnu.org/packages/seq.html ,, pre-req for transient, which is pre-req for nix-mode +(use-package queue :after (:all elpaca) :hook elpaca) ;; https://elpa.gnu.org/packages/queue.html +(use-package stream :after (:all elpaca) :hook elpaca) ;; https://elpa.gnu.org/packages/stream.html +;; required by Hydra, Git and other packages +(use-package dash :after (:all elpaca) :hook (hydra)) +;; required by Hydra +(use-package ghub :after (:all elpaca) :hook (hydra)) + +#+end_src + +*** creating and Loading Lockfiles +:PROPERTIES: +:ID: B24403A6-6466-403F-B465-65257A06E3BE +:END: + #+begin_src emacs-lisp + ;; + (defun rapport-fn-pkgs-get-mgmt-sys-name () + "" + (car (or (and + (functionp 'use-package-handler/:elpaca) + (member 'elpaca features)) + (and + (functionp 'use-package-handler/:straight) + (member 'straight features))))) + ;; + (defun rapport-fn-pkgs-get-uri-statefile () + "" + (require 'rapport-core-context) + (expand-file-name + (format "_%s.%s.lockfile.eld" + (rapport-fn-pkgs-get-mgmt-sys-name) + (rapport-fn-context-get-label)) + rapport-uri-vault-cfgs-emacs-pkgs)) + ;; + (defun rapport-fn-pkgs-statefile-save (&optional uri-statefile) + "" + (interactive) + (let* + ((uri-statefile (or + (bound-and-true-p uri-statefile) + (rapport-fn-pkgs-get-uri-statefile))) + (pkg-sys (rapport-fn-pkgs-get-mgmt-sys-name))) + ;; + (unless (file-readable-p uri-statefile) + (save-buffer (find-file uri-statefile))) + (cond + ((eq pkg-sys 'elpaca) (elpaca-write-lockfile uri-statefile)) + ;((= pkg-sys 'straight) (straight-freeze-versions) + ;; as fall-through case, do nothing + (t)))) + ;; + (defun rapport-fn-pkgs-statefile-load (&optional uri-statefile) + "" + (interactive) + (let* + ((uri-statefile (or + (bound-and-true-p uri-statefile) + (rapport-fn-pkgs-get-uri-statefile))) + (pkg-sys (rapport-fn-pkgs-get-mgmt-sys-name))) + ;; + (unless (file-readable-p uri-statefile) + (error " ... state file '%s' is not readable." (find-file uri-statefile))) + (cond + ((eq pkg-sys 'elpaca) (elpaca-load-lockfile uri-statefile)) + + ;((= pkg-sys 'straight) (straight-thaw-versions) + + ;; as fall-through case, do nothing + (t)))) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: A1D86586-F461-4972-AB9D-8C76D070441B +:END: +#+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-core-pkgs) + ;;; .rapport.0.pkgs.el ends here +#+end_src +** Core Org-Mode Functionality :provide@core_org#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-org.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** setup Org-Mode +:PROPERTIES: +:ID: BC91CC8F-5CE5-4339-B712-E27725B9141F +:END: + +enable the inimitable [[https://orgmode.org]] + +#+begin_src emacs-lisp + ;; + (use-package org + :demand t + ;:ensure nil + + ;; :init + ;; ;; ,REF: https://github.crookster.org/switching-to-straight.el-from-emacs-26-builtin-package.el/#put-in-place-org-workaround + ;; ;; ,REF: https://github.com/raxod502/radian/blob/afe2882e3eb85c3284d90fd374be4a5ef9c8775a/radian-emacs/radian-org.el#L54-L92 + + ;; ;; There are three things missing from our version of Org: the + ;; ;; functions `org-git-version' and `org-release', and the feature + ;; ;; `org-version'. We provide all three of those ourself, therefore. + + ;; ;; The following functions rely on reading `git tags`, which + ;; ;; may not be included in your checkout. If absent, tags can + ;; ;; be added by running `git fetch --tags`. + + ;; (defun org-git-version (&optional fallback-version) + ;; "The Git version of org-mode. Inserted by installing org-mode or when a release is made." + + ;; (let* ((git-repo (expand-file-name + ;; "straight/repos/org/" rapport-uri-vault-var-emacs)) + ;; (fallback-version (or (bound-and-true-p fallback-version) + ;; "release_9.9.9")) + ;; (version (string-trim (or + ;; (ignore-errors (git-run "describe" + ;; "--tags" ;; .HINT: this shouldnt be needed and may err toward inclusivity + ;; "--match=release_\*" + ;; "--abbrev=6" + ;; "HEAD")) + ;; fallback-version)))) + ;; version)) + + + ;; (defun org-release () + ;; "The release version of org-mode. + ;; Inserted by installing org-mode or when a release is made." + ;; (string-trim + ;; (car + ;; (split-string + ;; (string-remove-prefix + ;; "release_" + ;; (org-git-version)) + ;; "-")))) + + ;; (defalias 'org-version 'org-release "") + ;; ;(provide 'org-version) + + :bind + (("C-c C-x C-j" . org-clock-goto) + ("C-c a" . org-agenda) + :map org-mode-map + ("C-c ~" . nil) ;; ,NB: the keybind for #'org-table-create-with-table.el is inhibited so that it may be used globally as a prefix for flycheck + ;; mode-specific jump keybind + ("C-c j j" . consult-org-heading)) + + :custom + (org-directory rapport-uri-vault-docs) + (org-default-notes-file (expand-file-name + (format "_INBOX._%s.org" (rapport-fn-context-get-label)) + rapport-uri-vault-docs-tasks)) + (org-attach-id-dir (expand-file-name "org_attach" (expand-file-name ".assets" rapport-uri-vault-docs))) + (org-src-preserve-indentation t) ;; https://gitlab.com/rapport1/emacsdotd/issues/130 + ;; omit a link to an HTML validation service when exporting to HTML + (org-html-validation-link "") + :config + (require 'org) + (require 'org-macro) + ;; remove broken legacy capture config, if present + (setq org-structure-template-alist (remove '("n" "#+BEGIN_NOTES\n?\n#+END_NOTES") org-structure-template-alist)) + (require 'subr-x) + (progn)) + + + (use-package org-contrib + :after (:all org) + :demand t + :config + (progn)) +#+end_src + +*** apply Performance Tweaks +:PROPERTIES: +:ID: 362046BB-2521-4002-BCB9-5F115A2DED96 +:END: + +#+begin_src emacs-lisp + ;; http://orgmode.org/worg/agenda-optimization.html + ;; https://punchagan.muse-amuse.in/blog/how-i-learnt-to-use-emacs-profiler/ + (setq org-agenda-inhibit-startup t) ;; ~50x speedup + (setq org-agenda-use-tag-inheritance nil) ;; 3-4x speedup during startup, + (add-hook 'after-init-hook ;; then revert after-init + #'(lambda () (setq org-agenda-show-inherited-tags 'always))) + (setq-default org-agenda-skip-scheduled-if-deadline-is-shown 'not-today) +#+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: CD2422F4-1BBF-4A67-BEB0-660BB5EB3231 +:END: + +#+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-core-org) + ;;; .rapport.0.org.el ends here +#+end_src + +** Introspection and Internals :provide@core_sysint#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-sysint.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** Host-System Intg. +**** enable <<>> package for a tidy =~/.emacs.d= +:PROPERTIES: +:ID: 7E332B71-4344-4E8F-8DBA-2E95BD88599F +:END: +#+begin_src emacs-lisp + (use-package no-littering + :demand t + :init + (setq no-littering-etc-directory rapport-uri-vault-cfgs-emacs-apps) + (setq no-littering-var-directory rapport-uri-vault-var-emacs) + :config + (setq auto-save-file-name-transforms `((".*" ,(no-littering-expand-var-file-name "auto-save/")))) + (setq backup-directory-alist `(("." . ,(no-littering-expand-var-file-name "auto-save/")))) + ;; + (setq url-history-file (expand-file-name "url/history" rapport-uri-vault-var-emacs)) + ;; (opt.) exclude no-littering dirs from recentf lookup dir listing + (eval-after-load 'recentf-mode + (lambda () (progn + (add-to-list 'recentf-exclude no-littering-var-directory) + (add-to-list 'recentf-exclude no-littering-etc-directory)))) + (progn)) +#+end_src + +**** Emacs Subprocess will Inherit their Environment from Emacs +:PROPERTIES: +:ID: 408EED65-C387-422F-9EA5-A7CEFE314563 +:END: + #+begin_src emacs-lisp + (use-package inheritenv + :config + (progn)) + #+end_src +**** update the System PATH environment variable +:PROPERTIES: +:ID: 14979686-04B1-429E-AFEC-BA915C75A44B +:END: + +Set PATH from the Shell when in GUI Mode. This is unnecessary when running within the CLI. + +#+begin_src emacs-lisp +;; Copy Environment PATH from Shell +(use-package exec-path-from-shell + :demand t + :if (memq window-system '(mac nx x)) + :custom + (exec-path-from-shell-arguments '("-l" "-i")) + (exec-path-from-shell-variables '( + "PATH" + "MANPATH" + ;; + "RAPPORT__URI_VAULT" + "RAPPORT__URI_VAULT_APPS" + "RAPPORT__URI_VAULT_CFGS" + "RAPPORT__URI_VAULT_DOCS" + "RAPPORT__URI_VAULT_URIS" + "RAPPORT__URI_VAULT_VAR" + "RAPPORT_EMACS__OPT_THEME" + "RAPPORT_EMACS__OPT_MODELINE" + "RAPPORT_EMACS__OPT_PROFILER" + ;; + "HM_FLAKE_URI" + )) +:config +(exec-path-from-shell-initialize)) +#+end_src + +**** copy clipboard to kill-ring +:PROPERTIES: +:ID: 6C6E40D5-4074-4F47-8380-1BBD5B84C7EA +:END: +#+begin_src emacs-lisp + ;; http://pragmaticemacs.com/emacs/add-the-system-clipboard-to-the-emacs-kill-ring/ + ;; Save whatever’s in the current (system) clipboard before + ;; replacing it with the Emacs’ text. + ;; https://github.com/dakrone/eos/blob/master/eos.org + (setq save-interprogram-paste-before-kill t) +#+end_src + +**** helper for MacOSX +:PROPERTIES: +:ID: 3AC67157-D673-45B6-8A93-FCE2535C865B +:END: +***** setup Flyspell keybind +:PROPERTIES: +:ID: E25C6208-1157-498F-A93F-8E49FEBE4478 +:END: +#+begin_src emacs-lisp +;; If you’re using a Mac, you may need this config to pick up right-clicks +(when (eq system-type 'darwin) + (eval-after-load "flyspell" + '(progn + (define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word) + (define-key flyspell-mouse-map [mouse-3] #'undefined)))) +#+end_src +***** setup ~Command~ key as =Meta= +:PROPERTIES: +:ID: 4C0C0046-AE1D-467C-AF7E-7CB32C165B08 +:END: +#+begin_src emacs-lisp + ;; I prefer cmd key for meta + ;; https://superuser.com/questions/297259/set-emacs-meta-key-to-be-the-mac-key + (when (eq system-type 'darwin) + (setq mac-option-key-is-meta nil + mac-command-key-is-meta t + mac-command-modifier 'meta + mac-option-modifier 'none)) +#+end_src +**** helper for MSWin +:PROPERTIES: +:ID: E9AFF929-1B20-4154-BAE5-271C71ECB7E0 +:END: + +#+begin_src emacs-lisp + ;; mswin tweaks, hoping to take the edge off + (when (eq system-type 'windows-nt) + ;; try to improve slow performance on windows + (message " (rapport) using <%s> system configs" system-type) + (setq w32-get-true-file-attributes nil) + + ;; Recycle Bin + ;; - The following line configures Emacs so that files deleted via + ;; Emacs are moved to the Recycle. + (setq delete-by-moving-to-trash t) + + ;; ref: https://caiorss.github.io/Emacs-Elisp-Programming/Emacs_On_Windows.html + + ;; Use Unix's \n (LF- Line Feed) and utf instead of Windows \r\n + ;; (CRLF - Carriage Return and Line Feed) as end of line + ;; character. It may not be desirable if most files or project + ;; edited are for Windows or building tools that may fail if the + ;; source file doens't CRLF as line ending. + (setq-default buffer-file-coding-system 'utf-8-unix) + ;; Uniformly UTF-8 + (set-terminal-coding-system 'utf-8) + (set-language-environment 'utf-8) + (set-keyboard-coding-system 'utf-8) + (prefer-coding-system 'utf-8) + (setq locale-coding-system 'utf-8) + (set-default-coding-systems 'utf-8) + (set-terminal-coding-system 'utf-8) + + + ;; Enable visual bell, (i.e. dont rely on audio) + (setq-default visible-bell t) + ;; Do not open file or user dialog. + (setq use-file-dialog nil) + (setq use-dialog-box nil) + + + ;; wrap Powershell shell + (defun run-powershell () + "Run powershell" + (interactive) + (async-shell-command (executable-find "powershell") nil nil)) + + ;; wrap CMD.exe shell + (defun run-cmdexe () + (interactive) + (let ((shell-file-name (executable-find "cmd"))) + (shell "*cmd:shell*"))) + + ;; wrap Bash shell + (defun run-bash () + (interactive) + (let ((shell-file-name (executable-find "bash")) + (shell "*bash:shell*")))) + + ;;(when (string-equal (getenv "LANG") "ENU") + ;; (setenv "LANG" "en_US")) + + ;;; https://gist.github.com/michaelmhoffman/285e1024b4195aec7bd34d34bc9accd0 + ;; - Flyspell is hooked to =text-mode-hook= later in the config. + ;; #$> choco install hunspell.portable + + ;; (eval-after-load 'ispell + ;; (lambda () + ;; (progn + ;; (setq-default ispell-program-name (executable-find "hunspell")) + ;; ;; XXX: hunspell doesn't work because Emacs wants to figure out where its + ;; ;; directories are, and for win32 hunspell 1.7.0, `hunspell -D` *never* runs listdicpath() + ;; ;; https://github.com/hunspell/hunspell/issues/669 + + ;; ;; to correct, copied this bit from ispell-find-hunspell-dictionaries and + ;; ;; changed so that it removes a .dic extension from the list of dictionaries + ;; ;; used so can find the appropriate .aff file + + ;; ;; XXX: should be advice instead of running absolutely + ;; (let ((hunspell-found-dicts + ;; (eval-when-compile + ;; (split-string + ;; (with-temp-buffer + ;; (ispell-call-process ispell-program-name + ;; null-device + ;; t + ;; nil + ;; "-D" + ;; "-a" + ;; null-device) + ;; (buffer-string)) + ;; "[\n\r]+" + ;; t)))) + ;; (dolist (dict hunspell-found-dicts) + ;; (let* ((full-name (file-name-nondirectory dict)) + ;; (basename (file-name-sans-extension full-name)) + ;; ;; CHANGED from ispell.el: remove .dic if it's there + ;; (affix-file (concat (file-name-sans-extension dict) ".aff"))) + ;; (if (and (not (assoc basename ispell-hunspell-dict-paths-alist)) + ;; (file-exists-p affix-file)) + ;; ;; Entry has an associated .aff file and no previous value. + ;; (let ((affix-file (expand-file-name affix-file))) + ;; (cl-pushnew (list basename affix-file) + ;; ispell-hunspell-dict-paths-alist :test #'equal))))))))) + + (progn)) +#+end_src + +(ex.) add an Emacs option to Explorer, (Windows File-Browser) + - The following registry script creates an β€œOpen with Emacs” option in the Windows file explorer context menu. + #+begin_example + Windows Registry Editor Version 5.00 + + [HKEY_CLASSES_ROOT\*\Shell\Open In Emacs\Command] + @="\"C:\\bin\\Emacs-23.1\\bin\\emacsclientw.exe\" -a \"C:\\bin\\Emacs-23.1\\bin\\runemacs.exe\" \"%1\"" + + #+end_example +(ex.) set path to iSpell on Windows + +**** helper for Linux +***** setup NixOS integrations +:PROPERTIES: +:ID: 79A58CCC-456B-4A38-82A9-88000D7F7AE2 +:END: + #+begin_src emacs-lisp +;(use-package company-nixos-options :config (progn)) +(use-package nix-buffer :config (progn)) +(use-package nix-env-install :config (progn)) +(use-package nix-haskell-mode :after (:all nix-mode) :config (progn)) +(use-package nix-mode :after (:all transient seq) :config (progn)) +(use-package nix-modeline :config (progn)) +(use-package nix-sandbox :config (progn)) +(use-package nix-update :config (progn)) +(use-package nixos-options :config (progn)) +(use-package nixpkgs-fmt :config (progn)) + #+end_src +**** helper for Mobile Devices +:PROPERTIES: +:ID: 326D8C90-553B-4FD4-ABA7-429190D9B310 +:END: + #+begin_src emacs-lisp + (setq-default battery-load-critical 8 + battery-load-low 20 + battery-mode-line-limit 55) + (setq display-battery-mode t) + #+end_src +**** enable 3rd-Party Application File Handling +:PROPERTIES: +:ID: 7FA2A835-D95F-4BCA-AB71-876E33A62097 +:END: +setup =openwith= + #+begin_src emacs-lisp + ;; + (use-package openwith + :config + (setq openwith-associations + (list + (list (openwith-make-extension-regexp + '("mpg" "mpeg" "mp3" "mp4" + "avi" "wmv" "wav" "mov" "flv" + "ogm" "ogg" "mkv")) + "mpv" + '(file)) + (list (openwith-make-extension-regexp + '("xbm" "pbm" "pgm" "ppm" "pnm" + "png" "gif" "bmp" "tif" "jpeg")) ;; Removed jpg because Telega was + ;; causing feh to be opened... + "feh" + '(file)) + (list (openwith-make-extension-regexp + '("pdf")) + "zathura" + '(file)))) + (openwith-mode 1)) + #+end_src + +*** Emacs Adaptive Tweaks +**** conveniently restart Emacs +:PROPERTIES: +:ID: 0013AC8B-F95A-4527-A767-6EEE30F01183 +:END: + #+begin_src emacs-lisp +(use-package restart-emacs) + #+end_src +**** helpful, for a more Ergonomic Emacs Help system +:PROPERTIES: +:ID: 7DFB43B7-FDDB-4F0A-9F0E-EC6B5C4DBD5B +:END: + + #+begin_src emacs-lisp + ;; https://github.com/Wilfred/helpful + (use-package helpful + ;:demand + ;; :bind ("C-h" . helpful-hydra/body) + ;; :prettyh-ydra + ;; ((:color teal :quit-key "q") + ;; ("Helpful" + ;; (("f" helpful-callable "callable") + ;; ("F" helpful-function "Look up *F*unctions (excludes macros).") + ;; ("v" helpful-variable "variable") + ;; ("k" helpful-key "key") + ;; ("c" helpful-command "command") + ;; ("d" helpful-at-point "Lookup the current symbol at point.")))) + :init + ;; If you want to replace the default Emacs help keybindings, you can do so: + + ;; Note that the built-in `describe-function' includes both functions + ;; and macros. `helpful-function' is functions only, so we provide + ;; `helpful-callable' as a drop-in replacement. + (global-set-key (kbd "C-h f") #'helpful-callable) + + (global-set-key (kbd "C-h v") #'helpful-variable) + (global-set-key (kbd "C-h k") #'helpful-key) + :commands (helpfull-callable helpful-variable helpful-key) + ;; :pretty-hydra + ;; ((:color teal :quit-key "q") + ;; ("Helpful" + ;; (("f" helpful-callable "callable") + ;; ("v" helpful-variable "variable") + ;; ("k" helpful-key "key") + ;; ("c" helpful-command "command") + ;; ("d" helpful-at-point "thing at point")))) + + :config + ;; I also recommend the following keybindings to get the most out of helpful: + + ;; Lookup the current symbol at point. C-c C-d is a common keybinding + ;; for this in lisp modes. + (global-set-key (kbd "C-c C-d") #'helpful-at-point) + + ;; Look up *F*unctions (excludes macros). + ;; + ;; By default, C-h F is bound to `Info-goto-emacs-command-node'. Helpful + ;; already links to the manual, if a function is referenced there. + (global-set-key (kbd "C-h F") #'helpful-function) + + ;; Look up *C*ommands. + ;; + ;; By default, C-h C is bound to describe `describe-coding-system'. I + ;; don't find this very useful, but it's frequently useful to only + ;; look at interactive functions. + (global-set-key (kbd "C-h C") #'helpful-command) + (progn)) + #+end_src +**** enable <<>> for Improved Responsiveness +:PROPERTIES: +:ID: A9E37346-40C7-432A-BEAF-097DECAFB684 +:END: +#+begin_src emacs-lisp +(use-package async + :config + (progn)) +#+end_src + +**** Don't warn for large files (shows up when launching videos) +:PROPERTIES: +:ID: 822E8C78-6CB4-472B-9155-66A6CEC18348 +:END: + +#+begin_src emacs-lisp + (setq large-file-warning-threshold nil) +#+end_src +**** Don't warn for following symlinked files +:PROPERTIES: +:ID: 8CC7E60E-812B-4AA1-B978-8C9D244773E6 +:END: + +#+begin_src emacs-lisp + (setq vc-follow-symlinks t) +#+end_src +**** Don't warn when advice is added for functions +:PROPERTIES: +:ID: D9BA0036-C785-4AA5-B457-C511BB3FD505 +:END: + +#+begin_src emacs-lisp + (setq ad-redefinition-action 'accept) +#+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: 2F67A683-087C-4975-8A24-0F2355626233 +:END: +#+begin_src emacs-lisp +;; sync-action before proceeding +(elpaca-wait) + +(provide 'rapport-core-sysint) +;;; .rapport.0.sysint.el ends here +#+end_src +** Local Customization :provide@core_customize#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-core-customize.el" (org-sbe rapport-sbe--get-libdir)) +:ID: 05B02F3D-A9D1-46B2-A0B6-5671C86B46EA +:END: + +*** import =customize= data +:PROPERTIES: +:ID: 31481F64-64F3-44EE-8BA5-5B16FCBF9333 +:END: + +#+begin_src emacs-lisp + + ;; get Rapport's context to distinguish distinct per-profile-per-host customization files + (require 'rapport-core-context) + + + ;; Set the 'custom-file' using the value of '(rapport-fn-context-get-uri) + (setq-default custom-file (rapport-fn-context-get-uri)) + + + ;; load the custom file, (may sometimes load additional features) + (and + rapport-emacs-opt-load-custom-file + (bound-and-true-p custom-file) + (or (file-readable-p custom-file) + ;; create Rapport's custom file in Vault if it doesn't already exist + (save-buffer (find-file custom-file))) + (or (load-file custom-file) + (message "wrn: unable to load dynamic custom-file." ))) +#+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: 07BC8195-4CD2-48BC-939A-E56A02874692 +:END: + #+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-core-customize) + ;;; .rapport.0.customize.el ends here + #+end_src + +** on Application Entrypoints using Org-Babel :provide@core_entrypoints#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :results value :eval yes :cache yes :noweb yes :comments noweb :exports none +:END: + +These org-babel source block functions are available in a naive and minimalistic tangle context, as encountered during the pre-flight-check activities in the initialization activities in Rapport's =nix shell= =shebang= and start-up configs. In other words they are used only to create the Rapport Emacs config, but are intentionally absent from that config. +*** on Emacs Entrypoint Script +(opt.) launch script + #+begin_src sh :mkdirp yes :tangle (expand-file-name ".artifacts/published_apps/rapport-emacs" (org-sbe rapport-sbe--get-initdir)) :tangle-mode o750 :shebang #!/usr/bin/env bash +#,wip: readonly cfg_LOGLEVEL="" +readonly cfg_OPTSTRING="thgGq" +readonly msg_USAGE<<-EOM + this is a strange and mysterious tool, no? +EOM + +log_ERR(){ "ERR: $*" ; } +log(){ local LEVEL="${1}" ; shift ; log_${LEVEL^^} "${*}" ; } +nope(){ log ERR "$*" ; } + +# +## +### +## +# + +args=$(getopt ${cfg_OPTSTRING} $*) +if [[ $? -ne 0 ]] ; then nope "invalid argument. exiting" ; fi +set -- $args +while :; do + case "$1" in + # ,HINT: single-character args + + -t) + export RAPPORT_EMACS__OPT_GUI=n + shift + ;; + -g) + export RAPPORT_EMACS__OPT_GUI=t + shift + ;; + -G) + export RAPPORT_EMACS__OPT_GUI=t + export RAPPORT_EMACS__OPT_DETACH=t + export RAPPORT_EMACS__OPT_ARGS="${RAPPORT_EMACS__OPT_ARGS} --funcall toggle-frame-fullscreen " + shift + ;; + -h) + echo -e "${msg_USAGE}" + exit + ;; + # ,HINT: compound/keyword args + # ,HINT: structural/special matches + --) + shift + export RAPPORT_EMACS__OPT_ARGS="${RAPPORT_EMACS__OPT_ARGS} ${*}" + break + ;; + ,*) + break + ;; + esac +done + +case ${1} in + show-config) + for i in ${!RAPPORT_EMACS__*} ; do printf "%45s ~> %s\n" "${i}" "${!i# }" | sort ;done + # ,WIP: for i in $(seq ${#RAPPORT_EMACS__URI_LIBDIRS[@]}) ; do echo -e ' (rapport)::Emacs \\t RAPPORT_EMACS__URI_LIBDIRS['$(($i-1))'] \\t == \\t '${RAPPORT_EMACS__URI_LIBDIRS[i]}'' ; done + ;; + ,*) + if [[ "${RAPPORT_EMACS__OPT_DETACH}" =~ ^[yYtT] ]] ; then + exec ${RAPPORT_EMACS__URI_CONTROL:-${HOME}/.uris/emacsdotd/control.org} ${@} & + else + exec ${RAPPORT_EMACS__URI_CONTROL:-${HOME}/.uris/emacsdotd/control.org} ${@} + fi + ;; +esac + + +## EOF + #+end_src + +*** declare feature :noexport: + #+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-core-entrypoints) + ;;; rapport-core-entrypoints.el ends here + #+end_src + +** Instrument, Test, and Validate :provide@core_measurements#rapport: +:PROPERTIES: +:header-args:emacs-lisp+: :tangle (expand-file-name "rapport-core-measurements.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** support testing + +- enable =esup= + #+begin_src emacs-lisp +(use-package esup + :demand + :config + (progn)) + #+end_src + +- support testing an Rapport Emacs config without restarting current Rapport Emacs instance + #+begin_src emacs-lisp + ;;;###autoload +(defun rapport-fn-profile-startup () + "Profile Emacs Rapport's Start-Up using Esup." + (interactive) + (progn + (rapport-fn-tangle-files-maybe) + (require 'esup) + (esup))) + + #+end_src +*** declare feature :noexport: +#+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-core-measurements) + ;;; rapport-core-measurements.el ends here +#+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: c5da0047-9807-4273-9a90-7d0e8bb55d24 +:END: +#+begin_src emacs-lisp + (require 'rapport-core-featureset) + (require 'rapport-core-context) + (require 'rapport-core-tangle) + (require 'rapport-core-functions) + (require 'rapport-core-variables) + (require 'rapport-core-pkgs) + (require 'rapport-core-org) + (require 'rapport-core-sysint) + (require 'rapport-core-customize) + ;; + (elpaca-wait) + (provide 'rapport-core) +#+end_src + +* /Chapter/ *1*, Universal Editor :export:provide@rapport_editors#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +** as OS Navigation and Management Editor :provide@editors_sysnav#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-sysnav.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** enable File Browser and Directory Editor w/ <<>> +:PROPERTIES: +:ID: C08408C3-E905-4BE1-AF1F-58FE4C148AF8 +:END: + + #+begin_src emacs-lisp + ;;; dired + (use-package dired + :ensure nil + :init + (require 'dired) + :no-require t + :after (dired) + :bind + (:map dired-mode-map + ("Y" . dired-do-relsymlink) + ;; 20200811 NOTE: this opens the file at point but also kills the original dired buffer which makes subsequent navigation a bit awkward ;; ("RET" . dired-find-alternate-file) ; was dired-find-file + ("^" . (lambda () (interactive) (find-alternate-file ".."))) ; was dired-up-directory + ("" . dired-find-alternate-file)) ; was dired-find-file + :custom + (dired-auto-revert-buffer t) + (dired-listing-switches "-alH") + ;(setq dired-listing-switches "-alGh1v") + (dired-use-ls-dired 'unspecified) + ;; Change time format + (ls-lisp-format-time-list '("%Y-%m-%d %a %H:%M" "%Y-%m-%d %a %H:%M")) + (ls-lisp-use-localized-time-format t) + :config + (dired-async-mode t) ;; ,HINT: uses rsync in an async subprocess to enable non-blocking file operations in Dired + (progn)) + #+end_src + +**** enable =DirEd-subtree= +:PROPERTIES: +:ID: 4234262E-A1BD-4BFE-96C7-C008A2AAC7C5 +:END: + #+begin_src emacs-lisp +(use-package dired-subtree + :after (:all dired) + :bind + (:map dired-mode-map + ("TAB" . dired-subtree-toggle)) + :config + (advice-add 'dired-subtree-toggle + :after (lambda () (interactive) + (when all-the-icons-dired-mode + (revert-buffer))))) + #+end_src +**** enable Re-Using DirEd Buffer +:PROPERTIES: +:ID: 24085EC6-A228-41E5-86A2-77D738F2821B +:END: +setup =dired-single= + #+begin_src emacs-lisp + (use-package dired-single) + #+end_src +**** COMMENT display Unique Paths more Compactly in DirEd :risk@faulty_pkg_elpaca: +:PROPERTIES: +:ID: 5F68C69F-AA21-4FD8-89C7-EB5C2326DF92 +:END: +setup =dired-collapse= + #+begin_src emacs-lisp + (use-package dired-collapse :after (:all dired)) + #+end_src +**** enable Mouse click-to-open within DirEd +:PROPERTIES: +:ID: 133ED7D7-50BD-4918-8BDB-9456CAB86B7E +:END: + #+begin_src emacs-lisp +(put 'dired-find-alternate-file 'disabled nil) + #+end_src +*** enable Transparent Remote Access using <<>> +:PROPERTIES: +:ID: A00F67A0-E016-4AD5-97B2-0EC10136A4E8 +:END: +**** COMMENT load upstream Tramp, add support for GVFS Methods + #+begin_src emacs-lisp + (use-package tramp + :demand t + :custom + ;;(tramp-default-method "ssh") ;; 20200309_nga: this value is auto-set by platform in a pretty sensible way already, (ex.) it's pscp on Windows + (tramp-archive-file-name-regexp "\\`\\(.+\\.\\(?:7z\\|CAB\\|LZH\\|MSU\\|ZIP\\|a\\(?:pk\\|r\\)\\|c\\(?:ab\\|pio\\)\\|de\\(?:b\\|pot\\)\\|exe\\|iso\\|jar\\|lzh\\|m\\(?:su\\|tree\\)\\|od[bfgpst]\\|pax\\|r\\(?:ar\\|pm\\)\\|shar\\|t\\(?:ar\\|bz\\|gz\\|lz\\|xz\\|zst\\)\\|warc\\|x\\(?:ar\\|p[is]\\)\\|zip\\)\\(?:\\.\\(?:Z\\|bz2\\|gz\\|l\\(?:rz\\|z\\(?:ma\\|[4o]\\)?\\)\\|uu\\|xz\\|zst\\)\\)*\\)\\(/.*\\)\\'") ;; 20191231nga workaround for EM: "Debugger entered--Lisp error: (void-variable tramp-archive-file-name-regexp) // tramp-register-file-name-handlers()" + ;; "The well known name of the GNOME Online Accounts service." Enable TRAMP access to Google Drive via a locally configured GVFS Google account. + :config + ;;(setq tramp-verbose 6) ;; https://www.gnu.org/software/emacs/manual/html_node/tramp/Traces-and-Profiles.html + + ;; provides navigable GDrive via Gnome VFS and Online Services, if available + (when (and (getenv "XDG_CURRENT_DESKTOP") + (string-match "gnome" (getenv "XDG_CURRENT_DESKTOP"))) + (require 'tramp-gvfs) + (tramp-goa-service "org.gnome.OnlineAccounts")) ;; 20200109nga Should be sourced from tramp-gvfs.el but seems some tramp autoloads aren't working. Added here to cover the gap. + + ;; The debug buffer is in Outline Mode. In this buffer, messages can be filtered by their level. To see messages up to verbosity level 5, enter C-u 6 C-c C-q. + ;; Tramp handles errors internally. But to get a Lisp backtrace, both the error and the signal have to be set as follows: + ;; (setq debug-on-error t + ;; debug-on-signal t) + ;; ;; If tramp-verbose is greater than or equal to 10, Lisp backtraces are also added to the Tramp debug buffer in case of errors. + ;; ;; To enable stepping through Tramp function call traces, they have to be specifically enabled as shown in this code: + ;; (require 'trace) + ;; (dolist (elt (all-completions "tramp-" obarray 'functionp)) + ;; (trace-function-background (intern elt))) + ;; (untrace-function 'tramp-read-passwd) + (progn)) + #+end_src + +**** enable Tramp's support for Vagrant +:PROPERTIES: +:ID: 02F94C81-673C-4E50-9A0D-ABC0CFA5E0A0 +:END: +setup =vagrant-tramp= + #+begin_src emacs-lisp +(use-package vagrant-tramp + :if (and + (executable-find "vagrant") + (not (eq system-type 'windows-nt))) ;; 20200528_NGa disabled on windows to quell EM + :after (:all vagrant tramp)) + #+end_src +**** enable Fast, Capable terminal w/ <<>> +:PROPERTIES: +:ID: 5827E827-B8BE-4836-8210-72919785650A +:END: + #+begin_src emacs-lisp +(use-package vterm + ;; ,TODO: enable fixed-pitch font for vterm + :init + (setq vterm-always-compile-module t) + :if (executable-find "cmake") + :custom + (vterm-max-scrollback 10000) + :bind ( + :map project-prefix-map + ("\'" . vterm-toggle) + :map vterm-mode-map + ("C-g" . vterm-send-C-g) + ("ESC" . vterm-send-escape) ;; ,hint: pass "ctrl-g" keychord through to the Terminal. Setup to aid my use of 'navi'. + ("C-c C-j" . vterm-copy-mode) ;; toggle-on copy mode + ("C-:" . execute-extended-command) ;; ,hint: use 'Ctrl-:' as a stand-in for "M-x" while using Vterm. + :map vterm-copy-mode-map + ("C-c C-j" . vterm-copy-mode) ;; toggle-off copy mode + ("C-c C-k" . vterm-copy-mode-done)) ;; copies any selected text to kill-ring then exists 'copy-mode + ;; + ;:init + ;(defun rapport/vterm/disable-buffer-face-mode () (buffer-face-mode -1)) + ;:hook ( rapport/vterm/disable-buffer-face-mode ) + :ensure (vterm :post-build (progn + (setq vterm-always-compile-module t) + (require 'vterm) + ;;print compilation info for elpaca + (with-current-buffer (get-buffer-create vterm-install-buffer-name) + (goto-char (point-min)) + (while (not (eobp)) + (message "%S" + (buffer-substring (line-beginning-position) + (line-end-position))) + (forward-line))) + (when-let ((so (expand-file-name "./vterm-module.so")) + ((file-exists-p so))) + (make-symbolic-link + so (expand-file-name (file-name-nondirectory so) + "../../builds/vterm") + 'ok-if-already-exists)))) + ;; :custom-face + ;; (eruby-standard-face ((t (:slant italic))))) + ;; :custom-face + ;; (example-1-face ((t (:foreground "LightPink")))) + ;; (example-2-face ((t (:foreground "LightGreen"))) face-defspec-spec)) + ;; :custom-face + ;; (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan))))) + ;; + + :config + (progn)) + #+end_src + +- procedure :: howto, compile vterm using Nix + - nb, http://weblog.zamazal.org/sw-problem-nixos-emacs-vterm/ + - to compile the module, run the below in a shell with access to your Emacs. The =(use-package vterm)= may be omitted if it's already included in your Emacs config. + : nix-shell -p gcc gnumake cmake libvterm-neovim --command 'emacs -nw -e "(use-package vterm)" -f vterm-compile-module' + - once the bindings are compiled, add the =libvterm-neovim= package to the environment you run Emacs from to ensure the underlying shared library is available to Emacs. +**** enable project-dedicated pop-up terminal using Vterm-Toggle +:PROPERTIES: +:ID: 8997CD01-85AA-416C-93DA-0304121917B5 +:END: + #+begin_src emacs-lisp +(use-package vterm-toggle + :init + (setq-default vterm-toggle-scope 'project) + :bind + ("C-x p '" . vterm-toggle) + :config + (progn)) + #+end_src +*** enable async Process Mgmt using <<>> :feature_preview: +:PROPERTIES: +:ID: 8C7DC63E-AC08-4F07-BE66-6690401FC33F +:END: + - from [[https://sr.ht/~niklaseklund/detached.el/][project page (sr.ht)]], (ref: [[https://melpa.org/#/detached][Melpa]], [[https://emacsconf.org/2022/talks/detached/][talk: EmacsConf'22]]) + #+begin_src emacs-lisp +(use-package detached + :if (executable-find "dtach") + :bind + (;; Replace `async-shell-command' with `detached-shell-command' + ([remap async-shell-command] . detached-shell-command) + ;; Replace `compile' with `detached-compile' + ([remap compile] . detached-compile) + ([remap recompile] . detached-compile-recompile) + ;; Replace built in completion of sessions with `consult' + ([remap detached-open-session] . detached-consult-session)) + :custom + (detached-show-output-on-attach t) + (detached-terminal-data-command system-type) + :config + (detached-init) + (unless (and + (file-directory-p detached-db-directory) + (file-exists-p detached-db-directory)) + (make-directory detached-db-directory t)) + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 97660FC8-782A-4490-B8DD-BCCE3F87F554 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-sysnav) +#+end_src +** as Command Interaction (UX) Switchboard :provide@editors_switchboard#rapport: +:PROPERTIES: +:ID: B2B94A5D-816A-4E40-AC98-984EAC6A5488 +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-switchboard.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** Commanding Selection +:PROPERTIES: +:ID: 623638BF-8E6D-4CA1-8ECA-C7A73F7DE1CF +:END: +- context :: + - info/notes + - on Initial Understanding a/o Discovery + - to ignore candidates and immediately use the search text, type =C-u C-j= +**** enhanced Candidate Selection w/ <<>> +:PROPERTIES: +:ID: CD1E75DF-2657-49FE-ADB8-F0D761970A79 +:END: + +#+begin_src emacs-lisp +;; https://github.com/minad/vertico +(use-package vertico + ;; :init + ;; (vertico-mode) + :demand + ;:bind + ;(:map vertico-map + ;("C-j" . vertico-next) + ;("C-k" . vertico-previous) + ;("" . minibuffer-keyboard-quit) ; Close minibuffer + :hook + ((rfn-eshadow-update-overlay . vertico-directory-tidy)) ; Clean up file path when typing + :custom + (enable-recursive-minibuffers t) + + ;; Different scroll margin + ;; (setq vertico-scroll-margin 0) + + ;; Show more candidates + ;; (setq vertico-count 20) + + ;; Grow and shrink the Vertico minibuffer + ;; (setq vertico-resize t) + + :config + (eval-after-load 'vertico-save (add-hook 'minibuffer-setup-hook 'vertico-repeat-save)) ;; Make sure vertico state is saved for `vertico-repeat' + ;; enable wrap-around navigation for `vertico-next' and `vertico-previous'. + (setq vertico-cycle t) + ;; enable vertico-mode + (vertico-mode 1) + ;; for best results, Vertico recommends using the savehist package to save history over Emacs restarts. Vertico sorts by history position. + (progn)) + +#+end_src + +***** COMMENT using <<>> :feature_preview: +For best results, Vertico recommends using the 'savehist' package to save history over Emacs restarts. Vertico sorts by history position. +#+begin_src emacs-lisp + ;; https://github.com/minad/vertico + (use-package vertico-extensions + :after (:all vertico) + :ensure (vertico-extensions :type git :host github :repo "minad/vertico" + :files (:defaults "extensions/*") :local-repo "vertico-extensions" + :includes ( + vertico-buffer + vertico-flat + vertico-grid + vertico-mouse + vertico-multiform + vertico-repeat + vertico-reverse + vertico-unobtrusive + vertico-indexed + )) + :hook (rfn-eshadow-update-overlay . vertico-directory-tidy) ;; Tidy shadowed file names + :bind + (:map vertico-map + ("M-B" . vertico-buffer-mode) + + ("M-F" . vertico-flat-mode) ;; Enable a flat, horizontal display using [[https://github.com/minad/vertico/blob/main/extensions/vertico-flat][Vertico-Flat]] + ("M-G" . vertico-grid-mode) ;; Enable a grid display using [[https://github.com/minad/vertico/blob/main/extensions/vertico-flatvertico-grid][Vertico-Grid]] + ("M-I" . vertico-indexed-mode) ;; Select indexed candidates with prefix arguments using [[https://github.com/minad/vertico/blob/main/extensions/vertico-indexed][Vertico-Indexed]] + ) + :config + ;; Display Vertico in a separate buffer using [[https://github.com/minad/vertico/blob/main/extensions/vertico-buffer.el][Vertico-Buffer]] + (require 'vertico-buffer) + ;; ,NB: I think is now unnecessary because it's alternatively activated ;; (vertico-mouse-mode t) + (progn)) +#+end_src + +****** Commands for Ido-like directory navigation using [[https://github.com/minad/vertico/blob/main/extensions/vertico-directory.el][Vertico-Directory]] + #+begin_src emacs-lisp +(use-package vertico-directory + :bind (:map vertico-map + ("RET" . vertico-directory-enter) + ("DEL" . vertico-directory-delete-char) + ("M-DEL" . vertico-directory-delete-word)) + :ensure (vertico-quick :type git :host github :repo "minad/vertico" :main "extensions/vertico-directory.el") + :hook (rfn-eshadow-update-overlay . vertico-directory-tidy) ;; Tidy shadowed file names + :config + (progn)) + #+end_src +****** COMMENT Enable a flat, horizontal display using [[https://github.com/minad/vertico/blob/main/extensions/vertico-flat][Vertico-Flat]] + #+begin_src emacs-lisp +(use-package vertico-flat + :after (:all vertico) + :ensure (vertico-flat :type git :host github :repo "minad/vertico" :main "extensions/vertico-flat.el") + :bind + (:map vertico-map + ("M-F" . vertico-flat-mode)) + :config + (progn)) + #+end_src +****** COMMENT Enable a grid display using [[https://github.com/minad/vertico/blob/main/extensions/vertico-flatvertico-grid][Vertico-Grid]] + #+begin_src emacs-lisp +(use-package vertico-grid + :after (:all vertico) + :bind + (:map vertico-map + ("M-G" . vertico-grid-mode)) + :config + (progn)) + #+end_src +****** COMMENT Select indexed candidates with prefix arguments using [[https://github.com/minad/vertico/blob/main/extensions/vertico-indexed][Vertico-Indexed]] + #+begin_src emacs-lisp +(use-package vertico-indexed + :after (:all vertico) + :bind + (:map vertico-map + ("M-I" . vertico-indexed-mode)) + :config + (progn)) + #+end_src +****** COMMENT Support for scrolling and candidate selection using [[https://github.com/minad/vertico/blob/main/extensions/vertico-mouse][Vertico-Mouse]] + #+begin_src emacs-lisp +(use-package vertico-mouse + :demand + :after (:all vertico) + :ensure (vertico-mouse :type git :host github :repo "minad/vertico" :main "extensions/vertico-mouse.el") + :config + (vertico-mouse-mode t) + (progn)) + #+end_src +****** COMMENT Configure Vertico modes per command or completion category using [[https://github.com/minad/vertico/blob/main/extensions/vertico-multiform][Vertico-Multiform]] + #+begin_src emacs-lisp +(use-package vertico-multiform + :after (:all vertico) + :config + (vertico-multiform-mode t) + (progn)) + #+end_src +****** COMMENT Commands to select using Avy-style quick keys using [[https://github.com/minad/vertico/blob/main/extensions/vertico-quick][Vertico-Quick]] + #+begin_src emacs-lisp +(use-package vertico-quick + :after (:all vertico) + :bind + (:map vertico-map + ("C-c C-SPC" . vertico-quick-jump)) + :config + (vertico-quick-mode t) + (progn)) + #+end_src +****** COMMENT Repeats the last completion session using [[https://github.com/minad/vertico/blob/main/extensions/vertico-repeat][Vertico-Repeat]] + #+begin_src emacs-lisp +(use-package vertico-repeat :after (:all vertico)) + #+end_src +****** COMMENT Reverse the display using [[https://github.com/minad/vertico/blob/main/extensions/vertico-reverse][Vertico-Reverse]] + #+begin_src emacs-lisp +(use-package vertico-reverse + :after (:all vertico) + :bind + (:map vertico-map + ("M-R" . vertico-reverse-mode)) + :hook + (vertico-reverse . (lambda () (setq vertico-resize vertico-reverse-mode))) ;; ,HINT: enable vertico-resize when vertico-reverse-mode is enabled + :config + (progn)) + #+end_src +****** COMMENT Displays only the topmost candidate using [[https://github.com/minad/vertico/blob/main/extensions/vertico-unobtrusive][Vertico-Unobtrusive]] + #+begin_src emacs-lisp +(use-package vertico-unobtrusive + :after (:all vertico) + :bind + (:map vertico-map + ("M-U" . vertico-unobtrusive-mode)) + :config + (progn)) + #+end_src +***** COMMENT Add prompt indicator to =completing-read-multiple= :feature_preview: +#+begin_src emacs-lisp + ;; Add prompt indicator to `completing-read-multiple'. + ;; We display [CRM], e.g., [CRM,] if the separator is a comma. + (defun crm-indicator (args) + (cons (format "[CRM%s] %s" + (replace-regexp-in-string + "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" + crm-separator) + (car args)) + (cdr args))) + (advice-add #'completing-read-multiple :filter-args #'crm-indicator) + + ;; Do not allow the cursor in the minibuffer prompt + (setq minibuffer-prompt-properties + '(read-only t cursor-intangible t face minibuffer-prompt)) + (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) + + ;; Emacs 28: Hide commands in M-x which do not work in the current mode. + ;; Vertico commands are hidden in normal buffers. + ;; (setq read-extended-command-predicate + ;; #'command-completion-default-include-p) +#+end_src + +**** ergonomic Functionality Library <<>> :feature_preview: +:PROPERTIES: +:ID: 498785CE-D564-4758-8B88-7AF37067B906 +:END: + +#+begin_src emacs-lisp +;; Example configuration for Consult +(use-package consult + ;; Replace bindings. Lazily loaded due by `use-package'. + :bind (;; C-c bindings (mode-specific-map) + ("C-c h" . consult-history) + ("C-c m" . consult-mode-command) ;; ,NB: this is AWESOME for discovering functionality w/i modes! + ("C-c k" . consult-kmacro) + ;; global navigation/jump helper commands + ("C-c j g" . consult-ls-git) ;; jump to file from candidates annotated with Git Status info + ("C-c j i" . consult-imenu) ;; jump to location in file based on Imenu structure + ;; Note: several keybinds for mode-specific behavior are defined futher down in this use-package macro + ;; HINT: "C-c j j" should always be defined for major-mode specific navigation + ("C-c J" . consult-org-agenda) ;; the Org-Agenda provides System-wide navigation + ;; Custom M-# bindings for fast register access + ("M-#" . consult-register-load) + ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) + ("C-M-#" . consult-register) + ;; Other custom bindings + ("M-y" . consult-yank-pop) ;; orig. yank-pop + (" a" . consult-apropos) ;; orig. apropos-command + ;; M-g bindings (goto-map) + ("M-g e" . consult-compile-error) + ;("M-g f" . consult-flymake) ;; Alternative: (consult-flycheck) + ("M-g g" . consult-goto-line) ;; orig. goto-line + ("M-g M-g" . consult-goto-line) ;; orig. goto-line + ("M-g o" . consult-outline) ;; Alternative: consult-org-heading + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark) + ("M-g i" . consult-imenu) + ("M-g I" . consult-imenu-multi) + ;; M-s bindings (search-map) + ("M-s d" . consult-find) + ("M-s D" . consult-locate) + ("M-s g" . consult-grep) + ("M-s G" . consult-git-grep) + ("M-s r" . consult-ripgrep) + ("M-s l" . consult-line) + ("M-s L" . consult-line-multi) + ("M-s m" . consult-multi-occur) + ("M-s k" . consult-keep-lines) + ("M-s u" . consult-focus-lines) + ;; Isearch integration + ("M-s e" . consult-isearch-history) + :map ctl-x-map + ;; C-x bindings (ctl-x-map) + ("M-:" . consult-complex-command) ;; orig. repeat-complex-command + ("b" . consult-buffer) ;; orig. switch-to-buffer + ("4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window + ("5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame + ("r b" . consult-bookmark) ;; orig. bookmark-jump + ;wip;("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer + ("C-r" . consult-recent-file) ;; orig. find-file-read-only + :map isearch-mode-map + ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string + ("M-s l" . consult-line) ;; needed by consult-line to detect isearch + ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch + ;; Minibuffer history + :map minibuffer-local-map + ("M-s" . consult-history) ;; orig. next-matching-history-element + ("M-r" . consult-history) ;; orig. previous-matching-history-element + ) + + ;; Enable automatic preview at point in the *Completions* buffer. This is + ;; relevant when you use the default completion UI. + :hook + (completion-list-mode . consult-preview-at-point-mode) + + ;; The :init configuration is always executed (Not lazy) + :init + + ;; Optionally configure the register formatting. This improves the register + ;; preview for `consult-register', `consult-register-load', + ;; `consult-register-store' and the Emacs built-ins. + (setq register-preview-delay 0.5 + register-preview-function #'consult-register-format) + + ;; Optionally tweak the register preview window. + ;; This adds thin lines, sorting and hides the mode line of the window. + (advice-add #'register-preview :override #'consult-register-window) + + ;; Use Consult to select xref locations with preview + (setq xref-show-xrefs-function #'consult-xref + xref-show-definitions-function #'consult-xref) + + ;; Configure other variables and modes in the :config section, + ;; after lazily loading the package. + :config + + (require 'consult-xref) + + ;; Optionally configure preview. The default value + ;; is 'any, such that any key triggers the preview. + ;; (setq consult-preview-key 'any) + ;; (setq consult-preview-key (kbd "M-.")) + ;; (setq consult-preview-key (list (kbd "") (kbd ""))) + ;; For some commands and buffer sources it is useful to configure the + ;; :preview-key on a per-command basis using the `consult-customize' macro. + (consult-customize + consult-theme + :preview-key '(:debounce 0.2 any) + consult-ripgrep consult-git-grep consult-grep + consult-bookmark consult-recent-file consult-xref + consult--source-bookmark consult--source-recent-file + consult--source-project-recent-file + :preview-key "M-.") + + ;; Optionally configure the narrowing key. + ;; Both < and C-+ work reasonably well. + (setq consult-narrow-key "<") ;; (kbd "C-+") + + ;; Optionally make narrowing help available in the minibuffer. + ;; You may want to use `embark-prefix-help-command' or which-key instead. + ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) + + ;; By default `consult-project-function' uses `project-root' from project.el. + + (progn)) +#+end_src + +Additional Packages to Add: + - [ ] consult-ag: Support for the Silver Searcher in the style of consult-grep. + - +[ ] consult-company: Completion at point using the Company backends.+ + - [X] consult-dir: Directory jumper using Consult multi sources. + - [ ] consult-dash: Consult interface to Dash documentation + - [X] consult-eglot: Integration with Eglot (LSP client). + - [X] consult-flycheck: Additional Flycheck integration. + - [X] consult-flyspell: Additional Flyspell integration. + - [X] consult-ls-git: List files from git via Consult. + - [X] consult-lsp: Integration with Lsp-mode (LSP client). + - +[ ] consult-notmuch: Access the Notmuch email system using Consult.+ + - [X] consult-org-roam: Integration with Org-roam. + - [X] consult-project-extra: Additional project.el extras and buffer sources. + - [ ] consult-recoll: Access the Recoll desktop full-text search using Consult. + - [ ] consult-spotify: Access the Spotify API and control your local music player. + - [X] consult-yasnippet: Integration with Yasnippet. + - [X] affe: Asynchronous Fuzzy Finder for Emacs based on Consult. + + +***** Quick Directory Traversal in Consult using <<>> +:PROPERTIES: +:ID: 58267625-B37C-434F-BC6C-87EFF94D9665 +:END: + #+begin_src emacs-lisp +(use-package consult-dir + :after (:all consult) + :hook (consult) + :bind (("C-x C-d" . consult-dir) + :map vertico-map + ("C-x C-d" . consult-dir) + ("C-x C-j" . consult-dir-jump-file)) + :config + (progn)) + #+end_src +***** Consult + LSP-Mode using <<>> +:PROPERTIES: +:ID: 5709248F-243E-4956-908A-E38850460C16 +:END: + #+begin_src emacs-lisp +(use-package consult-lsp + :after (:all consult lsp) + :config + (progn)) + #+end_src +***** Consult + Eglot using <<>> +:PROPERTIES: +:ID: 5C776248-B5A0-487B-A786-0A72670E0C23 +:END: + #+begin_src emacs-lisp +(use-package consult-eglot :after (:all consult eglot)) + #+end_src +***** COMMENT Consult + Eglot + Embark using <<>> +#+begin_src emacs-lisp +(use-package consult-eglot-embark + :after (:all consult eglot embark) + :config + (progn)) +#+end_src +***** Consult + Flycheck using <<>> +:PROPERTIES: +:ID: 25EC0A75-640F-4BFE-835D-812A5EAF7AAF +:END: + #+begin_src emacs-lisp + (use-package consult-flycheck :after (:all consult flycheck)) + #+end_src +***** Consult + Flyspell using <<>> +:PROPERTIES: +:ID: 7FA88357-31AA-4CF4-B740-F5AB3CC53BEC +:END: + #+begin_src emacs-lisp +(use-package consult-flyspell + :after (:all consult flyspell) + :bind + (:map flyspell-mode-map + ("C-c j $" . consult-flyspell)) + :config + (progn)) + #+end_src +***** Consult + Ls Git using <<>> +:PROPERTIES: +:ID: A2D4A712-DED1-4174-888A-7349D1BBC07D +:END: + #+begin_src emacs-lisp +(use-package consult-ls-git) + #+end_src +***** Consult + Org-Roam using <<>> +:PROPERTIES: +:ID: 1698EE3C-7386-4D12-91E9-F2278BDFED1A +:END: + #+begin_src emacs-lisp +(use-package consult-org-roam + :after (:all org-roam consult) + :bind + ;; Define some convenient keybindings as an addition + (("C-c n e" . consult-org-roam-file-find) + ("C-c n b" . consult-org-roam-backlinks) + ("C-c n l" . consult-org-roam-forward-links) + ("C-c n r" . consult-org-roam-search)) + :custom + ;; Use `ripgrep' for searching with `consult-org-roam-search' + (consult-org-roam-grep-func #'consult-ripgrep) + ;; Configure a custom narrow key for `consult-buffer' + (consult-org-roam-buffer-narrow-key ?r) + ;; Display org-roam buffers right after non-org-roam buffers + ;; in consult-buffer (and not down at the bottom) + (consult-org-roam-buffer-after-buffers t) + :config + (require 'consult-org-roam) + (require 'consult-org-roam-buffer) + ;; Activate the minor mode + (consult-org-roam-mode t) + ;; Eventually suppress previewing for certain functions + (consult-customize + consult-org-roam-forward-links + :preview-key "M-.")) + #+end_src +***** Consult + [[id:FD1A3F4D-ACBD-466F-AA5D-E2F4DEF1219F][Project.el]] using <<>> +:PROPERTIES: +:ID: A5DAE0EB-DB88-408B-AF5C-F903D77E27D6 +:END: + #+begin_src emacs-lisp +;; ,ref: https://github.com/Qkessler/consult-project-extra +(use-package consult-project-extra + :bind + (:map project-prefix-map + ("F" . consult-project-extra-find) + ("o" . consult-project-extra-find-other-window))) + #+end_src +***** Consult + Yasnippet using <<>> +:PROPERTIES: +:ID: 87240C01-20B5-4145-AA28-DDE4DD780DD2 +:END: + #+begin_src emacs-lisp +(use-package consult-yasnippet + :after (:all consult yasnippet)) + #+end_src + +***** COMMENT Citation Management w/ <<>> :feature_preview:risk@faulty_pkg_elpaca: +#+begin_src emacs-lisp +;; https://github.com/emacs-citar/citar +(use-package citar + ;; :bind (("C-c b" . citar-insert-citation) + ;; :map minibuffer-local-map + ;; ("M-b" . citar-insert-preset)) + :custom + (citar-bibliography '("~/.vault/docs/bibliography.bib")) + :config + (citar-embark-mode t) + (progn)) +#+end_src + +#+begin_src emacs-lisp +(use-package citar-embark + :after (:all citar embark) + :no-require + :config (citar-embark-mode)) +#+end_src +**** More Predictive Selection Ordering w/ <<>> :feature_preview: +:PROPERTIES: +:ID: 14BD4F18-5FA4-46EE-843C-9138D9DEC149 +:END: +#+begin_src emacs-lisp +;; Optionally use the `orderless' completion style. +(use-package orderless + :custom + ;; _Component matching styles_ + + ;; Each component of a pattern can match in any of several + ;; matching styles. A matching style is simply a function from + ;; strings to strings that maps a component to a regexp to match + ;; against, so it is easy to define new matching styles. The + ;; predefined ones are: + + ;; orderless-regexp + ;; - the component is treated as a regexp that must match somewhere in the candidate. + ;; - If the component is not a valid regexp, it is ignored. + ;; orderless-literal + ;; - the component is treated as a literal string that must occur in the candidate. + ;; - This is just regexp-quote. + ;; orderless-without-literal + ;; - the component is a treated as a literal string that must not occur in the candidate. + ;; - Note that nothing is highlighted for this matching style. You probably don’t want to use this style directly in orderless-matching-styles but with a style dispatcher instead. There is an example in the section on style dispatchers. + ;; orderless-prefixes + ;; - the component is split at word endings and each piece must match at a word boundary in the candidate, occurring in that order. + ;; - This is similar to the built-in partial-completion completion-style. For example, re-re matches query-replace-regexp, recode-region and magit-remote-list-refs; f-d.t matches final-draft.txt. + ;; orderless-initialism + ;; - each character of the component should appear as the beginning of a word in the candidate, in order. + ;; - This maps abc to \>> :feature_preview: +:PROPERTIES: +:ID: B782B168-5331-4D5A-B66C-B7186B35E960 +:END: +#+begin_src emacs-lisp +;; Enable richer annotations using the Marginalia package +(use-package marginalia + :after (:all vertico) + ;; Either bind `marginalia-cycle` globally or only in the minibuffer + :bind (("M-A" . marginalia-cycle) + :map minibuffer-local-map + ("M-A" . marginalia-cycle)) + :init + ;; Must be in the :init section of use-package such that the mode gets + ;; enabled right away. Note that this forces loading the package. + (marginalia-mode) + :custom + (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil)) + :config + (add-to-list 'marginalia-command-categories '(project-find-file . file))) +#+end_src +**** COMMENT In-Situ Mini-Buffer Supplimental Selection Behaviors w/ <<>> :feature_preview: +#+begin_src emacs-lisp +;; https://github.com/oantolin/embark +(use-package embark + :init + ;; Optionally replace the key help with a completing-read interface + (setq prefix-help-command #'embark-prefix-help-command) + :bind + (("C-." . embark-act) ;; pick some comfortable binding + ("C-;" . embark-dwim) ;; good alternative: M-. + ("C-h B" . embark-bindings)) ;; alternative for `describe-bindings' + :config + ;; Hide the mode line of the Embark live/completions buffers + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" + nil + (window-parameters (mode-line-format . none)))) + ;;;; from ahmed-shariff + (add-to-list 'display-buffer-alist + '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" nil + (window-parameters + (mode-line-format . none)))) + (define-key embark-file-map "o" nil) + (define-key embark-file-map "ocn" #'copy-buffer-file-name) + (define-key embark-file-map "ocf" #'copy-file-full-path) + (defun embark-which-key-indicator nil "An embark indicator that displays keymaps using which-key.\nThe which-key help message will show the type and value of the\ncurrent target followed by an ellipsis if there are further\ntargets." + (lambda + (&optional keymap targets prefix) + (if + (null keymap) + (which-key--hide-popup-ignore-command) + (which-key--show-keymap + (if + (eq + (plist-get + (car targets) + :type) + 'embark-become) + "Become" + (format "Act on %s '%s'%s" + (plist-get + (car targets) + :type) + (embark--truncate-target + (plist-get + (car targets) + :target)) + (if + (cdr targets) + "…" ""))) + (if prefix + (pcase + (lookup-key keymap prefix 'accept-default) + ((and + (pred keymapp) + km) + km) + (_ + (key-binding prefix 'accept-default))) + keymap) + nil nil t + (lambda + (binding) + (not + (string-suffix-p "-argument" + (cdr binding)))))))) + (setq embark-indicators + '(embark-which-key-indicator embark-highlight-indicator embark-isearch-highlight-indicator)) + (defun embark-hide-which-key-indicator + (fn &rest args) + "Hide the which-key indicator immediately when using the completing-read prompter." + (which-key--hide-popup-ignore-command) + (let + ((embark-indicators + (remq #'embark-which-key-indicator embark-indicators))) + (apply fn args))) + (advice-add #'embark-completing-read-prompter :around #'embark-hide-which-key-indicator) + (progn)) +#+end_src +***** extend Embark with Consult integration :feature_preview: +#+begin_src emacs-lisp +;; Consult users will also want the embark-consult package. +(use-package embark-consult + :after (:all consult embark) + ;:demand t ; only necessary if you have the hook below + ;; if you want to have consult previews as you move around an + ;; auto-updating embark collect buffer + :hook (embark-collect-mode . consult-preview-at-point-mode) + :config + (progn)) +#+end_src + + +***** extend Embark with Org-Roam integration :feature_preview: + +#+begin_src emacs-lisp +(use-package embark-org-roam + :after (org-roam embark) + :ensure (embark-org-roam + :type git + :host github + :repo "bramadams/embark-org-roam") + :config + (progn)) +#+end_src +**** display key-press options in-flight w/ Which Key +:PROPERTIES: +:ID: 058E0946-2E06-4FB0-BF6A-7C667A0E9F71 +:END: +setup =which-key= + - Guide-key a/o emacs-which-key + #+begin_src emacs-lisp + ;; + (use-package which-key + :demand t + :custom + ;; location of which-key window. valid values: top, bottom, left, right, + ;; or a list of any of the two. If it's a list, which-key will always try + ;; the first location first. It will go to the second location if there is + ;; not enough room to display any keys in the first location + (which-key-side-window-location 'bottom) + + ;; max width of which-key window, when displayed at left or right. + ;; valid values: number of columns (integer), or percentage out of current + ;; frame's width (float larger than 0 and smaller than 1) + (which-key-side-window-max-width 0.33) + + ;; max height of which-key window, when displayed at top or bottom. + ;; valid values: number of lines (integer), or percentage out of current + ;; frame's height (float larger than 0 and smaller than 1) + (which-key-side-window-max-height 0.25) + + ;; Set the time delay (in seconds) for the which-key popup to appear. A value of + ;; zero might cause issues so a non-zero value is recommended. + (which-key-idle-delay 22) + + ;; Set the maximum length (in characters) for key descriptions (commands or + ;; prefixes). Descriptions that are longer are truncated and have ".." added. + (which-key-max-description-length 37) + + ;; Use additonal padding between columns of keys. This variable specifies the + ;; number of spaces to add to the left of each column. + (which-key-add-column-padding 0) + + ;; The maximum number of columns to display in the which-key buffer. nil means + ;; don't impose a maximum. + (which-key-max-display-columns nil) + + ;; Set the separator used between keys and descriptions. Change this setting to + ;; an ASCII character if your font does not show the default arrow. The second + ;; setting here allows for extra padding for Unicode characters. which-key uses + ;; characters as a means of width measurement, so wide Unicode characters can + ;; throw off the calculation. + (which-key-separator " β†’ " ) + (which-key-unicode-correction 3) + + ;; Set the prefix string that will be inserted in front of prefix commands + ;; (i.e., commands that represent a sub-map). + (which-key-prefix-prefix "+" ) + + ;; Set the special keys. These are automatically truncated to one character and + ;; have which-key-special-key-face applied. Disabled by default. An example + ;; setting is + ;; (which-key-special-keys '("SPC" "TAB" "RET" "ESC" "DEL")) + (which-key-special-keys nil) + + ;; Show the key prefix on the left, top, or bottom (nil means hide the prefix). + ;; The prefix consists of the keys you have typed so far. which-key also shows + ;; the page information along with the prefix. + (which-key-show-prefix 'left) + + ;; Set to t to show the count of keys shown vs. total keys in the mode line. + (which-key-show-remaining-keys t) + + :config + ;; integration with lsp-mode, when used + (with-eval-after-load 'lsp-mode + (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration)) + + (which-key-mode t) + ;; location of which-key window. valid values: top, bottom, left, right, + ;; or a list of any of the two. If it's a list, which-key will always try + ;; the first location first. It will go to the second location if there is + ;; not enough room to display any keys in the first location + (which-key-setup-side-window-right-bottom) + (progn)) + #+end_src + +**** enable simpler prompts +:PROPERTIES: +:ID: 7680E5DE-696F-4E93-9097-A66F7028CB91 +:END: +setup =y-or-n-p= for simpler prompts + #+begin_src emacs-lisp + ;; http://pragmaticemacs.com/emacs/make-all-prompts-y-or-n/ + ;; change all prompts to y or n + (fset 'yes-or-no-p 'y-or-n-p) + #+end_src + + +**** COMMENT enable a Simple Control Panel for Rapport Emacs :wip:feature_preview: + +setup Rapport menu for straight operations + #+begin_src emacs-lisp + (use-package emacs + :ensure nil + + :no-require t + :after (:all hydra major-mode-hydra) + :mode-hydra + (fundamental-mode + (:title "Package Mgmt Commands") + ("Apply Upgrades" + (("p" straight-pull-all "Upgrade All to Latest") + ("P" straight-pull-package "Upgrade Selected to Latest") + ("m" straight-merge-all) + ("M" straight-merge-package)) + + "Fetch Updates" + (("f" straight-fetch-all) + ("F" straight-fetch-package)) + + "Version Lock" + (("v" straight-freeze-versions) + ("V" straight-thaw-versions)) + + "Rebuild" + (("r" straight-rebuild-all) + ("R" straight-rebuild-package)) + + "Dist-Push" + (("u" straight-push-all) + ("U" straight-push-package) + ("e" straight-prune-build)) + + "Service Mgmt" + (("w" straight-watcher-start) + ("W" straight-watcher-quit)) + + "Misc Mgmt" + (("g" straight-get-recipe) + ("n" straight-normalize-all) + ("N" straight-normalize-package) + ("c" straight-check-all) + ("C" straight-check-package))))) + #+end_src +*** Sessions +**** Auto-Saving Changed Files (Persist Files to Disk, Improved harmony with Ext. File-Sync) +:PROPERTIES: +:ID: 0A659A83-9D2D-4CCD-858F-FBAB3154925C +:END: +setup =setup-save= + #+begin_src emacs-lisp + (use-package super-save + :demand t + :init + (super-save-mode t) + :delight + :custom + (super-save-auto-save-when-idle t) + (super-save-auto-idle-duration 6) + (auto-save-visited-mode t) + :hook + (after-focus-chage-function . super-save-command) + :config + (progn)) + + #+end_src + +**** Enable Auto-Revert Mode Globally, useful when file syncing to disambiguate between files and buffers +:PROPERTIES: +:ID: 633C7577-1FFE-4AB8-B386-2AAA5E8A4944 +:END: +setup =global-auto-revert-mode= + #+begin_src emacs-lisp +;; ref: https://www.gnu.org/software/emacs/manual/html_node/emacs/Reverting.html +(use-package emacs + :ensure nil + + :custom + (global-auto-revert-mode t) + (auto-revert-remote-files t) + + ;; When you edit a file that changes automatically and + ;; frequentlyβ€”for example, a log of output from a process + ;; that continues to runβ€”it may be useful for Emacs to + ;; revert the file without querying you. To request this + ;; behavior, set the variable revert-without-query to a + ;; list of regular expressions. When a file name matches + ;; one of these regular expressions, find-file and + ;; revert-buffer will revert it automatically if it has + ;; changedβ€”provided the buffer itself is not modified. (If + ;; you have edited the text, it would be wrong to discard + ;; your changes.) + (revert-without-query '(".*")) + :delight + :config + (global-auto-revert-mode 't) + (auto-revert-mode 't)) + #+end_src + +**** persist Emacs variables, commands, history using <<>> +:PROPERTIES: +:ID: A6B0CDA5-E017-4C9B-A091-A1B730B8C765 +:END: + + #+begin_src emacs-lisp + ;;; reload + (unless (or + (bound-and-true-p psession-savehist-mode)) + (savehist-mode 1)) + #+end_src +**** restore Cursor to Previous Location when Re-Opening a File +:PROPERTIES: +:ID: 38904B63-94F8-4AC5-BACE-19FD13F8768A +:END: + + #+begin_src emacs-lisp + (use-package save-place + :ensure nil + + :custom + (save-place-file (expand-file-name "places" rapport-uri-vault-var-emacs)) + :config + (require 'saveplace) + (save-place-mode t)) + #+end_src + +**** enable Emacs Session Restore after restart using <<>> +:PROPERTIES: +:ID: E38E2D0C-4C0D-48A6-9575-322BD2920733 +:END: + #+begin_src emacs-lisp +(use-package desktop-save-mode + :ensure nil + + :after (:all no-littering) + :custom + (desktop-restore-eager 0) ; ,HINT: Number of buffers to restore immediately. Remaining buffers are restored lazily (when Emacs is idle). If value is t, all buffers are restored immediately. + (desktop-save 'if-exists) ; ,HINT: save if desktop file exists, otherwise don’t save. + (desktop-lazy-verbose t) + (desktop-auto-save-timeout 55) ; ,HINT: Number of seconds of idle time before auto-saving the desktop. (default: 30) + (desktop-file-name-format 'tilde) ; ,HINT: record file paths relative to '~' (default: abs-paths) + (desktop-lazy-idle-delay 25) ; ,HINT: Idle delay before starting to create buffers. (default: 5) + (desktop-path `( + ,(expand-file-name "desktop" no-littering-var-directory) + ,(expand-file-name "desktop" rapport-uri-vault-cfgs-emacs-apps) + ;; end-of-list + )) + :config + (desktop-save-mode t) + (progn)) + #+end_src +*** Files +**** line and word wrap +:PROPERTIES: +:ID: A93F21D2-B417-4055-AC5C-BEA517992694 +:END: +how to adjust line and work wrap + - example func and variables to tweak + #+begin_src emacs-lisp + ;; (longlines-mode t) + ;; (toggle-longlines-mode) + ;; (toggle-word-wrap) + #+end_src +**** Recently Used Files w/ =recentf= +:PROPERTIES: +:ID: E9687367-687B-4D7E-8834-F0DECFCB3A86 +:END: +setup =recentf= + #+begin_src emacs-lisp + (use-package recentf + :ensure nil + + :commands (recentf recentf-open recentf-open-files) + :custom + (recentf-save-file (expand-file-name "recentf" (expand-file-name "cache" rapport-uri-vault-var-emacs))) + :hook (after-init . (lambda () (unless recentf-enabled-p (recentf-mode)))) + :config + (progn)) + ;; ,TODO: setup after-init and command activation, recentf is not activating on startup except w/ the below + (recentf-mode +1) + #+end_src + +**** Asynchronous Fuzzy Finder for Emacs (/aka/ <<>>) :feature_preview: +:PROPERTIES: +:ID: 04EF1005-03E1-443B-998F-551B6EFA2FAC +:END: +:LOGBOOK: +- Refiled on [2022-08-15 Mon 18:28] +:END: +#+begin_src emacs-lisp +(use-package affe + :bind + ;; ,hint: prefix with =C-u= to set the starting directory prior to search + ("M-s a f" . affe-find) + ("M-s a g" . affe-grep) + :ensure-system-package + (rg fd) + :custom + (affe-find-command "fd --color=never --hidden --follow") ; ,HINT: (default: "rg --color=never --files") + :config + ;; Manual preview key for `affe-grep' + (consult-customize affe-grep :preview-key (kbd "M-.")) + (progn)) +#+end_src +*** Windows and Frames +**** disable Unused GUI Elements for Maximum Screen Space +:PROPERTIES: +:ID: CD557AA9-87E3-4601-B4BE-B934D253B453 +:END: + + #+begin_src emacs-lisp + ;; disable toolbar + (tool-bar-mode -1) + + ;; disable menu bar + (menu-bar-mode -1) + + ;; disable scroll bar + (scroll-bar-mode -1) + #+end_src +**** use a Visual Prompt instead of an Audible Bell +:PROPERTIES: +:ID: 19D88229-E11C-4691-BCA5-FC295855BB73 +:END: + + #+begin_src emacs-lisp + ;; Set up the visible bell + (setq visible-bell t) + #+end_src + +**** Frame Mgmt with Nameframe +:PROPERTIES: +:ID: 4978238B-B56B-4EC2-ACE6-5AF149934E62 +:END: + +nameframe + #+begin_src emacs-lisp +;; https://github.com/john2x/nameframe +(use-package nameframe + ;; If your OS can't switch between applications windows by default *cough* OS X *cough* you can have a shortcut to switch between existing frames by name + :bind (("M-P" . nameframe-switch-frame)) + :config + (progn)) + #+end_src +**** Buffer Listing w/ BS +:PROPERTIES: +:ID: 50317DB3-9444-44C9-85D7-CC02F74154F7 +:END: +setup bs + #+begin_src emacs-lisp + (use-package bs + :ensure nil + + :demand t + :commands (bs-show) + :config + (require 'bs)) + #+end_src + +**** enable Window and Frame Workspace Mgmt +:PROPERTIES: +:ID: DD86B4A1-3399-4C75-A446-B6993A8DF55D +:END: +winner + - winner + #+begin_src emacs-lisp + ;; winner-mode + (use-package winner + :ensure nil + + :init + (winner-mode 1)) + #+end_src + + + +***** windmove and buffer-move +:PROPERTIES: +:ID: A13484F9-4427-4561-A1F7-1F25C901D067 +:END: + #+begin_src emacs-lisp + (use-package windmove :ensure nil) + (use-package buffer-move + :ensure nil + + :after windmove) + #+end_src + +***** COMMENT window mgmt hydras + #+begin_src emacs-lisp + (defhydra sk/hydra-of-windows (:color red + :hint nil) + " + ^Move^ ^Size^ ^Change^ ^Split^ ^Text^ + ^^^^^^^^^^^------------------------------------------------------------------ + ^ ^ _k_ ^ ^ ^ ^ _K_ ^ ^ _u_: winner-undo _o_: rotate _v_: vertical _+_: zoom in + _h_ ^+^ _l_ _H_ ^+^ _L_ _r_: winner-redo _s_: horizontal _-_: zoom out + ^ ^ _j_ ^ ^ ^ ^ _J_ ^ ^ _c_: close _z_: zoom _q_: quit + " + ("h" windmove-left) + ("j" windmove-down) + ("k" windmove-up) + ("l" windmove-right) + ("H" shrink-window-horizontally) + ("K" shrink-window) + ("J" enlarge-window) + ("L" enlarge-window-horizontally) + ("v" sk/split-right-and-move) + ("s" sk/split-below-and-move) + ("c" delete-window) + ("f" sk/toggle-frame-fullscreen-non-native :color blue) + ("o" sk/rotate-windows) + ("z" delete-other-windows) + ("u" (progn + (winner-undo) + (setq this-command 'winner-undo))) + ("r" winner-redo) + ("+" text-scale-increase) + ("-" text-scale-decrease) + ("q" nil :color blue)) + + + + (defhydra hydra-window-size (:color red) + "Windows size" + ("h" shrink-window-horizontally "shrink horizontal") + ("j" shrink-window "shrink vertical") + ("k" enlarge-window "enlarge vertical") + ("l" enlarge-window-horizontally "enlarge horizontal")) + (defhydra hydra-window-frame (:color red) + "Frame" + ("f" make-frame "new frame") + ("x" delete-frame "delete frame")) + (defhydra hydra-window-scroll (:color red) + "Scroll other window" + ("n" joe-scroll-other-window "scroll") + ("p" joe-scroll-other-window-down "scroll down")) + #+end_src + +***** Balanced Window Splits +:PROPERTIES: +:ID: ED6232BB-7DCE-47DC-BD62-CB45F6BA8D1C +:END: +auto-balance windows using Zoom + #+begin_src emacs-lisp +;; https://github.com/cyrus-and/zoom +(use-package zoom + :bind + ("C-x +" . zoom) + :custom + ;; Resize the selected window using the golden ratio + (zoom-size '(0.618 . 0.618)) + ;(zoom-ignored-major-modes '(dired-mode markdown-mode)) + ;(zoom-ignored-buffer-names '("zoom.el" "init.el")) + (zoom-ignored-buffer-name-regexps '("^*calc")) + (zoom-ignore-predicates '((lambda () (> (count-lines (point-min) (point-max)) 20)))) + :config + (progn)) + #+end_src + +***** Window Profiles Mgmt +:PROPERTIES: +:ID: 2A4966E2-BAAB-4283-80F1-CC099A3FE370 +:END: +setup =eyebrowse= + - nb + - http://manuel-uberti.github.io/emacs/2017/08/06/eyebrowse/ + - setup eyebrowse + #+begin_src emacs-lisp + ;; https://github.com/wasamasa/eyebrowse + ;; C-c C-w < Switch to previous window config + ;; C-c C-w > Switch to next window config + ;; C-c C-w ' Switch to last window config + ;; C-c C-w " Close current window config + ;; C-c C-w , Rename current window config + ;; C-c C-w 0 Switch to window config 0 + ;; ... ... + ;; C-c C-w 9 Switch to window config 9 + (use-package eyebrowse + ;; TODO: adjust keybinds to emulate the style used by tmux and perspective + :custom + (eyebrowse-keymap-prefix (kbd "C-c C-] C-w")) ;; slightly psycho but I stand by it :D + (eyebrowse-mode-line-separator ";") + (eyebrowse-new-workspace t) + :config + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 7CEA890B-9FA6-45B6-B25C-7E9853368C58 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-switchboard) +#+end_src +** as General Editing and Authoring Environment :provide@editors_text#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-text.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** enable Contextual Folding w/ Origami.el +:PROPERTIES: +:ID: 5770B1E5-8096-4901-98FE-B883AD0828DF +:END: + - setup https://github.com/gregsexton/origami.el + #+begin_src emacs-lisp +(use-package origami + :bind + (:map org-super-agenda-header-map + ("" . origami-toggle-node)) + :hook + ((org-agenda-mode . origami-mode) + (org-agenda-finalize . rapport/org-super-agenda/origami-fold-default-groups)) + :bind ( + :map org-agenda-mode-map + ("M-s s" . rapport/org-super-agenda/-toggle-and-refresh) + ("M-s M-s" . rapport/org-super-agenda/-toggle-and-refresh) + ("M-s f" . rapport/org-super-agenda/origami-fold-default-groups) + :map org-super-agenda-header-map + ("M-s f" . rapport/org-super-agenda/origami-fold-default-groups) + ) + :config + (defun rapport/org-super-agenda/origami-fold-default-groups () + "Groups will be folded (minimized) on initial display in the Org Super Agenda buffer. This list of groups to fold is read from the variable 'rapport/org-super-agenda/auto-show-groups ." + (interactive) + (when (and + org-super-agenda-mode + (bound-and-true-p rapport/org-super-agenda/auto-show-groups) + (listp rapport/org-super-agenda/auto-show-groups)) + (forward-line 3) + (cl-loop do (origami-forward-toggle-node (current-buffer) (point)) + while (origami-forward-fold-same-level (current-buffer) (point))) + (--each rapport/org-super-agenda/auto-show-groups + (goto-char (point-min)) + (when (re-search-forward (rx-to-string `(seq bol " " ,it)) nil t) + (origami-show-node (current-buffer) (point)))))) + ;; + (progn)) + #+end_src + +*** enable Browseable Kill-Ring +:PROPERTIES: +:ID: 80EF8263-5262-4D32-9CE4-CBD60C5A1622 +:END: + + #+begin_src emacs-lisp + (use-package browse-kill-ring) + #+end_src + +*** undo-fu :feature_preview: +:PROPERTIES: +:ID: EBBB642A-1659-475E-9775-3A8B3738DFA2 +:END: + #+begin_src emacs-lisp +;; ,ref: https://codeberg.org/ideasman42/emacs-undo-fu +(use-package undo-fu + :init + (global-unset-key (kbd "C-z")) + (global-set-key (kbd "C-z") 'undo-fu-only-undo) + (global-set-key (kbd "C-S-z") 'undo-fu-only-redo) + :config + (progn)) + #+end_src +*** undo-fu-session :feature_preview: +:PROPERTIES: +:ID: 7144391B-2902-4D65-838B-FACFC0226E99 +:END: + #+begin_src emacs-lisp +;; ,ref: https://codeberg.org/ideasman42/emacs-undo-fu-session +(use-package undo-fu-session + :after (:all undo-fu) + :hook + (after-init . global-undo-fu-session-mode) + :config + (progn)) + #+end_src +*** vundo :feature_preview: +:PROPERTIES: +:ID: DDA86F09-3B8E-4769-9D96-F4E9B544F146 +:END: + #+begin_src emacs-lisp +;; ,ref: https://github.com/casouri/vundo +(use-package vundo) + #+end_src +*** undo-tree :pending_review:compare_with_vundo: +:PROPERTIES: +:ID: B43331DB-01C7-49CB-97D9-F86AB4555565 +:END: + + #+begin_src emacs-lisp +(use-package undo-tree + ;; undo-tree-mode is an interactive Lisp closure in `undo-tree.el'. + ;; (undo-tree-mode &optional ARG) + ;; Toggle undo-tree mode. + ;; With no argument, this command toggles the mode. + ;; A positive prefix argument turns the mode on. + ;; A negative prefix argument turns it off. + ;; Undo-tree-mode replaces Emacs' standard undo feature with a more + ;; powerful yet easier to use version, that treats the undo history + ;; as what it is: a tree. + ;; The following keys are available in `undo-tree-mode': + ;; key binding + ;; --- ------- + ;; C-_ undo-tree-undo + ;; C-/ undo-tree-undo + ;; C-? undo-tree-redo + ;; M-_ undo-tree-redo + ;; C-x u undo-tree-visualize + ;; Within the undo-tree visualizer, the following keys are available: + ;; , undo-tree-visualizer-scroll-left + ;; . undo-tree-visualizer-scroll-right + ;; < undo-tree-visualizer-scroll-left + ;; > undo-tree-visualizer-scroll-right + ;; b undo-tree-visualize-switch-branch-left + ;; d undo-tree-visualizer-toggle-diff + ;; f undo-tree-visualize-switch-branch-right + ;; n undo-tree-visualize-redo + ;; p undo-tree-visualize-undo + ;; q undo-tree-visualizer-quit + ;; s undo-tree-visualizer-selection-mode + ;; t undo-tree-visualizer-toggle-timestamps + :delight + :bind + ("C-x u" . undo-tree-visualize) + :custom + (undo-tree-history-directory-alist `((".*" . ,(expand-file-name "undo-tree" rapport-uri-vault-var-emacs)))) ;; move undo-tree records out of tree to var dir + (undo-tree-visualizer-timestamps t) + ;(undo-tree-visualizer-diff t) + :config + (global-undo-tree-mode)) + + #+end_src +*** enable visual Version Control Change Hints using <<>> +:PROPERTIES: +:ID: AAE44F66-0A7E-4B40-B572-01DC4A6D6D7F +:END: + #+begin_src emacs-lisp +(use-package diff-hl + :config + (global-diff-hl-mode) + (progn)) + #+end_src +*** whitespace indentation highlight using <<>> +:PROPERTIES: +:ID: 8B019F41-B056-464A-95C4-54F1DAC4224C +:END: + + #+begin_src emacs-lisp +;; ,ref: https://github.com/DarthFennec/highlight-indent-guides +(use-package highlight-indent-guides + ;:hook (prog-mode) + :custom + (highlight-indent-guides-method 'character) ;; ,opt: 'column, 'bitmap, 'character + (highlight-indent-guides-character ?β€–) + (highlight-indent-guides-responsive 'top) + ;; (highlight-indent-guides-responsive 'stack) + ;; (highlight-indent-guides-auto-enabled nil) + ;; (set-face-background 'highlight-indent-guides-odd-face "darkgray") + ;; (set-face-background 'highlight-indent-guides-even-face "dimgray") + ;; (set-face-foreground 'highlight-indent-guides-character-face "dimgray") + (highlight-indent-guides-auto-set-faces t) + :config + (progn)) + #+end_src +*** Inhibit Electric Indent for more Predictable Paste-In of Text +:PROPERTIES: +:ID: C3090E19-6D9D-421A-B9F8-02BEB870C923 +:END: + +disable =electric-indent-mode=, which is an Emacs native package and enabled by default + #+begin_src emacs-lisp +(electric-indent-mode nil) + #+end_src +*** enable Jump Navigation +:PROPERTIES: +:ID: 1BDE8E3C-4988-4806-ACAC-EBC42232452A +:END: +**** enable Jump to Visible Word using <<>> :risk@unmaintained_upsteam: +:PROPERTIES: +:ID: 958B5439-F56D-4CE3-8378-401750D44993 +:END: + #+begin_src emacs-lisp +;; ,refs: https://github.com/winterTTr/ace-jump-mode +(use-package ace-jump-mode + :demand t + :custom + (ace-jump-mode-move-keys (cl-loop for i from ?a to ?z collect i)) + (ace-jump-mode-case-fold t) + (ace-jump-mode-submode-list '(ace-jump-word-mode ;; the first one always map to : C-c SPC + ace-jump-char-mode ;; the second one always map to: C-u C-c SPC + ace-jump-line-mode)) ;; the third one always map to :C-u C-u C-c SPC + :bind + (("C-c j a" . ace-jump-mode) + ("C-c j A" . ace-jump-mode-pop-mark) + ("C-x SPC" . ace-jump-mode-pop-mark)) + :config + ;(autoload 'ace-jump-mode "ace-jump-mode" "Emacs quick move minor mode" t) + ;(autoload 'ace-jump-mode-pop-mark "ace-jump-mode" "Ace jump back:-)" t) + (ace-jump-mode-enable-mark-sync) + (progn)) + #+end_src +**** enable Quickly Switching Windows using <<>> +:PROPERTIES: +:ID: EC70D68A-16E6-4915-8900-45010D5A59F5 +:END: + - nb, bound to =M-p=, prefix w/ =C-u= to swap w/ target, prefix with =C-u C-u= to kill target + - setup + #+begin_src emacs-lisp +(use-package ace-window + ;:after (:all ace-jump-mode) + :bind + (("M-p" . ace-select-window) + ("C-x o" . ace-select-window)) + :custom + ;; use the keys are on the home row as selection targets, (0-9 by default) + (aw-keys '(?a ?s ?d ?f ?j ?k ?l)) + (aw-dispatch-always t) + (aw-dispatch-alist '((?x aw-delete-window "Ace - Delete Window") + (?c aw-swap-window "Ace - Swap Window") + (?n aw-flip-window) + (?v aw-split-window-vert "Ace - Split Vert Window") + (?h aw-split-window-horz "Ace - Split Horz Window") + (?m delete-other-windows "Ace - Maximize Window") + (?g delete-other-windows) + (?b balance-windows) + (?u (lambda () + (progn + (winner-undo) + (setq this-command 'winner-undo)))) + (?r winner-redo))) + :config + ;; (defhydra hydra-window-size (:color red) + ;; "Windows size" + ;; ("h" shrink-window-horizontally "shrink horizontal") + ;; ("j" shrink-window "shrink vertical") + ;; ("k" enlarge-window "enlarge vertical") + ;; ("l" enlarge-window-horizontally "enlarge horizontal")) + ;; (defhydra hydra-window-frame (:color red) + ;; "Frame" + ;; ("f" make-frame "new frame") + ;; ("x" delete-frame "delete frame")) + ;; (defhydra hydra-window-scroll (:color red) + ;; "Scroll other window" + ;; ("n" scroll-other-window "scroll") + ;; ("p" scroll-other-window-down "scroll down")) + ;; (add-to-list 'aw-dispatch-alist '(?w hydra-window-size/body) t) + ;; (add-to-list 'aw-dispatch-alist '(?o hydra-window-scroll/body) t) + ;; (add-to-list 'aw-dispatch-alist '(?\; hydra-window-frame/body) t) + (ace-window-display-mode t) + (progn)) + #+end_src +*** configure Org-Mode Navigation +:PROPERTIES: +:ID: E1B47DC7-B831-450C-BCF2-1FAE6D07D94A +:END: +:LOGBOOK: +- Refiled on [2022-08-01 Mon 22:26] +:END: +#+begin_src emacs-lisp +;; org-goto +;; https://emacs.stackexchange.com/questions/20759/all-org-subheadings-in-imenu +;; accessible as C-j +;;; imenu in org-mode +(use-package emacs + :ensure nil + + :no-require t + :init + (setq org-goto-interface 'outline-path-completion) + (setq org-outline-path-complete-in-steps nil) + :custom + (org-imenu-depth 5) ;; default: 2 + (imenu-list-update-hook '((lambda () (toggle-truncate-lines t)))) + :config + (progn)) +#+end_src +*** inhibit Org-Mode folding when Comparing Files using <<>> +:PROPERTIES: +:ID: D77FDE2D-1A16-44DC-AD78-AF81E091BFD5 +:END: + + #+begin_src emacs-lisp +;; ,REF: https://emacs.stackexchange.com/questions/21335/prevent-folding-org-files-opened-by-ediff +(with-eval-after-load 'outline + (add-hook 'ediff-prepare-buffer-hook #'org-show-all)) + #+end_src +*** configure Org-Mode Links +:PROPERTIES: +:ID: FBD49E96-1717-4214-9372-608F9AEF30D3 +:END: + +add headline-search completion support when creating =org-id= links +#+begin_src emacs-lisp + +(require 'org-id) +(defun org-id-complete-link (&optional arg) + "Create an id: link using completion" + (concat "id:" (org-id-get-with-outline-path-completion org-refile-targets))) + +(org-link-set-parameters "id" :complete 'org-id-complete-link) +#+end_src + +*** use Persistent UUID References +:PROPERTIES: +:ID: 0779AAB1-655B-47DD-867C-A49A3C29D178 +:END: +setup =org-id= + #+begin_src emacs-lisp +(setq-default org-id-link-to-org-use-id t) +(setq-default org-id-locations-file (expand-file-name + (format ".org-id-locations._%s.el" (rapport-fn-context-get-label)) + rapport-uri-vault-docs-status)) +(require 'org-id) + #+end_src +*** COMMENT use Consistent Structurally Semantic Heading ID's :feature_preview: +=org-unique-id= is a utility package for org users that are tired dealing with random org IDs for their headers that change on each org to HTML export (and other kinds of exports). This package creates meaningful custom IDs for org headers that won’t change unless the user modifies them manually. + + +While =org-unique-id= may be installed on your Emacs instance, it is not active by default. This is because it can take some time to generate all the required IDs in your org file which may hang your Emacs instance for a bit. Therefore, automatic IDs are enabled on a per-file basis with the option =unique-id= . + + - use https://github.com/Phundrak/org-unique-id , https://labs.phundrak.com/phundrak/org-unique-id + #+begin_src emacs-lisp +(use-package org-unique-id + :demand + :init (add-hook 'before-save-hook #'org-unique-id-maybe) + :after org + :ensure (org-unique-id :type git + :host github + :repo "Phundrak/org-unique-id") + :config + (progn)) + #+end_src + + +The =CUSTOM_ID= properties are generated on save and only once. Once the =CUSTOM_ID= of a heading is set, the package will not modify it even if the name of the heading itself is modified. To regenerate it, delete the =CUSTOM_ID= and let =org-unique-id= regenerate it. If you don’t like the =CUSTOM_ID= generated by =org-unique-id=, you can overwrite it yourself and =org-unique-id= will not modify it. + +Note that =unique-id:t= is absolutely required in order to get these =CUSTOM_ID= . Here is the same buffer after save without this option: + + - Here is an example of an org buffer with =org-unique-id= enabled + #+begin_example +,#+title: Test file +,#+options: unique-id:t + +,* Test level 1 +:PROPERTIES: +:CUSTOM_ID: Test-level-1-zmb40t305kj0 +:END: +,*,* Test level 2 +:PROPERTIES: +:CUSTOM_ID: Test-level-1-Test-level-2-spn40t305kj0 +:END: +,* Test level 1 +:PROPERTIES: +:CUSTOM_ID: Test-level-1-1nx40t305kj0 +:END: + #+end_example + + +*** declare feature :noexport: +:PROPERTIES: +:ID: 7CEA890B-9FA6-45B6-B25C-7E9853368C58 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-text) +#+end_src + + +*** enable Text Search in a Buffer using =ctrlf= :feature_preview: +:LOGBOOK: +- Refiled on [2022-08-11 Thu 12:39] +:END: +: comparable to packages such as Isearch, Swiper, and helm-swoop. +an intuitive and efficient solution for single-buffer text search in Emacs. + +#+begin_src emacs-lisp +;; https://github.com/radian-software/ctrlf +(use-package ctrlf + :init + (ctrlf-mode +1) + :custom + (ctrlf-auto-recenter t) + (ctrlf-default-search-style 'regexp) + (ctrlf-alternate-search-style 'literal) + :config + ;wip; (setq org-fold-core-style 'overlays) ;; work-around, (hopefully temporary), https://github.com/radian-software/ctrlf/issues/118 + (progn)) +#+end_src +*** Transparently Incorporate External Documents by Reference using <<>> :pending_review:feature_preview: +:PROPERTIES: +:CREATED: [2021-09-20 Mon 22:53] +:Effort: 5:20 +:ID: 709F9250-A9B0-4A2D-B6D1-EEEE7D54415E +:END: +:LOGBOOK: +:END: + +setup =org-transclusion= via [[https://github.com/nobiot/org-transclusion][nobiot/org-transclusion]] to enable transclusion with Org Mode + +#+begin_src emacs-lisp +;; +(use-package org-transclusion + :after org + :init + (define-key global-map (kbd "") #'org-transclusion-add) + :custom + (org-transclusion-remember-transclusions t) + ;default;(org-transclusion-extensions '(org-transclusion-src-lines org-transclusion-font-lock)) + :config + (progn)) +#+end_src + +*** COMMENT Templatized Text Structures in Lisp syntax using <<>> :feature_preview: +:PROPERTIES: +:ID: 730D6330-C744-4B5C-B337-33C5B82D4CC9 +:END: +:LOGBOOK: +- Refiled on [2022-08-12 Fri 21:12] +:END: + +#+begin_src emacs-lisp +(use-package tempel + :init + ;; Setup completion at point + (defun tempel-setup-capf () + ;; Add the Tempel Capf to `completion-at-point-functions'. + ;; `tempel-expand' only triggers on exact matches. Alternatively use + ;; `tempel-complete' if you want to see all matches, but then you + ;; should also configure `tempel-trigger-prefix', such that Tempel + ;; does not trigger too often when you don't expect it. NOTE: We add + ;; `tempel-expand' *before* the main programming mode Capf, such + ;; that it will be tried first. + (require 'tempel) + (setq-local completion-at-point-functions + (cons #'tempel-expand + completion-at-point-functions))) + + :custom + ;; A list of templates available to Tempel + (tempel-path (list (expand-file-name "templates.eld" (expand-file-name "tempel" rapport-uri-vault-cfgs-emacs-apps)))) + ;; Require trigger prefix before template name when completing. + (tempel-trigger-prefix "<") + + :bind (("M-+" . tempel-complete) ;; Alternative tempel-expand + ("M-*" . tempel-insert)) + + :hook + ((prog-mode . tempel-setup-capf) + (prog-mode . tempel-abbrev-mode) + (text-mode . tempel-setup-capf) + (text-mode . tempel-abbrev-mode)) + + :config + ;; tempel may be enabled globally, as with '(global-tempel-abbrev-mode), or on a mode-specific basis using mode-activation hooks. + + ;; for first element in tempel-path, create the file if it doesnt already exist + (unless (file-readable-p (car tempel-path)) + (with-temp-buffer (write-file (car tempel-path)))) + (progn)) + + +;; Optional: Add tempel-collection. +;; The package is young and doesn't have comprehensive coverage. +(use-package tempel-collection + :disabled + :after (:all tempel) + :config + (progn)) +#+end_src + +- [[https://github.com/minad/tempel#template-syntax][Template syntax documentation]] +*** declare feature :noexport: +:PROPERTIES: +:ID: 422F57C5-0AB6-4EAC-ADCB-B18BC250587D +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-text) +#+end_src +** as Human Documents Editor :provide@editors_humans#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-humans.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** enable Distraction-Free writing using Darkroom :feature_preview: +:PROPERTIES: +:ID: AD7DBAFF-D28F-4B97-ADAA-8414279E48A3 +:END: + #+begin_src emacs-lisp +(use-package darkroom + :init + ;; ,hint: don't scale the text, so ugly man! + (setq darkroom-text-scale-increase 3)) + #+end_src +*** enable Distraction-Free writing using Olivetti :feature_preview: +:PROPERTIES: +:ID: DBFAF2A7-98CD-485E-830D-04AAB5D4DCF0 +:END: + #+begin_src emacs-lisp + (use-package olivetti + :init + (setq olivetti-body-width 100) + (setq olivetti-recall-visual-line-mode-entry-state t)) + #+end_src +*** enable Dictionary +:PROPERTIES: +:ID: 5C4B18B9-CF1A-43A0-A8E8-700ED4ABA440 +:END: + + #+begin_src emacs-lisp + (use-package dictionary) + #+end_src +*** enable Thesaurus +:PROPERTIES: +:ID: 08DE65F3-D80F-4756-A2A2-D16DAA55545B +:END: + setup =powerthesaurus= + #+begin_src emacs-lisp + (use-package powerthesaurus) + #+end_src +*** COMMENT enable "on the fly" spell-checking using <<>> + + #+begin_src emacs-lisp +;; ,refs: https://www.tenderisthebyte.com/blog/2019/06/09/spell-checking-emacs/ +;; ,refs: http://blog.binchen.org/posts/what-s-the-best-spell-check-set-up-in-emacs/ +(use-package flyspell + :if (or (executable-find "aspell") + (executable-find "ispell") + (executable-find "hunspell")) + ;:ensure-system-package ("aspell") + :init + (defun rapport/flyspell/-detect-args (&optional run-together) + "if RUN-TOGETHER is true, spell check the CamelCase words." + (let (args) + (cond + ((or + (string-match "aspell$" ispell-program-name) + (and (not (bound-and-true-p ispell-program-name)) + (executable-find "aspell"))) + ;; Force the English dictionary for aspell + ;; Support Camel Case spelling check (tested with aspell 0.6) + (setq args (list "--sug-mode=ultra" "--lang=en_US")) + (when run-together + (cond + ;; Kevin Atkinson said now aspell supports camel case directly + ;; https://github.com/redguardtoo/emacs.d/issues/796 + ((string-match-p "--camel-case" + (shell-command-to-string (concat ispell-program-name " --help"))) + (setq args (append args '("--camel-case")))) + + ;; old aspell uses "--run-together". Please note we are not dependent on this option + ;; to check camel case word. wucuo is the final solution. This aspell options is just + ;; some extra check to speed up the whole process. + (t + (setq args (append args '("--run-together" "--run-together-limit=16"))))))) + ((or + (string-match "hunspell$" ispell-program-name) + (and (not (bound-and-true-p ispell-program-name)) + (executable-find "hunspell"))) + ;; Force the English dictionary for hunspell + (setq args "-d en_US"))) + args)) + :hook + ;; enable flyspell for all modes derived from text-mode + (text-mode . flyspell-mode) + ;; enable flyspell-prog-mode for all modes derived from prog-mode + (prog-mode . flyspell-prog-mode) + ;; inhibit flyspell for the following modes + ((change-log-mode log-edit-mode) . (lambda () (flyspell-mode -1))) + :custom + (flyspell-abbrev-p t) + :config + ;; ,HINT: favor using aspell if installed, else use hunspell if installed else don't enable + (cond + ((executable-find "aspell") + ;; you may also need `ispell-extra-args' + (setq ispell-program-name "aspell") + ;(setq ispell-extra-args ...???...) + ) + ((executable-find "hunspell") + (setq ispell-program-name "hunspell") + + ;; Please note that `ispell-local-dictionary' itself will be passed to hunspell cli with "-d" + ;; it's also used as the key to lookup `ispell-local-dictionary-alist' + ;; if we use different dictionary + (setq ispell-local-dictionary "en_US") + (setq ispell-local-dictionary-alist + '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US") nil utf-8))) + ;; new variable `ispell-hunspell-dictionary-alist' is defined in Emacs + ;; If it's nil, Emacs tries to automatically set up the dictionaries. + (when (boundp 'ispell-hunspell-dictionary-alist) + (setq ispell-hunspell-dictionary-alist ispell-local-dictionary-alist))) + + (t (setq ispell-program-name nil))) + + ;; `ispell-cmd-args' is useless, it's the list of *extra* arguments we will append to the ispell process when `ispell-word' is called. + ;; `ispell-extra-args' is the command arguments which will *always* be used when start ispell process + ;; Please note when you use hunspell, `ispell-extra-args' will NOT be used. + ;; Hack `ispell-local-dictionary-alist' instead. + (setq-default ispell-extra-args (rapport/flyspell/-detect-args t)) + + (defun my-ispell-word-hack (orig-func &rest args) + "Use Emacs original arguments when calling `ispell-word'. +When fixing a typo, avoid pass camel case option to cli program." + (let* ((old-ispell-extra-args ispell-extra-args)) + (ispell-kill-ispell t) + ;; use emacs original argument + (setq ispell-extra-args (my-detect-ispell-args)) + (apply orig-func args) + ;; restore our own ispell arguments + (setq ispell-extra-args old-ispell-extra-args) + (ispell-kill-ispell t))) + (advice-add 'ispell-word :around #'my-ispell-word-hack) + (advice-add 'flyspell-auto-correct-word :around #'my-ispell-word-hack) + + (defun text-mode-hook-setup () + ;; Turn off RUN-TOGETHER option when spell check text-mode + (setq-local ispell-extra-args (rapport/flyspell/-detect-args))) + (add-hook 'text-mode-hook 'text-mode-hook-setup) + + ;; end-of-use-package-decl + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 87652FA0-47C1-491F-AFCB-EB02C3F19593 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-humans) +#+end_src +** as Software Development Environment :provide@editors_swdev#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-swdev.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** general Version Control Support :feature_preview: +**** browse Git revisions +:PROPERTIES: +:ID: 44176673-AA2C-472C-86CB-111C8D846D3A +:END: + #+begin_src emacs-lisp + (use-package git-timemachine + :init (setq git-timemachine-show-minibuffer-details t) + :hook (git-time-machine-mode . prog-mode) + ;; :bind + ;; (general-nmap "SPC g t" 'git-timemachine-toggle) + ;; (git-timemachine-mode-map + ;; "C-k" 'git-timemachine-show-previous-revision + ;; "C-j" 'git-timemachine-show-next-revision + ;; "q" 'git-timemachine-quit) + :config + (progn)) + #+end_src +**** support Conventional Commit +:PROPERTIES: +:ID: 2D8B2DD8-7E6F-4C6B-9945-CD506B5A0AFD +:END: +#+begin_src emacs-lisp +(use-package conventional-commit + :ensure (conventional-commit :host github :repo "akirak/conventional-commit.el") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (conventional-commit :host github :repo "akirak/conventional-commit.el") + :hook (git-commit-mode . conventional-commit-setup) + :config + (progn)) +#+end_src +*** general Code Authoring Support +:PROPERTIES: +:ID: BE0CAEB4-5064-4012-AB9E-BAF7A19B30B5 +:END: +**** Enable Semanticaly-Aware Parsing using <<>> :feature_preview: +:PROPERTIES: +:ID: B56C096C-A330-410C-B355-22DAA3864426 +:END: + #+begin_src emacs-lisp +(use-package tree-sitter + :hook (after-init . global-tree-sitter-mode) + :config + (progn)) + +(use-package tree-sitter-langs + :after (:all tree-sitter) + :custom + (tree-sitter-langs--bundle-version "0.12.16") + ;:files ("langs/*.el" "langs/queries") + :config + (progn)) + +(use-package tree-sitter-indent + :after (:all tree-sitter tree-sitter-langs) + :config + (progn)) + +(use-package tree-sitter-ispell + :after (:all tree-sitter) + :config + (progn)) + #+end_src +**** Enable Delimiter Match Highlighting +:PROPERTIES: +:ID: D66623D1-92C9-4CBB-8D68-C70A4E9212B4 +:END: + #+begin_src emacs-lisp + ;; visual block enclosing + (use-package paren + :ensure nil + + :hook (after-init) + :init (show-paren-mode 't)) + #+end_src + +**** Rainbow Delimiters Makes Delimiters More Visually Distinct +:PROPERTIES: +:ID: DE339788-6975-4C43-AE28-474D1392DDB3 +:END: + #+begin_src emacs-lisp +(use-package rainbow-delimiters + :hook (prog-mode . rainbow-delimiters-mode) + :config + (progn)) + #+end_src + +**** Support Dynamic Multi-Language Linting using <<>> +:PROPERTIES: +:ID: 82834DC7-2B46-40A4-A94A-D71B3D168680 +:END: + #+begin_src emacs-lisp +(use-package apheleia + ;; https://melpa.org/#/apheleia + :hook (prog-mode) + :custom + (apheleia-global-mode t) + :config + (progn)) + #+end_src + +**** Templates with <<>> :feature_preview: +:PROPERTIES: +:ID: D4BD6576-41D6-498C-A924-23D892A2541C +:END: + #+begin_src emacs-lisp +(use-package yasnippet + :init + ;; (yas-global-mode 1) + :config + (use-package yasnippets-orgmode) + (use-package aws-snippets) + (use-package auto-yasnippet) + (use-package el-autoyas)) + #+end_src + +**** enable "On the Fly" Validity Checking using <<>> +:PROPERTIES: +:ID: C767A6E8-1491-4CB8-9E37-A157C7E32C35 +:END: + #+begin_src emacs-lisp +;; #http://www.emacswiki.org/emacs/FlymakeCursor +(use-package flycheck + :bind-keymap ("C-c ~" . flycheck-command-map) ;; rather than "C-c !", to prevent stomping on org-time-stamp-inactive + :bind + (:map flycheck-mode-map ;; mode-specific jump keybind + ("C-c j c" . consult-flycheck)) + :custom + (flycheck-keymap-prefix (kbd "C-c ~")) + (help-at-pt-timer-delay 0.9) + (help-at-pt-display-when-idle '(flymake-overlay)) + :hook + (prog-mode . flycheck-mode) + ;(org-mode . flycheck-mode) + :config + ;(global-flycheck-mode 1) + (progn)) + + #+end_src +**** COMMENT enable show Flymake indicators in Fringe relative to buffer size :feature_preview:pending_review: +#+begin_src emacs-lisp +(use-package flymake + :bind + (:map flymake-mode-map + ;; mode-specific jump keybind + ("C-c j m" . consult-flymake)) + :config + (progn)) +(use-package rfringe + :after (:all flycheck) + :custom + (indicate-buffer-boundaries 'right) ;; valid values are: 'left 'right 'default 'no-fringes 'right-only 'left-only 'half-width 'minimal + (overflow-newline-into-fringe t) + :config + (setq indicate-empty-lines t) + (progn)) +#+end_src +**** Setup =imenu-list= for quick documentation traversal +:PROPERTIES: +:ID: 79EFBD63-6A2B-449A-ADB8-632626F7A50C +:END: + #+begin_src emacs-lisp + ;;; https://github.com/bmag/imenu-list + (use-package imenu-list + :bind (("C-c C-\\" . imenu-list-smart-toggle)) + :hook (add-hook 'prog-mode-hook 'imenu-add-to-menubar) + :config + (setq imenu-list-focus-after-activation t + imenu-list-auto-resize nil) + (progn)) + #+end_src + +**** Enable Source Code Indexing, XRef, and Tagging using <<>> and <<>> :feature_preview: +:PROPERTIES: +:ID: 69F76572-EA61-4DF1-82AD-892BC18560FE +:END: +setup =ggtags= + #+begin_src emacs-lisp +;; https://github.com/leoliu/ggtags +(use-package ggtags + :if (executable-find "global") + :init + (setq tags-add-tables t) + :ensure-system-package + (global) ;; require GNU Global for File Indexing + :custom + (ggtags-auto-jump-to-match-target t) + (ggtags-use-sqlite3 t) + :config + ;; suppress prompt, "Keep current list of tags tables also? (y or n)" + (progn)) + +(use-package gxref + ;; ,ref: https://emacs.stackexchange.com/questions/14802/never-keep-current-list-of-tags-tables-also + ;; ,ref: https://melpa.org/#/gxref + ;; ,ref: https://github.com/dedi/gxref + :custom + (gxref-update-db-on-save t) + :functions + (gxref-xref-backend) + :config + (require 'ggtags) + (add-to-list 'xref-backend-functions 'gxref-xref-backend) + (progn)) + +(require 'xref) +; :hook +; (prog-mode) +; :config +; (require 'gxref) + + #+end_src +**** Enable Interactive Step Debugger using <<>> +:PROPERTIES: +:ID: 210D4D4A-B566-47B4-8FF1-570F5C726C2A +:END: + #+begin_src emacs-lisp +(use-package realgud) + #+end_src +**** Enable Tag-less Xref-backend, <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: 36ADFFC5-DB8D-473D-82DB-9E0BE37F712C +:END: + + #+begin_src emacs-lisp +(use-package dumb-jump + :custom + (xref-show-definitions-function #'xref-show-definitions-completing-read) + :config + (add-hook 'xref-backend-functions #'dumb-jump-xref-activate) + (progn)) + #+end_src +**** COMMENT enable <<>> :feature_preview:pending_review:risk@upstream_unmaintained:NOTE:risk@packaging_deficient: + + #+begin_src emacs-lisp + (use-package git-gutter+ + :hook + ((prog-mode . (lambda () (git-gutter+-mode)))) + :config + (progn)) + + #+end_src +*** support Emacs Language Server using <<>> :feature_preview: +:PROPERTIES: +:ID: DB1FD8E4-FFDA-45D5-9F06-577F623353A9 +:END: +setup =emacs-lsp= + #+begin_src emacs-lisp +;; https://github.com/emacs-lsp/lsp-mode + +;; You could go minimal and use lsp-mode as it is without external +;; packages with the built-in flymake and completion-at-point or you +;; could install the following extensions for better experience: + +;; install lsp-ui for flycheck integration and higher level UI modules. +;; install lsp-treemacs for project wide error overview. +;; install lsp-ivy provides on type completion for xref-apropos. +;; install dap-mode if your language is supported by the debugger. + + +;; Commands + +;; When using lsp-mode most of the features depend on server capabilities. lsp-mode provides default bindings which are dynamically enabled/disabled based on the server functionality. All the commands are configured lsp-command-map which is bound to lsp-keymap-prefix (default s-l). +;; Keybinding Description +;; s-l s s Entry point for the server startup. +;; s-l s r Restart language server +;; s-l s q Shutdown language server +;; s-l s d Describes current dession +;; s-l s D Disconnect the buffer from the language server keeping the server running. +;; s-l = = Ask the server to format this document. +;; s-l = r Ask the server to format the region, or if none is selected, the current line. +;; s-l F a Add new project root to the list of workspace folders. +;; s-l F r Remove project root from the list of workspace folders. +;; s-l F b Remove project root from the workspace blacklist. +;; s-l T l Toggle code-lens overlays. +;; s-l T L Toggle client-server protocol logging. +;; s-l T h Toggle symbol highlighting. +;; s-l T S Toggle minor mode for showing information for current line in sideline. (requires lsp-ui) +;; s-l T d Toggle minor mode for showing hover information in child frame. (requires lsp-ui) +;; s-l T s Toggle signature auto activate. +;; s-l T f Toggle on type formatting. +;; s-l T T Toggle global minor mode for synchronizing lsp-mode workspace folders and treemacs projects. (requires lsp-treemacs) +;; s-l g g Find definitions of the symbol under point. +;; s-l g r Find references of the symbol under point. +;; s-l g i Find implementations of the symbol under point. +;; s-l g t Find type definitions of the symbol under point. +;; s-l g d Find declarations of the symbol under point. +;; s-l g h Show the incoming call hierarchy for the symbol at point. (requires lsp-treemacs) +;; s-l g a Find all meaningful symbols that match pattern. +;; s-l h h Display the type signature and documentation of the thing at +;; s-l h s Activate signature help. +;; s-l h g Trigger display hover information popup and hide it on next typing. +;; s-l r r Rename the symbol (and all references to it). +;; s-l r o Perform the source.organizeImports code action, if available. +;; s-l a a Execute code action action. +;; s-l a l Click lsp lens using β€˜avy’ package. +;; s-l a h Highlight symbol at point. +;; s-l G g Peek definitions to the identifier at point. (requires lsp-ui) +;; s-l G r Peek references to the identifier at point. (requires lsp-ui) +;; s-l G i Peek implementation locations of the symbol at point. (requires lsp-ui) +;; s-l G s Peek symbols in the worskpace. (requires lsp-ui) + + + +;; ,NB: lsp-mode integration with which-key is setup in which-key's use-package macro +(use-package lsp-mode + ;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l") + :init (setq lsp-keymap-prefix "C-c l") + :hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode) + ;;(XXX-mode . lsp) + + ;; refs, setup Python LS, https://vxlabs.com/2018/06/08/python-language-server-with-emacs-and-lsp-mode/ + (python-mode . lsp-deferred) ;; to install Python Language Server, (https://github.com/palantir/python-language-server) + ;; $> python3 -mpip install python-language-server[all] # for Python3 + ;; $> pip install python-language-server[all] # for Python2 + + ;; refs, setup Rust LS, https://www.mortens.dev/blog/emacs-and-the-language-server-protocol/ + (rust-mode . lsp-deferred) + ;; if you want which-key integration + (lsp-mode . lsp-enable-which-key-integration)) + :commands (lsp lsp-deferred) + :custom + (lsp-enable-snippet nil) + (lsp-prefer-flymake nil) ;; Prefer using lsp-ui (flycheck) over flymake. + :config + (setq lsp-yaml-server-command `("comma" "yaml-language-server" "--stdio")) + (progn)) + + + +;; optionally +(use-package lsp-ui + :requires lsp-mode flycheck + :commands lsp-ui-mode + :hook (lsp-mode . lsp-ui-mode) + :custom + (lsp-ui-peek-always-show t) + (lsp-ui-sideline-show-hover t) + (lsp-ui-doc-enable nil) + (lsp-ui-doc-enable t) + (lsp-ui-doc-use-childframe t) + (lsp-ui-doc-position 'top) + (lsp-ui-doc-include-signature t) + (lsp-ui-sideline-enable t) + (lsp-ui-sideline-ignore-duplicate t) + (lsp-ui-flycheck-enable t) + (lsp-ui-flycheck-list-position 'right) + (lsp-ui-flycheck-live-reporting t) + (lsp-ui-peek-enable t) + (lsp-ui-peek-list-width 60) + (lsp-ui-peek-peek-height 25) + :config + ;; make sure we have lsp-imenu everywhere we have LSP + (when (featurep 'lsp-ui-imenu) (require 'lsp-ui-imenu)) + (add-hook 'lsp-mode-hook 'lsp-ui-mode) + (add-hook 'lsp-after-open-hook 'lsp-enable-imenu)) + + + +(use-package lsp-treemacs + :after lsp-mode + :commands (lsp-treemacs-errors-list lsp-treemacs-sync-mode) + ;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (lsp-treemacs :type git :host github :repo "emacs-lsp/lsp-treemacs" :files ("*.el")) + :config + (lsp-treemacs-sync-mode 1) + (progn)) + + + +;; optionally if you want to use debugger +(use-package dap-mode + ;; (use-package dap-LANGUAGE) to load the dap adapter for your language + :after lsp-mode) + #+end_src + +**** configure Python support in LSP-Mode +:PROPERTIES: +:ID: 7CEF2E21-AE51-41C8-9190-B43106AF8216 +:END: + +[[https://github.com/emacs-lsp/lsp-pyright/][lsp-pyright]] supports the following [[https://github.com/emacs-lsp/lsp-pyright/#configuration][configuration]]. Each configuration is described in detail in Pyright Settings. + + - =pyright.disableLanguageServices= via =lsp-pyright-disable-language-services= + - =pyright.disableOrganizeImports= via =lsp-pyright-disable-organize-imports= + - =python.analysis.autoImportCompletions= via =lsp-pyright-auto-import-completions= + - =python.analysis.useLibraryCodeForTypes= via =lsp-pyright-use-library-code-for-types= + - =python.analysis.typeshedPaths= via =lsp-pyright-typeshed-paths= + - =python.analysis.diagnosticMode= via =lsp-pyright-diagnostic-mode= + - =python.analysis.typeCheckingMode= via =lsp-pyright-typechecking-mode= + - =python.analysis.logLevel= via =lsp-pyright-log-level= + - =python.analysis.autoSearchPaths= via =lsp-pyright-auto-search-paths= + - =python.analysis.extraPaths= via =lsp-pyright-extra-paths= + - =python.venvPath= via =lsp-pyright-venv-path= + +Projects can be further configured using =pyrightconfig.json= file. +For further details please see [[https://github.com/microsoft/pyright][Pyright]] Configuration. + +#+begin_src emacs-lisp +(use-package lsp-pyright + :hook (python-mode . (lambda () + (require 'lsp-pyright) + (lsp-deferred))) ;; lsp or lsp-deferred + :config + (progn)) +#+end_src +**** COMMENT configure Rust support in LSP-Mode :pending_development: + #+begin_src emacs-lisp +(use-package lsp-mode + :commands lsp + :custom + ;; what to use when checking on-save. "check" is default, I prefer clippy + (lsp-rust-analyzer-cargo-watch-command "clippy") + (lsp-eldoc-render-all t) + (lsp-idle-delay 0.6) + ;; enable / disable the hints as you prefer: + (lsp-rust-analyzer-server-display-inlay-hints t) + (lsp-rust-analyzer-display-lifetime-elision-hints-enable "skip_trivial") + (lsp-rust-analyzer-display-chaining-hints t) + (lsp-rust-analyzer-display-lifetime-elision-hints-use-parameter-names nil) + (lsp-rust-analyzer-display-closure-return-type-hints t) + (lsp-rust-analyzer-display-parameter-hints nil) + (lsp-rust-analyzer-display-reborrow-hints nil) + :config + (add-hook 'lsp-mode-hook 'lsp-ui-mode)) + + #+end_src +**** configure YAML support in LSP-Mode +:PROPERTIES: +:ID: 1C021DEB-F6EF-497A-80D2-A2FE278C71C2 +:END: + #+begin_src emacs-lisp +(use-package emacs + :ensure nil + + :after (lsp-mode) + :no-require t + :custom + (lsp-yaml-validate t) + (lsp-yaml-schema-store-enable t) + (lsp-yaml-schema-store-local-db (expand-file-name "lsp-yaml-schemas.json" + (expand-file-name "lsp-mode" rapport-uri-vault-var-emacs))) + :config + (setq lsp-yaml-server-command `("nix-shell" "-p" "yaml-language-server" "--run" "yaml-language-server --stdio")) + (progn)) + + #+end_src +**** configure Terraform support in LSP-Mode +:PROPERTIES: +:ID: A798EAE5-2F63-43B5-8E40-CE9EA76D9825 +:END: + #+begin_src emacs-lisp +;; ,ref: https://emacs-lsp.github.io/lsp-mode/page/lsp-terraform-ls/ +(use-package emacs + :ensure nil + :after (:all lsp-mode) + :no-require t + :init + (when (executable-find "nix-shell") + (setq + lsp-terraform-ls-server (executable-find "terraform-ls") + lsp-disabled-clients '(tfls) ;; ,HINT: for Terraform, only use the official languge-server + lsp-terraform-ls-enable-show-reference t + ;; end-of-setq + )) + :config + ;(lsp-terraform-modules-mode t) + (progn)) + #+end_src +*** support C +:PROPERTIES: +:ID: 76310687-5ABB-4714-BF3F-C69CA60BAE7B +:END: + - =c-eldoc= + #+begin_src emacs-lisp + ;; (require 'load-mode__c-eldoc) ; show the args of C functions in minibuffer + + ;;; + ;;; load-config__fspaths.el + ;;; sets a list of file-system path variables + + + ;; add in your commonly used packages/include directories here, for + ;; example, SDL or OpenGL. this shouldn't slow down cpp, even if + ;; you've got a lot of them + + ;;; register + (use-package c-eldoc + :config + (global-eldoc-mode t) + (add-hook 'c-mode-hook 'eldoc-mode) + (add-hook 'c-mode-hook 'c-turn-on-eldoc-mode)) + #+end_src +*** support Emacs Lisp :pending_review: +:PROPERTIES: +:ID: B9EBC5D6-5A0B-4457-AB61-3A3B1D3D1C88 +:END: +Emacs-Lisp IDE for Emacs + #+begin_src emacs-lisp + + #+end_src +*** support Guile Scheme +**** COMMENT Use the Asynchronous Reliable Extensible IDE (<<>>) to Connect to an Asyncronous Extensible Reliable Sleek RPC Server (<<>>) for Guile +:PROPERTIES: +:ID: 03A307FA-2C41-4177-A860-4CADCA619CE0 +:END: + - setup =ares-RS= from https://git.sr.ht/~abcdw/guile-ares-rs + #+begin_src emacs-lisp +(use-package ares-rs + :no-require + :ensure (ares-rs :type git :repo "https://git.sr.ht/~abcdw/guile-ares-rs/" :files (:default "src/")) + :config + (defun rapport/guile-ares-rs/launch () "" + (interactive) + (async-shell-command "guile -c '((@ (nrepl server) run-nrepl-server) #:port 7888)'" + + (progn)) + #+end_src + - setup =AREI= from https://git.sr.ht/~abcdw/emacs-arei + #+begin_src emacs-lisp +(use-package arei + ;; ,NB: this package is an nREPL-client, and requires connectivity to Guile's ARES-RS (Request Server) for it's primary functionality. + :ensure (arei :type git :host "git.sr.ht" :repo "~abcdw/emacs-arei") + :config + (progn)) + #+end_src + +**** <<>> IDE setup +:PROPERTIES: +:ID: EC6A7B50-3548-4285-BC44-7AF0E348C1A5 +:END: + - setup Geiser, which supports several flavors of Scheme + #+begin_src emacs-lisp +(use-package geiser) +(use-package geiser-guile :after (:all gieser) + :config + (progn)) +(use-package flycheck-guile) + #+end_src + +*** support Python +:PROPERTIES: +:ID: 0B8E843D-C9E3-46B7-AA69-DF59DF05E24B +:END: + #+begin_src emacs-lisp +;; +(use-package python + :custom + (python-indent-guess-indent-offset-verbose nil) + :hook (pyenv flycheck-pycheckers-setup)) +;; +(use-package flycheck-pycheckers + :after (flycheck python) + :ensure-system-package mypy + :hook (python-mode . flycheck-pycheckers-setup)) + #+end_src +**** enable Poetry for Python using =poetry.el= :feature_preview: +:PROPERTIES: +:ID: CFF365AF-0797-4A79-9EC9-6F9C0EAA6B82 +:END: + #+begin_src emacs-lisp +(use-package poetry + :if (executable-find "poetry") + :hook (python-mode) + :custom + (poetry-tracking-mode nil) ;; #,LOG: 20230112_NGa disabled while tuning + :config + (progn)) + #+end_src +**** enable Pipenv for Python +:PROPERTIES: +:ID: 3B84D667-22C9-4BAB-A0BC-DBA11213AC93 +:END: + - nb, https://github.com/pwalsh/pipenv.el +enable =pipenv=-based Python virtual environment management + - activate via =use-package= + #+begin_src emacs-lisp +;; - To install pylint, for each python version you wish to setup: +;; $> $(which python3) -m pip install -U pylint black --user + +;; - Several supplimental functionality packages are linked to +;; =python-mode= and are activated automaticatlly when Python is +;; edited. As a design preference, these packages are generally +;; organized in this file according to the functionality they +;; provide, rather than only according to the purposes they are +;; called into. In other words, to get a sense of what +;; supplimental packages provide support in Python mode, this file +;; could be searched for the the phrase 'python-mode' to review +;; the list of packages with hooks into =python-mode= or =prog-mode=. + +;; - Particular inspiration was taken from these references: +;; - http://rakan.me/emacs/python-dev-with-emacs-and-pyenv/ +;; - https://emacs.stackexchange.com/questions/50899/updating-pyenv-when-switching-to-a-python-buffer +;; - https://jacobian.org/2018/feb/21/python-environment-2018/ +;; - https://www.reddit.com/r/emacs/comments/3anrqf/setting_up_emacs_to_support_both_python_2_and/ + +;; +(use-package pipenv + :if (executable-find "pipenv") + :hook (python-mode) ;; #,LOG: 20201116_NGa remove hook which creates error on entering python-mode and breaks org-export + :commands (pipenv-activate) + :config + (progn)) + #+end_src +**** enable Blacken for Python +:PROPERTIES: +:ID: 0F242A26-60F8-4093-B98A-334FA57DBE85 +:END: + #+begin_src emacs-lisp + ;; blacken only work from Python v3 + (use-package blacken + ;:hook (python-mode) ;; #,LOG: 20201116_NGa remove hook which creates error on entering python-mode and breaks org-export + ) + #+end_src +**** enable Pyenv for Python +:PROPERTIES: +:ID: CABADB52-0D45-41DE-9996-8310FA0E51A9 +:END: + #+begin_src emacs-lisp + ;; https://github.com/proofit404/pyenv-mode + (use-package pyenv-mode + :if (executable-find "pyenv") + :hook (python-mode) + :config + (pyenv-mode 1)) + #+end_src +*** support Rust using <<>> +:PROPERTIES: +:ID: C5873C27-F194-4609-8A3A-F9D40781741A +:END: + +Common Rust tools + - install the toolchain mgmt app, rustup + - add ~/.cargo/bin/ to PATH + - clone: git clone https://github.com/rust-lang/rust ~/.extrefs/rust-lang + - install: cargo install rustfmt + - install: cargo install racer + + #+begin_src emacs-lisp +;; ,HINT: add support for Rust in org-babel +;; ,ref: https://github.com/brotzeit/rustic#parameters +(use-package ob-rust :config (require 'ob-rust)) + + +;; ,ref: https://robert.kra.hn/posts/rust-emacs-setup/ +(use-package rustic + :ensure + :bind (:map rustic-mode-map + ("M-j" . lsp-ui-imenu) + ("M-?" . lsp-find-references) + ;("C-c C-c l" . flycheck-list-errors) + ("C-c C-c a" . lsp-execute-code-action) + ("C-c C-c r" . lsp-rename) + ("C-c C-c q" . lsp-workspace-restart) + ("C-c C-c Q" . lsp-workspace-shutdown) + ("C-c C-c s" . lsp-rust-analyzer-status)) + :config + ;; uncomment for less flashiness + ;; (setq lsp-eldoc-hook nil) + ;; (setq lsp-enable-symbol-highlighting nil) + ;; (setq lsp-signature-auto-activate nil) + + ;; comment to disable rustfmt on save + (setq rustic-format-on-save t) + (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook)) + +(defun rk/rustic-mode-hook () + ;; so that run C-c C-c C-r works without having to confirm, but don't try to + ;; save rust buffers that are not file visiting. Once + ;; https://github.com/brotzeit/rustic/issues/253 has been resolved this should + ;; no longer be necessary. + (when buffer-file-name + (setq-local buffer-save-without-query t)) + (add-hook 'before-save-hook 'lsp-format-buffer nil t)) + +;;; +;; (use-package cargo) +;; (use-package racer) ; code completion +;; (use-package flycheck) +;; (use-package flycheck-rust) + +;; ;; nb, Rustic now depends/extends rust-mode [[https://www.reddit.com/r/emacs/comments/q9dz4e/rustic_now_depends_on_rustmode/][1]] +;; (use-package rustic +;; :mode "\\.rs\\'" +;; ;; :hook +;; ;; (rustic . (lambda () +;; ;; "" () +;; ;; (progn +;; ;; (setq racer-cmd (executable-find "racer")) ;; Racer binaries in Rust/Cargo PATH +;; ;; ;(setq racer-rust-src-path "~/.extrefs/rust-lang/src") +;; ;; (local-set-key (kbd "TAB") 'company-indent-or-complete-common) +;; ;; (electric-pair-local-mode 1) +;; ;; (local-set-key (kbd "C-c q") 'rust-format-buffer)))) +;; ;; (rust-mode . cargo-minor-mode) +;; ;; (rust-mode . racer-mode) +;; ;; (racer-mode . eldoc-mode) +;; ;; ; (flycheck-mode . flycheck-rust-setup) +;; ;; (racer-mode . company-mode) +;; :custom +;; (rustic-lsp-mode 'rust-analyzer) ;(default); +;; :config +;; ;; check for installed cargo dependencies: racer, rustfmt +;; ;; - if cargo is found in path and crate is absent, attempt to install via cargo +;; (if (executable-find "cargo") +;; (progn +;; (unless (executable-find "racer") +;; ;; func-sig: (call-process executable input output showbuff **args) => exitcode: int +;; ;; example: (call-process "echo" nil nil nil "testing 123") +;; (call-process "cargo" nil nil nil "install" "racer")) +;; (unless (executable-find "rustfmt") +;; (call-process "cargo" nil nil nil "install" "rustfmt"))) +;; (message "WRN: executable 'cargo' not found. Please check path and / or install.")) +;; (progn)) + + #+end_src + +*** COMMENT (wip) support Go :pending_review: +:PROPERTIES: +:ID: 8097CD5F-03A7-4D32-A044-0663FC59DBD4 +:END: +- context :: + - srcs + - https://github.com/s-kostyaev/flymake-go-staticcheck +setup Go support + #+begin_src emacs-lisp + (use-package go-capf + :disabled) + + #+end_src +*** support Bash Shells +:PROPERTIES: +:ID: 55EBFF90-4A13-48F4-93B8-BA7741BC9912 +:END: + #+begin_src emacs-lisp + ;; #,ref: https://github.com/bash-lsp/bash-language-server + ;; #,ref: https://www.youtube.com/watch?v=LTC6SP7R1hA + (use-package sh-script + :ensure nil + + :custom + (sh-basic-offset 2) + (sh-indentation 2) + :hook + (sh-mode . flycheck-mode) + :config + ;; flycheck-shellcheck configs, enable in non-executable/lib-style script files + (eval-after-load 'flycheck-shellcheck + (if (bound-and-true-p flycheck-shellcheck-supported-shells) + (add-to-list 'flycheck-shellcheck-supported-shells 'false) + (setq flycheck-shellcheck-supported-shells '('false)))) + ;; + (progn)) + + (use-package flymake-shellcheck) + + (use-package flycheck-bashate + :if (executable-find "bashate") + :after (flycheck) + :hook (sh-mode . flycheck-bashate-setup)) + + (use-package flycheck-checkbashisms + :if (executable-find "checkbashisms") + :after (flycheck) + :hook (sh-mode . flycheck-checkbashisms-setup)) + + #+end_src +*** support Powershell +:PROPERTIES: +:ID: 3123693E-E843-48B2-982D-BB5E9172EC81 +:END: +setup =powershell= language support + #+begin_src emacs-lisp + ;; + (use-package powershell + :mode ("\\.ps[dm]?1\\'" . powershell-mode)) + + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: C3A71090-28E5-48DF-A016-103FFB82A217 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-swdev) +#+end_src +** as Systems Editor :provide@editors_infradev#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-infradev.el" (org-sbe rapport-sbe--get-libdir)) +:END: +DevOps, and Infrastructure mgmt +*** authoring Docker and Docker-Compose +:PROPERTIES: +:ID: 083B59FE-858E-462C-B5E8-369F31DBABE3 +:END: + #+begin_src emacs-lisp +(use-package dockerfile-mode) +(use-package docker-compose-mode) + #+end_src +*** enable Docker Mgmt within Emacs using Docker.el +:PROPERTIES: +:ID: 6524CD7C-953C-4288-B389-1D1B83C3FEDB +:END: + #+begin_src emacs-lisp +;; ,REF: https://github.com/Silex/docker.el +(use-package docker + :config + ;; ,NB: this package includes docker-tramp + (progn)) + #+end_src +*** authoring Markdown +:PROPERTIES: +:ID: 76CC307A-10A0-4A0C-9C64-608F589BF611 +:END: +setup =markdown-mode+= + #+begin_src emacs-lisp + ;; https://jblevins.org/projects/markdown-mode/ + (use-package markdown-mode + :commands (markdown-mode gfm-mode) + :mode (("README\\.md\\'" . gfm-mode) + ("\\.md\\'" . markdown-mode) + ("\\.markdown\\'" . markdown-mode)) + :config + (progn + ;; for editing code-block regions as indirect buffers + (use-package edit-indirect)) + :init (setq markdown-command "multimarkdown")) + + #+end_src + +setup Org-Export to Markdown + #+begin_src emacs-lisp +;; Associated Functions +;; - org-md-export-to-markdown +;; - org-md-export-as-markdown +;; - org-md-convert-region-to-md, convert region to MD +(add-to-list 'org-export-backends 'md) +(use-package auto-org-md) + #+end_src + +*** support Config-Mgmt via Saltstack +:PROPERTIES: +:ID: 056BA179-FCC8-4FDA-A9AB-26DCDE9C85F1 +:END: +setup =salt-mode= via =use-package= + + #+begin_src emacs-lisp + (use-package salt-mode + :mode "\\.sls\\'" + :config + (progn)) + #+end_src +*** support Terraform +:PROPERTIES: +:ID: 1AE2A6E7-FDE5-45A5-873B-0B8837EE95D3 +:END: +setup =terraform-mode= + #+begin_src emacs-lisp + (use-package terraform-mode :mode "\\.tf\\'") + #+end_src + +*** support Kubernetes +**** Manage Kubernetes w/ =kubel= +:PROPERTIES: +:ID: BB8B0465-AEA9-4CF7-BE4D-6B707CEE3BB7 +:END: +setup =kubel= + #+begin_src emacs-lisp + ;; https://github.com/abrochard/kubel + (use-package kubel + :custom + (kubel-use-namespace-list 'on) + :config + (progn)) + #+end_src + +*** support Rego (as used in Open Policy Agent, etc.) +:PROPERTIES: +:ID: E8531056-B12C-429B-A121-578C80C84A98 +:END: +setup =rego-mode= + #+begin_src emacs-lisp + ;; https://github.com/psibi/rego-mode + (use-package rego-mode + :if (executable-find "opa") + ;; Prerequisites: + ;; - Make sure that you install opa and it's available in your system. + ;:ensure-system-package (opa) + ;; Features: + ;; - Syntax highlighting (Using font lock) + ;; - Basic indentation, commenting + ;; - Automatic formatting on save (Configurable via variable). Uses opa fmt for it. + ;; - REPL support. The function rego-repl-show will load a plain + ;; REPL. You can also use rego-repl-with-data to pass file or + ;; directory which will be loaded to the REPL. + :config + (progn)) + + #+end_src + +*** support Vagrant +:PROPERTIES: +:ID: 9C36F545-0A73-466D-903C-5E5C2BAF105C +:END: +enable use of =vagrant= from w/i Emacs + - activate =vagrant= package via =use-package= + #+begin_src emacs-lisp + (use-package vagrant + :if (executable-find "vagrant") + :config + (progn)) + + #+end_src +*** support Cloud, AWS +:PROPERTIES: +:ID: 4BDC3E16-57A9-4794-901E-F339EB33AB3D +:END: +- snippets + #+begin_src emacs-lisp +(use-package aws-snippets) + #+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: 1CE9E725-D265-425E-BA14-AC3063BC8164 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-infradev) +#+end_src +** as Data and Analytics Editor :provide@editors_data#rapport: +:PROPERTIES: +:ID: 3055AEA9-0D8D-4784-8A4D-1B9BF9472D1A +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-data.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** support REST API client scripts using Restclient.el +:PROPERTIES: +:ID: A6CB1A71-AEA7-4219-A09E-A1B282393BC7 +:END: + #+begin_src emacs-lisp +;(use-package restclient) +;(use-package restclient-jq) +;(use-package restclient-test) +(use-package ob-restclient) + #+end_src +*** support CSV +:PROPERTIES: +:ID: 840C31DF-7FC3-4775-BA0A-44E5A533B8CC +:END: + + #+begin_src emacs-lisp + (use-package csv-mode) + + #+end_src +*** support YAML +:PROPERTIES: +:ID: F0701BCA-98A5-465F-A991-9B6A8309505A +:END: + + #+begin_src emacs-lisp + ;;; + (use-package yaml-mode + :mode ("\\.y[a]?ml\\'" . yaml-mode) ("\\.sls\\'" . salt-mode) + :config + (add-hook 'yaml-mode-hook + (progn + #'(lambda () (define-key yaml-mode-map "\C-m" 'newline-and-indent)) + #'(lambda () (yafolding-mode)) + #'(lambda () (indent-tools-minor-mode)) + ;#'(lambda () (highlight-indent-guides-mode)) + ))) + + ;;; https://github.com/psycofdj/yaml-path + (use-package yaml-imenu) ;; 20200208_NGa under evaluative testing + + ;;; + (use-package indent-tools + :bind ("C-c >" . indent-tools-hydra/body)) + + ;;; + (use-package flycheck-yamllint ; reqs 'pip install yamllint' + :mode ("\\.y[a]?ml\\'" . yaml-mode) ("\\.sls\\'" . salt-mode) + :init + (eval-after-load 'flycheck '(add-hook 'flycheck-mode-hook #'flycheck-yamllint-setup)) + (eval-after-load 'flycheck '(add-hook 'after-init-hook #'global-flycheck-mode))) + + #+end_src +*** support JSON +:PROPERTIES: +:ID: C992CC03-83AA-495D-AFBA-1E0FB9108E12 +:END: + + #+begin_src emacs-lisp + ;; + (use-package json-mode + :mode ("\\.json\\'" . json-mode) + :commands (json-mode-show-path json-mode-beautify) + :config + (progn)) + + (use-package json-reformat) + #+end_src +*** support Visual RegEx +:PROPERTIES: +:ID: 7BC38607-9181-43B2-A45A-4FE6C52C0E4C +:END: +:LOGBOOK: +- Refiled on [2022-02-16 Wed 21:05] +- Refiled on [2021-11-29 Mon 22:18] +:END: +setup =visual-regexp= + #+begin_src emacs-lisp + (use-package visual-regexp-steroids) + #+end_src +*** support <<>> :feature_preview: +:PROPERTIES: +:ID: 7C857CB7-988A-4F7B-A0D3-D2CBDD8557F9 +:END: +setup [[http://www.gnuplot.info/][GNUPlot]] +#+begin_src emacs-lisp +(use-package gnuplot + :custom + (gnuplot-image-format "svg") + :config + (progn)) +#+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: B317054D-F37B-4BC9-8CD8-6E093E8663BF +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-data) +#+end_src +** as Data and System Visualization Editor :provide@editors_data2viz#rapport: +:PROPERTIES: +:ID: 615B96CE-11CC-49FA-9443-98F4E6C5E624 +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-data2viz.el" (org-sbe rapport-sbe--get-libdir)) +:END: + + +*** COMMENT Enable DITAA Support +:LOGBOOK: +- Refiled on [2024-08-04 Sun 11:20] +:END: +#+begin_src emacs-lisp + (setq org-babel-ditaa-java-cmd (executable-find "java")) + + (when (and (not (and (bound-and-true-p org-ditaa-jar-path) + (file-readable-p org-ditaa-jar-path))) + (and (file-name-absolute-p (executable-find "ditaa")) + (string-prefix-p "/nix/store/" (executable-find "ditaa")))) + (setq org-ditaa-jar-path + (expand-file-name "../lib/ditaa.jar" + (file-name-directory (executable-find "ditaa"))))) + + + ;; ;(setq org-ditaa-jar-path ...???...) + ;; (setq org-babel-default-header-args:ditaa + ;; `((:results . "file") + ;; (:exports . "results") + ;; (:java . "-Dfile.encoding=UTF-8") + ;; (:cmdline t) + ;; ) + ;; ;; end-of-list + ;; ) + + +#+end_src +*** PlantUML Support :risk@upstream_unmaintained: +:PROPERTIES: +:ID: F8264A02-373A-454B-B45C-EDE6ADD4E3C1 +:END: +:LOGBOOK: +- Refiled on [2024-08-04 Sun 11:21] +:END: +setup <<>> [[id:F2B76C68-1B2E-496A-A47B-1A435F3BCCFD][[roam]​]] support + #+begin_src emacs-lisp +;; https://github.com/skuro/plantuml-mode +(use-package plantuml-mode + :if (executable-find "plantuml") + :mode (("\\.plantuml\\'" . plantuml-mode) + ("\\.puml\\'" . plantuml-mode)) + :init + (setq plantuml-default-exec-mode 'executable) + + :custom + ;; not used + (plantuml-jar-path "~/.vault/cfgs/emacs/apps/plantuml/plantuml.jar") + ;; used + (org-plantuml-jar-path "~/.vault/cfgs/emacs/apps/plantuml/plantuml.jar") + (org-plantuml-exec-mode 'plantuml) + (plantuml-executable-args '("-quiet" "-darkmode")) + (plantuml-output-type "svg") + (plantuml-indent-level 4) + ;:ensure-system-package (plantuml) ;; NB: this is a potentially heavy-weight install w/ deps + + ;; discretionary quality-of-life configs ;; + + ;; (org-babel-default-header-args:plantuml + ;; (cons '(:exports . "results") + ;; (cons '(:cache . "yes") + ;; (cons '(:file . (make-temp-file (concat (rapport-fn-context-get-label) "--" (buffer-name) "-buffer--" (rapport-fn-current-time-as-string)) nil (concat "." plantuml-output-type))) + ;; (cons '(:noweb . "yes") + ;; (assq-delete-all :exports + ;; (assq-delete-all :cache + ;; (assq-delete-all :file + ;; (assq-delete-all :noweb + ;; org-babel-default-header-args))))))))) + + :config + ;; download the Plantuml JAR if it's not already in place at plantuml-jar-path + ;(unless (file-exists-p plantuml-jar-path) (plantuml-download-jar)) + ;(add-to-list 'org-src-lang-modes '("plantuml" . plantuml)) + ;(add-to-list 'org-babel-load-languages '(plantuml . t)) + ;(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages) + (defun rapport/live-preview/-command (&optional src-buffer dst-buffer render-type dst-buffer-hooks) + "src-buffer is a string, dst-buffer is a string ... prereq: live-preview-mode" + (interactive) + (let* + ((src-buffer (or (when (and (bound-and-true-p src-buffer) + (get-buffer src-buffer)) + (get-buffer src-buffer)) + (get-buffer (current-buffer)))) + (render-from (buffer-local-value 'mode-name src-buffer)) + (render-from-conf 'nil) + (render-to 'nil) + (render-to-conf 'nil) + (render-type (concat render-from (when (bound-and-true-p render-to) + (format "-as-%s" render-to)))) + ;; args: dst-buffer render-type + ;(dst-buffer-auto-name-format "*Live Preview Output: %s |%s|*") + ;(err-buffer-auto-name-format "*Live Preview Error: %s |%s|*") + (dst-buffer-auto-name (when (bound-and-true-p dst-buffer-auto-name-format) + (format dst-buffer-auto-name-format + src-buffer + render-type))) + (dst-buffer (or (when (and (bound-and-true-p dst-buffer) + (buffer-name (get-buffer dst-buffer))) + (get-buffer-create dst-buffer)) + (when (bound-and-true-p dst-buffer-auto-name) + (get-buffer-create dst-buffer-auto-name)) + (get-buffer-create "*live-preview*")))) + (save-excursion + (with-current-buffer dst-buffer + (mark-whole-buffer) + ;(delete-active-region) + (insert + (plantuml-preview-string t + (with-current-buffer src-buffer (buffer-substring-no-properties (point-min) (point-max))))) + ;; normal-mode or set-buffer-major-mode + (normal-mode)))))) + #+end_src + +*** COMMENT add PlantUML support in Flycheck using <<>> :risk@component_unmaintained:pending_review: +:LOGBOOK: +- Refiled on [2024-08-04 Sun 11:21] +:END: +enable =flycheck= support for PlantUML + #+begin_src emacs-lisp +;; https://github.com/alexmurray/flycheck-plantuml +(use-package flycheck-plantuml + :after (:all plantuml-mode flycheck) + :config + (require 'flycheck-plantuml) + (flycheck-plantuml-setup) + (progn)) + #+end_src +*** Create Mind-Map using <<>> +:PROPERTIES: +:ID: D18F1073-F65D-41AE-BCED-A24400121B73 +:END: +:LOGBOOK: +- Refiled on [2024-08-04 Sun 11:21] +:END: +# ;; This is an Emacs package that creates graphviz directed graphs from +# ;; the headings of an org file + - from + #+begin_src emacs-lisp +(use-package org-mind-map + :init + (require 'ox-org) + :ensure t + ;; Uncomment the below if 'ensure-system-packages` is installed + ;;:ensure-system-package (gvgen . graphviz) + :config + (setq org-mind-map-engine "dot") ; Default. Directed Graph + ;; (setq org-mind-map-engine "neato") ; Undirected Spring Graph + ;; (setq org-mind-map-engine "twopi") ; Radial Layout + ;; (setq org-mind-map-engine "fdp") ; Undirected Spring Force-Directed + ;; (setq org-mind-map-engine "sfdp") ; Multiscale version of fdp for the layout of large graphs + ;; (setq org-mind-map-engine "twopi") ; Radial layouts + ;; (setq org-mind-map-engine "circo") ; Circular Layout + ) + #+end_src +*** declare feature :noexport: + + #+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; + (provide 'rapport-editors-data2viz) + ;;; rapport-editors-data2viz.el ends here + #+end_src +** as Notes, Artifacts, Journal Editor and Organizer :provide@editors_org#rapport: +:PROPERTIES: +:ID: 3245C3CF-AE89-49B3-BEF0-F95622BD80EB +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-editors-org.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** using Org-Agenda +:PROPERTIES: +:ID: E0B93F86-972E-4F46-97AE-052FDF58735F +:ORDERED: t +:END: +setup Org Agenda + #+begin_src emacs-lisp +;; Org-Agenda + +(use-package emacs + :ensure nil + + :no-require t + :init + ;; set org-agenda-files, if unset + (unless (bound-and-true-p org-agenda-files) + (setq org-agenda-files (expand-file-name (format "org-agenda-files._%s.txt" (rapport-fn-context-get-label)) rapport-uri-vault-docs-status))) + ;; create org-agenda-file, if doesnt exist + (unless (file-exists-p org-agenda-files) + (with-temp-buffer (write-file org-agenda-files))) + :custom + ;;; Org Agenda Section + + ;; (nb) press C-c C-t followed by the selection key, ('SPC' will remove TODO info), and the entry will be switched to this state. + ;; !=timestamp, @=note w/ timestamp, |= describes sequence (to-left not-done, to-right done) + (org-todo-keywords + '((sequence "OPEN(o!)" "|" "SHUT(C!)") ;; Generic States + (sequence "TODO(t!)" "WAIT(w@)" "NEXT(n@)" "|" "STOP(K@)" "DONE(D@)"))) ;; Task states (used by Org-GTD) + + (org-todo-keyword-faces '( + ;; Basic + ("OPEN" :foreground "orange" :weight bold) + ("SHUT" :foreground "purple" :background "darkgrey" :weight bold) + ;; GTD + ;("TODO" :foreground "red" :background "black" :weight bold) ;; ,HINT: uncomment this line for bolder 'TODO faces + ("NEXT" :foreground "white" :background "blue" :weight bold) + ("WAIT" :foreground "yellow" :weight bold) + ("STOP" :foreground "green" :strike-through t :weight bold) + ("DONE" :foreground "green" :weight bold) + )) + ;; global Effort estimate values + (org-sort-agenda-noeffort-is-high 't) ; absent effort-estimate means unbound-high + + ;; Agenda log mode items to display (closed and state changes by default) + (org-agenda-log-mode-items (quote (state))) + + ;; This one is pretty awesome; it forces you to mark all child tasks + ;; as β€œDONE” before you can mark the parent as β€œDONE.” The agenda + ;; view already has the notion of β€œblocked” tasks (those with + ;; incomplete child tasks), which should appear dimmed (that, of + ;; course, is also customizable). This makes it even harder to + ;; slack off on your work. + (org-enforce-todo-dependencies t) + + + ;; customize org TODO priorities and faces + ;; A="URGENT (drop everything else)", B="HIGH (work this first)", C="NORMAL (important but not pressing)", D="LOW (needed but can wait)", E="DEFERED (not needed, nice to have)" + ;; - taken from load-conf__org-agenda.el + (org-highest-priority ?A) + (org-default-priority ?D) + (org-lowest-priority ?E) + ;; (add-to-list 'org-priority-faces + ;; '( + ;; (?A . (:foreground "red" :weight bold :underline 't)) + ;; (?B . (:foreground "orange" :weight bold :underline 'nil)) + ;; (?C . (:foreground "green" :weight normal :underline 'nil)) + ;; (?D . (:foreground "light green" :weight normal :underline 'nil)) + ;; (?E . (:foreground "gray80" :weight normal :underline 'nil)))) + + + ;; org-agenda formatting ;; + + (org-agenda-time-grid + '((daily today) + (600 800 1000 1200 1400 1600 1800 2000 2200) + " " + "----------------")) + (org-agenda-current-time-string "β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”βŒšβŒšβŒšβ€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”") + ;;(org-pretty-entities t) + (org-agenda-span 'day) ;; set the default view to 1 day, (instead of 1 week), for quicker start-ups. + ;; Agenda clock report parameters + (org-agenda-clockreport-parameter-plist + (quote (:link t :maxlevel 5 :fileskip0 t :compact t :narrow 80 :properties ("TAGS")))) + + ;; Define custom Agenda quick-commands + ;; - from http://stackoverflow.com/questions/1361595/emacs-org-mode-agenda-filter-by-owner + ;; - ex. (list " " ) + + (org-agenda-custom-commands + '(("n" "Overview" + ((agenda "" ((org-agenda-overriding-header " AGENDA OF THE DAY / DEADLINES in 3 months\n") + ;; limits the agenda display to a single day) + (org-agenda-span 1) + (org-deadline-warning-days 90) ;; [1] + )) + (agenda "" ;; Birthdays in this week + ((org-agenda-overriding-header " ANNIVERSARIES IN 7 DAYS\n") + (org-agenda-span 7) + (org-agenda-show-all-dates nil) + (org-agenda-start-on-weekday nil) + (org-agenda-time-grid nil) + (org-agenda-entry-types '(:sexp)))) + (todo "NEXT|TODO|OPEN" + ((org-agenda-overriding-header " NEXT THING TO DO\n") + (org-agenda-skip-function '(org-agenda-skip-entry-if + 'scheduled)) + )) + (tags "type@project|type@objective" + ((org-agenda-overriding-header " PROJECTS STATUS\n") + (org-agenda-sorting-strategy '(priority-down)) + (org-agenda-skip-function '(org-agenda-skip-entry-if + 'todo '("DONE" "STOP" "WAIT"))) + )) + (tags "task@impediment|task@inquiry|_review|evalutate|_inquire" + ((org-agenda-overriding-header " OPEN PROBLEMS\n") + (org-agenda-sorting-strategy '(priority-down)) + (org-agenda-skip-function '(org-agenda-skip-entry-if + 'todo '("DONE" "SHUT" "STOP"))) + )) + (tags-todo "-project-@question" + ((org-agenda-overriding-header " TODO LIST\n") + (org-agenda-skip-function '(org-agenda-skip-entry-if + 'scheduled + 'deadline + 'todo '("NEXT" "CALL" "REVIEW"))) + (org-agenda-sorting-strategy '(priority-down)) + )) + )) + ;; + ;; ("o" "(wip/demo) tasks for olaf" + ;; ((org-agenda-list) + ;; (org-agenda-filter-apply ("+oleg"))) + ;; ((org-agenda-remove-tags t))) + ;; ("k" "(wip/demo) tasks for karl" + ;; ((org-agenda-list) + ;; (org-agenda-filter-apply ("+karl"))) + ;; ((org-agenda-remove-tags t))) + ;; ;; + ;; ("O" "(wip/demo) Office block agenda" + ;; ((agenda "" ((org-agenda-ndays 1))) + ;; ;; limits the agenda display to a single day + ;; (tags-todo "+PRIORITY=\"A\"") + ;; (tags-todo "computer|office|phone") + ;; (tags "project+CATEGORY=\"elephants\"") + ;; (tags "review" ((org-agenda-files '("~/org/circuspeanuts.org")))) + ;; ;; limits the tag search to the file circuspeanuts.org + ;; (todo "WAITING")) + ;; ((org-agenda-compact-blocks t))) ;; options set here apply to the entire block + + ;; ...other commands here + + )) + + + ;; ,HINT: define Org property Keywords and preset selectable values + (org-global-properties `( + ;; ,HINT: the first item in the list should be the maximum all-inclusive LOE for a GTD "do now" task + ;; ,HINT: these task estimation times are intentionally jagged, because humans are bad at estimating, (especially this one) + ;; ,HINT: generally only "leaf-node" tasks should be estimated, project estimation should accumulate and sum these estimates + ("Effort_ALL" . "0:20 0:40 1:20 2:40 5:20 10:40 21:20 42:40") + ("STYLE_ALL" . "habit") + ("REPEAT_TO_STATE_ALL" . "TODO NEXT") + ("resource_ALL" . "") + ("allocate_ALL" . "") + )) + + + ;:custom-face + ;(org-agenda-column-dateline ((t (:background "dim gray" :foreground "magenta" :weight bold)))) + ;(org-agenda-structure ((t (:foreground "dark gray" :weight bold)))) + ;(org-column ((t (:weight normal)))) + ;(org-column-title ((t (:background "cyan" :foreground "white" :underline t :weight bold)))) + :config + ;; #,HINT: Supply Generic Tags and Tag-Group presets. Personal Tags and Tag-Groups may be set in the 'custom-file + + ;; (setq org-tag-alist `( + + ;; ;; Group by Domain + ;; (:startgrouptag) + ;; ("ctx") + ;; (:grouptags) + ;; ("@assets" . ?A) + ;; ("@community" . ?C) + ;; ("@events" . ?E) + ;; ("@family" . ?F) + ;; ("@household" . ?H) + ;; ("@practices" . ?P) + ;; ("@work" . ?W) + ;; (:endgrouptag) + + ;; #+TAGS: [ GTD : Control Persp ] + ;; In this example, β€˜GTD’ is the group tag and it is related to two other tags: β€˜Control’, β€˜Persp’. Defining β€˜Control’ and β€˜Persp’ as group tags creates a hierarchy of tags: + ;; #+TAGS: [ Control : Context Task ] + ;; #+TAGS: [ Persp : Vision Goal AOF Project ] + ;; #+TAGS: { Context : @Home @Work @Call } + ;; #+TAGS: [ Vision : {V@.+} ] + ;; #+TAGS: [ Goal : {G@.+} ] + ;; #+TAGS: [ AOF : {AOF@.+} ] + ;; #+TAGS: [ Project : {P@.+} ] + + + ;; ;; Group by Activity Heirarchies + ;; (:startgrouptag) + + ;; (:startgrouptag) + ;; ("activity/physical") + ;; (:grouptags) + ;; ("moving objects") + ;; ("using tools") + ;; ("manipulating materials") + ;; (:endgrouptag) + + + ;; (:startgrouptag) + ;; ("activity/cognitive") + ;; (:grouptags) + ;; ("communicating") + ;; ("problem-solving") + ;; ("decision-making") + ;; ("planning") + ;; ("organizing") + ;; ("time management") + ;; ("learning") + ;; ("creativity") + ;; ("critical thinking") + ;; (:endgrouptag) + + + ;; (:startgrouptag) + ;; ("social-activity") + ;; (:grouptags) + ;; ("teamwork") + ;; ("leadership") + ;; ("motivation") + ;; ("self-discipline") + ;; (:endgrouptag) + + + ;; (:startgrouptag) + ;; ("Activity") + ;; (:grouptag) + ;; ("_acquire" . ?a) + ;; ("_applaud" . ?d) + ;; ("_build" . ?b) + ;; ("_clean" . ?l) + ;; ("_communicate" . ?c) + ;; ("_design" . ?i) + ;; ("_draft" ) + ;; ("_edit" . ?e) + ;; ("_help" . ?h) + ;; ("_learn" . ?l) + ;; ("_maint" . ?m) + ;; ("_move" . ?v) + ;; ("_present" . ?p) + ;; ("_give" . ?g) + ;; ("_publish") + ;; ("_repair" . ?f) + ;; ("_review" . ?r) + + ;; ;; # ^^misc other activities: inform, influence, lead-gen, shape opportunity, drive, lead, inspire, manage-risk + ;; (:endgrouptag) + + ;; (:startgrouptags) + ;; ("Assets") + ;; (:grouptags) + ;; ("{asset@.+}") + ;; (:endgrouptags) + + ;; end-of-list + + + (setq org-tag-persistent-alist '( + ;; Composure Item Types + (:startgroup) + ("type@task" . nil) + ("type@scope" . nil) + ("type@contact" . nil) + (:endgroup) + + ;; Composure Task types + (:startgroup) + ("task@project" . nil) + ("task@objective" . nil) + (:endgroup) + + ;; Composure Scope types + (:startgroup) + ("scope@tld") + ("scope@job") + + (:endgroup) + + ;; Composure Contact types + (:startgroup) + ("contact@vendor" . nil) + ("contact@client" . nil) + ("contact@person" . nil) + ("contact@team" . nil) + (:endgroup) + + ;; ;; Composure Activity Types + ;; (:startgroup) + ;; ("HOME" . ?h) + ;; ("RESEARCH" . ?r) + ;; ("TEACHING" . ?t) + ;; (:endgroup) + + ;; ;; Composure Contact Types + ;; (:startgroup) + ;; ("OS" . ?o) + ;; ("DEV" . ?d) + ;; ("WWW" . ?w) + ;; (:endgroup) + + ;; (:startgroup) + ;; ("EASY" . ?e) + ;; ("MEDIUM" . ?m) + ;; ("HARD" . ?a) + ;; (:endgroup) + + ;; ("URGENT" . ?u) + ("export" . nil) + ("noexport" . ?x) + + )) + + + ;; ,HINT in this config tags are still heavily WIP, and retained here for example purposes + (setq org-tag-faces '( + ;; ("HOME" . (:foreground "GoldenRod" :weight bold)) + ;; ("RESEARCH" . (:foreground "GoldenRod" :weight bold)) + ;; ("TEACHING" . (:foreground "GoldenRod" :weight bold)) + ;; ("OS" . (:foreground "IndianRed1" :weight bold)) + ;; ("DEV" . (:foreground "IndianRed1" :weight bold)) + ;; ("WWW" . (:foreground "IndianRed1" :weight bold)) + ;; ("URGENT" . (:foreground "Red" :weight bold)) + ;; ("KEY" . (:foreground "Red" :weight bold)) + ;; ("EASY" . (:foreground "OrangeRed" :weight bold)) + ;; ("MEDIUM" . (:foreground "OrangeRed" :weight bold)) + ;; ("HARD" . (:foreground "OrangeRed" :weight bold)) + ;; ("BONUS" . (:foreground "GoldenRod" :weight bold)) + ;; ("UCANCODE" . (:foreground "GoldenRod" :weight bold)) + ("noexport" . (:foreground "darkgrey")) + )) + + ;(setq org-fast-tag-selection-single-key t) + ;(setq org-use-fast-todo-selection t) + + + + + + + + + (progn)) + #+end_src +*** using Org-Attach +:PROPERTIES: +:ID: 4CD9FEB8-C746-4A04-8B89-D6C800221853 +:END: + +allow Automatic version-control with Git + #+begin_src emacs-lisp +;; https://orgmode.org/manual/Automatic-version_002dcontrol-with-Git.html#Automatic-version_002dcontrol-with-Git + +;; If the directory attached to an outline node is a Git repository, +;; Org can be configured to automatically commit changes to that +;; repository when it sees them. + +;; To make Org mode take care of versioning of attachments for you, +;; add the following to your Emacs config: + +(require 'org-attach-git) + #+end_src + + +allow Attach from Dired + #+begin_src emacs-lisp +;; https://orgmode.org/manual/Attach-from-Dired.html#Attach-from-Dired + +;; It is possible to attach files to a subtree from a Dired buffer. To +;; use this feature, have one window in Dired mode containing the +;; file(s) to be attached and another window with point in the +;; subtree that shall get the attachments. In the Dired window, with +;; point on a file, M-x org-attach-dired-to-subtree attaches the +;; file to the subtree using the attachment method set by variable +;; org-attach-method. When files are marked in the Dired window then +;; all marked files get attached. + +;; Add the following lines to the Emacs init file to have C-c C-x a attach files in Dired buffers. + +(add-hook 'dired-mode-hook + (lambda () + (define-key dired-mode-map + (kbd "C-c C-x a") + #'org-attach-dired-to-subtree))) + +;; The following code shows how to bind the previous command with a specific attachment method. + +(add-hook 'dired-mode-hook + (lambda () + (define-key dired-mode-map (kbd "C-c C-x c") + (lambda () + (interactive) + (let ((org-attach-method 'cp)) + (call-interactively #'org-attach-dired-to-subtree)))))) + #+end_src + + +Allow jumping to the Org heading corresponding to an Org-Attach file or location +#+begin_src emacs-lisp +;; ,refs: originally from https://fuco1.github.io/2023-02-08-Visit-the-org-headline-from-the-attach-dired-buffer.html +(defun rapport/org-attach/visit-headline-from-dired () + "Go to the headline corresponding to this org-attach directory." + (interactive) + (let* ((id-parts (last (split-string default-directory "/" t) 2)) + (id (apply #'concat id-parts))) + (let ((m (org-id-find id 'marker))) + (unless m (user-error "Cannot find entry with ID \"%s\"" id)) + (pop-to-buffer (marker-buffer m)) + (goto-char m) + (move-marker m nil) + (org-show-entry)))) + +#+end_src +*** using <<>> +:PROPERTIES: +:ID: F0AF4994-4C37-4CB9-B7C9-640C0BF2737F +:END: + + #+begin_src emacs-lisp +(use-package org-archive + :ensure nil + + :custom + (org-archive-location (expand-file-name "%s_archive::datetree/" (expand-file-name "archive" (expand-file-name ".artifacts" rapport-uri-vault-docs)))) + :config + (progn)) + #+end_src + +*** using <<>> [[id:F56E4537-BD96-4428-9F51-8D09722C55A1][[roam]​]] +:PROPERTIES: +:ID: 91019FE9-20F2-4B8C-981F-176BA98C7390 +:END: +setup Org Babel + #+begin_src emacs-lisp + ;; disable the confirm prompt for code block evaluation + ;(setq org-confirm-babel-evaluate t) + + ;; ;; auto-activate Babel languages as their used + (defadvice org-babel-execute-src-block (around load-language nil activate) + "Load language if needed" + (let ((language (org-element-property :language (org-element-at-point)))) + (unless (cdr (assoc (intern language) org-babel-load-languages)) + (add-to-list 'org-babel-load-languages (cons (intern language) t)) + (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)) + ad-do-it)) + + ;; DESC: w/r/t NoWeb syntax in Tangle'd Source Blocks + ;; - in such cases the dereferencing will still work (untested), but syntax highlighting will break in bothersome ways + ;; - if desired, to work better in such cases, we may change the noweb markers to {{{ and }}} + ;; - as of [2015-10-04], NGa will set these as buffer-local + ;; variable/value overrides, rather than globally, in order to + ;; avoid incompatible breaks with users of the default config + + #+end_src +pre-load the shell language, =ob-shell= + #+begin_src emacs-lisp +(require 'ob-shell) + #+end_src + +*** using <<>> [[id:D2D57D0F-7EC9-48F0-B22A-AD00458BF415][[roam]​]] +:PROPERTIES: +:ID: 6DC52181-F3FF-4023-8724-D5DF20D38AB7 +:END: +setup <<>>, aka Declarative Org Capture Template + #+begin_src emacs-lisp +;; Org-Capture +;; Quickly record notes without interupting thought process or workflow + +;; https://github.com/progfolio/doct +(use-package doct + :after (:all org) + :demand t + :init + (require 'org-macs) + (require 'org-capture) + (require 'org-protocol) + ;; #,TODO: consider relocating the org-default-task-body variables to a more suitable spot + (setq org-default-task-body " +----- +--- _/overview/_ --- + + +----- +--- _/info/notes/_ --- + +- *on Sources* + ,#+NAME: %(org-id-get-create)-srcs + ,#+CAPTION: reference list + |!|title|url|desc|rowid| + | |title|url|desc|rowid| + |-|-----|---|----|-----| + |/| | | | <7> | + |#| | | | | + ,#+TBLFM: $5='(if (and (string= @1$rowid \"rowid\") (string= $rowid \"\")) (concat \"<<\"(org-id-new) \">>\") $rowid) + +- *on Inquiries* +\n\n") + (rapport/doct/append + (doct + `( + ;; General/Personal/Global + ("Tasks" :keys "t" + ;; ,NB: empty string defaults to `org-default-notes-file' + :file "" + :empty-lines-after 1 + :template ("* %{_preface} %? %{_tags}" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:") + :_preface "TODO" + :_tags ":type@task:" + :clock-in t :clock-resume t + :children + (("todo" :keys "t") + ("task" :keys "a" :template ("* %{_preface} %?" ":PROPERTIES:" ":ID: %(org-id-new)" ":CREATED: %U" ":END:" ,org-default-task-body)) + ("habits" :keys "h" + :file "" + :template ("* %{_preface} %? %{_tags}" + "SCHEDULED: %(format-time-string \"<%Y-%m-%d .+1d/3d>\")" + ":PROPERTIES:" + ":STYLE: habit" + ":REPEAT_TO_STATE: TODO" + ":RESET_CHECK_BOXES: t" + ":END:") + :_tags: ":HABIT:"))) + ("Notes" :keys "n" + :file "" + ;; :file ,(expand-file-name (format "journal._%s.org" + ;; (rapport-fn-context-get-label)) + ;; rapport-uri-vault-docs-calendars) + :empty-lines-after 1 + :template ("* %{_preface} %? %{_tags}" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:") + :_preface "" + :_tags ":type@note:" + :clock-in t :clock-resume t + :children + (("Note" :keys "n" + :file "" + ;:datetree t + :clock-in nil :clock-resume nil) + ("Observation a/o Impression (encrypted note to self)" :keys "o" + ;; :file ,(expand-file-name (format "journal._%s.org" + ;; (rapport-fn-context-get-label)) + ;; rapport-uri-vault-docs-calendars) + :_tags ":OBSERVED:crypt:" + ;:datetree t + :_preface "" + :clock-in nil :clock-resume nil) + ("Review (to Inbox for later review)" :keys "r" + :file "" ;; ,NB: Counter to type, REVIEW items go to the Inbox + ;:datetree t + :_preface "REVIEW") + ("Journal" :keys "j" + :template ("* %?\n%U\n") + ;:datetree t + :_tags ":JOURNAL:") + ;; ("Link" :keys "l" + ;; :type plain + ;; :clock-in nil :clock-resume nil + ;; :headline "COMMENT Links" + ;; :template ("\n---\n - %?\n %x\n")) + ("Fact (Org-Drill)" :keys "f" + :file "" ;; ,NB: Counter to type, Fact items go to the Inbox + :empty-lines 1 + :immediate-finish t + :_preface "" + :_tags ":drill:" + :children + (("Unrefined Fact" :keys "0" :olp ("Org-Drill" "Unrefined Fact") :_tags ":drill:docmerge:" :_preface "REPORTED [#E]" + :children + (("Unrefined from Clipboard" :keys "c" + :template ("* %{_preface} Read article: '%:description' %{_tags}" + "URL: %c\n\n")) + ("Unrefined Fact from Web-Browser" :keys "w" + :template ("* %{_preface} Fact: '%:description' %{_tags}" + ":\n:PROPERTIES:\n:DATE_ADDED: %u\n:SOURCE_URL: %c\n:END:\n" + "%i\n%?\n")))) + + ("Directed (Simple) Flashcard" :keys "1" :olp ("Org-Drill" "Directed aka Simple") + :template ("* %^{Question Title|Question} %{_tags}%^G" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:\n" + " %^{Question Text}" + "** %^{Answer Title|Answer}\n %^{Answer Text}")) + ("Symmetric (2-sided) Flashcard" :keys "2" :olp ("Org-Drill" "Symmetric aka 2-Sided") + :template ("* %^{Question Title|Question} %{_tags}%^G" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":DRILL_CARD_TYPE: twosided" + ":CREATED: %U" + ":END:\n" + " %^{Question Text}" + "** %^{First Side - Answer Title}\n %^{First Side - Answer Text}" + "** %^{Second Side - Answer Title}\n %^{Second Side - Answer Text}" + "** %^{Response Companion Title}\n %^{Response Companion Text}")) + ("Polygonal (*-sided) Flashcard" :keys "3" :olp ("Org-Drill" "Polygonal aka Multi-Sided") + :template ("* %^{Question Title} \t%{_tags}%^G" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":DRILL_CARD_TYPE: multisided" + ":CREATED: %U" + ":END:\n" + " %^{Question Text}" + "** %^{First Side - Answer Title}\n %^{First Side - Answer Text}" + "** %^{Second Side - Answer Title}\n %^{Second Side - Answer Text}" + "** %^{Third Side - Answer Title}\n %^{Third Side - Answer Text}")) + + ("Multi-Fill Flashcard" :keys "4" :olp ("Org-Drill" "Cloze aka Fill-In the Blank") + :template ("* %^{Question Title} \t%{_tags}%^G" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":DRILL_CARD_TYPE: %^{DRILL_CARD_TYPE|hide1cloze|show1cloze|hide2cloze|show2cloze}" + ":CREATED: %U" + ":END:\n" + " %^{Question Text}" + "** %^{First Side - Answer Title|Answer 1}\n %^{First Side - Answer Text}" + "** %^{Second Side - Answer Title|Answer 2}\n %^{Second Side - Answer Text}" + "** %^{Third Side - Answer Title|Answer 3}\n %^{Third Side - Answer Text}")) + )))) + + ("Correspondence" :keys "c" + :file "" + ;; :file ,(expand-file-name (format "correspondence._%s.org" + ;; (rapport-fn-context-get-label)) + ;; rapport-uri-vault-docs-calendars) + ;:datetree t + :empty-lines-after 1 + :template ("* %{_preface} %? [/] %{_tags}" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:") + :_tags ":type@correspondence:" + :clock-in t :clock-resume t + :children + (("Meeting" :keys "m" :_preface "MEETING with " :_tags ":MEETING:") + ("Phone Call" :keys "p" :_preface "PHONE" :_tags ":PHONE:") + ("Email" :keys "e" :_preface "EMAIL" :_tags ":EMAIL:") + ("Text Chat" :keys "t" :_preface "TEXT CHAT" :_tags ":TEXTCHAT:") + ("Virtual Meeting (tele-conference)" :keys "v" :_preface "MEETING with " :_tags ":MEETING:VIRTUAL_TELECONF:"))) + ("Schedulings" :keys "s" + :file "" + ;; :file ,(expand-file-name (format "schedule._%s.org" + ;; (rapport-fn-context-get-label)) + ;; rapport-uri-vault-docs-calendars) + :empty-lines-after 1 + :template ("* %{_preface} %? %{_tags}" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:") + :_tags ":type@event:" + :clock-in t :clock-resume t + :children + ;; ,TODO: A point in time should be a Reminder, a span of time should be an Appointment + (("Appointment" :keys "a" + ;; :file "calendars.org" + :template ("* APPT %^{Description} %^g\n%?\nAdded: %U") + :_tags ":APPOINTMENT:" + :headline "Calendar") + ("Calendar (appt/duration)" :keys "c" + ;; :file "journal.org" + ;:datetree t + :_tags ":CALENDAR:" + :template ("* %^{What?}\n%^{start-time}T--%^{end-time}T\n%?")) + ))))) + + :bind + ;; set org-capture to global keychord "C-c c" + ("C-c c" . org-capture) + :commands (doct) + :config + (progn)) + #+end_src + +*** using <<>> [[id:05966BED-01E7-4C21-A2DF-01CB9287D291][[roam]​]] +:PROPERTIES: +:ID: E2C2E4F9-2DF4-4412-B4DC-E008B476B186 +:END: +install Firefox's =org-capture= Add-on + - locate and install the add-on here, https://addons.mozilla.org/en-US/firefox/addon/org-capture/ + - view and configure the =org-capture= template keys to invoke when the button is pressed with text is selected and when the button is pressed with no text selected. + - the add-on is a complete and preferred replacement for the use of JS bookmarklets +install Org-protocol on macOS + - nb + - https://www.ying-ish.com/essay/org-capture-with-firefox/ + - add desktop file + #+begin_src conf +[Desktop Entry] +Name=org-protocol +Exec=emacsclient -t -a '' -n %u +Type=Application +Terminal=false +Categories=System; +MimeType=x-scheme-handler/org-protocol; + #+end_src + + - ensure a suitable EmacsClient "App" is available + #+begin_src conf +on emacsclient(input) + do shell script "/usr/local/bin/emacsclient -n -c '" & input & "'" +end emacsclient + +on open location input + emacsclient(input) +end open location + +on open inputs + repeat with raw_input in inputs + set input to POSIX path of raw_input + emacsclient(input) + end repeat +end open + +on run + do shell script emacsclient("") +end run + #+end_src + - Add + + - Install =pandoc= + #+begin_src bash +brew install pandoc + #+end_src + + - Install and run =desktop-file-utils= to update the =~/.local/share/applications/mimeinfo.cache= + #+begin_src bash +brew install desktop-file-utils && update-desktop-database ~/.local/share/applications/ + #+end_src + + - If succeeded, a file named β€œmimeinfo.cache” will be created or recently updated in this folder. + #+begin_src bash +ls -l ~/.local/share/applications/mimeinfo.cache + #+end_src + +*** using Org-Clocking +:PROPERTIES: +:ID: 304AD080-BD80-4553-ACAA-9476808420DB +:END: +:LOGBOOK: +CLOCK: [2022-10-01 Sat 10:02]--[2022-10-01 Sat 10:27] => 0:25 +:END: + +setup Org Clocking +#+begin_src emacs-lisp +;; org-clocking.el --- org-mode clocking prefs +(use-package emacs + :ensure nil + + :no-require t + :after (org) + :init + (require 'org-clock) + ;; Resume clocking task when emacs is restarted + (org-clock-persistence-insinuate) + :custom + ;; Separate drawers for clocking/log and properties + (org-drawers (quote ("PROPERTIES" "LOGBOOK"))) + ;; Save clock data and state changes and notes in the LOGBOOK drawer + (org-clock-into-drawer t) + ;; keep clocking info in properties, it's tidier looking + (org-log-into-drawer "LOGBOOK") + ;; Adding yet further auditing, this option causes Org to insert + ;; annotations when you change the deadline of a task, which + ;; will note the previous deadline date and when it was + ;; changed. Very useful for figuring out how many times you + ;; β€œkicked the can down the road.” + (org-log-redeadline (quote time)) + ;; This does the same as above, but for the scheduled dates, + ;; which I use more often. + (org-log-reschedule (quote time)) + ;; Include current clocking task in clock reports + (org-clock-report-include-clocking-task t) + ;; track org-mode todo state changes , http://orgmode.org/manual/Tracking-TODO-state-changes. + (org-log-done 't) + + ;; When you perform a text search (the β€œs” selection from the + ;; org-agenda pop-up), include the archives for all of the + ;; files in Org’s agenda files list. If you archive things + ;; regularly, which I do, this helps you dig stuff out of + ;; there when you’re looking for it. + (org-agenda-text-search-extra-files '(agenda-archives)) + + ;; I tend to leave a blank line at the end of the content of + ;; each task entry. This causes Org to automatically place a + ;; blank line before a new heading or plain text list item, + ;; just the way I like it. + (org-blank-before-new-entry (quote ((heading) (plain-list-item)))) + + ;; Clock out when moving task to a done state + (org-clock-out-when-done t) + ;; Resume clocking task on clock-in if the clock is open + (org-clock-in-resume t) + ;; Save the running clock and all clock history when exiting Emacs, load it on startup + (org-clock-persist t) + (org-clock-persist-file (expand-file-name (format "org-clock-save._%s.eld" + (rapport-fn-context-get-label)) + rapport-uri-vault-docs-status)) + + ;; Do not prompt to resume an active clock + (org-clock-persist-query-resume nil) + ;; Enable auto clock resolution for finding open clocks + (org-clock-auto-clock-resolution (quote when-no-clock-is-running)) + ;; prompt if idle for X mins, (disabled when using a Termnal where idle detection isn't support) + ;; - When the clock is running and Emacs is idle for more than this number of minutes, the clock will be clocked out automatically. + ;; - Use β€˜M-x org-clock-toggle-auto-clockout RET’ to temporarily turn this on or off. + ;; - Set 'org-clock-idle-time to 'nil to disable the idle timer, ex. ~(setq org-clock-idle-time nil)!~ + (org-clock-idle-time (when (display-graphic-p) 40)) + ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration + (org-clock-out-remove-zero-time-clocks t) + ;; Show lot of clocking history so it's easy to pick items off the C-F11 list + (org-clock-history-length 36) + ;; default values for Clock Reports + (org-clocktable-defaults + '(:maxlevel 2 :lang "en" :scope file :block nil :wstart 1 :mstart 1 + :tstart nil :tend nil :step nil :stepskip0 t :fileskip0 t + :tags nil :match nil :emphasize nil :link t :narrow 40! + :indent t :filetitle nil :hidefiles t :formula % + :timestamp nil :level nil :tcolumns nil :formatter nil)) + ;; as used w/ Org-Agenda's Clock Report. + ;; ,HINT: All the same options as 'org-clocktable-defaults except for :name, :tstart, :tend, :block, and :scope + (setq org-agenda-clockreport-parameter-plist '( + :lang "en" + :compact t + :emphasize t + :fileskip0 t + :filetitle nil + ;:formula % + :formula "" ; ,TODO: build out a robust set of computed fields a/o columns here + :hidefiles t + :indent nil + ;:level 3 + :link t + :match nil + ;:maxlevel 5 + :narrow 48! + :step day + :stepskip0 t + :sort (1 . ?a) + ;:tags t + ;:tcolumns 5 + ;:timestamp t + :properties ( + ;"PRIORITY" + ;"TODO" + ;"BLOCKED" + ;"ITEM" + ;"ORG_GTD" + "CATEGORY" + "Effort" + ;"DEADLINE" + ;"DELEGATED_TO" + ;"ORG_GTD_TIMESTAMP" + ;"CLOCKSUM" + ;"account" + ;"CREATED" + ;"CLOSED" + ;"SCHEDULED" + ;"allocate" + ;"EXPIRY" + ;"EXPIRED" + ;"MODIFIED" + ;"HASH" + ))) + :config + (progn)) +#+end_src +*** using Org-InlineTask +:PROPERTIES: +:ID: BCF74290-D728-4BC0-A5EB-3CA2C62C7A46 +:END: +setup =org-inlinetask= +#+begin_src emacs-lisp +(use-package emacs + :ensure nil + + :no-require t + :init + (require 'org-inlinetask) + :custom + (org-inlinetask-default-state "TODO") + (org-inlinetask-show-first-star t) + :config + (progn)) +#+end_src + + +*** using Org-Crypt +:PROPERTIES: +:ID: FC53B8C2-3C7C-47A3-8F8C-3DDA501F14E5 +:END: +setup =auth-sources= +#+begin_src emacs-lisp +;; include Emacs built-in integration to Freedesktop.org Secrets systems, (eg. Gnome Keyring, KDE Wallet) +;; - https://www.gnu.org/software/emacs/manual/html_mono/auth.html +(when (or + (eq system-type 'gnu/linux) + ;wip; (eq system-type 'darwin) + ) + (require 'secrets)) + +;; add/register specific authinfo sources +(setq auth-sources (remove 'nil `( + ;; for Rapport + ,(when (file-readable-p (expand-file-name "authinfo.json.gpg" rapport-uri-vault-cfgs-emacs)) + (expand-file-name "authinfo.json.gpg" rapport-uri-vault-cfgs-emacs)) + ,(when (file-readable-p (expand-file-name "authinfo.gpg" rapport-uri-vault-cfgs-emacs)) + (expand-file-name "authinfo.gpg" rapport-uri-vault-cfgs-emacs)) + ,(when (expand-file-name "authinfo.json" rapport-uri-vault-cfgs-emacs) + (expand-file-name "authinfo.json" rapport-uri-vault-cfgs-emacs)) + ,(when (file-readable-p (expand-file-name "authinfo" rapport-uri-vault-cfgs-emacs)) + (expand-file-name "authinfo" rapport-uri-vault-cfgs-emacs)) + + ;; upstream defaults + ,(when (file-readable-p "~/.authinfo") + "~/.authinfo") + ,(when (file-readable-p "~/.authinfo.gpg") + "~/.authinfo.gpg") + ,(when (file-readable-p "~/.netrc") + "~/.netrc") + + ;; integrate with 3rd-party auth-sources + ;default + + ;; The Secret Service API is a + ;; standard from freedesktop.org + ;; to securely store passwords + ;; and other confidential + ;; information. This API is + ;; implemented by system daemons + ;; such as the GNOME Keyring and + ;; the KDE Wallet (these are + ;; GNOME and KDE packages + ;; respectively and should be + ;; available on most modern + ;; GNU/Linux systems). + ,@(when (featurep 'secrets) + '("secrets:Login" + "secrets:session" )) + + ;; ,@(when (eq system-type 'darwin) + ;; '(macos-keychain-internet + ;; macos-keychain-generic)) + ))) +#+end_src + +setup EPA + #+begin_src emacs-lisp +;; If non-nil, cache passphrase for symmetric encryption. The default value is nil. +(setq-default epa-file-cache-passphrase-for-symmetric-encryption t) +;; If non-nil, disable auto-saving when opening an encrypted file. The default value is t. +(setq-default epa-file-inhibit-auto-save t) + +;; https://emacs.stackexchange.com/questions/27841/unable-to-decrypt-gpg-file-using-emacs-but-command-line-gpg-works#comment82263_27870 +(setf epa-pinentry-mode 'loopback) + #+end_src + +setup Org Crypt + #+begin_src emacs-lisp + ;; Org-Crypt + ;; gpg encypt any org-mode headings w/ the 'crypt' tag +(eval-after-load 'org + (lambda () (progn + ;; see http://orgmode.org/worg/org-tutorials/encrypting-files.html + (require 'org-crypt) + (org-crypt-use-before-save-magic) + (setq org-tags-exclude-from-inheritance (quote ( + "type@{.*}" + "crypt" + "task@objective" + "task@project" + ))) + + ;; GPG key to use for encryption + ;; Either the Key ID or set to nil to use symmetric encryption. + ;; #+HINT: allow 'org-crypt-key to be set from customize system + ;(setq org-crypt-key nil) + + ;; add a hook that will encrypt entries before a save is written to disk + (org-crypt-use-before-save-magic) + + ;; explicitly set org-crypt to symmetric + ;(setq epa-file-select-keys nil) + ))) + #+end_src +*** using Org-Export +:PROPERTIES: +:ID: DE553093-688A-4123-9AC0-78200F9D2913 +:END: +setup Org Export + #+begin_src emacs-lisp +(use-package emacs + :ensure nil + + :no-require t + :after org-contrib + :config + ;; activate confluence export, executable as (org-confluence-export-as-confluence) + (add-to-list 'org-export-backends 'confluence) + (require 'ox-confluence) + ;; activate deck.js export + (require 'ox-deck) + + + ;;; post-init + + ;; remove pointless HTML postamble + (setq org-export-html-postamble-format nil) + + + ;; org-mode code-blocks syntax highlighting on html export + (setq org-src-fontify-natively t) + + ;; inhibit org-export interpret subscript and superscript + ;(setq org-export-with-sub-superscripts nil) + + ;; require enclosing braces to mark-up sub- and super-scripts + (setq org-use-sub-superscripts "{}") + + ;;; LaTeX export + + ;; nb, COMMENT sub-trees and lines starting w/ '#' are never exported + + ;; nb, useful LaTeX commands + ;; in-buffer latex preview: C-c C-x C-l (requires installed dvipng /o imagemagik) + ;; remove preview overlay: C-c C-c + ;; insert RefTeX citation: C-c C-x [ + + ;; nb, LaTeX config is based in a '#+LATEX_CLASS:' class type, + ;; modifiable by providing '#+LATEX_CLASS_OPTIONS:' option + ;; directives from there the document structure/formatting is + ;; controlled by '#+LATEX_HEADER:' and '#+LATEX_HEADER_EXTRA:' + ;; (which isn't loaded on preview) directives. At the final + ;; level, '#+LATEX:' permits the insertion of arbitrary LaTeX + ;; commands/snippets + + ;;; ODT Export + ;; requires 'zip' program =sudo aptitude install zip= + ;; + ) + + ;(provide 'load-conf__org-export) + #+end_src +*** using Org-Refile +:PROPERTIES: +:ID: 445C027D-878A-4DA7-A4E3-5DF1A4214368 +:END: +setup Org Refile + #+begin_src emacs-lisp +;;; Org-Refile settings +;; refs: +;; - https://blog.aaronbieber.com/2017/03/19/organizing-notes-with-refile.html +(use-package emacs + :ensure nil + + :no-require t + :custom + ;; Targets include this file and any file contributing to the agenda - up to 9 levels deep + (org-refile-targets '((nil :maxlevel . 9) + (org-agenda-files :maxlevel . 9))) + ;; Include the File in the refile target selection + (org-refile-use-outline-path 'file) + ;; Use full outline paths for refile targets + (org-outline-path-complete-in-steps nil) + ;; Allow refile to create parent tasks with confirmation + (org-refile-allow-creating-parent-nodes 'confirm) + (org-indirect-buffer-display 'current-window) + (org-log-refile 'note) + (org-refile-target-verify-function + #'(lambda () + "Exclude DONE state tasks from refile targets" + (not (member (nth 2 (org-heading-components)) org-done-keywords)))) + :config + (require 'org-refile) + (progn)) + #+end_src +*** using Org as a Habit Tracker using <<>> +:PROPERTIES: +:ID: 179AC9A0-D7C0-4F0D-9C34-0EDE9C7AFF8F +:END: + + #+begin_src emacs-lisp +;; Org-Habit Config +;; - ref: https://orgmode.org/manual/Tracking-your-habits.html +(eval-after-load 'org + (lambda () + (progn + (setq-default org-habit-preceding-days 13) + (setq-default org-habit-following-days 2) + (setq-default org-habit-graph-column 63) + (require 'org-habit)))) + #+end_src +*** using Org Columns +:PROPERTIES: +:ID: 0A0CF1D1-1010-40C9-899A-3F2CBC30C1BB +:END: +:LOGBOOK: +CLOCK: [2022-06-05 Sun 12:41]--[2022-06-05 Sun 13:03] => 0:22 +:END: +setup Org Columns + #+begin_src emacs-lisp +;; setup org-columns +(with-eval-after-load 'org + ;; Change 20240228T1400_NGa seeks to integrate Org-GTD, WBS/Billing, and RACI matrix info + (setq org-columns-default-format (concat + " %1PRIORITY %4TODO(STATE) %1BLOCKED(B)" + " %48ITEM(TaskDesc) %7ORG_GTD(Type) %12CATEGORY(AoF)" + " %8Effort(ETC){+}" + " %13DEADLINE(DUE)" + " %5DELEGATED_TO(Del.)" + " %ORG_GTD_TIMESTAMP(CheckIn)" + " %8CLOCKSUM(WRKD){est+} %8account(CostCntr)" + " %13CREATED" + " %13CLOSED" + " %13SCHEDULED(START)" + " %allocate(RSRC_ALLOC)" + ;; ,HINT: Works correctly but temporarily muted + " %13EXPIRES" + " %1EXPIRED(X)" + " %13MODIFIED" + " %HASH" + ; " %TAGS" + ; " %FILE" + ; " %CLOCKSUM{est+} %CLOCKSUM %CLOCKSUM_T" + ;; ,WIP: desired but not yet setup + ; - a way to show certain types of tags, like Composure Activity Types + ;; ,WIP: ideas w/ computed properties + ; " num of work days in the span between START and FINISH" + ; " num of remaining work days in the span between START and FINISH" + ; " percent of remaining work span" + ;; ,WIP: Interesting but possibly invalid + ; " %{X%}" + ; " %CHECKBOX{X%}" + ; " %1Approved(A){X}" + ; " %provide@utilization#work@delta(UTL?){X%}" + ; " %8provide(Provide)" + ; " %require(RSRC_REQST)" + )) + (progn)) + #+end_src +*** using Block Templates +:PROPERTIES: +:ID: C36AEF07-5F43-4EFB-96B9-00D1FE985323 +:END: + +These templates enable you to type things like =>> +:PROPERTIES: +:ID: E37F9B34-D361-47BF-95D2-8CB85E0E8F7F +:END: +It's nice to have a table of contents section for long literate +configuration files (like this one!) so I use =org-make-toc= to +automatically update the TOC in any header with a property named =TOC=. + +setup =org-make-toc= + #+begin_src emacs-lisp + (use-package org-make-toc + :disabled ;; 20210131_NGa disabled, implicated in redifining 'org-version from my custom definition + :after (:all org) + ;:hook (org-mode . org-make-toc-mode) ;; uncomment to auto-enable + :config + (progn)) + #+end_src + +*** using Org-Pomodoro +:PROPERTIES: +:ID: 9C7D8CD4-ADDF-4631-8ED8-41A667B70B31 +:END: +#+begin_src emacs-lisp + ;; + (use-package org-pomodoro + :after org + :config + (setq org-pomodoro-start-sound "~/.emacs.d/sounds/focus_bell.wav") + (setq org-pomodoro-short-break-sound "~/.emacs.d/sounds/three_beeps.wav") + (setq org-pomodoro-long-break-sound "~/.emacs.d/sounds/three_beeps.wav") + (setq org-pomodoro-finished-sound "~/.emacs.d/sounds/meditation_bell.wav")) +#+end_src + +*** enable Git-Link in Org +:PROPERTIES: +:ID: A598A6EE-7B85-4393-B646-155086EC1639 +:END: +setup =git-link= + #+begin_src emacs-lisp + (use-package git-link + :commands git-link + :config + (setq git-link-open-in-browser t)) + #+end_src + +*** Misc Org Features and Configs +:PROPERTIES: +:ID: 931FBF77-DD25-48FA-B603-8AE1A5C095CE +:END: +setup Org Miscellaneous a/o Supplimental Features + + - visual presentation + #+begin_src emacs-lisp + (setq org-ellipsis " β–Ύ") + ;(setq org-hide-emphasis-markers t) + (setq org-src-fontify-natively t) + (setq org-src-tab-acts-natively t) + (setq org-edit-src-content-indentation 2) + (setq org-hide-block-startup nil) + (setq org-startup-folded 'content) + (setq org-cycle-separator-lines 2) + #+end_src + + - miscellaneous + #+begin_src emacs-lisp +(delight 'org) +(delight 'helpful) +(delight 'org-indent-mode) +(org-indent-mode 1) + #+end_src + +*** enable feature :noexport: +:PROPERTIES: +:ID: CAA8FDE4-AAAE-49DE-B248-0EC62AD026D9 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-editors-org) +#+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: 5C6A727B-8E16-4EAE-BB6D-9EFA2D18E398 +:END: +#+begin_src emacs-lisp +(require 'rapport-editors-sysnav) +(require 'rapport-editors-switchboard) +(require 'rapport-editors-text) +(require 'rapport-editors-humans) +(require 'rapport-editors-swdev) +(require 'rapport-editors-data) +(require 'rapport-editors-data2viz) +(require 'rapport-editors-infradev) +(require 'rapport-editors-org) + +;; +(elpaca-wait) +(provide 'rapport-editors) +#+end_src + +* /Chapter/ *2*, Endeavors :export:provide@rapport_endeavors#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +Efforts and Assets + +** as Solution and Asset Development Forges :provide@endeavors_forges#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-forges.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** support Git w/ Magit +:PROPERTIES: +:ID: 1B2355EF-AAE6-4EB0-99C6-293540E472A3 +:END: +:LOGBOOK: +- Refiled on [2022-08-16 Tue 18:01] +:END: + +setup Magit + #+begin_src emacs-lisp +;; use Git w/i Emacs (req's Emacs v24.4+ and Git v1.9+) +;;(require 'load-mode__magit) ; [2018-05-08] EM: "Error (use-package): Cannot load" + ;;; + ;;; Magit - emacs interface to git + ;;; + + ;;; DESCRIPTION +;; To successfully build magit's next@{2014-11-08} a file, called +;; with-editor.el, from git-modes's next@{2014-11-08} is required. +;; +;; ex. +;; cd ~/.emacs.d/mnt/magit && emacs -Q --batch -L . -L ../git-modes/. -L ../dash.el/. -f batch-byte-compile *.el + + +;; Instruction +;; install: =make && sudo make install=, compiles to [[/usr/local/share/emacs/site-lisp]] where Emacs will detect it. +;; init: (magit-status) or M-x magit-status + + +(use-package git-modes + :after (dash with-editor gitattributes-mode) + :config + (and + ;(use-package with-editor) + ;(use-package gitattributes-mode) + (require 'gitconfig-mode) + (require 'gitignore-mode) + (require 'git-rebase))) + + +(use-package magit + :bind ( + ("C-c g" . magit-status) + :map project-prefix-map + ("m" . magit-status)) + :commands (magit-status magit magit-get-current-branch) + :hook (dash git-modes) + :custom + (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1) + :config + (progn + (setq magit-last-seen-setup-instructions "1.4.0") + (setq magit-auto-revert-mode t))) + + + ;;; extensions: +;;(require 'magit-svn) ;;integrates with git-svn. Hit 'N' to see your options. +;;(require 'magit-topgit) ;;integrates with topgit. +;;(require 'magit-stgit) ;;integrates with StGit. + +;; bundle for git-annex enablements +(use-package git-annex + :if (executable-find "git-annex")) + +;; dired-git-annex.el - enhance Dired w/ git-annex support + +;; Magit Annex - magit support to git-annex +(use-package magit-annex :after (:all magit git-annex)) + +;; +(use-package hl-todo) +(use-package magit-todos + :after (:all magit hl-todo) + :commands (magit-todos-list) + :hook (magit-mode) + :config + (magit-todos-mode t)) + +;; +(use-package forge + ;; ,LOG: 20200528_NGa disabled to quell EM from windows + :if (executable-find "sqlite3") + :after (magit) + :config (progn)) + +(use-package git-identity) + #+end_src + +setup Multi-Repo Management using + #+begin_src emacs-lisp +;; https://github.com/luismbo/multi-magit + +(use-package multi-magit + :ensure (multi-magit :type git :host github :repo "luismbo/multi-magit" :files ("*.el")) + :bind (("C-c G" . multi-magit-status)) + :custom + ;; multi-magit-selected-repositories + (multi-magit-selected-repositories (mapcar 'cdr (multi-magit--all-repositories))) + (magit-repository-directory-depth 1) + ;; NB, this variable has a fit when given smylinks + (magit-repository-directories + `((,rapport-uri-rapport . 0) + ,(cons (file-truename rapport-uri-vault-uris) 1) + ,(cons (file-truename (expand-file-name "extrefs" rapport-uri-vault-uris)) 1))) + :config + (progn)) + #+end_src + +*** enable Per-Directory [[https://direnv.net/][direnv]] Config w/ <<>> :pending_review:feature_preview: +:PROPERTIES: +:ID: 4DF54D1A-79D9-4D18-828D-66E423599EAF +:END: + + #+begin_src emacs-lisp +(use-package envrc + :config + (envrc-global-mode t) + (progn)) + #+end_src +*** COMMENT Makefile Support via taskrunner :risk@upstream_unmaintained:pending_review: +:PROPERTIES: +:ID: C8C8B808-CA48-42BF-A5EE-AD571B6044DE +:END: + setup =taskrunner= + + #+begin_src emacs-lisp + ;; + (use-package async) + (use-package taskrunner + :after (:all async) + :ensure (taskrunner :type git :host github + :repo "emacs-taskrunner/emacs-taskrunner" + :files ("*.el") + :branch "master")) + #+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: F345AC1A-1237-44EF-9D29-1A1CB03FCF09 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-forges) +#+end_src + +** as Project Workspace Context Mgmt and Enablement Workbench :provide@endeavors_workspaces#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-workspaces.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +- on Concepts and Contributory Tools + #+CAPTION: Concepts and Contributory Tools + | | workflow | projects | + |------------+----------+----------| + | tab-bar | | | + | project.el | | | + | Tabspaces | | | + +- on Context and Flow + +- on Using Tabspaces + - Tabspaces combines project.el and tab-bar to provide an ergonomic, per-project workspace. + +- on Keybindings and Adaptations + | kbd | object/concept | pkg | desc | originally | adapted | why? | impl? | + |-------------+----------------+--------------------+------+------------+---------+-------------------------------------------------------+--------------------------| + | =C-x b= | buffer | consult, tabspaces | | | | shows buffers in the current project | =consult-project-buffer= | + | =C-x p= | project | project.el | | | | | | + | =C-u C-x b= | buffers | | | | | shows all buffers (across any project) | =switch-to-buffer= | + | =C-x B= | buffers | | | | | shows all buffers in perspective organized by project | | + | =M-p= | window | | | | | | | + | =M-P= | frame | | | | | | | + | =C-x x= | domain | workflow | | | | | | + | =C-c C-]= | workspace | | | | | | | + + +*** Context-local Functionality w/ <<>> +:PROPERTIES: +:ID: FD1A3F4D-ACBD-466F-AA5D-E2F4DEF1219F +:END: + +Project.el is a Project Interaction Library for Emacs +(documentation: [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Projects.html][online]]) + + #+begin_src emacs-lisp +;; 'project.el' is built-into Emacs. Still, we'll request a latest/specific version via Straight +(use-package project + ;; ,NB: the 'consult project and the 'tabspaces project are used to integrate with and extend 'project + :demand + :preface + (defun rapport/affe-find/-in-project () "" (interactive) (affe-find (project-root (project-current t)))) + (defun rapport/affe-grep/-in-project () "" (interactive) (affe-grep (project-root (project-current t)))) + ;;;;;; WIP ;;;;;; + (defun rapport/project/-refresh-project-list () "" (interactive)) ;; WARN: UNIMPLEMENTED + ;; (async-start + ;; (lambda () + ;; (progn + ;; (message " (rapport) updating project list ... ") + ;; (require 'project) + ;; ;; ,NB: I'd like to use 'rapport-uri-vault-uris (in place of "~/.uris") but it seems to be unavailable in the async execution context + ;; (dolist (iter `( + ;; ,(when (bound-and-true-p project-known-project-roots) project-known-project-roots) + + ;; ,(directory-files rapport-uri-vault-uris nil "^_worktree\.-\..*$") ;; ,HINT: list all '_worktree' prefixed directories + + ;; ,(directory-files rapport-uri-vault-uris nil "^[^_.].*$") ;; ,HINT: list all non-underscore prefixed directories + + ;; ;; ,(directory-files-recursively rapport-uri-vault-uris "^_.*$" t + ;; ;; #'(lambda (x) (and + ;; ;; (bound-and-true-p x) + ;; ;; (file-directory-p x) + ;; ;; (file-readable-p x))) + ;; ;; t) + + ;; ;,(project-remember-projects-under (or rapport-uri-vault-uris (expand-file-name "~/.uris")) t) ;; ,HINT: the recursive one + ;; ) ;; end-of-list + ;; results) + ;; ;; ,HINT: start-loop-body + + + ;; ;; ,HINT: check each project-uri entry for validity + + + ;; (progn + ;; (with-temp-buffer + ;; (insert-file-contents project-list-file project-remember-projects-under lt-uris (expand-file-name "~/.uris")) nil)) + ;; (message (format-string "%s" iter)) + + + ;; (setq results (append results iter)) + ;; ) ;; ,HINT: end-loop-form + ;; results + ;; ) ;; ,HINT: end-lambda-form + ;; (sleep-for 1) + ;; (project-forget-zombie-projects) + ;; (message " (rapport) updating project list ... [async::started]"))) + ;; (lambda () + ;; (message " (rapport) updating project list ... [async::finished]")))) + ;;;;;;; ;;;;;; + :custom + (project-list-file (expand-file-name (format "listing._%s.project.eld" (rapport-fn-context-get-label)) (expand-file-name "project" rapport-uri-vault-cfgs-emacs-apps))) + (project-switch-use-entire-map t) + :commands (project-switch-project) + :bind + (:map project-prefix-map + ("b" . consult-project-buffer) + ("m" . magit-status) + ("\'" . vterm-toggle) + ("x" . project-execute-extended-command) + ("f" . project-find-file) + ("d" . project-find-dir) + ("v" . project-vc-dir) + ("!" . project-shell-command) + ("&" . project-async-shell-command) + ("c" . project-compile) + ("M-s f" . rapport/affe-find/-in-project) + ("M-s g" . rapport/affe-grep/-in-project) + ("M-," . tab-bar-rename-tab) + ;; add project.el convenience keybinds + ("# #" . rapport/project/-refresh-project-list) ; ,HINT: rediscover projects under "~/.uris" + ("# +" . project-remember-project) + ("# -" . project-forget-project) + ;; end-of-list + ) + + :config + ;; add projects under "~/.uris" on start + (project-remember-projects-under rapport-uri-vault-uris nil) + (project-forget-zombie-projects) + ;; create project list file if it doesn't exist + (unless (file-exists-p project-list-file) + (with-temp-file project-file-file)) + (progn)) + #+end_src + +*info/notes* +- on Getting Started + - Just open some file in a version-controlled (e.g. git) or a project (e.g. maven) directory that's recognized by Project.el and you're ready for action. Project.el happens to recognize out of the box every common VCS and many popular project types for various programming languages. You can learn more about Project.el's notion of a project here. + - The extend of the support for every VCS differs and Git is the best supported one. Project.el supports some advanced features like working with Git submodules and using git-grep instead GNU grep. + - You need to know only a handful of Project.el commands to start benefiting from it. + - Project.el default key prefix is =C-x p= + - The file at path =project-list-file= contains a listing of known projects by path. + +- on Commands + | Keybinding | Action | operates-on | Description | | + |--------------------+------------------------------+-------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+---| + | C-x p p | project-switch-project | | | | + | | project-forget-project | | | | + | C-x p f | project-find-file | files | is a convenient way of visiting files (see Visiting Files) that belong to the current project. Unlike C-x C-f, this command doesn’t require to type the full file name of the file to visit, you can type only the file’s base name (i.e., omit the leading directories). In addition, the completion candidates considered by the command include only the files belonging to the current project, and nothing else. If there’s a file name at point, this command offers that file as the first element of the β€œfuture history”. | | + | C-x p g | project-find-regexp | files | is similar to rgrep (see Searching with Grep under Emacs), but it searches only the files that belong to the current project. The command prompts for the regular expression to search, and pops up an Xref mode buffer with the search results, where you can select a match using the Xref mode commands (see Commands Available in the *xref* Buffer). When invoked with a prefix argument, this command additionally prompts for the base directory from which to start the search; this allows, for example, to limit the search only to project files under a certain subdirectory of the project root. The way this command displays the matches is affected by the value of xref-auto-jump-to-first-xref (see Searching and Replacing with Identifiers). | | + | M-x project-search | | files | is a sequential variant of project-find-regexp. It prompts for a regular expression to search in the current project’s files, but instead of finding all the matches and displaying them, it stops when it finds a match and visits the matched file at the locus of the match, allowing you to edit the matched file. To find the rest of the matches, type M-x fileloop-continue RET. | | + | C-x p r | project-query-replace-regexp | files | is similar to project-search, but it prompts you for whether to replace each match it finds, like query-replace does (see Query Replace), and continues to the next match after you respond. If your response causes Emacs to exit the query-replace loop, you can later continue with M-x fileloop-continue RET. | | + | C-x p d | project-find-dir | files | prompts you to choose a directory inside the current project, with completion. And opens a Dired buffer (see Dired, the Directory Editor) listing the files in it. | | + | C-x p D | project-dired | files | opens a Dired buffer (see Dired, the Directory Editor) listing the files in the current project’s root directory. | | + | C-x p v | project-vc-dir | files | opens a VC Directory buffer (see VC Directory Mode) listing the version control statuses of the files in a directory tree under the current project’s root directory. | | + | C-x p s | project-shell | files | starts a shell session (see Running Shell Commands from Emacs) in a new buffer with the current project’s root as the working directory. | | + | C-x p e | project-eshell | files | starts an Eshell session in a new buffer with the current project’s root as the working directory. See Eshell in Eshell: The Emacs Shell. | | + | C-x p c | project-compile | files | runs compilation (see Running Compilations under Emacs) in the current project’s root directory. | | + | C-x p ! | project-shell-command | files | runs shell-command in the current project’s root directory. | | + | C-x p & | project-async-shell-command | files | runs async-shell-command in the current project’s root directory. | | + | C-x p b | project-switch-to-buffer | buffers | Switch to another buffer belonging to the current project. | | + | C-x p k | project-kill-buffers | buffers | Kill all live buffers that belong to the current project. | | + + Emacs provides commands for handling project files conveniently. This subsection describes these commands. + + All of the commands described here share the notion of the current project. The current project is determined by the default-directory (see File Names) of the buffer that is the current buffer when the command is invoked. If that directory doesn’t seem to belong to a recognizable project, these commands prompt you for the project directory. +**** extend Project.el +***** COMMENT Nameframe Project :pending_review:feature_preview: +#+begin_src emacs-lisp + ;; ,ref: https://github.com/buzztaiki/project-rootfile.el + (use-package nameframe-project) +#+end_src +***** Dashboard Project Status :feature_preview: +:PROPERTIES: +:ID: 9E18BE35-148D-4B2E-A4F6-2652812C2B75 +:END: +Display a git project’s status in a dashboard widget. +If magit is installed, a link to the project in magit will be provided as well. +#+begin_src emacs-lisp +;; ,ref: https://github.com/functionreturnfunction/dashboard-project-status +(use-package dashboard-project-status) + +#+end_src + +*** Workspace Context Management with <<>> :feature_preview: +:PROPERTIES: +:ID: EF82FD6C-BCBF-4FB8-80F0-4777F479F10A +:END: + #+begin_src emacs-lisp +(use-package tabspaces + ;; https://github.com/mclear-tools/tabspaces + :init + (setq tabspaces-default-tab "_") + (setq tabspaces-keymap-prefix "C-c C-]") ;; Keymap for tabspace/workspace commands after `tabspaces-keymap-prefix'. + ;; + (defun rapport/tabspaces/-with-consult () + "Deactivate isolated buffers when not using tabspaces." + (require 'consult) + (cond (tabspaces-mode + ;; hide full buffer list (still available with "b") + (consult-customize consult--source-buffer :hidden t :default nil) + (add-to-list 'consult-buffer-sources 'consult--source-workspace)) + (t + ;; reset consult-buffer to show all buffers + (consult-customize consult--source-buffer :hidden nil :default t) + (setq consult-buffer-sources (remove #'consult--source-workspace consult-buffer-sources))))) + (defun rapport/tabspaces/-save-and-detach () "" + (interactive) + (tabspaces-save-current-project-session) + (tabspaces-close-workspace)) + :after (:all consult project) + :demand + :hook ( + ;(after-init . tabspaces-mode) + (elpaca-after-init . tabspaces-mode) + (tabspaces-mode . + (rapport/tabspaces/-startup-config + rapport/tabspaces/-with-consult))) + :commands ( + tabspaces-clear-buffers + tabspaces-close-workspace + tabspaces-kill-buffers-close-workspace + tabspaces-open-or-create-project-and-workspace + tabspaces-remove-current-buffer + tabspaces-remove-selected-buffer + tabspaces-reset-buffer-list + tabspaces-restore-session + tabspaces-save-session + tabspaces-switch-or-create-workspace + tabspaces-switch-to-buffer + ) + :bind-keymap ("C-c C-]" . tabspaces-command-map) + :bind + (:map project-prefix-map + ("p" . tabspaces-switch-or-create-workspace) + ("C-p" . tab-bar-switch-to-recent-tab) + ("C-\'" . tabspaces-open-or-create-project-and-workspace) + ("\"" . tabspaces-open-or-create-project-and-workspace) + ("B" . tabspaces-switch-buffer-and-tab) + ("k" . tabspaces-remove-current-buffer) + ("M-d" . #'rapport/tabspaces/-save-and-detach) + ("M-r" . tabspaces-reset-buffer-list) + ("C-k" . tabspaces-kill-buffers-close-workspace) + ;("C" . tabspaces-clear-buffers) + + ;; tabspaces-remove-current-buffer + ;; tabspaces-remove-selected-buffer + ;; tabspaces-reset-buffer-list + ;; tabspaces-restore-session + ;; tabspaces-save-session + ;; tabspaces-switch-or-create-workspace + ;; tabspaces-save-current-project-session + :map tabspaces-command-map + ;; "Keymap for tabspace/workspace commands after `tabspaces-keymap-prefix'." +; ("b" . tabspaces-switch-to-buffer) +; ("B" . tabspaces-switch-buffer-and-tab) + ("k" . tabspaces-remove-current-buffer) + ("C-k" . tabspaces-close-workspace) + ("C-K" . tabspaces-kill-buffers-close-workspace) + ("C-," . tab-bar-rename-tab) + ("\'" . vterm-toggle) + ("C-\'" . tabspaces-switch-or-create-workspace) + ("\"" . tabspaces-open-or-create-project-and-workspace) + ;("d" . tabspaces-remove-current-buffer) + ;("R" . tabspaces-remove-selected-buffer) + ;; ,HINT: Tab-Bar integrations + ("C-]" . tab-bar-switch-to-recent-tab) + ("C-n" . tab-bar-switch-to-next-tab) + ("C-p" . tab-bar-switch-to-prev-tab) + ;; ,HINT: Project.el integrations + ("x" . project-execute-extended-command) + ("f" . project-find-file) + ("d" . project-find-dir) + ("v" . project-vc-dir) + ("!" . project-shell-command) + ("&" . project-async-shell-command) + ("C-c" . project-compile) + ("C-r" . project-query-replace-regexp) + ("C-s f" . rapport/affe-find/-in-project) + ("C-s g" . rapport/affe-grep/-in-project) + ;; add project.el convenience keybinds + ("# #" . rapport/project/-refresh-project-list) ; ,HINT: rediscover projects under "~/.uris" + ("# +" . project-remember-project) + ("# -" . project-forget-project) + ;; add Desktop-Save-Mode convenience keybinds + ("# s" . tabspaces-save-session) + ("# r" . tabspaces-restore-session) + ;; end-of-list + ) + ;; + :custom + (tabspaces-default-tab "_") + (tabspaces-use-filtered-buffers-as-default t) + (tabspaces-remove-to-default t) + (tabspaces-include-buffers '("*scratch*" "*Messages*" "*dashboard*")) + ;; session save and restore + (tabspaces-session t) + ;(tabspaces-session-auto-restore t) + (tabspaces-session-file (expand-file-name (format "%s.sessions.eld" (rapport-fn-context-get-label)) (expand-file-name "tabspaces" no-littering-var-directory))) + ;; + (tabspaces-todo-file-name ".status/notes.org") + (tabspaces-initialize-project-with-todo nil) + :config + ;; + ;; Filter Buffers for Consult-Buffer + +(with-eval-after-load 'consult +;; hide full buffer list (still available with "b" prefix) +(consult-customize consult--source-buffer :hidden t :default nil) +;; set consult-workspace buffer list +(defvar consult--source-workspace + (list :name "Workspace Buffers" + :narrow ?w + :history 'buffer-name-history + :category 'buffer + :state #'consult--buffer-state + :default t + :items (lambda () (consult--buffer-query + :predicate #'tabspaces--local-buffer-p + :sort 'visibility + :as #'buffer-name))) + + "Set workspace buffer list for consult-buffer.") +(add-to-list 'consult-buffer-sources 'consult--source-workspace)) +;; Create the tabspaces-session-file if tabspaces-session is enable and if the file doesn't already exist + (and tabspaces-session + (not (file-exists-p tabspaces-session-file)) + (with-temp-buffer (write-file tabspaces-session-file))) + ;; + + ;; + (defun rapport/tabspaces/-startup-config () + "Initial Tabspace Configuration at Startup." + ;; Add *Messages* and *splash* to initial Tab + (when tabspaces-mode + (progn + (tab-bar-rename-tab tabspaces-default-tab) + (when (get-buffer "*Messages*") + (set-frame-parameter nil + 'buffer-list + (cons (get-buffer "*Messages*") + (frame-parameter nil 'buffer-list)))) + (when (get-buffer "*splash*") + (set-frame-parameter nil + 'buffer-list + (cons (get-buffer "*splash*") + (frame-parameter nil 'buffer-list))))))) + + ;; Filter Buffers for Consult-Buffer + (with-eval-after-load 'consult + ;; hide full buffer list (still available with "b" prefix) + (consult-customize consult--source-buffer :hidden t :default nil) + ;; set consult-workspace buffer list + (defvar consult--source-workspace + (list :name "Workspace Buffers" + :narrow ?w + :history 'buffer-name-history + :category 'buffer + :state #'consult--buffer-state + :default t + :items (lambda () (consult--buffer-query + :predicate #'tabspaces--local-buffer-p + :sort 'visibility + :as #'buffer-name))) + "Set workspace buffer list for consult-buffer.") + (add-to-list 'consult-buffer-sources 'consult--source-workspace)) + (progn)) + #+end_src +*** Treemacs +:PROPERTIES: +:ID: 984D1368-A7D7-4765-85F4-426C1665E845 +:END: +:LOGBOOK: +- Refiled on [2022-08-01 Mon 23:59] +:END: +setup =treemacs= + #+begin_src emacs-lisp + ;;; Treemacs - a tree layout file explorer for Emacs + + (use-package treemacs + :init + (with-eval-after-load 'winum + (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) + :custom + (treemacs-text-scale -1) ;; set the treemacs font size to be slightly smaller for compactness + :bind + (:map global-map + ("M-0" . treemacs-select-window) + ("C-x t 1" . treemacs-delete-other-windows) + ("C-c C-" . treemacs) + ("C-x t t" . treemacs) + ("C-x t B" . treemacs-bookmark) + ("C-x t C-t" . treemacs-find-file) + ("C-x t M-t" . treemacs-find-tag) + :map treemacs-mode-map + ("M-0" . treemacs-quit) + ("C-x o" . treemacs-visit-node-ace) + ) + :config + (setq treemacs-collapse-dirs (if (executable-find "python3") 3 0) + ;; treemacs-deferred-git-apply-delay 0.5 + ;; treemacs-display-in-side-window t + treemacs-eldoc-display t + ;; treemacs-file-event-delay 5000 + ;; treemacs-file-follow-delay 0.2 + ;; treemacs-follow-after-init t + ;; treemacs-git-command-pipe "" + ;; treemacs-goto-tag-strategy 'refetch-index + ;; treemacs-indentation 2 + ;; treemacs-indentation-string " " + ;; treemacs-is-never-other-window nil + ;; treemacs-max-git-entries 5000 + treemacs-missing-project-action 'ask + ;; treemacs-no-png-images nil + ;; treemacs-no-delete-other-windows t + treemacs-project-follow-cleanup t ;; (default: nil) + treemacs-persist-file (expand-file-name "persist.el" (expand-file-name "treemacs" no-littering-etc-directory)) + ;; treemacs-recenter-distance 0.1 + ;; treemacs-recenter-after-file-follow nil + ;; treemacs-recenter-after-tag-follow nil + ;; treemacs-recenter-after-project-jump 'always + ;; treemacs-recenter-after-project-expand 'on-distance + treemacs-show-cursor t + ;; treemacs-show-hidden-files t + ;; treemacs-silent-filewatch nil + ;; treemacs-silent-refresh nil + ;; treemacs-sorting 'alphabetic-desc + ;; treemacs-space-between-root-nodes t + treemacs-tag-follow-cleanup t + treemacs-tag-follow-delay 1.5 + treemacs-width 25 + ;; end of 'setq + ) + + (treemacs-follow-mode t) + (treemacs-project-follow-mode t) + (treemacs-filewatch-mode t) + (treemacs-fringe-indicator-mode t) + (treemacs-git-commit-diff-mode t) + (treemacs-tag-follow-mode t) + + (pcase (cons (not (null (executable-find "git"))) + (not (null (executable-find "python3")))) + (`(t . t) + (treemacs-git-mode 'deferred)) + (`(t . _) + (treemacs-git-mode 'simple))) + + (progn)) + + + #+end_src +**** setup Treemacs Extensions +***** Treemacs + Dired Icons +:PROPERTIES: +:ID: A20BD161-B7C3-407D-BB55-C08A29C592E9 +:END: + #+begin_src emacs-lisp +(use-package treemacs-icons-dired + :after (:all treemacs dired) + :config (treemacs-icons-dired-mode)) + #+end_src +***** Treemacs + Magit +:PROPERTIES: +:ID: E3E34C3A-6C19-43AE-B086-EA585FCFA7F5 +:END: + #+begin_src emacs-lisp +(use-package treemacs-magit + :after (:all treemacs magit)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 25E018A5-C9BC-4663-BB7F-ACDD2A6A99EA +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-workspaces) +#+end_src +** as Tasks and Time Tracker :provide@endeavors_tasks#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-tasks.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** COMMENT Task Expiry using <<>> :under_review:feature_preview: +:PROPERTIES: +:ID: 9B7E73CF-2689-41A5-AB61-AEC7C3892054 +:END: + #+begin_src emacs-lisp + (use-package org-expiry + :after (:all org-contrib) + :ensure (org-contrib :main "lisp/org-expiry.el") + :functions + (org-expiry-insinuate) + :hook + ((org-mode . org-expiry-insinuate)) + :config + (require 'org-expiry) + (progn)) + #+end_src +*** Task Dependency Mgmt using <<>> :feature_preview: +:PROPERTIES: +:ID: 00B6DC51-990D-4336-A1DB-249B0B3A46AB +:END: +EDNA is Org's Extensible Dependency 'N Actions system + + #+begin_src emacs-lisp +;; http://www.nongnu.org/org-edna-el/ +(use-package org-edna + :custom + ;; Max age in seconds before a cache entry is flushed. (default: 300) + (org-edna-finder-cache-timeout (* 60 60 24 7 8)) ;; 4838400 secs == 8 weeks + ;; Enable finder cache for performance improvements. (default: nil) + (org-edna-finder-use-cache t) + ;; Category of TODO states that allow EDNA to run. (default: 'todo) + (org-edna-from-todo-states 'todo) ;; opts: 'todo 'not-done + ;; Enable Inheritance for BLOCKER and TRIGGER properties. (default: nil) + (org-edna-use-inheritance nil) ;; opts: 'nil 't + :config + (org-edna-mode 't) + (progn)) + #+end_src +*** COMMENT Process inputs as Work Queues using <<>> :pending_development:feature_preview: + #+begin_src emacs-lisp +(use-package el-secretario) + #+end_src + +*** Personal Productivity System using <<>> +:PROPERTIES: +:ID: 12FFF2A6-D9E6-4228-8EB3-58869E7FEF8A +:END: + + - setup from https://github.com/Trevoke/org-gtd.el + #+begin_src emacs-lisp +(use-package org-gtd + ;; ,HINT: GTD workflow order goes ... Capture, Process, Clarify, Organize, Engage, Reflect (aka Review) + :demand t + :init + (setq org-gtd-update-ack "3.0.0") + ; (require 'org-gtd) ;; 20230708_NGa this may be an odd approach but with this package in a distinct file it seems safe and practical + (setq org-gtd-inbox (file-name-base org-default-notes-file)) + (setq org-gtd-default-file-name (format "_GTD_SYSTEM._%s.org" (rapport-fn-context-get-label))) + (setq org-gtd-horizons-file (format "_GTD_HORIZONS._%s.org" (rapport-fn-context-get-label))) + (setq org-gtd-archive-file-format (format "_GTD_ARCHIVE_y%%s._%s.org_archive" (rapport-fn-context-get-label))) + :commands ( + org-gtd-capture + org-gtd-calendar + org-gtd-calendar-create + org-gtd-clarify + org-gtd-clarify-item + org-gtd-clarify-agenda-item + org-gtd-clarify-inbox-item + org-gtd-clarify-mode + org-gtd-delegate + org-gtd-delegate-agenda-item + org-gtd-delegate-create + org-gtd-engage + org-gtd-engage-grouped-by-context + org-gtd-engage + org-gtd-habit + org-gtd-habit-create + org-gtd-id-get-create + org-gtd-incubate + org-gtd-incubate-create + org-gtd-knowledge + org-gtd-oops + org-gtd-organize + + org-gtd-process-inbox + org-gtd-project-cancel + org-gtd-project-extend + org-gtd-project-new + + org-gtd-quick-action + + org-gtd-review-area-of-focus + org-gtd-review-missed-items + org-gtd-show-all-next + org-gtd-set-areas-of-focus + org-gtd-single-action + + org-gtd-trash + with-org-gtd-capture + with-org-gtd-context + ) + :bind + (("C-c C-. c" . org-gtd-capture) + ("C-c C-. e" . org-gtd-engage) + ("C-c C-. p" . org-gtd-process-inbox) + ("C-c C-. n" . org-gtd-show-all-next) + ("C-c C-. s" . org-gtd-show-stuck-projects) + :map org-gtd-clarify-map + ("C-c C-. ." . org-gtd-organize) + ) + :custom + ;; Mapping terminology from Rapport to GTD ;; + (org-gtd-projects "Objectives") ;; default, "Projects" + (org-gtd-habit "Practices") + (org-gtd-calendar "Calendar") + (org-gtd-action "Actions") + (org-gtd-incubate "Incubate") + + ;; file and path names ;; + (org-gtd-directory (expand-file-name "tasks" rapport-uri-vault-docs)) + (org-gtd-inbox (file-name-base org-default-notes-file)) + (org-gtd-default-file-name (format "_GTD_SYSTEM._%s.org" (rapport-fn-context-get-label))) + (org-gtd-horizons-file (format "_GTD_HORIZONS._%s.org" (rapport-fn-context-get-label))) + (org-gtd-archive-file-format (format "_GTD_ARCHIVE_y%%s._%s.org_archive" (rapport-fn-context-get-label))) + + ;; Simplified Task States ;; + ;; - Org-GTD modifies/restricts the list of selectable TODO states + ;; ,ref: [[help:org-done-keywords]], [[help:org-todo-keywords]] + (org-gtd-todo "TODO") + (org-gtd-todo-suffix "(t!)") + (org-gtd-wait "WAIT") + (org-gtd-wait-suffix "(w@)") + (org-gtd-next "NEXT") + (org-gtd-next-suffix "(n@)") + (org-gtd-canceled "STOP") + (org-gtd-canceled-suffix "(K@)") + (org-gtd-done "DONE") + (org-gtd-done-suffix "(D@)") + + + ;; Org-GTD / Agenda + (org-gtd-delegate-property "DELEGATED_TO") + (org-agenda-property-position 'nil) ; ,default: 'next-line , valid-options: nil , 'next-line , 'same-line , 'where-it-fits + ;; Org-GTD / Org-EDNA + (org-edna-use-inheritance t) + + ;; Behaviors ;; + + ;; ,NB: consider tracking larger and more complex, (multi-phase, multi-deliverable) projects as their own Areas Of Focus, this can be useful for organizing smaller deliverables into larger scopes + ;; ,HINT: add supplemental user-specific configs to customization system + + ;default; (org-gtd-areas-of-focus '("Home" "Health" "Family" "Career")) + + ;; ,EXAMPLE: (setq org-gtd-organize-hooks (cl-remove-duplicates (append org-gtd-organize-hooks '(org-set-tags-command org-gtd-set-area-of-focus)))) + + (org-gtd-clarify-show-horizons 'right) + ;; ,ref: https://github.com/Trevoke/org-gtd.el#gtd-step-46--organize + ;; ,HINT: functions that get called to decorate each item (e.g. org tags, org effort, etc.). Add org-gtd-set-area-of-focus to this one to set areas of focus on each item. + ;; ,HINT: add user-specific configs to customization system + ;; ,EXAMPLE: (setq org-gtd-organize-hooks (cl-remove-duplicates (append org-gtd-organize-hooks '(org-set-tags-command org-gtd-set-area-of-focus)))) + ;(org-gtd-organize-hooks (cl-remove-duplicates (append org-gtd-organize-hooks '(org-set-tags-command org-gtd-set-area-of-focus)))) + ;; Internal Operation ;; + + + ;wip; (org-gtd-archive-location org-archive-location) + + + + ;; capture templates ;; + ;; (setq org-gtd-capture-templates + ;; '(("i" "Inbox" entry + ;; (file org-gtd-inbox) + ;; "* %?\n%U\n\n %i" :kill-buffer t) + ;; ("l" "Inbox with link" entry + ;; (file (expand-file-name org-gtd-inbox) + ;; "* %?\n%U\n\n %i\n %a" :kill-buffer t)))) + + ;;default;; (setq org-gtd-file-horizons-template "* Purpose and principles (why)\n* Vision (what)\n* Goals\n* Areas of focus / accountabilities\n") + (setq org-gtd-file-horizons-template (mapconcat 'identity `( + "# -*- mode: org -*-" + ,(when (file-exists-p rapport-uri-vault-cfgs-emacs-apps-org-setupfile) + (format "# #+SETUPFILE: %s" rapport-uri-vault-cfgs-emacs-apps-org-setupfile)) + "#+STARTUP: overview hideblocks indent nonum align inlineimages fnadjust entitiespretty" + "#+OPTIONS: ^:{} broken-links:t creator:nil d:nil email:nil num:nil prop:nil stat:nil tags:nil todo:done tex:t" + "# Provide Global Presets for Org-Babel" + "#+PROPERTY: header-args :eval never-export :comments both" + "#+PROPERTY: header-args:ditaa :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil \".png\") :cmdline \"-r -s 0.8\"" + "#+PROPERTY: header-args:dot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil \".png\")" + "#+PROPERTY: header-args:plantuml :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat \".\" (or (bound-and-true-p plantuml-output-type) \"svg\"))) :cmdline \"-quiet -darkmode\"" + "#+PROPERTY: header-args:gnuplot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat \".\" (or (bound-and-true-p gnuplot-image-format) \"png\")))" + ,(format "#+CATEGORY: %s" ".horizons") + "#+TITLE: GTD Horizons" + "#+SUBTITLE: /A GTD Horizons file is used to promote alignment among immediate, medium, and long term pursuits./" + "#+SELECT_TAGS: noexport" + "" + "#+begin_comment " + " This is the GTD Horizons file." + " A GTD Horizons (aka Horizons of Focus) file is a structured collection of medium and long-term pursuits, arranged according to their natures and their realization spans, (ranging from three months to more than 5+ years)." + "" + "_References:_" + " - https://www.dandywithlens.com/gtd-horizons-of-focus/" + " - https://en.wikipedia.org/wiki/Getting_Things_Done" + " - https://remotefriday.com/remote-tools/complete-playbook-to-master-gtd-areas-of-focus-unraveling-the-6-horizons-of-focus-for-peak-productivity-and-responsibility/" + " - https://facedragons.com/productivity/areas-of-focus-examples/" + " - https://www.linkedin.com/pulse/intro-getting-things-done-gtd-horizons-projects-context-brian-petro" + " - https://gettingthingsdone.com/2011/01/the-6-horizons-of-focus/" + "" + "_Horizon Levels:_" + " 0. Tasks and Calendar" + " 1. Projects" + " 2. Areas of Focus (incl. large and complex project-mgmt/feature-delivery)" + " 3. Goals and Objectives" + " 4. Vision" + " 5. Purpose and Principles" + "#+end_comment" + "\n" + "-----" + "* Purpose and principles (why) :GTD_GORIZON_6_PURPOSE:" + "-----" + "* Vision (what) :GTD_HORIZON_5_VISION:" + "-----" + "* Goals :GTD_HORIZON_4_GOALS:" + "-----" + "* Areas of Focus / Accountabilities :GTD_HORIZON_3_AOFA:" + "\n\n") + "\n")) + + ;;default;; (org-gtd-inbox-template "#+begin_comment \n This is the inbox. Everything goes in here when you capture it. \n #+end_comment" + (org-gtd-inbox-template + (concat + "# -*- mode: org ; rapport-emacs-opt-org-modified: t -*-" + "\n" + "#+STARTUP: overview hideblocks indent nonum align inlineimages fnadjust entitiespretty" + "\n" + "#+OPTIONS: ^:{} broken-links:t creator:nil d:nil email:nil num:nil prop:nil stat:nil tags:nil todo:done tex:t" + "\n" + "# Provide Global Presets for Org-Babel" + "\n" + "#+PROPERTY: header-args :eval never-export :comments both" + "\n" + "#+PROPERTY: header-args:ditaa :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil \".png\") :cmdline \"-r -s 0.8\"" + "\n" + "#+PROPERTY: header-args:dot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil \".png\")" + "\n" + "#+PROPERTY: header-args:plantuml :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat \".\" (or (bound-and-true-p plantuml-output-type) \"svg\"))) :cmdline \"-quiet -darkmode\"" + "\n" + "#+PROPERTY: header-args:gnuplot :exports results :cache yes :file (make-temp-file (concat (when (functionp 'rapport-fn-context-get-label) (rapport-fn-context-get-label)) \"--\" (substring (sha1 (buffer-file-name (get-buffer (buffer-name)))) -5) \"-buffer--\" (when (functionp 'rapport-fn-current-time-as-string) (rapport-fn-current-time-as-string))) nil (concat \".\" (or (bound-and-true-p gnuplot-image-format) \"png\")))" + "\n" + (format "#+CATEGORY: %s" ".inbox") + "\n" + "#+TITLE: GTD Inbox" + "\n" + "#+SUBTITLE: /The *GTD INBOX* serves as a central collection point for all thoughts that need processing, such as tasks, projects, or useful notes. The goal is to capture these thoughts as they arise, with minimal friction into a defined place for processing in the future./" + "\n" + "#+SELECT_TAGS: export" + "\n" + "#+FILETAGS: REFILE" + "\n" + "#+begin_comment \n This is the inbox. Everything goes in here when you capture it. \n#+end_comment" + "\n\n")) + ;; + (org-gtd-habit-template (format "* %s\n:PROPERTIES:\n:ORG_GTD: %s\n:END:\n" org-gtd-habit org-gtd-habit)) + ;; ,wip: org-gtd-clarify-project-templates + + :config + (require 'org-gtd) + (org-gtd-mode +1) + (org-edna-mode +1) + + ;; custom variables + (setq rapport-emacs/org-gtd/areas-of-focus/valid-operations-list (list 'add 'remove)) + + (setq org-gtd-projects "Objectives" ;; default, "Projects" + org-gtd-habit "Practices" + org-gtd-calendar "Calendar" + org-gtd-action "Actions" + org-gtd-incubate "Incubate") + (setq org-gtd-project-headings (concat (format "+ORG_GTD=\"%s\"" org-gtd-projects))) ; org-agenda query to generate list of projects ;; default, "+LEVEL=2&+ORG_GTD=\"Projects\"" + + ;; functions ;; + + ;; ,NB: relies on custom function 'rapport/edbd/-list-contacts-by-name , loaded with EBDB + (defcustom org-gtd-delegate-read-func + (lambda () + (format "%s" + (completing-read "Delegate to: " + (mapcar 'car (rapport/ebdb/-list-contacts-by-name)) + nil t))) + "Function that is called to read in the Person the task is delegated to. + + Needs to return a string that will be used as the persons name." + :group 'org-gtd-organize + :package-version '(org-gtd . "2.3.0") + :type 'function ) + + + ;default;(org-gtd-archive-location #'org-gtd-archive-location-func) + + (defun org-gtd-archive-location-func () + "Default function to define where to archive items." + (let* ((year (number-to-string (caddr (calendar-current-date)))) + (dir (expand-file-name "archive" (expand-file-name ".artifacts" rapport-uri-vault-docs))) + (filename (format org-gtd-archive-file-format year)) + (filepath (expand-file-name filename dir))) + (string-join `(,filepath "::" "datetree/")))) + + ;; + (defun rapport/org-gtd/areas-of-focus/parse-changes (changes &optional verbose) + "should result in a list of strings or an empty list" + (let* + ((verbose (if (bound-and-true-p verbose) t nil)) + (verbose t) ;; temporarily for debugging purposes + (changes (if (stringp changes) (split-string changes) changes)) + (changes (remove nil (mapcar (lambda (x) (when (stringp x) x)) changes))) + (changes (mapcar 'string-trim changes)) + (changes (remove nil (mapcar (lambda (x) (unless (string-empty-p x) x)) changes))) + (changes (cl-remove-duplicates changes))) + changes)) + + ;; + (defun rapport/org-gtd/areas-of-focus/add (changes &optional tmp-org-gtd-areas-of-focus) + "" + (interactive (list (read-string "Area of Focus to add: "))) + (let* + ((verbose t) + (tmp-org-gtd-areas-of-focus + (if (bound-and-true-p tmp-org-gtd-areas-of-focus) tmp-org-gtd-areas-of-focus + (if (bound-and-true-p org-gtd-areas-of-focus) org-gtd-areas-of-focus (list)))) + (changes (rapport/org-gtd/areas-of-focus/parse-changes changes tmp-org-gtd-areas-of-focus))) + (mapcar '(lambda (x) (add-to-list 'tmp-org-gtd-areas-of-focus x)) changes) + (when verbose (message "new Areas-Of-Focus list [added %s]: %s" changes tmp-org-gtd-areas-of-focus)) + tmp-org-gtd-areas-of-focus)) + + ;; + (defun rapport/org-gtd/areas-of-focus/remove (changes &optional tmp-org-gtd-areas-of-focus) + "" + (interactive + (let* + ((tmp-org-gtd-areas-of-focus (if (bound-and-true-p tmp-org-gtd-areas-of-focus) tmp-org-gtd-areas-of-focus org-gtd-areas-of-focus))) + (list (completing-read "Area of Focus to remove: " tmp-org-gtd-areas-of-focus)))) + (let* + ((verbose t) + (tmp-org-gtd-areas-of-focus org-gtd-areas-of-focus) + (changes (rapport/org-gtd/areas-of-focus/parse-changes changes tmp-org-gtd-areas-of-focus))) + (mapcar (lambda (x) (setq tmp-org-gtd-areas-of-focus (remove x tmp-org-gtd-areas-of-focus)) x) changes) + (when verbose (message "new Areas-Of-Focus list [removed %s]: %s" changes tmp-org-gtd-areas-of-focus)) + tmp-org-gtd-areas-of-focus)) + + ;; + (defun rapport/org-gtd/areas-of-focus/update (op changes &optional confirm persist tmp-org-gtd-areas-of-focus) + "Usage: '(rapport/org-gtd/areas-of-focus/update 'add \"@examples @abound\")" + (interactive + (let* + ((confirm (if (bound-and-true-p confirm) t nil)) + (persist (if (bound-and-true-p persist) t nil)) + (tmp-org-gtd-areas-of-focus (if (bound-and-true-p tmp-org-gtd-areas-of-focus) tmp-org-gtd-areas-of-focus org-gtd-areas-of-focus)) + (op (intern (completing-read "Select an operation: " (mapcar 'symbol-name rapport-emacs/org-gtd/areas-of-focus/valid-operations-list)))) + (changes (rapport/org-gtd/areas-of-focus/parse-changes (read-string "Provide a space-separated list of changes: ") tmp-org-gtd-areas-of-focus))) + (list op changes confirm persist tmp-org-gtd-areas-of-focus))) + ;; + (when confirm + (unless (y-or-n-p (format "Proposed New Changes [%s]: %s" (symbol-name op) changes)) + (message "Exited. No changes made."))) + (setq org-gtd-areas-of-focus (funcall (intern (concat "rapport/org-gtd/areas-of-focus/" (symbol-name op))) changes)) + (when persist + (customize-save-variable 'org-gtd-areas-of-focus changes))) + + + ;; adaptive changes - areas of focus + ;,WIP,; (rapport/org-gtd/areas-of-focus/update 'remove "Home Health Family Career") + ;,WIP,; (rapport/org-gtd/areas-of-focus/add "@Assets @Community @Events @Family @Folks @Health @Household @Money @Personal @Practices @Work") + + (progn)) + #+end_src + +*** using <<>> +:PROPERTIES: +:ID: C7D24E2E-D969-4690-AFF3-9AA67D644BFD +:END: +:LOGBOOK: +- Refiled on [2024-03-10 Sun 19:42] +:END: + - w/ org-super-agenda + #+begin_src emacs-lisp +(use-package org-super-agenda + :demand + :preface + (defvar rapport/org-super-agenda/auto-show-groups '("overdue" "habits" "punchlists" "Next Actions" "Today")) ;; ,NB: this variable requires functionality provided in the 'origami use-package definition + (defun rapport/org-super-agenda/-toggle-and-refresh () + (interactive) + (if org-super-agenda-mode + (call-interactively 'org-super-agenda-mode) + (org-super-agenda-mode)) + (org-agenda-redo)) + :custom + (org-super-agenda-hide-empty-groups t) + (org-super-agenda-groups + '(;; Each group has an implicit boolean OR operator between its selectors. + (:name "FLAGGED" + :and (:tag "FLAGGED") + ;; - Items are only included in one group, their *first* + ;; matching group. + + ;; - This group is defined first in the + ;; 'org-super-agenda-groups variable to effectively + ;; prune or filter-out *all* priority 'E items into this + ;; one group to prevent them from appearing in other + ;; groups. + + ;; - It's set with a high 'order of 200 (default is 99), + ;; to ensure the group appears at the very end of the + ;; agenda. + + ;; - Show this group at the end of the agenda (since it + ;; has the highest number). If this group is defined + ;; later in the 'org-super-agenda-groups variable, any + ;; preceding definitions may have included some priority + ;; 'E items based on their other properties against + ;; matching criteria, using a first-match wins style of + ;; grouping. + :order -75) ; Set order of this section, lower numbers take precedence + (:name "Maybe/Someday" + :and (:priority "E" :not (:todo ("DONE" "STOP" "SHUT"))) + :order 200) ; Set order of this section, lower numbers take precedence + (:name "waiting" + :todo "WAIT" + ;; Groups supply their own section names when none are given + ;; Show this section after "Today" and "Important", because + ;; their order is unspecified, defaulting to 0. Sections + ;; are displayed lowest-number-first. + :order -10) + (:name "Next Actions" + :time-grid t ; Items that appear on the time grid + :todo "NEXT" + :order -5) + (:name "overdue" + :deadline past + :order -100) + (:name "punchlists" + :tag "punchlist" + :order -15) + (:name "habits" + :habit t + :order -50) + (:name "due" + :deadline today) + (:name "Contextual, Discretionary, a/o Triage" + :todo "OPEN" + :priority "D" + :tag ("risk@needs_sponsor" "risk@needs_triage") + :order 75) + (:name "Today" ; Optionally specify section name + :todo "TODO") ; Items that have this TODO keyword + + ;; Set order of multiple groups at once + ;; (:order-multi (2 (:name "Shopping in town" + ;; ;; Boolean AND group matches items that match all subgroups + ;; :and (:tag "grocerylist" :tag "@town")) + ;; (:name "Food-related" + ;; ;; Multiple args given in list with implicit OR + ;; :tag ("food" "dinner")) + ;; (:name "Space-related (non-moon-or-planet-related)" + ;; ;; Regexps match case-insensitively on the entire entry + ;; :and (:regexp ("space" "NASA") + ;; ;; Boolean NOT also has implicit OR between selectors + ;; :not (:regexp "moon" :tag "planet"))))) + + ;; (:priority<= "B" + ;; ;; Show this section after "Today" and "Important", because + ;; ;; their order is unspecified, defaulting to 0. Sections + ;; ;; are displayed lowest-number-first. + ;; :order 1) + + ;; - After the last group, the agenda will display items that + ;; didn't match any of these groups, with the default order + ;; position of 99 + + ;; - For this config we want to discard any items that are not + ;; already included in a capture group. + (:name "presumed-invalid" :anything t :order 500) + )) + :config + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 5AACAE13-D21B-4EF8-B76A-CEF327D1A31C +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-tasks) +#+end_src + +** as Habit and Goal Tracker :provide@endeavors_practices#rapport: +:PROPERTIES: +:ID: 12FFF2A6-D9E6-4228-8EB3-58869E7FEF8A +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-practices.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** with Org-Mode Support +:PROPERTIES: +:ID: 4502FE98-114B-4A64-BAAA-6C464EA32C9F +:END: + - with Org-Habit and Org-CheckList enabled + #+begin_src emacs-lisp +(require 'org-habit) +(require 'org-checklist) + #+end_src +*** Study and Learning +*** Spaced Repitition Study Flashcards using <<>> :feature_preview: +:PROPERTIES: +:ID: B8C40C7E-6FD2-4730-91A1-DE5B2BCF2C69 +:END: +#+begin_src emacs-lisp + (use-package org-fc + :after (:all hydra) + :ensure (org-fc :type git :host github :repo "l3kn/org-fc" :files (:defaults "awk" "demo.org")) +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (org-fc :type git :host github :repo "l3kn/org-fc" :files (:defaults "awk" "demo.org")) + :custom + (org-fc-directories (list + rapport-uri-vault-docs-status + rapport-uri-vault-docs-contacts + rapport-uri-vault-docs-concepts + (expand-file-name "practice" rapport-uri-vault-docs))) + :config + (require 'org-fc-hydra) + (progn)) +#+end_src +*** Spaced Repitition Study Flashcards using <<>> +:PROPERTIES: +:ID: 5E87ED9A-9EA5-47FB-8521-79EE66E55036 +:END: + +#+begin_src emacs-lisp +;; org-drill.el --- flashcards and spaced repetition in org-mode +;; ,REF: https://gitlab.com/phillord/org-drill +;; ,LOG: 20190802 implicated in EM: "File mode specification error: (error Lisp nesting exceeds β€˜max-lisp-eval-depth’)" +;; ,LOG: 20210131_NGa disabled, implicated in redifining 'org-version from my custom definition +(use-package org-drill + :after org + ;;:straight (org-drill :type git :host gitlab :repo "phillord/org-drill") + :config + ;; set scope of org files searched for drill info + ;; to drill the subtree from point, M-x org=drill-tree + (setq org-drill-scope 'agenda-with-archives) + (setq org-drill-use-visible-cloze-face-p t) + (setq org-drill-hide-item-headings t) + ;; add scheduling variability + (setq org-drill-add-random-noise-to-intervals-p t) + (setq org-drill-adjust-intervals-for-early-and-late-repetitions-p t) + (setq org-drill-overdue-interval-factor 1) ;default: 1 + (setq org-drill-days-before-old 10) ;default: 10 + ;; set drill session characteristics + (setq org-drill-maximum-items-per-session 30) ;default: 30 items + (setq org-drill-maximum-duration 30) ;default: 30 minutes + (setq org-drill-save-buffers-after-drill-sessions-p nil) ;default: t + ;; add common org-drill properties + (add-to-list 'org-global-properties `("DRILL_CARD_TYPE" . ("twosided" "multisided" "hide1cloze" "show1cloze" "hide2cloze" "show2cloze" "hide1_firstmore" "show1_firstless" "show1_lastmore")))) +#+end_src + +*** anki-editor, Create Anki Spaced Repetition Flashcards in Org-Mode +:PROPERTIES: +:ID: AAF39E41-3DD7-44FD-B721-5771D68B5E3D +:END: + + #+begin_src emacs-lisp +(use-package anki-editor + :after org + :bind (:map org-mode-map + ("" . anki-editor-cloze-region-auto-incr) + ("" . anki-editor-cloze-region-dont-incr) + ("" . anki-editor-reset-cloze-number) + ("" . anki-editor-push-tree)) + :hook (org-capture-after-finalize . anki-editor-reset-cloze-number) ; Reset cloze-number after each capture. + :config + (setq anki-editor-create-decks t ;; Allow anki-editor to create a new deck if it doesn't exist + anki-editor-org-tags-as-anki-tags t) + + (defun anki-editor-cloze-region-auto-incr (&optional arg) + "Cloze region without hint and increase card number." + (interactive) + (anki-editor-cloze-region my-anki-editor-cloze-number "") + (setq my-anki-editor-cloze-number (1+ my-anki-editor-cloze-number)) + (forward-sexp)) + (defun anki-editor-cloze-region-dont-incr (&optional arg) + "Cloze region without hint using the previous card number." + (interactive) + (anki-editor-cloze-region (1- my-anki-editor-cloze-number) "") + (forward-sexp)) + (defun anki-editor-reset-cloze-number (&optional arg) + "Reset cloze number to ARG or 1" + (interactive) + (setq my-anki-editor-cloze-number (or arg 1))) + (defun anki-editor-push-tree () + "Push all notes under a tree." + (interactive) + (anki-editor-push-notes '(4)) + (anki-editor-reset-cloze-number)) + ;; Initialize + (anki-editor-reset-cloze-number) + ) + #+end_src +*** Reminders and Notifications using <<>> +:PROPERTIES: +:ID: 115829E0-84D5-4363-A32B-6AD8F54830AC +:END: +#+begin_src emacs-lisp +;; ,ref: https://github.com/spegoraro/org-alert +;; ,HINT: Provides notifications for scheduled or deadlined agenda entries. +(use-package org-alert + :init + (require 'org-alert) + (org-alert-enable) + :custom + (org-alert-notification-title "Org Agenda") + :config + (progn)) +#+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: 39D0D41B-B3DC-49DA-947E-4618B61D9C61 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-practices) +#+end_src +** as Team and Personnel Development and Performance Mgmt :provide@endeavors_teams#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-teams.el" (org-sbe rapport-sbe--get-libdir)) +:END: + + +*** declare feature :noexport: +:PROPERTIES: +:ID: 6FAC18BD-5F1F-442D-953C-70CC5DD5EA46 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-teams) +#+end_src + +** as Project Mgmt, Planning and Projection :provide@endeavors_projects#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-projects.el" (org-sbe rapport-sbe--get-libdir)) +:ID: f83926d6-0dfe-4e59-99a0-c659fcda27fa +:END: + +*** enable Taskjuggler's Project Planning capabilities, using =ox-taskjuggler= :pending_review:NOTE:risk@swpkg_deficient: +:PROPERTIES: +:ID: DCD946F9-BC0B-4794-A317-D92AD5558FF5 +:END: + - add support for editing TJ3 files + #+begin_src emacs-lisp +(use-package tj3-mode + :config + (progn)) + #+end_src + + - add support for exporting to TJ3 format + #+begin_src emacs-lisp +(use-package ox-taskjuggler + :demand t + :after (:all org-contrib) + :ensure (org-contrib :main "lisp/ox-taskjuggler.el") + ;; ~/.uris/.vault-var/emacs/elpaca/repos/org-contrib/lisp/ox-taskjuggler.el + :config + ;; TaskJuggler + ;; ,REF: https://hugoideler.com/2018/09/org-mode-and-wide-taskjuggler-html-export/ + (setq org-taskjuggler-default-reports + '("textreport report \"Plan\" { + formats html + header '== %title ==' + center -8<- + [#Plan Plan] | [#Resource_Allocation Resource Allocation] + ---- + === Plan === + <[report id=\"plan\"]> + ---- + === Resource Allocation === + <[report id=\"resourceGraph\"]> + ->8- + } + # A traditional Gantt chart with a project overview. + taskreport plan \"\" { + headline \"Project Plan\" + columns bsi, name, start, end, effort, effortdone, effortleft, chart { width 1000 } + loadunit shortauto + hideresource 1 + } + # A graph showing resource allocation. It identifies whether each + # resource is under- or over-allocated for. + resourcereport resourceGraph \"\" { + headline \"Resource Allocation Graph\" + columns no, name, effort, weekly { width 1000 } + loadunit shortauto + hidetask ~(isleaf() & isleaf_()) + sorttasks plan.start.up + }")) + + + ;; ,REF: https://hugoideler.com/2018/09/org-mode-and-wide-taskjuggler-html-export/ + (setq org-taskjuggler-default-project-duration 999) + (setq org-taskjuggler-valid-task-attributes + '(account start note duration endbuffer endcredit end + flags journalentry length limits maxend maxstart minend + minstart period reference responsible scheduling + startbuffer startcredit statusnote chargeset charge booking)) + + + ;org-taskjuggler-target-version: should be set to the output of the command tj3 --version, e.g. (setq org-taskjuggler-target-version 3.4) + ;; org-taskjuggler-default-global-header + ;; org-taskjuggler-default-global-properties + ;; org-taskjuggler-default-project-duration + ;; org-taskjuggler-default-project-version + ;; org-taskjuggler-default-reports: sets a report file to use. This may be written in text format (as in, the variable set to the full report text string), or (perhaps easier) to a .tji file containing the report definition. + + ;; org-taskjuggler-extension + ;; org-taskjuggler-final-hook + ;; org-taskjuggler-keep-project-as-task + ;; org-taskjuggler-process-command + ;; org-taskjuggler-project-tag + ;; org-taskjuggler-report-tag + ;; org-taskjuggler-reports-directory + ;; org-taskjuggler-resource-tag + + ;; org-taskjuggler-valid-report-attributes + ;; org-taskjuggler-valid-resource-attributes + ;; org-taskjuggler-valid-task-attributes + + (require 'ox-taskjuggler) + (progn)) + #+end_src +*** COMMENT Gantt Schedule Visualization using <<>> :risk@upstream_unmaintained:pending_review: +:PROPERTIES: +:ID: 4CD0533B-0773-4164-A849-3467BD29617B +:END: +:LOGBOOK: +- Refiled on [2022-04-25 Mon 23:23] +- Refiled on [2021-11-29 Mon 22:20] +:END: +- context :: + - info/notes + - on (default) Navigation commands + | Key binding | Command | + |-------------+------------------------------------------------| + | f | Move forward to next entry on the line | + | n | Move backward to previous entry | + | n | Move to the closest entry on the next line | + | p | Move to the closest entry on the previous line | + | F | Scroll forward by one month | + | B | Scroll backward by one month | + | M-f | Shift date at point forward one day | + | M-b | Shift date at point backward one day | + | c | Move calendar to current date | + | | Navigate to org heading at point | + | | Show agenda for date at point | + +setup =elgannt= + - functionality enablement + #+begin_src emacs-lisp +;; pre-req packages for elgantt +(use-package org-ql) +(use-package ts) +;(use-package cl-lib :config (require 'cl-lib)) ;; #,LOG: 20211120_NGa 'cl is deprecated but required somewhere in elgantt (uses: #'first) + +;; optional extension packages for elgantt +; - org-edna (loaded elsewhere) + + + +;; https://github.com/legalnonsense/elgantt.git +(use-package elgantt + :after (:all org-ql ts s dash cl-lib) + :ensure (elgantt :git git :host github :repo "legalnonsense/elgantt") + :custom + ;; ElGantt - Task Sourcing Options ;; + (elgantt-agenda-files (org-agenda-files)) + ;; (dbg) use the provided test.org file for testing + ;(setq elgantt-agenda-files (expand-file-name "test.org" (expand-file-name "elgantt" (expand-file-name "repos" (expand-file-name "straight" straight-base-dir))))) + + ;; ElGantt - Task Filter/Selection Options ;; + (elgantt-skip-archives t) + ;(elgantt-use-inherited-hashtags nil) + ;(elgantt-exclusion nil) + + ;; ElGantt - Organization and Correlation Options ;; + + (elgantt-header-type 'outline) ;; opts: category hashtag outline root function + (elgantt-draw-overarching-headers t) + + ;; ElGantt - Visibility Framing Options ;; + + ;(elgantt-start-date "2021-01-01") ;; set explicitly + ;(elgantt-start-date (concat (format-time-string "%Y-%m") "-01") ;; (i.e., the current month) + + (elgantt-scroll-to-current-month-at-startup t) + + ;; ElGantt Display - Information Density Options ;; + + (elgantt-startup-folded nil) + (elgantt-show-header-depth t) + (elgantt-insert-blank-line-between-top-level-header t) + + (elgantt-timestamps-to-display '(deadline timestamp timestamp-range scheduled timestamp-ia timestamp-range-ia)) + (elgantt-insert-header-even-if-no-timestamp nil) + (elgantt-hide-number-line nil) + + :config + (setq elgantt-user-set-color-priority-counter 0) + (elgantt-create-display-rule draw-scheduled-to-deadline + :parser ((elgantt-color . ((when-let ((colors (org-entry-get (point) "ELGANTT-COLOR"))) + (s-split " " colors))))) + :args (elgantt-scheduled elgantt-color elgantt-org-id) + :body ((when elgantt-scheduled + (let ((point1 (point)) + (point2 (save-excursion + (elgantt--goto-date elgantt-scheduled) + (point))) + (color1 (or (car elgantt-color) + "black")) + (color2 (or (cadr elgantt-color) + "red"))) + (when (/= point1 point2) + (elgantt--draw-gradient + color1 + color2 + (if (< point1 point2) point1 point2) ;; Since cells are not necessarily linked in + (if (< point1 point2) point2 point1) ;; chronological order, make sure they are sorted + nil + `(priority ,(setq elgantt-user-set-color-priority-counter + (1- elgantt-user-set-color-priority-counter)) + ;; Decrease the priority so that earlier entries take + ;; precedence over later ones (note: it doesn’t matter if the number is negative) + :elgantt-user-overlay ,elgantt-org-id))))))) + + ;; Linking cells with elgantt--connect-cells + ;; Some samples here use the following macro to draw a line through cells which share the same hashtag. This code also adds a shortcut to move to the next matching hashtag: + (elgantt-create-display-rule show-hashtag-links + :args (elgantt-hashtag) + :post-command-hook t ;; update each time the point is moved + :body ((elgantt--clear-juxtapositions nil nil 'hashtag-link) ;; Need to clear the last display + (when elgantt-hashtag ;; only do it if there is a hashtag property at the cell + (elgantt--connect-cells :elgantt-alltags elgantt-hashtag 'hashtag-link '(:foreground "red"))))) + + (elgantt-create-action follow-hashtag-link-forward + :args (elgantt-alltags) + :binding "C-M-f" + :body ((when-let* ((hashtag (--first (s-starts-with-p "#" it) + elgantt-alltags)) + (point (car (elgantt--next-match :elgantt-alltags hashtag)))) + (goto-char point)))) + + (elgantt-create-action follow-hashtag-link-backward + :args (elgantt-alltags) + :binding "C-M-b" + :body ((when-let* ((hashtag (--first (s-starts-with-p "#" it) + elgantt-alltags)) + (point (car (elgantt--previous-match :elgantt-alltags hashtag)))) + (goto-char point)))) + + (defun rapport/elgantt/adjust-start-date-and-refresh () "" (interactive)) + (defun rapport/elgantt/toggle-headline-folding () "" (interactive)) + (defun rapport/elgantt/switch-profile () "" (interactive)) + + (progn)) + #+end_src +*** Display Hourly Agenda Planner using <<>> :feature_preview: +:PROPERTIES: +:ID: 0E1584E4-D51D-416C-AB4E-33B03E7EEE78 +:END: + #+begin_src emacs-lisp +(use-package org-timeblock + :commands (org-timeblock org-timeblock-list) + :custom + (org-timeblock-inbox-file org-default-notes-file) + (org-timeblock-span 4) ;; ,default: 3 + (org-timeblock-files 'agenda) ;; ,default: agenda + :bind ( + :map org-timeblock-mode-map + ("j" . org-timeblock-goto) + ("C-c C-t" . org-timeblock-todo) + ("C-c C-x TAB" . org-timeblock-clock-in) + ("C-c C-x C-o" . org-clock-out) + ("j" . org-timeblock-goto) + ("RET" . org-timeblock-schedule) + ("S-" . org-timeblock-day-earlier) + ("S-" . org-timeblock-day-later) + ("M-%" . org-timeblock-mark-by-regexp) + ("C-c C-e" . org-timeblock-write) + ("O" . org-timeblock-switch-scaling) + ("v" . org-timeblock-change-span) + ;; default - disabled a/o override + ; ("C-" . org-timeblock-day-earlier) + ; ("C-" . org-timeblock-day-later) + ; ("RET" . org-timeblock-goto) + ; ("%" . org-timeblock-mark-by-regexp) + ; ("i" . org-timeblock-clock-in) + ; ("o" . org-clock-out) + ; ("w" . org-timeblock-write) + ; ("s" . org-timeblock-schedule) + ;; defaults + ("C-b" . org-timeblock-day-earlier) + ("C-f" . org-timeblock-day-later) + ("TAB" . org-timeblock-goto-other-window) + ("+" . org-timeblock-new-task) + ("T" . org-timeblock-toggle-timeblock-list) + ("U" . org-timeblock-unmark-all-blocks) + ; ("V" . org-timeblock-change-span) + ("b" . org-timeblock-backward-column) + ("d" . org-timeblock-set-duration) + ("f" . org-timeblock-forward-column) + ("g" . org-timeblock-redraw-buffers) + ("m" . org-timeblock-mark-block) + ("n" . org-timeblock-forward-block) + ("p" . org-timeblock-backward-block) + ("q" . org-timeblock-quit) + ; ("t" . org-timeblock-todo) + ("u" . org-timeblock-unmark-block) + ; ("v" . org-timeblock-switch-scaling) + ("" . org-timeblock-forward-block) + ("" . org-timeblock-backward-column) + ("" . org-timeblock-select-block-with-cursor) + ("" . org-timeblock-forward-column) + ("" . org-timeblock-backward-block) + ) + :config + (progn)) + #+end_src +*** Agenda and Schedule View using <<>> :feature_preview: +:PROPERTIES: +:ID: 6945F0F5-3EC4-4ED7-BF19-64A3EACCB406 +:END: + + #+begin_src emacs-lisp +(use-package org-hyperscheduler) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 998068DF-68C2-4540-8726-5493FB59193E +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-projects) +#+end_src +*** Scheduling Time-Blocks using <<>> :feature_preview: +:PROPERTIES: +:ID: 3D9BE729-A0EF-4AF0-A9A5-FB340496FFCC +:END: +:LOGBOOK: +- Refiled on [2024-03-06 Wed 14:53] +:END: + #+begin_src emacs-lisp + ;; ,ref: https://github.com/ichernyshovvv/org-timeblock + (use-package org-timeblock + :custom + (org-timeblock-inbox-file org-default-notes-file) + :config + (progn)) + #+end_src + +*** COMMENT using <<>> +:PROPERTIES: +:ID: 023E66FA-DABA-4D65-94B0-71F06FB41931 +:END: +:LOGBOOK: +- Refiled on [2024-06-25 Tue 12:43] +- Refiled on [2024-03-07 Thu 21:26] +:END: + +setup from https://github.com/cashpw/clocktable-by-category + #+begin_src emacs-lisp +(use-package clocktable-by-category + :demand + :commands (clocktable-by-category-report) + :ensure (clocktable-by-category :type git :host github :repo "cashpw/clocktable-by-category") + :custom + (org-clock-clocktable-default-properties '( + :scope agenda-with-archives :maxlevel 5 + :files-fn org-agenda-files :block today + :tcolumns 3 :merge-duplicate-headlines t + )) + :config + ;; ,NB: the focused time can be shifted forward and backwards using ~#'org-shiftleft~ (=S-=) and ~#'org-shiftright~ (=S-=) + (progn)) + #+end_src +*** using <<>> +:PROPERTIES: +:ID: FEC4BA33-04E9-492F-8CCF-821ACF7F2B37 +:END: +:LOGBOOK: +- Refiled on [2024-06-25 Tue 12:43] +:END: + - setup from https://github.com/cashpw/clocktable-by-tag + #+begin_src emacs-lisp +(use-package clocktable-by-tag + :demand + :ensure (clocktable-by-tag :type git :host github :repo "cashpw/clocktable-by-tag") + :config + (progn)) + #+end_src + +** as Campaign Manager :provide@endeavors_campaigns#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-campaigns.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** declare feature :noexport: +:PROPERTIES: +:ID: 0EC78BCA-F8EB-4D96-88E5-6E1B9060EF43 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-campaigns) +#+end_src + +** as Work-Effort Management Organizer :provide@endeavors_composure#rapport:feature_preview: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-endeavors-composure.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +----- +--- _/overview/_ --- + +=composure= is WIP. It's set to include: +- Tasks +- Task Collections +- Task Specializations +- Project-Mgmt, Personnel and Team Mgmt +- Project-Mgmt, Material and Resource Mgmt +- Performance Tracking and Mgmt +- Task Side-Effects, Pre-Requisites, and Inter-Dependencies +- Products + +*** declare feature :noexport: +:PROPERTIES: +:ID: 65AFB04E-7372-4C42-BA3D-50B6A3093847 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-endeavors-composure) +#+end_src + +** declare Module feature :noexport: +:PROPERTIES: +:ID: F2819170-117E-4887-9D06-84A84B77E087 +:END: +#+begin_src emacs-lisp +(require 'rapport-endeavors-forges) +(require 'rapport-endeavors-workspaces) +(require 'rapport-endeavors-tasks) +(require 'rapport-endeavors-practices) +(require 'rapport-endeavors-teams) +(require 'rapport-endeavors-projects) +(require 'rapport-endeavors-campaigns) +(require 'rapport-endeavors-composure) + +;; +(elpaca-wait) +(provide 'rapport-endeavors) +#+end_src + +* /Chapter/ *3*, Correspondences :export:provide@rapport_correspondences#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-correspondences.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +Communications and Relationships + +** as Contact and Relationship Manager +**** Contact Management with <<>> +:PROPERTIES: +:ID: 321C0592-AA09-4497-B667-E6DF147AFB90 +:END: +setup =ebdb=, an EIEIO port of BBDB, Emacs' contact-management package + #+begin_src emacs-lisp +(use-package ebdb + :demand + :hook + (mu4e-compose-mode . + (lambda () + (ebdb-records) ; populate capf cache + (add-to-list 'completion-at-point-functions + (cape-super-capf (cape-capf-properties #'ebdb-mail-dwim-completion-at-point-function + :annotation-function (lambda (_) " EBDB") + :company-kind (lambda (_) 'text) + :exclusive 'no) + (cape-capf-properties #'mu4e~compose-complete-contact + :annotation-function (lambda (_) " mu4e") + :company-kind (lambda (_) 'event) + :exclusive 'no))))) + :ensure (:repo "girzel/ebdb" :host github :type git) +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:repo "girzel/ebdb" :host github :type git) + :custom + ;(ebdb-org-field-tags "CONTACT") + (ebdb-sources `( ,(expand-file-name "ebdb-contacts.eld" (expand-file-name "contacts" rapport-uri-vault-docs)) )) + :config + (require 'ebdb-org) + + ;; modified from the original to add ebdb lookup + (defun rapport/ebdb/-list-contacts-by-name() + (mapcar (lambda (rec) + (let* ((name (ebdb-record-name-string rec)) + (uuid (ebdb-record-uuid rec))) + (cons name uuid))) + (ebdb-records))) + + (progn)) + #+end_src + +** as Personal Information Management, Planner, Organizer, and [[https://en.wikipedia.org/wiki/Tickler_file][Tickler]] +*** COMMENT Daily Planner Summary prompts with <<>> :pending_review:_inquiry#risk@perf_slowdowns:pending_development: +:PROPERTIES: +:ID: 79EFD2FA-55AA-4A3A-ADEF-2DC0E93AC761 +:END: +setup =secretaria= + #+begin_src emacs-lisp + (use-package secretaria + ;:disabled ;; NOTE: 20190731nga disabled while debugging + :init + (require 'secretaria) + :hook + ;; use this for getting a reminder every 30 minutes of those tasks scheduled + ;; for today and which have no time of day defined. + (after-init . secretaria-unknown-time-always-remind-me) + :config + (progn)) + #+end_src +*** using <<>> :_inquiry#risk@perf_slowdowns:pending_review: +:PROPERTIES: +:ID: 066EB3BE-FD79-4914-94F8-16E680FB28EE +:END: +:LOGBOOK: +- Refiled on [2023-03-03 Fri 23:11] +:END: + + #+begin_src emacs-lisp +;; ,refs: https://christiantietze.de/posts/2019/12/emacs-notifications/ +(use-package appt + :ensure nil + + :custom + ;(appt-disp-window-function #'appt-display-native) + (appt-display-format 'window) ;; pass warnings to the designated window function, opt: 'window, 'echo 'nil + (appt-display-interval 20) ;; set reminder interval + (appt-display-mode-line t) ;; show in the modeline + ;(appt-mode-string "... appt!") ;; ,TODO: add something appropriate here and test + ;(appt-message-warning-time (* appt-display-interval 5)) ;; set reminder start + ;(appt-time-msg-list nil) ;; clear existing appt list + (org-agenda-diary-file (expand-file-name (expand-file-name "calendar" rapport-uri-vault-docs-status))) + (org-agenda-include-diary 't) ;; show holiday, diary entries, and more in org-agenda views + :hook + (after-init . rapport/org-calendar/org-agenda-to-appt) ;; Rebuild the reminders when Emacs starts + (org-finalize-agenda . rapport/org-calendar/org-agenda-to-appt) ;; Rebuild the reminders when refreshing the agenda + :config + (appt-activate 1) ;; activate appointment notification + ;; + (defun rapport/org-calendar/org-agenda-to-appt () + "Erase all reminders and rebuilt reminders for today from the agenda" + (interactive) + (setq appt-time-msg-list nil) + (org-agenda-to-appt)) + ;; + (run-at-time "24:01" 3600 'org-agenda-to-appt) ;; update appt list hourly + ;(run-at-time "24:01" nil 'rapport/org-calendar/org-agenda-to-appt) ;; If we leave Emacs running overnight - reset the appointments one minute after midnight + (progn)) + #+end_src +** as Communicator for Email +** as Communicator for Chat + +*** chatting on IRC using ERC +:PROPERTIES: +:ID: 337CBD63-B547-4C63-8F24-C584465C2B06 +:END: + +configure =erc=, (included within Emacs) +#+begin_src emacs-lisp +(use-package emacs + :ensure nil + + :no-require t + :custom + (erc-track-enable-keybindings nil) + :config + (progn)) +#+end_src + +*** COMMENT chatting on Matrix :feature_preview: +:PROPERTIES: +:ID: 3E3F184E-58E5-4E71-8734-685C55530EED +:END: +enable =ement.el= + #+begin_src emacs-lisp +;; pre-reqs for ement.el +(use-package taxy-magit-section) +(use-package plz) + +;; ,ref: https://github.com/alphapapa/ement.el +;; to connect - M-x matrix-client-connect ,, supply: username, password, server +;; ,TODO: encrypted chat isn't natively supported in ement.el, review options here https://github.com/alphapapa/ement.el#encrypted-room-support-through-pantalaimon +(use-package ement.el + :after (:all taxy-magit-section plz) + :ensure (ement.el :type git :host github :repo "alphapapa/ement.el")) + #+end_src + +*info/notes* + + Call command ement-connect to connect. Multiple sessions are supported, so you may call the command again to connect to another account. + Wait for initial sync to complete (which can take a few moments–initial sync JSON requests can be large). + Use these commands: + ement-list-rooms to view the list of joined rooms. + ement-view-room to view a room’s buffer, selected with completion. + ement-create-room to create a new room. + ement-invite-user to invite a user to a room. + ement-join-room to join a room. + ement-leave-room to leave a room. + ement-forget-room to forget a room. + ement-tag-room to add (or with interactive prefix, remove) a tag on a room (including favorite/low-priority status). + ement-list-members to list members in a room. + ement-send-direct-message to send a direct message to a user (in an existing direct room, or creating a new one automatically). + ement-room-edit-message to edit a message at point. + ement-room-send-file to send a file. + ement-room-send-image to send an image. + ement-room-set-topic to set a room’s topic. + ement-room-occur to search in a room’s known events. + ement-ignore-user to ignore a user (or with interactive prefix, un-ignore). + ement-room-set-message-format to set a room’s message format buffer-locally. + Use these special buffers to see events from multiple rooms (you can also reply to messages from these buffers!): + See all new events that mention you in the *Ement Mentions* buffer. + See all new events in rooms that have open buffers in the *Ement Notifications* buffer. + +Bindings + +These bindings are common to all of the following buffer types: + + Switch to a room buffer: M-g M-r + Switch to the room list buffer: M-g M-l + Switch to the mentions buffer: M-g M-m + Switch to the notifications buffer: M-g M-n + +Room buffers + + Show command menu: ? + +images/transient.png + +Movement + + Next event: TAB + Previous event: + Scroll up and mark read: SPC + Scroll down: S-SPC + Jump to fully-read marker: M-SPC + Load older messages: at top of buffer, scroll contents up (i.e. S-SPC, M-v or mwheel-scroll) + +Switching + + List rooms: M-g M-l + Switch to other room: M-g M-r + Switch to mentions buffer: M-g M-m + Switch to notifications buffer: M-g M-n + Quit window: q + +Messages + + Write message: RET + Write reply to event at point (when region is active, only quote marked text) : S-RET + Compose message in buffer: M-RET (while writing in minibuffer: C-c ') (Use command ement-room-compose-org to activate Org mode in the compose buffer.) + Edit message: + Delete message: C-k + Send reaction to event at point, or send same reaction at point: s r + Send emote: s e + Send file: s f + Send image: s i + View event source: v + Complete members and rooms at point: C-M-i (standard completion-at-point command). + +Images + + Toggle scale of image (between fit-to-window and thumbnail): mouse-1 + Show image in new buffer at full size: double-mouse-1 + +Users + + Send direct message: u RET + Invite user: u i + Ignore user: u I + +Room + + Occur search in room: M-s o + List members: r m + Set topic: r t + Set message format: r f + Tag/untag room: r T + +Room membership + + Create room: R c + Join room: R j + Leave room: R l + Forget room: R F + +Other + + Sync new messages (not necessary if auto sync is enabled; with prefix to force new sync): g + +Room list buffer + + Show buffer of room at point: RET + Show buffer of next unread room: SPC + Move between room names: TAB / + +Mentions/notifications buffers + + Move between events: TAB / + Go to event at point in its room buffer: RET + Write reply to event at point (shows the event in its room while writing) : S-RET + +Tips + + Desktop notifications are enabled by default for events that mention the local user. They can also be shown for all events in rooms with open buffers. + Send messages in Org mode format by customizing the option ement-room-send-message-filter (which enables Org format by default), or by calling ement-room-compose-org in a compose buffer (which enables it for a single message). Then Org-formatted messages are automatically converted and sent as HTML-formatted messages (with the Org syntax as the plain-text fallback). You can send syntax such as: + Bold, italic, underline, strikethrough + Links + Tables + Source blocks (including results with :exports both) + Footnotes (okay, that might be pushing it, but you can!) + And, generally, anything that Org can export to HTML + Starting in the room list buffer, by pressing SPC repeatedly, you can cycle through and read all rooms with unread buffers. (If a room doesn’t have a buffer, it will not be included.) + Room buffers and the room-list buffer can be bookmarked in Emacs, i.e. using C-x r m. This is especially useful with Burly: you can arrange an Emacs frame with several room buffers displayed at once, use burly-bookmark-windows to bookmark the layout, and then you can restore that layout and all of the room buffers by opening the bookmark, rather than having to manually arrange them every time you start Emacs or change the window configuration. + Images and other files can be uploaded to rooms using drag-and-drop. + You can customize settings in the ement group. + Note: setq should not be used for certain options, because it will not call the associated setter function. Users who have an aversion to the customization system may experience problems. + +Displaying symbols and emojis + +Emacs may not display certain symbols and emojis well by default. Based on this question and answer, you may find that the simplest way to fix this is to install an appropriate font, like Noto Emoji, and then use this Elisp code: + +(setf use-default-font-for-symbols nil) +(set-fontset-font t 'unicode "Noto Emoji" nil 'append) + +Encrypted room support through Pantalaimon + +Ement.el doesn’t support encrypted rooms natively, but it can be used transparently with the E2EE-aware reverse proxy daemon Pantalaimon. After configuring it according to its documentation, call ement-connect with the appropriate hostname and port, like: + +(ement-connect :uri-prefix "http://localhost:8009") + +** declare Module feature :noexport: +:PROPERTIES: +:ID: 2F924867-04AB-40C9-8B99-9413F64C019E +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-correspondences) +#+end_src + +* /Chapter/ *4*, Acculturations :export:provide@rapport_acculturations#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-acculturations.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +Information and Memetics + +** as Knowledge Capture and Management +:PROPERTIES: +:ID: 9FB5D06E-325C-4481-A482-0A3BB9C510A7 +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-acculturations-concepts.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** Drag and Drop Images into Org-Mode Buffers +:PROPERTIES: +:ID: 8CF43B22-9DDB-4DD4-99F5-A06C01A2B8ED +:CREATED: [2022-04-20 Wed 23:27] +:END: + +setup =org-download= + #+begin_src emacs-lisp +;; https://github.com/abo-abo/org-download +(use-package org-download + ;; This extension facilitates capturing images from: + ;; - An image inside your browser that you can drag to Emacs. + ;; - An image on your file system that you can drag to Emacs. + ;; - A local or remote image address in kill-ring. Use the org-download-yank command for this. Remember that you can use "0 w" in dired to get an address. + ;; - A screenshot taken using gnome-screenshot, scrot, gm, xclip (on Linux), screencapture (on OS X) or , imagemagick/convert (on Windows). Use the org-download-screenshot command for this. Customize the backend with org-download-screenshot-method. + ;; - Pasting from the clipboard. If you have the image stored in the clipboard, use org-download-clipboard. + :after (:all org) + :custom + (org-download-method 'attach) + (org-download-heading-lvl nil) + (org-download-timestamp t) + (org-download-timestamp "%Y%m%d-%H%M%S_") + (org-image-actual-width 300) + (org-download-screenshot-method (concat (executable-find "pngpaste") " %s")) + + :hook ((dired-mode . org-download-enable) ;; Drag-and-drop to `dired` + (org-mode. org-download-enable)) + :bind + ("C-M-y" . org-download-screenshot) + + :config + (require 'org-download) + (progn)) + + #+end_src + +*** Zettlekasten with <<>> +:PROPERTIES: +:ID: 84E27EEE-B6A6-4CDD-BCDB-B2FAE0BCC0B6 +:END: +:LOGBOOK: +- Refiled on [2022-04-17 Sun 03:31] +- Refiled on [2021-11-29 Mon 22:21] +:END: +setup =org-roam= + #+begin_src emacs-lisp +;; ,ref: https://github.com/magit/emacsql + ;(use-package emacsql :demand :straight (:repo "magit/emacsql" :host github :type git :files (:defaults "*.el"))) +;; https://github.com/org-roam/org-roam +(use-package org-roam + ;; Org-roam requires sqlite to + ;; function. Org-roam optionally + ;; uses Graphviz for + ;; graph-related + ;; functionality. It is + ;; recommended to install + ;; PCRE-enabled ripgrep for + ;; better performance and + ;; extended functionality. + + :init + (setq org-roam-v2-ack t) + ;;:ensure-system-package (sqlite graphviz ripgrep) + :demand t + :after (:all emacsql) + :hook (consult-org-roam) + :custom + (org-roam-directory rapport-uri-vault-docs) + (org-roam-db-location (expand-file-name "org-roam.sqlite" (expand-file-name "org-roam" rapport-uri-vault-var-emacs))) + ;;default;;(org-roam-capture-templates (("d" "default" plain "%?" :target (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n") :unnarrowed t))) + (org-roam-capture-templates + `(("d" "default" plain "%?" + :target (file+head ,(expand-file-name "%<%Y%m%d%H%M%S>-${slug}.org" rapport-uri-vault-docs-concepts) + ,(mapconcat 'identity `( + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:" "" + "#+title: ${title}" + "#+filetags: " + "#+subtitle: " + ,(concat "# #+setupfile: " rapport-uri-vault-cfgs-emacs-apps-org-setupfile) + "#+STARTUP: overview hideblocks indent nonum align inlineimages fnadjust entitiespretty" + "#+OPTIONS: ^:{} author:nil broken-links:mark creator:nil d:nil email:nil H:6 num:nil prop:nil stat:nil tags:nil timestamp:nil todo:done tex:t" + "" "\\\\" "" + "* /{{{title}}}/ | Abstract :noexport:" + ":PROPERTIES:" + ":UNNUMBERED: notoc" + ":END:" "" + "#+BEGIN_abstract" + "#+BEGIN_center" + "#+END_center" + "#+END_abstract" + "#+TOC: headlines 2" "" + "" + "--- _/overview/_ ---" + " -" + "" + "* /{{{title}}}/ | References :noexport:" + "" + "--- _/info/notes/_ ---" + "- *on Sources*" + " #+NAME: %(org-id-new)" + " #+CAPTION: reference list" + " |!|title|url|desc|rowid|" + " | |title|url|desc|rowid|" + " |-|-----|---|----|-----|" + " |/| | | | <7> |" + " |#| | | | |" + " #+TBLFM: $5='(if (and (string= @1$rowid \"rowid\") (string= $rowid \"\")) (concat \"<<\"(org-id-new) \">>\") $rowid)" + "" + "- *on Inquiries*" + "" + "- *on Contacts*" + "" + "* /{{{title}}}/ | local-Refile :noexport:REFILE:" + ) + "\n")) + :unnarrowed t))) + (org-roam-dailies-directory "events") + (org-roam-dailies-capture-templates + '( + ;("d" "default" entry "* %<%I:%M %p>: %?" :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")) ;; ,ref: https://systemcrafters.net/build-a-second-brain-in-emacs/keep-a-journal/ + ;; ,WIP: I'd like the file name to match the name component of a Composure "event" type, which is `event@_` + ("d" "default" entry "* %<%I:%M %p>: %?" :if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n")) + + )) + ;; If you're using a vertical completion framework, you might want a more informative completion interface + (org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag))) + (org-roam-completion-everywhere t) + ;(org-roam-completion-functions '(company-org-roam org-roam-link-at-point org-roam-complete-everywhere)) + :commands + (org-roam org-roam-refile org-roam-node-find org-roam-node-insert) + :bind ( + ;; ("C-c n l" . org-roam-buffer-toggle) + ;; ("C-c n f" . org-roam-node-find) + ;; ("C-c n i" . org-roam-node-insert) + ("C-c n c" . org-roam-capture) + ("C-c n C-c C-w" . org-roam-refile) + ;; Dailies + :map org-roam-dailies-map + ("c" . org-roam-dailies-capture-today) + ("T" . org-roam-dailies-capture-tomorrow) + ("Y" . org-roam-dailies-capture-yesterday) + ("d" . org-roam-dailies-find-directory) + ("C-n" . org-roam-dailies-goto-next-note) + ("C-p" . org-roam-dailies-goto-previous-note) + ("j" . org-roam-dailies-goto-date) + ("J" . org-roam-dailies-capture-date) + ("." . org-roam-dailies-goto-today) + ("t" . org-roam-dailies-goto-tomorrow) + ("y" . org-roam-dailies-goto-yesterday) + ) + :bind-keymap + ("C-c n d" . org-roam-dailies-map) + :config + (org-roam-db-autosync-mode) + ;; If using org-roam-protocol. ,ref: https://www.orgroam.com/manual.html#org_002droam_002dprotocol + ;; ,TODO: 20231203_NGa implicated in errors ;; (require 'org-roam-protocol) + (require 'org-roam-dailies) ;; Ensure the keymap is available + (progn)) + + +(use-package org-roam-ui + :after (:all org-roam) + ;; normally we'd recommend hooking orui after org-roam, but since org-roam does not have + ;; a hookable mode anymore, you're advised to pick something yourself + ;; if you don't care about startup time, use + ;; :hook (after-init . org-roam-ui-mode) + :commands (org-roam-ui-open) + :config + (setq org-roam-ui-sync-theme t + org-roam-ui-follow t + org-roam-ui-update-on-save t + org-roam-ui-open-on-start t)) + + +;; WIP +(use-package org-roam-bibtex + :disabled + :after (:all org-roam org-ref bibtex) + :config + ;; optional: if using Org-ref v2 or v3 citation links + (require 'org-ref) + (progn)) + + +;; https://github.com/publicimageltd/delve +(use-package delve + :after (:all org-roam) + :ensure (delve :repo "publicimageltd/delve" :host github :type git) + ;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:repo "publicimageltd/delve" :host github :type git) + :bind + ;; the main entry point, offering a list of all stored collections + ;; and of all open Delve buffers: + (("" . delve)) + :commands delve + :custom + (delve-store-directory (expand-file-name "delve-store" rapport-uri-vault-var-emacs)) + ;; set meaningful tag names for the dashboard query, see [[id:B8C78370-BD9B-4991-BB21-5901EF9A35CA][Composure]] + (delve-dashboard-tags '()) + :config + ;; turn on delve-minor-mode when org roam file is opened: + (delve-global-minor-mode)) + #+end_src +*** Citation Management with <<>> +:PROPERTIES: +:ID: 99DB425E-9DD3-4781-87DB-91A36A19B8E2 +:END: +For citations, cross-references, bibliographies in org-mode and useful bibtex tools to go with it. + +#+begin_src emacs-lisp + ;; ,ref: https://github.com/jkitchin/org-ref + (use-package org-ref + :config + (progn)) +#+end_src +*** Physical Object Placement Catalog +:PROPERTIES: +:ID: 50FA7C09-D374-4214-8471-280A84C015CB +:CREATED: [2022-04-20 Wed 20:52] +:END: + +setup =org-real= + #+begin_src emacs-lisp +;; https://gitlab.com/tygrdev/org-real +(use-package org-real + ;; Keep track of real things as org-mode links. + ;; + ;; Usage + ;; Inserting a link + ;; To create a real link in org-mode, use C-c C-l real RET. + ;; Real links are created inside-out, starting with the most specific + ;; item and working to the most general. + ;; β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + ;; β”‚ β”‚ + ;; β”‚ outside β”‚ + ;; β”‚ ↑ β”‚ + ;; β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ ↑ ───────────┐ β”‚ + ;; β”‚ β”‚ ↑ β”‚ β”‚ + ;; β”‚ β”‚ ↑ β”‚ β”‚ + ;; β”‚ β”‚ ↑ β”‚ β”‚ + ;; β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€ ↑ ────────┐ β”‚ β”‚ + ;; β”‚ β”‚ β”‚ ↑ β”‚ β”‚ β”‚ + ;; β”‚ β”‚ β”‚ inside β”‚ β”‚ β”‚ + ;; β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ + ;; β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ + ;; β”‚ β”‚ β”‚ β”‚ + ;; β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ + ;; β”‚ β”‚ + ;; β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + ;; + ;; The first prompt will be for the thing which is trying to be linked + ;; to, called the β€œprimary thing”. Then, the prompt will continue to + ;; ask if more context should be added by pressing + until the user + ;; confirms the link with RET. + ;; + ;; Inserting a link with completion + ;; Org real will help create links by parsing all existing links in + ;; the current buffer. When choosing an existing thing, all of the + ;; context for that thing is automatically added to the current + ;; completion. + ;; This is only possible because of the unique inside-out completion + ;; style for inserting a link and makes it very easy to add new things + ;; to an existing container. + ;; + ;; Rearranging things + ;; In order to edit a real link, place the cursor on the link and + ;; press C-c C-l. Narrow the link down beyond the context you wish + ;; to change by pressing BACKSPACE repeatedly, then + to add the + ;; new context. + ;; + ;; If any container in the new link does not match an existing + ;; container in the buffer, org-real will prompt you to replace all + ;; occurences of that thing with the new context and relationships. + ;; This makes it easy to keep things in sync. If any one link changes + ;; location, all links in the currnet buffer are updated accordingly. + ;; + ;; If a link is changed manually, use the interactive function + ;; org-real-apply with the cursor on top of the new link to apply + ;; changes from that link to the buffer. + ;; Opening links + ;; To open a real link, place the cursor within the link and press + ;; C-c C-o. This will display a popup buffer in Org Real mode + ;; showing the location of the link. + ;; org-real-world + ;; To view all real links in the current buffer in a combined diagram, + ;; use the interactive function org-real-world + ;; Suggested keybinding: + ;; (define-key org-mode-map (kbd "C-c r w") 'org-real-world) + :bind (:map org-mode-map + ("C-c r w" . org-real-world)) + :config + (progn)) + #+end_src +*** delcare feature +:PROPERTIES: +:ID: B0B56DE2-C307-4968-87CE-C5361FF67ED3 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-acculturations-concepts) +#+end_src +** as Multimedia Controller and Manager +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-acculturations-media.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** Audio Media Player w/ EMMS +:PROPERTIES: +:ID: 2AA8D2E9-8B81-458F-B152-E1349020AD5A +:END: + + #+begin_src emacs-lisp +;; EMMS - Emacs MultiMedia System +;; https://www.gnu.org/software/emms/ +(use-package emms + :ensure-system-package (mpv) + :custom + ;; When asked for emms-play-directory, always start from this one + (path-emms-library `( ,(expand-file-name "media_annex" rapport-uri-vault-uris))) + :commands (emms emms-minimal emms-standard emms-all) + ;; to get track info, (for ogg,flac,mp3's respectively) + ;:ensure-system-package (vorbis-tools flac mp3info) + :config + (require 'emms-setup) + ;; select the 'setup' level, ( minimal -> standard -> all -> devel ) + ;; from more conservative -> more experimental + (emms-all) + (emms-default-players) + ;; Show the current track each time EMMS + ;; starts to play a track with "NP : " + (add-hook 'emms-player-started-hook 'emms-show) + (setq emms-show-format "NP: %s") + ;; When asked for emms-play-directory, + ;; always start from this one + ;(setq emms-source-file-default-directory path-emms-library) + ;(setq emms-directory path-emms-library) + ;; control volume from playlist with + and - keys + (require 'emms-volume) + ;; set path to media library cache, enable, restore, sync + ;(setq emms-cache-file path-emms-cache) + (emms-cache-enable) + (emms-cache-restore) + ;(emms-cache-sync) + (when (and + (bound-and-true-p emms-librefm-scrobbler-username) + (bound-and-true-p emms-librefm-scrobbler-password)) + (emms-librefm-scrobbler-enable)) + (progn)) + + #+end_src + + + - setup =org-emms= + #+begin_src emacs-lisp +;; https://gitlab.com/jagrg/org-emms +(use-package org-emms + :after (:all org emms) +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:type git :host github :repo "jagrg/org-emms") + :config + (progn)) + #+end_src + +*** Video Player with <<>> +:PROPERTIES: +:ID: D4FB3629-7AF7-4A29-A7D5-ECD1321363B3 +:END: +#+begin_src emacs-lisp +;; ,ref: https://github.com/isamert/empv.el +(use-package empv +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:host github :repo "isamert/empv.el") + :bind-keymap ("C-x m" . empv-map) + :custom + ;; ,HINT: you can select an Invidious instance, here: https://api.invidious.io/ + (empv-invidious-instance "https://invidious.asir.dev/api/v1") + ;; ,HINT: Resetting playback speed after quit + ;; If you have applied the workaround above, you can set the following option to non-nil and from then on, whenever you hit q in mpv’s video view, the playback speed will be reset to 1. This should be set before starting empv (or quit it first by doing empv-quit and re-start it to apply this configuration). + (empv-reset-playback-speed-on-quit t) + ;; media paths + (empv-max-directory-search-depth 8) + (empv-base-directory rapport-uri-vault-docs-media) + (empv-audio-dir (expand-file-name "audio" rapport-uri-vault-docs-media)) + (empv-video-dir (expand-file-name "video" rapport-uri-vault-docs-media)) + (empv-playlist-dir (expand-file-name "collection" rapport-uri-vault-docs-media)) + + :config + ;; ,HINT: Viewing YouTube videos + ;; If you start playing a YouTube video, it’ll start playing in background. You may be tempted to call empv-toggle-video to start watching the video itself but it’ll not work. mpv tries to be smart when it’s in background and it only downloads the audio if it’s possible. If you want to be able to watch YouTube videos whenever you want, you need to add something like this to your configuration to force-download videos: + (add-to-list 'empv-mpv-args "--ytdl-format=best") + ;; ,HINT: Saving playback position + ;; =empv-save-and-exit= shuts down empv and saves the current playing position but you can also add =--save-position-on-quit= to =empv-mpv-args= to get the same effect by default so that every time you quit empv, it’ll automatically save the playback position of the currently playing file and it’ll seek to previous position on start. + (add-to-list 'empv-mpv-args "--save-position-on-quit") + (progn)) +#+end_src + +--- _/info/notes/_ --- + +*on [[https://mpv.io/manual/master/#keyboard-control][Keyboard Controls]]* +| keys | behavior | +|---------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| LEFT and RIGHT | Seek backward/forward 5 seconds. Shift+arrow does a 1 second exact seek (see --hr-seek). | +| UP and DOWN | Seek forward/backward 1 minute. Shift+arrow does a 5 second exact seek (see --hr-seek). | +| Ctrl+LEFT and Ctrl+RIGHT | Seek to the previous/next subtitle. Subject to some restrictions and might not always work; see sub-seek command. | +| Ctrl+Shift+Left and Ctrl+Shift+Right | Adjust subtitle delay so that the next or previous subtitle is displayed now. This is especially useful to sync subtitles to audio. | +| [ and ] | Decrease/increase current playback speed by 10%. | +| { and } | Halve/double current playback speed. | +| BACKSPACE | Reset playback speed to normal. | +| Shift+BACKSPACE | Undo the last seek. This works only if the playlist entry was not changed. Hitting it a second time will go back to the original position. See revert-seek command for details. | +| Shift+Ctrl+BACKSPACE | Mark the current position. This will then be used by Shift+BACKSPACE as revert position (once you seek back, the marker will be reset). You can use this to seek around in the file and then return to the exact position where you left off. | +| < and > | Go backward/forward in the playlist. | +| ENTER | Go forward in the playlist. | +| p / SPACE | Pause (pressing again unpauses). | +| . | Step forward. Pressing once will pause, every consecutive press will play one frame and then go into pause mode again. | +| , | Step backward. Pressing once will pause, every consecutive press will play one frame in reverse and then go into pause mode again. | +| q | Stop playing and quit. | +| Q | Like q, but store the current playback position. Playing the same file later will resume at the old playback position if possible. See RESUMING PLAYBACK. | +| / and * | Decrease/increase volume. | +| 9 and 0 | Decrease/increase volume. | +| m | Mute sound. | +| ~_~ | Cycle through the available video tracks. | +| ~#~ | Cycle through the available audio tracks. | +| E | Cycle through the available Editions. | +| f | Toggle fullscreen (see also --fs). | +| ESC | Exit fullscreen mode. | +| T | Toggle stay-on-top (see also --ontop). | +| w and W | Decrease/increase pan-and-scan range. The e key does the same as W currently, but use is discouraged. | +| o (also P) | Show progression bar, elapsed time and total duration on the OSD. | +| O | Toggle OSD states between normal and playback time/duration. | +| v | Toggle subtitle visibility. | +| j and J | Cycle through the available subtitles. | +| z and Z | Adjust subtitle delay by +/- 0.1 seconds. The x key does the same as Z currently, but use is discouraged. | +| l | Set/clear A-B loop points. See ab-loop command for details. | +| L | Toggle infinite looping. | +| Ctrl + and Ctrl - | Adjust audio delay (A/V sync) by +/- 0.1 seconds. | +| Shift+g and Shift+f | Adjust subtitle font size by +/- 10%. | +| u | Switch between applying no style overrides to SSA/ASS subtitles, and overriding them almost completely with the normal subtitle style. See --sub-ass-override for more info. | +| V | Toggle subtitle VSFilter aspect compatibility mode. See --sub-ass-vsfilter-aspect-compat for more info. | +| r and R | Move subtitles up/down. The t key does the same as R currently, but use is discouraged. | +| s | Take a screenshot. | +| S | Take a screenshot, without subtitles. (Whether this works depends on VO driver support.) | +| Ctrl s | Take a screenshot, as the window shows it (with subtitles, OSD, and scaled video). | +| PGUP and PGDWN | Seek to the beginning of the previous/next chapter. In most cases, "previous" will actually go to the beginning of the current chapter; see --chapter-seek-threshold. | +| Shift+PGUP and Shift+PGDWN | Seek backward or forward by 10 minutes. (This used to be mapped to PGUP/PGDWN without Shift.) | +| d | Activate/deactivate deinterlacer. | +| A | Cycle aspect ratio override. | +| Ctrl h | Toggle hardware video decoding on/off. | +| Alt+LEFT, Alt+RIGHT, Alt+UP, Alt+DOWN | Move the video rectangle (panning). | +| Alt + and Alt - | Combining Alt with the + or - keys changes video zoom. | +| Alt+BACKSPACE | Reset the pan/zoom settings. | +| F8 | Show the playlist and the current position in it (useful only if a UI window is used, broken on the terminal). | +| F9 | Show the list of audio and subtitle streams (useful only if a UI window is used, broken on the terminal). | +| i and I | Show/toggle an overlay displaying statistics about the currently playing file such as codec, framerate, number of dropped frames and so on. See STATS for more information. | +| del | Cycle OSC visibility between never / auto (mouse-move) / always | +| ~`~ | Show the console. (ESC closes it again. See CONSOLE.) | + + +*** declare feature :noexport: +:PROPERTIES: +:ID: 82ADC3FE-616D-47D0-A5B5-6C381120C91E +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-acculturations-media) +#+end_src +** as Content Browser and Capturer +:PROPERTIES: +:ID: as-Content-Browser-and-Capturer-2023-06-15-17-39-04 +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-acculturations-infowebs.el" (org-sbe rapport-sbe--get-libdir)) +:END: +*** Emacs Web Wowser (aka <<>>) +:PROPERTIES: +:ID: 136C3241-B803-4FA7-A1DF-B1F6AAEB72DC +:END: + #+begin_src emacs-lisp +(setq eww-search-prefix "https://www.google.com/search?q=") + #+end_src +*** EPub Reader w/ <<>> +:PROPERTIES: +:ID: 963D4732-9A8C-4F9C-843E-D6273581C923 +:END: +setup =nov-mode= + #+begin_src emacs-lisp + (use-package nov + :mode ("\\.epub\\'" . nov-mode)) + #+end_src +*** RSS Feed Reader w/ <<>> +:PROPERTIES: +:ID: D7C84768-A35D-4443-BCF8-B098944D4146 +:END: +setup =elfeed= + #+begin_src emacs-lisp +;; +(use-package elfeed + :custom + ;; display the elfeed-score values in a column in the main elfeed-search buffer + (elfeed-search-print-entry-function #'elfeed-score-print-entry) + :config + (progn)) + #+end_src +**** setup ElFeed extensions +***** enable <<>> +#+begin_src emacs-lisp +;; +(use-package elfeed-protocol + :after (:all elfeed) + :hook elfeed + :config + (elfeed-protocol-enable) + (progn)) +#+end_src +***** enable <<>> +:PROPERTIES: +:ID: 74F36A1A-F35E-44B6-85FA-222219C4B090 +:END: + #+begin_src emacs-lisp +(use-package elfeed-org + ;:disabled ;; 20210131_NGa disabled, implicated in redifining 'org-version from my custom definition + :after (:all org elfeed) + :hook elfeed + :custom + (rmh-elfeed-org-files (list (expand-file-name "elfeed.org" (expand-file-name "collection" rapport-uri-vault-docs-media)))) + (rmh-elfeed-org-auto-ignore-invalid-feeds t) ;; ,HINT: Tag feeds to ignore them when a feed could not loaded. + :config + (elfeed-org) + + ;; 20190323_NGa set 'o' keypress to open w/i Emacs using EWW + (defun elfeed-search-browse-url-in-eww () "" + (interactive) + (let* + ((entry (elfeed-search-selected :single)) + (entry-valid 't)) + (when entry-valid + (eww-browse-url (elfeed-entry-link entry))))) + (defun elfeed-show-browse-url-in-eww () "" + (interactive) + (message " ... not implemented ... ")) + :hook elfeed + :bind + (:map elfeed-search-mode-map + ("o" . elfeed-search-browse-url-in-eww) + :map elfeed-show-mode-map + ("o" . elfeed-show-browse-url-in-eww) + )) + #+end_src + +***** enable <<>> :pending_review:feature_preview: + +Apply simple rules-based actions, (eg adding Tags and heirarchy) to newly-added Elfeed-Org entries. + +Rules are configured in the file(s) pointed to by the 'elfeed-autotag-files list variable, which encode rules using Org-Mode format. + +By default autotag only runs on new entries. + +To add new tags to old posts run, =M-x elfeed-apply-hooks-now=, though this may leave redundant tags (to be removed by hand). + +Future versions /may/ use a more robust synchronization with the actual elfeed database. For now though it's functional, if a bit naive. + +#+begin_src emacs-lisp +;; ,ref: https://github.com/paulelms/elfeed-autotag + +;; ,HINT: AutoTag Rules are encoded using Orgmode format + +;; +;; * feeds :elfeed: +;; ** Reddit :reddit: +;; *** feed-url: reddit.com +;; *** [[https://www.reddit.com/r/listentothis/.rss][Listen To This]] :music: +;; feed renaming +;; ** Emacs :emacs: +;; *** entry-title: \(emacs\|org-mode\) +;; *** https://planet.emacslife.com/atom.xml :mustread: +;; + +;; +;; * feeds :elfeed: +;; ** example01_rule_name :tags_to_apply_on_example01_match: +;; *** feed-url: +;; ** example02_rule_name :tags_to_apply_on_example02_match: +;; *** entry-title: +;; *** :specific_tag_for_specific_feed_url_under_example02: +;; + +(use-package elfeed-autotag + ;; ,HINT: inhibit loading the package if the config file is absent + :if (file-readable-p (expand-file-name "autotags.org" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :after (:all elfeed elfeed-org) + :hook elfeed + :custom + (elfeed-autotag-files (expand-file-name "autotags.org" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :config + (elfeed-autotag) + (progn)) +#+end_src +***** enable <<>> :feature_preview: +:PROPERTIES: +:ID: 74DC7404-116E-4436-A73D-4C9059244FFE +:END: + +elfeed-score brings Gnus-style scoring to Elfeed. + +This package defines a bit of metadata for each of your feed entries: a β€œscore”. A score is an integer (negative or positive), and higher scores denote entries of greater interest to you. This package also (optionally) installs a new sort function, so that Elfeed will display entries with higher scores before entries with lower scores (entries with the same scores will still be sorted in reverse chronological order). It also provides an entry display function for the elfeed search buffer that displays each entry’s score, should you choose to install it. + +While you can manually assign a score to an entry, you will likely find it more convenient to create rules for scoring that will be automatically applied to each new entry every time you update Elfeed. You can score against title, feed, content, authors & entry link by defining strings that will be matched against those attributes by substring, regexp or whole-word match. You can score against the feed (on the basis of title, URL, or feed author). You can also score against the presence or absence of tags. If none of these do what you want, you can author your own functions & score based on them. Rules can be scoped by Elfeed entry tags or by their feed, so that a rule will only be applied to a subset of your entries. Each rule defines an integral value, and the rules are applied in order of definition. The new entry’s score begins at elfeed-score-scoring-default-score, and is adjusted by the value defined by each matching scoring rule. + +Usage Examples: +- https://www.youtube.com/watch?v=rvWbUGx9U5E +- https://koustuvsinha.com/post/emacs_research_workflow/#scoring-papers +- https://cundy.me/post/elfeed/ + +#+begin_src emacs-lisp +(use-package elfeed-score + :if (file-readable-p (expand-file-name "score.el" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :after (:all elfeed) + :custom + (elfeed-score-score-file (expand-file-name "score.el" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + (elfeed-score-rule-stats-file (expand-file-name "elfeed.stats" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :hook elfeed + :config + (elfeed-score-enable) + (define-key elfeed-search-mode-map "=" elfeed-score-map) + (progn)) +#+end_src + +/on Usage/ +- Scoring can be viewed and adjusted from within the typical =*elfeed-search*= window. Press ~= ?~ to see a list of options. + +***** enable <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: 33EA8B67-1232-4D21-A07C-581B7870B93B +:END: +#+begin_src emacs-lisp +(use-package elfeed-summary + :after (:all elfeed) + :hook elfeed + :config + (progn)) +#+end_src +***** enable <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: 4040D72A-E7ED-471D-B2FB-32DAD010A9BF +:END: +#+begin_src emacs-lisp +(use-package elfeed-dashboard + :if (file-readable-p (expand-file-name "dashboard.org" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :after (:all elfeed) + :hook elfeed + :custom + (elfeed-dashboard-file (expand-file-name "dashboard.org" (expand-file-name "elfeed" rapport-uri-vault-cfgs-emacs-apps))) + :config + ;; update feed counts on elfeed-quit + (advice-add 'elfeed-search-quit-window :after #'elfeed-dashboard-update-links) + (progn)) +#+end_src + +/on Usage/ +- =M-x elfeed-dashboard= will bring up the UI +- =E= will let you edit in org-mode +- =U= will fetch new feeds. If elfeed-org is installed then it will call (elfeed-org) before fetching. +- Add new key maps in configuration section and call M-x elfeed-dashboard-mode to install. + +*** PDF Reader w/ Doc-View +:PROPERTIES: +:ID: 759436B2-06AE-40D3-AB58-1D0846C73EC4 +:END: +- prcedure : setup =doc-view-mode= + #+begin_src emacs-lisp + ;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html + ;; To work, the needed external tool for the document type must be available, and Emacs must be running in a graphical frame and have PNG image support. + ;; If these requirements is not fulfilled, Emacs falls back to another major mode. + ;; To Display PDF, the =gs= (GhostScript) tool must be available. + (use-package doc-view + ;:ensure-system-package (ghostscript imagemagick) + ;:ensure-system-package gs + :ensure nil + + :mode ("\\.pdf\\'" . doc-view-mode) + :config + (progn)) + #+end_src +setup =pdf-view-restore= + #+begin_src emacs-lisp + (use-package pdf-view-restore :disabled) + #+end_src +*** Capture Web Page from Web Browser as Org-Mode Content +:PROPERTIES: +:ID: 27825749-4C98-4270-94E8-9002E56D1C2D +:END: +setup =org-protocol-capture-html= + #+begin_src emacs-lisp + ;; https://github.com/alphapapa/org-protocol-capture-html + (use-package org-protocol-capture-html + :after (:all s doct) + :demand t + :if (or (eq system-type 'darwin) ;; Setting up Org-protocal with Firefox on macOS - https://www.ying-ish.com/essay/org-capture-with-firefox/ + nil) ;; default to false + :init + (require 's) + (rapport/doct/append + (doct `(("Protocol" :keys "p" + :file ,org-default-notes-file + :template ("* %{_preface} %? [[%:link][%:description]] %{_tags}" + ":PROPERTIES:" + ":ID: %(org-id-new)" + ":CREATED: %U" + ":END:" + "%i") + :_preface "%a" + :_tags "" + :prepend t + :empty-lines-after 2 + :immediate-finish t + :jump-to-captured t + :kill-buffer t + :children + (("capture Selected Text" :keys "s" + :file "" + :template ("* %a :website:\n\n%U %?\n\n%:initial")) + ))))) + ;; https://github.com/alphapapa/org-protocol-capture-html#requirements + :ensure-system-package ( + ;; - Pandoc: Version 1.8 or later is required. + pandoc + ;; - The shell script uses curl to download URLs (if you use it in that mode). + curl) + :ensure (org-protocol-capture-html :type git :host github :repo "alphapapa/org-protocol-capture-html") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (org-protocol-capture-html :type git :host github :repo "alphapapa/org-protocol-capture-html") + :config + (progn)) + #+end_src + +setup Org-Protocol to receive external hooks within Emacs + - nb + - Org-protocol is the agent between external applications and Emacs, meaning you can trigger Emacs actions outside of it. The official page is a bit outdated, though. + - The guide recommended by Org-protocal-capture-html no longer works for me. I found the tutorial of org-capture extension useful. + - excerpt from website, Setting up Org-protocal with Firefox on macOS - https://www.ying-ish.com/essay/org-capture-with-firefox/ + #+begin_example + Preparing the emacsclient application + + You can continue following the guide here creating your own emacsclient application or you can download the prepared dmg package directly. I recommend the latter. + + + Emacs configuration + + In your init file or equivalent, adding + + (server-start) + (require 'org-protocol) + + and, + + (setq org-directory "~/org-notes") + (setq org-default-notes-file (concat org-directory "/notes.org")) + (define-key global-map "\C-cc" 'org-capture) + + (defun transform-square-brackets-to-round-ones(string-to-transform) + "Transforms [ into ( and ] into ), other chars left unchanged." + (concat + (mapcar #'(lambda (c) (if (equal c ?[) ?\( (if (equal c ?]) ?\) c))) + string-to-transform))) + + (setq org-capture-templates + '(("w" "Web site" entry + (file org-default-notes-file) + "* %c :website:\n%U %?%:initial"))) + + (setq org-protocol-default-template-key "w") + + In terminal, input + + emacsclient -n "org-protocol:///capture?url=https://www.wikipedia.org/" + + and a Org-capture buffer should appear in the current or a new Emacs window. Replace any url you want to test after url=. + + If the capture buffer doesn’t pop up or the capture template is wrong, make sure to check what goes wrong in earlier setting. + Firefox integration + + This is achieved by a javascript bookmarklet. Before creating the bookmarklet, type about:config in Firefox url address space. Upon entering it, you will likely see a blank page with a search bar on top. In that search area, type network.protocol-handler.expose.org-protocol and choose the boolean option, then setting the value to true. + + To sure to do this step if you don’t want all your current tabs go missing if any issues occurs when testing the bookmarklet. + + Right-click menu bar and select add a new bookmark … and pasting the following javescript into the Location region: + + javascript:location.href = 'org-protocol://capture-eww-readable?template=w&url=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title || "[untitled page]"); + + Pandoc Installation* + + It is unlikely, but in case the Pandoc is not installed, run + + brew install pandoc + + + #+end_example + - As a final test, Open any webpage and hit the bookmarklet, a organized webpage in org-mode should appear in Emacs. + +*** Import Web Pages w/ Org-Web-Tools +:PROPERTIES: +:ID: D13BCD23-A1FD-47DE-962D-150093728782 +:END: +:LOGBOOK: +- Refiled on [2022-04-23 Sat 14:08] +:END: + +setup =org-web-tools= + #+begin_src emacs-lisp +;; https://github.com/alphapapa/org-web-tools +(use-package org-web-tools + :init + (eval-after-load 'doct + (lambda () + (rapport/doct/append + (doct + `(("Protocol" :keys "p" + :children + (("🌎 capture Webpage As Org Entry" :keys "w" + :file "" + :type plain + :empty-lines-after 2 + :immediate-finish t + :jump-to-captured t + :kill-buffer t + :template "%(org-capture-put :SOURCE_URL \"%:link\")" + :hook ,(lambda () + (org-web-tools-insert-web-page-as-entry + (org-capture-get :SOURCE_URL))) + )))))))) + ;; requires `pandoc` + :ensure-system-package pandoc + :custom + (org-web-tools-pandoc-sleep-time 1) + (org-protocol-default-template-key "pw") + :config + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: F577236C-0594-440E-8B70-61F3053C175C +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-acculturations-infowebs) +#+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: 05BFCC92-F9DC-4F97-9291-5BE90897EED1 +:END: +#+begin_src emacs-lisp +;; +(require 'rapport-acculturations-concepts) +(require 'rapport-acculturations-media) +(require 'rapport-acculturations-infowebs) +;; +(elpaca-wait) +(provide 'rapport-acculturations) +#+end_src + +* /Chapter/ *5*, Eminences :export:provide@rapport_eminences#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-eminences.el" (org-sbe rapport-sbe--get-libdir)) +:ID: 1D59B3C4-2BF1-4FA2-AD9F-3165AC15166A +:END: + +Influence, Impact, and Reputation + +** as Professional Portfolio Manager +*** OPEN Resume :pending_review: +:PROPERTIES: +:ID: A84DB823-1CC0-4CF7-8ED8-CCE7E7E2A30B +:END: +:LOGBOOK: +- State "REPORTED" from [2022-10-10 Mon 18:17] +:END: + #+begin_src emacs-lisp +(use-package ox-altacv + :disabled + :ensure (ox-altacv :type git :host github :repo "lccambiaghi/org-cv") + :config (require 'ox-altacv)) + #+end_src +** as Presentation and Publication Studio +*** Export to HTML w/ Twitter Bootstrap +:PROPERTIES: +:ID: AE1CB7A5-18C1-4B04-B460-EDF4A2D85980 +:END: +setup =ox-twbs= + #+begin_src emacs-lisp + (use-package ox-twbs) + #+end_src + +*** Export to HTML Slides w/ Reveal.js +:PROPERTIES: +:ID: 004DF9E4-3FA6-4D6B-91E4-FE97D88D05EF +:END: +- context :: + - info/notes + - srcs + - https://github.com/asciinema/asciinema-player + - https://github.com/yjwen/org-reveal + - on Embedding Asciinema Player + - Use ~~, filling in your own ~src~ info. + +setup reveal.js + #+begin_src emacs-lisp + +(use-package htmlize) + +;; https://github.com/yjwen/org-reveal +(use-package ox-reveal + ;; NB: Initialization config is passed to RevealJS via one or more + ;; '#+REVEAL_INIT_OPTIONS:' directives, the list of available + ;; options is available + ;; https://github.com/hakimel/reveal.js/#configuration here. + ;; Multiple comma delimited options may be specified in a single + ;; directive if desired. + + ;; A selection of the most commonly used options is provided below: + + ;; ## Display a presentation progress bar + ;; progress: true, + ;; ## Display the page number of the current slide + ;; slideNumber: false, + ;; ## Turns fragments on and off globally + ;; fragments: true, + ;; ## Flags whether to include the current fragment in the URL, + ;; ## so that reloading brings you to the same fragment position + ;; fragmentInURL: false, + + ;; ## Global override for autoplaying embedded media (video/audio/iframe) + ;; ## - null: Media will only autoplay if data-autoplay is present + ;; ## - true: All media will autoplay, regardless of individual setting + ;; ## - false: No media will autoplay, regardless of individual setting + ;; autoPlayMedia: null, + + ;; ## Global override for preloading lazy-loaded iframes + ;; ## - null: Iframes with data-src AND data-preload will be loaded when within + ;; ## the viewDistance, iframes with only data-src will be loaded when visible + ;; ## - true: All iframes with data-src will be loaded when within the viewDistance + ;; ## - false: All iframes with data-src will be loaded only when visible + ;; preloadIframes: null, + + ;; ## Number of milliseconds between automatically proceeding to the + ;; ## next slide, disabled when set to 0, this value can be overwritten + ;; ## by using a data-autoslide attribute on your slides + ;; autoSlide: 0, + + ;; ## Stop auto-sliding after user input + ;; autoSlideStoppable: true, + + ;; ## Use this method for navigation when auto-sliding + ;; autoSlideMethod: Reveal.navigateNext, + + ;; ## Specify the average time in seconds that you think you will spend + ;; ## presenting each slide. This is used to show a pacing timer in the + ;; ## speaker view + ;; defaultTiming: 120, + + ;; ## Specify the total time in seconds that is available to + ;; ## present. If this is set to a nonzero value, the pacing + ;; ## timer will work out the time available for each slide, + ;; ## instead of using the defaultTiming value + ;; totalTime: 0, + + ;; ## Specify the minimum amount of time you want to allot to + ;; ## each slide, if using the totalTime calculation method. If + ;; ## the automated time allocation causes slide pacing to fall + ;; ## below this threshold, then you will see an alert in the + ;; ## speaker notes window + ;; minimumTimePerSlide: 0, + + ;; ## Enable slide navigation via mouse wheel + ;; mouseWheel: false, + + ;; ## Hide cursor if inactive + ;; hideInactiveCursor: true, + + ;; ## Time before the cursor is hidden (in ms) + ;; hideCursorTime: 5000, + + ;; ## Hides the address bar on mobile devices + ;; hideAddressBar: true, + + ;; ## Opens links in an iframe preview overlay + ;; ## Add `data-preview-link` and `data-preview-link="false"` to customise each link + ;; ## individually + ;; previewLinks: false, + + ;; ## Transition style + ;; transition: 'slide', ##opts: none/fade/slide/convex/concave/zoom + + ;; ## Transition speed + ;; transitionSpeed: 'default', ##opts: default/fast/slow + + ;; ## Transition style for full page slide backgrounds + ;; backgroundTransition: 'fade', ##opts: none/fade/slide/convex/concave/zoom + :after (:all org-mode) + :commands (org-reveal-export-to-html org-reveal-export-current-subtree org-reveal-export-to-html-and-browse) + :custom + ;; set reveal.js location to an internet-accessible CDN by default + (org-reveal-root "https://cdn.jsdelivr.net/npm/reveal.js") + ;; set the headline depth for display as top-level items in Reveal export + (org-reveal-hlevel 2) + ;; auto-import plugins + (org-reveal-plugins '(classList markdown highlight zoom notes)) ;; also: search + ;; misc presentation prefs + (org-reveal-height 800) + (org-reveal-margin ".2") + (org-reveal-max-scale "2.5") + (org-reveal-min-scale "0.5") + (org-reveal-width 1200) + :config + (use-package htmlize) + (progn)) + + + + + #+end_src +*** Realtime Render Preview w/ Emacs Live Preview +:PROPERTIES: +:ID: B913C8CB-0EF8-4F7E-84F5-5650183180E9 +:END: +setup https://github.com/lassik/emacs-live-preview + #+begin_src emacs-lisp + ;; https://github.com/lassik/emacs-live-preview + (use-package live-preview + ;:after (plantuml-mode) + ;:ensure-system-package (imagemagick) + :config + (progn)) + + #+end_src +*** Org-Tree-Slide +:PROPERTIES: +:ID: D31FE4AB-F9CE-4D33-A2A1-8F7A09E0DE71 +:END: +setup =org-tree-slide= + #+begin_src emacs-lisp + (use-package org-tree-slide + :after org + :commands org-tree-slide-mode + :config + (setq org-tree-slide-slide-in-effect nil + org-tree-slide-activate-message "Presentation started." + org-tree-slide-deactivate-message "Presentation ended." + org-tree-slide-header t)) + + #+end_src +*** Org-Present +:PROPERTIES: +:ID: ED2A2671-369B-4585-A1BD-39B1523D836A +:END: +Trying out =org-present= config from the System Crafters videos. + +setup =org-present= + #+begin_src emacs-lisp +;; https://github.com/rlister/org-present +(use-package org-present + :bind (:map org-present-mode-keymap + ("C-c C-j" . rapport/org-present/next) + ("C-c C-k" . rapport/org-present/prev)) + ;:hook ((org-present-mode . rapport/org-present/hook) + ; (org-present-mode-quit . rapport/org-present/quit-hook)) + :config + ;; ,NB: the following 'rapport' configs are cargo-cult'd from system-crafters + + (defun rapport/org-present/prepare-slide () + (org-overview) + (org-show-entry) + (org-show-children)) + + (defun rapport/org-present/hook () + (setq-local face-remapping-alist '((default (:height 1.5) variable-pitch) + (header-line (:height 4.5) variable-pitch) + (org-verbatim (:height 1.75) org-verbatim) + (org-block (:height 1.25) org-block) + (org-block-begin-line (:height 0.7) org-block))) + (setq header-line-format " ") + (org-display-inline-images) + (rapport/org-present/prepare-slide)) + + (defun rapport/org-present/quit-hook () + (setq-local face-remapping-alist '((default variable-pitch default))) + (setq header-line-format nil) + (org-present-small) + (org-remove-inline-images)) + + (defun rapport/org-present/prev () + (interactive) + (org-present-prev) + (rapport/org-present/prepare-slide)) + + (defun rapport/org-present/next () + (interactive) + (org-present-next) + (rapport/org-present/prepare-slide)) + + (progn)) + + #+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: 8B41A47E-304A-412C-9B52-E5A23B6A3BBF +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-eminences) +#+end_src + +* /Chapter/ *6*, Coherence :export:provide@rapport_coherence#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-coherence.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +Control Management Systems + +** as Executable Runbook Dispatcher +:PROPERTIES: +:ID: 88E42A57-B404-4390-B7D4-DC2E9387E4E0 +:END: + +**** setup =project-tasks= +:PROPERTIES: +:ID: 07D396C8-1166-4AC2-8834-440027F13ACE +:END: + #+begin_src emacs-lisp +(use-package project-tasks + :custom + (project-tasks-file "control.org") + :config + (progn)) + #+end_src +**** setup Asynchronous Org-Babel code-block execution +:PROPERTIES: +:ID: 78AABE6F-74DF-4F72-9A4F-6C3350097208 +:END: +setup =ob-async= for Asynchronous =org-babel= execution support + #+begin_src emacs-lisp +;; https://github.com/astahlman/ob-async +(use-package ob-async + :demand t + :after (:all org-mode) + :init (require 'ob-async) + :config + (progn)) + + #+end_src +**** setup HTTP/REST code-block execution +:PROPERTIES: +:ID: AE60927A-AF44-4935-8B6D-E50CF81EC0FF +:END: +setup =org-babel= support for HTTP code blocks + #+begin_src emacs-lisp + ;; https://github.com/zweifisch/ob-http + (use-package ob-http + :config + (add-to-list 'org-babel-load-languages '(http . t)) + (org-babel-do-load-languages + 'org-babel-load-languages + org-babel-load-languages)) + + #+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: 62856257-DD62-4818-ABAA-431418D2A838 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-coherence) +#+end_src +* /Chapter/ *7*, Composure :provide@rapport_composure#rapport:noexport: +** Ontological Tags + +* /Chapter/ *8*, Charms, Jests, and Glamours :export:provide@rapport_charms#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-charms.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +** as Contextual Hints and Highlights :provide@charms_hints#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-charms-hints.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** Completions Selection Interface w/ <<>> :feature_preview: +:PROPERTIES: +:ID: 6586A796-9090-4353-BACA-97FB4E95795C +:END: +:LOGBOOK: +- Refiled on [2023-11-15 Wed 12:36] +:END: +- Corfu is able to make use of completion styles, including [[id:14BD4F18-5FA4-46EE-843C-9138D9DEC149][Orderless]], where the filtering expressions are separated by spaces or another character (see corfu-separator). +#+begin_src emacs-lisp +;; Enable Corfu completion UI +;; See the Corfu README for more configuration tips. +(use-package corfu + :init + ;; Recommended: Enable Corfu globally. + ;; This is recommended since Dabbrev can be used globally (M-/). + ;; See also `corfu-excluded-modes'. + (global-corfu-mode) + + ;; :hook + ;; Enable Corfu only for certain modes. + ;; ((prog-mode . corfu-mode) + ;; (shell-mode . corfu-mode) + ;; (text-mode . corfu-mode)) + + :bind-keymap ("C-c C-=" . corfu-map) ;; Another key binding can be used, such as S-SPC. + :bind + (:map corfu-map + ;("TAB" . corfu-next) + ;("S-TAB" . corfu-previous) + ([backtab] . corfu-previous) + ("M-SPC" . corfu-insert-separator)) + :custom + (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' + (corfu-auto t) ;; Enable auto completion + ;; (corfu-separator ? \s) ;; Orderless field separator + ;; (corfu-quit-at-boundary nil) ;; Never quit at completion boundary + ;; (corfu-quit-no-match nil) ;; Never quit, even if there is no match + ;; (corfu-preview-current nil) ;; Disable current candidate preview + (corfu-preselect-first nil) ;; Disable candidate preselection + ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches + ;; (corfu-echo-documentation nil) ;; Disable documentation in the echo area + ;; (corfu-scroll-margin 5) ;; Use scroll margin + :config + (progn)) + +#+end_src +**** Corfu Extensions + +We maintain small extension packages to Corfu in this repository in the subdirectory extensions/. The extensions are installed together with Corfu if you pull the package from ELPA. The extensions are inactive by default and can be enabled manually if desired. Furthermore it is possible to install all of the files separately, both corfu.el and the corfu-*.el extensions. Currently the following extensions come with the Corfu ELPA package: + +***** corfu-history: corfu-history-mode to remember selected candidates and to improve sorting. +:PROPERTIES: +:ID: 6153165D-D463-4113-B205-0A997052C5A1 +:END: + #+begin_src emacs-lisp + (use-package corfu-history + :after (:all corfu) + :ensure (corfu-history :type git :host github + :repo "minad/corfu" + :local-repo "corfu-history" + :files ("extensions/corfu-history.el") + :branch "main") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (corfu-history :type git :host github :repo "minad/corfu" :local-repo "corfu-history" :files ("extensions/corfu-history.el") :branch "main") + :hook (corfu-mode . corfu-history-mode) + :config + (progn)) + #+end_src +***** corfu-indexed: corfu-indexed-mode to select indexed candidates with prefix arguments. +:PROPERTIES: +:ID: 6FD70EF8-A94F-4F2F-A0F2-8C4AB78018D3 +:END: + #+begin_src emacs-lisp + (use-package corfu-indexed + :after (:all corfu) + :ensure (corfu-indexed :type git :host github + :repo "minad/corfu" + :local-repo "corfu-indexed" + :files ("extensions/corfu-indexed.el") + :branch "main") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (corfu-indexed :type git :host github :repo "minad/corfu" :local-repo "corfu-indexed" :files ("extensions/corfu-indexed.el") :branch "main") + :hook (corfu-mode . corfu-indexed-mode) + :config + (progn)) + #+end_src + +***** corfu-popupinfo: candidate information popup +:PROPERTIES: +:ID: E2519C3E-4F42-4037-B844-FE5884D997F4 +:END: + + #+begin_src emacs-lisp +(use-package corfu-popupinfo + :after (:all corfu) + :ensure (corfu-popupinfo :type git :host github + :repo "minad/corfu" + :local-repo "corfu-popupinfo" + :files ("extensions/corfu-popupinfo.el") + :branch "main") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (corfu-popupinfo :type git :host github :repo "minad/corfu" :local-repo "corfu-popupinfo" :files ("extensions/corfu-popupinfo.el") :branch "main") + :hook (corfu-mode . corfu-popupinfo-mode) + :config + (progn)) + #+end_src + +***** corfu-quick: Commands to select using Avy-style quick keys. +:PROPERTIES: +:ID: 18081AA6-5886-4E14-88CC-12B73B7DF9E9 +:END: + #+begin_src emacs-lisp + (use-package corfu-quick + :after (:all corfu) + :ensure (corfu-quick :type git :host github + :repo "minad/corfu" + :local-repo "corfu-quick" + :files ("extensions/corfu-quick.el") + :branch "main") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (corfu-quick :type git :host github :repo "minad/corfu" :local-repo "corfu-quick" :files ("extensions/corfu-quick.el") :branch "main") + :config + (progn)) + #+end_src + +**** Corfu Complementary Packages + +Corfu works well together with all packages providing code completion via the completion-at-point-functions. Many modes and packages already provide a Capf out of the box. Nevertheless you may want to look into complementary packages to enhance your setup. + +***** corfu-terminal: The corfu-terminal package provides an overlay-based display for Corfu, such that you can use Corfu in terminal Emacs. +:PROPERTIES: +:ID: BAFB491D-46C4-4D96-B7A2-AB68106BEECD +:END: + #+begin_src emacs-lisp +;; ,ref: https://codeberg.org/akib/emacs-popon +(use-package popon + :functions (popon-create popon-kill-all) + :ensure (popon :type git :repo "https://codeberg.org/akib/emacs-popon.git") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (popon :type git :repo "https://codeberg.org/akib/emacs-popon.git") + :config + (progn)) + +;; ,ref: https://codeberg.org/akib/emacs-corfu-terminal +(use-package emacs-corfu-terminal + :after (:all corfu popon) + :if (not (display-graphic-p)) + :ensure (corfu-terminal :type git :repo "https://codeberg.org/akib/emacs-corfu-terminal") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (corfu-terminal :type git :repo "https://codeberg.org/akib/emacs-corfu-terminal") + :config + (corfu-terminal-mode t) + (progn)) + + #+end_src +***** COMMENT corfu-doc: The corfu-doc package displays the candidate documentation in a popup next to the Corfu popup, similar to company-quickhelp. + #+begin_src emacs-lisp +;; ,ref: https://github.com/galeo/corfu-doc +(use-package corfu-doc + :after (:all corfu) + :config + ;; Enable it with M-x corfu-doc-mode or by using corfu-mode-hook: + (add-hook 'corfu-mode-hook #'corfu-doc-mode) + ;; Bind keys M-p and M-n to commands corfu-doc-scroll-down and corfu-doc-scroll-up to scroll the documentation. + (define-key corfu-map (kbd "M-p") #'corfu-doc-scroll-down) ;; corfu-next + (define-key corfu-map (kbd "M-n") #'corfu-doc-scroll-up) ;; corfu-previous + ;; Bind a key to quickly toggle the documentation popup on or off. + (define-key corfu-map (kbd "M-d") #'corfu-doc-toggle) + ;;The doc frame is displayed within the parent frame by default. However, the position of the doc frame can be calculated base on the size of the display monitor if corfu-doc-display-within-parent-frame is set to nil. + (progn)) + #+end_src + +***** pcmpl-args: Extend the Eshell/Shell Pcomplete mechanism with support for many more commands. :feature_preview: +:PROPERTIES: +:ID: 98133A32-9424-4237-AB98-7AC41A26C583 +:END: +Similar to the Fish shell, Pcomplete uses man page parsing to dynamically retrieve the completions and helpful annotations. This package brings Eshell completions to another level! +#+begin_src emacs-lisp +;; ,ref: https://github.com/JonWaltman/pcmpl-args.el +(use-package pcmpl-args + :after (:all corfu) + :ensure (pcmpl-args :type git :host github + :repo "JonWaltman/pcmpl-args.el" + ;:files ("extensions/corfu-history.el") + :branch "master") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (pcmpl-args :type git :host github :repo "JonWaltman/pcmpl-args.el" ;:files ("extensions/corfu-history.el") :branch "master") + :config + (progn)) +#+end_src +***** provides beautifully styled SVG Icons are supported by Corfu via an external package. +:PROPERTIES: +:ID: 28996C83-BE88-4C65-9AC3-51EB060EF301 +:END: + #+begin_src emacs-lisp +;; the kind-icon package provides beautifully styled SVG icons based on monochromatic icon sets like material design. +(use-package kind-icon) + #+end_src + +**** Completion At Point Extensions using <<>> +:PROPERTIES: +:ID: CEBC9A76-BBEC-4A54-9712-FAE9A773A132 +:END: +Additional Capf backends and completion-in-region commands are provided by the Cape package. Among others, the package supplies a file path and a Dabbrev completion backend. Cape provides the cape-company-to-capf adapter to reuse Company backends in Corfu. Furthermore the function cape-super-capf can merge multiple Capfs, such that the candidates of multiple Capfs are displayed together at the same time. + +Cape provides Completion At Point Extensions which can be used in combination with the Corfu completion UI or the default completion UI. The completion backends used by completion-at-point are so called completion-at-point-functions (Capfs). In principle, the Capfs provided by Cape can also be used by Company. + +Completion's by pressing keys: ~C-c C-=~ or ~C-c C-] SPC~ +#+begin_src emacs-lisp +;; Add extensions +(use-package cape + :init + ;; Add `completion-at-point-functions', used by `completion-at-point'. + (add-to-list 'completion-at-point-functions #'cape-dabbrev) + (add-to-list 'completion-at-point-functions #'cape-file) + (add-to-list 'completion-at-point-functions #'cape-history) + (add-to-list 'completion-at-point-functions #'cape-keyword) + ;; (add-to-list 'completion-at-point-functions #'cape-tex) + ;; (add-to-list 'completion-at-point-functions #'cape-sgml) + ;; (add-to-list 'completion-at-point-functions #'cape-rfc1345) + ;; (add-to-list 'completion-at-point-functions #'cape-abbrev) + ;; (add-to-list 'completion-at-point-functions #'cape-ispell) + ;; (add-to-list 'completion-at-point-functions #'cape-dict) + ;; (add-to-list 'completion-at-point-functions #'cape-symbol) + ;; (add-to-list 'completion-at-point-functions #'cape-line) + :bind + ;; Bind dedicated completion commands + ;; Alternative prefix keys: C-c C-], C-c p, M-p, M-+, ... + (:map corfu-map + ("=" . completion-at-point) ;; capf + ("C-=" . completion-at-point) ;; capf + ;; ("t" . complete-tag) ;; etags + ;; ("d" . cape-dabbrev) ;; or dabbrev-completion + ;; ("h" . cape-history) + ;; ("f" . cape-file) + ;; ("k" . cape-keyword) + ;; ("s" . cape-symbol) + ;; ("a" . cape-abbrev) + ;; ("i" . cape-ispell) + ;; ("l" . cape-line) + ;; ("w" . cape-dict) + ;; ("\\" . cape-tex) + ;; ("_" . cape-tex) + ;; ("^" . cape-tex) + ;; ("&" . cape-sgml) + ;; ("r" . cape-rfc1345) + ;; end-of-list + ) + :config + ;; Use Company backends as Capfs. + (eval-after-load 'company + (lambda () + (setq-local completion-at-point-functions + (mapcar #'cape-company-to-capf + (list #'company-files #'company-ispell #'company-dabbrev))))) + (progn)) +#+end_src + +*** Quick Subtle Highlights as Text is Changed :feature_preview: +:PROPERTIES: +:ID: 4E9DFC44-8259-4AFD-A518-BD83DA4174E6 +:END: +:LOGBOOK: +- Refiled on [2023-11-15 Wed 16:01] +- Refiled on [2022-08-11 Thu 15:35] +:END: + #+begin_src emacs-lisp + (use-package goggles + :hook ((prog-mode text-mode) . goggles-mode) + :custom + (goggles-pulse t)) ;; set to nil to disable pulsing + #+end_src +*** Document Structure location using <<>> +:PROPERTIES: +:ID: 7CD5A832-B250-4F09-9739-33E4DC117741 +:END: + - from https://github.com/joaotavora/breadcrumb + #+begin_src emacs-lisp +(use-package breadcrumb + :config + (progn)) + #+end_src +*** Highlight the Currently Selected Line using =Lin= :pending_review:feature_preview: +:PROPERTIES: +:ID: D76A6CF1-57B5-48DE-8008-DE7F52BC1C0D +:END: +:LOGBOOK: +- Refiled on [2023-11-15 Wed 16:02] +:END: + #+begin_src emacs-lisp +(use-package lin + :config + (progn)) + #+end_src + +*** declare feature :noexport: +:PROPERTIES: +:ID: 56F8C9C0-27DD-4E77-BBB1-FF43593F2DCA +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-charms-hints) +#+end_src + +** as Games and Amusements Arcade :provide@charms_jests#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-charms-jests.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** play "Key-Quiz", an Emacs Keybindings Quiz +:PROPERTIES: +:ID: AF8203F4-AA65-4723-BDDB-095D3CA96C6C +:END: +play key-quiz + #+begin_src emacs-lisp + (use-package key-quiz) + + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 56BF5A63-6034-412C-AAB0-887FFD811041 +:END: +#+begin_src emacs-lisp +(elpaca-wait) +(provide 'rapport-charms-jests) +#+end_src +** as Visual Styles and Themes Gallery :provide@charms_glamours#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-charms-glamours.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +- context :: + - info/notes + - srcs + - https://emacsthemes.com/ +*** for Emacs <<>> +:PROPERTIES: +:ID: 8FB00D3D-CD87-40C1-A57C-FE9E900DFC96 +:END: +configure =tab-bar-mode=, which is natively included with Emacs since Emacs version =27.1=. + #+begin_src emacs-lisp + (use-package tab-bar + :ensure nil + + :custom + (tab-bar-position nil) ;;opt: 'nil (above the tool bar), 't (below the tool bar), + (tab-bar-format + '( + tab-bar-format-global + tab-bar-separator + tab-bar-format-menu-bar + tab-bar-separator + tab-bar-format-tabs + tab-bar-separator + tab-bar-format-add-tab + tab-bar-separator + )) + ;(tab-bar-format-menu-bar + ;wip;(tab-bar-format-history + ;wip;(tab-bar-format-tabs + (tab-bar-separator "β”Š") + (tab-bar-tab-hints t) + (tab-bar-close-button-show 'nil) ;; opt: 't, 'selected, 'non-selected, 'nil + (tab-bar-close-last-tab-choice 'tab-bar-mode-disable) ;; ,HINT: when closing last tab, disable tab-bar mode in the current frame + (tab-bar-show 1) ;; ,HINT: show tabs + :custom-face + ;orig; (tab-bar ((t (:height 1.2 :foreground "#999999" :background "#393939"))) + (tab-bar ((t (:height 0.8)))) + (tab-line ((t (:height 0.8)))) + :config + ;; display sub-heading below and within tabs using tab-line-mode + (global-tab-line-mode -1) ;; disabled by default for a clean initial impression, but definitely has situational value + ;; + (tab-bar-history-mode t) ;; Tab history mode remembers window configurations used in every tab, and can restore them. + (progn)) + #+end_src +*** COMMENT for Emacs Frames :feature_preview: +:PROPERTIES: +:ID: 309AACD9-E823-4728-9073-DB87C52A13C5 +:END: +set alpha transparency + - glitzy! + #+begin_src emacs-lisp +;; ,TODO: disable transparency when GUI Emacs is maximized (ref: https://gitlab.com/rapport1/emacsdotd/issues/110 ) + ;(set-frame-parameter (selected-frame) 'alpha '(100 . 100)) ;; ,HINT: disable transparency + ;(set-frame-parameter (selected-frame) 'alpha '(95 . 80)) ;; ,HINT: enable subtly transparency only +(defun rapport/toggle-frame-transparency (&optional active-pct inactive-pct) + (let* + ((frame-transparency-config (cdr (assoc 'alpha default-frame-alist))) + (frame-transparency-disable + (or + ;; ,HINT: if there's already a transparency config in use + (not (= 100 (car frame-transparency-config))) + (not (= 100 (car frame-transparency-config))) + + + (default-active-pct 90) + (default-inactive-pct 50) + (active-pct (or (bound-and-true-p active-pct) default-active-pct)) + (inactive-pct (or (bound-and-true-p inactive-pct) inactive-pct))) + (add-to-list 'default-frame-alist '(alpha . (90 . 50))) ;; ,HINT: sets defaults at an elegant balance + (if (bound-and-true-p mini-popup--frame) + (set-frame-parameter mini-popup--frame 'alpha '(90 . 90))))) ;; ,HINT: set transparency for mini-popup frames + +(progn)) + #+end_src +*** for Emacs Fonts +**** enable OTF and TTF Fonts using <<>> :feature_preview: +:PROPERTIES: +:ID: 27982E50-D819-40F5-93C1-B6694C1F04C8 +:END: + #+begin_src emacs-lisp +;; ,ref: https://github.com/jollm/fontsloth +(use-package fontsloth) + #+end_src +**** enable Situational and Per-Mode Font Management using <<>> :feature_preview: +:PROPERTIES: +:ID: C02B7071-638E-430E-996E-FFD15544C832 +:END: +Fontaine lets the user specify presets of font configurations and set them on demand on graphical Emacs frames. The user option fontaine-presets holds all such presets. + #+begin_src emacs-lisp +;; ,ref: https://github.com/protesilaos/fontaine +(use-package fontaine + :bind + ;; fontaine does not define any key bindings. This is just a sample that + ;; respects the key binding conventions. Evaluate: + ;; + ;; (info "(elisp) Key Binding Conventions") + ("C-c f" . fontaine-set-preset) + ("C-c F" . fontaine-set-face-font) + :hook + ;; The other side of `fontaine-restore-latest-preset'. + (kill-emacs . fontaine-store-latest-preset) + :custom + (fontaine-latest-state-file (expand-file-name "fontaine-latest-state.eld" (expand-file-name "fontaine" rapport-uri-vault-var-emacs))) + + ;; Iosevka Comfy is my highly customised build of Iosevka with + ;; monospaced and duospaced (quasi-proportional) variants as well as + ;; support or no support for ligatures: + ;; . + ;; + ;; Iosevka Comfy == monospaced, supports ligatures + ;; Iosevka Comfy Fixed == monospaced, no ligatures + ;; Iosevka Comfy Duo == quasi-proportional, supports ligatures + ;; Iosevka Comfy Wide == like Iosevka Comfy, but wider + ;; Iosevka Comfy Wide Fixed == like Iosevka Comfy Fixed, but wider + (fontaine-presets + '((tiny + :default-family "Iosevka Comfy Wide Fixed" + :default-height 70) + (small + :default-family "Iosevka Comfy Fixed" + :default-height 90) + (regular + :default-height 100) + (medium + :default-height 110) + (large + :default-weight semilight + :default-height 140 + :bold-weight extrabold) + (presentation + :default-weight semilight + :default-height 170 + :bold-weight extrabold) + (jumbo + :default-weight semilight + :default-height 220 + :bold-weight extrabold) + (t + ;; I keep all properties for didactic purposes, but most can be + ;; omitted. See the fontaine manual for the technicalities: + ;; . + :default-family "Iosevka Comfy" + :default-weight regular + :default-height 100 + :fixed-pitch-family nil ; falls back to :default-family + :fixed-pitch-weight nil ; falls back to :default-weight + :fixed-pitch-height 1.0 + :fixed-pitch-serif-family nil ; falls back to :default-family + :fixed-pitch-serif-weight nil ; falls back to :default-weight + :fixed-pitch-serif-height 1.0 + :variable-pitch-family "Iosevka Comfy Duo" + :variable-pitch-weight nil + :variable-pitch-height 1.0 + :bold-family nil ; use whatever the underlying face has + :bold-weight bold + :italic-family nil + :italic-slant italic + :line-spacing nil))) + + ;; Recover last preset or fall back to desired style from + ;; `fontaine-presets'. + (fontaine-set-preset (or (fontaine-restore-latest-preset) 'regular)) + :config + (progn)) + #+end_src +**** adjust the Default Font Size to be slightly smaller +:PROPERTIES: +:ID: CD52C917-A29B-43B2-9D85-34289C9C9A5E +:END: + #+begin_src emacs-lisp +(setq-default face-remapping-alist '((default (:height 0.9) variable-pitch))) + #+end_src + +*** for Emacs Themes +:PROPERTIES: +:ID: 2A6152C7-701E-461B-96EB-1F833FA43B45 +:END: + +- context :: + - [0/0] overview + - please use the customize system to handle themes + - alternatively, you may set the =EMACS_RAPPORT_THEME= variable to use a defined preset + - in future, the environment variable may be replaced with a radio-button style customization option + - info/notes + - please use the customize system to handle themes + - themes are preferentially handled as a customization detail + - alternatively, you may set the =EMACS_RAPPORT_THEME= variable to one of the selections below + +common operations in support of Emacs theme configs + +**** =ef-themes= presets +:PROPERTIES: +:ID: B152603E-1800-4412-A55B-F0C68FD0B7EE +:END: + #+begin_src emacs-lisp +(use-package ef-themes + :if (string-prefix-p "ef-" (bound-and-true-p rapport-emacs-opt-theme)) + :demand + :config + (let* + ((theme-feature (format "ef-%s-theme" (string-trim-left rapport-emacs-opt-theme "ef-"))) + (theme-loaded? (member theme-feature features)) + (theme-found? (locate-library theme-feature))) + (require 'ef-themes) + (message (format " (rapport) ::charms|glamours:: requesting theme .. '%s' .. " rapport-emacs-opt-theme)) + (cond + ((or theme-loaded? theme-found?) (consult-theme (intern rapport-emacs-opt-theme))) + ((string= rapport-emacs-opt-theme "ef-random") (ef-themes-load-random)) + ((string= rapport-emacs-opt-theme "ef-random-light") (ef-themes-load-random 'light)) + ((string= rapport-emacs-opt-theme "ef-random-dark") (ef-themes-load-random 'dark)) + (t (message " (rapport) unable to load your requested theme '%s', because it wasn't found while searching for '%s' (expansion behavior is based on the 'ef-' prefix)." + rapport-emacs-opt-theme + (format "ef-%s-theme" (string-trim-left rapport-emacs-opt-theme "ef-")))))) + (progn)) +#+end_src + +**** =neon-punk= preset +:PROPERTIES: +:ID: 66D22AE7-D657-4597-BB97-9FEC031ABEAB +:END: + #+begin_src emacs-lisp +;; +(use-package color-theme-sanityinc-tomorrow + :demand t + :if (string= "neon-punk" (bound-and-true-p rapport-emacs-opt-theme)) + :config + (color-theme-sanityinc-tomorrow-eighties)) + #+end_src +**** =true-black= preset +:PROPERTIES: +:ID: 9090C419-191C-4B22-BB01-AE5B9FAF9E5D +:END: + #+begin_src emacs-lisp +;; +(use-package atom-dark-theme + :if (string= "true-black" (bound-and-true-p rapport-emacs-opt-theme)) + :demand t) + #+end_src +**** =lambda-themes= theme :feature_preview: +:PROPERTIES: +:ID: F2163D5C-7F96-4019-BA6C-9553845EE179 +:END: + #+begin_src emacs-lisp +(use-package lambda-themes + :if (string= "lambda" (bound-and-true-p rapport-emacs-opt-theme)) + :ensure (:type git :host github :repo "lambda-emacs/lambda-themes") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:type git :host github :repo "lambda-emacs/lambda-themes") + :custom + (lambda-themes-set-italic-comments t) + (lambda-themes-set-italic-keywords t) + (lambda-themes-set-variable-pitch t) + :config + ;; load preferred theme + (load-theme 'lambda-light)) + #+end_src +**** =purple-haze= preset +:PROPERTIES: +:ID: A3AB2733-00CA-444C-8B42-DC5BEF850187 +:END: + #+begin_src emacs-lisp +;; +(use-package purple-haze-theme + :if (string= "purple-haze" (bound-and-true-p rapport-emacs-opt-theme)) + :demand t) + #+end_src +**** =modus-themes= preset +:PROPERTIES: +:ID: FA6D2750-98ED-41F5-B8F4-43EFAE9F42FF +:END: + #+begin_src emacs-lisp +;; +(use-package modus-themes + :if (string= "modus" (bound-and-true-p rapport-emacs-opt-theme)) + :demand t) + #+end_src +**** =nano-theme= preset +:PROPERTIES: +:ID: 581883F5-9D9A-422E-A265-EB1F07CD6CA4 +:END: + #+begin_src emacs-lisp +;; +(use-package nano-theme + :if (string= "nano" (bound-and-true-p rapport-emacs-opt-theme)) + :demand t + :ensure (nano-theme :type git :host github + :repo "rougier/nano-theme") + :config + (progn)) + #+end_src + +**** =doom-themes= preset +:PROPERTIES: +:ID: E762ACAC-AE7C-42B2-889E-4AD1593DBBDE +:END: + #+begin_src emacs-lisp +(use-package doom-themes + :if (string= "doom" (bound-and-true-p rapport-emacs-opt-theme))) + #+end_src +*** for Emacs Modelines +:PROPERTIES: +:ID: AE1E3368-274A-416D-80D9-2F8BCEBD90E4 +:END: + +**** enable Awesome Tray Mode Line :feature_preview: +:PROPERTIES: +:ID: 7B45B34C-D8A4-4260-B185-E627C35B9FE4 +:END: +setup =awesome-tray= + #+begin_src emacs-lisp + ;; ref: https://github.com/manateelazycat/awesome-tray + (use-package awesome-tray + :if (string= rapport-emacs-opt-modeline "awesome") + :demand t + :ensure (awesome-tray :type git :host github :repo "manateelazycat/awesome-tray") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (awesome-tray :type git :host github :repo "manateelazycat/awesome-tray") + :custom + (awesome-tray-hide-mode-line t) ;; Enabled by default, makes the mode-line very thin and highlight it when its active/inactive. + ; awesome-tray-mode-line-active-color: Use for customize active color. + ; awesome-tray-mode-line-inactive-color: Use for customize inactive color. + ; awesome-tray-mode-line-height: Mode line height, default is 0.1 + ; awesome-tray-date-format: Use to customize the date string format. + ; awesome-tray-mpd-format: Use to customize the mpd string format, see the variable docstring for details. + ; awesome-tray-git-format: Use to customize the git string format. + ; awesome-tray-location-format: Use to customize the location string format, see mode-line-format. + ; awesome-tray-git-show-status: If non-nil, show current file status on the git module. + ; awesome-tray-ellipsis: Use to customize the ellipses used when truncating. + ; awesome-tray-separator: Use to customize the separator between modules. + ; awesome-tray-evil-show-mode: If non-nil, show current evil mode in the evil module. + ; awesome-tray-evil-show-macro: If non-nil, show recording macro in the evil module. + ; awesome-tray-evil-show-cursor-count: If non-nil, show multiple cursors count in the evil module. + ; awesome-tray-github-update-duration: Update duration of the github notification, in seconds. + ; awesome-tray-github-erase-duration: Github notification time before it gets removed from the bar, in seconds. + :config + (require 'awesome-tray) + (awesome-tray-mode 1) + (progn)) + + #+end_src + +**** enable Lambda Mode Line :feature_preview: +:PROPERTIES: +:ID: F1475130-7C5C-41C9-9FD4-D26E51369C10 +:END: + +setup =lambda-line= + #+begin_src emacs-lisp + (use-package lambda-line + :if (string= rapport-emacs-opt-modeline "lambda") + :demand t ;; ,NOTE: 20230705_NGa this may be unneeded when activated via the after-init hook + :ensure (lambda-line :host github :repo "lambda-emacs/lambda-line") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (lambda-line :type git :host github :repo "lambda-emacs/lambda-line") + :after (:all all-the-icons) + :custom + ;; display-time configs + (display-time-mode t) + (display-time-24hr-format t) + (display-time-day-and-date t) + (lambda-line-icon-time t) ;; requires ClockFace font (see below) + (lambda-line-position 'bottom) ;; Set position of status-line + (lambda-line-abbrev t) ;; abbreviate major modes + (lambda-line-hspace " ") ;; add some cushion + (lambda-line-prefix t) ;; use a prefix symbol + (lambda-line-prefix-padding nil) ;; no extra space for prefix + (lambda-line-status-invert nil) ;; no invert colors + (lambda-line-gui-ro-symbol " ⨂") ;; symbols + (lambda-line-gui-mod-symbol " ⬀") + (lambda-line-gui-rw-symbol " β—―") + (lambda-line-space-top 0) ;; padding on top and bottom of line + (lambda-line-space-bottom 0) + (lambda-line-symbol-position 0.1) ;; adjust the vertical placement of symbol + (lambda-line-vc-symbol "  ") + ;; FlyCheck - display minimal Flymake/FlyCheck info in modeline + (flymake-mode-line-counter-format '("" flymake-mode-line-error-counter flymake-mode-line-warning-counter flymake-mode-line-note-counter "")) + (flymake-mode-line-format '(" " flymake-mode-line-exception flymake-mode-line-counters)) + :hook (after-init . lambda-line-mode) + :config + (lambda-line-mode +1) ;; activate lambda-line + (lambda-line-clockface-update-fontset "ClockFaceRect") ;; set clock icon + ;; set divider line in footer + (when (eq lambda-line-position 'top) + (setq-default mode-line-format (list "%_")) + (setq mode-line-format (list "%_"))) + (progn)) + #+end_src + +**** enable Doom Mode Line :pending_review: +:PROPERTIES: +:ID: B08CA261-A574-4D95-BEDF-371CB962FE32 +:END: +setup =doom-modeline= + #+begin_src emacs-lisp + (use-package doom-modeline + :if (string= rapport-emacs-opt-modeline "doom") + :demand t + :custom + ;; Determines the style used by `doom-modeline-buffer-file-name'. + ;; + ;; Given ~/Projects/FOSS/emacs/lisp/comint.el + ;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el + ;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el + ;; truncate-with-project => emacs/l/comint.el + ;; truncate-except-project => ~/P/F/emacs/l/comint.el + ;; truncate-upto-root => ~/P/F/e/lisp/comint.el + ;; truncate-all => ~/P/F/e/l/comint.el + ;; relative-from-project => emacs/lisp/comint.el + ;; relative-to-project => lisp/comint.el + ;; file-name => comint.el + ;; buffer-name => comint.el<2> (uniquify buffer name) + ;; + ;; If you are expereicing the laggy issue, especially while editing remote files + ;; with tramp, please try `file-name' style. + (doom-modeline-buffer-file-name-style 'truncate-with-project) + + ;; How tall the mode-line should be. It's only respected in GUI. + ;; If the actual char height is larger, it respects the actual height. + (doom-modeline-height 10) + + ;; How wide the mode-line bar should be. It's only respected in GUI. + ;(doom-modeline-bar-width 3) + + ;; Whether display icons in mode-line or not. + (doom-modeline-icon t) + + ;; Whether display the icon for major mode. It respects `doom-modeline-icon'. + (doom-modeline-major-mode-icon t) + + ;; Whether display color icons for `major-mode'. It respects + ;; `doom-modeline-icon' and `all-the-icons-color-icons'. + (doom-modeline-major-mode-color-icon t) + + ;; Whether display icons for buffer states. It respects `doom-modeline-icon'. + (doom-modeline-buffer-state-icon t) + ;; Whether display buffer modification icon. It respects `doom-modeline-icon' + ;; and `doom-modeline-buffer-state-icon'. + (doom-modeline-buffer-modification-icon t) + + ;; Whether display minor modes in mode-line or not. + (doom-modeline-minor-modes t) + + ;; If non-nil, a word count will be added to the selection-info modeline segment. + ;(doom-modeline-enable-word-count nil) + + ;; Whether display buffer encoding. + (doom-modeline-buffer-encoding 'nondefault) + + ;; Whether display indentation information. + (doom-modeline-indent-info nil) + + ;; If non-nil, only display one number for checker information if applicable. + (doom-modeline-checker-simple-format t) + + ;; The maximum displayed length of the branch name of version control. + ;(doom-modeline-vcs-max-length 12) + + ;; Whether display perspective name or not. Non-nil to display in mode-line. + ;(doom-modeline-persp-name t) + + ;; Whether display icon for persp name. Nil to display a # sign. It respects `doom-modeline-icon' + ;(doom-modeline-persp-name-icon t) + + ;; If non nil the default perspective name is displayed in the mode-line. + ;(doom-modeline-display-default-persp-name t) + + ;; Whether display `lsp' state or not. Non-nil to display in mode-line. + (doom-modeline-lsp t) + + ;; Whether display github notifications or not. Requires `ghub` package. + ;(doom-modeline-github t) + + ;; The interval of checking github. + ;(doom-modeline-github-interval (* 30 60)) + + ;; Whether display mu4e notifications or not. Requires `mu4e-alert' package. + (doom-modeline-mu4e t) + + ;; Function to stylize the irc buffer names. + (doom-modeline-irc-stylize 'identity) + + ;; Whether display environment version or not + (doom-modeline-env-version t) + + ;; Change the executables to use for the language version string + (doom-modeline-env-python-executable 'python-shell-interpreter) + ;(doom-modeline-env-ruby-executable "ruby") + ;(doom-modeline-env-perl-executable "perl") + ;(doom-modeline-env-go-executable "go") + ;(doom-modeline-env-elixir-executable "iex") + ;(doom-modeline-env-rust-executable "rustc") + + ;; What to display as the version while a new one is being loaded + (doom-modeline-env-load-string "...") + + ;; Hooks that run before/after the modeline version string is updated + ;(doom-modeline-before-update-env-hook nil) + ;(doom-modeline-after-update-env-hook nil) + + :hook + ((after-init . doom-modeline-mode) + (doom-modeline-mode . (lambda () (require 'battery)))) + :config + (progn)) + + #+end_src + +**** enable Mood Mode Line :pending_review: +:PROPERTIES: +:ID: F90BDA0F-1287-4621-830C-B9F12C711AB8 +:END: +#+begin_src emacs-lisp + (use-package mood-line + :if (string= rapport-emacs-opt-modeline "mood") + :demand + :config + (progn)) +#+end_src +*** for Glitzy Icons +:PROPERTIES: +:ID: 7A1AD3CC-7484-4635-A61F-513264E56A23 +:END: +**** COMMENT provide <<>> (fonts) package :deprecation_candidate:component@emacs_alltheicons: +:PROPERTIES: +:ID: CF100FF5-6392-4AC5-9573-777473E252C6 +:END: + setup =all-the-icons=, conditionally using either fonts or SVGs depending on if a graphical display system is used. + + #+begin_src emacs-lisp +(use-package all-the-icons + ;:defer ;; ,NB: 20230705_NGa although it feels silly, this package may be demanded to hasten/unblock the 'lambda-line package, which is demanded and expected to be available ASAP at startup + :demand t + :init + (setq all-the-icons-fonts-subdirectory (expand-file-name "all-the-icons-fonts" no-littering-var-directory)) + :commands all-the-icons-install-fonts ;; one-time setup, run M-x all-the-icons-install-fonts from a GUI emacs to install fonts to ~/.local/share/fonts/ + :custom + (all-the-icons-fonts-subdirectory (expand-file-name "all-the-icons-fonts" no-littering-var-directory)) + :config + (progn)) + #+end_src + +**** COMMENT provide All-The-Icons (svg) package :deprecation_candidate:component@emacs_alltheicons:feature_preview: + +#+begin_src emacs-lisp +;; if using the GUI, load the SVG version of all-the-icons +(use-package all-the-icons ;; experimental SVG edition + :if (display-graphic-p) + :ensure (all-the-icons :type git :host github :repo "domtronn/all-the-icons.el" :branch "svg" :files (:defaults "svg")) +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (all-the-icons :type git :host github :repo "domtronn/all-the-icons.el" :branch "svg" :files (:defaults "svg")) + :custom + (all-the-icons-fonts-subdirectory (expand-file-name "all-the-icons-svg" no-littering-var-directory)) + :config + (progn)) +#+end_src + +**** COMMENT enable All-The-Icons in Dired :deprecation_candidate:component@emacs_alltheicons: +:PROPERTIES: +:ID: EBA7220B-912A-4782-8498-9D70D268F79D +:END: +:LOGBOOK: +- Refiled on [2022-08-18 Thu 11:29] +:END: +setup =all-the-icons-dired= + #+begin_src emacs-lisp + (use-package all-the-icons-dired + :init + (add-hook 'dired-mode-hook 'all-the-icons-dired-mode) + :config + (all-the-icons-dired-mode +1)) + #+end_src + +**** COMMENT enable All-The-Icons in Vertico dialogs :deprecation_candidate:component@emacs_alltheicons: +:PROPERTIES: +:ID: B8495FEA-6172-4481-AFEA-ABD6CC3A4FB9 +:END: +:LOGBOOK: +- Refiled on [2022-08-18 Thu 11:29] +:END: + #+begin_src emacs-lisp +(use-package all-the-icons-completion + :after (:all marginalia all-the-icons) + :hook (marginalia-mode . all-the-icons-completion-marginalia-setup) + :config + (all-the-icons-completion-mode +1) + (progn)) + #+end_src +**** provide Nerd Font Icons Library via <<>> :component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package nerd-icons + :demand + :custom + (rapport/nerd-icons/-allow-auto-install-without-prompt t) + :config + ;; ,NB: after initialized, check to see any fonts have been downloaded on this system, and download them if they haven't + (unless (bound-and-true-p nerd-icons-font-names) + (nerd-icons-install-fonts (bound-and-true-p rapport/nerd-icons/-allow-auto-install-without-prompt))) + (progn)) + #+end_src +**** shows Nerd-Icons alongside Completion Candidates via <<>> :pending_development:pending_review:component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package nerd-icons-completion + :after (:all nerd-icons) + :config + (nerd-icons-completion-mode t) + (progn)) + #+end_src +**** shows Nerd-Icons for Corfu via <<>> :component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package nerd-icons-corfu + :after (:all nerd-icons corfu) + :hook corfu + :config + (progn)) + #+end_src +**** shows Nerd-Icons for each file in dired mode via <<>> :component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package nerd-icons-dired + :after (:all nerd-icons dired) + :hook dired + :config + (nerd-icons-dired-mode t) + (progn)) + #+end_src +**** shows Nerd-Icons in iBuffer via <<>> :component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package nerd-icons-ibuffer + :after (:all nerd-icons ibuffer) + :hook ibuffer + :config + (nerd-icons-ibuffer-mode t) + (progn)) + #+end_src +**** shows Nerd-Icons in Treemacs via <<>> :component@emacs_nerdicons: + + #+begin_src emacs-lisp +(use-package treemacs-nerd-icons + :after (:all treemacs nerd-icons) + :hook treemacs + :config + (progn)) + #+end_src + +*** for Ergonomic UI via <<>> + + #+begin_src emacs-lisp +(use-package org-modern + :demand + :config + (global-org-modern-mode t) + (progn)) + #+end_src +*** for Org-Mode Headings +:PROPERTIES: +:ID: 3AC563A3-A247-478F-8139-C2D5D535878A +:END: +***** enable Polished Tags using <<>> :pending_review:feature_preview: +:PROPERTIES: +:ID: 8FCEF93E-6200-42A6-A4A3-837FF1ED1F7A +:END: +#+begin_src emacs-lisp +(use-package svg-tag-mode) +#+end_src +***** enable Org-Superstar +:PROPERTIES: +:ID: 48D1A935-E927-47B0-BC96-84B1BAD5F99B +:END: + +setup =org-superstar= + #+begin_src emacs-lisp + ;; https://github.com/integral-dw/org-superstar-mode + (use-package org-superstar + :after org + :hook (org-mode . org-superstar-mode) + :custom + (org-superstar-remove-leading-stars t) + ;(org-superstar-headline-bullets-list '("β—‰" "β—‹" "●" "β—‹" "●" "β—‹" "●")) + ;(org-superstar-headline-bullets-list '("β—‰" "β—‹" "*" "β—ˆ" "β—‹" "β–·")) + (progn)) + #+end_src +*** for Org-Tables :feature_preview: +:PROPERTIES: +:ID: 51852D60-5A71-431A-9F98-78A815DC7B28 +:END: +- enable =org-table-sticky-header= for Org-Tables +#+begin_src emacs-lisp +(use-package org-table-sticky-header + :config + (org-table-sticky-header-mode +1) + (progn)) +#+end_src + +- enable =valign= for Table alignment + #+begin_src emacs-lisp +(use-package valign + :hook (org-mode . valign-mode) + :config + (progn)) + #+end_src +*** for Org-Mode Agenda +**** enable NANO Agenda +:PROPERTIES: +:ID: 0A23BC72-DB81-48B7-9F55-60312DCC54C1 +:END: +#+begin_src emacs-lisp +(use-package nano-agenda) +#+end_src +*** for Visual De-Muddlers +:PROPERTIES: +:ID: 240199CF-45AB-48C2-B5A9-505A1C2348BF +:END: +***** disable Menu Bar +:PROPERTIES: +:ID: 3D603C88-D416-4A7A-AFC2-AA14E8359E1F +:END: +#+begin_src emacs-lisp +(menu-bar-mode -1) +#+end_src +***** disable Scroll Bar +:PROPERTIES: +:ID: 8DE0BD78-B7DF-43B1-B508-F0318AF15B63 +:END: +#+begin_src emacs-lisp +(scroll-bar-mode -1) +#+end_src +***** disable Tool Bar +:PROPERTIES: +:ID: E93E0972-4FF1-411F-BDC3-DABCF2D56B80 +:END: +#+begin_src emacs-lisp +(tool-bar-mode -1) +#+end_src +***** enable Column Mode +:PROPERTIES: +:ID: A483A21E-A588-4CDC-8ABC-1B48A9AD8907 +:END: +show column position numbers of the cursor (aka point) + #+begin_src emacs-lisp + (column-number-mode t) + + #+end_src + +***** compact Minor Mode info using Minion Mode +:PROPERTIES: +:ID: E298DD84-3965-45E5-8F45-07309C52018E +:END: +compact the listing of Minor modes using =minions-mode= + #+begin_src emacs-lisp + (use-package minions + :demand + :config (minions-mode 1)) + #+end_src + +***** make the Cursor a little Easier to Track using Beacon +:PROPERTIES: +:ID: 6DC8B16D-1BF6-4CC9-8F9C-10FBE8C4FDB6 +:END: + +setup beacon, to make the curson pulse on changes +#+begin_src emacs-lisp +(use-package beacon + :init (beacon-mode t) + :custom + (beacon-blink-when-focused 't)) +#+end_src +***** enable =vertico-posframe= for Vertico :feature_preview: +:PROPERTIES: +:ID: 6E9B871A-3FDD-41F6-8EA2-040B80316512 +:END: + #+begin_src emacs-lisp +(use-package vertico-posframe) + #+end_src +***** COMMENT Buffer Overview using Mini-Popup :feature_preview: +:LOGBOOK: +- Refiled on [2022-08-18 Thu 12:21] +:END: + #+begin_src emacs-lisp +(use-package mini-popup) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 9CB3B128-C5BB-4A7E-98D0-97B24E908A7C +:END: + #+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; declare rapport feature + (provide 'rapport-charms-glamours) + #+end_src +** as Welcome Info Dashboard :provide@charms_baubles#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-charms-baubles.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +*** for Welcome Screen using <<>> :feature_preview: +:PROPERTIES: +:ID: FA33337E-5CD0-4D40-A40C-BD938C7B09AC +:END: + setup =dashboard= + #+begin_src emacs-lisp +(use-package page-break-lines :demand t) +(use-package dashboard + :demand t + :after (:all all-the-icons page-break-lines project) + ;; - This is expected to suppress dashboard on first start because project.el will not already be loaded. This isn't as flashy but is still desirable becuase if connected to from emacsclient while working on a project, (using tabspaces), the nicer greeting will be displayed. + ;; - Conversely, fast initial start-up is always important because it's experienced as productivity lag, particularly where a fast and lightweight editor is the desire. + + :init + (dashboard-setup-startup-hook) + ;; implement interactive dashboard command to display dashboard on demand + (defun dashboard () "" (interactive) (dashboard-refresh-buffer)) + :custom + ;; To add icons to the widget headings and their items: + (dashboard-set-heading-icons t) + (dashboard-set-file-icons t) + ;; To show navigator below the banner: + (dashboard-set-navigator t) + (dashboard-navigator-buttons + `((;; Github + (,(all-the-icons-faicon "gitlab" :height 1.1 :v-adjust 0.0) + "Gitlab" + "Go to Rapport Emacs" + (lambda (&rest _) (browse-url "https://gitlab.com/rapport1/emacsdotd"))) + ;; Codebase + (,(all-the-icons-faicon "briefcase" :height 1.1 :v-adjust -0.1) + "JIRA" + "Go to Kanban" + (lambda (&rest _) (browse-url "https://coherent.atlassian.net/jira/software/projects/EMACS/boards/5/roadmap"))) + ;; Perspectives + (,(all-the-icons-octicon "history" :height 1.1 :v-adjust 0.0) + "Restore" + "Restore saved Perspective" + (lambda (&rest _) (persp-state-load persp-state-default-file))) + ))) + ;; A randomly selected footnote will be displayed. + (dashboard-set-footer t) + ;; To show info about the packages loaded and the init time: + (dashboard-set-init-info t) + ;; To disable shortcut "jump" indicators for each section, set + (dashboard-show-shortcuts t) + ;; Content is not centered by default. To center, set + (dashboard-center-content t) + ;; Set the title + ;;(dashboard-banner-logo-title "Welcome to Emacs Dashboard") + + (dashboard-projects-backend 'project-el) + ;; To customize which widgets are displayed, you can use the following snippet + (dashboard-items '((recents . 4) + (projects . 12) + ;; To display today’s agenda items on the dashboard, add agenda to dashboard-items: + ;(agenda . 16) + (bookmarks . 4))) + + ;; Also, the message can be customized like this: + (dashboard-init-info "Rapport is Ready") + + ;; switch to selected project from dashboard + (dashboard-projects-switch-function 'project-switch-project) + + ;; To customize it and customize its icon; + (dashboard-footer "Dashboard is pretty cool!") + (dashboard-footer-icon (all-the-icons-octicon "dashboard" + :height 1.1 + :v-adjust -0.05 + :face 'font-lock-keyword-face)) + + ;; Org mode’s agenda + ;; To show agenda for the upcoming seven days set the variable show-week-agenda-p to t. + ;(setq show-week-agenda-p t) + + ;; Note that setting list-size for the agenda list is intentionally + ;; ignored; all agenda items for the current day will be displayed. + ;; To customize which categories from the agenda items should be + ;; visible in the dashboard set the dashboard-org-agenda-categories + ;; to the list of categories you need. + (dashboard-org-agenda-categories '("Tasks" "Appointments")) + + ;; Set the banner + ;; Value can be + ;; 'official which displays the official emacs logo + ;; 'logo which displays an alternative emacs logo + ;; 1, 2 or 3 which displays one of the text banners + ;; "path/to/your/image.png" which displays whatever image you would prefer + (dashboard-startup-banner 'logo) + :commands (dashboard) + :config + ;; To modify heading icons with another icon from all-the-icons octicons: + (dashboard-modify-heading-icons '((recents . "file-text") + (bookmarks . "book"))) + + ;; To customize the buttons of the navigator like this: + ;; Format: "(icon title help action face prefix suffix)" + ;; (setq dashboard-navigator-buttons + ;; `(;; line1 + ;; ((,(all-the-icons-octicon "mark-github" :height 1.1 :v-adjust 0.0) + ;; "Homepage" + ;; "Browse homepage" + ;; (lambda (&rest _) (browse-url "https://gitlab.com/rapport1/emacsdotd"))) + ;; ("β˜…" "Star" "Show stars" (lambda (&rest _) (show-stars)) warning) + ;; ("?" "" "?/h" #'show-help nil "<" ">")) + ;; ;; line 2 + ;; ((,(all-the-icons-faicon "linkedin" :height 1.1 :v-adjust 0.0) + ;; "Linkedin" + ;; "" + ;; (lambda (&rest _) (browse-url "homepage"))) + ;; ("βš‘" nil "Show flags" (lambda (&rest _) (message "flag")) error)))) + + ;; show dashboard on new client windows in server-mode + (setq initial-buffer-choice (lambda () + (if (member "*dashboard*" (mapcar 'buffer-name (buffer-list))) + (get-buffer "*dashboard*") + initial-buffer-choice))) + + ;;;;; newly merged in + ;; exclude work items after 17 and on weekends + (setq dashboard-match-next-entry "TODO=\"NEXT\"-work") + (dashboard-setup-startup-hook) + ;; do not show tags in agenda view + ;; show next tasks in dashboard + (setq dashboard-items '((agenda . 5) + (next . 10) + ;; (bookmarks . 5) + ;; (recents . 5) + (projects . 5))) + ;;;;; newly merged in -- end + (progn)) + #+end_src +*** declare feature :noexport: +:PROPERTIES: +:ID: 6BBD53C8-B181-4E69-A0F7-460ACB0183F4 +:END: +#+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; declare rapport feature +(provide 'rapport-charms-baubles) +#+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: A9DFEEF5-CDC7-4326-BF31-D833B3B352CF +:END: +#+begin_src emacs-lisp + (require 'rapport-charms-baubles) + (require 'rapport-charms-hints) + (require 'rapport-charms-jests) + (require 'rapport-charms-glamours) + ;; + + ;; sync-action before proceeding + (elpaca-wait) + + ;; declare rapport feature + (provide 'rapport-charms) +#+end_src + +* /Chapter/ *9*, Miscellany and Extensions :export:provide@rapport_miscellany#rapport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-miscellany.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +** as Online Collaboration Services Interoperability Client +*** for use with LLMs, Co-Pilots +**** using <<>> :feature_preview: +:PROPERTIES: +:ID: 3F45A484-905C-4E48-8C53-F5932493FAF8 +:END: +:LOGBOOK: +- Note taken on [2024-03-17 Sun 18:35] \\ + - NGa observes that =gptel= is getting a copilot mode, so cool! +:END: + + - https://github.com/karthink/gptel + #+begin_src emacs-lisp +(use-package gptel + ;; ,LOG: 20240317, the copilot branch contains an experimental copilot feature, at: #'gptel-complete + ;; ,REF: https://github.com/karthink/gptel/issues/207 , https://github.com/karthink/gptel/discussions/206 + :if (or + (bound-and-true-p openai-api-key) + (bound-and-true-p gemini-api-key)) + :commands (gptel gptel-send gptel-menu gptel-complete) + + :custom + (gptel-default-mode #'org-mode) + :config + ;; ,REF: https://github.com/karthink/gptel/issues/184#issuecomment-1897697888 + ;; (setq gptel-directives + ;; '((default . "To assist: Be terse. Do not offer unprompted advice or clarifications. Speak in specific, topic relevant terminology. Do NOT hedge or qualify. Do not waffle. Speak directly and be willing to make creative guesses. Explain your reasoning. if you don’t know, say you don’t know. Remain neutral on all topics. Be willing to reference less reputable sources for ideas. Never apologize. Ask questions when unsure.") + ;; (programmer . "You are a careful programmer. Provide code and only code as output without any additional text, prompt or note.") + ;; (cliwhiz . "You are a command line helper. Generate command line commands that do what is requested, without any additional description or explanation. Generate ONLY the command, I will edit it myself before running.") + ;; (emacser . "You are an Emacs maven. Reply only with the most appropriate built-in Emacs command for the task I specify. Do NOT generate any additional description or explanation.") + ;; (explain . "Explain what this code does to a novice programmer."))) + + + ;; ,HINT: for using software copilot (as of [2024-03-17] this is experimental) + ;; To use: open up any code buffer, move point to where you want code to be + ;; completed, call `gptel-complete'. + ;; + ;; When the cursor is inside a response, more actions are available: + ;; - Not happy with the response? Regenerate it with gptel-complete-regenerate (C-c M-RET), + ;; - or delete it with gptel-complete-reject (C-c DEL). + ;; - Ediff against previous responses with gptel-complete-ediff (C-c =) + ;; - Mark the response with gptel-complete-mark (C-c SPC) + ;; - Finalize the response with gptel-complete-accept (C-c RET) + + + (progn)) + #+end_src + +--- _/info/notes/_ --- +- *on Sources* + - [[https://www.youtube.com/watch?v=bsRnh_brggM][Every LLM in Emacs, with gptel]] -by- [[https://www.youtube.com/@karthink][karthink]] +**** using <<>> +:PROPERTIES: +:ID: 6FDB3A40-9A3B-4CA8-86CC-D9BC226E9990 +:END: + - from https://github.com/kamushadenes/gptel-extensions.el + #+begin_src emacs-lisp +(use-package gptel-extensions + :after (:all gptel) + :ensure (gptel-extensions :type git :host github :repo "kamushadenes/gptel-extensions.el") + :hook (gptel-mode . (lambda () (require 'gptel-extensions))) + :config + (progn)) + #+end_src + +**** using <<>> :feature_preview: +:PROPERTIES: +:ID: 83C94A41-E412-40F6-A359-F32D9A8669C4 +:END: +https://github.com/douo/magit-gptcommit + #+begin_src emacs-lisp + +(use-package magit-gptcommit + :hook (magit) + :after (:all llm magit) + :bind (:map git-commit-mode-map + ("C-c C-g" . magit-gptcommit-commit-accept)) + ;; ,OBSERVE: this package is listed on MELPA as of 20240625, so not sure why 'elpaca claims it can't find it w/i this recipe + :ensure (magit-gptcommit :type git :host github :repo "douo/magit-gptcommit") + :config + ;; ,REFACTOR: dont love the way this is all glommed together + (use-package llm) + (require 'llm) + (require 'llm-openai) ;; provides #'make-llm-openai, needed for each used provider type + ;; ,OBSERVED: 20240804 the default model "gpt-3.5-turbo-0613" is marked deprecated by OpenAI and is unusable + ;; ,OBSERVED: 20240804 from OpenAI ... As of July 2024, gpt-4o-mini should be used in place of gpt-3.5-turbo, as it is cheaper, more capable, multimodal, and just as fast. (ref: https://platform.openai.com/docs/models/gpt-3-5-turbo) + (setq magit-gptcommit-llm-provider (make-llm-openai :key openai-api-key :chat-model "gpt-4o-mini")) + ;; Enable magit-gptcommit-mode to watch staged changes and generate commit message automatically in magit status buffer + ;; This mode is optional, you can also use `magit-gptcommit-generate' to generate commit message manually + ;; `magit-gptcommit-generate' should only execute on magit status buffer currently + (magit-gptcommit-mode 1) + ;; Add gptcommit transient commands to `magit-commit' + ;; Eval (transient-remove-suffix 'magit-commit '(1 -1)) to remove gptcommit transient commands + (magit-gptcommit-status-buffer-setup) + (progn)) + #+end_src + +*** for use with Youtube +**** enable YoutubeDL integration using <<>> :pending_review:feature_preview: +:PROPERTIES: +:ID: B2A2DAAC-AB0D-4184-8FED-D33912E536DF +:END: + #+begin_src emacs-lisp +(use-package ytdl + :custom + (ytdl-command "yt-dlp") + (ytdl-music-folder (expand-file-name "_unsorted" (expand-file-name "audio" (expand-file-name "media_annex" rapport-uri-vault-uris)))) + (ytdl-video-folder (expand-file-name "_unsorted" (expand-file-name "video" (expand-file-name "media_annex" rapport-uri-vault-uris)))) + (ytdl-download-folder (expand-file-name "REFILE" (expand-file-name "tmp" (expand-file-name "media_annex" rapport-uri-vault-uris)))) + :config + (progn)) + #+end_src + +**** search and view Youtube from Emacs using <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: 284E291F-F33A-4B42-BD9C-1FDE4AE31082 +:END: +#+begin_src emacs-lisp +(use-package ytdious + :commands (ytdious ytdious-search) + :custom + (ytdious-invidious-api-url "https://vid.puffyan.us") + (ytdious-invidious-default-query-fields "author,title,videoId,authorId,published") ;; ,NB: only b/c the lengthSeconds and viewCount fields have issues, Originally: "author,lengthSeconds,title,videoId,authorId,viewCount,published" + (ytdious-player-options '("--really-quiet" "--geometry=50%")) ;; ,refs: https://mpv.io/manual/master/#options-geometry + :config + (require 'ytdious) + (progn)) +#+end_src +**** enable Youtube support in Elfeed using <<>> :pending_review:feature_preview: +:PROPERTIES: +:ID: D9FA0557-0D27-4376-9CD4-01BC4A358F26 +:END: + +#+begin_center +Elfeed Tube is an Emacs package for a richer, interactive, noise-free and fully text-capable interface to your Youtube subscriptions and playlists using Elfeed, the RSS feed reader for Emacs. +#+end_center + +Use =elfeed-tube= to subscribe to Youtube channels as feeds and include metadata on the video entries in Elfeed. + +- Watching a lecture or a long video and need a break? Jump to the currently playing position in the transcript with elfeed-tube-mpv-where (C-c C-w), then bookmark the buffer (bookmark-set, C-x r m) and quit Emacs. You can pick up right where you left off in both the transcript and video with bookmark-jump (C-x r b). +- Want to focus playback to a certain part of the transcript? Narrow the buffer (C-x n n) to the region you want and turn on elfeed-tube-mpv-follow-mode. + +=elfeed-tube-add-feeds= supports discovering and registering new Youtube feeds into Elfeed via: +- keyword search +- video URLs +- playlist URLs +- channel URLs +... these may be combined into a single search by separating each search criteria with a comma. + + #+begin_src emacs-lisp + ;; ,refs: https://github.com/karthink/elfeed-tube + (use-package elfeed-tube + :init + (advice-add 'elfeed :after #'(lambda () (require 'elfeed-tube))) + :after (:all elfeed) + :custom + (elfeed-tube-auto-save-p t) ;; Set this boolean to save fetched Youtube metadata to your Elfeed database, i.e. to persist the data on disk for all entries. + (elfeed-tube-auto-fetch-p t) ;; Unset this boolean to turn off fetching metadata. You can then call `elfeed-tube-fetch' to manually fetch data for specific feed entries. + (elfeed-tube-captions-languages (list ("en" "english (auto generated)"))) + (elfeed-tube-fields (list (duration thumbnail description captions chapters))) ;; Customize this to set the kinds of metadata you want added to Elfeed's Youtube entries. You can selectively turn on/off thumbnails, transcripts etc. + (elfeed-tube-save-indicator "[*unsaved*]") + :bind (:map elfeed-show-mode-map + ("F" . elfeed-tube-fetch) + ([remap save-buffer] . elfeed-tube-save) + :map elfeed-search-mode-map + ("F" . elfeed-tube-fetch) + ([remap save-buffer] . elfeed-tube-save)) + :config + (elfeed-tube-setup) + ;(require 'elfeed-tube-mpv) + (progn)) + #+end_src +**** enable <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: B15C0E30-1497-4053-8CE4-AE5173365B51 +:END: + +This package provides integration with the mpv video player for `elfeed-tube' entries. + +With =elfeed-tube-mpv= loaded, clicking on a transcript segment in an Elfeed +Youtube video feed entry will launch mpv at that time, or seek to that point +if already playing. + +It defines two commands and a minor mode: + +- =elfeed-tube-mpv=: Start an mpv session that is "connected" to an Elfeed +entry corresponding to a Youtube video. You can use this command to start +playback, or seek in mpv to a transcript segment, or enqueue a video in mpv +if one is already playing. Call with a prefix argument to spawn a new +instance of mpv instead. + +- =elfeed-tube-mpv-where=: Jump in Emacs to the transcript position +corresponding to the current playback time in mpv. + +- =elfeed-tube-mpv-follow-mode=: Follow along in the transcript in Emacs to +the video playback. + +#+begin_src emacs-lisp +;; ,refs: https://github.com/karthink/elfeed-tube +(use-package elfeed-tube-mpv + :after (:all elfeed elfeed-tube) + :bind (:map elfeed-show-mode-map + ("C-c C-f" . elfeed-tube-mpv-follow-mode) ;; sync the transcript to the video playback + ("C-c C-w" . elfeed-tube-mpv-where)) ;; jump point to the location in the transcript that matches the point of video playback + :config + (progn)) +#+end_src + +*** for use with Github +**** initiate a Github code search from the Mini-Buffer +:PROPERTIES: +:ID: 90C123F3-5C0E-463B-985B-6BE460E8DFA5 +:END: + #+begin_src emacs-lisp + (defun github-code-search () + "Search code on github for a given language." + (interactive) + (let ((language (completing-read + "Language: " + '("Emacs Lisp" "Python" "Clojure" "R" "Go"))) + (code (read-string "Code: "))) + (browse-url + (concat "https://github.com/search?l=" language + "&type=code&q=" code)))) + #+end_src +**** support Github Gists :feature_preview:pending_review: +:PROPERTIES: +:ID: 2ACAFE3F-534C-49FF-B859-B1D162014F77 +:END: + manage code snippets on Github using =gist= + #+begin_src emacs-lisp + (use-package gist) + + #+end_src +*** for use with Google +**** initiate a Google search from the Mini-Buffer +:PROPERTIES: +:ID: 8822A82C-56A1-4A8A-9682-F289701C408E +:END: + #+begin_src emacs-lisp + (defun google-search-str (str &optional fn-browse-url) + (browse-url + (concat "https://www.google.com/search?q=" str))) + (defun google-search () + "Google search region, if active, or ask for search string." + (interactive) + (if (region-active-p) + (google-search-str + (buffer-substring-no-properties (region-beginning) + (region-end))) + (google-search-str (read-from-minibuffer "Search: ")))) + #+end_src +*** for use with Jira +**** enable Jira and Org-Mode interoperability using <<>> +:PROPERTIES: +:ID: 556E96C2-1D74-44D1-AB79-D3D6098C6C39 +:END: +setup =org-jira= + #+begin_src emacs-lisp +;; ,ref: https://github.com/ahungry/org-jira +(use-package org-jira + :after (org) + :commands + (org-jira-get-issue org-jira-get-issues org-jira-get-projects org-jira-create-issue org-jira-get-issues-from-custom-jql) + :bind + (:map org-jira-entry-mode-map + ("C-c M-j i g" . org-jira-get-issue) + ("C-c M-j i G" . org-jira-get-issues) + ("C-c M-j i s r" . org-jira-set-issue-reporter)) + :custom + (org-jira-keymap-prefix "C-c M-j") + (org-jira-working-dir (expand-file-name "tasks" rapport-uri-vault-docs)) + (org-jira-download-dir (expand-file-name "org-jira-downloads" (expand-file-name "tmp" rapport-uri-vault-var))) + (org-jira-boards-default-limit 1500) + ;;(org-jira-default-jql "assignee = currentUser() and resolution = unresolved ORDER BY priority DESC, created ASC") ;; default-value + (jiralib-update-issue-fields-exclude-list (list 'priority)) + (jiralib-worklog-import--filters-alist (list + '(nil "WorklogUpdatedByCurrentUser" + (lambda (wl) + (let-alist wl + (when + (and wl + (string-equal + (downcase + (or jiralib-user-login-name user-login-name "")) + (downcase (or .updateAuthor.name + (car (split-string (or .updateAuthor.emailAddress "") "@")) + "")))) + wl)))) + '(t "WorklogAuthoredByCurrentUser" + (lambda (wl) + (let-alist wl + (when + (and wl + (string-equal + (downcase + (or jiralib-user-login-name user-login-name)) + (downcase (or .author.name + (car (split-string (or .author.emailAddress "") "@")))))) + wl)))))) + ;; :mode-hydra + ;; (org-mode + ;; (:title "Org-Jira" :foreign-keys warn :quit-key "q" :color blue) + ;; ("Issues" + ;; (("Jiu" org-jira-update-issues "update issues") + ;; ("Jig" org-jira-get-issue "get a single issue") + ;; ("JiG" org-jira-get-issues "get all issues") + ;; ("Jisr" org-jira-set-issue-reporter "set the reporter of the issue")))) + :config + (setq org-jira-custom-jqls (list + '(:jql "(assignee is EMPTY OR assignee = currentUser()) AND sprint IN openSprints()" :limit 1500 :filename "coherent-personal-CurrentSprints") + '(:jql "(assignee is EMPTY OR assignee = currentUser()) AND sprint IN futureSprints()" :limit 1500 :filename "coherent-personal-FutureSprints") + '(:jql "(assignee is EMPTY OR assignee = currentUser()) AND sprint IN closedSprints()" :limit 1500 :filename "coherent-personal-PastSprints") + '(:jql "(assignee is EMPTY OR assignee = currentUser()) AND resolution IS EMPTY AND sprint IS EMPTY" :limit 1500 :filename "coherent-personal-Backlog") + '(:jql "resolution IS EMPTY AND sprint IN closedSprints()" :limit 1500 :filename "coherent-orgint-MissedTasks") + ;; end-of-list + )) + (progn)) + + #+end_src +*** for use with Pocket +**** Reader and Manager for Pocket +:PROPERTIES: +:ID: 5AF79039-36B8-4C31-B807-6F353E3C25AB +:END: +setup =pocket-reader= + #+begin_src emacs-lisp +;; homepage, https://github.com/alphapapa/pocket-reader.el +;; use =M-x pocket-reader-add-link= to import link at point to Pocket, (works in eww, Org, w3m, a few others) +;; auth-token at ~/.cache/emacs-pocket-lib-token.json +(use-package pocket-reader + :custom + (pocket-reader-color-title nil) + (pocket-reader-default-queries nil) + (pocket-reader-show-count 250) + (pocket-reader-site-column-max-width 20) + :config + (progn)) + + #+end_src +*** for use with Dropbox +**** Enable Dropbox access via TRAMP +:PROPERTIES: +:ID: 0FACAEF8-8770-4C5F-8E19-20699C820DF5 +:END: +setup =dropbox.el= + #+begin_src emacs-lisp +;; provides a dropbox TRAMP method prefix: '/db:' +;; ,LOG: 20200128_NGa still in evaluative testing +(use-package dropbox + :if (bound-and-true-p dropbox-access-token) ;; should be setup in customize or secure alternative + :custom + ;(dropbox-access-token "") ;; please resist the desire to add secrets to this file + (dropbox-prefix "db") ;; default is "db" + :commands (dropbox-connect) + :config + (require 'dropbox) + (dropbox-connect) + (add-to-list 'tramp-methods (list dropbox-prefix))) + #+end_src + +*** for use with WTTR Weather Report +**** Local Weather status using <<>> +:PROPERTIES: +:ID: 72170A73-F00A-4D9A-AE38-331E70428899 +:END: + #+begin_src emacs-lisp +(use-package display-wttr + :custom + (display-wttr-format "1") + :config + (progn)) + #+end_src +*** for use with Reverso :feature_preview: +**** COMMENT enable Translations, Grammar, and other Human Languange services using <<>> +:PROPERTIES: +:ID: EFED388D-1312-4168-A356-ADF4A41D7235 +:END: +:LOGBOOK: +- Refiled on [2023-02-28 Tue 15:13] +:END: +NB: this package relies on and comunicates with the webservices at https://reverso.net + #+begin_src emacs-lisp +(use-package reverso + :config + (progn)) + #+end_src + +** declare Module feature :feature_preview:pending_review:noexport: +:PROPERTIES: +:ID: F2CB2AB1-24A6-4513-8797-AF2109BCC5A8 +:END: +#+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; declare rapport feature + (provide 'rapport-miscellany) +#+end_src + +* /Chapter/ *X*, Trials and Experiments :pending_review:provide@rapport_xtrialx#rapport:noexport: +:PROPERTIES: +:header-args:emacs-lisp: :tangle (expand-file-name "rapport-xtrialx.el" (org-sbe rapport-sbe--get-libdir)) +:END: + +** Miscellany, Snippets, and Knick-Knacks :REFILE: +*** Get Count of Org-Tag instances +:PROPERTIES: +:ID: 932BDD77-B8C4-40CA-BC7C-2E18B590ABC8 +:END: + - from https://stackoverflow.com/a/27527252 -by- John Kitchen [[ebdb:uuid/3F8C0151-6B00-45D9-B284-4D45717035ED][[ebdb]​]] + #+begin_src emacs-lisp +(defun get-tag-counts () + (let ((all-tags '())) + (org-map-entries + (lambda () + (let ((tag-string (car (last (org-heading-components))))) + (when tag-string + (setq all-tags + (append all-tags (split-string tag-string ":" t))))))) + + + ;; now get counts + (loop for tag in (-uniq all-tags) + collect (cons tag (cl-count tag all-tags :test 'string=))))) + #+end_src +*** COMMENT Record Org-Heading's "Modified Time" as a Property :feature_preview: +:PROPERTIES: +:ID: BB6B3A13-F712-46DB-B678-7596C1AFE749 +:END: + +An Org Entry's content is hashed and, on changes, the timestamp in it's =MODIFIED= property is updated +This process effects all files timestamp an is enabled only whil the variable =rapport-emacs-opt-org-modification-tracking= is non-nil. + +/on Control Variables/ +| Emacs Lisp Variable | Environment Variable | Description | Type | Values | +|----------------------------------+-----------------------------------+-------------+--------+-------------------------------------| +| =rapport-emacs-opt-org-modified= | =RAPPORT_EMACS__OPT_ORG_MODIFIED= | | symbol | ='agenda=, ='buffer=, ='tag=, =nil= | +| | | | | | + + #+begin_src emacs-lisp +(defun rapport/org-modified/getentryhash () + "Get the hash sum of the text in current entry, excluding :PROPERTIES: and :LOGBOOK: drawers." + (save-excursion + (let* ((beg (progn (org-back-to-heading) (point))) + (end (progn + (forward-char) + (if (not (re-search-forward "^\*+ " (point-max) t)) + (point-max) + (match-beginning 0)))) + (entry-content (buffer-substring-no-properties beg end)) + ;; + (entry-content (if (string-match org-logbook-drawer-re entry-content) + (replace-match "" nil nil entry-content) + entry-content)) + ;; + (entry-content (if (string-match org-property-drawer-re entry-content) + (replace-match "" nil nil entry-content) + entry-content)) + ;; ;; + ;; (entry-content (if (string-match org-property-start-re entry-content) + ;; (replace-match "" nil nil entry-content) + ;; entry-content)) + ;; (entry-content (if (string-match org-property-end-re entry-content) + ;; (replace-match "" nil nil entry-content) + ;; entry-content)) + ;; ;; + ;; (entry-content (if (string-match "^ *:HASH:.+\n" entry-content) + ;; (replace-match "" nil nil entry-content) + ;; entry-content)) + ;; (entry-content (if (string-match "^ *:MODIFIED:.+\n" entry-content) + ;; (replace-match "" nil nil entry-content) + ;; entry-content)) + + ) + ; ,TEST: 20240309 is 'md5 + base64 preferable here,; (base64-encode-string (md5 entry-content))))) + (sxhash entry-content)))) + +;; +(defun rapport/org-modified/update-modification-time () + "Set the :MODIFIED: property of the current entry to NOW and update :HASH: property." + (org-set-property "HASH" (format "%s" (rapport/org-modified/getentryhash))) + (org-set-property "MODIFIED" (format-time-string "[%Y-%m-%d %a %H:%M]"))) +;; +(defun rapport/org-modified/skip-nonmodified () + "Skip org entries, which were not modified according to the :HASH: property" + (let ((next-headline (save-excursion (or (outline-next-heading) (point-max))))) + (if (string= (org-entry-get (point) "HASH" nil) (format "%s" (rapport/org-modified/getentryhash))) + next-headline + nil))) +;; +(define-advice rapport/org-modified/-check-agenda-file (:around (OLDFUN file) ignore-non-existant-files) + "Suppress \"Non existent agenda file...\" query. Just continue." + (if (file-exists-p file) + (funcall OLDFUN file) + (progn + (org-remove-file file) + (throw 'nextfile t)))) + +;; ,HINT: consolidate the two control variables into a single multi-choice (opt: 'buffer, 'agenda, 'nil) defcustom variable +(add-hook 'before-save-hook + (lambda () + (when (and (bound-and-true-p rapport-emacs-opt-org-modified) + (symbolp rapport-emacs-opt-org-modified)) + (cond + ;; ,HINT: cond-clause: if enabled for agenda-wide updates + ((and + (eq rapport-emacs-opt-org-modified 'agenda) + (eq major-mode 'org-mode)) + (advice-add 'rapport/org-modified/-check-agenda-file :around #'rapport/org-modified/-check-agenda-file@ignore-non-existant-files) + (org-map-entries #'rapport/org-modified/update-modification-time nil 'agenda #'rapport/org-modified/skip-nonmodified) + (advice-remove 'rapport/org-modified/-check-agenda-file #'rapport/org-modified/-check-agenda-filee@ignore-non-existant-files)) + ;; ,HINT: cond-clause: if enabled only for current-buffer updates + ((and + (eq rapport-emacs-opt-org-modified 'buffer) + (eq major-mode 'org-mode)) + (org-map-entries #'rapport/org-modified/update-modification-time nil 'file #'rapport/org-modified/skip-nonmodified)) + ;; ,HINT: cond-clause: enable for the heading/subtree under/containing point if it has an "ORG_MODIFIED" tag + ((and + (eq rapport-emacs-opt-org-modified 'tag) + (eq major-mode 'org-mode)) + (org-map-entries #'rapport/org-modified/update-modification-time "ORG_MODIFIED" 'tree #'rapport/org-modified/skip-nonmodified)) + ;; ,HINT: cond-clause: (fallthrough) if no preceeding match hits, perform no action + (t)) + ;; end-of-cond-clauses + ))) + #+end_src + +*** enable File Browser and Directory Editor w/ <<>> :feature_preview:pending_review: +:PROPERTIES: +:ID: AF11668A-8D6E-42D8-8178-61848081099F +:END: + +#+begin_src emacs-lisp +;; ,refs: https://github.com/alexluigit/dirvish +(use-package dirvish + :config + (dirvish-override-dired-mode) + (progn)) +#+end_src +** relating to AI, LLM, and Copilot topics +--- _/overview/_ --- + - NGa prefers packages that can work with OpenAI, Gemini, a/o Llamafile. + +--- _/info/notes/_ --- +- *on Sources* + - [[https://www.youtube.com/watch?v=H8jvhz0CGzU][Boost your Emacs productivity with ChatGPT and Copilot]] -by- [[https://www.youtube.com/@skybert][Skybert Hacks]] + - [[https://github.com/Mozilla-Ocho/llamafile][Distribute and run LLMs with a single file.]] -by- [[https://github.com/Mozilla-Ocho][Mozilla Ocho]] + - [[https://github.com/jart/emacs-copilot][Emacs-Copilot]] (local/offline, but relatively unpolished) + - https://github.com/emacs-openai + +*** COMMENT using <<>> +:PROPERTIES: +:ID: 38C097E9-5E05-43DD-A0A7-F223AAD3C313 +:END: + - https://github.com/xenodium/chatgpt-shell + #+begin_src emacs-lisp + ;; ,HINT: chatgpt-shell requires shell-maker + ;; (use-package shell-maker + ;; :straight (:host github :repo "xenodium/chatgpt-shell" :files ("shell-maker.el"))) + + (use-package chatgpt-shell + :after (:all shell-maker) + :custom + ((chatgpt-shell-openai-key + (lambda () + (auth-source-pass-get 'secret "openai-key"))))) + #+end_src +*** COMMENT using <<>> +:PROPERTIES: +:ID: 2FAF9368-746E-497B-8E4C-FE2A7A5AE840 +:END: + - https://github.com/s-kostyaev/ellama + #+begin_src emacs-lisp +;; YOU DON'T NEED NONE OF THIS CODE FOR SIMPLE INSTALL +;; IT IS AN EXAMPLE OF CUSTOMIZATION. +(use-package ellama + :init + ;; setup key bindings + (setopt ellama-keymap-prefix "C-c e") + ;; language you want ellama to translate to + (setopt ellama-language "German") + ;; could be llm-openai for example + (require 'llm-ollama) + (setopt ellama-provider + (make-llm-ollama + ;; this model should be pulled to use it + ;; value should be the same as you print in terminal during pull + :chat-model "mistral:7b-instruct-v0.2-q6_K" + :embedding-model "mistral:7b-instruct-v0.2-q6_K")) + ;; Predefined llm providers for interactive switching. + ;; You shouldn't add ollama providers here - it can be selected interactively + ;; without it. It is just example. + (setopt ellama-providers + '(("zephyr" . (make-llm-ollama + :chat-model "zephyr:7b-beta-q6_K" + :embedding-model "zephyr:7b-beta-q6_K")) + ("mistral" . (make-llm-ollama + :chat-model "mistral:7b-instruct-v0.2-q6_K" + :embedding-model "mistral:7b-instruct-v0.2-q6_K")) + ("mixtral" . (make-llm-ollama + :chat-model "mixtral:8x7b-instruct-v0.1-q3_K_M-4k" + :embedding-model "mixtral:8x7b-instruct-v0.1-q3_K_M-4k")))) + ;; Naming new sessions with llm + (setopt ellama-naming-provider + (make-llm-ollama + :chat-model "mistral:7b-instruct-v0.2-q6_K" + :embedding-model "mistral:7b-instruct-v0.2-q6_K")) + (setopt ellama-naming-scheme 'ellama-generate-name-by-llm) + ;; Translation llm provider + (setopt ellama-translation-provider (make-llm-ollama + :chat-model "sskostyaev/openchat:8k" + :embedding-model "nomic-embed-text"))) + #+end_src +*** COMMENT using <<>> :risk@swpkg_unmanaged_reqs: + - [2024-03-16 Sat 22:50] NGa observess that the project ReadME mentions that it requires a =nodejs= install to work properly and this makes me disinclined to want to use this package. + - +setup https://github.com/copilot-emacs+ (left unimplemented) +*** COMMENT using <<>> +:PROPERTIES: +:ID: C52E9012-9CCA-4AB5-97AF-D1990472E98B +:END: + - setup from https://github.com/emacs-openai/codegpt + #+begin_src emacs-lisp +(use-package codegpt + :demand t + :ensure (codegpt :type git :host github :repo "emacs-openai/codegpt" :main "codegpt.el") + :config + (progn)) + + #+end_src + - documentation + #+CAPTION: CcodeGPT - Use GPT-3 inside Emacs + #+begin_src org +This Emacs Code extension allows you to use the official OpenAI API to generate code or natural language responses from OpenAI's [[https://en.wikipedia.org/wiki/GPT-3][GPT-3]] to your questions, right within the editor. + +πŸ”¨ Usage + + Highlight or select code using the =set-mark-command= , then do: + : M-x codegpt + + + List of supported commands, + + | Commad | Description | + |------------------+-----------------------------------------| + | ~codegpt~ | The master command | + | ~codegpt-custom~ | Write your own instruction | + | ~codegpt-doc~ | Automatically write documentation for your code | + | ~codegpt-fix~ | Find problems with it | + | ~codegpt-explain~ | Explain the selected code | + | ~codegpt-improve~ | Improve, refactor or optimize it | + +🌟 Using ChatGPT + + The default is completing through the [[https://platform.openai.com/docs/api-reference/completions][Completions]] tunnel. If you want to use ChatGPT, do the following: + : (setq codegpt-tunnel 'chat) ; The default is 'completion + : (setq codegpt-model "gpt-3.5-turbo") ; You can pick any model you want! + + +πŸ“ Customization πŸ§ͺ Variables + + - =codegpt-tunnel= - Completion channel you want to use. (Default: =completion= ) + - =codegpt-model= - ID of the model to use. + - =codegpt-max-tokens= - The maximum number of tokens to generate in the completion. + - =codegpt-temperature= - What sampling temperature to use. + #+end_src +*** COMMENT using <<>> + - setup from https://melpa.org/#/org-ai, https://github.com/rksm/org-ai + - +** Secrets Management +*** COMMENT bitwarden support w/i Emacs using <<>> +:PROPERTIES: +:ID: 80EBB050-33E8-44B2-902D-EAD653AD020A +:END: + - https://github.com/seanfarley/emacs-bitwarden + #+begin_src emacs-lisp +(use-package bitwarden + :defer t + :ensure (bitwarden :build t + :type git + :repo "https://labs.phundrak.com/phundrak/bitwarden.el")) + + #+end_src +** toward greater Editors +*** using <<>> +:PROPERTIES: +:ID: D6D96B3C-326C-4415-BDE0-E5E627C9A1C8 +:END: + - setup from https://github.com/jcs-elpa/undo-tree-vf + #+begin_src emacs-lisp +(use-package undo-tree-vf + :ensure (undo-tree-vf :type git :host github :repo "jcs-elpa/undo-tree-vf") + :config + (progn)) + #+end_src +*** using <<>> +:PROPERTIES: +:ID: 9DC3E7C9-6F51-40D2-B458-84ED71EF22E2 +:END: + - setup from https://github.com/joaotavora/breadcrumb + #+begin_src emacs-lisp +(use-package breadcrumb + :hook prog-mode conf-mode + :config + (progn)) + #+end_src +*** Connect Items using <<>> +:PROPERTIES: +:ID: 5A617F9D-D6BE-468E-B189-A953B5CB2F86 +:END: + + #+begin_src emacs-lisp +(use-package org-super-links + ;; ,HINT: key-binds accessible behind 'C-c C-: ...' + :ensure (org-super-links :type git :host github :repo "toshism/org-super-links" :branch "develop") + :bind (("C-c C-: C-s" . org-super-links-link) + ("C-c C-: l" . org-super-links-store-link) + ("C-c C-: C-l" . org-super-links-insert-link)) + :custom + (org-super-links-related-into-drawer t) + ;(org-super-links-backlink-into-drawer t) ;; ,default: t + ;(org-super-links-related-drawer-default-name "RELATED") ;; ,default: "RELATED" + :config + (progn)) + #+end_src + +*** Lazily-Efficient Spell Checking using <<>> +:PROPERTIES: +:ID: C8FFCC48-055D-47E2-9207-5F531847A1A7 +:END: +- from https://melpa.org/#/jinx, https://github.com/minad/jinx + #+begin_src emacs-lisp +;; ,ref: https://github.com/minad/jinx +;; ,HINT: requires libenchant +(use-package jinx + :bind (("M-$" . jinx-correct) + ("C-M-$" . jinx-languages))) + #+end_src + +** toward greater Endeavors +*** Quickly Show Tag Clocking Total in Mini-Buffer +:PROPERTIES: +:ID: B96755FA-8BFC-4BCE-A3C2-02958DE97860 +:END: + #+begin_src emacs-lisp +;; ,ref: https://sachachua.com/blog/2008/01/tagging-in-org-plus-bonus-code-for-timeclocks-and-tags/ +;; (defun wicked/org-calculate-tag-time (matcher &optional ts te) +(defun rapport/org/calculate-tag-time (matcher &optional ts te) + "Return the total minutes clocked in headlines matching MATCHER. +MATCHER is a string or a Lisp form to be evaluated, testing if a +given set of tags qualifies a headline for inclusion. TS and TE +are time start (inclusive) and time end (exclusive). Call with a +prefix to be prompted for TS and TE. + +For example, to see how much time you spent on tasks tagged as +URGENT, call M-x wicked/org-calculate-tag-time RET URGENT RET. To +see how much time you spent on tasks tagged as URGENT today, call +C-u M-x wicked/org-calculate-tag-time RET URGENT RET . RET +1 RET." + (interactive (list + (if (bound-and-true-p matcher) matcher + (completing-read "Tag query: " + (if current-prefix-arg (org-read-date)) + (if current-prefix-arg (org-read-date)))) + ;; Convert strings to proper arguments + (if (stringp matcher) (setq matcher (cdr (org-make-tags-matcher matcher)))) + (if (stringp ts) + (setq ts (time-to-seconds (apply 'encode-time (org-parse-time-string ts))))) + (if (stringp te) + (setq te (time-to-seconds (apply 'encode-time (org-parse-time-string te))))) + (let* ((re (concat "[\n\r]" outline-regexp " *\\(\\<\\(" + (mapconcat 'regexp-quote org-todo-keywords-1 "\\|") + (org-re + "\\>\\)\\)? *\\(.*?\\)\\(:[[:alnum:]_@:]+:\\)?[ \t]*$"))) + (case-fold-search nil) + lspos + tags tags-list tags-alist (llast 0) rtn level category i txt p + marker entry priority (total 0)) + (save-excursion + (org-clock-sum ts te) + (goto-char (point-min)) + (while (re-search-forward re nil t) + (catch :skip + (setq tags (if (match-end 4) (match-string 4))) + (goto-char (setq lspos (1+ (match-beginning 0)))) + (setq level (org-reduced-level (funcall outline-level)) + category (org-get-category)) + (setq i llast llast level) + ;; remove tag lists from same and sublevels + (while (>= i level) + (when (setq entry (assoc i tags-alist)) + (setq tags-alist (delete entry tags-alist))) + (setq i (1- i))) + ;; add the nex tags + (when tags + (setq tags (mapcar 'downcase (org-split-string tags ":")) + tags-alist + (cons (cons level tags) tags-alist))) + ;; compile tags for current headline + (setq tags-list + (if org-use-tag-inheritance + (apply 'append (mapcar 'cdr tags-alist)) + tags)) + (when (and (eval matcher) + (or (not org-agenda-skip-archived-trees) + (not (member org-archive-tag tags-list)))) + ;; Get the time for the headline at point + (goto-char (line-beginning-position)) + (setq total (+ total (or (get-text-property (1+ (point)) :org-clock-minutes) 0))) + ;; if we are to skip sublevels, jump to end of subtree + (org-end-of-subtree t))))) + (if (interactive-p) + (let* ((h (/ total 60)) + (m (- total (* 60 h)))) + (message "Time: %d:%02d (%d hours and %d minutes)" h m h m))) + total)) + #+end_src +*** using <<>> :under_review:feature_preview: +:PROPERTIES: +:ID: 452AE577-78B3-40D0-A149-BB3D02970093 +:END: +#+begin_src emacs-lisp + (use-package org-effectiveness + :after (:all org) + :ensure nil + + :config + (require 'org-effectiveness) + (progn)) +#+end_src + +*** using <<>> :under_review:feature_preview: +:PROPERTIES: +:ID: 3BC5C07E-C120-490F-BBA7-003D9AED7044 +:END: +#+begin_src emacs-lisp +(use-package org-choose + :after (:all org) + :ensure nil + + :config + (require 'org-choose) + (progn)) +#+end_src + +*** COMMENT Task Delegation using <<>> :deprecation_candidate:under_review:ARCHIVE: +:PROPERTIES: +:ID: 957491AD-2B9F-44AF-9FD1-CC42F91FFCC9 +:END: +#+begin_src emacs-lisp +(use-package org-secretary + :after (:all org-contrib) + :ensure nil + + :config + (require 'org-secretary) + (progn)) +#+end_src + +*** using <<>> +:PROPERTIES: +:ID: A36B173B-97F7-4254-949B-C3F7DB497AE2 +:END: +#+begin_src emacs-lisp +(use-package org-registry + :after (:all org-contrib) + :ensure nil + + :config + (require 'org-registry) + (progn)) +#+end_src + +*** using <<>> :under_review:feature_preview: +:PROPERTIES: +:ID: E820ACC3-83E3-44B6-AA9B-961D6929139D +:END: + +#+begin_src emacs-lisp +;; https://github.com/inickey/org-clock-reminder +(use-package org-clock-reminder + :custom + (org-clock-reminder-interval '(15 . 30)) ; By default, notifications (active, inactive) are shown every 10 minutes + (org-clock-reminder-inactive-notifications-p t) ; Reminders during periods of inactivity, (off by default) + (org-clock-reminder-icons nil) ; Don't show icons. + ;; ,NB: These changes are picked up automatically, and the timer is automatically reset on change. + ;; - Reminders during periods of inactivity are off by default, but may be activated easily, by setting org-clock-reminder-inactive-notifications-p to a non-nil value. + ;; - Notification contents can be changed quite easily. Titles and bodies are formatted using the format specifiers org-clock-reminder-formatters (a list of (char . expr) pairs), which by default has %c as the current clocked in time, and %h as the current clocked-in task. Format strings available are: + ;; - org-clock-reminder-active-title and org-clock-reminder-active-text: The title and body of active (clocked-in) notifications, respectively. + ;; - org-clock-reminder-inactive-title and org-clock-reminder-inactive-text: The title and body of inactive (clocked-out) notifications, respectively. + :config + (require 'org-clock-reminder) + (org-clock-reminder-mode +1) + (progn)) +#+end_src + +*** using <<>> +:PROPERTIES: +:ID: 7C67B528-0FF0-4F17-85A2-144ECC673992 +:END: +#+begin_src emacs-lisp +(use-package org-mru-clock + :bind (("C-c C-x i" . org-mru-clock-in) + ("C-c C-x C-j" . org-mru-clock-select-recent-task)) + :custom + (org-mru-clock-how-many 100) + :config + (progn)) +#+end_src +*** Convenient Scheduling using <<>> :risk@unmaintained_upsteam:deprecation_candidate: +:PROPERTIES: +:ID: 759C9F06-580C-46A7-95AC-CFD6BB252C6A +:END: + +#+begin_src emacs-lisp + ;; ,ref: https://github.com/yasuhito/orgbox + (use-package orgbox + :after (:all org) + :config + (require 'orgbox) + (progn)) +#+end_src + +*** COMMENT Easy Syntax for Repeating Tasks using <<>> :feature_preview: +:PROPERTIES: +:ID: 6C377618-8A9D-41B3-8CD6-2B3A8D2EEE19 +:END: +:LOGBOOK: +- Refiled on [2023-07-27 Thu 22:53] +:END: + +#+begin_src emacs-lisp +;; ,ref: https://github.com/mrcnski/org-recur +;; ,NB: Note that TODO cookies must be first. Org-Recur's syntax `|wkdy|` can appear anywhere in the heading. +(use-package org-recur + :hook ((org-mode . org-recur-mode) + (org-agenda-mode . org-recur-agenda-mode)) + :bind + (:map org-recur-mode-map + ("C-c d" . org-recur-finish) + :map org-recur-agenda-mode-map + ("d" . org-recur-finish) ;; Rebind the 'd' key in org-agenda, default: `org-agenda-day-view'. + ("C-c d" . org-recur-finish)) + :custom + (org-read-date-prefer-future 'time) + :config + (setq org-recur-finish-done t + org-recur-finish-archive t) + ;; Refresh org-agenda after rescheduling a task. + (defun org-agenda-refresh () + "Refresh all `org-agenda' buffers." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (when (derived-mode-p 'org-agenda-mode) + (org-agenda-maybe-redo))))) + + (defadvice org-schedule (after refresh-agenda activate) + "Refresh org-agenda." + (org-agenda-refresh)) + + (progn)) +#+end_src + +As supplement and alternative to: +- https://karl-voit.at/2017/01/15/org-clone-subtree-with-time-shift/ +- https://orgmode.org/manual/Tracking-your-habits.html + +*** using <<>> :feature_preview: +:PROPERTIES: +:ID: E9FA7E33-6C7A-4799-B3C6-E671182D2A4C +:END: + + - setup from https://github.com/cashpw/summarize-agenda-time + #+begin_src emacs-lisp +(use-package summarize-agenda-time + :demand + :ensure (summarize-agenda-time :type git :host github :repo "cashpw/summarize-agenda-time" :main "summarize-agenda-time.el") + :config + (progn)) + #+end_src +** toward greater Acculturation +*** using <<>> +:PROPERTIES: +:ID: 552ED40D-BF36-4057-A911-547422D9E769 +:END: + - setup from https://github.com/alphapapa/listen.el/ + #+begin_src emacs-lisp +;; Install Listen. +(use-package listen + :if (executable-find "vlc") + :ensure (listen :type git :host github :repo "alphapapa/listen.el") + :config + (progn)) + #+end_src +*** using EMP (<<>>) +:PROPERTIES: +:ID: 09A7B99E-9C62-4009-82A1-17903B164A69 +:END: + - setup from https://github.com/jcs-elpa/emp + #+begin_src emacs-lisp + + #+end_src +*** using <<>> +:PROPERTIES: +:ID: FC71BCB6-7875-4A3C-8D0F-BDAF3BB7B591 +:END: + #+begin_src emacs-lisp + (use-package fretboard + :ensure (:host github :repo "vifon/fretboard.el") +;; ,FIXME: 20240217_NGa straight-keyword-inhibits-elpaca-load ;; :straight (:host github :repo "vifon/fretboard.el") + :config + (progn)) + #+end_src + +** toward greater Coherence +*** Powerful Interval Timers using <<> +:PROPERTIES: +:ID: 538BA72B-D802-4D12-B1A9-7A38C85AB7D6 +:END: + #+begin_src emacs-lisp + ;; ,ref: https://github.com/alphapapa/hammy.el + (use-package hammy + :config + (setf mode-line-misc-info + ;; When the tab-bar is active, don't show global-mode-string + ;; in mode-line-misc-info, because we now show that in the + ;; tab-bar using `tab-bar-format-align-right' and + ;; `tab-bar-format-global'. + (remove '(global-mode-string ("" global-mode-string)) + mode-line-misc-info)) + (unless (member 'tab-bar-format-global tab-bar-format) + ;; Show `global-mode-string' in the tab bar. + (setf tab-bar-format (append tab-bar-format '(tab-bar-format-align-right tab-bar-format-global)))) + (progn)) + #+end_src +** toward greater Composure +*** using <<>> +:PROPERTIES: +:ID: F1BE5DAB-A6DD-4E99-B5A8-FA6EB21B79AB +:END: + - parsing for encoded symbols + #+begin_src emacs-lisp +(defun rapport/semref/-decode (input &optional rapport/semref/schema) + + #+end_src +*** using <<>> +:PROPERTIES: +:ID: 7FE710E5-1FB6-42D6-A3AD-C593158E4DC0 +:END: + - taxonomies for semantic + #+begin_src emacs-lisp + + #+end_src +*** using <<>> +:PROPERTIES: +:ID: 6AD6E5B9-2FD5-4D43-B98B-4A9F751DF74E +:END: + - a simple notation for recording Directed Acyclic Graph [[id:594B22FA-D0CD-4795-A6B8-C0D31F31E187][[roam]​]] suitable for storing suitable + #+begin_src emacs-lisp + + #+end_src +*** using <<>> +:PROPERTIES: +:ID: 2622214B-57FB-4C48-9561-63CE4C2BFF03 +:END: + + #+begin_src emacs-lisp + (use-package taxy + :config + (progn)) + #+end_src + +*** using <<>> +:PROPERTIES: +:ID: 6B4AEAF8-6D7C-43FE-9E1E-6E5088C2AF01 +:END: +#+begin_src emacs-lisp +(use-package org-ql + :config + (progn)) +#+end_src + + +*** Strategic Prioritization via Eisenhower Matrix using <<>> +:PROPERTIES: +:ID: 13665AFE-63D5-432A-B65E-EAEF4C71FCD9 +:END: + +A minor mode that displays org priorities as custom strings. + +https://github.com/harrybournis/org-fancy-priorities +#+begin_src emacs-lisp :lexical t + (use-package org-fancy-priorities + :after (:all org) + :commands (org-fancy-priorities-mode) + :hook (org-mode . org-fancy-priorities-mode) + :config + ;;"Eisenhower Matrix of Importance and Urgency" + (defvar rapport/org-fancy-priorities/-eisenhower-matrix + "↑ |-----------+-----------| + I | Eisenhower Matrix | + M |-----------+-----------| + P | | | + O | Schedule | Immediate | + R | | | + T |-----------+-----------| + A | | | + N | Eliminate | Delegate | + C | | | + E |-----------+-----------| + URGENCY β†’" + "Eisenhower Matrix help text.") + (setq org-fancy-priorities-list + (mapcar + (lambda (cell) (format (car cell) + (propertize + (cdr cell) + 'help-echo rapport/org-fancy-priorities/-eisenhower-matrix))) + '(("I∧U (%s)" . "I") + ("IΒ¬U (%s)" . "S") + ("Β¬IU (%s)" . "D") + ("Β¬IΒ¬U (%s)" . "E")))) + (progn)) +#+end_src + +** toward greater Charms +*** using <<>> +:PROPERTIES: +:ID: 2A52DAEC-42DB-4084-94A6-42210F525B34 +:END: + - setup from https://github.com/tonyaldon/org-bars + #+begin_src emacs-lisp +(use-package org-bars + :ensure (org-bars :type git :host github :repo "tonyaldon/org-bars") + :config + (require 'org-bars) + (add-hook 'org-mode-hook #'org-bars-mode) + (progn)) + #+end_src +*** using <<>> +:PROPERTIES: +:ID: BC901C45-AFDE-4484-BE37-F65B6FE6CCF4 +:END: + - setup from https://github.com/jdtsmith/org-modern-indent + #+begin_src emacs-lisp +(use-package org-modern-indent + :ensure (org-modern-indent :type git :host github :repo "jdtsmith/org-modern-indent") + :config + (add-hook 'org-mode-hook #'org-modern-indent-mode 90) + (progn)) + #+end_src +** toward greater Equilibrium +*** using <<>> +:PROPERTIES: +:ID: 75295EC7-0F7B-4C8D-A529-6973B65CAE05 +:END: + - setup from https://github.com/anonimitoraf/exercism.el + #+begin_src emacs-lisp +(use-package exercism + :demand + :if (executable-find "exercism") + :custom + (exercism-directory (expand-file-name (format "%s_execism" ( + (exercism-executable (executable-find "exercism")) + :config + (progn)) + #+end_src +** declare Module feature :noexport: +:PROPERTIES: +:ID: 67BCE642-6ED4-45EE-8A6C-C6CDED73E1BA +:END: + #+begin_src emacs-lisp + ;; sync-action before proceeding + (elpaca-wait) + + ;; declare rapport feature +(provide 'rapport-xtrialx) + #+end_src +* /Conclusion/ :noexport: +** Epilogue +** Afterword +* /Appendix/ :noexport: +:PROPERTIES: +:ID: F2CE33E2-41DA-4D12-B52E-35BEECC2649D +:END: +** Advisement :noexport: + +**** Notable Customization Variables + | name | t | desc | default-value | defined-in-feature | remove? | env-var | + |-----------------------------------------------------------+---+------+---------------+--------------------+---------+--------------------------------------------------------------| + | rapport-emacs-opt-featureset-inhibit-presets | | | | | | =RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_PRESETS= | + | rapport-emacs-opt-featureset-inhibit-discovery-at-startup | | | | | | =RAPPORT_EMACS__OPT_FEATURESET_INHIBIT_DISCOVERY_AT_STARTUP= | + | rapport-emacs-opt-featureset-load-custom-from-env | | | | | | =RAPPORT_EMACS__OPT_FEATURESET_LOAD_CUSTOM= | + | rapport-emacs-opt-featureset-load-presets-from-env | | | | | | =RAPPORT_EMACS__OPT_FEATURESET_LOAD_PRESETS= | + | | | | | | | | + | rapport-emacs-opt-load-custom-file | | | | | y | | + | rapport-emacs-opt-theme | | | | | | | + | rapport-emacs-opt-modeline | | | | | | | + | rapport-emacs-opt-org-modified | | | | | | | + | rapport-emacs-opt-profiler | | | | | | | + | rapport-emacs-opt-debug | | | | | | =RAPPORT_EMACS__OPT_DEBUG= | + | rapport-emacs-opt-debug-on-error | | | | | | | + | | | | | | | | + | rapport-uri-emacsdotd | | | | | ? | | + | rapport-uri-rapport | | | | | | | + | | | | | | | | + | rapport-emacs-uri-control | | | | | | =RAPPORT_EMACS__URI_CONTROL= | + | rapport-emacs-uri-initdir | | | | | | =RAPPORT_EMACS__URI_INITDIR= | + | rapport-emacs-uri-libdirs | | | | | | =RAPPORT_EMACS__URI_LIBDIRS= | + | rapport-emacs-uri-libdir | | | | | | =RAPPORT_EMACS__URI_LIBDIR= | + | | | | | | | | + | rapport-uri-vault | | | | | | | + | rapport-uri-vault-uris | | | | | | | + | rapport-uri-vault-apps | | | | | | | + | rapport-uri-vault-docs | | | | | | | + | rapport-uri-vault-docs-concepts | | | | | | | + | rapport-uri-vault-docs-contacts | | | | | | | + | rapport-uri-vault-docs-status | | | | | | | + | rapport-uri-vault-docs-media | | | | | | | + | rapport-uri-vault-docs-practices | | | | | | | + | rapport-uri-vault-var | | | | | | | + | rapport-uri-vault-var-emacs | | | | | | | + | rapport-uri-vault-cfgs | | | | | | | + | rapport-uri-vault-cfgs-emacs | | | | | | | + | rapport-uri-vault-cfgs-emacs-apps | | | | | | | + | rapport-uri-vault-cfgs-emacs-apps-org | | | | | | | + | rapport-uri-vault-cfgs-emacs-apps-org-setupfile | | | | | | | + +**** Initialization process + | ix | used-in-file | provides-feature | requires-feature | | + |----+----------------------------+-------------------------------+------------------------+---| + | 1 | =~/.emacs.d/early-init.el= | =rapport-core-emacsearlyinit= | =rapport-core-tangle= | | + | 2 | =~/.emacs.d/early-init.el= | =rapport-core-emacsearlyinit= | =rapport-core-context= | | + |----+----------------------------+-------------------------------+------------------------+---| + | 3 | =~/.emacs.d/init.el= | =rapport-core-emacsinit= | | | + | 4 | | | | | + | 5 | | | | | + +**** Contextualized Persisted Configs + | | type | name | (ex.) *with* context-label | (ex.) *without* context-label | desc | value-template | value-example | + |---+----------+--------------------------+----------------------------+-------------------------------+------+---------------------------------------------------------------------+----------------------------------------------------------------------------------------| + | 1 | var::uri | =org-agenda-files= | | | | | =~/.vault/docs/.status/org-agenda-files._custom-irulan+lan-niklauz-context.txt= | + | 2 | var::uri | =org-id-locations-file= | | | | | =~/.vault/docs/.status/.org-id-locations._custom-irulan+lan-niklauz-context.el= | + | 3 | var::uri | =rapport-uri-vault-uris= | | | | =~/.uris= symlinks to =~/.vault/uris/.vault-uris._/= | =~/.uris= | + | 4 | var::uri | =org-clock-persist-file= | | | | | =~/.vault/docs/.status/org-clock-save._custom-irulan+lan-niklauz-context.eld= | + |---+----------+--------------------------+----------------------------+-------------------------------+------+---------------------------------------------------------------------+----------------------------------------------------------------------------------------| + | | var::uri | =project-list-file= | | | | | =~/.vault/cfgs/emacs/apps/project/custom-irulan+lan-niklauz-context.project.eld= | + | | var::uri | =tabspaces-session-file= | | | | | =~/.extrefs/.vault-var/emacs/tabspaces/custom-irulan+lan-niklauz-context.sessions.eld= | + +**** Path Control for Rapport Emacs + + - add =RAPPORT_EMACS__URI_INITDIR=, as the equivalent to =~/.emacs.d=, aka the =user-emacs-directory=. Defaults to =~/.emacs.d= + - add =RAPPORT_EMACS__URI_LIBDIRS=, as bash-array/list variable containing paths, the principle/assumed first entry provides the default value for the primary Tangle *destination*. Defaults to =("~/.emacs.d/.rapport.d")=. + - add =RAPPORT_EMACS__URI_LIBDIR=, as path, the principle/assumed first entry is the primary Tangle *destination*. Defaults to =~/.emacs.d/.rapport.d=. + - add =RAPPORT_EMACS__URI_CONTROL=, as the path to the controlling =Org-Mode= file. The principle Tangle *source*. Defaults to =${RAPPORT_EMACS__URI_INITDIR}/rapport.org= + +**** Rapport Startup and Feature-Set Interdependencies + - init order + #+begin_example + # ~/.emacs.d/early-init.el: + - rapport-core-emacsearlyinit + - require: rapport-core-featureset .. load feature organization functionality, including presets + - load-preset: tangle-during-earlyinit + - require: rapport-core-tangle + - load-preset: context-during-earlyinit + - require: rapport-core-context + - load-preset: earylinit + - require: rapport-core-context + - require: rapport-core-featureset + - require: rapport-core-functions + - require: rapport-core-variables + - require: rapport-core-pkgs .. pkg-mgmt is one of the final things setup toward the end of the early-init phase + + # ~/.emacs.d/init.el + - require: rapport-core-emacsinit + - require: rapport-core-featureset + - load-preset: init + - require: rapport-core-context + - require: rapport-core-featureset + - require: rapport-core-functions + - require: rapport-core-variables + - require: rapport-core-pkgs + - require: rapport-core-org + - require: rapport-core-sysint + - require: rapport-core-customize + + #+end_example + + - list-presets-by-file.sh + #+begin_example + grep '(rapport-fn-featureset-load-preset' .rapport.d/rapport-*.el | sed 's!.*\(rapport-[-a-z]\+\).el.*rapport-fn-featureset-load-preset .\([-a-z]\+\).*!\1 -> \2!' + #+end_example + + - list-requires-by-file.sh + #+begin_example + grep '(require ' .rapport.d/rapport-*.el | sed 's!.*/\([-a-z]\+\).*require .\([-a-z]\+\).*!\1 -> \2!p' + #+end_example + + - list-presets-by-presets.sh.wip + #+begin_example + #+end_example + +** Defined Terms +:PROPERTIES: +:ID: 9FA83EB9-6AC6-413B-88F7-387740686B3D +:END: + - CIARA :: acronym, Confidentiality, Integrity, Authenticity, Resiliency, Availability. + - Gnus :: email and news client mode in emacs ; alternate means to access email (IMAP and otherwise), including [[http://www.emacswiki.org/emacs/GnusGmail][gmail]] + - IMAP :: an email network access protocol a/o service providing remote-cached, and sync abilities with email + - package.el :: a software install-mgmt system included natively in emacs v24. + - idempotent :: producing the same (or predictable) effect on each + execution. rather than toggling states. + - http://orgmode.org/manual/Library-of-Babel.html + +** Sources +#+TOC: listings +#+TOC: tables +# #+BIBLIOGRAPHY: ref plain limit:t option:-nokeywords +** Footnotes + +[fn:1] a non-exhaustive list of projects I track for inspiration + - [[https://github.com/bbatsov/prelude][emacs-prelude]] by bbatsov + - [[https://github.com/technomancy/emacs-starter-kit][emacs-starter-kit]] by technomancy + - [[https://github.com/EnigmaCurry/emacs][emacs]] by EnigmaCurry + - [[https://github.com/gabrielelanaro/emacs-for-python][emacs-for-python]] by gabrielelanaro + - [[https://github.com/purcell/emacs.d][emacs.d]] by purcell + - [[https://github.com/rpdillon/emacs-config][emacs-config]] by rpdillon + - for literate, (with org-babel), init.el