Config: add init-org-refile.el , fix dirvish quick access path

This commit is contained in:
User
2026-04-09 16:04:01 +08:00
parent 41c64ca475
commit c3c59376f0
4 changed files with 170 additions and 26 deletions

142
lisp/init-org-refile.el Normal file
View File

@@ -0,0 +1,142 @@
;;; init-org-refile.el --- org-refile config -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:
(defun my-org-refile-to-new-file ()
"org-refile as a separate org file with custom template."
(interactive)
(require 'org-element)
(org-back-to-heading t)
(let* ((heading-components (org-heading-components))
;; (todo (nth 2 heading-components)) ; 保留todo状态
(raw-title (nth 4 heading-components)) ; 纯标题文本
(tags (org-get-tags nil t))
(begin (point))
(end (save-excursion (org-end-of-subtree t t) (point)))
(original-content (buffer-substring begin end))
;; 检测原条目是否有属性不包括logbook
(has-properties-p
(with-temp-buffer
(insert original-content)
(goto-char (point-min))
(forward-line 1) ; 跳过headline
(looking-at org-property-drawer-re)))
;; 如果有属性则提取内容
(original-props
(when has-properties-p
(with-temp-buffer
(insert original-content)
(goto-char (point-min))
(forward-line 1)
(let ((start (point)))
(when (re-search-forward ":END:" nil t)
(forward-line 1)
(buffer-substring start (point)))))))
;; 询问文件名,保留中文,只替换空格和特殊字符
(default-name (replace-regexp-in-string "[ \\/:*?\"<>|]" "_" raw-title))
(user-filename (read-string "Filename (without .org): " default-name))
(filename (format "%s-%s.org"
(format-time-string "%Y%m%d")
user-filename))
(target-dir (if *is-windows*
"h:/emacs/my-org-note/"
"~/org/my-org-note/"))
(filepath (expand-file-name filename target-dir))
;; 询问category
(category (completing-read "Category: "
'("none" "note" "project")
nil t "project"))
;; 询问 Tags原有标签作为默认值
(tag-input (read-string "Tags (space separated): "
(mapconcat #'identity tags " ")))
(formatted-tags
(if (and tag-input (not (string= tag-input "")))
(concat ":" (replace-regexp-in-string " " ":" tag-input) ":")
""))
;; 提取body
(body
(with-temp-buffer
(insert original-content)
(goto-char (point-min))
(forward-line 1)
;; 如果有属性抽屉则跳过
(when (looking-at org-property-drawer-re)
(while (not (looking-at org-property-end-re))
(forward-line 1))
(forward-line 1))
;; 跳过schedule和deadline
;; (when (looking-at org-planning-line-re)
;; (forward-line 1))
;; 清理开头的空行
(skip-chars-forward "\n")
(buffer-substring (point) (point-max)))))
;; 检查文件是否存在
(when (and (file-exists-p filepath)
(not (y-or-n-p (format "File %s exists. Overwrite? " filename))))
(error "Refile canceled"))
(unless (file-exists-p target-dir)
(make-directory target-dir t))
;; 将原条目的TODO关键字改为COMMENT如果有
(let ((todo (nth 2 heading-components)))
(when todo
(save-excursion
(goto-char begin)
(when (re-search-forward (concat "^\\(\\*+ \\s-*\\)" (regexp-quote todo)) (save-excursion (forward-line 1) (point)) t)
(replace-match "\\1COMMENT" t nil)))))
;; 创建新文件
(condition-case err
(with-temp-file filepath
;; 文件头
(insert (format "#+title: %s\n" user-filename))
(insert (format "#+date: %s\n" (format-time-string "[%Y-%m-%d %a %H:%M]")))
(insert (format "#+category: %s\n\n" category))
;; 插入标题和tag
(insert (format "* STARTED %s %s\n"
;; (if todo (concat todo " ") "")
user-filename
formatted-tags))
;; 只有原条目有属性时才插入
(when original-props
(insert original-props))
;; 插入body
(insert body)
;; 确保格式正确,添加文件尾局部变量
(unless (bolp) (insert "\n"))
(insert "\n# Local Variables:\n# org-use-tag-inheritance: nil\n# End:\n"))
(error
(goto-char begin)
(insert original-content)
(error "Failed to create file: %s" err)))
(find-file-other-window filepath)
(message "Successfully refiled to %s" filepath)))
(with-eval-after-load 'org
(define-key org-mode-map (kbd "C-c o w") #'my-org-refile-to-new-file))
(provide 'init-org-refile)
;;; init-org-refile.el ends here