25 files changed, 6 insertions(+), 1528 deletions(-)
M .gitignore
D bookmarks
D org-persist/16/5cfccc-d7c6-455f-99ed-1f1e310ed979
D org-persist/45/157a60-e5f5-4934-b910-fbea6feaf957
D org-persist/46/f0a523-6bb4-42d2-9cce-c2f6cb599174
D org-persist/b7/50fb89-4df4-4ea9-9074-48e231c0539a
D org-persist/bc/ac81bc-baa3-41b3-b765-7409b4e5da0c
D org-persist/c9/858381-8a0c-49af-8505-a771820bc7e2
D org-persist/cd/61aad8-4e7e-4374-bfac-042337d84922
D org-persist/fc/b2fb90-123c-4849-b13f-d499ba489b3a
D org-persist/gc-lock.eld
D org-persist/index.eld
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!bookmarks~
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!init.el~
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!mastodon.plstore~
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!snippets!org-mode!hugo-blog-monthly~
D saves/!drive_d!Org!inbox.org~
D saves/!drive_d!Org!notes!projects.org~
D saves/!drive_d!Org!notes!reading.org~
D saves/!drive_d!Org!personal.org~
D saves/!drive_d!Org!reading.org~
D saves/!drive_d!Org!shopping.org~
D saves/!drive_d!Org!tech.org~
D saves/#d!!Org!inbox.org#
D saves/#d!!Org!tech.org#
M .gitignore => .gitignore +6 -0
@@ 2,3 2,9 @@
.org-path
mastodon.plstore
auto-save-list/
+
+org-persist/
+
+saves/
+
+bookmarks
D bookmarks => bookmarks +0 -17
@@ 1,17 0,0 @@
-;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8-emacs; mode: lisp-data -*-
-;;; This format is meant to be slightly human-readable;
-;;; nevertheless, you probably don't want to edit it.
-;;; -*- End Of Bookmark File Format Version Stamp -*-
-(("org-refile-last-stored"
- (filename . "d:/Org/reading.org")
- (front-context-string . "** 世界没有你的时候也会继续运")
- (rear-context-string . "1-05 Mon 12:08]\n")
- (position . 2927)
- (last-modified 26974 2343 828742 0))
-("org-capture-last-stored"
- (filename . "d:/Org/notes/reading.org")
- (front-context-string . "** 找到两个数的最大公约数\n如")
- (rear-context-string . "1-05 Mon 12:08]\n")
- (position . 1654)
- (last-modified 26973 27640 735114 0))
-)
D org-persist/16/5cfccc-d7c6-455f-99ed-1f1e310ed979 => org-persist/16/5cfccc-d7c6-455f-99ed-1f1e310ed979 +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [[[nil nil #9=(headline (:standard-properties [16 16 nil nil 30 0 #2=(:title) nil element t nil nil nil 1 nil #3=[org-element-deferred org-element--headline-deferred nil t] nil #4=(org-data (:standard-properties [1 1 1 219 219 0 nil org-data nil t nil 3 219 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Org/tech.org"))] :pre-blank 0 :raw-value #1=[org-element-deferred org-element--headline-parse-title (t) t] :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#)) 0] [nil nil #7=(headline (:standard-properties [49 49 183 208 208 0 #2# section element t nil 185 208 2 nil #3# nil #5=(headline (:standard-properties [38 38 49 208 208 0 #2# nil element t nil 51 208 1 nil #3# nil #4#] :pre-blank 0 :raw-value #1# :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 133) t] :title [org-element-deferred org-element-property-2 (:raw-value) nil] :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p [org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp [org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil)) 0] #5# 0] nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[nil nil #4# 0] [nil nil (keyword (:standard-properties [1 1 nil nil 16 1 nil top-comment element t nil nil nil nil nil nil nil #6=(section (:standard-properties [1 1 1 16 16 0 nil first-section element t nil 1 16 nil nil nil nil #4#]))] :key "TITLE" :value "Tech")) 0] #6# 0] [[nil nil #5# 0] [nil [nil nil (paragraph (:standard-properties [183 183 183 208 208 0 nil planning element t nil nil nil nil nil nil nil #8=(section (:standard-properties [183 183 183 208 208 0 nil section element t nil 183 208 nil nil nil nil #7#]))])) 0] #8# 1] #7# 1] #9# 1] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/45/157a60-e5f5-4934-b910-fbea6feaf957 => org-persist/45/157a60-e5f5-4934-b910-fbea6feaf957 +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [[[nil nil #9=(headline (:standard-properties [60 60 69 90 90 0 (:title) nil element t nil 71 90 1 nil [org-element-deferred org-element--headline-deferred nil t] nil #1=(org-data (:standard-properties [1 1 1 197 197 0 nil org-data nil t nil 3 197 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Org/inbox.org" :fragile-cache nil))] :pre-blank 1 :raw-value [org-element-deferred org-element--headline-raw-value (2 7) t] :title [org-element-deferred org-element-property-2 (:raw-value) nil] :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p [org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp [org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil)) 0] [[nil nil #13=(headline (:standard-properties [114 114 131 153 153 0 #2=(:title) nil element t nil 133 153 1 nil #3=[org-element-deferred org-element--headline-deferred nil t] nil #1#] :pre-blank 1 :raw-value [org-element-deferred org-element--headline-raw-value (2 15) t] :title #4=[org-element-deferred org-element-property-2 (:raw-value) nil] :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5=[org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp #6=[org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil)) 0] [nil nil #16=(headline (:standard-properties [181 181 nil nil 197 0 #2# nil element t nil nil nil 1 nil #3# nil #1#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 15) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] #14=(headline (:standard-properties [153 153 170 181 181 0 #2# nil element t nil 172 181 1 nil #3# nil #1#] :pre-blank 1 :raw-value [org-element-deferred org-element--headline-raw-value (2 15) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] #11=(headline (:standard-properties [90 90 99 114 114 0 #2# nil nil t nil 101 114 1 nil #3# nil #1#] :pre-blank 1 :raw-value #7=[org-element-deferred org-element--headline-parse-title (t) t] :title #7# :level #7# :priority #7# :tags #7# :todo-keyword #7# :todo-type #7# :footnote-section-p #7# :archivedp #7# :commentedp #7#)) 1] nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[[nil nil #1# 0] [nil nil (keyword (:standard-properties [1 1 nil nil 20 0 nil top-comment element t nil nil nil nil nil nil nil #8=(section (:standard-properties [1 1 1 60 60 0 nil first-section element t nil 1 60 nil nil nil nil #1#]))] :key "TITLE" :value "GTD Inbox")) 0] #8# 0] [nil nil (keyword (:standard-properties [39 39 nil nil 60 1 nil nil element t nil nil nil nil nil nil nil #8#] :key "STARTUP" :value "overview")) 0] (keyword (:standard-properties [20 20 nil nil 39 0 nil nil element t nil nil nil nil nil nil nil #8#] :key "DATE" :value "2026-01-04")) -1] [[[[nil nil #10=(section (:standard-properties [69 69 69 90 90 0 nil section element t nil 69 90 nil nil nil nil #9#])) 0] nil (paragraph (:standard-properties [69 69 69 90 90 0 nil planning element t nil nil nil nil nil nil nil #10#])) -1] [[nil nil #12=(section (:standard-properties [99 99 99 114 114 0 nil section element t nil 99 114 nil nil nil nil #11#])) 0] nil (paragraph (:standard-properties [99 99 99 114 114 0 nil planning element t nil nil nil nil nil nil nil #12#])) -1] #11# 0] [[[nil nil #15=(section (:standard-properties [131 131 131 153 153 0 nil section element t nil 131 153 nil nil nil nil #13#])) 0] [nil nil #14# 0] (paragraph (:standard-properties [131 131 131 153 153 0 nil planning element t nil nil nil nil nil nil nil #15#])) 0] [nil [nil nil #16# 0] (paragraph (:standard-properties [170 170 170 181 181 0 nil planning element t nil nil nil nil nil nil nil #17=(section (:standard-properties [170 170 170 181 181 0 nil section element t nil 170 181 nil nil nil nil #14#]))])) 1] #17# 0] #13# 0] #9# 1] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/46/f0a523-6bb4-42d2-9cce-c2f6cb599174 => org-persist/46/f0a523-6bb4-42d2-9cce-c2f6cb599174 +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [nil nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[nil nil #1=(org-data (:standard-properties [1 1 1 124 124 0 nil org-data nil t nil 3 124 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Programs/blog/blog-local/org-drafts/test-post.org")) 0] [[nil nil (keyword (:standard-properties [1 1 nil nil 41 0 nil top-comment element t nil nil nil nil nil nil nil #2=(section (:standard-properties [1 1 1 117 117 0 nil first-section element t nil 1 117 nil nil nil nil #1#]))] :key "TITLE" :value "测试 Emacs & Org.mode 对接 Hexo 框架")) 0] [nil nil (keyword (:standard-properties [60 60 nil nil 93 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "FILETAGS" :value ":hexo:emacs:org.mode")) 0] (keyword (:standard-properties [41 41 nil nil 60 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "DATE" :value "2026-01-03")) 0] #2# 1] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/b7/50fb89-4df4-4ea9-9074-48e231c0539a => org-persist/b7/50fb89-4df4-4ea9-9074-48e231c0539a +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [[[nil nil #4=(headline (:standard-properties [20 20 37 275 275 0 #2=(:title) nil nil t nil 39 275 1 nil #3=[org-element-deferred org-element--headline-deferred nil t] nil #5=(org-data (:standard-properties [1 1 1 297 297 0 nil org-data nil t nil 3 297 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Org/shopping.org" :fragile-cache nil))] :pre-blank 0 :raw-value #1=[org-element-deferred org-element--headline-parse-title (t) t] :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#)) 0] [nil [nil nil #15=(headline (:standard-properties [224 224 264 275 275 0 #2# nil element t nil 266 275 2 nil #3# nil #4#] :pre-blank 0 :raw-value #1# :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#)) 0] #9=(headline (:standard-properties [150 150 190 224 224 0 #2# nil element t nil 192 224 2 nil #3# nil #4#] :pre-blank 0 :raw-value #1# :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#)) 1] #7=(headline (:standard-properties [37 37 104 150 150 0 #2# nil nil t nil 106 150 2 nil #3# nil #4#] :pre-blank 0 :raw-value #1# :title #1# :level #1# :priority #1# :tags #1# :todo-keyword #1# :todo-type #1# :footnote-section-p #1# :archivedp #1# :commentedp #1#)) 1] nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[[nil nil #5# 0] [nil nil (keyword (:standard-properties [1 1 nil nil 20 1 nil top-comment element t nil nil nil nil nil nil nil #6=(section (:standard-properties [1 1 1 20 20 0 nil first-section element t nil 1 20 nil nil nil nil #5#]))] :key "TITLE" :value "Shopping")) 0] #6# 0] [[nil nil #7# 0] [nil nil (paragraph (:standard-properties [104 104 104 150 150 0 nil planning element t nil nil nil nil nil nil nil #8=(section (:standard-properties [104 104 104 150 150 0 nil section element t nil 104 150 nil nil nil nil #7#]))])) 0] #8# 0] #4# 0] [[[nil nil #11=(section (:standard-properties [190 190 190 224 224 0 nil section element t nil 190 224 nil nil nil nil #9#])) 0] [nil nil (item (:standard-properties [190 190 198 201 201 0 #13=(:tag) item element t nil nil nil nil nil nil #10=((190 2 "- " nil "[ ]" nil 201) (201 2 "- " nil "[ ]" nil 212) (212 2 "- " nil "[ ]" nil 224)) #12=(plain-list (:standard-properties [190 190 190 224 224 0 nil planning element t nil nil nil nil nil nil #10# #11#] :type unordered))] :bullet #14="- " :checkbox off :counter nil :pre-blank 0 :tag nil)) 0] #12# 0] [[nil nil (item (:standard-properties [212 212 220 224 224 0 #13# item element t nil nil nil nil nil nil #10# #12#] :bullet #14# :checkbox off :counter nil :pre-blank 0 :tag nil)) 0] [nil [nil nil (plain-list (:standard-properties [264 264 264 275 275 0 nil planning element t nil nil nil nil nil nil ((264 2 "- " nil "[ ]" nil 275)) #16=(section (:standard-properties [264 264 264 275 275 0 nil section element t nil 264 275 nil nil nil nil #15#]))] :type unordered)) 0] #16# 1] #15# 1] (item (:standard-properties [201 201 209 212 212 0 #13# item element t nil nil nil nil nil nil #10# #12#] :bullet #14# :checkbox off :counter nil :pre-blank 0 :tag nil)) 1] #9# 1] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/bc/ac81bc-baa3-41b3-b765-7409b4e5da0c => org-persist/bc/ac81bc-baa3-41b3-b765-7409b4e5da0c +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [nil nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[[nil nil #1=(org-data (:standard-properties [1 1 1 604 604 0 nil org-data nil t nil 3 604 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Programs/blog/blog-local/scaffolds/post-zh.org" :fragile-cache nil)) 0] [nil nil (keyword (:standard-properties [1 1 nil nil 37 0 nil top-comment element t nil nil nil nil nil nil nil #2=(section (:standard-properties [1 1 1 604 604 0 nil first-section element t nil 1 604 nil nil nil nil #1#] :fragile-cache nil))] :key "TITLE" :value "将 Emacs + Org.mode 接入 Hexo")) 0] #2# 0] [[nil nil (keyword (:standard-properties [65 65 nil nil 76 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "LANG" :value "zh")) 0] [nil nil (keyword (:standard-properties [109 109 nil nil 128 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "CATEGORIES" :value "编程笔记")) 0] (keyword (:standard-properties [76 76 nil nil 109 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "FILETAGS" :value ":hexo:emacs:org.mode")) 0] (keyword (:standard-properties [37 37 nil nil 65 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "DATE" :value "2026-01-03 00:38:30")) 0] [[[nil nil (keyword (:standard-properties [141 141 nil nil 158 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "MATHJAX" :value "false")) 0] [nil nil (keyword (:standard-properties [173 173 nil nil 188 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "DESCRIPTION" :value #3="")) 0] (keyword (:standard-properties [158 158 nil nil 173 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "HIDDEN" :value "true")) 0] [nil nil (paragraph (:standard-properties [221 221 221 468 469 1 nil nil element t nil nil nil nil nil nil nil #2#])) 0] (keyword (:standard-properties [188 188 nil nil 221 1 nil nil element t nil nil nil nil nil nil nil #2#] :key "OPTIONS" :value "\\n:t toc:nil num:nil")) -1] (keyword (:standard-properties [128 128 nil nil 141 0 nil nil element t nil nil nil nil nil nil nil #2#] :key "ABBRLINK" :value #3#)) 0] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/c9/858381-8a0c-49af-8505-a771820bc7e2 => org-persist/c9/858381-8a0c-49af-8505-a771820bc7e2 +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [[[[nil nil #10=(headline (:standard-properties [55 55 63 137 137 0 #1=(:title) nil nil t nil 65 137 1 nil #2=[org-element-deferred org-element--headline-deferred nil t] nil #3=(org-data (:standard-properties [1 1 1 2934 2934 0 nil org-data nil t nil 3 2934 nil nil nil nil nil] :path "d:/Org/reading.org" :fragile-cache nil :CATEGORY "reading"))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 7) t] :title #4=[org-element-deferred org-element-property-2 (:raw-value) nil] :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5=[org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp #6=[org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil)) 0] [[nil nil #12=(headline (:standard-properties [145 145 160 1285 1285 0 #1# section element t nil 162 1285 2 nil #2# nil #7=(headline (:standard-properties [137 137 145 1285 1285 0 #1# nil element t nil 147 1285 1 nil #2# nil #3#] :pre-blank 1 :raw-value [org-element-deferred org-element--headline-raw-value (2 6) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 14) t] :title #4# :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] nil #18=(headline (:standard-properties [1285 1285 nil nil 1293 1 #1# nil element t nil nil nil 1 nil #2# nil #3#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 6) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) -1] #7# 1] [[nil nil #19=(headline (:standard-properties [1301 1301 1438 1547 1547 0 #1# nil nil t nil 1440 1547 2 nil #2# nil #8=(headline (:standard-properties [1293 1293 1301 2927 2927 0 #1# nil nil t nil 1303 2927 1 nil #2# nil #3#] :pre-blank 1 :raw-value [org-element-deferred org-element--headline-raw-value (2 6) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 136) t] :title #4# :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] [nil [nil nil #26=(headline (:standard-properties [2927 2927 nil nil 2934 0 #1# nil element t nil nil nil 1 nil #2# nil #3#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 6) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] #23=(headline (:standard-properties [2645 2645 2670 2927 2927 0 #1# nil element t nil 2672 2925 2 nil nil nil #8#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 24) t] :title #4# :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 1] #21=(headline (:standard-properties [1547 1547 1609 2645 2645 0 #1# nil nil t nil 1611 2645 2 nil #2# nil #8#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (3 61) t] :title #4# :level 2 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 1] #8# 0] nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[[[[nil nil #3# 0] [nil nil (keyword (:standard-properties [1 1 nil nil 15 0 nil top-comment element t nil nil nil nil nil nil nil #9=(section (:standard-properties [1 1 1 55 55 0 nil first-section element t nil 1 55 nil nil nil nil #3#]))] :key "TITLE" :value "阅读笔记")) 0] #9# 0] [nil nil (keyword (:standard-properties [34 34 nil nil 55 1 nil nil element t nil nil nil nil nil nil nil #9#] :key "STARTUP" :value "overview")) 0] (keyword (:standard-properties [15 15 nil nil 34 0 nil nil element t nil nil nil nil nil nil nil #9#] :key "DATE" :value "2026-01-04")) -1] [[nil nil #11=(section (:standard-properties [63 63 63 137 137 0 nil section element t nil 63 137 nil nil nil nil #10#])) 0] [nil nil (paragraph (:standard-properties [115 115 115 137 137 0 nil nil element t nil nil nil nil nil nil nil #11#])) 0] (property-drawer (:standard-properties [63 63 78 106 115 1 nil planning element t nil nil nil nil nil nil nil #11#])) 0] #10# -1] [[[[nil nil #12# 0] nil #13=(section (:standard-properties [160 160 160 1285 1285 0 nil section element t nil 160 1285 nil nil nil nil #12#])) -1] [[nil nil (src-block (:standard-properties [181 181 nil nil 292 0 nil nil element t nil nil nil nil nil nil nil #13#] :language "python" :switches nil :parameters nil :number-lines nil :preserve-indent nil :retain-labels t :use-labels t :label-fmt nil :value [org-element-deferred org-element--unescape-substring (19 101) t])) 0] nil (paragraph (:standard-properties [292 292 292 787 787 0 nil nil element t nil nil nil nil nil nil nil #13#])) -1] (paragraph (:standard-properties [160 160 160 181 181 0 nil planning element t nil nil nil nil nil nil nil #13#])) 0] [[nil nil (paragraph (:standard-properties [1021 1021 1021 1125 1125 0 nil nil element t nil nil nil nil nil nil nil #13#])) 0] nil #15=(plain-list (:standard-properties [1125 1125 1125 1285 1285 0 nil nil element t nil nil nil nil nil nil #14=((1125 0 "1. " nil nil nil 1156) (1156 0 "2. " nil nil nil 1189) (1189 0 "3. " nil nil nil 1285)) #13#] :type ordered)) -1] (src-block (:standard-properties [787 787 nil nil 1021 0 nil nil element t nil nil nil nil nil nil nil #13#] :language "java" :switches nil :parameters nil :number-lines nil :preserve-indent nil :retain-labels t :use-labels t :label-fmt nil :value [org-element-deferred org-element--unescape-substring (17 224) t])) -1] #7# 0] [[[[nil nil (item (:standard-properties [1156 1156 1159 1189 1189 0 #16=(:tag) item element t nil nil nil nil nil nil #14# #15#] :bullet "2. " :checkbox nil :counter nil :pre-blank 0 :tag nil)) 0] nil #17=(item (:standard-properties [1189 1189 1192 1285 1285 0 #16# item element t nil nil nil nil nil nil #14# #15#] :bullet "3. " :checkbox nil :counter nil :pre-blank 0 :tag nil)) -1] [[nil [nil nil (paragraph (:standard-properties [1260 1260 1260 1285 1285 0 nil nil element t nil nil nil nil nil nil nil #17#])) 0] (drawer (:standard-properties [1219 1219 1234 1252 1260 0 nil nil element t nil nil nil nil nil nil nil #17#] :drawer-name #25="PROPERTIES")) 1] [nil nil #8# 0] #18# -1] (paragraph (:standard-properties [1192 1192 1192 1218 1219 1 nil nil element t nil nil nil nil nil nil nil #17#])) 1] [[[[nil nil #20=(section (:standard-properties [1438 1438 1438 1547 1547 0 nil section element t nil 1438 1547 nil nil nil nil #19#])) 0] [nil nil (paragraph (:standard-properties [1522 1522 1522 1547 1547 0 nil nil element t nil nil nil nil nil nil nil #20#])) 0] (property-drawer (:standard-properties [1438 1438 1453 1514 1522 0 nil planning element t nil nil nil nil nil nil nil #20#])) 0] [[nil [nil nil (paragraph (:standard-properties [1609 1609 1609 2534 2534 0 nil planning element t nil nil nil nil nil nil nil #22=(section (:standard-properties [1609 1609 1609 2645 2645 0 nil section element t nil 1609 2645 nil nil nil nil #21#]))])) 0] #22# 1] [nil nil #24=(section (:standard-properties [2670 2670 2670 2927 2927 0 nil section element t nil 2670 2927 nil nil nil nil #23#])) 0] #23# -1] #21# 1] [[nil nil #27=(drawer (:standard-properties [2789 2789 2804 2894 2902 0 nil nil element t nil nil nil nil nil nil nil #24#] :drawer-name #25#)) 0] [nil [nil nil #26# 0] (paragraph (:standard-properties [2902 2902 2902 2927 2927 0 nil nil element t nil nil nil nil nil nil nil #24#])) 1] (paragraph (:standard-properties [2804 2804 2804 2894 2894 0 nil nil element t nil nil nil nil nil nil nil #27#])) 1] (paragraph (:standard-properties [2670 2670 2670 2789 2789 0 nil planning element t nil nil nil nil nil nil nil #24#])) -1] #19# 1] (item (:standard-properties [1125 1125 1128 1156 1156 0 #16# item element t nil nil nil nil nil nil #14# #15#] :bullet "1. " :checkbox nil :counter nil :pre-blank 0 :tag nil)) 1] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/cd/61aad8-4e7e-4374-bfac-042337d84922 => org-persist/cd/61aad8-4e7e-4374-bfac-042337d84922 +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((index "3.2") . "c:/Users/Cytrogen/AppData/Roaming/.emacs.d/org-persist/index.eld"))>
\ No newline at end of file
D org-persist/fc/b2fb90-123c-4849-b13f-d499ba489b3a => org-persist/fc/b2fb90-123c-4849-b13f-d499ba489b3a +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((elisp org-element--headline-cache) . #s(avl-tree- [[[nil nil #7=(headline (:standard-properties [20 20 nil nil 29 0 #1=(:title) nil element t nil nil nil 1 nil #2=[org-element-deferred org-element--headline-deferred nil t] nil #3=(org-data (:standard-properties [1 1 1 56 56 0 nil org-data nil t nil 3 56 nil nil [org-element-deferred org-element--get-global-node-properties nil t] nil nil] :path "d:/Org/personal.org"))] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 8) t] :title #4=[org-element-deferred org-element-property-2 (:raw-value) nil] :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5=[org-element-deferred org-element--headline-footnote-section-p nil nil] :archivedp #6=[org-element-deferred org-element--headline-archivedp nil nil] :commentedp nil)) 0] [nil [nil nil #8=(headline (:standard-properties [48 48 nil nil 56 0 #1# nil element t nil nil nil 1 nil #2# nil #3#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 7) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 0] #9=(headline (:standard-properties [39 39 nil nil 48 0 #1# nil element t nil nil nil 1 nil #2# nil #3#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 8) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 1] #10=(headline (:standard-properties [29 29 nil nil 39 0 #1# nil element t nil nil nil 1 nil #2# nil #3#] :pre-blank 0 :raw-value [org-element-deferred org-element--headline-raw-value (2 9) t] :title #4# :level 1 :priority nil :tags nil :todo-keyword nil :todo-type nil :footnote-section-p #5# :archivedp #6# :commentedp nil)) 1] nil nil 0] org-element--cache-compare)) ((elisp org-element--cache) . #s(avl-tree- [[[[nil nil #3# 0] [nil nil #7# 0] (section (:standard-properties [1 1 1 20 20 0 nil first-section element t nil 1 20 nil nil nil nil #3#])) 0] [nil [nil nil #8# 0] #9# 1] #10# 0] nil nil 0] org-element--cache-compare)) ((version "2.3")))>
\ No newline at end of file
D org-persist/gc-lock.eld => org-persist/gc-lock.eld +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-(((26971 60430 129674 0) 26973 8568 544429 0))>
\ No newline at end of file
D org-persist/index.eld => org-persist/index.eld +0 -2
@@ 1,2 0,0 @@
-;; -*- mode: lisp-data; -*-
-((:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "c9/858381-8a0c-49af-8505-a771820bc7e2" :associated (:hash "289a5b968ee27111af6c3f5ec8921358" :file "d:/Org/reading.org" :inode 8444249301604469) :expiry 30 :last-access 1767770328.823907 :last-access-hr "2026-01-07T02:18:48-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "fc/b2fb90-123c-4849-b13f-d499ba489b3a" :associated (:hash "8db4d80e65de12ae820115e8d528a759" :file "d:/Org/personal.org" :inode 1407374886699438) :expiry 30 :last-access 1767739881.859652 :last-access-hr "2026-01-06T17:51:21-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "b7/50fb89-4df4-4ea9-9074-48e231c0539a" :associated (:hash "23079ce53dba5afc3bb24db0df91311a" :file "d:/Org/shopping.org" :inode 54606145484068429) :expiry 30 :last-access 1767739881.846487 :last-access-hr "2026-01-06T17:51:21-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "16/5cfccc-d7c6-455f-99ed-1f1e310ed979" :associated (:hash "0eeee4074dec0c1e7278f821e464d923" :file "d:/Org/tech.org" :inode 35747322045399462) :expiry 30 :last-access 1767766893.861967 :last-access-hr "2026-01-07T01:21:33-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "45/157a60-e5f5-4934-b910-fbea6feaf957" :associated (:hash "c38f5e059b7c0dfcb4b2950428e1d379" :file "d:/Org/inbox.org" :inode 41095346599840470) :expiry 30 :last-access 1767766847.863775 :last-access-hr "2026-01-07T01:20:47-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "bc/ac81bc-baa3-41b3-b765-7409b4e5da0c" :associated (:hash "0afd7273fb233cc4e5889c7eb7e1e7e1" :file "d:/Programs/blog/blog-local/scaffolds/post-zh.org" :inode 20829148278818618) :expiry 30 :last-access 1767418015.494549 :last-access-hr "2026-01-03T00:26:55-0500") (:container ((elisp org-element--headline-cache) (elisp org-element--cache) (version "2.3")) :persist-file "46/f0a523-6bb4-42d2-9cce-c2f6cb599174" :associated (:hash "deb0afdca365fa892b9f481ca5b2ab23" :file "d:/Programs/blog/blog-local/org-drafts/test-post.org" :inode 1970324840096268) :expiry 30 :last-access 1767402078.04534 :last-access-hr "2026-01-02T20:01:18-0500") (:container ((index "3.2")) :persist-file "cd/61aad8-4e7e-4374-bfac-042337d84922" :associated nil :expiry never :last-access 1767395207.318254 :last-access-hr "2026-01-02T18:06:47-0500"))>
\ No newline at end of file
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!bookmarks~ => saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!bookmarks~ +0 -17
@@ 1,17 0,0 @@
-;;;; Emacs Bookmark Format Version 1;;;; -*- coding: utf-8-emacs; mode: lisp-data -*-
-;;; This format is meant to be slightly human-readable;
-;;; nevertheless, you probably don't want to edit it.
-;;; -*- End Of Bookmark File Format Version Stamp -*-
-(("org-refile-last-stored"
- (filename . "d:/Org/tech.org")
- (front-context-string . "** Emacs 的缓存机制,让")
- (rear-context-string . "ools\n* Learning\n")
- (position . 49)
- (last-modified 26973 64366 314531 0))
-("org-capture-last-stored"
- (filename . "d:/Org/notes/reading.org")
- (front-context-string . "** 找到两个数的最大公约数\n如")
- (rear-context-string . "1-05 Mon 12:08]\n")
- (position . 1654)
- (last-modified 26973 27640 735114 0))
-)
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!init.el~ => saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!init.el~ +0 -1125
@@ 1,1125 0,0 @@
-(set-language-environment "UTF-8")
-(prefer-coding-system 'utf-8-unix)
-(set-default-coding-systems 'utf-8-unix)
-(set-terminal-coding-system 'utf-8-unix)
-(set-keyboard-coding-system 'utf-8-unix)
-(set-selection-coding-system 'utf-8-unix)
-(set-file-name-coding-system 'utf-8-unix)
-(set-clipboard-coding-system 'utf-8-unix)
-(set-buffer-file-coding-system 'utf-8-unix)
-
-(if (eq system-type 'windows-nt)
- (setq file-name-coding-system 'gbk))
-
-;; Package Initialization
-
-(require 'package)
-(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
-(package-initialize)
-
-;; Theme Loading
-
-;; Fonts
-
-(defun my/setup-blog-fonts ()
- "Setup fonts with precise control over CJK, Punctuation, and Nerd Icons.
-Refactored to strictly separate Fixed Pitch (Code) and Variable Pitch (Writing) faces."
- (interactive)
- (require 'org)
-
- ;; =================================================================
- ;; 1.【核心修复】脚本劫持 (保持不变)
- ;; =================================================================
- (set-char-table-range char-script-table '(#x3000 . #x303F) 'han)
- (set-char-table-range char-script-table '(#xFF00 . #xFFEF) 'han)
- (set-char-table-range char-script-table '(#x2000 . #x206F) 'han)
-
- ;; =================================================================
- ;; 2. 基础字体 (Default Face) - Emacs 的基底
- ;; =================================================================
- ;; 英文/数字: 强制 JetBrains Mono
- (set-face-attribute 'default nil :font "JetBrains Mono-13")
-
- ;; 中文: 强制 Source Han Sans SC (思源黑体) 用于 UI 和基础对齐
- (set-fontset-font t 'han (font-spec :family "Source Han Sans SC"))
- (set-fontset-font t 'cjk-misc (font-spec :family "Source Han Sans SC"))
-
- ;; =================================================================
- ;; 3. 【关键修复】固定宽度字体 (Fixed Pitch)
- ;; =================================================================
- ;; 专门用于代码块、表格、属性栏。这能解决 "Georgia + Courier" 的问题。
- (set-face-attribute 'fixed-pitch nil :family "JetBrains Mono" :height 1.0)
-
- ;; 为 fixed-pitch 补充中文部分,保持表格对齐
- (let ((fixed-fontset (face-attribute 'fixed-pitch :fontset)))
- (when (eq fixed-fontset 'unspecified)
- (setq fixed-fontset (create-fontset-from-fontset-spec
- (font-xlfd-name (face-attribute 'default :font)))))
- (set-fontset-font fixed-fontset 'han (font-spec :family "Source Han Sans SC")))
-
- ;; =================================================================
- ;; 4. 变宽/阅读字体 (Variable Pitch) - 写作模式
- ;; =================================================================
- ;; 英文: 优先使用 Source Serif 4,如果没有则回退到 Georgia
- (let* ((en-serif-font (if (find-font (font-spec :family "Source Serif 4"))
- "Source Serif 4"
- "Georgia"))
- ;; 创建一个专属的 fontset,命名为 fontset-variable
- (v-fontset-name "fontset-variable")
- ;; 注意:create-fontset-from-fontset-spec 需要符合 XLFD 格式或特定的 fontset 描述
- ;; 这里我们更安全地基于标准 fontset 创建,或者直接定义它
- (v-fontset (create-fontset-from-fontset-spec
- (font-xlfd-name
- (font-spec :family en-serif-font
- :registry "fontset-variable")))))
-
- ;; 步骤 A: 设定 variable-pitch 面
- ;; 强制指定 slant 为 normal,防止英文也跟着变斜
- (set-face-attribute 'variable-pitch nil
- :family en-serif-font
- :height 1.1
- :weight 'regular
- :slant 'normal
- :fontset v-fontset-name)
-
- ;; 步骤 B: 针对您的系统环境精确配置中文
- ;; 您的列表显示字体名为 "思源宋体 CN",必须精确匹配这个字符串
- (let ((cjk-serif-name "思源宋体 CN"))
- (if (member cjk-serif-name (font-family-list))
- (progn
- ;; 针对汉字 (han)
- (set-fontset-font v-fontset-name 'han
- (font-spec :family cjk-serif-name
- :weight 'normal
- :slant 'normal)) ;; 关键:显式禁止倾斜
-
- ;; 针对中文标点 (#x3000 - #x303F)
- (set-fontset-font v-fontset-name '(#x3000 . #x303F)
- (font-spec :family cjk-serif-name
- :weight 'normal
- :slant 'normal)))
- (message "Warning: CJK Serif font '%s' not found. Fallback might occur." cjk-serif-name))))
-
- ;; =================================================================
- ;; 5. 标题字体 (Headings)
- ;; =================================================================
- (let ((heading-font-family "Open Sans")
- (heading-cjk-family "Noto Sans SC"))
- (when (find-font (font-spec :family heading-font-family))
- (dolist (face '(org-level-1 org-level-2 org-level-3 org-level-4
- org-level-5 org-level-6 org-level-7 org-level-8))
- (when (facep face)
- (set-face-attribute face nil :family heading-font-family :weight 'bold)
- ;; 确保标题中文使用黑体
- (when (find-font (font-spec :family heading-cjk-family))
- (let ((face-fontset (face-attribute face :fontset)))
- (when (eq face-fontset 'unspecified)
- ;; 如果 face 没有独立的 fontset,创建一个
- (setq face-fontset (create-fontset-from-fontset-spec
- (font-xlfd-name (face-attribute 'default :font)))))
- (set-fontset-font face-fontset 'han
- (font-spec :family heading-cjk-family :weight 'bold))))))))
-
- ;; =================================================================
- ;; 6. Org 界面元素微调
- ;; =================================================================
- ;; 让 Org 的代码块、元数据、表格、引用块强制继承 fixed-pitch
- (dolist (face '(org-block org-code org-table org-verbatim org-formula
- org-checkbox org-date org-priority org-special-keyword
- org-tag line-number))
- (when (facep face)
- (set-face-attribute face nil :inherit 'fixed-pitch)))
-
- ;; 特殊处理:Meta line (如 #+TITLE) 通常需要更淡的颜色,但也需要等宽
- (when (facep 'org-meta-line)
- (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch)))
-
- ;; =================================================================
- ;; 7. 【Nerd Icons 修复】强制映射私有使用区 (PUA)
- ;; =================================================================
- (let ((nerd-font (font-spec :family "Symbols Nerd Font Mono")))
- (when (find-font nerd-font)
- (set-fontset-font t '(#xE000 . #xF8FF) nerd-font nil 'prepend)))
-
- ;; =================================================================
- ;; 8. 【Emoji 修复】
- ;; =================================================================
- (when (eq system-type 'windows-nt)
- (let* ((emoji-candidates
- '("Segoe UI Emoji" "Symbola" "Noto Emoji" "Apple Color Emoji"))
- (primary-emoji-font (cl-find-if (lambda (f) (find-font (font-spec :family f))) emoji-candidates)))
- (if primary-emoji-font
- (progn
- (let ((font-spec (font-spec :family primary-emoji-font)))
- (set-fontset-font t 'emoji font-spec nil 'prepend)
- (set-fontset-font t '(#x1F000 . #x1FFFF) font-spec nil 'prepend)
- (set-fontset-font t '(#x2600 . #x27BF) font-spec nil 'prepend)))
- (message "Warning: No suitable Emoji font found."))))
-
- (message "Fonts setup: Default(JB Mono) | Writing(Source Serif 4/Georgia) | Fixed(JB Mono)"))
-
-(defun my/force-restore-fonts (&rest _args)
- (message "Theme changed, re-applying fonts...")
- (my/setup-blog-fonts))
-
-(advice-add 'load-theme :after #'my/force-restore-fonts)
-
-(add-to-list 'custom-theme-load-path "~/.emacs.d/themes/")
-(load-theme 'darcula t)
-
-;; Package Configs
-
-;; Ox-Hugo
-
-(unless (package-installed-p 'ox-hugo)
- (package-refresh-contents)
- (package-install 'ox-hugo))
-
-(with-eval-after-load 'ox
- (require 'ox-hugo)
- (setq org-hugo-content-folder "D:/Programs/Blog/Blog-local/source"))
-
-;; YASnippet
-
-(unless (package-installed-p 'yasnippet)
- (package-install 'yasnippet))
-
-(with-eval-after-load 'yasnippet
- (yas-global-mode 1)
- (yas-reload-all))
-
-;; Rainbow Delimiters
-
-(unless (package-installed-p 'rainbow-delimiters)
- (package-refresh-contents)
- (package-install 'rainbow-delimiters))
-
-(add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
-(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode)
-(add-hook 'lisp-interaction-mode-hook #'rainbow-delimiters-mode)
-
-;; Built-in Paren Highlighting
-
-(show-paren-mode 1)
-(electric-pair-mode 1)
-(setq show-paren-delay 0)
-(setq show-paren-style 'parenthesis)
-
-;; GPG Configuration (Fixed for Windows)
-
-(require 'cl-lib) ; 确保cl-some函数可用
-
-(defun my/setup-gpg ()
- "配置GPG,优先查找Windows常见安装路径。"
- (interactive)
- (require 'epa-file)
-
- ;; 1. 定义查找列表:优先找用户实际安装位置
- (let* ((candidates '("D:/GnuPG/bin/gpg.exe" ; 用户实际安装位置 (最高优先级)
- "C:/Program Files (x86)/GnuPG/bin/gpg.exe" ; Gpg4win 默认路径 (64位系统)
- "C:/Program Files/GnuPG/bin/gpg.exe" ; Gpg4win 备选路径
- "gpg")) ; 系统 PATH
- ;; 找到第一个存在的路径
- (found-gpg (cl-some (lambda (path)
- (if (string-match-p "/" path)
- (and (file-exists-p path) path)
- (executable-find path)))
- candidates)))
-
- (if found-gpg
- (progn
- ;; Add GPG path to exec-path for proper discovery
- (let ((gpg-dir (file-name-directory found-gpg)))
- (when (and gpg-dir (not (member gpg-dir exec-path)))
- (add-to-list 'exec-path gpg-dir)))
-
- ;; Use custom-set-variables for EPA configuration (StackOverflow solution)
- (custom-set-variables
- `(epg-gpg-program ,found-gpg)
- '(epa-pinentry-mode 'loopback)
- '(epg-debug t)
- `(epg-gpg-home-directory ,(or (getenv "GNUPGHOME")
- (expand-file-name "~/.gnupg")))
- '(epa-file-cache-passphrase-for-symmetric-encryption t)
- '(epa-file-select-keys 'silent)
- '(epa-file-encrypt-to nil)
- '(epa-armor t)
- '(epg-user-id nil))
-
- ;; Enable encrypted file support
- (require 'epa-file)
- (epa-file-enable)
-
- (message "GPG configured successfully. Path: %s" found-gpg))
-
- ;; GPG not found handling
- (message "Warning: GPG executable not found. Mastodon will not be able to save credentials securely.")
- (message "Please check if Gpg4win is installed and confirm the installation path."))))
-
-;; GPG密钥检测和创建函数
-(defun my/check-or-create-gpg-keys ()
- "检测GPG密钥,如果没有则提示创建。"
- (interactive)
- (when epg-gpg-program
- (condition-case err
- (let* ((context (epg-make-context))
- (keys (epg-list-keys context)))
- (if keys
- (progn
- (message "Found %d GPG keys" (length keys))
- (dolist (key keys)
- (let ((user-ids (epg-key-user-id-list key)))
- (when user-ids
- (message "Key: %s" (epg-user-id-string (car user-ids)))))))
- ;; 没有密钥,提供创建选项
- (when (yes-or-no-p "未找到GPG密钥,是否创建新密钥对? ")
- (my/create-gpg-keypair))))
- (error
- (message "Error checking GPG keys: %s" (error-message-string err))))))
-
-(defun my/create-gpg-keypair ()
- "创建新的GPG密钥对。"
- (interactive)
- (let* ((name (read-string "输入姓名: "))
- (email (read-string "输入邮箱: "))
- (passphrase (read-passwd "输入密码(可选,直接回车跳过): "))
- (batch-config (format "%%echo Generating GPG key
-Key-Type: RSA
-Key-Length: 2048
-Subkey-Type: RSA
-Subkey-Length: 2048
-Name-Real: %s
-Name-Email: %s
-%s
-Expire-Date: 0
-%%commit
-%%echo Done"
- name
- email
- (if (string-empty-p passphrase)
- "%no-protection"
- (format "Passphrase: %s" passphrase))))
- (temp-file (make-temp-file "gpg-batch" nil ".txt")))
-
- (with-temp-file temp-file
- (insert batch-config))
-
- (message "Creating GPG keypair, please wait...")
- (let ((result (shell-command (format "\"%s\" --batch --generate-key \"%s\""
- epg-gpg-program temp-file))))
- (delete-file temp-file)
- (if (= result 0)
- (progn
- (message "GPG keypair created successfully!")
- (my/check-or-create-gpg-keys))
- (message "Failed to create GPG keypair. Please check configuration")))))
-
-;; GPG配置文件检查和修复
-(defun my/check-gpg-config ()
- "检查和修复GPG配置文件。"
- (interactive)
- (let* ((gpg-home (or (getenv "GNUPGHOME")
- (expand-file-name "~/.gnupg")))
- (gpg-conf (expand-file-name "gpg.conf" gpg-home))
- (gpg-agent-conf (expand-file-name "gpg-agent.conf" gpg-home)))
-
- ;; 确保.gnupg目录存在
- (unless (file-directory-p gpg-home)
- (make-directory gpg-home t)
- (message "Created GPG home directory: %s" gpg-home))
-
- ;; 检查和创建gpg.conf
- (unless (file-exists-p gpg-conf)
- (with-temp-file gpg-conf
- (insert "# GPG配置文件\n")
- (insert "use-agent\n")
- (insert "armor\n")
- (insert "keyid-format long\n"))
- (message "Created gpg.conf configuration file"))
-
- ;; 检查和创建gpg-agent.conf (Windows需要)
- (unless (file-exists-p gpg-agent-conf)
- (with-temp-file gpg-agent-conf
- (insert "# GPG Agent配置文件\n")
- (insert "default-cache-ttl 28800\n")
- (insert "max-cache-ttl 86400\n")
- (when (eq system-type 'windows-nt)
- (insert "pinentry-program C:/Program Files (x86)/Gpg4win/bin/pinentry-basic.exe\n")))
- (message "Created gpg-agent.conf configuration file"))
-
- (message "GPG configuration check completed")))
-
-;; 一键修复EPA问题的函数
-(defun my/fix-epa-issues ()
- "一键诊断和修复EPA配置问题。"
- (interactive)
- (message "Starting EPA diagnostics and repair...")
-
- ;; 重新配置GPG
- (my/setup-gpg)
-
- ;; 检查配置文件
- (my/check-gpg-config)
-
- ;; 检查密钥
- (my/check-or-create-gpg-keys)
-
- ;; 重新初始化EPA
- (when (fboundp 'epa-file-disable)
- (epa-file-disable))
- (epa-file-enable)
-
- ;; 测试EPA功能
- (run-with-timer 3 nil (lambda ()
- (condition-case err
- (progn
- (epg-make-context)
- (message "EPA repair completed! Please test Mastodon functionality"))
- (error
- (message "EPA still has issues: %s" (error-message-string err))
- (message "Suggestion: manually check GPG installation and key configuration"))))))
-
-;; Simple EPA test function
-(defun my/test-epa-quick ()
- "Quick EPA functionality test."
- (interactive)
- (condition-case err
- (progn
- (require 'epg)
- (epg-make-context)
- (message "EPA test passed - ready for Mastodon"))
- (error
- (message "EPA test failed: %s" (error-message-string err)))))
-
-
-;; Initialize GPG configuration
-(my/setup-gpg)
-;; (run-with-timer 1 nil 'my/check-gpg-config)
-;; (run-with-timer 2 nil 'my/check-or-create-gpg-keys)
-;; (run-with-timer 3 nil 'my/test-epa-quick)
-
-;; Mastodon Client
-
-(unless (package-installed-p 'mastodon)
- (package-install 'mastodon))
-
-(with-eval-after-load 'mastodon
- ;; 基础设置:请修改为您自己的实例和用户名
- (setq mastodon-instance-url "https://m.otter.homes"
- mastodon-active-user "cytrogen")
-
- ;; 界面设置
- (setq mastodon-client-width-mode nil)
-
- ;; --- UI Modernization (Avatars & Images) ---
- ;; 1. Enable Avatars
- (setq mastodon-tl--show-avatars t)
- ;; Note: 'mastodon-client-display-avatar-in-status' doesn't seem to be a std var in this version,
- ;; checking source: mastodon-tl--show-avatars is the custom var for avatars.
-
- ;; 2. Optimize Image Preview
- (setq mastodon-media-format-type 'preview)
-
- ;; 智能EPA绕过和错误隔离
- (defvar my/mastodon-encryption-attempted nil
- "记录是否已尝试启用加密。")
-
- (defun my/test-mastodon-encryption ()
- "测试Mastodon是否能安全使用GPG加密。"
- (condition-case err
- (progn
- (epg-make-context)
- (epg-list-keys (epg-make-context))
- t) ; 成功返回t
- (error nil))) ; 失败返回nil
-
- ;; 根据EPA功能自动选择加密方式
- (if (and (not my/mastodon-encryption-attempted)
- (my/test-mastodon-encryption))
- (progn
- (setq mastodon-client-file-encryption t)
- (setq my/mastodon-encryption-attempted t)
- (message "Mastodon enabled GPG encrypted storage"))
- (progn
- (setq mastodon-client-file-encryption nil)
- (setq my/mastodon-encryption-attempted t)
- (message "Mastodon using plaintext storage (EPA unavailable or problematic)")))
-
- ;; 运行时错误隔离
- (condition-case gpg-err
- (when mastodon-client-file-encryption
- (when (and epg-gpg-program (file-exists-p epg-gpg-program))
- (message "Mastodon GPG configuration validation completed")))
- (error
- (setq mastodon-client-file-encryption nil) ; 自动fallback到明文
- (message "Detected EPA issues, automatically switching to plaintext storage: %s" (error-message-string gpg-err)))))
-
-;; Mastodon UI Beautification (Nerd Icons & Modern Look)
-
-(unless (package-installed-p 'nerd-icons)
- (package-install 'nerd-icons))
-
-;; --- Nerd Icons Font Setup and Verification ---
-;; Emacs needs to be able to find a suitable Nerd Font to display icons.
-;; The recommended font is "Symbols Nerd Font Mono".
-;; If you see empty squares instead of icons, you might need to install it.
-;; Run `M-x nerd-icons-install-fonts` in Emacs, then manually install the font file.
-;; If Emacs still doesn't see it, restart Emacs.
-
-(defun my/verify-nerd-font ()
- "Check if Symbols Nerd Font is available."
- (interactive)
- (let* ((font-name "Symbols Nerd Font Mono")
- (font (find-font (font-spec :name font-name))))
- (if font
- (message "✅ 成功! Emacs 已找到字体: %s" font)
- (message "❌ 失败! Emacs 找不到 '%s'。请确认已选择'为所有用户安装'并重启了 Emacs。" font-name))))
-
-;; If you already have another Nerd Font (e.g., "JetBrainsMono Nerd Font") and prefer to use it,
-;; uncomment the line below and replace "Your Nerd Font Name" with its exact name.
-(with-eval-after-load 'nerd-icons
- ;; (setq nerd-icons-font-family "Your Nerd Font Name")
- )
-
-(with-eval-after-load 'mastodon
- (require 'nerd-icons)
-
- ;; 1. Replace text symbols with Nerd Icons
- (setq mastodon-tl--symbols
- `((reply . (,(nerd-icons-faicon "nf-fa-reply") . "R"))
- (boost . (,(nerd-icons-faicon "nf-fa-retweet") . "B"))
- (reblog . (,(nerd-icons-faicon "nf-fa-retweet") . "B"))
- (favourite . (,(nerd-icons-faicon "nf-fa-star") . "F"))
- (bookmark . (,(nerd-icons-faicon "nf-fa-bookmark") . "K"))
- (media . (,(nerd-icons-faicon "nf-fa-file_image_o") . "[media]"))
- (verified . (,(nerd-icons-octicon "nf-oct-verified") . "V"))
- (locked . (,(nerd-icons-faicon "nf-fa-lock") . "[locked]"))
- (private . (,(nerd-icons-faicon "nf-fa-lock") . "[followers]"))
- (mention . (,(nerd-icons-faicon "nf-fa-at") . "[mention]"))
- (direct . (,(nerd-icons-faicon "nf-fa-envelope") . "[direct]"))
- (edited . (,(nerd-icons-faicon "nf-fa-pencil") . "[edited]"))
- (update . (,(nerd-icons-faicon "nf-fa-pencil") . "[edited]"))
- (status . (,(nerd-icons-faicon "nf-fa-bell") . "[posted]"))
- (poll . (,(nerd-icons-faicon "nf-fa-bar_chart") . "[poll]"))
- (follow . (,(nerd-icons-faicon "nf-fa-user_plus") . "+"))
- (follow_request . (,(nerd-icons-faicon "nf-fa-user_plus") . "+"))
- (severed_relationships . (,(nerd-icons-faicon "nf-fa-chain_broken") . "//"))
- (moderation_warning . (,(nerd-icons-faicon "nf-fa-exclamation_triangle") . "!!"))
- (reply-bar . ("┃" . "|"))))
-
- ;; 2. Modernize Faces
- ;; Use variable width font for main text (if desired)
- (add-hook 'mastodon-mode-hook #'variable-pitch-mode)
-
- ;; Make headers stand out
- (set-face-attribute 'mastodon-display-name-face nil :height 1.2 :weight 'bold)
- (set-face-attribute 'mastodon-handle-face nil :height 0.9 :slant 'italic :foreground "gray60")
-
- ;; Improve metadata visibility
- (set-face-attribute 'mastodon-toot-docs-face nil :height 0.85 :foreground "gray50")
-
- ;; Fix alignment for icons if needed
- (when (display-graphic-p)
- (setq mastodon-tl--enable-proportional-fonts t)))
-
-;; Universal Elisp Tags Filter
-
-(with-eval-after-load 'ox
- (defun my/org-export-hexo-universal-block (block backend info)
- (when (org-export-derived-backend-p backend 'md)
- (let* ((type (downcase (org-element-property :type block)))
- (content (org-export-data (org-element-contents block) info)))
- (format "{%% %s %%}\n%s{%% end%s %%}" type content type))))
- (add-to-list 'org-export-filter-special-block-functions 'my/org-export-hexo-universal-block))
-
-;; Visual Line Mode
-
-(add-hook 'org-mode-hook #'visual-line-mode)
-(add-hook 'markdown-mode-hook #'visual-line-mode)
-
-(when (fboundp 'adaptive-wrap-prefix-mode)
- (add-hook 'visual-line-mode-hook #'adaptive-wrap-prefix-mode))
-
-;; Fonts
-
-(defun my/org-mode-visual-setup ()
- "Activate visual adjustments for Org mode writing."
- (variable-pitch-mode 1) ; 开启变宽字体模式(正文使用 Source Serif 4/宋体)
- (visual-line-mode 1)) ; 开启视觉折行(按词换行,而非按字符截断)
-
-(add-hook 'org-mode-hook 'my/org-mode-visual-setup)
-
-;; Apply Fonts
-
-(if (daemonp)
- (add-hook 'after-make-frame-functions
- (lambda (frame) (with-selected-frame
- frame (my/setup-blog-fonts))))
- (my/setup-blog-fonts))
-
-;; Org Directory (Dynamic Setting)
-
-(defvar my/org-path-config-file (concat user-emacs-directory ".org-path")
- "File to store the user's Org directory path.")
-
-(defun my/setup-org-directory ()
- "Load Org directory from config file or prompt user to select one."
- (let ((path nil))
- ;; 1. Try to read from file
- (when (file-exists-p my/org-path-config-file)
- (with-temp-buffer
- (insert-file-contents my/org-path-config-file)
- (setq path (string-trim (buffer-string)))))
-
- ;; 2. Validate path, if invalid/missing, prompt user
- (unless (and path (file-directory-p path))
- (setq path (read-directory-name "请选择您的 Org 笔记根目录 (Please select Org root): " "D:/"))
- (unless (file-directory-p path)
- (make-directory path t))
- ;; Save for next time
- (with-temp-file my/org-path-config-file
- (insert path)))
-
- ;; 3. Apply setting
- (setq org-directory (file-name-as-directory path))
- (setq org-default-notes-file (concat org-directory "inbox.org"))
- (message "Org Directory loaded: %s" org-directory)))
-
-;; Execute setup immediately
-(my/setup-org-directory)
-
-;; Set agenda files to include all org files in the directory
-(setq org-agenda-files
- (append (list org-directory)
- (when (file-exists-p org-directory)
- (directory-files org-directory t "\\.org$"))))
-
-;; Ensure Org directories exist immediately to prevent crashes during config load
-(let ((notes-dir (concat org-directory "notes/")))
- (unless (file-exists-p notes-dir)
- (make-directory notes-dir t)
- (message "Created missing directory: %s" notes-dir)))
-
-;; --- Custom Dashboard / Startup Screen ---
-
-(defun my/show-dashboard ()
- "Render a custom GTD dashboard."
- (interactive)
- (let ((buf (get-buffer-create "*Cytrogen's Home*")))
- (with-current-buffer buf
- (let ((inhibit-read-only t))
- (erase-buffer)
-
- ;; Header
- (insert "#+TITLE: Cytrogen 的个人领地\n")
- (insert "#+STARTUP: showall\n\n")
-
- (insert "\n")
- (insert "Welcome back, Cytrogen.\n")
- (insert "------------------------------------\n\n")
-
- ;; GTD Intro
- (insert "* GTD 工作流指南\n\n")
- (insert "1. Capture (收集): 大脑用来思考,不是用来记事的。\n")
- (insert " 任何想法、任务、灵感,第一时间通过 Capture 放入 Inbox。\n")
- (insert " - [C-c c] 唤起 Capture 面板\n")
- (insert " - [C-c C-c] 确认保存\n")
- (insert " - [C-c C-k] Abort (放弃/取消)\n\n")
-
- (insert "2. Process (整理): 清空 Inbox。\n")
- (insert " 每天/每周定期检查 Inbox,将任务移动到具体的项目或归档。\n")
- (insert " - [C-c w] Quick Refile (快速移动条目)\n\n")
-
- (insert "3. Do (执行): 专注当下。\n")
- (insert " 通过 Agenda 查看今日待办。\n")
- (insert " - [C-c a] 打开 Agenda 视图\n\n")
-
- ;; Keybindings Cheatsheet
- (insert "* 常用命令\n\n")
- (insert "| 快捷键 | 描述 | 命令 |\n")
- (insert "|---|---|---|\n")
- (insert "| ~C-c c~ | 快速记录 | org-capture |\n")
- (insert "| ~C-c a~ | 日程/代办 | org-agenda |\n")
- (insert "| ~C-c w~ | 快速归档 | my/quick-refile |\n")
- (insert "| ~C-c o~ | 打开笔记 | my/open-org-file |\n")
- (insert "| ~C-c m~ | 长毛象 | mastodon |\n")
- (insert "| ~C-c i~ | 编辑配置 | my/open-init-file |\n")
- (insert "| ~C-c r~ | 重载配置 | my/reload-init-file |\n")
-
- ;; Footer
- (insert "\n\n/\"保持简单,保持流动。\"/\n")
-
- (org-mode)
- (my/org-mode-visual-setup)
- (org-indent-mode 1)
- (visual-line-mode 1)
-
- (when (bound-and-true-p display-line-numbers-mode)
- (display-line-numbers-mode -1))
-
- (setq mode-line-format nil)
- (setq-local org-hide-emphasis-markers t)
-
- (goto-char (point-min))
- (while (re-search-forward "^#\\+.*$" nil t)
- (add-text-properties (match-beginning 0) (match-end 0)
- '(invisible t)))
- (add-to-list 'buffer-invisibility-spec '(t . t))
-
- (setq buffer-read-only t)
- (goto-char (point-min))
-
- (while (get-char-property (point) 'invisible)
- (forward-line 1))))
-
- (switch-to-buffer buf)))
-
-;; Disable default startup screen and show ours
-(setq inhibit-startup-screen t)
-(add-hook 'emacs-startup-hook #'my/show-dashboard)
-
-(with-eval-after-load 'org
- ;; --- Refile Configuration ---
- ;; 强化 Refile 功能,允许将条目移动到项目或分类的具体标题下
- (setq org-refile-use-outline-path 'file)
- (setq org-outline-path-complete-in-steps nil)
- (setq org-refile-allow-creating-parent-nodes 'confirm)
-
- ;; 设定 Refile 的目标文件
- (setq org-refile-targets
- `((nil :maxlevel . 3) ; 当前 buffer 的标题 (直到 3 级)
- (org-agenda-files :maxlevel . 3) ; 所有 Agenda 文件 (直到 3 级)
- ;; 添加 notes 目录下的所有 org 文件
- (,(directory-files-recursively (concat org-directory "notes/") "\\.org$") :maxlevel . 3)))
-
- ;; --- Capture Templates ---
- ;; 强化 Capture 功能,快速捕获任务、笔记和博客想法
- (setq org-capture-templates
- '(("t" "Todo [任务]" entry (file+headline "inbox.org" "Tasks")
- "* TODO %?\n %U\n %a")
- ("n" "Note [笔记/灵感]" entry (file+headline "inbox.org" "Notes")
- "* %? \n %U\n")
- ("b" "Blog Idea [写作灵感]" entry (file+headline "inbox.org" "Writing Ideas")
- "* IDEA %?\n :PROPERTIES:\n :CAPTURED: %U\n :END:\n")
- ("r" "Reading [阅读/学习]" entry (file+headline "notes/reading.org" "Inbox")
- "* %? \n :PROPERTIES:\n :SOURCE: %^{Source}\n :END:\n %U\n")
- ("j" "Journal [学习日志]" entry (file+olp+datetree "notes/journal.org")
- "* %?\n %U\n")
- ("s" "Snippet [代码片段]" entry (file+headline "notes/snippets.org" "新片段")
- "* %^{Title}\n#+BEGIN_SRC %^{Language}\n%?\n#+END_SRC\n %U\n")
- ("m" "Mastodon [长毛象]" entry (file+headline "inbox.org" "Notes")
- "* %^{Title}\n:PROPERTIES:\n:SOURCE: %l\n:CAPTURED: %U\n:END:\n\n#+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n%?")
- ("S" "Shopping" entry (file+olp "inbox.org" "Shopping List")
- "* Shopping List %U\n - [ ] %?\n"))))
-
-;; Syncthing
-
-(setq backup-directory-alist `(("." . ,(concat user-emacs-directory "saves/"))))
-(setq auto-save-file-name-transforms `((".*" ,(concat user-emacs-directory "saves/") t)))
-(setq create-lockfiles nil)
-(unless (file-exists-p (concat user-emacs-directory "saves/"))
- (make-directory (concat user-emacs-directory "saves/")))
-
-;; Custom Variables
-
-(custom-set-variables
- ;; custom-set-variables 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.
- '(epa-armor t t)
- '(epa-file-cache-passphrase-for-symmetric-encryption t)
- '(epa-file-encrypt-to nil t)
- '(epa-file-select-keys 'silent)
- '(epg-debug t)
- '(epg-gpg-home-directory "c:/Users/Cytrogen/AppData/Roaming/.gnupg")
- '(epg-gpg-program "D:/GnuPG/bin/gpg.exe")
- '(epg-pinentry-mode 'loopback)
- '(epg-user-id nil t)
- '(package-selected-packages
- '(adaptive-wrap mastodon nerd-icons ox-hugo rainbow-delimiters
- yasnippet)))
-(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.
- )
-
-;; Global Keybindings
-
-(global-set-key (kbd "C-c c") 'org-capture)
-(global-set-key (kbd "C-c a") 'org-agenda)
-(global-set-key (kbd "C-c m") 'mastodon)
-(global-set-key (kbd "C-c C-w") 'org-refile)
-(global-set-key (kbd "C-c w") 'my/quick-refile)
-(global-set-key (kbd "C-c i") 'my/open-init-file)
-(global-set-key (kbd "C-c r") 'my/reload-init-file)
-(global-set-key (kbd "C-c o") 'my/open-org-file)
-
-;; Custom Functions
-
-(require 'cl-lib)
-
-;; Quick Access to Configuration
-
-(defun my/open-init-file ()
- "快速打开init.el配置文件进行编辑。"
- (interactive)
- (find-file user-init-file)
- (message "Opened configuration file: %s" user-init-file))
-
-(defun my/reload-init-file ()
- "重新加载init.el配置文件。"
- (interactive)
- (load-file user-init-file)
- (message "Configuration file reloaded: %s" user-init-file))
-
-(defun my/open-org-file ()
- "交互式选择并打开 Org 目录下的文件。"
- (interactive)
- ;; 1. 确保 org-directory 存在
- (unless (and org-directory (file-directory-p org-directory))
- (user-error "Org directory not found or invalid: %s" org-directory))
-
- (let* ((files (directory-files-recursively org-directory "\\.org$"))
- ;; 2. 构建候选列表,如果列表为空则提示
- (candidates (if files
- (mapcar (lambda (f)
- (cons (file-relative-name f org-directory) f))
- files)
- nil)))
-
- (if (not candidates)
- (message "No .org files found in %s" org-directory)
- ;; 3. 正常选择
- (let ((selection (completing-read "Open Org File: " (mapcar #'car candidates))))
- (when selection
- (let ((full-path (cdr (assoc selection candidates))))
- (when full-path
- (find-file full-path)
- (message "Opened: %s" selection))))))))
-
-;; Interactive Refile System
-
-(defvar my/refile-targets
- '(("t" "Tech"
- (("d" "Development" "tech.org" "Development")
- ("l" "Tools" "tech.org" "Tools")
- ("e" "Learning" "tech.org" "Learning")
- ("p" "Projects" "tech.org" "Projects")))
- ("s" "Shopping"
- (("l" "Shopping Lists" "shopping.org" "Shopping Lists")
- ("b" "Budgets" "shopping.org" "Budgets")
- ("p" "Purchases" "shopping.org" "Purchases")))
- ("p" "Personal"
- (("h" "Health" "personal.org" "Health")
- ("f" "Finance" "personal.org" "Finance")
- ("m" "Family" "personal.org" "Family")
- ("g" "Goals" "personal.org" "Goals")))
- ("n" "Notes"
- (("r" "Reading" "notes/reading.org" "Inbox")
- ("p" "Projects" "notes/projects.org" "Active")
- ("a" "Archive Projects" "notes/projects.org" "Completed"))))
- "Quick refile destinations in format: (key label ((subkey sublabel file heading)))")
-
-(defun my/quick-refile ()
- "Interactive refile with menu selection."
- (interactive)
- (unless (org-region-active-p)
- (org-back-to-heading t))
-
- ;; Display main categories
- (let* ((categories (mapcar (lambda (cat)
- (format "[%s] %s" (car cat) (cadr cat)))
- my/refile-targets))
- (prompt (concat "Quick Refile to: " (mapconcat 'identity categories " ") " "))
- (choice (read-char-exclusive prompt)))
-
- ;; Find selected category
- (let* ((choice-str (char-to-string choice))
- (selected-cat (cl-find-if (lambda (cat) (string= (car cat) choice-str))
- my/refile-targets)))
- (if (not selected-cat)
- (message "Invalid choice: %s" choice-str)
-
- ;; Display subcategories
- (let* ((subcats (caddr selected-cat))
- (subcat-display (mapcar (lambda (sub)
- (format "[%s] %s" (car sub) (cadr sub)))
- subcats))
- (sub-prompt (concat "Choose destination: "
- (mapconcat 'identity subcat-display " ") " "))
- (sub-choice (read-char-exclusive sub-prompt)))
-
- ;; Find selected subcategory and refile
- (let* ((sub-choice-str (char-to-string sub-choice))
- (selected-sub (cl-find-if (lambda (sub) (string= (car sub) sub-choice-str))
- subcats)))
- (if (not selected-sub)
- (message "Invalid subcategory choice: %s" sub-choice-str)
-
- ;; Perform the refile
- (let* ((file (caddr selected-sub))
- (heading (cadddr selected-sub))
- (target-path (expand-file-name file org-directory)))
-
- (if (not (file-exists-p target-path))
- (message "Target file does not exist: %s" target-path)
- (let ((pos (save-excursion
- (with-current-buffer (find-file-noselect target-path)
- (org-find-exact-headline-in-buffer heading)))))
- (if (not pos)
- (message "Heading '%s' not found in %s" heading file)
- (org-refile nil nil (list heading target-path nil pos))
- (message "Refiled to: %s -> %s" file heading))))))))))))
-
-(defun my/ensure-org-infrastructure ()
- "Ensure all necessary Org files and base headings exist based on capture templates."
- (interactive)
- (require 'org)
- (message "--- Org Infrastructure Check Start ---")
- (message "Org Directory: %s" org-directory)
-
- ;; Define complete file structure for capture & refile system
- (let ((file-configs '(;; Main files in root directory
- ("inbox.org" . ("Tasks" "Notes" "Writing Ideas" "Shopping List"))
- ("tech.org" . ("Development" "Tools" "Learning" "Projects"))
- ("shopping.org" . ("Shopping Lists" "Budgets" "Purchases"))
- ("personal.org" . ("Health" "Finance" "Family" "Goals"))
- ;; Notes subdirectory files
- ("notes/reading.org" . ("Inbox"))
- ("notes/journal.org" . nil) ; Uses datetree, no specific headings needed
- ("notes/snippets.org" . ("新片段"))
- ("notes/projects.org" . ("Active" "Backlog" "Completed")))))
-
- ;; 1. Ensure directories and files exist
- (dolist (config file-configs)
- (let* ((file (car config))
- (headings (cdr config))
- (path (expand-file-name file org-directory)))
- (message "Checking file: %s" path)
-
- ;; Create file if it doesn't exist
- (unless (file-exists-p path)
- (message " [MISSING] Creating file...")
- (condition-case err
- (progn
- (make-directory (file-name-directory path) t)
- (with-temp-file path
- (insert "#+TITLE: " (capitalize (file-name-base file)) "\n\n"))
- (message " [SUCCESS] File created."))
- (error (message " [ERROR] Failed to create file: %s" err))))
-
- ;; Check and create required headings
- (when (and (file-exists-p path) headings)
- (with-current-buffer (find-file-noselect path)
- (save-excursion
- (dolist (heading headings)
- (goto-char (point-min))
- (unless (re-search-forward (format "^\\* %s" (regexp-quote heading)) nil t)
- (message " [MISSING HEADING] Creating '%s' in %s" heading file)
- (goto-char (point-max))
- (unless (bolp) (insert "\n"))
- (insert "* " heading "\n"))))
- (save-buffer)))))
-
- (message "--- Org Infrastructure Check End ---")))
-
-
-(defun my/check-gpg-status ()
- "检查并显示当前GPG配置状态。"
- (interactive)
- (with-output-to-temp-buffer "*GPG状态检查*"
- (princ "=== GPG状态检查 ===\n\n")
-
- ;; 使用与my/setup-gpg相同的查找逻辑
- (princ "1. GPG程序检查(按优先级顺序):\n")
- (let* ((candidates '("D:/GnuPG/bin/gpg.exe" ; 用户实际安装位置
- "C:/Program Files (x86)/GnuPG/bin/gpg.exe"
- "C:/Program Files/GnuPG/bin/gpg.exe"
- "gpg"))
- (found-paths '()))
-
- ;; 检查每个候选路径
- (dolist (path candidates)
- (let ((exists (if (string-match-p "/" path)
- (file-exists-p path)
- (executable-find path))))
- (if exists
- (progn
- (princ (format " Found: %s\n" path))
- (push path found-paths))
- (princ (format " ✗ %s\n" path)))))
-
- ;; 显示当前使用的路径
- (princ "\n2. 当前Emacs配置:\n")
- (if epg-gpg-program
- (progn
- (princ (format " Using path: %s\n" epg-gpg-program))
- (condition-case err
- (let ((version (shell-command-to-string (format "\"%s\" --version" epg-gpg-program))))
- (princ (format " Version: %s" (car (split-string version "\n")))))
- (error (princ (format " Warning: version check failed: %s\n" (error-message-string err))))))
- (princ " ✗ epg-gpg-program 未设置\n"))
-
- (princ (format " epa-pinentry-mode: %s\n" epa-pinentry-mode))
-
- ;; Mastodon相关设置
- (princ "\n3. Mastodon配置:\n")
- (if (boundp 'mastodon-client-file-encryption)
- (princ (format " Encryption setting: %s\n"
- (if mastodon-client-file-encryption "GPG加密" "明文存储(当前设置)")))
- (princ " ✓ 加密设置: 默认(依赖GPG)\n"))
-
- ;; 给出建议
- (princ "\n=== 状态总结 ===\n")
- (cond
- ((not (boundp 'mastodon-client-file-encryption))
- (princ "⚠️ Mastodon包未加载,无法确定加密设置\n"))
- ((not mastodon-client-file-encryption)
- (princ "OK: Mastodon configured for plaintext storage, should work normally\n")
- (princ " For GPG encryption, run M-x my/test-gpg-basic to diagnose issues\n"))
- ((and epg-gpg-program (file-exists-p epg-gpg-program))
- (princ "OK: GPG configured, mastodon should work with encryption\n"))
- (found-paths
- (princ "Warning: Found GPG but not properly configured, please restart Emacs\n"))
- (t
- (princ "Error: GPG not found, suggest enabling plaintext storage\n"))))
-
- (princ "\nRun M-x my/setup-gpg to reconfigure GPG\n")))
-
-(defun my/test-gpg-basic ()
- "Test basic GPG functionality to help troubleshoot issues."
- (interactive)
- (with-output-to-temp-buffer "*GPG Basic Test*"
- (princ "=== GPG Basic Functionality Test ===\n\n")
-
- ;; 测试GPG版本
- (princ "1. GPG Version Test:\n")
- (condition-case err
- (let ((version-output (shell-command-to-string (format "\"%s\" --version" epg-gpg-program))))
- (princ (format " Version info:\n%s\n" version-output)))
- (error (princ (format " Error: Version check failed: %s\n" (error-message-string err)))))
-
- ;; 测试密钥列表
- (princ "2. Key Check:\n")
- (condition-case err
- (let ((keys-output (shell-command-to-string (format "\"%s\" --list-keys" epg-gpg-program))))
- (if (string-match "gpg: error" keys-output)
- (princ " Warning: Key list has warnings, but this is usually normal\n")
- (princ " Key list access normal\n")))
- (error (princ (format " Error: Key check failed: %s\n" (error-message-string err)))))
-
- ;; 测试Emacs EPA
- (princ "3. Emacs EPA Test:\n")
- (condition-case err
- (progn
- (require 'epg)
- (let ((context (epg-make-context)))
- (princ " EPA context created successfully\n")))
- (error (princ (format " Error: EPA test failed: %s\n" (error-message-string err)))))
-
- ;; 给出建议
- (princ "\n=== Suggestions ===\n")
- (princ "If GPG basic functionality works but mastodon still has issues:\n")
- (princ "1. Plaintext storage is currently enabled, mastodon should work normally\n")
- (princ "2. For full GPG support, you may need to generate GPG keypair\n")
- (princ "3. Run: gpg --full-generate-key (in command line)\n")
- (princ "4. Or continue using plaintext storage (usually secure enough for personal use)\n")))
-
-;; Insert Newsletter TOC
-
-(defun my/slugify-title (title)
- "Convert title to anchor-compatible slug, similar to the nodejs script."
- (let ((slug title))
- ;; Remove 《》 brackets
- (setq slug (replace-regexp-in-string "《\\|》" "" slug))
- ;; Remove punctuation, keep Unicode letters, numbers, spaces, hyphens
- (setq slug (replace-regexp-in-string "[^[:alnum:]\\s-]" "" slug))
- ;; Replace spaces with hyphens
- (setq slug (replace-regexp-in-string "\\s+" "-" slug))
- ;; Convert to lowercase
- (downcase slug)))
-
-(defun my/generate-newsletter-toc ()
- "Generate TOC for newsletter, similar to the nodejs script."
- (interactive)
- (save-excursion
- (goto-char (point-min))
-
- ;; Find the end of details block
- (if (not (re-search-forward "#+END_details" nil t))
- (message "Error: Could not find #+END_details block")
-
- (let ((toc-sections '())
- (current-section nil))
-
- ;; Parse content after the details block
- (while (not (eobp))
- (beginning-of-line)
- (let ((line (thing-at-point 'line t)))
- (cond
- ;; Match H2 headings (exported as ## in markdown)
- ((string-match "^\\* \\(.*\\)$" line)
- (let ((section-title (match-string 1 line)))
- (setq current-section (list :title section-title :articles '()))
- (push current-section toc-sections)))
-
- ;; Match H4 headings with article links (exported as #### [...](url))
- ((and current-section
- (string-match "^\\*\\*\\*\\* \\[\\[.*?\\]\\[《\\(.*?\\)》\\]\\]" line))
- (let ((article-title (match-string 1 line)))
- (push article-title (plist-get current-section :articles))))))
- (forward-line 1))
-
- ;; Reverse to get correct order
- (setq toc-sections (reverse toc-sections))
- (dolist (section toc-sections)
- (setq section (plist-put section :articles (reverse (plist-get section :articles)))))
-
- ;; Generate TOC markdown
- (let ((toc-content "\n## 输入\n\n"))
- (dolist (section toc-sections)
- (let ((section-title (plist-get section :title))
- (articles (plist-get section :articles)))
- (when articles
- (setq toc-content
- (concat toc-content
- (format "### %s\n\n" section-title)))
- (dolist (article articles)
- (let ((display-title article)
- (anchor (my/slugify-title article)))
- (setq toc-content
- (concat toc-content
- (format "- [%s](#%s)\n" display-title anchor))))
- (setq toc-content (concat toc-content "\n")))))
-
- ;; Find the details block and replace its content
- (goto-char (point-min))
- (if (re-search-forward "#+BEGIN_details 本期导读" nil t)
- (progn
- (forward-line 4) ; Skip PROPERTIES block
- (let ((start (point)))
- (if (re-search-forward "#+END_details" nil t)
- (progn
- (beginning-of-line)
- (delete-region start (point))
- (insert toc-content)
- (message "Newsletter TOC generated and inserted!"))
- (message "Error: Could not find #+END_details"))))
- (message "Error: Could not find details block"))))))))
-
-(defun my/insert-newsletter-toc ()
- "Deprecated: Use my/generate-newsletter-toc instead."
- (interactive)
- (message "Please use M-x my/generate-newsletter-toc instead."))
-
-;; Auto-save Refile
-(defun my/save-after-refile (&rest _)
- (org-save-all-org-buffers))
-
-(advice-add 'org-refile :after #'my/save-after-refile)
-
-;; Run infrastructure check after all functions are defined
-(my/ensure-org-infrastructure)
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!mastodon.plstore~ => saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!mastodon.plstore~ +0 -24
@@ 1,24 0,0 @@
-;;; public entries -*- mode: plstore -*-
-(("user-cytrogen@m.otter.homes" :secret-client_id t
- :secret-client_secret t :username "cytrogen@m.otter.homes" :instance
- "https://m.otter.homes")
- ("mastodon-https://m.otter.homes" :secret-client_id t
- :secret-client_secret t :id "7544" :name "mastodon.el" :website
- "https://codeberg.org/martianh/mastodon.el" :scopes
- ["read" "write" "follow"] :redirect_uris
- ["urn:ietf:wg:oauth:2.0:oob"] :vapid_key
- "BAfijz4Pcl3l4QjyGDdOeKg2PZKqUNdUP54GZOxtUvDaPHyT_4TrIlK8FRWeSo1WinDXQnM4tA-Q-cP4i_5GTOc="
- :redirect_uri "urn:ietf:wg:oauth:2.0:oob" :client_secret_expires_at
- 0))
-;;; secret entries
-"-----BEGIN PGP MESSAGE-----
-
-jA0ECQMIQMa/qY6HMif60sAgARVlEN+0dChmv5dBz/dZXZNfs4CqlGXQ3E7oRTLm
-zt2XnIj8f47A94N9UijcSWmWfraSGp3R2fwbCvYZpGqM+VZ4ctUBmtIK3cHyEdYL
-tb6BI7sVAvNKLiaIKQ/+1FpJZbdmHQrSiz/IEEvxbZKMyP2eoC3Edt0DaVemK+sT
-iaSKrybIykA6w2edF3qLRTXlngEyD4vXPwnU5zPSXDkbD4c5YI/HoKoAREMoQzar
-rU3cKiLhQwB7dlhfvOrHqeBZ2/79w57Wl4dGaoLo78VznlpCFHJfF5+/8JK0jxeb
-Y2o=
-=tLYc
------END PGP MESSAGE-----
-"
D saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!snippets!org-mode!hugo-blog-monthly~ => saves/!drive_c!Users!Cytrogen!AppData!Roaming!.emacs.d!snippets!org-mode!hugo-blog-monthly~ +0 -112
@@ 1,112 0,0 @@
-# -*- mode: snippet -*-
-# name: Blog Post / Newsletter
-# key: nlblog
-# --
-#+TITLE: ${1:`(capitalize (file-name-base (or (buffer-file-name) "Untitled")))`}
-#+DATE: ${2:`(format-time-string "%Y-%m-%d")`}
-#+LANG: zh
-#+CATEGORIES: ${3:想法迭代}
-#+FILETAGS: :${4:Org Mode Tags}:
-#+TAGS: :${5:Hexo Tags}:
-#+MATHJAX: false
-#+HIDDEN: false
-#+DESCRIPTION:
-
-$0
-
-#+HTML: <!--more-->
-
-#+BEGIN_details 本期导读
-:PROPERTIES:
-:CUSTOM_ID: 本期导读
-:END:
-
-${6:# 这里会生成TOC,完成写作后使用 M-x my/generate-newsletter-toc}
-
-#+END_details
-
-* 商业与社会
-:PROPERTIES:
-:CUSTOM_ID: 商业与社会
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 心理与关系
-:PROPERTIES:
-:CUSTOM_ID: 心理与关系
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 科学与自然
-:PROPERTIES:
-:CUSTOM_ID: 科学与自然
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 技术与创造
-:PROPERTIES:
-:CUSTOM_ID: 技术与创造
-:END:
-
-**** 有趣项目
-:PROPERTIES:
-:CUSTOM_ID: 有趣项目
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
------
-
-* 折腾博客
-:PROPERTIES:
-:CUSTOM_ID: 折腾博客
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 我写的文章
-:PROPERTIES:
-:CUSTOM_ID: 我写的文章
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 编程历程
-:PROPERTIES:
-:CUSTOM_ID: 我的编程历程
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 书籍
-:PROPERTIES:
-:CUSTOM_ID: 书籍
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 影视
-:PROPERTIES:
-:CUSTOM_ID: 影视
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 音乐
-:PROPERTIES:
-:CUSTOM_ID: 音乐
-:END:
-
-[[#本期导读][↑ 返回导读]]
-
-* 日记片段
-:PROPERTIES:
-:CUSTOM_ID: 日记片段
-:END:
-
-#+BEGIN_EXPORT markdown
-{% diary_aggregator %}
-#+END_EXPORT>
\ No newline at end of file
D saves/!drive_d!Org!inbox.org~ => saves/!drive_d!Org!inbox.org~ +0 -25
@@ 1,25 0,0 @@
-#+TITLE: GTD Inbox
-#+DATE: 2026-01-04
-#+STARTUP: overview
-
-* Tasks
-
-所有新的任务和待办事项都会在这里被捕获。
-** TODO 卷心菜、苹果泥(次要)、土豆、胡萝卜、咖喱粉(拍照)、蒜粉如果打折买蒜粉(次要)、蒜末(次要)、砂糖(主要)、青豆、
- [2026-01-04 Sun 14:45]
- [[help:position:]]
-* Notes
-
-快速记录的想法、笔记和灵感。
-
-* Writing Ideas
-
-博客文章和Newsletter的写作想法。
-** IDEA Emacs 和 Org Mode 的使用,以及我是如何对接 Hexo 框架的
- :PROPERTIES:
- :CAPTURED: [2026-01-03 Sat 23:24]
- :END:
-* Someday/Maybe
-
-未来可能要做的事情。
-* Shopping List
D saves/!drive_d!Org!notes!projects.org~ => saves/!drive_d!Org!notes!projects.org~ +0 -2
@@ 1,2 0,0 @@
-#+TITLE: Projects
-
D saves/!drive_d!Org!notes!reading.org~ => saves/!drive_d!Org!notes!reading.org~ +0 -76
@@ 1,76 0,0 @@
-#+TITLE: 阅读笔记
-#+DATE: 2026-01-04
-#+STARTUP: overview
-
-* Inbox
- :PROPERTIES:
- :CUSTOM_ID: reading-inbox
- :END:
-
-快速记录的阅读笔记和学习内容将出现在这里。
-** 世界没有你的时候也会继续运转,你会怎么办?
-艰难时期有着两个糟糕的部分:一是认为自己是唯一一个经历这一切的人,二是发现世界继续向前,而你停滞不前。事实是,没有人会救我们。只有我们可以拯救自己——这听上去像是毒鸡汤,但确实如此。我们很小,是这个宇宙的无数尘埃之一,我们只能依靠自己。
- :PROPERTIES:
- :SOURCE: https://tala.bearblog.dev/what-do-you-do-when-life-keeps-going-on-without-you/
- :END:
- [2026-01-05 Mon 11:52]
-** 作者比较了三个写作平台:Write.as、Pika.Page 以及 Bear Blog。我从未接触过这些写作平台。过去,我以为你要写博客只能是自己构建、部署一个。直到最近我才知道,其实早就有了这样的平台,可以帮助你构建网页样式,你只需要写……还有选择域名?应该吧。
- :PROPERTIES:
- :SOURCE: https://commentingon.xyz/bear-vs-pika-vs-writeas/
- :END:
- [2026-01-05 Mon 11:56]
-** 作者聊了聊他眼里,从 90 年代到现在的这 30 年里,web 开发都发生了什么。这篇文章有点长,值得了解这段历史。
-我个人很羡慕从小就接触了计算机并去学习原理的人。我是疫情的时候才学习计算机相关的东西。当时我想要自己弄一个视觉小说游戏,接触了 OnScripter,后来想着反正闲着也是闲着,不如学习编程。当时入门学的是 C++,但是没有系统地学习,基础没有打好就开始做「C-c C-v战士」了。
-让我意外的是,WordPress 居然在03年就诞生了。后面想了想也合理,它的底层是 PHP,能用上这东西的怎么说也是老资历了。我只用过一次 WordPress,是因为甲方要求我用这个。感觉刚会 Web 开发不久,对这种低代码平台很是嗤之以鼻——又慢又难用,实在是不够优雅。现在看来技术栈什么的真的没有那么重要,业务才是最重要的。就像是个人博客网站,重点是展示自己,也就是内容。不过技术栈也可以或多或少代表一个人的某些特质,还是不能把话说死了。
-我了解过前端的历史,很多事情都要从那个手机开始说起——iPhone。智能手机的大众化让开发者不得不去考虑「如何让网站变成在移动设备上看也很正常」这个问题。答案是响应式设计。前端和后端就此正式分成了两派,你写你的 API,我渲染我的样式,我们不走同个道了~
-文章里提到了 MongoDB,并讲了这样的一个笑话:「初创公司会选择 MongoDB 因为他们会考虑到未来的百万用户,然后在用户只有几千人的情况下花费数年时间。」哦不,这说的根本就是我!
-Agile 和 Scrum,我认为它们是有趣的东西。Scrum 可以在现在的许多企业里看到,至于 Agile,就不太一定了。我在某个项目里曾经提起过 Agile,主要是因为那会儿功能都没有约定好,你个破登录做了这么久做不好,不如直接开始折腾后面的部署,先把 MVP 展示出来。结果那个同事以很鄙夷的语气问道:「你想要搞敏捷开发?」虽然后面登录做好了,但是没有保护路由,所以登录不登录根本不重要。而他也因为不太懂部署和前后端之间的关系,折腾了很久才部署成功。
-
- :PROPERTIES:
- :SOURCE: https://www.artmann.co/articles/30-years-of-br-tags
- :END:
- [2026-01-05 Mon 12:08]
-** 找到两个数的最大公约数
-如果用 Python 来说的话,或许是:
-#+BEGIN_SRC python
-def gcd(p, q):
- if q == 0:
- return p
- r = p % q
- return gcd(q, r)
-#+END_SRC
-首先了解什么是公约数,其实就是 Common Factor,即可以整除这两个数字的数字。最大公约数顾名思义,是最大的公约数。
-如果数字 q 是 0 的话,最大的公约数只能是 p 了。
-但是我不理解后面的,为什么要得出余数 r,然后再获取 q 和 r 的最大公约数?
-这本书用的是 Java 语言来进行演示,不过作者也很努力地强调,算法和编程语言的选择关系不大,学会其原理后用什么来实现都可以。因为我对 Python 的语法更熟悉(不好意思 JavaScript 你真的很奇怪),所以我会用 Python 来演示。不过呢,使用 Java 语言的人去读这本书学到的肯定会更多,作者也教读者如何写 Java 代码,很是贴心。
-其实我做算法做的很糟糕,我都不知道我当年是如何通过的 CS50AI,里面多数都是算法题目,推荐一试。
-最初用 Python 入门编程的一个问题是,一时间想不起来 for 循环怎么写。Python 的 for 循环和其他语言的 for 循环很不一样,这也让我在写其他语言的 for 循环时,很难一下子就理解 i 和 j 到底是什么的位置。
-书中出现了一个我不明白的代码:
-#+BEGIN_SRC java
- public static double sqrt(double c)
- {
- if (c < 0) return Double.NaN;
- double err = 1e-15;
- double t = c;
- while (Math.abs(t - c/t) > err * t)
- t = (c/t + t) / 2.0;
- return t;
- }
-#+END_SRC
-说是牛顿迭代法,不过我不是很清楚这个法具体是什么东西。
-1.1.6.4 节要开始讲递归了。这是一个我很不明白的概念。当然我知道它的字面意义,但是脑子依然无法一时间想出来它是如何运作的。作者说递归代码有三点:
-1. 方法的第一条语句总是一个包含 return 的条件语句
-2. 总是去尝试解决一个规模更小的子问题,需要收敛到最简单的情况
-3. 调用的父问题和尝试解决的子问题之间不应该有任何交集
-
- :PROPERTIES:
- :SOURCE: 算法·第四版
- :END:
- [2026-01-06 Tue 11:20]
-* 书籍笔记
-
-* 课程笔记
-
-* 文章笔记
-
-* 视频笔记
D saves/!drive_d!Org!personal.org~ => saves/!drive_d!Org!personal.org~ +0 -2
@@ 1,2 0,0 @@
-#+TITLE: Personal
-
D saves/!drive_d!Org!reading.org~ => saves/!drive_d!Org!reading.org~ +0 -76
@@ 1,76 0,0 @@
-#+TITLE: 阅读笔记
-#+DATE: 2026-01-04
-#+STARTUP: overview
-
-* Inbox
- :PROPERTIES:
- :CUSTOM_ID: reading-inbox
- :END:
-
-快速记录的阅读笔记和学习内容将出现在这里。
-** 作者比较了三个写作平台:Write.as、Pika.Page 以及 Bear Blog。我从未接触过这些写作平台。过去,我以为你要写博客只能是自己构建、部署一个。直到最近我才知道,其实早就有了这样的平台,可以帮助你构建网页样式,你只需要写……还有选择域名?应该吧。
- :PROPERTIES:
- :SOURCE: https://commentingon.xyz/bear-vs-pika-vs-writeas/
- :END:
- [2026-01-05 Mon 11:56]
-** 作者聊了聊他眼里,从 90 年代到现在的这 30 年里,web 开发都发生了什么。这篇文章有点长,值得了解这段历史。
-我个人很羡慕从小就接触了计算机并去学习原理的人。我是疫情的时候才学习计算机相关的东西。当时我想要自己弄一个视觉小说游戏,接触了 OnScripter,后来想着反正闲着也是闲着,不如学习编程。当时入门学的是 C++,但是没有系统地学习,基础没有打好就开始做「C-c C-v战士」了。
-让我意外的是,WordPress 居然在03年就诞生了。后面想了想也合理,它的底层是 PHP,能用上这东西的怎么说也是老资历了。我只用过一次 WordPress,是因为甲方要求我用这个。感觉刚会 Web 开发不久,对这种低代码平台很是嗤之以鼻——又慢又难用,实在是不够优雅。现在看来技术栈什么的真的没有那么重要,业务才是最重要的。就像是个人博客网站,重点是展示自己,也就是内容。不过技术栈也可以或多或少代表一个人的某些特质,还是不能把话说死了。
-我了解过前端的历史,很多事情都要从那个手机开始说起——iPhone。智能手机的大众化让开发者不得不去考虑「如何让网站变成在移动设备上看也很正常」这个问题。答案是响应式设计。前端和后端就此正式分成了两派,你写你的 API,我渲染我的样式,我们不走同个道了~
-文章里提到了 MongoDB,并讲了这样的一个笑话:「初创公司会选择 MongoDB 因为他们会考虑到未来的百万用户,然后在用户只有几千人的情况下花费数年时间。」哦不,这说的根本就是我!
-Agile 和 Scrum,我认为它们是有趣的东西。Scrum 可以在现在的许多企业里看到,至于 Agile,就不太一定了。我在某个项目里曾经提起过 Agile,主要是因为那会儿功能都没有约定好,你个破登录做了这么久做不好,不如直接开始折腾后面的部署,先把 MVP 展示出来。结果那个同事以很鄙夷的语气问道:「你想要搞敏捷开发?」虽然后面登录做好了,但是没有保护路由,所以登录不登录根本不重要。而他也因为不太懂部署和前后端之间的关系,折腾了很久才部署成功。
-作者写到 AI 时代的时候,这种事实的冲击依然让人难以接受:原本感觉无限丰富的市场,居然收得这么快速。初创公司貌似变多了,但是岗位一直在减少,大家挤破了头都想进一个岗位——靠更好看的简历、更有噱头的项目、更硬的人脉……
- :PROPERTIES:
- :SOURCE: https://www.artmann.co/articles/30-years-of-br-tags
- :END:
- [2026-01-05 Mon 12:08]
-** 找到两个数的最大公约数
-如果用 Python 来说的话,或许是:
-#+BEGIN_SRC python
-def gcd(p, q):
- if q == 0:
- return p
- r = p % q
- return gcd(q, r)
-#+END_SRC
-首先了解什么是公约数,其实就是 Common Factor,即可以整除这两个数字的数字。最大公约数顾名思义,是最大的公约数。
-如果数字 q 是 0 的话,最大的公约数只能是 p 了。
-但是我不理解后面的,为什么要得出余数 r,然后再获取 q 和 r 的最大公约数?
-这本书用的是 Java 语言来进行演示,不过作者也很努力地强调,算法和编程语言的选择关系不大,学会其原理后用什么来实现都可以。因为我对 Python 的语法更熟悉(不好意思 JavaScript 你真的很奇怪),所以我会用 Python 来演示。不过呢,使用 Java 语言的人去读这本书学到的肯定会更多,作者也教读者如何写 Java 代码,很是贴心。
-其实我做算法做的很糟糕,我都不知道我当年是如何通过的 CS50AI,里面多数都是算法题目,推荐一试。
-最初用 Python 入门编程的一个问题是,一时间想不起来 for 循环怎么写。Python 的 for 循环和其他语言的 for 循环很不一样,这也让我在写其他语言的 for 循环时,很难一下子就理解 i 和 j 到底是什么的位置。
-书中出现了一个我不明白的代码:
-#+BEGIN_SRC java
- public static double sqrt(double c)
- {
- if (c < 0) return Double.NaN;
- double err = 1e-15;
- double t = c;
- while (Math.abs(t - c/t) > err * t)
- t = (c/t + t) / 2.0;
- return t;
- }
-#+END_SRC
-说是牛顿迭代法,不过我不是很清楚这个法具体是什么东西。
-1.1.6.4 节要开始讲递归了。这是一个我很不明白的概念。当然我知道它的字面意义,但是脑子依然无法一时间想出来它是如何运作的。作者说递归代码有三点:
-1. 方法的第一条语句总是一个包含 return 的条件语句
-2. 总是去尝试解决一个规模更小的子问题,需要收敛到最简单的情况
-3. 调用的父问题和尝试解决的子问题之间不应该有任何交集
-
- :PROPERTIES:
- :SOURCE: 算法·第四版
- :END:
- [2026-01-06 Tue 11:20]
-** 世界没有你的时候也会继续运转,你会怎么办?
-艰难时期有着两个糟糕的部分:一是认为自己是唯一一个经历这一切的人,二是发现世界继续向前,而你停滞不前。事实是,没有人会救我们。只有我们可以拯救自己——这听上去像是毒鸡汤,但确实如此。我们很小,是这个宇宙的无数尘埃之一,我们只能依靠自己。
- :PROPERTIES:
- :SOURCE: https://tala.bearblog.dev/what-do-you-do-when-life-keeps-going-on-without-you/
- :END:
- [2026-01-05 Mon 11:52]
-* 书籍笔记
-
-* 课程笔记
-
-* 文章笔记
-
-* 视频笔记
D saves/!drive_d!Org!shopping.org~ => saves/!drive_d!Org!shopping.org~ +0 -5
@@ 1,5 0,0 @@
-#+TITLE: Shopping
-
-* Shopping Lists
-* Budgets
-* Purchases
D saves/!drive_d!Org!tech.org~ => saves/!drive_d!Org!tech.org~ +0 -2
@@ 1,2 0,0 @@
-#+TITLE: Tech
-
D saves/#d!!Org!inbox.org# => saves/#d!!Org!inbox.org# +0 -17
@@ 1,17 0,0 @@
-#+TITLE: GTD Inbox
-#+DATE: 2026-01-04
-#+STARTUP: overview
-
-* Tasks
-
-所有新的任务和待办事项都会在这里被捕获。
-* Notes
-
-快速记录的想法、笔记和灵感。
-* Writing Ideas
-
-博客文章和Newsletter的写作想法。
-* Someday/Maybe
-
-未来可能要做的事情。
-* Shopping List
D saves/#d!!Org!tech.org# => saves/#d!!Org!tech.org# +0 -8
@@ 1,8 0,0 @@
-#+TITLE: Tech
-
-* Development
-* Tools
-* Learning
-** Emacs 的缓存机制,让 C-c C-w 时将内容从 Buffer A 剪切粘贴到了 Buffer B,重点是它们都是内存,并不是硬盘修改。这意味着需要使用 C-x b,进入 Buffer B,保存才可以。可以将自动保存功能挂载到 refile 动作之后。
- [2026-01-05 Mon 11:46]
-* Projects