You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在自定义日历主模式中绑定按键修改文本块Face

实现自定义日历模式中选中文本块修改Face的方案

嘿,这个需求完全可以搞定,而且能按照你的自定义需求灵活调整——毕竟自己造轮子就是要的这份掌控感嘛!我之前做过类似的自定义任务模式配置,给你一步步拆解具体实现:

1. 先定义你的「已完成」Face

首先得创建一个符合你视觉需求的自定义Face,用来标记已完成的任务。用defface可以适配不同的背景主题:

(defface completed-task-face
  '((((class color) (min-colors 88) (background light))
     :foreground "gray50" :strike-through t)
    (((class color) (min-colors 88) (background dark))
     :foreground "gray40" :strike-through t)
    (t :strike-through t))
  "Face for marking completed tasks in my custom calendar mode."
  :group 'my-calendar-group)

这个配置会在浅色背景下用浅灰色加删除线,深色背景用深灰色加删除线,通用环境下至少保留删除线,完美符合「已完成」的视觉提示。

2. 编写修改Face的核心函数

接下来写一个交互函数,用来给选中的文本块应用(或移除)这个Face。先从基础版本开始:

(defun my-calendar-mark-completed ()
  "Mark the selected text block as completed with `completed-task-face'."
  (interactive)
  (if (region-active-p)
      (let ((start (region-beginning))
            (end (region-end)))
        (add-text-properties start end '(face completed-task-face)))
    (message "Please select a text block first!")))

这个函数会先检查是否有激活的选区,如果有就给选区添加自定义Face;没有的话弹出提示让用户选中文本。

如果想要更实用的切换功能(按一次标记完成,再按一次取消),可以改成这样:

(defun my-calendar-toggle-completed ()
  "Toggle the completed state of the selected text block."
  (interactive)
  (if (region-active-p)
      (let ((start (region-beginning))
            (end (region-end)))
        (if (get-text-property start 'face)
            (remove-text-properties start end '(face))
          (add-text-properties start end '(face completed-task-face))))
    (message "Please select a text block first!")))

3. 绑定快捷键到自定义主模式

把这个函数绑定到你自定义日历模式的快捷键映射里就行。假设你的主模式叫my-calendar-mode,可以这样配置:

(defvar my-calendar-mode-map
  (let ((map (make-sparse-keymap)))
    ;; 绑定C-c C-t作为切换已完成状态的快捷键,你可以改成自己喜欢的组合
    (define-key map (kbd "C-c C-t") 'my-calendar-toggle-completed)
    map)
  "Keymap for my custom calendar major mode.")

如果已经存在主模式的keymap,直接在模式定义里或者单独加define-key就行,不用重新创建map。

4. 进阶优化:自动选中当前行

如果你的日历模式里每个任务都是单独一行,还可以优化函数,让用户不用手动选文本,直接按快捷键就能标记当前行:

(defun my-calendar-toggle-completed ()
  "Toggle completed state of the current line (or selected text block)."
  (interactive)
  (let (start end)
    (if (region-active-p)
        (setq start (region-beginning) end (region-end))
      ;; 如果没有选区,自动选中当前行
      (setq start (line-beginning-position) end (line-end-position)))
    (if (get-text-property start 'face)
        (remove-text-properties start end '(face))
      (add-text-properties start end '(face completed-task-face)))))

这样用户光标放在任务行上,直接按快捷键就能完成标记,体验更流畅。

这些代码都可以直接放到你的Emacs配置里,或者自定义模式的文件中,完全适配你的自定义日历模式,比依赖org-mode灵活多了!

内容的提问来源于stack exchange,提问作者C-x C-c

火山引擎 最新活动