aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emacs/.emacs.d/init/ycp-basic.el6
-rw-r--r--emacs/.emacs.d/init/ycp-emms.el2
-rw-r--r--emacs/.emacs.d/init/ycp-help.el3
-rw-r--r--emacs/.emacs.d/init/ycp-org.el2
m---------emacs/.emacs.d/lisp/exitter0
-rw-r--r--emacs/.emacs.d/lisp/my/belf.el92
-rw-r--r--emacs/.emacs.d/lisp/my/infobox.el15
-rw-r--r--emacs/.emacs.d/lisp/my/my-emms.el30
-rw-r--r--emacs/.emacs.d/lisp/my/my-github.el4
-rw-r--r--emacs/.emacs.d/lisp/my/my-gitlab.el10
-rw-r--r--emacs/.emacs.d/lisp/my/my-gnus.el2
-rw-r--r--emacs/.emacs.d/lisp/my/my-mariadb.el10
-rw-r--r--emacs/.emacs.d/lisp/my/my-package.el2
-rw-r--r--emacs/.emacs.d/lisp/my/my-prog.el13
-rw-r--r--emacs/.emacs.d/lisp/my/my-web.el30
15 files changed, 182 insertions, 39 deletions
diff --git a/emacs/.emacs.d/init/ycp-basic.el b/emacs/.emacs.d/init/ycp-basic.el
index 6baf1b8..cb097e7 100644
--- a/emacs/.emacs.d/init/ycp-basic.el
+++ b/emacs/.emacs.d/init/ycp-basic.el
@@ -27,6 +27,12 @@
;;; Code:
+;;; If started from systemd, emacs treats env variables inside env
+;;; variables as literal. e.g. if we have
+;;; Environment=PATH=$HOME/.local/bin:$HOME/bin
+;;; emacs will set exec-path to be literally
+;;; $HOME/.local/bin:$HOME/bin, without expanding $HOME.
+(setq exec-path (seq-map 'substitute-in-file-name exec-path))
(my-configure
(my-keybind global-map
diff --git a/emacs/.emacs.d/init/ycp-emms.el b/emacs/.emacs.d/init/ycp-emms.el
index 08c9d92..b2e8382 100644
--- a/emacs/.emacs.d/init/ycp-emms.el
+++ b/emacs/.emacs.d/init/ycp-emms.el
@@ -81,7 +81,7 @@
"C-<return>" #'my-emms-playlist-mode-make-current
"w" #'my-emms-playlist-kill-track-name-at-point
"D" #'my-emms-playlist-delete-at-point
- "R" #'my-emms-random-album
+ "R" #'my-emms-playlist-random-album
"N" #'my-emms-next-track-or-random-album
)
(add-hook 'emms-player-started-hook 'my-emms-maybe-seek-to-last-played)
diff --git a/emacs/.emacs.d/init/ycp-help.el b/emacs/.emacs.d/init/ycp-help.el
index 5cbbed0..98fa58c 100644
--- a/emacs/.emacs.d/init/ycp-help.el
+++ b/emacs/.emacs.d/init/ycp-help.el
@@ -44,7 +44,8 @@
)
(my-package info
- ;; TODO consider using `Info-additional-directory-list' instead
+ ;; Can't `Info-additional-directory-list' - won't be used in
+ ;; `info-display-manual' somehow
(add-to-list 'Info-directory-list (locate-user-emacs-file "info")))
(my-keybind global-map
diff --git a/emacs/.emacs.d/init/ycp-org.el b/emacs/.emacs.d/init/ycp-org.el
index 6385a46..43ae6cb 100644
--- a/emacs/.emacs.d/init/ycp-org.el
+++ b/emacs/.emacs.d/init/ycp-org.el
@@ -450,7 +450,7 @@
;; org man links
(my-package ol-man
(:delay 30)
- (setq org-man-command 'woman))
+ (setq org-man-command 'man))
(my-package ol
(:delay 10)
diff --git a/emacs/.emacs.d/lisp/exitter b/emacs/.emacs.d/lisp/exitter
-Subproject 36551754f548954d83af723d227dc7d14fd57d6
+Subproject 7ccd8ff06b50008ad0602c6652caebd4c4674a6
diff --git a/emacs/.emacs.d/lisp/my/belf.el b/emacs/.emacs.d/lisp/my/belf.el
new file mode 100644
index 0000000..d9392c9
--- /dev/null
+++ b/emacs/.emacs.d/lisp/my/belf.el
@@ -0,0 +1,92 @@
+;;; belf.el -- Bookshelf, ebook library management -*- lexical-binding: t -*-
+
+;; Copyright (C) 2025 Free Software Foundation, Inc.
+
+;; Author: Yuchen Pei <id@ypei.org>
+;; Package-Requires: ((emacs "29.4"))
+
+;; This file is part of dotted.
+
+;; dotted is free software: you can redistribute it and/or modify it under
+;; the terms of the GNU Affero General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; dotted 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 Affero General
+;; Public License for more details.
+
+;; You should have received a copy of the GNU Affero General Public
+;; License along with dotted. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Bookshelf, ebook library management.
+
+;;; Code:
+
+(require 'tabulated-list)
+(require 'infobox)
+
+(defvar-keymap belf-mode-map
+ :parent tabulated-list-mode-map
+ "i" #'belf-book-infobox
+ "RET" #'belf-open-book
+ "o" #'belf-open-book-other-window)
+
+(define-derived-mode belf-mode tabulated-list-mode "Bookshelf"
+ "Major mode for browsing a list of books."
+ (setq tabulated-list-format
+ [("Authors" 25 t)
+ ("Title" 48 t)
+ ("Year" 4 t)])
+ (setq tabulated-list-padding 2)
+ (tabulated-list-init-header)
+ (setq revert-buffer-function #'belf-list-refresh-contents)
+ (hl-line-mode))
+
+(defun belf-list-books ()
+ (interactive)
+ (let ((buf (get-buffer-create "*Bookshelf*")))
+ (with-current-buffer buf
+ (belf-mode)
+ (belf-list-refresh-contents)
+ (tabulated-list-print))
+ (pop-to-buffer-same-window buf)))
+
+(defun belf-list-refresh-contents (&rest _)
+ (setq-local tabulated-list-entries (belf-parse-all-file-names)))
+
+(defvar belf-dir "~/Documents" "Directory of books.")
+
+(defun belf-parse-all-file-names ()
+ (seq-filter
+ #'identity
+ (seq-map
+ (lambda (f)
+ (when-let ((parsed (belf-parse-file-name f)))
+ (let-alist parsed
+ (list f (vector .authors .title .year)))))
+ (directory-files belf-dir t))))
+
+(defun belf-parse-file-name (file-name)
+ (let ((base (file-name-base file-name)))
+ (when (string-match "^\\(.*?\\) - \\(.*\\) (\\([0-9]*\\))" base)
+ `((authors . ,(match-string 1 base))
+ (title . ,(match-string 2 base))
+ (year . ,(match-string 3 base))))))
+
+(defun belf-book-infobox ()
+ (interactive)
+ (infobox-exiftool (tabulated-list-get-id)))
+
+(defun belf-open-book ()
+ (interactive)
+ (find-file (tabulated-list-get-id)))
+
+(defun belf-open-book-other-window ()
+ (interactive)
+ (find-file-other-window (tabulated-list-get-id)))
+
+(provide 'belf)
diff --git a/emacs/.emacs.d/lisp/my/infobox.el b/emacs/.emacs.d/lisp/my/infobox.el
index 036cee8..9c5c7b1 100644
--- a/emacs/.emacs.d/lisp/my/infobox.el
+++ b/emacs/.emacs.d/lisp/my/infobox.el
@@ -63,6 +63,17 @@ something like
(with-help-window "*infobox*"
(with-current-buffer standard-output
(let ((n-rows 0))
+ ;; TODO: use a more standard function than
+ ;; `my-make-filename-from-url'
+ (when-let* ((thumb-url (alist-get "Thumbnail" info nil nil 'equal))
+ (file-name (file-name-concat
+ "/tmp"
+ (my-make-filename-from-url thumb-url))))
+ (url-copy-file (message thumb-url) file-name t)
+ (insert-image (create-image file-name nil nil
+ :max-width (window-width nil t)))
+ (insert "\n")
+ (setq n-rows (1+ n-rows)))
(seq-do
(lambda (pair)
(when pair
@@ -102,8 +113,8 @@ something like
(end-of-line)
(insert " -- " (buttonize
"xdg-open"
- (lambda (_)
- (call-process "xdg-open" nil 0 nil filename))))
+ (lambda (_) (call-process "xdg-open" nil 0 nil filename)))
+ " " (buttonize "find-file" (lambda (_) (find-file filename))))
(buffer-string))
`(infobox-exiftool ,filename)
(called-interactively-p 'interactive)
diff --git a/emacs/.emacs.d/lisp/my/my-emms.el b/emacs/.emacs.d/lisp/my/my-emms.el
index e6fb0e2..cdbe57a 100644
--- a/emacs/.emacs.d/lisp/my/my-emms.el
+++ b/emacs/.emacs.d/lisp/my/my-emms.el
@@ -374,17 +374,20 @@ artist/album/track."
my-emms-favourites-playlist)))
;;; random album in emms
-(defun my-my-emms-current-album-name ()
+(defun my-emms-current-album-name ()
(file-name-directory (my-emms-get-current-track-name)))
+(defun my-emms-playlist-album-name-at-point ()
+ (file-name-directory (emms-track-get (emms-playlist-track-at) 'name)))
+
(defun my-emms-next-track-or-random-album ()
(interactive)
- (let ((current-album (my-my-emms-current-album-name)))
+ (let ((current-album (my-emms-current-album-name)))
(when emms-player-playing-p (emms-stop))
(emms-playlist-current-select-next)
- (if (string-equal (my-my-emms-current-album-name) current-album)
+ (if (string-equal (my-emms-current-album-name) current-album)
(emms-start)
- (my-emms-random-album nil))))
+ (my-emms-playlist-random-album))))
(defvar-local my-emms-albums-cache (vector))
@@ -415,20 +418,15 @@ under /zzz-seren/."
(elt my-emms-albums-cache (random (length my-emms-albums-cache)))))
album))
-(defun my-emms-random-album (update-album)
- (interactive "P")
+(defun my-emms-playlist-random-album ()
+ (interactive)
(with-current-emms-playlist
- (when (or update-album (length= my-emms-albums-cache 0))
- (my-emms-save-albums-cache))
- (when emms-player-playing-p (emms-stop))
- (let ((saved-position (point)))
+ (goto-line (1+ (random (count-lines (point-min) (point-max)))))
+ (let ((album-name (my-emms-playlist-album-name-at-point)))
(goto-char (point-min))
- (if (search-forward
- (my-emms-get-random-album)
- nil t)
- (emms-playlist-mode-play-current-track)
- (goto-char saved-position)
- (error "Cannot play random album")))))
+ (search-forward album-name)
+ (beginning-of-line)
+ (emms-playlist-mode-play-current-track))))
;;; override the minor mode
;;;###autoload
diff --git a/emacs/.emacs.d/lisp/my/my-github.el b/emacs/.emacs.d/lisp/my/my-github.el
index 7caff57..e2d5f6a 100644
--- a/emacs/.emacs.d/lisp/my/my-github.el
+++ b/emacs/.emacs.d/lisp/my/my-github.el
@@ -25,7 +25,7 @@
;; Github client.
;;; Code:
-
+(require 'my-web)
(defun my-grok-github (url)
"get github info of a project.
@@ -93,7 +93,7 @@ License; name; description; homepage; created at"
)
(defvar my-github-project-info-specs
- `((html_url . "Clone")
+ `((html_url . ("URL" . my-forge-infobox-format-url))
(full_name . "Name")
(description . "Description")
(created_at . ("Created at" . my-gitlab-format-time-string))
diff --git a/emacs/.emacs.d/lisp/my/my-gitlab.el b/emacs/.emacs.d/lisp/my/my-gitlab.el
index 27f3344..56542c0 100644
--- a/emacs/.emacs.d/lisp/my/my-gitlab.el
+++ b/emacs/.emacs.d/lisp/my/my-gitlab.el
@@ -75,17 +75,9 @@
(require 'my-buffer)
(require 'my-web)
(require 'my-magit)
-(defun my-gitlab-format-url (url)
- (concat url
- " -- " (buttonize "clone"
- (lambda (_)
- (my-magit-clone url current-prefix-arg)))
- " " (buttonize "context"
- (lambda (_)
- (funcall my-url-context-function url)))))
(defvar my-gitlab-project-info-specs
- `((http_url_to_repo . ("URL" . my-gitlab-format-url))
+ `((http_url_to_repo . ("URL" . my-forge-infobox-format-url))
(name_with_namespace . "Name")
(description . "Description")
(created_at . ("Created at" . my-gitlab-format-time-string))
diff --git a/emacs/.emacs.d/lisp/my/my-gnus.el b/emacs/.emacs.d/lisp/my/my-gnus.el
index 14dff82..6a2142b 100644
--- a/emacs/.emacs.d/lisp/my/my-gnus.el
+++ b/emacs/.emacs.d/lisp/my/my-gnus.el
@@ -162,7 +162,7 @@ The archiving target comes from `my-gnus-group-alist'."
"The default inbox to be opened with `my-gnus-open-inbox'.")
(defun my-gnus-open-inbox ()
(interactive)
- (gnus-group-read-group t t my-gnus-inbox-group))
+ (gnus-group-read-group 200 t my-gnus-inbox-group))
(defun my-gnus-start ()
(interactive)
diff --git a/emacs/.emacs.d/lisp/my/my-mariadb.el b/emacs/.emacs.d/lisp/my/my-mariadb.el
index d790944..d6c2463 100644
--- a/emacs/.emacs.d/lisp/my/my-mariadb.el
+++ b/emacs/.emacs.d/lisp/my/my-mariadb.el
@@ -33,7 +33,9 @@
(interactive)
(if (equal (file-name-extension (buffer-file-name))
"test")
- (call-interactively 'project-compile)
+ (progn
+ (my-mtr-set-compile-command)
+ (call-interactively 'compile))
(sql-send-buffer)))
(defun my-gdb-maria ()
@@ -311,7 +313,11 @@ switches to the buffer."
(match-string 3 buffer-file-name))))))
(setq-local
compile-command
- (format "%smysql-test/mtr %s" build-dir test-name)))))
+ (format "%s %s %s %s"
+ "taskset -c 0-3"
+ (file-name-concat build-dir "mysql-test/mtr")
+ test-name
+ "--rr")))))
(provide 'my-mariadb)
;;; my-mariadb.el ends here
diff --git a/emacs/.emacs.d/lisp/my/my-package.el b/emacs/.emacs.d/lisp/my/my-package.el
index 9eefa2e..ab3ad77 100644
--- a/emacs/.emacs.d/lisp/my/my-package.el
+++ b/emacs/.emacs.d/lisp/my/my-package.el
@@ -274,7 +274,7 @@ same name, cancel that one first."
(add-hook hook function)))
(defvar my-common-packages
- '(package windmove consult icomplete isearch
+ '(package windmove consult corfu icomplete isearch paredit
my-utils my-buffer my-editing my-complete)
"Common packages to include with any profile")
diff --git a/emacs/.emacs.d/lisp/my/my-prog.el b/emacs/.emacs.d/lisp/my/my-prog.el
index faf20b6..92fcf21 100644
--- a/emacs/.emacs.d/lisp/my/my-prog.el
+++ b/emacs/.emacs.d/lisp/my/my-prog.el
@@ -442,6 +442,11 @@ overlay arrow in source buffer."
;; (accept-process-output (get-buffer-process gud-comint-buffer) .1)))
;; (gud-gdb-completions-1 gud-gdb-fetched-lines)))
+(defun my-gud-watch-expr (expr)
+ (with-current-buffer gud-comint-buffer
+ (insert "watch -l " expr)
+ (comint-send-input)))
+
(defun my-gud-print-expr (expr)
(with-current-buffer gud-comint-buffer
(insert "p " expr)
@@ -449,9 +454,11 @@ overlay arrow in source buffer."
(defun my-gud-print-expr-region (b e)
(interactive "r")
- (if (eq (gdb-get-source-buffer) (current-buffer))
- (my-gud-print-expr (buffer-substring b e))
- (error "Not in the source buffer")))
+ (unless (eq (gdb-get-source-buffer) (current-buffer))
+ (error "Not in the source buffer"))
+ (if current-prefix-arg
+ (my-gud-watch-expr (buffer-substring b e))
+ (my-gud-print-expr (buffer-substring b e))))
;;; which-func
(defun my-copy-which-func ()
diff --git a/emacs/.emacs.d/lisp/my/my-web.el b/emacs/.emacs.d/lisp/my/my-web.el
index aeb5a6d..21b227d 100644
--- a/emacs/.emacs.d/lisp/my/my-web.el
+++ b/emacs/.emacs.d/lisp/my/my-web.el
@@ -202,5 +202,35 @@ https://emacs.stackexchange.com/questions/40887/in-org-mode-how-do-i-link-to-int
(setq files (delq var files)))))
(apply orig-fun files client args))
+(defvar my-firefox-profile-dir nil "Firefox profile dir")
+(defvar my-firefox-place-limit 1000 "Firefox urls result limit")
+
+(defun my-firefox-places (&optional query)
+ (let ((where
+ (mapconcat
+ (lambda (word) (format "(url LIKE '%%%s%%' OR title LIKE '%%%s%%')" word word))
+ (split-string (or query ""))
+ " AND ")))
+ (unless (string-empty-p where) (setq where (format "WHERE %s" where)))
+ (with-temp-buffer
+ (call-process "sqlite3" nil t nil
+ (format "file://%s/places.sqlite?immutable=1"
+ my-firefox-profile-dir)
+ (format
+ "SELECT url,title FROM moz_places %s ORDER BY visit_count desc limit %d"
+ where
+ my-firefox-place-limit))
+ (buffer-string)
+ )))
+
+(defun my-forge-infobox-format-url (url)
+ (concat url
+ " -- " (buttonize "clone"
+ (lambda (_)
+ (my-magit-clone url current-prefix-arg)))
+ " " (buttonize "context"
+ (lambda (_)
+ (funcall my-url-context-function url)))))
+
(provide 'my-web)
;;; my-web.el ends here