Files
.emacs.d/lisp/init-org.el
andsy10 b4733718d4 refactor: Reorganize config with use-package and optimize startup hooks
- Split monolithic init-package.el into focused modules
- Convert eager `:init` blocks to lazy `:hook`
- Consolidate UI settings and defer theme loading.
- Remove duplicated config between GUI and terminal paths.
2026-06-04 02:27:20 +08:00

310 lines
11 KiB
EmacsLisp

;;; init-org.el --- org-mode config -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:
(use-package org
:hook
(org-mode . (lambda ()
(org-indent-mode)
(visual-line-mode)
(jinx-mode)
(electric-pair-local-mode)
(require 'org-tempo)
(setq-local electric-pair-inhibit-predicate
(lambda (char)
(or (eq char ?<)
(electric-pair-default-inhibit char))))))
:config
;; log默认放入drawer中
(setq org-log-done t
org-log-into-drawer t)
;; 不要在capture时设置bookmark
(setq org-bookmark-names-plist nil)
;; 设置todo关键字
(setq org-todo-keywords
(quote ((sequence "TODO(t)" "STARTED(S)" "|" "DONE(d!/!)")
(sequence "WAITING(w@/!)" "SOMEDAY(s)" "|" "CANCELLED(c@/!)"))))
;; agenda相关
(cond
(*is-windows*
(setq org-agenda-files '("h:/emacs/hugo/this-is-my-blog/all-blog.org"
"h:/emacs/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-mac*
(setq org-agenda-files '("~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-linux*
(setq org-agenda-files '("~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org")))
(*is-android*
(setq org-agenda-files '("~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org"))))
(setq org-agenda-span 'day)
(setq org-agenda-skip-function-global
'(org-agenda-skip-entry-if 'todo '("COMMENT"))))
;; org-babel scheme
(use-package ob-scheme
:demand t
:after org
:straight nil
:config
(add-to-list 'org-babel-load-languages '(scheme . t))
(org-babel-do-load-languages
'org-babel-load-languages
org-babel-load-languages))
;; denote
(use-package denote
:hook
(after-init . denote-rename-buffer-mode)
:config
(if *is-android*
(setq denote-directory "~/storage/shared/my-org-note/")
(setq denote-directory "~/org/my-org-note/"))
(setq denote-prompts '(title signature keywords))
(setq denote-title-history nil)
(setq denote-signature-history
'("note" "project" "fun" "wisdom" "article" "data" "metanote" "agenda"))
(setq denote-known-keywords
'("emacs" "org" "elisp" "scheme" "programming" "philosophy" "film" "linux" "computerstuff" "game" "masterpiece")))
;; denote-org
(use-package denote-org)
;; denote-journal
(use-package denote-journal
:hook
(calendar-mode . denote-journal-calendar-mode)
:config
(setq denote-journal-directory (expand-file-name "journal" denote-directory))
(setq denote-journal-keyword nil)
(setq denote-journal-signature "journal")
(setq denote-journal-keyword "daily"))
;; denote-explore
(use-package denote-explore)
;; consult-notes
(use-package consult-notes
:straight
'(consult-notes :fork (:host github :repo "Andsy10/consult-notes"))
:hook
(after-init . consult-notes-denote-mode)
:config
(setq consult-notes-denote-display-keywords-indicator "_")
(setq consult-notes-denote-display-id-format 'date)
(setq consult-notes-denote-display-signature t))
;; org-download
(use-package org-download
:config
(when *is-mac*
(setq org-download-image-dir "./images")
(unless (file-exists-p "./images")
(make-directory "./images" t))
(setq org-download-link-format "[[file:%s]]\n")
(setq org-download-timestamp "%Y%m%d_%H%M%S_")
(setq org-download-dragndrop t)
(setq org-image-actual-width nil)
(setq org-download-image-html-width 600)
(add-hook 'org-mode-hook 'org-display-inline-images))
(with-eval-after-load 'org
(require 'org-download)
(setq org-return-follows-link t)))
;; org-ql
(use-package org-ql)
;; org-super-agenda 配置
(use-package org-super-agenda
:config
(org-super-agenda-mode))
;; agenda
(use-package org-agenda
:straight nil
:config
(setq org-agenda-custom-commands
'(("pa" "priority >= A"
((org-ql-block '(and (priority "A") (todo))
((org-ql-block-header "priority = A")))))
("pb" "priority >= B"
((org-ql-block '(and (priority >= "B") (todo))
((org-ql-block-header "priority >= B")
(org-super-agenda-groups
'((:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")))))))
("pc" "priority >= C"
((org-ql-block '(and (priority >= "C") (todo))
((org-ql-block-header "priority >= C")
(org-super-agenda-groups
'((:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")
(:name "priority = C" :priority "C")))))))
("qd" "TODO entries sort by closed time"
((org-ql-block '(closed)
((org-ql-block-header "Closed TODOs")
(org-super-agenda-groups
'((:auto-ts t)))))))
("qs" "SOMEDAYs"
((org-ql-block '(todo "SOMEDAY")
((org-ql-block-header "SOMEDAYs")
(org-super-agenda-groups
'((:auto-ts t)))))))
("qS" "STARTEDs"
((org-ql-block '(todo "STARTED")
((org-ql-block-header "STARTEDs")
(org-super-agenda-groups
'((:auto-ts t)))))))
("qt" "TODOs sort by start time"
((org-ql-block '(todo)
((org-ql-block-header "TODOs")
(org-super-agenda-groups
'((:auto-ts t)))))))
("qa" "all TODO entries"
((org-ql-block '(and (not (done)) (todo))
((org-ql-block-header "all TODOs")
(org-super-agenda-groups
'((:name "started" :todo "STARTED")
(:name "priority = A" :priority "A")
(:name "priority = B" :priority "B")
(:name "other priority" :priority< "B")
(:name "someday" :todo "SOMEDAY"))))))))))
;; capture
(use-package org-capture
:straight nil
:config
(setq org-capture-templates
(cond
((or *is-linux* *is-mac*)
'(("t" "TODO" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* TODO %<%m-%d> %?\n%T"
:empty-lines 1)
("s" "SOMEDAY" entry
(file+headline "~/org/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* SOMEDAY %<%m-%d> %?\n%T"
:empty-lines 1)))
(*is-android*
'(("t" "TODO" entry
(file+headline "~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* TODO %<%m-%d> %?\n%T"
:empty-lines 1)
("s" "SOMEDAY" entry
(file+headline "~/storage/shared/my-org-note/20260509T232442==agenda--all-my-todos__org.org" "Something to do")
"* SOMEDAY %<%m-%d> %?\n%T"
:empty-lines 1)))
(t nil))))
;; hugo
(use-package ox-hugo
:config
(with-eval-after-load 'org-capture
(defun org-hugo-new-subtree-post-capture-template ()
"Returns `org-capture' template string for new Hugo post.
See `org-capture-templates' for more information."
(let* ((title (read-from-minibuffer "Post Title: ")) ;Prompt to enter the post title
(fname (org-hugo-slug title)))
(mapconcat #'identity
`(
,(concat "* TODO " title)
":PROPERTIES:"
,(concat ":EXPORT_FILE_NAME: " fname)
":END:"
"\n\n") ;Place the cursor here finally
"\n")))
(if *is-windows*
(add-to-list 'org-capture-templates
'("h" ;`org-capture' binding + h
"Hugo post"
entry
;; It is assumed that below file is present in `org-directory'
;; and that it has a "Blog Ideas" heading. It can even be a
;; symlink pointing to the actual location of all-posts.org!
(file+headline "h:/emacs/hugo/this-is-my-blog/all-blog.org" "Blog Ideas")
(function org-hugo-new-subtree-post-capture-template)))
(add-to-list 'org-capture-templates
'("h" ;`org-capture' binding + h
"Hugo post"
entry
;; It is assumed that below file is present in `org-directory'
;; and that it has a "Blog Ideas" heading. It can even be a
;; symlink pointing to the actual location of all-posts.org!
(file+headline "~/org/hugo/this-is-my-blog/all-blog.org" "Blog Ideas")
(function org-hugo-new-subtree-post-capture-template)))))
;; 快速部署
(defun my-blog-publish ()
"Publish blog , git add/commit/push , generate commit message."
(interactive)
(let* ((blog-dir (if *is-windows*
"h:/emacs/hugo/this-is-my-blog/"
"~/org/hugo/this-is-my-blog/"))
(timestamp (format-time-string "%Y-%m-%d %H:%M:%S"))
(default-directory blog-dir))
;; save buffer
(save-buffer)
;; git add
(message "Adding files...")
(eshell-command "git add .")
;; git commit with timestamp
(message "Committing: %s" timestamp)
(eshell-command (format "git commit -m \"Update: %s\"" timestamp))
;; git push
(message "Pushing to remote...")
(let ((exit-code (eshell-command "git push")))
(if (eq exit-code t)
(message "Push may have failed or nothing to push, check *Messages* buffer for details")
(message "Push successfully %s" timestamp)))))
;; 预览博客
(defun my-blog-preview ()
"Save and preview blog."
(interactive)
(save-buffer)
(let ((default-directory (if *is-windows*
"h:/emacs/hugo/this-is-my-blog/"
"~/org/hugo/this-is-my-blog/")))
;; 启动 Hugo server
(start-process "hugo-server" "*hugo-server*"
"hugo" "server" "-D" "--bind" "0.0.0.0" "--port" "1313")
;; 等待服务器启动
(sleep-for 2)
;; 自动打开浏览器
(browse-url "http://localhost:1313"))))
;; 农历日历
(use-package cal-china-x
:after calendar
:autoload cal-china-x-setup
:init
(cal-china-x-setup)
:config
(setq calendar-mark-holidays-flag t
cal-china-x-important-holidays cal-china-x-chinese-holidays
cal-china-x-general-holidays '((holiday-lunar 1 15 "元宵节")
(holiday-lunar 7 7 "七夕节")
(holiday-fixed 3 8 "妇女节")
(holiday-fixed 3 12 "植树节")
(holiday-fixed 5 4 "青年节")
(holiday-fixed 6 1 "儿童节")
(holiday-fixed 9 10 "教师节"))
holiday-other-holidays '((holiday-fixed 2 14 "情人节")
(holiday-fixed 4 1 "愚人节")
(holiday-fixed 12 25 "圣诞节")
(holiday-fixed 6 7 "高考")
(holiday-float 5 0 2 "母亲节")
(holiday-float 6 0 3 "父亲节")
(holiday-float 11 4 4 "感恩节"))
calendar-holidays (append cal-china-x-important-holidays
cal-china-x-general-holidays
holiday-other-holidays)))
(provide 'init-org)
;;; init-org.el ends here