mirror of
https://github.com/SqrtMinusOne/dotfiles.git
synced 2025-12-10 19:23:03 +03:00
emacs: optimize lazy loading
This commit is contained in:
parent
23496bfacc
commit
10429c4ad6
2 changed files with 177 additions and 430 deletions
299
.emacs.d/init.el
299
.emacs.d/init.el
|
|
@ -30,12 +30,6 @@
|
|||
(setq my/nested-emacs (and (getenv "IS_EMACS") t))
|
||||
(setenv "IS_EMACS" "true")
|
||||
|
||||
(defmacro with-eval-after-load-norem (file &rest body)
|
||||
(declare (indent 1) (debug (form def-body)))
|
||||
`(unless my/remote-server
|
||||
(with-eval-after-load ,file
|
||||
,@body)))
|
||||
|
||||
(setq my/emacs-started nil)
|
||||
|
||||
(add-hook 'emacs-startup-hook
|
||||
|
|
@ -111,6 +105,9 @@
|
|||
|
||||
(setq confirm-kill-emacs 'y-or-n-p)
|
||||
|
||||
(setq initial-major-mode 'fundamental-mode)
|
||||
(setq initial-scratch-message "Hello there <3\n\n")
|
||||
|
||||
(use-package general
|
||||
:straight t
|
||||
:config
|
||||
|
|
@ -329,11 +326,18 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
"u" 'winner-undo
|
||||
"U" 'winner-redo)
|
||||
|
||||
(defun my/lisp-interaction-buffer ()
|
||||
(interactive)
|
||||
(let ((buf (get-buffer-create "*lisp-interaction*")))
|
||||
(with-current-buffer buf
|
||||
(lisp-interaction-mode))
|
||||
(switch-to-buffer buf)))
|
||||
|
||||
(my-leader-def
|
||||
:infix "b"
|
||||
"" '(:which-key "buffers")
|
||||
"s" '((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||||
:which-key "*scratch*")
|
||||
"s" '(my/lisp-interaction-buffer
|
||||
:which-key "*lisp-interaction*")
|
||||
"m" '((lambda () (interactive) (persp-switch-to-buffer "*Messages*"))
|
||||
:which-key "*Messages*")
|
||||
"l" 'next-buffer
|
||||
|
|
@ -356,7 +360,7 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
|
|||
|
||||
(require 'hideshow)
|
||||
(general-define-key
|
||||
:keymaps '(hs-minor-mode-map outline-minor-mode-map)
|
||||
:keymaps '(hs-minor-mode-map outline-minor-mode-map outline-mode-map)
|
||||
:states '(normal motion)
|
||||
"ze" 'hs-hide-level
|
||||
"TAB" 'evil-toggle-fold)
|
||||
|
|
@ -1030,12 +1034,13 @@ Obeys `widen-automatically', which see."
|
|||
(use-package olivetti
|
||||
:straight t
|
||||
:if (display-graphic-p)
|
||||
:commands (olivetti-mode)
|
||||
:config
|
||||
(setq-default olivetti-body-width 86))
|
||||
|
||||
(use-package keycast
|
||||
:straight t
|
||||
:config
|
||||
:init
|
||||
(define-minor-mode keycast-mode
|
||||
"Keycast mode"
|
||||
:global t
|
||||
|
|
@ -1044,10 +1049,12 @@ Obeys `widen-automatically', which see."
|
|||
(add-to-list 'global-mode-string '("" keycast-mode-line " "))
|
||||
(add-hook 'pre-command-hook 'keycast--update t) )
|
||||
(remove-hook 'pre-command-hook 'keycast--update)
|
||||
(setq global-mode-string (delete '("" keycast-mode-line " ") global-mode-string)))))
|
||||
(setq global-mode-string (delete '("" keycast-mode-line " ") global-mode-string))))
|
||||
:commands (keycast--update))
|
||||
|
||||
(use-package doom-themes
|
||||
:straight t
|
||||
;; Not deferring becuase I want `doom-themes-visual-bell-config'
|
||||
:config
|
||||
(setq doom-themes-enable-bold t
|
||||
doom-themes-enable-italic t)
|
||||
|
|
@ -1227,7 +1234,7 @@ Obeys `widen-automatically', which see."
|
|||
(tab-bar-tab :background (my/color-value 'bg)
|
||||
:foreground (my/color-value 'yellow)
|
||||
:underline (my/color-value 'yellow))
|
||||
(tab-bar :background nil :foreground nil)
|
||||
(tab-bar :background 'unspecified :foreground 'unspecified)
|
||||
(magit-section-secondary-heading :foreground (my/color-value 'blue)
|
||||
:weight 'bold))
|
||||
|
||||
|
|
@ -1245,7 +1252,8 @@ Obeys `widen-automatically', which see."
|
|||
(my/regenerate-desktop)))
|
||||
|
||||
(if my/is-termux
|
||||
(my/switch-theme 'modus-operandi-tinted)
|
||||
(progn
|
||||
(my/switch-theme 'modus-operandi-tinted))
|
||||
(my/switch-theme 'ef-duo-light))
|
||||
|
||||
(with-eval-after-load 'transient
|
||||
|
|
@ -2572,6 +2580,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
;; (setq livedown-browser "qutebrowser"))
|
||||
|
||||
(use-package adoc-mode
|
||||
:mode (rx (| ".asciidoc") eos)
|
||||
:straight t)
|
||||
|
||||
(use-package plantuml-mode
|
||||
|
|
@ -2596,6 +2605,8 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(use-package subed
|
||||
:straight (:host github :repo "rndusr/subed" :files ("subed/*.el")
|
||||
:build (:not native-compile))
|
||||
;; (cons (rx (| "srt" "vtt" "ass") eos) #'subed-mode)
|
||||
:mode ("\\(?:ass\\|\\(?:sr\\|vt\\)t\\)\\'" . subed-mode)
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps '(subed-mode-map subed-vtt-mode-map)
|
||||
|
|
@ -2655,6 +2666,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
:straight (:host github :repo "SqrtMinusOne/reverso.el")
|
||||
:init
|
||||
(my-leader-def "ar" #'reverso)
|
||||
:commands (reverso)
|
||||
:config
|
||||
(setq reverso-languages '(russian english german))
|
||||
(reverso-history-mode))
|
||||
|
|
@ -2739,6 +2751,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(add-hook 'clips-mode 'lispy-mode))
|
||||
|
||||
(use-package ein
|
||||
:commands (ein:run)
|
||||
:straight t)
|
||||
|
||||
(setq my/pipenv-python-alist '())
|
||||
|
|
@ -2883,6 +2896,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
|
||||
(use-package json-mode
|
||||
:straight t
|
||||
:mode "\\.json\\'"
|
||||
:config
|
||||
(add-hook 'json-mode-hook #'smartparens-mode)
|
||||
(add-hook 'json-mode-hook #'hs-minor-mode)
|
||||
|
|
@ -2918,11 +2932,13 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
|
||||
(use-package jenkinsfile-mode
|
||||
:straight t
|
||||
:mode "Jenkinsfile\\'"
|
||||
:config
|
||||
(add-hook 'jenkinsfile-mode-hook #'smartparens-mode)
|
||||
(my/set-smartparens-indent 'jenkinsfile-mode))
|
||||
|
||||
(use-package crontab-mode
|
||||
:mode "/crontab\\(\\.X*[[:alnum:]]+\\)?\\'"
|
||||
:straight t)
|
||||
|
||||
(use-package nginx-mode
|
||||
|
|
@ -2931,6 +2947,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(my/set-smartparens-indent 'nginx-mode))
|
||||
|
||||
(use-package hcl-mode
|
||||
:mode "\\.hcl\\'"
|
||||
:straight t)
|
||||
|
||||
(add-hook 'sh-mode-hook #'smartparens-mode)
|
||||
|
|
@ -2961,9 +2978,11 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
"rr" #'sqlformat-buffer)
|
||||
|
||||
(use-package sparql-mode
|
||||
:mode "\\.sparql\\'"
|
||||
:straight t)
|
||||
|
||||
(use-package graphql-mode
|
||||
:mode (rx (| "gql" "grapql") eos)
|
||||
:straight t)
|
||||
|
||||
(defun my/doc-view-setup ()
|
||||
|
|
@ -2997,6 +3016,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(add-hook 'gnuplot-mode-hook #'smartparens-mode))
|
||||
|
||||
(use-package x509-mode
|
||||
:commands (x509-dwim)
|
||||
:straight (:host github :repo "jobbflykt/x509-mode"
|
||||
:build (:not native-compile)))
|
||||
|
||||
|
|
@ -3080,7 +3100,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(lambda ()
|
||||
(rainbow-delimiters-mode -1))))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-crypt)
|
||||
(org-crypt-use-before-save-magic)
|
||||
(setq org-tags-exclude-from-inheritance '("crypt"))
|
||||
|
|
@ -3103,7 +3123,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
keys
|
||||
(funcall fun prompt keys)))
|
||||
|
||||
(with-eval-after-load-norem 'epa
|
||||
(with-eval-after-load 'epa
|
||||
(advice-add #'epa--select-keys :around #'my/epa--select-keys-around))
|
||||
|
||||
(unless my/remote-server
|
||||
|
|
@ -3151,7 +3171,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(with-eval-after-load 'org
|
||||
(org-link-set-parameters "rel" :follow #'browse-url :export #'my/export-rel-url))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(general-define-key
|
||||
:keymaps 'org-mode-map
|
||||
"C-c d" #'org-decrypt-entry
|
||||
|
|
@ -3190,7 +3210,7 @@ Returns (<buffer> . <workspace-index>) or nil."
|
|||
(kill-new url)
|
||||
(message (concat "Copied URL: " url))))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(general-nmap :keymaps 'org-mode-map
|
||||
"C-x C-l" 'my/org-link-copy))
|
||||
|
||||
|
|
@ -3258,11 +3278,11 @@ With ARG, repeats or can move backward if negative."
|
|||
(sp-local-pair 'org-mode "$" "$")
|
||||
(sp--remove-local-pair "'"))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(setq my/org-latex-scale 1.75)
|
||||
(setq org-format-latex-options (plist-put org-format-latex-options :scale my/org-latex-scale)))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(setq my/latex-preview-header "\\documentclass{article}
|
||||
\\usepackage[usenames]{color}
|
||||
\\usepackage{graphicx}
|
||||
|
|
@ -3375,6 +3395,7 @@ With ARG, repeats or can move backward if negative."
|
|||
(use-package restclient
|
||||
:if (not my/remote-server)
|
||||
:straight t
|
||||
:mode ("\\.http\\'" . restclient-mode)
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps 'restclient-mode-map
|
||||
|
|
@ -3393,7 +3414,7 @@ With ARG, repeats or can move backward if negative."
|
|||
:if (not my/remote-server)
|
||||
:straight t)
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
`((emacs-lisp . t)
|
||||
|
|
@ -3680,9 +3701,11 @@ With ARG, repeats or can move backward if negative."
|
|||
|
||||
(use-package phscroll
|
||||
:straight (:host github :repo "misohena/phscroll")
|
||||
:commands (org-phscroll-mode)
|
||||
:config
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-phscroll)))
|
||||
(require 'org-phscroll)
|
||||
(org-phscroll-deactivate)))
|
||||
|
||||
(defun my/update-org-agenda ()
|
||||
(interactive)
|
||||
|
|
@ -3717,7 +3740,7 @@ With ARG, repeats or can move backward if negative."
|
|||
(run-hooks 'my/org-refile-hooks))))
|
||||
|
||||
(setq org-roam-directory (concat org-directory "/roam"))
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(require 'seq)
|
||||
(my/update-org-agenda))
|
||||
|
||||
|
|
@ -3766,7 +3789,7 @@ With ARG, repeats or can move backward if negative."
|
|||
(setq org-clock-persist 'clock)
|
||||
(org-clock-persistence-insinuate))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(add-to-list
|
||||
'org-global-properties
|
||||
'("Effort_ALL" . "0 0:05 0:10 0:15 0:30 0:45 1:00 1:30 2:00 4:00 8:00")))
|
||||
|
|
@ -3908,90 +3931,6 @@ With ARG, repeats or can move backward if negative."
|
|||
"v" #'org-ql-view
|
||||
"q" #'org-ql-search))
|
||||
|
||||
(with-eval-after-load 'org-ql
|
||||
(org-ql-defpred property (property &optional value &key inherit multi)
|
||||
"Return non-nil if current entry has PROPERTY, and optionally VALUE.
|
||||
If INHERIT is nil, only match entries with PROPERTY set on the
|
||||
entry; if t, also match entries with inheritance. If INHERIT is
|
||||
not specified, use the Boolean value of
|
||||
`org-use-property-inheritance', which see (i.e. it is only
|
||||
interpreted as nil or non-nil). If MULTI is non-nil, also check for
|
||||
multi-value properties."
|
||||
:normalizers ((`(,predicate-names)
|
||||
;; HACK: This clause protects against the case in
|
||||
;; which the arguments are nil, which would cause an
|
||||
;; error in `rx-to-string' in other clauses. This
|
||||
;; can happen with `org-ql-completing-read',
|
||||
;; e.g. when the input is "property:" while the user
|
||||
;; is typing.
|
||||
;; FIXME: Instead of this being moot, make this
|
||||
;; predicate test for whether an entry has local
|
||||
;; properties when no arguments are given.
|
||||
(list 'property ""))
|
||||
(`(,predicate-names ,property ,value . ,plist)
|
||||
;; Convert keyword property arguments to strings. Non-sexp
|
||||
;; queries result in keyword property arguments (because to do
|
||||
;; otherwise would require ugly special-casing in the parsing).
|
||||
(when (keywordp property)
|
||||
(setf property (substring (symbol-name property) 1)))
|
||||
(list 'property property value
|
||||
:inherit (if (plist-member plist :inherit)
|
||||
(plist-get plist :inherit)
|
||||
org-use-property-inheritance)
|
||||
:multi (when (plist-member plist :multi)
|
||||
(plist-get plist :multi)))))
|
||||
;; MAYBE: Should case folding be disabled for properties? What about values?
|
||||
;; MAYBE: Support (property) without args.
|
||||
|
||||
;; NOTE: When inheritance is enabled, the preamble can't be used,
|
||||
;; which will make the search slower.
|
||||
:preambles ((`(,predicate-names ,property ,value ,(map :multi) . ,(map :inherit))
|
||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||
;; because the regexp could match a string not inside a property drawer.
|
||||
(list :regexp (unless inherit
|
||||
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||
,@(when multi '((? "+"))) ":"
|
||||
(1+ space) ,value (0+ space) eol)))
|
||||
:query query))
|
||||
(`(,predicate-names ,property ,(map :multi) . ,(map :inherit))
|
||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||
;; because the regexp could match a string not inside a property drawer.
|
||||
;; NOTE: The preamble only matches if there appears to be a value.
|
||||
;; A line like ":ID: " without any other text does not match.
|
||||
(list :regexp (unless inherit
|
||||
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||
,@(when multi '((? "+")))
|
||||
":" (1+ space)
|
||||
(minimal-match (1+ not-newline)) eol)))
|
||||
:query query)))
|
||||
:body
|
||||
(pcase property
|
||||
('nil (user-error "Property matcher requires a PROPERTY argument"))
|
||||
(_ (pcase value
|
||||
('nil
|
||||
;; Check that PROPERTY exists
|
||||
(org-ql--value-at
|
||||
(point) (lambda ()
|
||||
(org-entry-get (point) property))))
|
||||
(_
|
||||
;; Check that PROPERTY has VALUE.
|
||||
|
||||
;; TODO: Since --value-at doesn't account for inheritance,
|
||||
;; we should generalize --tags-at to also work for property
|
||||
;; inheritance and use it here, which should be much faster.
|
||||
(if multi
|
||||
(when-let (values (org-ql--value-at
|
||||
(point) (lambda ()
|
||||
;; The default separator is space
|
||||
(let ((org-property-separators `((,property . "\n"))))
|
||||
(org-entry-get (point) property inherit)))))
|
||||
(seq-some (lambda (v)
|
||||
(string-equal value v))
|
||||
(split-string values "\n")))
|
||||
(string-equal value (org-ql--value-at
|
||||
(point) (lambda ()
|
||||
(org-entry-get (point) property inherit)))))))))))
|
||||
|
||||
(cl-defun my/org-ql-view-recent-items
|
||||
(&key num-days (type 'ts)
|
||||
(files (org-agenda-files))
|
||||
|
|
@ -4132,77 +4071,6 @@ and lots of comments which are too long for my Emacs config."
|
|||
(with-eval-after-load 'org-ql
|
||||
(advice-add #'org-ql-view--format-element :override #'my/org-ql-view--format-element-override))
|
||||
|
||||
(defun my/org-meeting--prompt ()
|
||||
(let* ((meetings (org-ql-query
|
||||
:select #'element-with-markers
|
||||
:from (org-agenda-files)
|
||||
:where '(and (todo) (tags "mt") (ts-active :from today to 31))
|
||||
:order-by 'scheduled))
|
||||
(data (mapcar
|
||||
(lambda (meeting)
|
||||
(let ((raw-value (org-element-property :raw-value meeting))
|
||||
(scheduled (org-format-timestamp
|
||||
(org-element-property :scheduled meeting)
|
||||
(cdr org-time-stamp-formats))))
|
||||
(cons (format "%-30s %s" raw-value
|
||||
(propertize scheduled 'face 'org-agenda-date))
|
||||
meeting)))
|
||||
meetings))
|
||||
(ivy-prescient-sort-commands nil))
|
||||
(cdr
|
||||
(assoc
|
||||
(completing-read "Meeting: " data nil t)
|
||||
data))))
|
||||
|
||||
(defun my/org-meeting--format-link (meeting)
|
||||
(format "[[file:%s::*%s][%s]]"
|
||||
(buffer-file-name
|
||||
(marker-buffer
|
||||
(org-element-property :org-marker meeting)))
|
||||
(org-element-property :raw-value meeting)
|
||||
(org-element-property :raw-value meeting)))
|
||||
|
||||
(defun my/org-meeting-link (&optional arg)
|
||||
(interactive "p")
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(let* ((meeting (my/org-meeting--prompt))
|
||||
(link (my/org-meeting--format-link meeting))
|
||||
(element (org-element-at-point-no-context)))
|
||||
(if (or (not arg) (not (org-element-property :MEETING element)))
|
||||
(org-set-property "MEETING" link)
|
||||
(let ((range (org-get-property-block
|
||||
(org-element-property :begin element)))
|
||||
(case-fold-search nil))
|
||||
(goto-char (cdr range))
|
||||
(beginning-of-line)
|
||||
(insert-and-inherit ":MEETING+: " link "\n")
|
||||
(org-indent-line))))))
|
||||
|
||||
(defun my/org-ql-meeting-tasks (meeting)
|
||||
(interactive (list (my/org-meeting--prompt)))
|
||||
(org-ql-search (org-agenda-files)
|
||||
`(property "MEETING" ,(my/org-meeting--format-link meeting)
|
||||
:multi t)
|
||||
:sort '(date priority todo)
|
||||
:buffer (format "*Meeting Tasks: %s*" (org-element-property :raw-value meeting))
|
||||
:super-groups '((:auto-outline-path t))))
|
||||
|
||||
(defun my/org-ql-meeting-tasks-agenda ()
|
||||
(interactive)
|
||||
(let ((meeting (save-window-excursion
|
||||
(org-agenda-switch-to)
|
||||
(org-back-to-heading)
|
||||
(org-ql--add-markers
|
||||
(org-element-at-point)))))
|
||||
(my/org-ql-meeting-tasks meeting)))
|
||||
|
||||
(with-eval-after-load 'org-agenda
|
||||
(general-define-key
|
||||
:keymaps 'org-agenda-mode-map
|
||||
:states '(normal motion)
|
||||
"gm" #'my/org-ql-meeting-tasks-agenda))
|
||||
|
||||
(use-package org-habit-stats
|
||||
:straight (:host github :repo "ml729/org-habit-stats")
|
||||
:after (org)
|
||||
|
|
@ -5010,6 +4878,7 @@ TODO Write something, maybe? "))))
|
|||
|
||||
(use-package calfw
|
||||
:straight t
|
||||
:defer t
|
||||
:config
|
||||
(add-hook 'cfw:calendar-mode-hook #'my/calfw-setup-buffer))
|
||||
|
||||
|
|
@ -5115,7 +4984,7 @@ TODO Write something, maybe? "))))
|
|||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")))))
|
||||
|
||||
;; Make sure to eval the function when org-latex-classes list already exists
|
||||
(with-eval-after-load-norem 'ox-latex
|
||||
(with-eval-after-load 'ox-latex
|
||||
(my/setup-org-latex))
|
||||
|
||||
(with-eval-after-load 'ox
|
||||
|
|
@ -5307,7 +5176,6 @@ TODO Write something, maybe? "))))
|
|||
(use-package dired-recent
|
||||
:straight t
|
||||
:after dired
|
||||
:commands (dired-recent-open)
|
||||
:config
|
||||
(dired-recent-mode)
|
||||
(general-define-key
|
||||
|
|
@ -5318,14 +5186,15 @@ TODO Write something, maybe? "))))
|
|||
|
||||
(use-package all-the-icons-dired
|
||||
:straight t
|
||||
:after (dired)
|
||||
:if (display-graphic-p)
|
||||
:hook (dired-mode . (lambda ()
|
||||
(unless (string-match-p "/gnu/store" default-directory)
|
||||
(all-the-icons-dired-mode))))
|
||||
:config)
|
||||
(all-the-icons-dired-mode)))))
|
||||
|
||||
(use-package dired-open
|
||||
:straight t
|
||||
:after (dired)
|
||||
:commands (dired-open-xdg))
|
||||
|
||||
(use-package dired-du
|
||||
|
|
@ -5440,10 +5309,13 @@ TODO Write something, maybe? "))))
|
|||
(list (telega-msg-for-interactive)
|
||||
(prefix-numeric-value current-prefix-arg)))
|
||||
(if (eq arg 4)
|
||||
(let ((default-directory
|
||||
(with-current-buffer (my/get-good-buffer 'dired-mode "Dired buffer: ")
|
||||
(dired-current-directory))))
|
||||
(progn
|
||||
(setq telega-msg-save-dir
|
||||
(with-current-buffer (my/get-good-buffer 'dired-mode "Dired buffer: ")
|
||||
(dired-current-directory)))
|
||||
(telega-msg-save msg))
|
||||
(setq default-directory (expand-file-name "~"))
|
||||
(setq telega-msg-save-dir nil)
|
||||
(telega-msg-save msg)))
|
||||
|
||||
(defun my/dired-attach-to-notmuch (files notmuch-buffer)
|
||||
|
|
@ -5987,6 +5859,7 @@ TODO Write something, maybe? "))))
|
|||
("terminfo/65" "terminfo/65/*")
|
||||
("integration" "integration/*")
|
||||
(:exclude ".dir-locals.el" "*-tests.el")))
|
||||
:commands (eat eat-shell-mode)
|
||||
:config
|
||||
(setq eat-shell "/bin/bash"))
|
||||
|
||||
|
|
@ -6731,6 +6604,7 @@ ENTRY is an instance of `elfeed-entry'."
|
|||
:straight t
|
||||
:init
|
||||
(my-leader-def "au" #'gnus)
|
||||
:commands (gnus)
|
||||
:config
|
||||
(my/persp-add-rule
|
||||
gnus-summary-mode 0 "gnus"
|
||||
|
|
@ -7782,6 +7656,11 @@ base toot."
|
|||
:straight t
|
||||
:if (not my/remote-server)
|
||||
:functions (my-google-translate-at-point google-translate--search-tkk)
|
||||
:commands (google-translate-at-point
|
||||
google-translate-at-point-reverse
|
||||
google-translate-query-translate
|
||||
google-translate-query-translate-reverse
|
||||
google-translate-smooth-translate)
|
||||
:custom
|
||||
(google-translate-backend-method 'curl)
|
||||
:config
|
||||
|
|
@ -7878,6 +7757,7 @@ base toot."
|
|||
|
||||
(use-package sx
|
||||
:straight t
|
||||
:commands (sx-search sx-tab-frontpage)
|
||||
:config
|
||||
(general-define-key
|
||||
:states '(normal)
|
||||
|
|
@ -7963,6 +7843,7 @@ base toot."
|
|||
:straight t
|
||||
:init
|
||||
(setq ellama-language "English")
|
||||
:defer t
|
||||
:config
|
||||
(require 'llm-ollama)
|
||||
;; I've looked for this option for 1.5 hours
|
||||
|
|
@ -7982,7 +7863,7 @@ base toot."
|
|||
:embedding-model "llama3:instruct")))))
|
||||
|
||||
(with-eval-after-load 'ellama
|
||||
(transient-define-prefix my/ellama ()
|
||||
(transient-define-prefix my/ellama-transient ()
|
||||
"Ellama actions."
|
||||
["General"
|
||||
:class transient-row
|
||||
|
|
@ -8021,8 +7902,15 @@ base toot."
|
|||
("sp" "Provider" ellama-provider-select)
|
||||
("ss" "Session" ellama-session-switch)
|
||||
("sr" "Rename ression" ellama-session-rename)
|
||||
("sd" "Delete session" ellama-session-remove)])
|
||||
(my-leader-def "aie" #'my/ellama))
|
||||
("sd" "Delete session" ellama-session-remove)]))
|
||||
|
||||
|
||||
(defun my/ellama ()
|
||||
(interactive)
|
||||
(require 'ellama)
|
||||
(call-interactively #'my/ellama-transient))
|
||||
|
||||
(my-leader-def "aie" #'my/ellama)
|
||||
|
||||
(defun my/diff-strings (str1 str2)
|
||||
(let ((file1 (make-temp-file "diff1"))
|
||||
|
|
@ -8085,37 +7973,6 @@ base toot."
|
|||
(interactive (list (my/ellama--text) (derived-mode-p 'org-mode)))
|
||||
(my/ellama-text-with-diff text is-org-mode my/ellama-improve-concise-prompt))
|
||||
|
||||
(with-eval-after-load 'ellama
|
||||
(cl-defstruct (llm-ollama-gradient (:include llm-ollama)) num-ctx)
|
||||
|
||||
(cl-defmethod llm-provider-chat-request ((provider llm-ollama-gradient) prompt _)
|
||||
(let (request-alist messages options)
|
||||
(setq messages
|
||||
(mapcar (lambda (interaction)
|
||||
`(("role" . ,(symbol-name (llm-chat-prompt-interaction-role interaction)))
|
||||
("content" . ,(llm-chat-prompt-interaction-content interaction))))
|
||||
(llm-chat-prompt-interactions prompt)))
|
||||
(when (llm-chat-prompt-context prompt)
|
||||
(push `(("role" . "system")
|
||||
("content" . ,(llm-provider-utils-get-system-prompt prompt llm-ollama-example-prelude)))
|
||||
messages))
|
||||
(push `("messages" . ,messages) request-alist)
|
||||
(push `("model" . ,(llm-ollama-chat-model provider)) request-alist)
|
||||
(when (llm-chat-prompt-temperature prompt)
|
||||
(push `("temperature" . ,(llm-chat-prompt-temperature prompt)) options))
|
||||
(when (llm-chat-prompt-max-tokens prompt)
|
||||
(push `("num_predict" . ,(llm-chat-prompt-max-tokens prompt)) options))
|
||||
(when (llm-ollama-gradient-num-ctx provider)
|
||||
(push `("num_ctx" . ,(llm-ollama-gradient-num-ctx provider)) options))
|
||||
(when options (push `("options" . ,options) request-alist))
|
||||
request-alist))
|
||||
|
||||
(push `("llama3-gradient" . ,(make-llm-ollama-gradient
|
||||
:chat-model "llama3-gradient"
|
||||
:embedding-model "llama3-gradient"
|
||||
:num-ctx 48000))
|
||||
ellama-providers))
|
||||
|
||||
(with-eval-after-load 'gptel
|
||||
(cl-defmethod gptel--request-data :around ((_backend gptel-ollama) prompts)
|
||||
(let ((request-alist (cl-call-next-method)))
|
||||
|
|
@ -8126,6 +7983,7 @@ base toot."
|
|||
request-alist)))
|
||||
|
||||
(use-package ini
|
||||
:mode "\\.ini\\'"
|
||||
:straight (:host github :repo "daniel-ness/ini.el"))
|
||||
|
||||
(defvar my/index-root (concat (getenv "HOME") "/"))
|
||||
|
|
@ -8500,6 +8358,7 @@ prefix."
|
|||
|
||||
TREE is a form a defined by `my/index--tree-get'. The return value is
|
||||
a list of commands as defined by `my/index--commands-display'."
|
||||
(require 'ini)
|
||||
(let* ((map-tree (my/index--wakatime-get-map-tree tree))
|
||||
(map-tree-encoding (ini-encode `(("projectmap" . ,map-tree))))
|
||||
(map-tree-saved (with-temp-buffer
|
||||
|
|
@ -8905,6 +8764,7 @@ to `dired' if used interactively."
|
|||
"M-o" #'casual-main-menu))
|
||||
|
||||
(use-package chess
|
||||
:commands (chess-pgn-mode)
|
||||
:straight t)
|
||||
|
||||
(setq my/chess-python "/home/pavel/.guix-extra-profiles/dev/dev/bin/python3")
|
||||
|
|
@ -8992,6 +8852,7 @@ to `dired' if used interactively."
|
|||
|
||||
(use-package zone
|
||||
:ensure nil
|
||||
:commands (zone)
|
||||
:config
|
||||
(setq original-zone-programs (copy-sequence zone-programs)))
|
||||
|
||||
|
|
|
|||
308
Emacs.org
308
Emacs.org
|
|
@ -67,6 +67,7 @@ I decided not to keep configs for features that I do not use anymore because thi
|
|||
| org-roam-protocol | 2f0c20eb01b8899d00d129cc7ca5c6b263c69c65 |
|
||||
| eshell-info-banner | 4ccc0bbc412b68e1401533264d801d86b1fc8cc7 |
|
||||
| aweshell | 4ccc0bbc412b68e1401533264d801d86b1fc8cc7 |
|
||||
| link tasks to meetings | 23496bfacc31ffedf2092da04e4e602b71373425 |
|
||||
|
||||
* Initial setup
|
||||
Setting up the environment, performance tuning and a few basic settings.
|
||||
|
|
@ -150,14 +151,6 @@ To launch Emacs with this config, run
|
|||
emacs -q -l ~/.emacs.d/init-minimal.el
|
||||
#+end_src
|
||||
|
||||
A convinience macro:
|
||||
#+begin_src emacs-lisp
|
||||
(defmacro with-eval-after-load-norem (file &rest body)
|
||||
(declare (indent 1) (debug (form def-body)))
|
||||
`(unless my/remote-server
|
||||
(with-eval-after-load ,file
|
||||
,@body)))
|
||||
#+end_src
|
||||
** Performance
|
||||
*** Measure startup speed
|
||||
A small function to print out the loading time and number of GCs during the loading. Can be useful as a point of data for optimizing Emacs startup time.
|
||||
|
|
@ -174,7 +167,7 @@ A small function to print out the loading time and number of GCs during the load
|
|||
(setq my/emacs-started t)))
|
||||
#+end_src
|
||||
|
||||
Set the following to =t= to print debug information during the startup. This will include the order in which the packages are loaded and the loading time of individual packages.
|
||||
Set the following to =t= to print debug information during the startup. This will include package loading order and time.
|
||||
#+begin_src emacs-lisp
|
||||
(setq use-package-verbose nil)
|
||||
#+end_src
|
||||
|
|
@ -189,7 +182,7 @@ Just setting ~gc-cons-treshold~ to a larger value.
|
|||
*** Run garbage collection when Emacs is unfocused
|
||||
Run GC when Emacs loses focus. +Time will tell if that's a good idea.+
|
||||
|
||||
Some time has passed, and I still don't know if there is any quantifiable advantage to this, but it doesn't hurt.
|
||||
I still don't know if there is any quantifiable advantage to this, but it doesn't hurt.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(add-hook 'emacs-startup-hook
|
||||
|
|
@ -291,6 +284,15 @@ This adds a confirmation to avoid accidental Emacs closing.
|
|||
#+begin_src emacs-lisp
|
||||
(setq confirm-kill-emacs 'y-or-n-p)
|
||||
#+end_src
|
||||
** Scratch buffer
|
||||
I have a problem with =emacs-lisp-mode= as =initial-major-mode= because in my config it loads =lispy=, which loads =org-mode=.
|
||||
|
||||
So until I've made a better loading screen, this will do.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(setq initial-major-mode 'fundamental-mode)
|
||||
(setq initial-scratch-message "Hello there <3\n\n")
|
||||
#+end_src
|
||||
* General settings
|
||||
** Keybindings
|
||||
*** general.el
|
||||
|
|
@ -549,6 +551,7 @@ Using the =SPC= key as a leader key, like in Doom Emacs or Spacemacs.
|
|||
(my-leader-def
|
||||
"a" '(:which-key "apps"))
|
||||
#+end_src
|
||||
|
||||
**** Universal argument
|
||||
Change the universal argument to =M-u=. I use =C-u= to scroll up, as I'm used to from vim.
|
||||
|
||||
|
|
@ -608,12 +611,23 @@ It doesn't play too well with perspective.el, that is it has a single history li
|
|||
"U" 'winner-redo)
|
||||
#+end_src
|
||||
**** Buffer management
|
||||
The following is necessary since my scratch buffer isn't lisp-interaction.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/lisp-interaction-buffer ()
|
||||
(interactive)
|
||||
(let ((buf (get-buffer-create "*lisp-interaction*")))
|
||||
(with-current-buffer buf
|
||||
(lisp-interaction-mode))
|
||||
(switch-to-buffer buf)))
|
||||
#+end_src
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(my-leader-def
|
||||
:infix "b"
|
||||
"" '(:which-key "buffers")
|
||||
"s" '((lambda () (interactive) (switch-to-buffer (persp-scratch-buffer)))
|
||||
:which-key "*scratch*")
|
||||
"s" '(my/lisp-interaction-buffer
|
||||
:which-key "*lisp-interaction*")
|
||||
"m" '((lambda () (interactive) (persp-switch-to-buffer "*Messages*"))
|
||||
:which-key "*Messages*")
|
||||
"l" 'next-buffer
|
||||
|
|
@ -651,7 +665,7 @@ Evil does a pretty good job of abstracting all these packages with a set of vim-
|
|||
#+begin_src emacs-lisp
|
||||
(require 'hideshow)
|
||||
(general-define-key
|
||||
:keymaps '(hs-minor-mode-map outline-minor-mode-map)
|
||||
:keymaps '(hs-minor-mode-map outline-minor-mode-map outline-mode-map)
|
||||
:states '(normal motion)
|
||||
"ze" 'hs-hide-level
|
||||
"TAB" 'evil-toggle-fold)
|
||||
|
|
@ -1716,6 +1730,7 @@ Title format, which used to look something like =emacs:project@hostname=. Now it
|
|||
(use-package olivetti
|
||||
:straight t
|
||||
:if (display-graphic-p)
|
||||
:commands (olivetti-mode)
|
||||
:config
|
||||
(setq-default olivetti-body-width 86))
|
||||
#+end_src
|
||||
|
|
@ -1725,7 +1740,7 @@ Showing the last pressed key. Occasionally useful.
|
|||
#+begin_src emacs-lisp
|
||||
(use-package keycast
|
||||
:straight t
|
||||
:config
|
||||
:init
|
||||
(define-minor-mode keycast-mode
|
||||
"Keycast mode"
|
||||
:global t
|
||||
|
|
@ -1734,7 +1749,8 @@ Showing the last pressed key. Occasionally useful.
|
|||
(add-to-list 'global-mode-string '("" keycast-mode-line " "))
|
||||
(add-hook 'pre-command-hook 'keycast--update t) )
|
||||
(remove-hook 'pre-command-hook 'keycast--update)
|
||||
(setq global-mode-string (delete '("" keycast-mode-line " ") global-mode-string)))))
|
||||
(setq global-mode-string (delete '("" keycast-mode-line " ") global-mode-string))))
|
||||
:commands (keycast--update))
|
||||
#+end_src
|
||||
** Themes and colors
|
||||
*** Theme packages
|
||||
|
|
@ -1742,6 +1758,7 @@ My colorschemes of choice.
|
|||
#+begin_src emacs-lisp
|
||||
(use-package doom-themes
|
||||
:straight t
|
||||
;; Not deferring becuase I want `doom-themes-visual-bell-config'
|
||||
:config
|
||||
(setq doom-themes-enable-bold t
|
||||
doom-themes-enable-italic t)
|
||||
|
|
@ -1970,7 +1987,7 @@ Defining colors for =tab-bar.el=:
|
|||
(tab-bar-tab :background (my/color-value 'bg)
|
||||
:foreground (my/color-value 'yellow)
|
||||
:underline (my/color-value 'yellow))
|
||||
(tab-bar :background nil :foreground nil)
|
||||
(tab-bar :background 'unspecified :foreground 'unspecified)
|
||||
(magit-section-secondary-heading :foreground (my/color-value 'blue)
|
||||
:weight 'bold))
|
||||
#+end_src
|
||||
|
|
@ -1994,7 +2011,8 @@ The built-in =load-theme= does not deactivate the previous theme, so here's a fu
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(if my/is-termux
|
||||
(my/switch-theme 'modus-operandi-tinted)
|
||||
(progn
|
||||
(my/switch-theme 'modus-operandi-tinted))
|
||||
(my/switch-theme 'ef-duo-light))
|
||||
#+end_src
|
||||
**** Extending current theme
|
||||
|
|
@ -3502,6 +3520,7 @@ Section snippets. The code turned out to be more complicated than just writing t
|
|||
*** Ascii Doc
|
||||
#+begin_src emacs-lisp
|
||||
(use-package adoc-mode
|
||||
:mode (rx (| ".asciidoc") eos)
|
||||
:straight t)
|
||||
#+end_src
|
||||
*** PlantUML
|
||||
|
|
@ -3536,6 +3555,8 @@ A major mode to work with subtitles.
|
|||
(use-package subed
|
||||
:straight (:host github :repo "rndusr/subed" :files ("subed/*.el")
|
||||
:build (:not native-compile))
|
||||
;; (cons (rx (| "srt" "vtt" "ass") eos) #'subed-mode)
|
||||
:mode ("\\(?:ass\\|\\(?:sr\\|vt\\)t\\)\\'" . subed-mode)
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps '(subed-mode-map subed-vtt-mode-map)
|
||||
|
|
@ -3622,6 +3643,7 @@ References:
|
|||
:straight (:host github :repo "SqrtMinusOne/reverso.el")
|
||||
:init
|
||||
(my-leader-def "ar" #'reverso)
|
||||
:commands (reverso)
|
||||
:config
|
||||
(setq reverso-languages '(russian english german))
|
||||
(reverso-history-mode))
|
||||
|
|
@ -3749,6 +3771,7 @@ An honorary Lisp.
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ein
|
||||
:commands (ein:run)
|
||||
:straight t)
|
||||
#+end_src
|
||||
*** pyright
|
||||
|
|
@ -3994,6 +4017,7 @@ A function to start up [[https://www.tensorflow.org/tensorboard][TensorBoard]].
|
|||
#+begin_src emacs-lisp
|
||||
(use-package json-mode
|
||||
:straight t
|
||||
:mode "\\.json\\'"
|
||||
:config
|
||||
(add-hook 'json-mode-hook #'smartparens-mode)
|
||||
(add-hook 'json-mode-hook #'hs-minor-mode)
|
||||
|
|
@ -4044,6 +4068,7 @@ A package to quickly create =.gitignore= files.
|
|||
#+begin_src emacs-lisp
|
||||
(use-package jenkinsfile-mode
|
||||
:straight t
|
||||
:mode "Jenkinsfile\\'"
|
||||
:config
|
||||
(add-hook 'jenkinsfile-mode-hook #'smartparens-mode)
|
||||
(my/set-smartparens-indent 'jenkinsfile-mode))
|
||||
|
|
@ -4051,6 +4076,7 @@ A package to quickly create =.gitignore= files.
|
|||
*** crontab
|
||||
#+begin_src emacs-lisp
|
||||
(use-package crontab-mode
|
||||
:mode "/crontab\\(\\.X*[[:alnum:]]+\\)?\\'"
|
||||
:straight t)
|
||||
#+end_src
|
||||
*** nginx
|
||||
|
|
@ -4063,6 +4089,7 @@ A package to quickly create =.gitignore= files.
|
|||
*** HCL
|
||||
#+begin_src emacs-lisp
|
||||
(use-package hcl-mode
|
||||
:mode "\\.hcl\\'"
|
||||
:straight t)
|
||||
#+end_src
|
||||
** Shell
|
||||
|
|
@ -4109,11 +4136,13 @@ So far I didn't find a nice SQL client for Emacs, but I occasionally run SQL que
|
|||
*** SPARQL
|
||||
#+begin_src emacs-lisp
|
||||
(use-package sparql-mode
|
||||
:mode "\\.sparql\\'"
|
||||
:straight t)
|
||||
#+end_src
|
||||
*** GraphQL
|
||||
#+begin_src emacs-lisp
|
||||
(use-package graphql-mode
|
||||
:mode (rx (| "gql" "grapql") eos)
|
||||
:straight t)
|
||||
#+end_src
|
||||
** Documents
|
||||
|
|
@ -4160,6 +4189,7 @@ Emacs integration for [[http://gnuplot.info/][gnuplot]].
|
|||
** x509
|
||||
#+begin_src emacs-lisp
|
||||
(use-package x509-mode
|
||||
:commands (x509-dwim)
|
||||
:straight (:host github :repo "jobbflykt/x509-mode"
|
||||
:build (:not native-compile)))
|
||||
#+end_src
|
||||
|
|
@ -4281,7 +4311,7 @@ Use the built-in org mode (=:type built-in=).
|
|||
Setting up =org-crypt= to encrypt parts of file.
|
||||
|
||||
#+begin_src emacs-lisp :noweb-ref
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-crypt)
|
||||
(org-crypt-use-before-save-magic)
|
||||
(setq org-tags-exclude-from-inheritance '("crypt"))
|
||||
|
|
@ -4311,7 +4341,7 @@ Another way to encrypt Org files is to save them with the extension =.org.gpg=.
|
|||
keys
|
||||
(funcall fun prompt keys)))
|
||||
|
||||
(with-eval-after-load-norem 'epa
|
||||
(with-eval-after-load 'epa
|
||||
(advice-add #'epa--select-keys :around #'my/epa--select-keys-around))
|
||||
|
||||
(unless my/remote-server
|
||||
|
|
@ -4388,7 +4418,7 @@ I've moved this block above because the =my-leader-def= expression in the next b
|
|||
|
||||
*** General keybindings
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(general-define-key
|
||||
:keymaps 'org-mode-map
|
||||
"C-c d" #'org-decrypt-entry
|
||||
|
|
@ -4429,7 +4459,7 @@ I've moved this block above because the =my-leader-def= expression in the next b
|
|||
(kill-new url)
|
||||
(message (concat "Copied URL: " url))))
|
||||
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(general-nmap :keymaps 'org-mode-map
|
||||
"C-x C-l" 'my/org-link-copy))
|
||||
#+end_src
|
||||
|
|
@ -4517,14 +4547,14 @@ Call the function before opening an org file or reopen a buffer after calling th
|
|||
|
||||
Scale latex fragments preview.
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(setq my/org-latex-scale 1.75)
|
||||
(setq org-format-latex-options (plist-put org-format-latex-options :scale my/org-latex-scale)))
|
||||
#+end_src
|
||||
|
||||
Also, LaTeX fragments preview tends to break whenever the are custom =#+LATEX_HEADER= entries. To circumvent this, I add a custom header and modify the ~org-preview-latex-process-alist~ variable
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(setq my/latex-preview-header "\\documentclass{article}
|
||||
\\usepackage[usenames]{color}
|
||||
\\usepackage{graphicx}
|
||||
|
|
@ -4698,6 +4728,7 @@ References:
|
|||
(use-package restclient
|
||||
:if (not my/remote-server)
|
||||
:straight t
|
||||
:mode ("\\.http\\'" . restclient-mode)
|
||||
:config
|
||||
(general-define-key
|
||||
:keymaps 'restclient-mode-map
|
||||
|
|
@ -4719,7 +4750,7 @@ References:
|
|||
*** Org Babel Setup
|
||||
Enable languages
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(org-babel-do-load-languages
|
||||
'org-babel-load-languages
|
||||
`((emacs-lisp . t)
|
||||
|
|
@ -5127,9 +5158,11 @@ I use Org to manage some small tables which I want to process further. So here i
|
|||
#+begin_src emacs-lisp
|
||||
(use-package phscroll
|
||||
:straight (:host github :repo "misohena/phscroll")
|
||||
:commands (org-phscroll-mode)
|
||||
:config
|
||||
(with-eval-after-load 'org
|
||||
(require 'org-phscroll)))
|
||||
(require 'org-phscroll)
|
||||
(org-phscroll-deactivate)))
|
||||
#+end_src
|
||||
|
||||
** Productivity & Knowledge management
|
||||
|
|
@ -5188,7 +5221,7 @@ Also, my project structure is somewhat chaotic, so I have an =.el= file in the o
|
|||
(run-hooks 'my/org-refile-hooks))))
|
||||
|
||||
(setq org-roam-directory (concat org-directory "/roam"))
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(require 'seq)
|
||||
(my/update-org-agenda))
|
||||
#+end_src
|
||||
|
|
@ -5266,7 +5299,7 @@ The following enables org-clock persistence between Emacs sessions.
|
|||
|
||||
Effort estimation. Not using this as of now.
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load-norem 'org
|
||||
(with-eval-after-load 'org
|
||||
(add-to-list
|
||||
'org-global-properties
|
||||
'("Effort_ALL" . "0 0:05 0:10 0:15 0:30 0:45 1:00 1:30 2:00 4:00 8:00")))
|
||||
|
|
@ -5446,97 +5479,6 @@ It doesn't look great with org-bars mode, so...
|
|||
"q" #'org-ql-search))
|
||||
#+end_src
|
||||
|
||||
***** Add :multi argument to the property predicate
|
||||
I use the property predicate to find tasks linked to meetings, and I want to link some tasks to multiple meetings. So I modified the property predicate to support that.
|
||||
|
||||
I can't contribute that back to =org-ql= because it requires copyright assignment, so here it is.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'org-ql
|
||||
(org-ql-defpred property (property &optional value &key inherit multi)
|
||||
"Return non-nil if current entry has PROPERTY, and optionally VALUE.
|
||||
If INHERIT is nil, only match entries with PROPERTY set on the
|
||||
entry; if t, also match entries with inheritance. If INHERIT is
|
||||
not specified, use the Boolean value of
|
||||
`org-use-property-inheritance', which see (i.e. it is only
|
||||
interpreted as nil or non-nil). If MULTI is non-nil, also check for
|
||||
multi-value properties."
|
||||
:normalizers ((`(,predicate-names)
|
||||
;; HACK: This clause protects against the case in
|
||||
;; which the arguments are nil, which would cause an
|
||||
;; error in `rx-to-string' in other clauses. This
|
||||
;; can happen with `org-ql-completing-read',
|
||||
;; e.g. when the input is "property:" while the user
|
||||
;; is typing.
|
||||
;; FIXME: Instead of this being moot, make this
|
||||
;; predicate test for whether an entry has local
|
||||
;; properties when no arguments are given.
|
||||
(list 'property ""))
|
||||
(`(,predicate-names ,property ,value . ,plist)
|
||||
;; Convert keyword property arguments to strings. Non-sexp
|
||||
;; queries result in keyword property arguments (because to do
|
||||
;; otherwise would require ugly special-casing in the parsing).
|
||||
(when (keywordp property)
|
||||
(setf property (substring (symbol-name property) 1)))
|
||||
(list 'property property value
|
||||
:inherit (if (plist-member plist :inherit)
|
||||
(plist-get plist :inherit)
|
||||
org-use-property-inheritance)
|
||||
:multi (when (plist-member plist :multi)
|
||||
(plist-get plist :multi)))))
|
||||
;; MAYBE: Should case folding be disabled for properties? What about values?
|
||||
;; MAYBE: Support (property) without args.
|
||||
|
||||
;; NOTE: When inheritance is enabled, the preamble can't be used,
|
||||
;; which will make the search slower.
|
||||
:preambles ((`(,predicate-names ,property ,value ,(map :multi) . ,(map :inherit))
|
||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||
;; because the regexp could match a string not inside a property drawer.
|
||||
(list :regexp (unless inherit
|
||||
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||
,@(when multi '((? "+"))) ":"
|
||||
(1+ space) ,value (0+ space) eol)))
|
||||
:query query))
|
||||
(`(,predicate-names ,property ,(map :multi) . ,(map :inherit))
|
||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||
;; because the regexp could match a string not inside a property drawer.
|
||||
;; NOTE: The preamble only matches if there appears to be a value.
|
||||
;; A line like ":ID: " without any other text does not match.
|
||||
(list :regexp (unless inherit
|
||||
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||
,@(when multi '((? "+")))
|
||||
":" (1+ space)
|
||||
(minimal-match (1+ not-newline)) eol)))
|
||||
:query query)))
|
||||
:body
|
||||
(pcase property
|
||||
('nil (user-error "Property matcher requires a PROPERTY argument"))
|
||||
(_ (pcase value
|
||||
('nil
|
||||
;; Check that PROPERTY exists
|
||||
(org-ql--value-at
|
||||
(point) (lambda ()
|
||||
(org-entry-get (point) property))))
|
||||
(_
|
||||
;; Check that PROPERTY has VALUE.
|
||||
|
||||
;; TODO: Since --value-at doesn't account for inheritance,
|
||||
;; we should generalize --tags-at to also work for property
|
||||
;; inheritance and use it here, which should be much faster.
|
||||
(if multi
|
||||
(when-let (values (org-ql--value-at
|
||||
(point) (lambda ()
|
||||
;; The default separator is space
|
||||
(let ((org-property-separators `((,property . "\n"))))
|
||||
(org-entry-get (point) property inherit)))))
|
||||
(seq-some (lambda (v)
|
||||
(string-equal value v))
|
||||
(split-string values "\n")))
|
||||
(string-equal value (org-ql--value-at
|
||||
(point) (lambda ()
|
||||
(org-entry-get (point) property inherit)))))))))))
|
||||
#+end_src
|
||||
|
||||
***** Recent items
|
||||
I just want to change the default grouping in =org-ql-view-recent-items=...
|
||||
#+begin_src emacs-lisp
|
||||
|
|
@ -5695,83 +5637,6 @@ and lots of comments which are too long for my Emacs config."
|
|||
(advice-add #'org-ql-view--format-element :override #'my/org-ql-view--format-element-override))
|
||||
#+end_src
|
||||
|
||||
**** Link tasks to meetings
|
||||
The workflow here is basically link some tasks to meeting(s) and create a report from tasks linked to a particular meetings. The report also shows the time spent per task thanks to the last modification to =org-ql=.
|
||||
|
||||
This is essentially to avoid having to scramble my mind for hints of what I'm supposed to tell I was doing at each meeting.
|
||||
|
||||
#+begin_src emacs-lisp
|
||||
(defun my/org-meeting--prompt ()
|
||||
(let* ((meetings (org-ql-query
|
||||
:select #'element-with-markers
|
||||
:from (org-agenda-files)
|
||||
:where '(and (todo) (tags "mt") (ts-active :from today to 31))
|
||||
:order-by 'scheduled))
|
||||
(data (mapcar
|
||||
(lambda (meeting)
|
||||
(let ((raw-value (org-element-property :raw-value meeting))
|
||||
(scheduled (org-format-timestamp
|
||||
(org-element-property :scheduled meeting)
|
||||
(cdr org-time-stamp-formats))))
|
||||
(cons (format "%-30s %s" raw-value
|
||||
(propertize scheduled 'face 'org-agenda-date))
|
||||
meeting)))
|
||||
meetings))
|
||||
(ivy-prescient-sort-commands nil))
|
||||
(cdr
|
||||
(assoc
|
||||
(completing-read "Meeting: " data nil t)
|
||||
data))))
|
||||
|
||||
(defun my/org-meeting--format-link (meeting)
|
||||
(format "[[file:%s::*%s][%s]]"
|
||||
(buffer-file-name
|
||||
(marker-buffer
|
||||
(org-element-property :org-marker meeting)))
|
||||
(org-element-property :raw-value meeting)
|
||||
(org-element-property :raw-value meeting)))
|
||||
|
||||
(defun my/org-meeting-link (&optional arg)
|
||||
(interactive "p")
|
||||
(save-excursion
|
||||
(org-back-to-heading t)
|
||||
(let* ((meeting (my/org-meeting--prompt))
|
||||
(link (my/org-meeting--format-link meeting))
|
||||
(element (org-element-at-point-no-context)))
|
||||
(if (or (not arg) (not (org-element-property :MEETING element)))
|
||||
(org-set-property "MEETING" link)
|
||||
(let ((range (org-get-property-block
|
||||
(org-element-property :begin element)))
|
||||
(case-fold-search nil))
|
||||
(goto-char (cdr range))
|
||||
(beginning-of-line)
|
||||
(insert-and-inherit ":MEETING+: " link "\n")
|
||||
(org-indent-line))))))
|
||||
|
||||
(defun my/org-ql-meeting-tasks (meeting)
|
||||
(interactive (list (my/org-meeting--prompt)))
|
||||
(org-ql-search (org-agenda-files)
|
||||
`(property "MEETING" ,(my/org-meeting--format-link meeting)
|
||||
:multi t)
|
||||
:sort '(date priority todo)
|
||||
:buffer (format "*Meeting Tasks: %s*" (org-element-property :raw-value meeting))
|
||||
:super-groups '((:auto-outline-path t))))
|
||||
|
||||
(defun my/org-ql-meeting-tasks-agenda ()
|
||||
(interactive)
|
||||
(let ((meeting (save-window-excursion
|
||||
(org-agenda-switch-to)
|
||||
(org-back-to-heading)
|
||||
(org-ql--add-markers
|
||||
(org-element-at-point)))))
|
||||
(my/org-ql-meeting-tasks meeting)))
|
||||
|
||||
(with-eval-after-load 'org-agenda
|
||||
(general-define-key
|
||||
:keymaps 'org-agenda-mode-map
|
||||
:states '(normal motion)
|
||||
"gm" #'my/org-ql-meeting-tasks-agenda))
|
||||
#+end_src
|
||||
**** Tracking habits
|
||||
Let's see how this goes.
|
||||
|
||||
|
|
@ -6887,6 +6752,7 @@ An example contact entry can look like this:
|
|||
|
||||
(use-package calfw
|
||||
:straight t
|
||||
:defer t
|
||||
:config
|
||||
(add-hook 'cfw:calendar-mode-hook #'my/calfw-setup-buffer))
|
||||
|
||||
|
|
@ -7013,7 +6879,7 @@ Add a custom LaTeX template without default packages. Packages are indented to b
|
|||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")))))
|
||||
|
||||
;; Make sure to eval the function when org-latex-classes list already exists
|
||||
(with-eval-after-load-norem 'ox-latex
|
||||
(with-eval-after-load 'ox-latex
|
||||
(my/setup-org-latex))
|
||||
#+end_src
|
||||
|
||||
|
|
@ -7363,7 +7229,6 @@ I used to use [[https://www.emacswiki.org/emacs/DiredPlus][dired+]], which provi
|
|||
(use-package dired-recent
|
||||
:straight t
|
||||
:after dired
|
||||
:commands (dired-recent-open)
|
||||
:config
|
||||
(dired-recent-mode)
|
||||
(general-define-key
|
||||
|
|
@ -7382,17 +7247,18 @@ Display icons for files.
|
|||
#+begin_src emacs-lisp
|
||||
(use-package all-the-icons-dired
|
||||
:straight t
|
||||
:after (dired)
|
||||
:if (display-graphic-p)
|
||||
:hook (dired-mode . (lambda ()
|
||||
(unless (string-match-p "/gnu/store" default-directory)
|
||||
(all-the-icons-dired-mode))))
|
||||
:config)
|
||||
(all-the-icons-dired-mode)))))
|
||||
#+end_src
|
||||
|
||||
Provides stuff like =dired-open-xdg=
|
||||
#+begin_src emacs-lisp
|
||||
(use-package dired-open
|
||||
:straight t
|
||||
:after (dired)
|
||||
:commands (dired-open-xdg))
|
||||
#+end_src
|
||||
|
||||
|
|
@ -7552,10 +7418,13 @@ Save a telega file to a dired buffer.
|
|||
(list (telega-msg-for-interactive)
|
||||
(prefix-numeric-value current-prefix-arg)))
|
||||
(if (eq arg 4)
|
||||
(let ((default-directory
|
||||
(with-current-buffer (my/get-good-buffer 'dired-mode "Dired buffer: ")
|
||||
(dired-current-directory))))
|
||||
(progn
|
||||
(setq telega-msg-save-dir
|
||||
(with-current-buffer (my/get-good-buffer 'dired-mode "Dired buffer: ")
|
||||
(dired-current-directory)))
|
||||
(telega-msg-save msg))
|
||||
(setq default-directory (expand-file-name "~"))
|
||||
(setq telega-msg-save-dir nil)
|
||||
(telega-msg-save msg)))
|
||||
#+end_src
|
||||
|
||||
|
|
@ -8325,6 +8194,7 @@ Still, I'll probably switch to =eat= if =eshell= doesn't work for me.
|
|||
("terminfo/65" "terminfo/65/*")
|
||||
("integration" "integration/*")
|
||||
(:exclude ".dir-locals.el" "*-tests.el")))
|
||||
:commands (eat eat-shell-mode)
|
||||
:config
|
||||
(setq eat-shell "/bin/bash"))
|
||||
#+end_src
|
||||
|
|
@ -9344,6 +9214,7 @@ I'll try to use it for NTTP for now. Will see if I can do more with it.
|
|||
:straight t
|
||||
:init
|
||||
(my-leader-def "au" #'gnus)
|
||||
:commands (gnus)
|
||||
:config
|
||||
(my/persp-add-rule
|
||||
gnus-summary-mode 0 "gnus"
|
||||
|
|
@ -10706,6 +10577,11 @@ References:
|
|||
:straight t
|
||||
:if (not my/remote-server)
|
||||
:functions (my-google-translate-at-point google-translate--search-tkk)
|
||||
:commands (google-translate-at-point
|
||||
google-translate-at-point-reverse
|
||||
google-translate-query-translate
|
||||
google-translate-query-translate-reverse
|
||||
google-translate-smooth-translate)
|
||||
:custom
|
||||
(google-translate-backend-method 'curl)
|
||||
:config
|
||||
|
|
@ -10824,6 +10700,7 @@ There is a package called =devdocs= that does more or less the same, but I like
|
|||
#+begin_src emacs-lisp
|
||||
(use-package sx
|
||||
:straight t
|
||||
:commands (sx-search sx-tab-frontpage)
|
||||
:config
|
||||
(general-define-key
|
||||
:states '(normal)
|
||||
|
|
@ -10923,6 +10800,7 @@ I don't have access to any proprietary APIs, but LLaMA 3 8b with [[https://ollam
|
|||
:straight t
|
||||
:init
|
||||
(setq ellama-language "English")
|
||||
:defer t
|
||||
:config
|
||||
(require 'llm-ollama)
|
||||
;; I've looked for this option for 1.5 hours
|
||||
|
|
@ -10945,7 +10823,7 @@ I don't have access to any proprietary APIs, but LLaMA 3 8b with [[https://ollam
|
|||
The keybindings are a bit crazy to use even with =which-key=, so here goes transient.el.
|
||||
#+begin_src emacs-lisp
|
||||
(with-eval-after-load 'ellama
|
||||
(transient-define-prefix my/ellama ()
|
||||
(transient-define-prefix my/ellama-transient ()
|
||||
"Ellama actions."
|
||||
["General"
|
||||
:class transient-row
|
||||
|
|
@ -10984,8 +10862,15 @@ The keybindings are a bit crazy to use even with =which-key=, so here goes trans
|
|||
("sp" "Provider" ellama-provider-select)
|
||||
("ss" "Session" ellama-session-switch)
|
||||
("sr" "Rename ression" ellama-session-rename)
|
||||
("sd" "Delete session" ellama-session-remove)])
|
||||
(my-leader-def "aie" #'my/ellama))
|
||||
("sd" "Delete session" ellama-session-remove)]))
|
||||
|
||||
|
||||
(defun my/ellama ()
|
||||
(interactive)
|
||||
(require 'ellama)
|
||||
(call-interactively #'my/ellama-transient))
|
||||
|
||||
(my-leader-def "aie" #'my/ellama)
|
||||
#+end_src
|
||||
|
||||
**** Change natural text & diff against the results
|
||||
|
|
@ -11073,10 +10958,10 @@ Also, a prompt to make a text more concise.
|
|||
- =ellama-code-complete= is pretty good to write migrations
|
||||
*** Model settings
|
||||
**** llama3-gradient
|
||||
[[https://ollama.com/library/llama3-gradient][llama3-gradient]] is a version of LLaMA 3 with an extended context size. It requires setting the =num_ctx= parameter to work correctly.
|
||||
[[https://ollama.com/library/llama3-gradient][llama3-gradient]] is a version of LLaMA 3 with an extended context size. It requires setting the =num_ctx= parameter to work correctly. For ellama, the following works.
|
||||
|
||||
For ellama, the following works:
|
||||
#+begin_src emacs-lisp
|
||||
It's problematic to load this so I'm commenting this out for now.
|
||||
#+begin_src emacs-lisp :tangle no
|
||||
(with-eval-after-load 'ellama
|
||||
(cl-defstruct (llm-ollama-gradient (:include llm-ollama)) num-ctx)
|
||||
|
||||
|
|
@ -11211,6 +11096,7 @@ Another interesting tool is [[https://rclone.org/][rclone]], which provides a si
|
|||
We'll a package called [[https://github.com/daniel-ness/ini.el][ini.el]] to parse INI files.
|
||||
#+begin_src emacs-lisp
|
||||
(use-package ini
|
||||
:mode "\\.ini\\'"
|
||||
:straight (:host github :repo "daniel-ness/ini.el"))
|
||||
#+end_src
|
||||
|
||||
|
|
@ -11711,6 +11597,7 @@ And insert that in =wakatime.cfg= if necessary.
|
|||
|
||||
TREE is a form a defined by `my/index--tree-get'. The return value is
|
||||
a list of commands as defined by `my/index--commands-display'."
|
||||
(require 'ini)
|
||||
(let* ((map-tree (my/index--wakatime-get-map-tree tree))
|
||||
(map-tree-encoding (ini-encode `(("projectmap" . ,map-tree))))
|
||||
(map-tree-saved (with-temp-buffer
|
||||
|
|
@ -11726,9 +11613,6 @@ a list of commands as defined by `my/index--commands-display'."
|
|||
insert-command)))))
|
||||
#+end_src
|
||||
|
||||
#+RESULTS:
|
||||
: my/index--wakatime-commands
|
||||
|
||||
**** Symlinks
|
||||
The last part here is creating symbolic links.
|
||||
|
||||
|
|
@ -12258,6 +12142,7 @@ chess.el is a package by John Wiegley.
|
|||
|
||||
#+begin_src emacs-lisp
|
||||
(use-package chess
|
||||
:commands (chess-pgn-mode)
|
||||
:straight t)
|
||||
#+end_src
|
||||
|
||||
|
|
@ -12415,6 +12300,7 @@ Watch out if you are using EXWM.
|
|||
#+begin_src emacs-lisp
|
||||
(use-package zone
|
||||
:ensure nil
|
||||
:commands (zone)
|
||||
:config
|
||||
(setq original-zone-programs (copy-sequence zone-programs)))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue