emacs: the Bolsheviks can rest in peace

In what's left of it, anyway.
This commit is contained in:
Pavel Korytov 2023-12-25 01:52:11 +03:00
parent b1392141b5
commit 952fe0ae5d
2 changed files with 241 additions and 220 deletions

View file

@ -536,6 +536,8 @@ then it takes a second \\[keyboard-quit] to abort the minibuffer."
(general-imap "M-TAB" 'company-yasnippet)
(setq default-input-method "russian-computer")
(use-package smartparens
:straight t)
@ -2865,6 +2867,107 @@ 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
(general-define-key
:keymaps 'org-mode-map
"C-c d" 'org-decrypt-entry
"C-c e" 'org-encrypt-entry
"M-p" 'org-latex-preview
"M-o" 'org-redisplay-inline-images)
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"L" 'org-shiftright
"H" 'org-shiftleft
"S-<next>" 'org-next-visible-heading
"S-<prior>" 'org-previous-visible-heading
"M-0" 'org-next-visible-heading
"M-9" 'org-previous-visible-heading
"M-]" 'org-babel-next-src-block
"M-[" 'org-babel-previous-src-block)
(general-define-key
:keymaps 'org-agenda-mode-map
"M-]" 'org-agenda-later
"M-[" 'org-agenda-earlier)
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c))
(defun my/org-link-copy (&optional arg)
"Extract URL from org-mode link and add it to kill ring."
(interactive "P")
(let* ((link (org-element-lineage (org-element-context) '(link) t))
(type (org-element-property :type link))
(url (org-element-property :path link))
(url (concat type ":" url)))
(kill-new url)
(message (concat "Copied URL: " url))))
(with-eval-after-load-norem 'org
(general-nmap :keymaps 'org-mode-map
"C-x C-l" 'my/org-link-copy))
(defun my/org-babel-next-visible-src-block (arg)
"Move to the next visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(let ((regexp org-babel-src-block-regexp))
(if (< arg 0)
(beginning-of-line)
(end-of-line))
(while (and (< arg 0) (re-search-backward regexp nil :move))
(unless (bobp)
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-start o))
(re-search-backward regexp nil :move))
(_ nil))))
(cl-incf arg))
(while (and (> arg 0) (re-search-forward regexp nil t))
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-end o))
(re-search-forward regexp nil :move))
(_ (end-of-line) nil)))
(re-search-backward regexp nil :move)
(cl-decf arg))
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
(defun my/org-babel-previous-visible-src-block (arg)
"Move to the prevous visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(my/org-babel-next-visible-src-block (- arg)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"M-]" #'my/org-babel-next-visible-src-block
"M-[" #'my/org-babel-previous-visible-src-block))
(defun my/org-file-open ()
(interactive)
(let* ((files
(thread-last
'("projects" "misc")
(mapcar (lambda (f)
(directory-files (concat org-directory "/" f) t (rx ".org" eos))))
(apply #'append)
(mapcar (lambda (file)
(string-replace (concat org-directory "/") "" file)))
(append
'("inbox.org" "contacts.org")))))
(find-file
(concat org-directory "/"
(completing-read "Org file: " files)))))
(my-leader-def
"o o" 'my/org-file-open)
(use-package jupyter
:straight t
:after (org)
@ -3284,7 +3387,8 @@ Returns (<buffer> . <workspace-index>) or nil."
:straight (:host github :repo "SqrtMinusOne/org-clock-agg")
:commands (org-clock-agg)
:init
(my-leader-def "ol" #'org-clock-agg))
(with-eval-after-load 'org
(my-leader-def "ol" #'org-clock-agg)))
(with-eval-after-load 'org
(setq org-clock-persist 'clock)
@ -4620,107 +4724,6 @@ KEYS is a list of cons cells like (<label> . <time>)."
collect (list "ru" :default (plist-get (cdr entry) :utf-8))
else collect entry)))))
(with-eval-after-load-norem 'org
(general-define-key
:keymaps 'org-mode-map
"C-c d" 'org-decrypt-entry
"C-c e" 'org-encrypt-entry
"M-p" 'org-latex-preview
"M-o" 'org-redisplay-inline-images)
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"L" 'org-shiftright
"H" 'org-shiftleft
"S-<next>" 'org-next-visible-heading
"S-<prior>" 'org-previous-visible-heading
"M-0" 'org-next-visible-heading
"M-9" 'org-previous-visible-heading
"M-]" 'org-babel-next-src-block
"M-[" 'org-babel-previous-src-block)
(general-define-key
:keymaps 'org-agenda-mode-map
"M-]" 'org-agenda-later
"M-[" 'org-agenda-earlier)
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c))
(defun my/org-link-copy (&optional arg)
"Extract URL from org-mode link and add it to kill ring."
(interactive "P")
(let* ((link (org-element-lineage (org-element-context) '(link) t))
(type (org-element-property :type link))
(url (org-element-property :path link))
(url (concat type ":" url)))
(kill-new url)
(message (concat "Copied URL: " url))))
(with-eval-after-load-norem 'org
(general-nmap :keymaps 'org-mode-map
"C-x C-l" 'my/org-link-copy))
(defun my/org-babel-next-visible-src-block (arg)
"Move to the next visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(let ((regexp org-babel-src-block-regexp))
(if (< arg 0)
(beginning-of-line)
(end-of-line))
(while (and (< arg 0) (re-search-backward regexp nil :move))
(unless (bobp)
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-start o))
(re-search-backward regexp nil :move))
(_ nil))))
(cl-incf arg))
(while (and (> arg 0) (re-search-forward regexp nil t))
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-end o))
(re-search-forward regexp nil :move))
(_ (end-of-line) nil)))
(re-search-backward regexp nil :move)
(cl-decf arg))
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
(defun my/org-babel-previous-visible-src-block (arg)
"Move to the prevous visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(my/org-babel-next-visible-src-block (- arg)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"M-]" #'my/org-babel-next-visible-src-block
"M-[" #'my/org-babel-previous-visible-src-block))
(defun my/org-file-open ()
(interactive)
(let* ((files
(thread-last
'("projects" "misc")
(mapcar (lambda (f)
(directory-files (concat org-directory "/" f) t (rx ".org" eos))))
(apply #'append)
(mapcar (lambda (file)
(string-replace (concat org-directory "/") "" file)))
(append
'("inbox.org" "contacts.org")))))
(find-file
(concat org-directory "/"
(completing-read "Org file: " files)))))
(my-leader-def
"o o" 'my/org-file-open)
(defun my/extract-guix-dependencies (&optional category)
(let ((dependencies '()))
(org-table-map-tables

254
Emacs.org
View file

@ -945,6 +945,21 @@ References:
(general-imap "M-TAB" 'company-yasnippet)
#+end_src
*** Input Method
#+begin_quote
I have to switch layouts all the time, especially in LaTeX documents, because for some reason the Bolsheviks abandoned the idea of replacing Russian Cyrillic letters with Latin ones.
#+end_quote
- Me, [2021-04-24 Sat], in a commit to [[https://github.com/SystemCrafters/crafter-configs][SystemCrafters/crafter-configs]].
Fortunately, Emacs offers a way out of the above with input methods.
References:
- https://protesilaos.com/codelog/2023-12-12-emacs-multilingual-editing/ - A video by Prot from which I learned about this feature.
#+begin_src emacs-lisp
(setq default-input-method "russian-computer")
#+end_src
*** Other small packages
**** Managing parentheses (smartparens)
A minor mode to deal with pairs. Its functionality overlaps with evil-surround, but smartparens provides the most comfortable way to do stuff like automatically insert pairs.
@ -3970,6 +3985,124 @@ Source: https://emacs.stackexchange.com/questions/9807/org-mode-dont-change-rela
(org-link-set-parameters "rel" :follow #'browse-url :export #'my/export-rel-url))
#+end_src
** Keybindings & stuff
I've moved this block above because the =my-leader-def= expression in the next block seems to override the previous ones. So it has to be on the top.
*** General keybindings
#+begin_src emacs-lisp
(with-eval-after-load-norem 'org
(general-define-key
:keymaps 'org-mode-map
"C-c d" 'org-decrypt-entry
"C-c e" 'org-encrypt-entry
"M-p" 'org-latex-preview
"M-o" 'org-redisplay-inline-images)
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"L" 'org-shiftright
"H" 'org-shiftleft
"S-<next>" 'org-next-visible-heading
"S-<prior>" 'org-previous-visible-heading
"M-0" 'org-next-visible-heading
"M-9" 'org-previous-visible-heading
"M-]" 'org-babel-next-src-block
"M-[" 'org-babel-previous-src-block)
(general-define-key
:keymaps 'org-agenda-mode-map
"M-]" 'org-agenda-later
"M-[" 'org-agenda-earlier)
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c))
#+end_src
*** Copy a link
#+begin_src emacs-lisp
(defun my/org-link-copy (&optional arg)
"Extract URL from org-mode link and add it to kill ring."
(interactive "P")
(let* ((link (org-element-lineage (org-element-context) '(link) t))
(type (org-element-property :type link))
(url (org-element-property :path link))
(url (concat type ":" url)))
(kill-new url)
(message (concat "Copied URL: " url))))
(with-eval-after-load-norem 'org
(general-nmap :keymaps 'org-mode-map
"C-x C-l" 'my/org-link-copy))
#+end_src
*** Navigating source blocks
An idea born from discussing Org Mode navigation with @Infu.
Modifying =org-babel-next-src-block= and =org-babel-previous-src-block= to ignore hidden source blocks.
#+begin_src emacs-lisp
(defun my/org-babel-next-visible-src-block (arg)
"Move to the next visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(let ((regexp org-babel-src-block-regexp))
(if (< arg 0)
(beginning-of-line)
(end-of-line))
(while (and (< arg 0) (re-search-backward regexp nil :move))
(unless (bobp)
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-start o))
(re-search-backward regexp nil :move))
(_ nil))))
(cl-incf arg))
(while (and (> arg 0) (re-search-forward regexp nil t))
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-end o))
(re-search-forward regexp nil :move))
(_ (end-of-line) nil)))
(re-search-backward regexp nil :move)
(cl-decf arg))
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
(defun my/org-babel-previous-visible-src-block (arg)
"Move to the prevous visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(my/org-babel-next-visible-src-block (- arg)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"M-]" #'my/org-babel-next-visible-src-block
"M-[" #'my/org-babel-previous-visible-src-block))
#+end_src
*** Open a file from =org-directory=
A function to open a file from =org-directory=, excluding a few directories like =roam= and =journal=.
#+begin_src emacs-lisp
(defun my/org-file-open ()
(interactive)
(let* ((files
(thread-last
'("projects" "misc")
(mapcar (lambda (f)
(directory-files (concat org-directory "/" f) t (rx ".org" eos))))
(apply #'append)
(mapcar (lambda (file)
(string-replace (concat org-directory "/") "" file)))
(append
'("inbox.org" "contacts.org")))))
(find-file
(concat org-directory "/"
(completing-read "Org file: " files)))))
(my-leader-def
"o o" 'my/org-file-open)
#+end_src
** Literate programing
*** Python & Jupyter
Use jupyter kernels for Org Mode.
@ -4592,7 +4725,8 @@ It's been somewhat complicated to integrate into my workflow, but I think it's b
:straight (:host github :repo "SqrtMinusOne/org-clock-agg")
:commands (org-clock-agg)
:init
(my-leader-def "ol" #'org-clock-agg))
(with-eval-after-load 'org
(my-leader-def "ol" #'org-clock-agg)))
#+end_src
The following enables org-clock persistence between Emacs sessions.
@ -6336,7 +6470,7 @@ Add a custom LaTeX template without default packages. Packages are indented to b
#+end_src
**** Fix Russian dictionary
No idea why, but somehow the exported uses english words if there isn't =:default= key in the dictionary.
No idea why, but somehow the exported file uses english words if there isn't =:default= key in the dictionary.
#+begin_src emacs-lisp
(with-eval-after-load 'ox
@ -6351,122 +6485,6 @@ No idea why, but somehow the exported uses english words if there isn't =:defaul
else collect entry)))))
#+end_src
** Keybindings & stuff
*** General keybindings
#+begin_src emacs-lisp
(with-eval-after-load-norem 'org
(general-define-key
:keymaps 'org-mode-map
"C-c d" 'org-decrypt-entry
"C-c e" 'org-encrypt-entry
"M-p" 'org-latex-preview
"M-o" 'org-redisplay-inline-images)
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"L" 'org-shiftright
"H" 'org-shiftleft
"S-<next>" 'org-next-visible-heading
"S-<prior>" 'org-previous-visible-heading
"M-0" 'org-next-visible-heading
"M-9" 'org-previous-visible-heading
"M-]" 'org-babel-next-src-block
"M-[" 'org-babel-previous-src-block)
(general-define-key
:keymaps 'org-agenda-mode-map
"M-]" 'org-agenda-later
"M-[" 'org-agenda-earlier)
(general-nmap :keymaps 'org-mode-map "RET" 'org-ctrl-c-ctrl-c))
#+end_src
*** Copy a link
#+begin_src emacs-lisp
(defun my/org-link-copy (&optional arg)
"Extract URL from org-mode link and add it to kill ring."
(interactive "P")
(let* ((link (org-element-lineage (org-element-context) '(link) t))
(type (org-element-property :type link))
(url (org-element-property :path link))
(url (concat type ":" url)))
(kill-new url)
(message (concat "Copied URL: " url))))
(with-eval-after-load-norem 'org
(general-nmap :keymaps 'org-mode-map
"C-x C-l" 'my/org-link-copy))
#+end_src
*** Navigating source blocks
An idea born from discussing Org Mode navigation with @Infu.
Modifying =org-babel-next-src-block= and =org-babel-previous-src-block= to ignore hidden source blocks.
#+begin_src emacs-lisp
(defun my/org-babel-next-visible-src-block (arg)
"Move to the next visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(let ((regexp org-babel-src-block-regexp))
(if (< arg 0)
(beginning-of-line)
(end-of-line))
(while (and (< arg 0) (re-search-backward regexp nil :move))
(unless (bobp)
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-start o))
(re-search-backward regexp nil :move))
(_ nil))))
(cl-incf arg))
(while (and (> arg 0) (re-search-forward regexp nil t))
(while (pcase (get-char-property-and-overlay (point) 'invisible)
(`(outline . ,o)
(goto-char (overlay-end o))
(re-search-forward regexp nil :move))
(_ (end-of-line) nil)))
(re-search-backward regexp nil :move)
(cl-decf arg))
(if (> arg 0) (goto-char (point-max)) (beginning-of-line))))
(defun my/org-babel-previous-visible-src-block (arg)
"Move to the prevous visible source block.
With ARG, repeats or can move backward if negative."
(interactive "p")
(my/org-babel-next-visible-src-block (- arg)))
(with-eval-after-load 'org
(general-define-key
:keymaps 'org-mode-map
:states '(normal emacs)
"M-]" #'my/org-babel-next-visible-src-block
"M-[" #'my/org-babel-previous-visible-src-block))
#+end_src
*** Open a file from =org-directory=
A function to open a file from =org-directory=, excluding a few directories like =roam= and =journal=.
#+begin_src emacs-lisp
(defun my/org-file-open ()
(interactive)
(let* ((files
(thread-last
'("projects" "misc")
(mapcar (lambda (f)
(directory-files (concat org-directory "/" f) t (rx ".org" eos))))
(apply #'append)
(mapcar (lambda (file)
(string-replace (concat org-directory "/") "" file)))
(append
'("inbox.org" "contacts.org")))))
(find-file
(concat org-directory "/"
(completing-read "Org file: " files)))))
(my-leader-def
"o o" 'my/org-file-open)
#+end_src
** System configuration
Functions related to literate configuration.