Initial commit
This commit is contained in:
commit
2a28d0b97a
21 changed files with 132395 additions and 0 deletions
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Remove Emacs garbage
|
||||
*~
|
||||
\#*\#
|
||||
|
||||
# Internal config files
|
||||
.cache/
|
||||
eln-cache/
|
||||
elpa/
|
||||
games/
|
||||
ielm-history.eld
|
||||
org-roam.db
|
||||
org/
|
||||
places
|
||||
projects
|
||||
recentf
|
||||
straight/*
|
||||
tramp
|
||||
transient/
|
||||
url/
|
||||
.org-id-locations
|
||||
bookmarks
|
||||
|
||||
# Custom file
|
||||
custom.el
|
23
README.org
Normal file
23
README.org
Normal file
|
@ -0,0 +1,23 @@
|
|||
#+title: Theurgy
|
||||
|
||||
Theurgy is an Emacs distribution.
|
||||
|
||||
The focus is to make Emacs a complete, distributable, consistent toolbox.
|
||||
|
||||
Additionally, good UI/UX should be provided on a per-workflow basis. Theurgy is tab oriented, with each tab intended to focus on a different workflow.
|
||||
|
||||
Theurgy is very opinionated, but easy to modify.
|
||||
|
||||
* Basics
|
||||
The following is set up across all workflows.
|
||||
|
||||
** Dashboard
|
||||
This is the first present screen when opening Emacs or opening a new tab.
|
||||
|
||||
** Burly
|
||||
For frame and window configuration management.
|
||||
|
||||
* Workflows
|
||||
|
||||
** Exobrain
|
||||
This is the main and default workflow, providing tools for note taking, note storage, and information aggregation.
|
2
early-init.el
Normal file
2
early-init.el
Normal file
|
@ -0,0 +1,2 @@
|
|||
;; Disable package.el in favor of straight.el
|
||||
(setq package-enable-at-startup nil)
|
129704
en_AU.dict
Normal file
129704
en_AU.dict
Normal file
File diff suppressed because it is too large
Load diff
81
init.el
Normal file
81
init.el
Normal file
|
@ -0,0 +1,81 @@
|
|||
;; Fixes a MELPA 403
|
||||
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
|
||||
|
||||
;; Show errors at minimum
|
||||
(setq warning-minimum-level :error)
|
||||
|
||||
;;; Utility functions
|
||||
;; https://emacs.stackexchange.com/a/18441
|
||||
(defun load-directory (directory)
|
||||
"Load recursively all `.el' files in DIRECTORY."
|
||||
(dolist (element (directory-files-and-attributes directory nil nil nil))
|
||||
(let* ((path (car element))
|
||||
(fullpath (concat directory "/" path))
|
||||
(isdir (car (cdr element)))
|
||||
(ignore-dir (or (string= path ".") (string= path ".."))))
|
||||
(cond
|
||||
((and (eq isdir t) (not ignore-dir))
|
||||
(load-directory fullpath))
|
||||
((and (eq isdir nil) (string= (substring path -3) ".el"))
|
||||
(load (file-name-sans-extension fullpath)))))))
|
||||
|
||||
;;; Package Repositories
|
||||
(require 'package)
|
||||
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))
|
||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
||||
(add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
|
||||
(package-initialize)
|
||||
|
||||
;; Install straight.el
|
||||
(defvar bootstrap-version)
|
||||
(let ((bootstrap-file
|
||||
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
|
||||
(bootstrap-version 6))
|
||||
(unless (file-exists-p bootstrap-file)
|
||||
(with-current-buffer
|
||||
(url-retrieve-synchronously
|
||||
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
|
||||
'silent 'inhibit-cookies)
|
||||
(goto-char (point-max))
|
||||
(eval-print-last-sexp)))
|
||||
(load bootstrap-file nil 'nomessage))
|
||||
|
||||
;; Install use-package
|
||||
(straight-use-package 'use-package)
|
||||
|
||||
;; Use straight by default
|
||||
(setq straight-use-package-by-default t)
|
||||
|
||||
;; Always ensure packages to install them automatically
|
||||
(require 'use-package-ensure)
|
||||
(setq use-package-always-ensure t)
|
||||
|
||||
;; TODO: https://github.com/joaotavora/eglot/discussions/1487
|
||||
(use-package eldoc :straight (:type built-in))
|
||||
(use-package org :straight (:type built-in))
|
||||
|
||||
(setq inhibit-startup-screen t
|
||||
inhibit-startup-message t
|
||||
inhibit-startup-echo-area-message t
|
||||
initial-scratch-message nil)
|
||||
|
||||
;; Shared library packages
|
||||
(load (concat user-emacs-directory "shared-packages.el"))
|
||||
;; UI and display related packages
|
||||
(load (concat user-emacs-directory "ui.el"))
|
||||
;; Writing behavior and packages
|
||||
(load (concat user-emacs-directory "writing.el"))
|
||||
;; Navigation behavior and packages
|
||||
(load (concat user-emacs-directory "navigation.el"))
|
||||
;; Window rules
|
||||
(load (concat user-emacs-directory "window-utils.el"))
|
||||
;; Userland application replacements
|
||||
(load-directory (concat user-emacs-directory "userland"))
|
||||
;; Mode/workflow level configuration
|
||||
(load-directory (concat user-emacs-directory "workflows"))
|
||||
;; Custom screens
|
||||
(load-directory (concat user-emacs-directory "screens"))
|
||||
|
||||
;; Use a custom file instead of putting customisations in init.el
|
||||
(setq custom-file (concat user-emacs-directory "custom.el"))
|
||||
(when (file-exists-p custom-file) (load custom-file))
|
88
navigation.el
Normal file
88
navigation.el
Normal file
|
@ -0,0 +1,88 @@
|
|||
;;; navigation.el --- Navigation behavior config -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Smooth scrolling
|
||||
(setq bidi-paragraph-direction 'left-to-right
|
||||
bidi-inhibit-bpa t
|
||||
bidi-display-reordering nil)
|
||||
|
||||
(use-package ultra-scroll
|
||||
:straight (:host github
|
||||
:repo "jdtsmith/ultra-scroll")
|
||||
:init
|
||||
(setq scroll-conservatively 3 ; or whatever value you prefer, since v0.4
|
||||
scroll-margin 0) ; important: scroll-margin>0 not yet supported
|
||||
:config
|
||||
(ultra-scroll-mode 1))
|
||||
|
||||
;; Keyboard Scrolling
|
||||
(global-set-key (kbd "C-<down>") '(lambda () (interactive) (scroll-up-line)))
|
||||
(global-set-key (kbd "C-<up>") '(lambda () (interactive) (scroll-down-line)))
|
||||
|
||||
(global-set-key (kbd "C-S-<down>") '(lambda () (interactive) (scroll-up-line 10)))
|
||||
(global-set-key (kbd "C-S-<up>") '(lambda () (interactive) (scroll-down-line 10)))
|
||||
|
||||
(global-set-key (kbd "M-<up>") #'scroll-other-window-down)
|
||||
(global-set-key (kbd "M-<down>") #'scroll-other-window)
|
||||
|
||||
;; Windmove bindings
|
||||
(global-set-key (kbd "C-c <left>") 'windmove-left)
|
||||
(global-set-key (kbd "C-c <right>") 'windmove-right)
|
||||
(global-set-key (kbd "C-c <up>") 'windmove-up)
|
||||
(global-set-key (kbd "C-c <down>") 'windmove-down)
|
||||
|
||||
;; Fullscreen and maximize button
|
||||
(global-set-key (kbd "C-x <f10>") 'toggle-frame-maximized)
|
||||
(global-set-key (kbd "C-x <f11>") 'toggle-frame-fullscreen)
|
||||
|
||||
;; Line jumps
|
||||
(defun jump-to-line-absolute ()
|
||||
(interactive)
|
||||
(let ((p display-line-numbers))
|
||||
(setq display-line-numbers t)
|
||||
(call-interactively 'goto-line)
|
||||
(setq display-line-numbers p)))
|
||||
|
||||
(defun relative-line-jump-helper (relative-line)
|
||||
(interactive "nGoto line: ")
|
||||
(goto-line (+ (line-number-at-pos) relative-line) '() t))
|
||||
|
||||
(defun jump-to-line-relative ()
|
||||
(interactive)
|
||||
(let ((p display-line-numbers))
|
||||
(setq display-line-numbers 'relative)
|
||||
(call-interactively 'relative-line-jump-helper)
|
||||
(setq display-line-numbers p)))
|
||||
|
||||
(global-set-key (kbd "M-g g") 'jump-to-line-absolute)
|
||||
(global-set-key (kbd "M-g r") 'jump-to-line-relative)
|
||||
|
||||
;; Eglot and flymake bindings
|
||||
(global-set-key (kbd "M-g <left>") 'flymake-goto-prev-error)
|
||||
(global-set-key (kbd "M-g <right>") 'flymake-goto-next-error)
|
||||
(global-set-key (kbd "C-x M-f") 'eglot-code-actions)
|
||||
|
||||
(provide 'navigation)
|
||||
|
||||
;;; navigation.el ends here
|
149
screens/dashboard.el
Normal file
149
screens/dashboard.el
Normal file
|
@ -0,0 +1,149 @@
|
|||
;;; dashboard.el --- A grid-based dashboard -*- lexical-binding: t -*-
|
||||
|
||||
;; Author: Jakub
|
||||
;; Maintainer: Jakub
|
||||
;; Version: 1.0
|
||||
;; Package-Requires: (grid straight)
|
||||
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; For layout
|
||||
(require 'grid)
|
||||
|
||||
(defvar enlight-theurgy-logo
|
||||
(propertize
|
||||
"\n\n\n\n ###########
|
||||
##### ##### #####
|
||||
#### ## ### ####
|
||||
### ### ## ###
|
||||
## ### ### ##
|
||||
## ############### ##
|
||||
### ## ### ### ## ###
|
||||
## ##### ##### ##
|
||||
## ## ## ## ## ##
|
||||
### ### ### ### ## ###
|
||||
##### # ### ### # #####
|
||||
#############################
|
||||
### ###
|
||||
#### ####
|
||||
##### #####
|
||||
########### "
|
||||
'face 'font-lock-keyword-face))
|
||||
|
||||
(defvar enlight-calendar
|
||||
(progn
|
||||
(calendar)
|
||||
(prog1 (with-current-buffer (buffer-name (current-buffer))
|
||||
(buffer-string))
|
||||
(calendar-exit))))
|
||||
|
||||
(defun get-weather ()
|
||||
"Get the weather JSON for THEURGY-CITY."
|
||||
(let ((buf (url-retrieve-synchronously (concat "https://wttr.in/" theurgy-city "?format=j1"))))
|
||||
(when buf
|
||||
(with-current-buffer buf
|
||||
;; Skip HTTP headers
|
||||
(goto-char (point-min))
|
||||
(re-search-forward "\n\n" nil 'move)
|
||||
(delete-region (point-min) (point))
|
||||
;; Now display it
|
||||
(switch-to-buffer buf)
|
||||
(buffer-string)))))
|
||||
|
||||
(defun connected-p ()
|
||||
"Are we connected to the host?"
|
||||
(= 0 (call-process-shell-command "ping -W 5 -c 2 wttr.in")))
|
||||
|
||||
(defun enlight-weather ()
|
||||
(if (connected-p)
|
||||
(progn (let ((weather (aref (gethash "current_condition"
|
||||
(json-parse-string (get-weather) :object-type 'hash-table)) 0)))
|
||||
(concat (propertize "Weather\n\n" 'face 'font-lock-keyword-face)
|
||||
"Currently " (gethash "value" (aref (gethash "weatherDesc" weather) 0)) "\n"
|
||||
"It is " (gethash "temp_C" weather) " degrees, feels like " (gethash "FeelsLikeC" weather) "\n"
|
||||
"Wind speed is " (gethash "windspeedKmph" weather) "km/h\n")))
|
||||
(concat (propertize "Weather\n\n" 'face 'font-lock-keyword-face)
|
||||
"No connection to weather service :(")))
|
||||
|
||||
;; Dashboard screen using enlight
|
||||
(use-package enlight
|
||||
:custom
|
||||
(enlight-content
|
||||
(concat
|
||||
(grid-get-box `(:align center :content ,enlight-theurgy-logo :width 80))
|
||||
(grid-get-row
|
||||
(list
|
||||
(grid-get-box
|
||||
`(:content ,(concat
|
||||
(grid-get-box
|
||||
`( :content
|
||||
,(concat
|
||||
(grid-get-box `( :content ,(propertize "Theurgy Emacs" 'face 'variable-pitch-serif-text)
|
||||
:width 80 :align center)))
|
||||
:width 80))
|
||||
enlight-calendar "\n\n"
|
||||
(grid-get-row
|
||||
(list (grid-get-box `(:content ,(concat
|
||||
(enlight-menu
|
||||
'(("Exobrain"
|
||||
("Agenda" (org-agenda nil "a") "a")
|
||||
("Go to Inbox" open-inbox "i")
|
||||
("Capture" org-capture "c")))))
|
||||
:align left
|
||||
:width 20))
|
||||
(grid-get-box `(:content ,(concat
|
||||
(enlight-menu
|
||||
'(("Projects"
|
||||
("Open" open-project "o")
|
||||
("Project List" open-inbox "p")))))
|
||||
:align center
|
||||
:width 20))
|
||||
(grid-get-box `(:content ,(concat
|
||||
(enlight-menu
|
||||
'(("Userland"
|
||||
("Dired" (dired "~") "d")
|
||||
("RSS" elfeed "r")
|
||||
("Terminal" theurgy-bottom-shell "t")
|
||||
("Weather" theurgy-show-weather "w")))))
|
||||
:align center
|
||||
:width 20))
|
||||
(grid-get-box `(:content ,(concat
|
||||
(enlight-menu
|
||||
'(("Meta"
|
||||
("Elisp Scratch" open-elisp-scratch "s")
|
||||
("Org Scratch" open-org-scratch "o")
|
||||
("Init Dir" (dired user-emacs-directory) "e")
|
||||
("Info" info "h")))))
|
||||
:align right
|
||||
:width 20)))))
|
||||
))
|
||||
))
|
||||
;(grid-get-box `(:content ,(enlight-weather) :align center))
|
||||
)))
|
||||
|
||||
(setopt initial-buffer-choice #'enlight)
|
||||
|
||||
(provide 'dashboard)
|
||||
|
||||
;;; dashboard.el ends here
|
44
shared-packages.el
Normal file
44
shared-packages.el
Normal file
|
@ -0,0 +1,44 @@
|
|||
;;; shared-packages.el --- Shared library packages -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; We use this for displaying text a bit nicer in some buffers.
|
||||
(use-package grid
|
||||
:straight (grid :type git :host github :repo "ichernyshovvv/grid.el"))
|
||||
|
||||
;; This is used by nano
|
||||
(use-package mini-frame)
|
||||
|
||||
;; Hydro, used by Treemacs
|
||||
(use-package hydra)
|
||||
|
||||
;; All the icons
|
||||
(use-package all-the-icons
|
||||
:if (display-graphic-p))
|
||||
|
||||
;; Transient
|
||||
(use-package transient)
|
||||
|
||||
(provide 'shared-packages)
|
||||
|
||||
;;; shared-packages.el ends here
|
180
ui.el
Normal file
180
ui.el
Normal file
|
@ -0,0 +1,180 @@
|
|||
;;; ui.el --- UI components and packages -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Ouroboros themes
|
||||
(straight-use-package
|
||||
'(ouroboros-emacs-themes :type git
|
||||
:host nil
|
||||
:repo "https://git.cyan.sh/BirDt/ouroboros-emacs-themes.git"
|
||||
:files ("*.el")))
|
||||
|
||||
;; Nano for making emacs look more slim
|
||||
(straight-use-package
|
||||
'(nano :type git :host github :repo "rougier/nano-emacs"))
|
||||
|
||||
;; Add ouroboros-emacs-themes to the theme load path
|
||||
(add-to-list 'custom-theme-load-path
|
||||
(expand-file-name (concat "straight/" straight-build-dir "/ouroboros-emacs-themes/") user-emacs-directory))
|
||||
|
||||
;; We need this for other nano stuff
|
||||
(require 'nano-faces)
|
||||
|
||||
(require 'nano-modeline)
|
||||
|
||||
;; Default frame values - NOTE this is buggy when not launching emacsclient, but everyone should be using that anyway :)
|
||||
(setq default-frame-alist
|
||||
(append (list
|
||||
'(min-height . 1)
|
||||
'(height . 45)
|
||||
'(min-width . 1)
|
||||
'(width . 81)
|
||||
'(vertical-scroll-bars . nil)
|
||||
'(internal-border-width . 24)
|
||||
'(left-fringe . 1)
|
||||
'(right-fringe . 1)
|
||||
'(tool-bar-lines . 0)
|
||||
'(menu-bar-lines . 1))))
|
||||
|
||||
;; Smart line wrapping
|
||||
(global-visual-line-mode)
|
||||
|
||||
;; Minibuffer must shrink
|
||||
(setq resize-mini-windows nil
|
||||
max-mini-window-height 1)
|
||||
|
||||
;; Use y instead of yes, etc
|
||||
(if (>= emacs-major-version 29)
|
||||
(setopt use-short-answers t)
|
||||
(defalias 'yes-or-no-p 'y-or-n-p))
|
||||
|
||||
;; Display line numbers in programming modes
|
||||
(add-hook 'prog-mode-hook #'display-line-numbers-mode)
|
||||
|
||||
;; Hide toolbar
|
||||
(tool-bar-mode -1)
|
||||
|
||||
;; Don't show scrollbars
|
||||
(scroll-bar-mode -1)
|
||||
|
||||
;; Don't show menu bar
|
||||
(menu-bar-mode -1)
|
||||
|
||||
;; No tooltips
|
||||
(tooltip-mode -1)
|
||||
|
||||
;; No ugly button for checkboxes
|
||||
(setq widget-image-enable nil)
|
||||
|
||||
;; Don't pop up UI dialogs
|
||||
(setq use-dialog-box nil)
|
||||
|
||||
;; Tabs
|
||||
(when (< 26 emacs-major-version)
|
||||
(tab-bar-mode 1) ;; enable tab bar
|
||||
(global-unset-key (kbd "C-t"))
|
||||
(define-key global-map (kbd "C-t 2") 'tab-new)
|
||||
(define-key global-map (kbd "C-t 0") 'tab-close)
|
||||
(setq tab-bar-close-button-show nil) ;; hide tab close / X button
|
||||
(setq tab-bar-new-tab-choice "*enlight*");; buffer to show in new tabs
|
||||
(setq tab-bar-tab-hints t) ;; show tab numbers
|
||||
(setq tab-bar-format '(tab-bar-format-tabs tab-bar-separator))) ;; elements to include in bar
|
||||
|
||||
;; Hideshow
|
||||
(add-hook 'prog-mode-hook #'hs-minor-mode)
|
||||
|
||||
;; Custom text-scale function with default scale
|
||||
(defun set-default-text-scale (&optional default-scale)
|
||||
(interactive)
|
||||
(let ((default-scale (or default-scale 0)))
|
||||
(text-scale-set default-scale)))
|
||||
|
||||
;; Keybindings for text-scale
|
||||
(global-set-key (kbd "C-=") 'text-scale-increase)
|
||||
(global-set-key (kbd "C--") 'text-scale-decrease)
|
||||
(global-set-key (kbd "C-0") '(lambda () (interactive) (set-default-text-scale)))
|
||||
|
||||
;; Beacon to show the cursor
|
||||
(use-package beacon
|
||||
:config
|
||||
(beacon-mode 1)
|
||||
(setq beacon-color "#D5D5D5"))
|
||||
|
||||
;; Burly for frame layout saving
|
||||
(use-package burly)
|
||||
|
||||
;; Highlight to-do
|
||||
(use-package hl-todo
|
||||
:straight (hl-todo :type git :host github :repo "tarsius/hl-todo")
|
||||
:config (global-hl-todo-mode 1))
|
||||
|
||||
;; Completion
|
||||
(use-package corfu
|
||||
:init
|
||||
|
||||
;; Enable Corfu globally.
|
||||
(global-corfu-mode)
|
||||
|
||||
;; Popup info
|
||||
(corfu-popupinfo-mode)
|
||||
:custom
|
||||
(corfu-min-width 80)
|
||||
(corfu-max-width corfu-min-width)
|
||||
:config
|
||||
(setq corfu-auto t
|
||||
corfu-quit-no-match t
|
||||
corfu-auto-delay 0
|
||||
corfu-auto-prefix 0
|
||||
corfu-popupinfo-delay 0)
|
||||
|
||||
(add-hook 'corfu-mode-hook
|
||||
(lambda ()
|
||||
;; Settings only for Corfu
|
||||
(setq-local completion-styles '(basic)
|
||||
completion-category-overrides nil
|
||||
completion-category-defaults nil)))
|
||||
(keymap-set corfu-map "RET" `( menu-item "" nil :filter
|
||||
,(lambda (&optional _)
|
||||
(and (derived-mode-p 'eshell-mode 'comint-mode)
|
||||
#'corfu-send))))
|
||||
)
|
||||
|
||||
;; Icons in corfu
|
||||
(use-package kind-icon
|
||||
:after corfu
|
||||
:custom
|
||||
(kind-icon-use-icons t)
|
||||
(kind-icon-default-face 'corfu-default) ; Have background color be the same as `corfu' face background
|
||||
(kind-icon-blend-background nil) ; Use midpoint color between foreground and background colors ("blended")?
|
||||
(kind-icon-blend-frac 0.08)
|
||||
:config
|
||||
(add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter) ; Enable `kind-icon'
|
||||
)
|
||||
|
||||
;; Flycheck is here
|
||||
(use-package flycheck
|
||||
:hook ((after-init . global-flycheck-mode)))
|
||||
|
||||
(provide 'ui)
|
||||
|
||||
;;; ui.el ends here
|
58
userland/browser.el
Normal file
58
userland/browser.el
Normal file
|
@ -0,0 +1,58 @@
|
|||
;;; browser.el --- Web browser configuration and shortcuts -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defcustom theurgy-city
|
||||
"Perth"
|
||||
"The city used for fetching weather from wttr.in."
|
||||
:type 'string
|
||||
:group 'theurgy
|
||||
:group 'theurgy-weather)
|
||||
|
||||
(defun theurgy-eww-rename-buffer ()
|
||||
"Rename the eww buffer intelligently."
|
||||
(when (eq major-mode 'eww-mode)
|
||||
(let ((url (plist-get eww-data :url)))
|
||||
(cond
|
||||
((string-match-p "wttr.in" url) "*weather*")
|
||||
(t "*eww*")))))
|
||||
|
||||
(setq eww-auto-rename-buffer #'theurgy-eww-rename-buffer)
|
||||
|
||||
(defun theurgy-show-weather ()
|
||||
"Show wttr.in in an eww buffer."
|
||||
(interactive)
|
||||
(if (get-buffer "*weather*")
|
||||
(switch-to-buffer "*weather*")
|
||||
(eww (concat "wttr.in/" theurgy-city "?0"))))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*weather\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . left)
|
||||
(slot . 4)
|
||||
(window-width . 0.15)))
|
||||
|
||||
(provide 'browser)
|
||||
|
||||
;;; browser.el ends here
|
104
userland/dired-custom.el
Normal file
104
userland/dired-custom.el
Normal file
|
@ -0,0 +1,104 @@
|
|||
;;; dired-custom.el --- Custom dired config -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'dired)
|
||||
|
||||
(setq dired-listing-switches "-lh")
|
||||
(setq dired-recursive-deletes t)
|
||||
(setq dired-recursive-copies t)
|
||||
|
||||
(defun dired-init ()
|
||||
"Theurgy Dired config."
|
||||
;; Hide file permissions
|
||||
(dired-hide-details-mode 1)
|
||||
;; Kill new buffers
|
||||
(when (>= emacs-major-version 28)
|
||||
(setq dired-kill-when-opening-new-dired-buffer t))
|
||||
(when (< emacs-major-version 28)
|
||||
(progn
|
||||
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
|
||||
(define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file "..")))))
|
||||
;; Human readable file size
|
||||
(setq dired-listing-switches "-lh"))
|
||||
|
||||
(add-hook 'dired-mode-hook 'dired-init)
|
||||
(add-hook 'dired-mode-hook 'auto-revert-mode)
|
||||
|
||||
;; Icons in dired
|
||||
(use-package all-the-icons-dired
|
||||
:config
|
||||
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode))
|
||||
|
||||
;; Multimedia and PDF viewing
|
||||
(when (not (equal system-type 'windows-nt))
|
||||
(use-package ready-player
|
||||
:ensure t
|
||||
:config
|
||||
(setq ready-player-autoplay nil)
|
||||
(ready-player-mode 1))
|
||||
|
||||
(use-package pdf-tools
|
||||
:config (pdf-loader-install)))
|
||||
|
||||
|
||||
;; Preview files
|
||||
(defun dired-preview-to-the-right ()
|
||||
"My preferred `dired-preview-display-action-alist-function'."
|
||||
'((display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 0)
|
||||
(window-width . 0.3)))
|
||||
|
||||
(use-package dired-preview
|
||||
:after (ready-player)
|
||||
:config
|
||||
(setq dired-preview-display-action-alist #'dired-preview-to-the-right)
|
||||
(setq dired-preview-buffer-name-indicator "[Preview]")
|
||||
(setq dired-preview-ignored-extensions-regexp
|
||||
(concat "\\."
|
||||
"\\(gz\\|"
|
||||
"zst\\|"
|
||||
"tar\\|"
|
||||
"xz\\|"
|
||||
"rar\\|"
|
||||
"zip\\|"
|
||||
"iso\\|"
|
||||
"epub"
|
||||
"\\)"))
|
||||
(dired-preview-global-mode 1))
|
||||
|
||||
;; Automatically kill preview buffers when opening a file
|
||||
(add-hook 'find-file-hook (lambda ()
|
||||
(dolist (buf (buffer-list))
|
||||
(when (string-match-p "\\[Preview\\]" (buffer-name buf))
|
||||
(kill-buffer buf)))))
|
||||
|
||||
(use-package neotree
|
||||
:config
|
||||
(define-key global-map (kbd "<f8>") 'neotree-toggle)
|
||||
(setq neo-theme (if (display-graphic-p) 'icons 'arrow)))
|
||||
|
||||
(provide 'dired-custom)
|
||||
|
||||
;;; dired-custom.el ends here
|
104
userland/flycheck_dired-custom.el
Normal file
104
userland/flycheck_dired-custom.el
Normal file
|
@ -0,0 +1,104 @@
|
|||
;;; dired-custom.el --- Custom dired config -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'dired)
|
||||
|
||||
(setq dired-listing-switches "-lh")
|
||||
(setq dired-recursive-deletes t)
|
||||
(setq dired-recursive-copies t)
|
||||
|
||||
(defun dired-init ()
|
||||
"Theurgy Dired config."
|
||||
;; Hide file permissions
|
||||
(dired-hide-details-mode 1)
|
||||
;; Kill new buffers
|
||||
(when (>= emacs-major-version 28)
|
||||
(setq dired-kill-when-opening-new-dired-buffer t))
|
||||
(when (< emacs-major-version 28)
|
||||
(progn
|
||||
(define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)
|
||||
(define-key dired-mode-map (kbd "^") (lambda () (interactive) (find-alternate-file "..")))))
|
||||
;; Human readable file size
|
||||
(setq dired-listing-switches "-lh"))
|
||||
|
||||
(add-hook 'dired-mode-hook 'dired-init)
|
||||
(add-hook 'dired-mode-hook 'auto-revert-mode)
|
||||
|
||||
;; Icons in dired
|
||||
(use-package all-the-icons-dired
|
||||
:config
|
||||
(add-hook 'dired-mode-hook 'all-the-icons-dired-mode))
|
||||
|
||||
;; Multimedia and PDF viewing
|
||||
(when (not (equal system-type 'windows-nt))
|
||||
(use-package ready-player
|
||||
:ensure t
|
||||
:config
|
||||
(setq ready-player-autoplay nil)
|
||||
(ready-player-mode 1))
|
||||
|
||||
(use-package pdf-tools
|
||||
:config (pdf-loader-install)))
|
||||
|
||||
|
||||
;; Preview files
|
||||
(defun dired-preview-to-the-right ()
|
||||
"My preferred `dired-preview-display-action-alist-function'."
|
||||
'((display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 0)
|
||||
(window-width . 0.3)))
|
||||
|
||||
(use-package dired-preview
|
||||
:after (ready-player)
|
||||
:config
|
||||
(setq dired-preview-display-action-alist #'dired-preview-to-the-right)
|
||||
(setq dired-preview-buffer-name-indicator "[Preview]")
|
||||
(setq dired-preview-ignored-extensions-regexp
|
||||
(concat "\\."
|
||||
"\\(gz\\|"
|
||||
"zst\\|"
|
||||
"tar\\|"
|
||||
"xz\\|"
|
||||
"rar\\|"
|
||||
"zip\\|"
|
||||
"iso\\|"
|
||||
"epub"
|
||||
"\\)"))
|
||||
(dired-preview-global-mode 1))
|
||||
|
||||
;; Automatically kill preview buffers when opening a file
|
||||
(add-hook 'find-file-hook (lambda ()
|
||||
(dolist (buf (buffer-list))
|
||||
(when (string-match-p "\\[Preview\\]" (buffer-name buf))
|
||||
(kill-buffer buf)))))
|
||||
|
||||
(use-package neotree
|
||||
:config
|
||||
(define-key global-map (kbd "<f8>") 'neotree-toggle)
|
||||
(setq neo-theme (if (display-graphic-p) 'icons 'arrow)))
|
||||
|
||||
(provide 'dired-custom)
|
||||
|
||||
;;; dired-custom.el ends here
|
40
userland/git-interace.el
Normal file
40
userland/git-interace.el
Normal file
|
@ -0,0 +1,40 @@
|
|||
;;; git-interface.el --- Magit config -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(use-package magit)
|
||||
|
||||
(use-package magit-todos
|
||||
:after (magit)
|
||||
:config (magit-todos-mode 1))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("magit:"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 4)
|
||||
(window-width . 0.2)))
|
||||
|
||||
(provide 'git-interface)
|
||||
|
||||
;;; git-interface.el ends here
|
69
userland/rss.el
Normal file
69
userland/rss.el
Normal file
|
@ -0,0 +1,69 @@
|
|||
;;; rss.el --- RSS feed reading via elfeed -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Elfeed and aggregation setup
|
||||
(use-package elfeed
|
||||
:config
|
||||
(setq elfeed-feeds
|
||||
'(;; Planet aggregators
|
||||
("https://planet.emacslife.com/atom.xml" planet emacs))))
|
||||
|
||||
;; This fixes a bug
|
||||
(define-advice elfeed-search--header (:around (oldfun &rest args))
|
||||
(if elfeed-db
|
||||
(apply oldfun args)
|
||||
"No database loaded yet"))
|
||||
|
||||
;; Display the elfeed entry buffer in the main window
|
||||
(setq elfeed-show-entry-switch #'elfeed-display-buffer)
|
||||
|
||||
(defun elfeed-display-buffer (buf &optional act)
|
||||
(pop-to-buffer buf)
|
||||
(delete-other-main-windows))
|
||||
|
||||
;; Navigate elfeed entry from the search window
|
||||
(defun elfeed-search-show-entry-pre (&optional lines)
|
||||
"Returns a function to scroll forward or back in the Elfeed
|
||||
search results, displaying entries without switching to them."
|
||||
(lambda (times)
|
||||
(interactive "p")
|
||||
(forward-line (* times (or lines 0)))
|
||||
(recenter)
|
||||
(call-interactively #'elfeed-search-show-entry)
|
||||
(select-window (previous-window))
|
||||
(unless elfeed-search-remain-on-entry (forward-line -1))))
|
||||
|
||||
(define-key elfeed-search-mode-map (kbd "n") (elfeed-search-show-entry-pre +1))
|
||||
(define-key elfeed-search-mode-map (kbd "p") (elfeed-search-show-entry-pre -1))
|
||||
(define-key elfeed-search-mode-map (kbd "M-RET") (elfeed-search-show-entry-pre))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*elfeed-search\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . top)
|
||||
(slot . 0)))
|
||||
|
||||
(provide 'rss)
|
||||
|
||||
;;; rss.el ends here
|
88
userland/scratch.el
Normal file
88
userland/scratch.el
Normal file
|
@ -0,0 +1,88 @@
|
|||
;;; scratch.el --- Custom scratchpads -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; We have our own scratch buffers, don't need this
|
||||
(add-hook 'emacs-startup-hook (lambda ()
|
||||
(when (get-buffer "*scratch*")
|
||||
(kill-buffer "*scratch*"))))
|
||||
|
||||
(defcustom elisp-scratch-initial-contents
|
||||
";; Emacs lisp scratch buffer\n\n"
|
||||
"Initial text for *elisp scratch*."
|
||||
:type 'string
|
||||
:group 'theurgy
|
||||
:group 'theurgy-scratch)
|
||||
|
||||
(defcustom org-scratch-initial-contents
|
||||
"# Org scratch buffer\n\n"
|
||||
"Initial text for *org scratch*."
|
||||
:type 'string
|
||||
:group 'theurgy
|
||||
:group 'theurgy-scratch)
|
||||
|
||||
(with-current-buffer (generate-new-buffer "*elisp scratch*")
|
||||
(insert elisp-scratch-initial-contents)
|
||||
(emacs-lisp-mode))
|
||||
|
||||
(with-current-buffer (generate-new-buffer "*org scratch*")
|
||||
(insert org-scratch-initial-contents)
|
||||
(org-mode))
|
||||
|
||||
(defun open-elisp-scratch ()
|
||||
(interactive)
|
||||
(switch-to-buffer "*elisp scratch*"))
|
||||
|
||||
(defun open-org-scratch ()
|
||||
(interactive)
|
||||
(switch-to-buffer "*org scratch*"))
|
||||
|
||||
(defun toggle-elisp-scratch ()
|
||||
(interactive)
|
||||
(if (get-buffer-window "*elisp scratch*")
|
||||
(delete-window (get-buffer-window "*elisp scratch*"))
|
||||
(switch-to-buffer "*elisp scratch*")))
|
||||
|
||||
(defun toggle-org-scratch ()
|
||||
(interactive)
|
||||
(if (get-buffer-window "*org scratch*")
|
||||
(delete-window (get-buffer-window "org scratch"))
|
||||
(switch-to-buffer "*org scratch*")))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*elisp scratch\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 1)
|
||||
(window-width . 0.2)))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*org scratch\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 2)
|
||||
(window-width . 0.2)))
|
||||
|
||||
(provide 'scratch)
|
||||
|
||||
;;; scratch.el ends here
|
54
userland/terminal.el
Normal file
54
userland/terminal.el
Normal file
|
@ -0,0 +1,54 @@
|
|||
;;; terminal.el --- Userland terminal with vterm -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(when (not (equal system-type 'windows-nt))
|
||||
(use-package vterm
|
||||
:ensure t))
|
||||
|
||||
(defun theurgy-shell ()
|
||||
(interactive)
|
||||
(if (fboundp 'vterm)
|
||||
'vterm
|
||||
'shell))
|
||||
|
||||
(defun theurgy-bottom-shell ()
|
||||
(interactive)
|
||||
(let ((win (car (window-at-side-list nil 'bottom))))
|
||||
(if (and win (equal 'bottom (window-parameter win 'window-side)))
|
||||
(delete-window win)
|
||||
(funcall (theurgy-shell)))))
|
||||
|
||||
(global-set-key (kbd "M-RET") 'theurgy-bottom-shell)
|
||||
(define-key vterm-mode-map (kbd "M-RET") 'theurgy-bottom-shell)
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*vterm\\*\\|\\*shell\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . bottom)
|
||||
(slot . 0)
|
||||
(window-height . 0.2)))
|
||||
|
||||
(provide 'terminal)
|
||||
|
||||
;;; terminal.el ends here
|
51
window-utils.el
Normal file
51
window-utils.el
Normal file
|
@ -0,0 +1,51 @@
|
|||
;;; window-utils.el --- Utility functions and config for window management -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(setq switch-to-buffer-obey-display-actions t)
|
||||
|
||||
(defun delete-other-main-windows ()
|
||||
"Kill all windows except for side windows."
|
||||
(interactive)
|
||||
(dolist (win (window-list))
|
||||
(when (and (not (equal (selected-window) win))
|
||||
(not (window-parameter win 'window-side)))
|
||||
(delete-window win))))
|
||||
|
||||
(define-key global-map (kbd "C-x 1") #'delete-other-main-windows)
|
||||
|
||||
(define-key global-map (kbd "C-S-x 1") #'delete-other-windows)
|
||||
|
||||
;; left, top, right, bottom
|
||||
(setq window-sides-slots '(5 1 5 1))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*Help\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 4)
|
||||
(window-height . 0.2)))
|
||||
|
||||
(provide 'window-utils)
|
||||
|
||||
;;; window-utils.el ends here
|
698
workflows/flycheck_org-custom.el
Normal file
698
workflows/flycheck_org-custom.el
Normal file
|
@ -0,0 +1,698 @@
|
|||
;;; org-custom.el --- Org-mode configuration -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'org)
|
||||
(require 'org-agenda)
|
||||
(require 'org-attach)
|
||||
(require 'transient)
|
||||
(require 'subr-x)
|
||||
|
||||
(defun org-mode-init ()
|
||||
"This is called through `org-mode-hook', so that I don't need to `add-hook' 20 million times."
|
||||
;; I want org to display pictures inline.
|
||||
(org-display-inline-images)
|
||||
;; I don't want monospace text by default.
|
||||
(variable-pitch-mode)
|
||||
)
|
||||
|
||||
(add-hook 'org-mode-hook #'org-mode-init)
|
||||
|
||||
(defcustom theurgy-org-directory "~/.org/"
|
||||
"The directory for all theurgy org-mode files."
|
||||
:type 'string
|
||||
:group 'theurgy
|
||||
:group 'theurgy-org)
|
||||
|
||||
;; Change a bunch of default org-mode variables.
|
||||
(setq org-log-done nil ;; I want to keep track of the time tasks are completed.
|
||||
org-return-follows-link t ;; I want to be able to follow links easily.
|
||||
org-hide-emphasis-markers t ;; This is a big one: hide markup syntax like ** and //.
|
||||
org-pretty-entities t ;; These two variables together render latex entities as UTF8, which means that Greek letters, subscript, and superscript are all rendered correctly.
|
||||
org-pretty-entities-include-sub-superscripts t
|
||||
org-enforce-todo-dependencies t ;; Prevent changing a parent to DONE if the children aren't
|
||||
org-enforce-todo-checkbox-dependencies t
|
||||
org-agenda-skip-scheduled-if-done t ;; Don't show done stuff in the agenda view
|
||||
org-agenda-skip-deadline-if-done t
|
||||
org-agenda-skip-timestamp-if-done t
|
||||
|
||||
org-todo-keywords '((sequence "TODO(t)" "WIP(w)" "DELEGATED(p)" "WAITING(?)" "|" "CANCELLED(x)" "DONE(d)")) ;; Some extra keywords in addition to TODO and DONE
|
||||
org-use-fast-todo-selection t ;; Always use fast selection
|
||||
org-refile-targets '((org-agenda-files :maxlevel . 2)) ;; Allow any agenda files to be refile targets.
|
||||
|
||||
org-agenda-files (append (apply 'append (mapcar
|
||||
(lambda (dir)
|
||||
(directory-files-recursively dir org-agenda-file-regexp))
|
||||
`(,(concat theurgy-org-directory "tasks"))))
|
||||
`(,(concat theurgy-org-directory "inbox.org"))) ;; Agenda files location - gathered recursively
|
||||
org-cite-global-bibliography `(,(concat theurgy-org-directory "global.bib")) ;; Global bibliography location
|
||||
|
||||
org-startup-indented t ;; Start indented - this fixed org-indent mode
|
||||
|
||||
org-attach-id-dir (concat theurgy-org-directory "lore/assets")
|
||||
|
||||
org-M-RET-may-split-line '((item . nil)) ;; https://irreal.org/blog/?p=6297
|
||||
)
|
||||
|
||||
;; Org modern and other interface enhancements
|
||||
(use-package org-modern
|
||||
:hook ((org-mode . org-modern-mode)
|
||||
(org-agenda-finalize . org-modern-agenda)))
|
||||
|
||||
(use-package org-modern-indent
|
||||
:straight (org-modern-indent :type git :host github :repo "jdtsmith/org-modern-indent")
|
||||
:hook ((org-mode . org-modern-indent-mode)))
|
||||
|
||||
(use-package wc-mode
|
||||
:hook ((org-mode . wc-mode))
|
||||
:config (setq wc-modeline-format "WC[%tw]"))
|
||||
|
||||
(use-package org-appear :ensure t
|
||||
:init
|
||||
(setq org-appear-delay 0.2)
|
||||
:hook
|
||||
org-mode)
|
||||
|
||||
;; Side tree
|
||||
(use-package org-side-tree
|
||||
:hook ((org-modern-mode . org-side-tree)))
|
||||
|
||||
;; Advice to display org-side-tree where we want it
|
||||
(defun theurgy-org-side-tree ()
|
||||
"Create or pop to Org-Side-Tree buffer."
|
||||
(interactive)
|
||||
(when (org-side-tree-buffer-p)
|
||||
(error "Don't tree a tree"))
|
||||
(unless (or (derived-mode-p 'org-mode)
|
||||
(derived-mode-p 'outline-mode)
|
||||
outline-minor-mode)
|
||||
(error "Not an outline buffer"))
|
||||
(let* ((tree-name (if (default-value 'org-side-tree-persistent)
|
||||
"*Org-Side-Tree*"
|
||||
(format "<tree>%s" (buffer-name))))
|
||||
(tree-buffer (get-buffer tree-name))
|
||||
(heading (org-side-tree-heading-number))
|
||||
(dd default-directory)
|
||||
(inv-spec buffer-invisibility-spec))
|
||||
(unless (buffer-live-p tree-buffer)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(jit-lock-mode 1)
|
||||
(jit-lock-fontify-now))
|
||||
(setq tree-buffer (generate-new-buffer tree-name))
|
||||
(add-hook 'kill-buffer-hook #'org-side-tree-cleanup nil t)
|
||||
(let* ((headings (org-side-tree-get-headings))
|
||||
(tree-head-line (or (cadar (org-collect-keywords
|
||||
'("title")))
|
||||
"Org-Side-Tree"))
|
||||
(tree-mode-line (format "Org-Side-Tree - %s"
|
||||
(buffer-name))))
|
||||
(when (default-value 'org-side-tree-enable-folding)
|
||||
(setq-local org-side-tree-enable-folding t))
|
||||
(with-current-buffer tree-buffer
|
||||
(setq-local default-directory dd)
|
||||
(org-side-tree-mode)
|
||||
(setq tabulated-list-entries headings)
|
||||
(tabulated-list-print t t)
|
||||
(when (default-value 'org-side-tree-enable-folding)
|
||||
(setq-local org-side-tree-enable-folding t)
|
||||
;; preserve org font-locking
|
||||
(setq-local outline-minor-mode-highlight nil)
|
||||
(outline-minor-mode 1))
|
||||
(setq buffer-invisibility-spec inv-spec)
|
||||
(setq header-line-format tree-head-line)
|
||||
(setq mode-line-format tree-mode-line))))
|
||||
(org-side-tree-set-timer)
|
||||
(switch-to-buffer (buffer-name))
|
||||
(display-buffer-in-side-window
|
||||
tree-buffer
|
||||
`((side . ,org-side-tree-display-side)
|
||||
(slot . 1)
|
||||
(window-width . ,org-side-tree-width)))
|
||||
(when (default-value 'org-side-tree-persistent)
|
||||
(setq-local org-side-tree-persistent
|
||||
(buffer-name))
|
||||
(org-side-tree-update))
|
||||
(when org-side-tree-select
|
||||
(pop-to-buffer tree-buffer))
|
||||
(setq window-size-fixed (when org-side-tree-width 'width))
|
||||
(pulse-momentary-highlight-one-line)
|
||||
(org-side-tree-go-to-heading heading)))
|
||||
|
||||
(advice-add 'org-side-tree :override #'theur)
|
||||
|
||||
;; Helper functions for the side tree
|
||||
(defun theurgy-toggle-org-side-tree ()
|
||||
(interactive)
|
||||
(if (get-buffer-window (concat "<tree>" (file-name-nondirectory (buffer-file-name))))
|
||||
(delete-window (get-buffer-window (concat "<tree>" (file-name-nondirectory (buffer-file-name)))))
|
||||
(org-side-tree)))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("<tree>.+\.org"
|
||||
(display-buffer-in-side-window)
|
||||
(side . left)
|
||||
(slot . 1)
|
||||
(window-height . 0.2)))
|
||||
|
||||
(define-key org-mode-map (kbd "C-<f8>") #'theurgy-toggle-org-side-tree)
|
||||
|
||||
;; https://chrismaiorana.com/summer-productivity-reset-emacs-functions/
|
||||
(defun csm/replace-punctuation-at-point ()
|
||||
"Replace punctuation at point (., !, ?) with the character typed by the user."
|
||||
(interactive)
|
||||
(let ((char (this-command-keys))) ;; Get the key pressed by the user
|
||||
(if (and (member (char-after) '(?. ?! ?? ?,)) ;; Check if current char is ., !, or ?
|
||||
(member (string-to-char char) '(?. ?! ??))) ;; Check if typed char is ., !, or ?
|
||||
(progn
|
||||
(delete-char 1) ;; Delete existing punctuation
|
||||
(insert char)) ;; Insert new punctuation
|
||||
(self-insert-command 1)))) ;; Default behavior: insert character
|
||||
|
||||
;; Bind this function to punctuation keys
|
||||
(define-key global-map "." 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "," 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "!" 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "?" 'csm/replace-punctuation-at-point)
|
||||
|
||||
;; Windmove bindings since org overwrites them otherwise
|
||||
(define-key org-mode-map (kbd "C-c <left>") 'windmove-left)
|
||||
(define-key org-mode-map (kbd "C-c <right>") 'windmove-right)
|
||||
(define-key org-mode-map (kbd "C-c <up>") 'windmove-up)
|
||||
(define-key org-mode-map (kbd "C-c <down>") 'windmove-down)
|
||||
|
||||
;; Same with scrolling
|
||||
(define-key org-mode-map (kbd "C-S-<down>") '(lambda () (interactive) (scroll-up-line 10)))
|
||||
(define-key org-mode-map (kbd "C-S-<up>") '(lambda () (interactive) (scroll-down-line 10)))
|
||||
|
||||
;; Sentence and word navigation and marking
|
||||
(setq sentence-end-double-space nil) ;; Otherwise, M-e is broken in normal writing.
|
||||
|
||||
;;; Generally useful things
|
||||
;; Mark word and sentence
|
||||
(defun mark-whole-word ()
|
||||
"Mark the whole word underneath the cursor."
|
||||
(interactive)
|
||||
(forward-word)
|
||||
(set-mark-command nil)
|
||||
(backward-word))
|
||||
|
||||
(defun mark-sentence ()
|
||||
"Mark the entire sentence underneath the cursor."
|
||||
(interactive)
|
||||
(forward-sentence)
|
||||
(set-mark-command nil)
|
||||
(backward-sentence))
|
||||
|
||||
(define-key org-mode-map (kbd "C-@") #'mark-whole-word)
|
||||
(define-key org-mode-map (kbd "M-@") #'mark-sentence)
|
||||
|
||||
(transient-define-prefix mark-menu-transient ()
|
||||
"Transient menu for marking units of text."
|
||||
["Mark" ("w" "Word" mark-whole-word)
|
||||
("s" "Sentence" mark-sentence)
|
||||
("p" "Paragraph" mark-paragraph)
|
||||
("b" "Buffer" mark-whole-buffer)])
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o SPC") #'mark-menu-transient)
|
||||
|
||||
;; Section navigation and reordering
|
||||
(defun move-sentence-right (&optional arg)
|
||||
"Move the whole sentence to the right of the next sentence, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(kill-sentence)
|
||||
(forward-sentence)
|
||||
(yank)
|
||||
(backward-sentence)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-sentence-left (&optional arg)
|
||||
"Move the whole sentence to the left of the previous sentence, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(kill-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(yank)
|
||||
(backward-sentence)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-paragraph-up (&optional arg)
|
||||
"Move the whole paragraph above the previous paragraph, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-paragraph)
|
||||
(backward-paragraph)
|
||||
(kill-paragraph nil)
|
||||
(backward-paragraph)
|
||||
(yank)
|
||||
(backward-paragraph)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-paragraph-down (&optional arg)
|
||||
"Move the whole paragraph above the previous paragraph, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-paragraph)
|
||||
(backward-paragraph)
|
||||
(kill-paragraph nil)
|
||||
(forward-paragraph)
|
||||
(yank)
|
||||
(backward-paragraph)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(define-key org-mode-map (kbd "C-M-<left>") #'move-sentence-left)
|
||||
(define-key org-mode-map (kbd "C-M-<right>") #'move-sentence-right)
|
||||
(define-key org-mode-map (kbd "C-M-<up>") #'move-paragraph-up)
|
||||
(define-key org-mode-map (kbd "C-M-<down>") #'move-paragraph-down)
|
||||
|
||||
(transient-define-prefix reorder-transient ()
|
||||
"Transient menu for text re-ordering commands."
|
||||
["Move sentence..." ("l" "Left" move-sentence-left)
|
||||
("r" "Right" move-sentence-right)]
|
||||
["Move paragraph..." ("u" "Up" move-paragraph-up)
|
||||
("d" "Down" move-paragraph-down)])
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o r") #'reorder-transient)
|
||||
|
||||
;; Focused rewriting
|
||||
(defun break-out-sentence ()
|
||||
"Breaks a sentence out into it's own buffer for editing."
|
||||
(interactive)
|
||||
(backward-sentence)
|
||||
(kill-sentence)
|
||||
(switch-to-buffer-other-window "*break-out*")
|
||||
(erase-buffer)
|
||||
(yank))
|
||||
|
||||
(defun break-out-choose-sentence ()
|
||||
"Chooses a sentence from the break-out buffer."
|
||||
(interactive)
|
||||
(backward-sentence)
|
||||
(kill-sentence)
|
||||
(other-window -1)
|
||||
(kill-buffer "*break-out*")
|
||||
(yank))
|
||||
|
||||
(defun break-out-dwim ()
|
||||
"Either break-out or choose sentency depending on buffer name."
|
||||
(interactive)
|
||||
(if (equal (buffer-name) "*break-out*")
|
||||
(break-out-choose-sentence)
|
||||
(break-out-sentence)))
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o b") #'break-out-dwim)
|
||||
|
||||
;; Powerthesaurus
|
||||
(use-package powerthesaurus
|
||||
:bind ("C-x t" . powerthesaurus-transient))
|
||||
|
||||
;; Harper
|
||||
(when (and (not (equal system-type 'windows-nt)) (locate-file "harper-ls" exec-path))
|
||||
(with-eval-after-load 'eglot
|
||||
(add-to-list 'eglot-server-programs
|
||||
'(org-mode . ("harper-ls" "--stdio"))))
|
||||
|
||||
(setq-default eglot-workspace-configuration
|
||||
'(:harper-ls (:dialect "Australian")))
|
||||
|
||||
(add-hook 'org-mode-hook 'eglot-ensure))
|
||||
|
||||
;;; Exobrain
|
||||
;;; Task management
|
||||
;; Maintenance and project file creation shortcuts
|
||||
(defun new-maintenance-file (maintenance-area)
|
||||
"Create a new maintenance file for a given `MAINTENANCE-AREA'."
|
||||
(interactive "sMaintenance area is: ")
|
||||
(find-file (concat "~/.org/tasks/maintenance/" maintenance-area ".org"))
|
||||
(insert "\n\n* Calendar\n\n* TO-DO\n\n* Routines\n\n* Archive\n")
|
||||
(goto-char (point-min)))
|
||||
|
||||
(defun new-project-file (project-name acceptance-criteria)
|
||||
"Create a new project file for a given `PROJECT-NAME', with some `ACCEPTANCE-CRITERIA'."
|
||||
(find-file (concat "~/.org/tasks/projects/" project-name ".org"))
|
||||
(insert (concat "\n\n* Acceptance Criteria\n\n" acceptance-criteria "\n\n* Ideas\n\n* TODO Work\n\n** Calendar\n\n** TO-DO\n\n** Routines\n\n** Archive\n"))
|
||||
(goto-char (point-min)))
|
||||
|
||||
(defun new-generic-project (project-name acceptance-criteria)
|
||||
"Interactive wrapper for `new-project-file', for generic projects."
|
||||
(interactive "sProject name is: \nsAcceptance criteria is: ")
|
||||
(new-project-file project-name acceptance-criteria))
|
||||
|
||||
(defun new-career-project (project-name acceptance-criteria)
|
||||
"Interactive wrapper for `new-project-file', for career projects."
|
||||
(interactive "sProject name is: \nsAcceptance criteria is: ")
|
||||
(new-project-file (concat "career/" project-name) acceptance-criteria))
|
||||
|
||||
;; Captures
|
||||
(defun select-task-area (location headline)
|
||||
"Prompt for a file in ~/.org/tasks/maintenance/ to insert the capture."
|
||||
(let* ((files (directory-files (concat "~/.org/tasks/" location) t "\\.org$"))
|
||||
(choices (mapcar
|
||||
(lambda (x) (string-remove-suffix ".org" x))
|
||||
(mapcar #'file-name-nondirectory files)))
|
||||
(selected (completing-read "Choose a file: " choices nil t)))
|
||||
(set-buffer (org-capture-target-buffer (concat "~/.org/tasks/" location selected ".org")))
|
||||
(org-capture-put-target-region-and-position)
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(setq headline (org-capture-expand-headline headline))
|
||||
(re-search-forward (format org-complex-heading-regexp-format
|
||||
(regexp-quote headline))
|
||||
nil t)
|
||||
(forward-line 0)))
|
||||
|
||||
(defun select-maintenance-area (headline)
|
||||
(select-task-area "maintenance/" headline))
|
||||
|
||||
(defun select-project (headline)
|
||||
(select-task-area "projects/" headline))
|
||||
|
||||
(defun select-career-project (headline)
|
||||
(select-task-area "projects/career/" headline))
|
||||
|
||||
(setq org-capture-templates
|
||||
'(("i" "Idea")
|
||||
("ii" "Generic" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :idea: \n\n%?"
|
||||
:empty-lines 1)
|
||||
("ip" "Project" entry
|
||||
(function (lambda () (select-project "Ideas")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1)
|
||||
("ic" "Career" entry
|
||||
(function (lambda () (select-career-project "Ideas")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1)
|
||||
|
||||
("t" "Task")
|
||||
("tt" "Generic")
|
||||
("ttt" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} :task:\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttm" "Maintenance" entry
|
||||
(function (lambda () (select-maintenance-area "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttp" "Project" entry
|
||||
(function (lambda () (select-project "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttc" "Career" entry
|
||||
(function (lambda () (select-career-project "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ts" "Scheduled")
|
||||
("tss" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} :scheduled:\n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsm" "Maintenance" entry
|
||||
(function (lambda () (select-maintenance-area "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsp" "Project" entry
|
||||
(function (lambda () (select-project "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsc" "Career" entry
|
||||
(function (lambda () (select-career-project "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
|
||||
("n" "Note")
|
||||
("nn" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :note: \n\n%?"
|
||||
:empty-lines 1)
|
||||
("nm" "Meeting")
|
||||
("nmm" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :meeting: \n\n%?"
|
||||
:clock-in t
|
||||
:clock-resume t)
|
||||
("nmc" "Career" entry
|
||||
(function (lambda () (select-career-project "Calendar")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1
|
||||
:clock-in t
|
||||
:clock-resume t)))
|
||||
|
||||
(defun open-inbox ()
|
||||
"Opens `~/.org/inbox.org'"
|
||||
(interactive)
|
||||
(find-file "~/.org/inbox.org"))
|
||||
|
||||
(defun open-maintenance ()
|
||||
"Opens `~/.org/tasks/maintenance/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/maintenance/"))
|
||||
|
||||
(defun open-projects ()
|
||||
"Opens `~/.org/tasks/projects/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/projects/"))
|
||||
|
||||
(defun open-career ()
|
||||
"Opens `~/.org/tasks/projects/career/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/projects/career/"))
|
||||
|
||||
(transient-define-prefix task-management-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Go To" ("i" "Inbox" open-inbox)
|
||||
("m" "Maintenance Directory" open-maintenance)
|
||||
("p" "Projects Directory" open-projects)
|
||||
("c" "Career Directory" open-career)]
|
||||
["Create New" ("M" "Maintenance File" new-maintenance-file)
|
||||
("P" "Project" new-generic-project)
|
||||
("C" "Career Project" new-career-project)])
|
||||
|
||||
(define-key global-map (kbd "C-c o t") #'task-management-menu)
|
||||
(define-key global-map (kbd "C-c a") #'org-agenda)
|
||||
(define-key global-map (kbd "C-c c") #'org-capture)
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*Org Agenda\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 3)
|
||||
(window-width . 0.2)))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*capture\\*\\|CAPTURE-"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 2)
|
||||
(window-width . 0.2)))
|
||||
|
||||
;; Org roam
|
||||
(use-package org-roam
|
||||
:straight nil
|
||||
:ensure t
|
||||
:init
|
||||
(setq org-roam-v2-ack t)
|
||||
:custom
|
||||
(org-roam-directory (file-truename "~/.org/lore/"))
|
||||
(org-roam-dailies-directory (file-truename "~/.org/lore/refined/journal/"))
|
||||
(org-roam-file-exclude-regexp "\\.git/.*\\|logseq/.*$")
|
||||
(org-roam-completion-everywhere)
|
||||
(org-roam-capture-templates
|
||||
'(("r" "Raw")
|
||||
("rr" "Note" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title}\n")
|
||||
:unnarrowed t)
|
||||
("rq" "Question" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title}\n#+filetags: :question:")
|
||||
:unnarrowed t)
|
||||
("i" "Index" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title} - Index\n#+filetags: :index:")
|
||||
:unnarrowed t)
|
||||
("R" "Refined")
|
||||
("Rm" "Mini-essay" plain
|
||||
"%?"
|
||||
:target (file+head "refined/wiki/${slug}.org" "#+title: ${title}\n#+author: Jakub Nowak\n#+filetags: :mini-essay:")
|
||||
:unnarrowed t)
|
||||
("Re" "Essay" plain
|
||||
"%?"
|
||||
:target (file+head "refined/wiki/${slug}.org" "#+title: ${title}\n#+author: Jakub Nowak\n#+filetags: :essay:")
|
||||
:unnarrowed t)))
|
||||
(org-roam-dailies-capture-templates
|
||||
'(("d" "default" entry
|
||||
"* %?"
|
||||
:target (file+head "%<%Y-%m-%d>.org" ;; format matches Logseq
|
||||
"#+title: %<%Y-%m-%d>\n"))))
|
||||
:bind (("C-c n l" . org-roam-buffer-toggle)
|
||||
("C-c n f" . org-roam-node-find)
|
||||
("C-c n g" . org-roam-graph)
|
||||
("C-c n i" . org-roam-node-insert)
|
||||
("C-c n c" . org-roam-capture)
|
||||
:map org-roam-dailies-map
|
||||
("Y" . org-roam-dailies-capture-yesterday)
|
||||
("T" . org-roam-dailies-capture-tomorrow))
|
||||
:bind-keymap ("C-c n d" . org-roam-dailies-map)
|
||||
:config
|
||||
(require 'org-roam-dailies) ;; Ensure the keymap is available
|
||||
(org-roam-db-autosync-mode))
|
||||
|
||||
(defun org-roam-create-node-from-headline ()
|
||||
"Create an Org-roam note from the current headline and jump to it.
|
||||
|
||||
Normally, insert the headline’s title using the ’#title:’ file-level property
|
||||
and delete the Org-mode headline. However, if the current headline has a
|
||||
Org-mode properties drawer already, keep the headline and don’t insert
|
||||
‘#+title:'. Org-roam can extract the title from both kinds of notes, but using
|
||||
‘#+title:’ is a bit cleaner for a short note, which Org-roam encourages."
|
||||
(interactive)
|
||||
(let ((title (nth 4 (org-heading-components)))
|
||||
(has-properties (org-get-property-block)))
|
||||
(org-cut-subtree)
|
||||
(org-roam-find-file title nil nil 'no-confirm)
|
||||
(org-paste-subtree)
|
||||
(unless has-properties
|
||||
(kill-line)
|
||||
(while (outline-next-heading)
|
||||
(org-promote)))
|
||||
(goto-char (point-min))
|
||||
(when has-properties
|
||||
(kill-line)
|
||||
(kill-line))))
|
||||
|
||||
(use-package logseq-org-roam
|
||||
:straight (:host github
|
||||
:repo "sbougerel/logseq-org-roam"
|
||||
:files ("*.el")))
|
||||
|
||||
(transient-define-prefix org-roam-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Node" ("c" "Capture" org-roam-node-find)
|
||||
("i" "Insert" org-roam-node-insert)
|
||||
("r" "Refile" org-roam-create-node-from-headline)
|
||||
("f" "Find" org-roam-node-find) ]
|
||||
["Dailies" ("t" "Today" org-roam-dailies-capture-today)
|
||||
("y" "Yesterday" org-roam-dailies-capture-yesterday)
|
||||
("n" "Tomorrow" org-roam-dailies-capture-tomorrow)]
|
||||
["Logseq" ("R" "Fix links" logseq-org-roam)]
|
||||
["Org Roam UI" ("U" "Enable org-roam-ui-mode" org-roam-ui-mode)])
|
||||
|
||||
(define-key global-map (kbd "C-c o n") #'org-roam-menu)
|
||||
|
||||
(use-package org-roam-ui
|
||||
:straight
|
||||
(:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
|
||||
:after 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)
|
||||
: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))
|
||||
|
||||
;; Bibliography stuff
|
||||
(setq bibtex-dialect 'biblatex) ;; Use biblatex instead of bibtex.
|
||||
|
||||
(use-package biblio)
|
||||
|
||||
(defun bibtex-online-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Online"))
|
||||
|
||||
(defun bibtex-misc-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Misc"))
|
||||
|
||||
(defun bibtex-software-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Software"))
|
||||
|
||||
(transient-define-prefix bibtex-transient-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Biblio" ("d" "doi.org" doi-insert-bibtex)
|
||||
("x" "arXiv" arxiv-lookup)]
|
||||
["Templates" ("o" "Online Resource" bibtex-online-entry)
|
||||
("m" "Misc" bibtex-misc-entry)
|
||||
("s" "Software" bibtex-software-entry)])
|
||||
|
||||
(define-key bibtex-mode-map (kbd "C-c r") #'bibtex-transient-menu)
|
||||
|
||||
;;; Literate Programming
|
||||
;; Racket
|
||||
(use-package ob-racket
|
||||
:after org
|
||||
:config
|
||||
(add-hook 'ob-racket-pre-runtime-library-load-hook
|
||||
#'ob-racket-raco-make-runtime-library)
|
||||
:straight (ob-racket
|
||||
:type git :host github :repo "hasu/emacs-ob-racket"
|
||||
:files ("*.el" "*.rkt")))
|
||||
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((emacs-lisp . t)
|
||||
(racket . t)
|
||||
))
|
||||
|
||||
;;; LaTeX configuration
|
||||
(require 'ox-latex)
|
||||
|
||||
(setq org-latex-pdf-process
|
||||
'("pdflatex -interaction nonstopmode -output-directory %o %f"
|
||||
"bibtex %b"
|
||||
"pdflatex -interaction nonstopmode -output-directory %o %f"
|
||||
"pdflatex -interaction nonstopmode -output-directory %o %f"))
|
||||
(setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export
|
||||
;; (setq org-latex-prefer-user-labels t)
|
||||
|
||||
;; deleted unwanted file extensions after latexMK
|
||||
(setq org-latex-logfiles-extensions
|
||||
(quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist")))
|
||||
|
||||
(unless (boundp 'org-latex-classes)
|
||||
(setq org-latex-classes nil))
|
||||
|
||||
(provide 'org-custom)
|
||||
|
||||
;;; org-custom.el ends here
|
45
workflows/lisp-custom.el
Normal file
45
workflows/lisp-custom.el
Normal file
|
@ -0,0 +1,45 @@
|
|||
;;; lisp-custom.el --- Customisations for working with lisp -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Paredit my beloved
|
||||
(use-package paredit
|
||||
:hook ((emacs-lisp-mode . enable-paredit-mode)
|
||||
(eval-expression-minibuffer-setup . enable-paredit-mode)
|
||||
(lisp-mode . enable-paredit-mode)
|
||||
(lisp-interaction-mode . enable-paredit-mode)
|
||||
(scheme-mode . enable-paredit-mode))
|
||||
:config
|
||||
(add-hook 'ielm-mode-hook (lambda ()
|
||||
(enable-paredit-mode)
|
||||
;; This fixes newline behavior in IELM, but breaks it everywhere else, hence it's wrapped here
|
||||
(define-key paredit-mode-map (kbd "RET") nil)
|
||||
(define-key paredit-mode-map (kbd "C-j") 'paredit-newline))))
|
||||
|
||||
;; SICP my beloved
|
||||
(use-package sicp
|
||||
:ensure t)
|
||||
|
||||
(provide 'lisp-custom)
|
||||
|
||||
;;; lisp-custom.el ends here
|
698
workflows/org-custom.el
Normal file
698
workflows/org-custom.el
Normal file
|
@ -0,0 +1,698 @@
|
|||
;;; org-custom.el --- Org-mode configuration -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'org)
|
||||
(require 'org-agenda)
|
||||
(require 'org-attach)
|
||||
(require 'transient)
|
||||
(require 'subr-x)
|
||||
|
||||
(defun org-mode-init ()
|
||||
"This is called through `org-mode-hook', so that I don't need to `add-hook' 20 million times."
|
||||
;; I want org to display pictures inline.
|
||||
(org-display-inline-images)
|
||||
;; I don't want monospace text by default.
|
||||
(variable-pitch-mode)
|
||||
)
|
||||
|
||||
(add-hook 'org-mode-hook #'org-mode-init)
|
||||
|
||||
(defcustom theurgy-org-directory "~/.org/"
|
||||
"The directory for all theurgy org-mode files."
|
||||
:type 'string
|
||||
:group 'theurgy
|
||||
:group 'theurgy-org)
|
||||
|
||||
;; Change a bunch of default org-mode variables.
|
||||
(setq org-log-done nil ;; I want to keep track of the time tasks are completed.
|
||||
org-return-follows-link t ;; I want to be able to follow links easily.
|
||||
org-hide-emphasis-markers t ;; This is a big one: hide markup syntax like ** and //.
|
||||
org-pretty-entities t ;; These two variables together render latex entities as UTF8, which means that Greek letters, subscript, and superscript are all rendered correctly.
|
||||
org-pretty-entities-include-sub-superscripts t
|
||||
org-enforce-todo-dependencies t ;; Prevent changing a parent to DONE if the children aren't
|
||||
org-enforce-todo-checkbox-dependencies t
|
||||
org-agenda-skip-scheduled-if-done t ;; Don't show done stuff in the agenda view
|
||||
org-agenda-skip-deadline-if-done t
|
||||
org-agenda-skip-timestamp-if-done t
|
||||
|
||||
org-todo-keywords '((sequence "TODO(t)" "WIP(w)" "DELEGATED(p)" "WAITING(?)" "|" "CANCELLED(x)" "DONE(d)")) ;; Some extra keywords in addition to TODO and DONE
|
||||
org-use-fast-todo-selection t ;; Always use fast selection
|
||||
org-refile-targets '((org-agenda-files :maxlevel . 2)) ;; Allow any agenda files to be refile targets.
|
||||
|
||||
org-agenda-files (append (apply 'append (mapcar
|
||||
(lambda (dir)
|
||||
(directory-files-recursively dir org-agenda-file-regexp))
|
||||
`(,(concat theurgy-org-directory "tasks"))))
|
||||
`(,(concat theurgy-org-directory "inbox.org"))) ;; Agenda files location - gathered recursively
|
||||
org-cite-global-bibliography `(,(concat theurgy-org-directory "global.bib")) ;; Global bibliography location
|
||||
|
||||
org-startup-indented t ;; Start indented - this fixed org-indent mode
|
||||
|
||||
org-attach-id-dir (concat theurgy-org-directory "lore/assets")
|
||||
|
||||
org-M-RET-may-split-line '((item . nil)) ;; https://irreal.org/blog/?p=6297
|
||||
)
|
||||
|
||||
;; Org modern and other interface enhancements
|
||||
(use-package org-modern
|
||||
:hook ((org-mode . org-modern-mode)
|
||||
(org-agenda-finalize . org-modern-agenda)))
|
||||
|
||||
(use-package org-modern-indent
|
||||
:straight (org-modern-indent :type git :host github :repo "jdtsmith/org-modern-indent")
|
||||
:hook ((org-mode . org-modern-indent-mode)))
|
||||
|
||||
(use-package wc-mode
|
||||
:hook ((org-mode . wc-mode))
|
||||
:config (setq wc-modeline-format "WC[%tw]"))
|
||||
|
||||
(use-package org-appear :ensure t
|
||||
:init
|
||||
(setq org-appear-delay 0.2)
|
||||
:hook
|
||||
org-mode)
|
||||
|
||||
;; Side tree
|
||||
(use-package org-side-tree
|
||||
:hook ((org-modern-mode . org-side-tree)))
|
||||
|
||||
;; Advice to display org-side-tree where we want it
|
||||
(defun theurgy-org-side-tree ()
|
||||
"Create or pop to Org-Side-Tree buffer."
|
||||
(interactive)
|
||||
(when (org-side-tree-buffer-p)
|
||||
(error "Don't tree a tree"))
|
||||
(unless (or (derived-mode-p 'org-mode)
|
||||
(derived-mode-p 'outline-mode)
|
||||
outline-minor-mode)
|
||||
(error "Not an outline buffer"))
|
||||
(let* ((tree-name (if (default-value 'org-side-tree-persistent)
|
||||
"*Org-Side-Tree*"
|
||||
(format "<tree>%s" (buffer-name))))
|
||||
(tree-buffer (get-buffer tree-name))
|
||||
(heading (org-side-tree-heading-number))
|
||||
(dd default-directory)
|
||||
(inv-spec buffer-invisibility-spec))
|
||||
(unless (buffer-live-p tree-buffer)
|
||||
(save-restriction
|
||||
(widen)
|
||||
(jit-lock-mode 1)
|
||||
(jit-lock-fontify-now))
|
||||
(setq tree-buffer (generate-new-buffer tree-name))
|
||||
(add-hook 'kill-buffer-hook #'org-side-tree-cleanup nil t)
|
||||
(let* ((headings (org-side-tree-get-headings))
|
||||
(tree-head-line (or (cadar (org-collect-keywords
|
||||
'("title")))
|
||||
"Org-Side-Tree"))
|
||||
(tree-mode-line (format "Org-Side-Tree - %s"
|
||||
(buffer-name))))
|
||||
(when (default-value 'org-side-tree-enable-folding)
|
||||
(setq-local org-side-tree-enable-folding t))
|
||||
(with-current-buffer tree-buffer
|
||||
(setq-local default-directory dd)
|
||||
(org-side-tree-mode)
|
||||
(setq tabulated-list-entries headings)
|
||||
(tabulated-list-print t t)
|
||||
(when (default-value 'org-side-tree-enable-folding)
|
||||
(setq-local org-side-tree-enable-folding t)
|
||||
;; preserve org font-locking
|
||||
(setq-local outline-minor-mode-highlight nil)
|
||||
(outline-minor-mode 1))
|
||||
(setq buffer-invisibility-spec inv-spec)
|
||||
(setq header-line-format tree-head-line)
|
||||
(setq mode-line-format tree-mode-line))))
|
||||
(org-side-tree-set-timer)
|
||||
(switch-to-buffer (buffer-name))
|
||||
(display-buffer-in-side-window
|
||||
tree-buffer
|
||||
`((side . ,org-side-tree-display-side)
|
||||
(slot . 1)
|
||||
(window-width . ,org-side-tree-width)))
|
||||
(when (default-value 'org-side-tree-persistent)
|
||||
(setq-local org-side-tree-persistent
|
||||
(buffer-name))
|
||||
(org-side-tree-update))
|
||||
(when org-side-tree-select
|
||||
(pop-to-buffer tree-buffer))
|
||||
(setq window-size-fixed (when org-side-tree-width 'width))
|
||||
(pulse-momentary-highlight-one-line)
|
||||
(org-side-tree-go-to-heading heading)))
|
||||
|
||||
(advice-add 'org-side-tree :override #'theurgy-org-side-tree)
|
||||
|
||||
;; Helper functions for the side tree
|
||||
(defun theurgy-toggle-org-side-tree ()
|
||||
(interactive)
|
||||
(if (get-buffer-window (concat "<tree>" (file-name-nondirectory (buffer-file-name))))
|
||||
(delete-window (get-buffer-window (concat "<tree>" (file-name-nondirectory (buffer-file-name)))))
|
||||
(org-side-tree)))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("<tree>.+\.org"
|
||||
(display-buffer-in-side-window)
|
||||
(side . left)
|
||||
(slot . 1)
|
||||
(window-height . 0.2)))
|
||||
|
||||
(define-key org-mode-map (kbd "C-<f8>") #'theurgy-toggle-org-side-tree)
|
||||
|
||||
;; https://chrismaiorana.com/summer-productivity-reset-emacs-functions/
|
||||
(defun csm/replace-punctuation-at-point ()
|
||||
"Replace punctuation at point (., !, ?) with the character typed by the user."
|
||||
(interactive)
|
||||
(let ((char (this-command-keys))) ;; Get the key pressed by the user
|
||||
(if (and (member (char-after) '(?. ?! ?? ?,)) ;; Check if current char is ., !, or ?
|
||||
(member (string-to-char char) '(?. ?! ??))) ;; Check if typed char is ., !, or ?
|
||||
(progn
|
||||
(delete-char 1) ;; Delete existing punctuation
|
||||
(insert char)) ;; Insert new punctuation
|
||||
(self-insert-command 1)))) ;; Default behavior: insert character
|
||||
|
||||
;; Bind this function to punctuation keys
|
||||
(define-key global-map "." 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "," 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "!" 'csm/replace-punctuation-at-point)
|
||||
(define-key global-map "?" 'csm/replace-punctuation-at-point)
|
||||
|
||||
;; Windmove bindings since org overwrites them otherwise
|
||||
(define-key org-mode-map (kbd "C-c <left>") 'windmove-left)
|
||||
(define-key org-mode-map (kbd "C-c <right>") 'windmove-right)
|
||||
(define-key org-mode-map (kbd "C-c <up>") 'windmove-up)
|
||||
(define-key org-mode-map (kbd "C-c <down>") 'windmove-down)
|
||||
|
||||
;; Same with scrolling
|
||||
(define-key org-mode-map (kbd "C-S-<down>") '(lambda () (interactive) (scroll-up-line 10)))
|
||||
(define-key org-mode-map (kbd "C-S-<up>") '(lambda () (interactive) (scroll-down-line 10)))
|
||||
|
||||
;; Sentence and word navigation and marking
|
||||
(setq sentence-end-double-space nil) ;; Otherwise, M-e is broken in normal writing.
|
||||
|
||||
;;; Generally useful things
|
||||
;; Mark word and sentence
|
||||
(defun mark-whole-word ()
|
||||
"Mark the whole word underneath the cursor."
|
||||
(interactive)
|
||||
(forward-word)
|
||||
(set-mark-command nil)
|
||||
(backward-word))
|
||||
|
||||
(defun mark-sentence ()
|
||||
"Mark the entire sentence underneath the cursor."
|
||||
(interactive)
|
||||
(forward-sentence)
|
||||
(set-mark-command nil)
|
||||
(backward-sentence))
|
||||
|
||||
(define-key org-mode-map (kbd "C-@") #'mark-whole-word)
|
||||
(define-key org-mode-map (kbd "M-@") #'mark-sentence)
|
||||
|
||||
(transient-define-prefix mark-menu-transient ()
|
||||
"Transient menu for marking units of text."
|
||||
["Mark" ("w" "Word" mark-whole-word)
|
||||
("s" "Sentence" mark-sentence)
|
||||
("p" "Paragraph" mark-paragraph)
|
||||
("b" "Buffer" mark-whole-buffer)])
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o SPC") #'mark-menu-transient)
|
||||
|
||||
;; Section navigation and reordering
|
||||
(defun move-sentence-right (&optional arg)
|
||||
"Move the whole sentence to the right of the next sentence, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(kill-sentence)
|
||||
(forward-sentence)
|
||||
(yank)
|
||||
(backward-sentence)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-sentence-left (&optional arg)
|
||||
"Move the whole sentence to the left of the previous sentence, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(kill-sentence)
|
||||
(backward-sentence)
|
||||
(left-char) ;; Capture previous space
|
||||
(yank)
|
||||
(backward-sentence)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-paragraph-up (&optional arg)
|
||||
"Move the whole paragraph above the previous paragraph, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-paragraph)
|
||||
(backward-paragraph)
|
||||
(kill-paragraph nil)
|
||||
(backward-paragraph)
|
||||
(yank)
|
||||
(backward-paragraph)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(defun move-paragraph-down (&optional arg)
|
||||
"Move the whole paragraph above the previous paragraph, `ARG' times."
|
||||
(interactive "^p")
|
||||
(or arg (setq arg 1))
|
||||
(while (> arg 0)
|
||||
(forward-paragraph)
|
||||
(backward-paragraph)
|
||||
(kill-paragraph nil)
|
||||
(forward-paragraph)
|
||||
(yank)
|
||||
(backward-paragraph)
|
||||
(setq arg (1- arg))))
|
||||
|
||||
(define-key org-mode-map (kbd "C-M-<left>") #'move-sentence-left)
|
||||
(define-key org-mode-map (kbd "C-M-<right>") #'move-sentence-right)
|
||||
(define-key org-mode-map (kbd "C-M-<up>") #'move-paragraph-up)
|
||||
(define-key org-mode-map (kbd "C-M-<down>") #'move-paragraph-down)
|
||||
|
||||
(transient-define-prefix reorder-transient ()
|
||||
"Transient menu for text re-ordering commands."
|
||||
["Move sentence..." ("l" "Left" move-sentence-left)
|
||||
("r" "Right" move-sentence-right)]
|
||||
["Move paragraph..." ("u" "Up" move-paragraph-up)
|
||||
("d" "Down" move-paragraph-down)])
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o r") #'reorder-transient)
|
||||
|
||||
;; Focused rewriting
|
||||
(defun break-out-sentence ()
|
||||
"Breaks a sentence out into it's own buffer for editing."
|
||||
(interactive)
|
||||
(backward-sentence)
|
||||
(kill-sentence)
|
||||
(switch-to-buffer-other-window "*break-out*")
|
||||
(erase-buffer)
|
||||
(yank))
|
||||
|
||||
(defun break-out-choose-sentence ()
|
||||
"Chooses a sentence from the break-out buffer."
|
||||
(interactive)
|
||||
(backward-sentence)
|
||||
(kill-sentence)
|
||||
(other-window -1)
|
||||
(kill-buffer "*break-out*")
|
||||
(yank))
|
||||
|
||||
(defun break-out-dwim ()
|
||||
"Either break-out or choose sentency depending on buffer name."
|
||||
(interactive)
|
||||
(if (equal (buffer-name) "*break-out*")
|
||||
(break-out-choose-sentence)
|
||||
(break-out-sentence)))
|
||||
|
||||
(define-key org-mode-map (kbd "C-c o b") #'break-out-dwim)
|
||||
|
||||
;; Powerthesaurus
|
||||
(use-package powerthesaurus
|
||||
:bind ("C-x t" . powerthesaurus-transient))
|
||||
|
||||
;; Harper
|
||||
(when (and (not (equal system-type 'windows-nt)) (locate-file "harper-ls" exec-path))
|
||||
(with-eval-after-load 'eglot
|
||||
(add-to-list 'eglot-server-programs
|
||||
'(org-mode . ("harper-ls" "--stdio"))))
|
||||
|
||||
(setq-default eglot-workspace-configuration
|
||||
'(:harper-ls (:dialect "Australian")))
|
||||
|
||||
(add-hook 'org-mode-hook 'eglot-ensure))
|
||||
|
||||
;;; Exobrain
|
||||
;;; Task management
|
||||
;; Maintenance and project file creation shortcuts
|
||||
(defun new-maintenance-file (maintenance-area)
|
||||
"Create a new maintenance file for a given `MAINTENANCE-AREA'."
|
||||
(interactive "sMaintenance area is: ")
|
||||
(find-file (concat "~/.org/tasks/maintenance/" maintenance-area ".org"))
|
||||
(insert "\n\n* Calendar\n\n* TO-DO\n\n* Routines\n\n* Archive\n")
|
||||
(goto-char (point-min)))
|
||||
|
||||
(defun new-project-file (project-name acceptance-criteria)
|
||||
"Create a new project file for a given `PROJECT-NAME', with some `ACCEPTANCE-CRITERIA'."
|
||||
(find-file (concat "~/.org/tasks/projects/" project-name ".org"))
|
||||
(insert (concat "\n\n* Acceptance Criteria\n\n" acceptance-criteria "\n\n* Ideas\n\n* TODO Work\n\n** Calendar\n\n** TO-DO\n\n** Routines\n\n** Archive\n"))
|
||||
(goto-char (point-min)))
|
||||
|
||||
(defun new-generic-project (project-name acceptance-criteria)
|
||||
"Interactive wrapper for `new-project-file', for generic projects."
|
||||
(interactive "sProject name is: \nsAcceptance criteria is: ")
|
||||
(new-project-file project-name acceptance-criteria))
|
||||
|
||||
(defun new-career-project (project-name acceptance-criteria)
|
||||
"Interactive wrapper for `new-project-file', for career projects."
|
||||
(interactive "sProject name is: \nsAcceptance criteria is: ")
|
||||
(new-project-file (concat "career/" project-name) acceptance-criteria))
|
||||
|
||||
;; Captures
|
||||
(defun select-task-area (location headline)
|
||||
"Prompt for a file in ~/.org/tasks/maintenance/ to insert the capture."
|
||||
(let* ((files (directory-files (concat "~/.org/tasks/" location) t "\\.org$"))
|
||||
(choices (mapcar
|
||||
(lambda (x) (string-remove-suffix ".org" x))
|
||||
(mapcar #'file-name-nondirectory files)))
|
||||
(selected (completing-read "Choose a file: " choices nil t)))
|
||||
(set-buffer (org-capture-target-buffer (concat "~/.org/tasks/" location selected ".org")))
|
||||
(org-capture-put-target-region-and-position)
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(setq headline (org-capture-expand-headline headline))
|
||||
(re-search-forward (format org-complex-heading-regexp-format
|
||||
(regexp-quote headline))
|
||||
nil t)
|
||||
(forward-line 0)))
|
||||
|
||||
(defun select-maintenance-area (headline)
|
||||
(select-task-area "maintenance/" headline))
|
||||
|
||||
(defun select-project (headline)
|
||||
(select-task-area "projects/" headline))
|
||||
|
||||
(defun select-career-project (headline)
|
||||
(select-task-area "projects/career/" headline))
|
||||
|
||||
(setq org-capture-templates
|
||||
'(("i" "Idea")
|
||||
("ii" "Generic" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :idea: \n\n%?"
|
||||
:empty-lines 1)
|
||||
("ip" "Project" entry
|
||||
(function (lambda () (select-project "Ideas")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1)
|
||||
("ic" "Career" entry
|
||||
(function (lambda () (select-career-project "Ideas")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1)
|
||||
|
||||
("t" "Task")
|
||||
("tt" "Generic")
|
||||
("ttt" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} :task:\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttm" "Maintenance" entry
|
||||
(function (lambda () (select-maintenance-area "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttp" "Project" entry
|
||||
(function (lambda () (select-project "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ttc" "Career" entry
|
||||
(function (lambda () (select-career-project "TO-DO")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE}\n\n%?"
|
||||
:empty-lines 1)
|
||||
("ts" "Scheduled")
|
||||
("tss" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} :scheduled:\n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsm" "Maintenance" entry
|
||||
(function (lambda () (select-maintenance-area "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsp" "Project" entry
|
||||
(function (lambda () (select-project "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
("tsc" "Career" entry
|
||||
(function (lambda () (select-career-project "Calendar")))
|
||||
"* TODO [%^{priority|#A|#B|#C|#D}] %^{TITLE} \n:SCHEDULED: %^T\n%?"
|
||||
:empty-lines 1
|
||||
:time-prompt t)
|
||||
|
||||
("n" "Note")
|
||||
("nn" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :note: \n\n%?"
|
||||
:empty-lines 1)
|
||||
("nm" "Meeting")
|
||||
("nmm" "Raw" entry
|
||||
(file "~/.org/inbox.org")
|
||||
"* %^{TITLE} :meeting: \n\n%?"
|
||||
:clock-in t
|
||||
:clock-resume t)
|
||||
("nmc" "Career" entry
|
||||
(function (lambda () (select-career-project "Calendar")))
|
||||
"* %^{TITLE} \n\n%?"
|
||||
:empty-lines 1
|
||||
:clock-in t
|
||||
:clock-resume t)))
|
||||
|
||||
(defun open-inbox ()
|
||||
"Opens `~/.org/inbox.org'"
|
||||
(interactive)
|
||||
(find-file "~/.org/inbox.org"))
|
||||
|
||||
(defun open-maintenance ()
|
||||
"Opens `~/.org/tasks/maintenance/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/maintenance/"))
|
||||
|
||||
(defun open-projects ()
|
||||
"Opens `~/.org/tasks/projects/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/projects/"))
|
||||
|
||||
(defun open-career ()
|
||||
"Opens `~/.org/tasks/projects/career/'"
|
||||
(interactive)
|
||||
(find-file "~/.org/tasks/projects/career/"))
|
||||
|
||||
(transient-define-prefix task-management-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Go To" ("i" "Inbox" open-inbox)
|
||||
("m" "Maintenance Directory" open-maintenance)
|
||||
("p" "Projects Directory" open-projects)
|
||||
("c" "Career Directory" open-career)]
|
||||
["Create New" ("M" "Maintenance File" new-maintenance-file)
|
||||
("P" "Project" new-generic-project)
|
||||
("C" "Career Project" new-career-project)])
|
||||
|
||||
(define-key global-map (kbd "C-c o t") #'task-management-menu)
|
||||
(define-key global-map (kbd "C-c a") #'org-agenda)
|
||||
(define-key global-map (kbd "C-c c") #'org-capture)
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*Org Agenda\\*"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 3)
|
||||
(window-width . 0.2)))
|
||||
|
||||
(add-to-list 'display-buffer-alist
|
||||
'("\\*capture\\*\\|CAPTURE-"
|
||||
(display-buffer-in-side-window)
|
||||
(side . right)
|
||||
(slot . 2)
|
||||
(window-width . 0.2)))
|
||||
|
||||
;; Org roam
|
||||
(use-package org-roam
|
||||
:straight nil
|
||||
:ensure t
|
||||
:init
|
||||
(setq org-roam-v2-ack t)
|
||||
:custom
|
||||
(org-roam-directory (file-truename "~/.org/lore/"))
|
||||
(org-roam-dailies-directory (file-truename "~/.org/lore/refined/journal/"))
|
||||
(org-roam-file-exclude-regexp "\\.git/.*\\|logseq/.*$")
|
||||
(org-roam-completion-everywhere)
|
||||
(org-roam-capture-templates
|
||||
'(("r" "Raw")
|
||||
("rr" "Note" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title}\n")
|
||||
:unnarrowed t)
|
||||
("rq" "Question" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title}\n#+filetags: :question:")
|
||||
:unnarrowed t)
|
||||
("i" "Index" plain
|
||||
"%?"
|
||||
:target (file+head "raw/${slug}.org" "#+title: ${title} - Index\n#+filetags: :index:")
|
||||
:unnarrowed t)
|
||||
("R" "Refined")
|
||||
("Rm" "Mini-essay" plain
|
||||
"%?"
|
||||
:target (file+head "refined/wiki/${slug}.org" "#+title: ${title}\n#+author: Jakub Nowak\n#+filetags: :mini-essay:")
|
||||
:unnarrowed t)
|
||||
("Re" "Essay" plain
|
||||
"%?"
|
||||
:target (file+head "refined/wiki/${slug}.org" "#+title: ${title}\n#+author: Jakub Nowak\n#+filetags: :essay:")
|
||||
:unnarrowed t)))
|
||||
(org-roam-dailies-capture-templates
|
||||
'(("d" "default" entry
|
||||
"* %?"
|
||||
:target (file+head "%<%Y-%m-%d>.org" ;; format matches Logseq
|
||||
"#+title: %<%Y-%m-%d>\n"))))
|
||||
:bind (("C-c n l" . org-roam-buffer-toggle)
|
||||
("C-c n f" . org-roam-node-find)
|
||||
("C-c n g" . org-roam-graph)
|
||||
("C-c n i" . org-roam-node-insert)
|
||||
("C-c n c" . org-roam-capture)
|
||||
:map org-roam-dailies-map
|
||||
("Y" . org-roam-dailies-capture-yesterday)
|
||||
("T" . org-roam-dailies-capture-tomorrow))
|
||||
:bind-keymap ("C-c n d" . org-roam-dailies-map)
|
||||
:config
|
||||
(require 'org-roam-dailies) ;; Ensure the keymap is available
|
||||
(org-roam-db-autosync-mode))
|
||||
|
||||
(defun org-roam-create-node-from-headline ()
|
||||
"Create an Org-roam note from the current headline and jump to it.
|
||||
|
||||
Normally, insert the headline’s title using the ’#title:’ file-level property
|
||||
and delete the Org-mode headline. However, if the current headline has a
|
||||
Org-mode properties drawer already, keep the headline and don’t insert
|
||||
‘#+title:'. Org-roam can extract the title from both kinds of notes, but using
|
||||
‘#+title:’ is a bit cleaner for a short note, which Org-roam encourages."
|
||||
(interactive)
|
||||
(let ((title (nth 4 (org-heading-components)))
|
||||
(has-properties (org-get-property-block)))
|
||||
(org-cut-subtree)
|
||||
(org-roam-find-file title nil nil 'no-confirm)
|
||||
(org-paste-subtree)
|
||||
(unless has-properties
|
||||
(kill-line)
|
||||
(while (outline-next-heading)
|
||||
(org-promote)))
|
||||
(goto-char (point-min))
|
||||
(when has-properties
|
||||
(kill-line)
|
||||
(kill-line))))
|
||||
|
||||
(use-package logseq-org-roam
|
||||
:straight (:host github
|
||||
:repo "sbougerel/logseq-org-roam"
|
||||
:files ("*.el")))
|
||||
|
||||
(transient-define-prefix org-roam-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Node" ("c" "Capture" org-roam-node-find)
|
||||
("i" "Insert" org-roam-node-insert)
|
||||
("r" "Refile" org-roam-create-node-from-headline)
|
||||
("f" "Find" org-roam-node-find) ]
|
||||
["Dailies" ("t" "Today" org-roam-dailies-capture-today)
|
||||
("y" "Yesterday" org-roam-dailies-capture-yesterday)
|
||||
("n" "Tomorrow" org-roam-dailies-capture-tomorrow)]
|
||||
["Logseq" ("R" "Fix links" logseq-org-roam)]
|
||||
["Org Roam UI" ("U" "Enable org-roam-ui-mode" org-roam-ui-mode)])
|
||||
|
||||
(define-key global-map (kbd "C-c o n") #'org-roam-menu)
|
||||
|
||||
(use-package org-roam-ui
|
||||
:straight
|
||||
(:host github :repo "org-roam/org-roam-ui" :branch "main" :files ("*.el" "out"))
|
||||
:after 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)
|
||||
: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))
|
||||
|
||||
;; Bibliography stuff
|
||||
(setq bibtex-dialect 'biblatex) ;; Use biblatex instead of bibtex.
|
||||
|
||||
(use-package biblio)
|
||||
|
||||
(defun bibtex-online-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Online"))
|
||||
|
||||
(defun bibtex-misc-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Misc"))
|
||||
|
||||
(defun bibtex-software-entry ()
|
||||
(interactive)
|
||||
(bibtex-entry "Software"))
|
||||
|
||||
(transient-define-prefix bibtex-transient-menu ()
|
||||
"Transient menu for task management shortcuts."
|
||||
["Biblio" ("d" "doi.org" doi-insert-bibtex)
|
||||
("x" "arXiv" arxiv-lookup)]
|
||||
["Templates" ("o" "Online Resource" bibtex-online-entry)
|
||||
("m" "Misc" bibtex-misc-entry)
|
||||
("s" "Software" bibtex-software-entry)])
|
||||
|
||||
(define-key bibtex-mode-map (kbd "C-c r") #'bibtex-transient-menu)
|
||||
|
||||
;;; Literate Programming
|
||||
;; Racket
|
||||
(use-package ob-racket
|
||||
:after org
|
||||
:config
|
||||
(add-hook 'ob-racket-pre-runtime-library-load-hook
|
||||
#'ob-racket-raco-make-runtime-library)
|
||||
:straight (ob-racket
|
||||
:type git :host github :repo "hasu/emacs-ob-racket"
|
||||
:files ("*.el" "*.rkt")))
|
||||
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
'((emacs-lisp . t)
|
||||
(racket . t)
|
||||
))
|
||||
|
||||
;;; LaTeX configuration
|
||||
(require 'ox-latex)
|
||||
|
||||
(setq org-latex-pdf-process
|
||||
'("pdflatex -interaction nonstopmode -output-directory %o %f"
|
||||
"bibtex %b"
|
||||
"pdflatex -interaction nonstopmode -output-directory %o %f"
|
||||
"pdflatex -interaction nonstopmode -output-directory %o %f"))
|
||||
(setq org-latex-with-hyperref nil) ;; stop org adding hypersetup{author..} to latex export
|
||||
;; (setq org-latex-prefer-user-labels t)
|
||||
|
||||
;; deleted unwanted file extensions after latexMK
|
||||
(setq org-latex-logfiles-extensions
|
||||
(quote ("lof" "lot" "tex~" "aux" "idx" "log" "out" "toc" "nav" "snm" "vrb" "dvi" "fdb_latexmk" "blg" "brf" "fls" "entoc" "ps" "spl" "bbl" "xmpi" "run.xml" "bcf" "acn" "acr" "alg" "glg" "gls" "ist")))
|
||||
|
||||
(unless (boundp 'org-latex-classes)
|
||||
(setq org-latex-classes nil))
|
||||
|
||||
(provide 'org-custom)
|
||||
|
||||
;;; org-custom.el ends here
|
91
writing.el
Normal file
91
writing.el
Normal file
|
@ -0,0 +1,91 @@
|
|||
;;; writing.el --- Writing behavior configuration -*- lexical-binding: t -*-
|
||||
|
||||
;; This file is not part of GNU Emacs
|
||||
|
||||
;; This program is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; This program is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; commentary
|
||||
|
||||
;;; Code:
|
||||
|
||||
;; Save place in file
|
||||
(save-place-mode 1)
|
||||
|
||||
;; Replace selection when pasting
|
||||
(delete-selection-mode 1)
|
||||
|
||||
;; Enable auto-pairing for parens
|
||||
(electric-pair-mode 1)
|
||||
|
||||
;; Enable narrowing
|
||||
(put 'narrow-to-region 'disabled nil)
|
||||
|
||||
;;; Spell Checking
|
||||
;; Use hunspell if available
|
||||
(if (file-exists-p "/usr/bin/hunspell")
|
||||
(progn
|
||||
(eval-after-load "ispell"
|
||||
'(progn
|
||||
(setq ispell-program-name "hunspell"
|
||||
ispell-dictionary "en_AU"
|
||||
ispell-alternate-dictionary (file-truename (concat user-emacs-directory "en_AU.dict"))
|
||||
ispell-local-dictionary-alist '(("en_AU" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_AU,en_AU-med") nil utf-8)))
|
||||
(defun ispell-get-coding-system () 'utf-8)))
|
||||
(eval-after-load "flyspell"
|
||||
'(progn
|
||||
(setq ispell-program-name "hunspell"
|
||||
ispell-dictionary "en_AU"
|
||||
ispell-alternate-dictionary (file-truename (concat user-emacs-directory "en_AU.dict"))
|
||||
ispell-local-dictionary-alist '(("en_AU" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_AU,en_AU-med") nil utf-8)))
|
||||
(defun ispell-get-coding-system () 'utf-8)))))
|
||||
|
||||
;; Visual undo tree
|
||||
(use-package vundo
|
||||
:straight (vundo :type git :host github :repo "casouri/vundo")
|
||||
|
||||
:config
|
||||
;; Take less on-screen space.
|
||||
(setq vundo-compact-display t)
|
||||
|
||||
:bind
|
||||
(:map global-map
|
||||
("C-x u" . vundo)))
|
||||
|
||||
;; Rainbow delimiters. Almost necessary for lisp.
|
||||
(use-package rainbow-delimiters
|
||||
:hook ((prog-mode . rainbow-delimiters-mode)))
|
||||
|
||||
;; Snippeting
|
||||
(use-package yasnippet
|
||||
;; This seems to be a necessity for working on the daemon
|
||||
:hook ((server-after-make-frame . (lambda () (yas-global-mode 1))))
|
||||
:config
|
||||
(yas-global-mode 1)
|
||||
(setq yas-snippet-dirs `(,(concat user-emacs-directory "snippets"))))
|
||||
|
||||
(use-package yasnippet-snippets
|
||||
:after (yasnippet))
|
||||
|
||||
;; Indentation
|
||||
(straight-use-package 'aggressive-indent-mode)
|
||||
(global-aggressive-indent-mode 1)
|
||||
(add-hook 'shell-mode-hook
|
||||
#'(lambda () (aggressive-indent-mode 0)))
|
||||
|
||||
(provide 'writing)
|
||||
|
||||
;;; writing.el ends here
|
Loading…
Add table
Add a link
Reference in a new issue