Last active
April 14, 2025 19:46
-
-
Save podhmo/ff90c6735f979c0a1e27e0b7b76f89da to your computer and use it in GitHub Desktop.
widgetパッケージを使ってみたい
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require 'widget) | |
(eval-when-compile (require 'wid-edit)) | |
(defvar-keymap my:widget-field-keymap | |
:parent widget-field-keymap | |
:doc "個人的な拡張をしたwidget-keymap" | |
"C-c C-n" #'widget-forward | |
"C-c C-p" #'widget-backward | |
;; "q" #'kill-buffer | |
"RET" #'newline | |
"C-c n" #'my:widget-add-node | |
"C-c d" #'my:widget-remove-node | |
) | |
(setq my:node-list | |
`( | |
((:tag . "memo\n") (:value . "ここに\nメモを入力")) | |
((:tag . "memo2\n") (:value . "ここにメモを入力")) | |
)) | |
(defvar my:widget-example-buffer-name "*Widget Example*") | |
(defun my:widget-example (&optional node-list) | |
(interactive "P") | |
(setq node-list (or node-list my:node-list)) | |
(let ((buf (get-buffer-create my:widget-example-buffer-name))) | |
(pop-to-buffer buf '(display-buffer-in-side-window (side . right) (window-width . 60))) | |
(with-current-buffer buf | |
(kill-all-local-variables) | |
(let ((inhibit-read-only t)) | |
(delete-all-overlays buf) | |
(erase-buffer)) | |
(widget-insert "* example *\n\tTabとS-Tabで移動\n\n") | |
(dolist (node node-list) | |
(widget-create 'group | |
:indent 2 | |
`(text | |
:tag ,(assoc-default :tag node) | |
:value ,(assoc-default :value node) | |
:keymap my:widget-field-keymap) | |
)) | |
(use-local-map my:widget-field-keymap) | |
(widget-setup) | |
(widget-move 1)))) | |
(defun my:widget-add-node () | |
(interactive) | |
(save-excursion | |
;; widgetの範囲外に行く | |
(goto-char (+ 1 (next-overlay-change (point)))) | |
(let ((inhibit-read-only t)) | |
(widget-create 'group | |
:indent 2 | |
`(text | |
:tag "new*\n" | |
:value "<new value>" | |
:keymap my:widget-field-keymap) | |
) | |
(widget-setup))) | |
(widget-move 1)) | |
(defun my:widget-remove-node () | |
(interactive) | |
(let* ((w (widget-at (point))) | |
(p (widget-get w :parent))) ; group | |
(widget-delete (and p w)) | |
(widget-setup) | |
(widget-move 1))) | |
;; serialize/deseriaize | |
(defun my:widget-example-to-string () | |
(with-current-buffer (get-buffer-create my:widget-example-buffer-name) | |
(save-excursion | |
(let ((prev (point-min)) | |
(buf nil)) | |
(goto-char (point-min)) | |
(while (<= prev (progn (widget-move 1 t) (point))) ; widget-moveは終端に達したら開始地点に戻るので無限ループはしない | |
(push (widget-value (widget-at (point))) buf) | |
(setq prev (point))) | |
(mapconcat #'identity (nreverse buf) "\n\n---\n\n"))))) | |
(defun my:widget-example-to-clipboard () | |
(interactive) | |
(kill-new (my:widget-example-to-string))) | |
(defun my:widget-example-from-string (text) | |
(let ((node-list | |
(mapcar (lambda (section) `((:tag . "memo\n") (:value . ,section))) | |
(split-string text "\n\n---\n\n" t)))) | |
(my:widget-example node-list))) | |
(defun my:widget-example-from-clipboard () | |
(interactive) | |
(my:widget-example-from-string | |
(with-temp-buffer | |
(yank) | |
(buffer-substring-no-properties (point-min) (point-max))))) | |
なぜか自分の環境ではまっさらな環境とは異なり widget-field
の が目立たなくなっていた。 M-x customize-face
とかで雑に変えた。
(custom-set-faces
;; custom-set-faces was added by Custom.
;; If you edit it by hand, you could mess it up, so be careful.
;; Your init file should contain only one such instance.
;; If there is more than one, they won't work right.
'(tab-bar-tab-inactive ((t (:strike-through t :inherit modus-themes-tab-inactive))))
'(widget-field ((t (:extend nil :background "dim gray" :foreground "#ffffff")))))
https://www.gnu.org/software/emacs/manual/html_mono/widget.html#Programming-Example
このページのコードから始めたせいで定義した関数の名前が全部my:widgetでまるし、my:widget-exampleという名前のまま進めてしまった。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tab, S-Tabなどで上下に行ったり来たりできる。
x/twitterのthreadみたいな感じでtext widgetを繋げて出来るelispのメモ