Twidget - Emacs中的文本控件库

如何使用请看 中文文档


更新:

  • 新增宏 twidget-db, 方便使用数据库 #5
  • 多个 gif 动画演示 #6
  • twidget-text 支持多个 widget,新增属性 :textarea #19
18 个赞

实现得真漂亮

实在是高产啊

好强。:+1:。。。

更新: 新增宏 twidget-db

我的想法是 twidget 不仅仅作为处理前端交互的控件库,也可以融合后端数据库,来实现需求更加复杂的应用。因此实现了这个宏。

twidget-db 对 emacsql 和 emacsql-sqlite3 的使用做了一个封装,使用户通过几行代码就可以建立数据库并进行增删改查操作。使用该宏后,可以得到两个函数 ‘[prefix]-db’ 和 ‘[prefix]-db-action’。[prefix] 是 :prefix 属性的值。具体看下面的例子。

例子


(twidget-db "~/.emacs.d/notebook/notebook.db"
  :prefix "test"
  :tables '((notes [title content album timestamp])))

(test-db-action
 [:insert :into notes :values
          (["title" "content of note" "default" "2021-05-10"]
           ["title2" "content of note2" "default" "2021-05-11"])])

(test-db-action [:select * :from notes]) ;; => (("title" "content of note" "default" "2021-05-10") ("title2" "content of note2" "default" "2021-05-11"))

详细解释看 这篇文章

可以贴点截图, 直观一点

中文文档里有一些例子和gif图。

一些例子的 gif (详细代码看 中文文档):

example1

example3

example4

example5

1 个赞

好强大!谢谢分享!刚好想做类似的东西!

1 个赞

哈哈,谢谢,欢迎各位大佬贡献想法或代码!

可否列举一下与 ewoc / bui / tui 的异同?

|  \  | twidget | ewoc | bui | tui |
|-----|---------|------|-----|-----|
| ... | ...     | ...  | ... | ... |

我没用过 tui 和 bui 诶。twidget 依赖 Ewoc,是在ewoc的基础上实现的控件更新并加入了按键绑定。

看起来不错,能弄个nb的杀手级应用出来就好了。excel?

(bui 链接错啦?

1 个赞

已更正 :custard::custard::custard:

现在还很弱,还需要很多努力。本人能力有限,没办法一下子看的那么远,架构的很漂亮。 我的想法是先实现一些小的应用,比如 notebook,在实现的过程中不断完善代码,拓展思路。

现在使用的emacs带evil-mode,得退出evil-mode,才能进行数字切换

我不用 evil-mode,evil的数字键是绑定了什么操作嘛?

1 个赞

evil的数字键是prefix argument

更新: twidget-text 支持多个 widget,新增属性 :textarea

1.我们知道 :format 属性值中的 [t] 代表一个widget, 渲染时会被替代成value值。现在支持多个widget,写法是 [t0], [t1], [t2]…, value 值为一个列表。例子:

(defvar twidget-text-format
  "Emacs is a family of [t0] that are characterized by their extensibility. The manual for the most widely used variant, [t1], describes it as \"the [t2], [t3], [t4], real-time display editor\". Development of the first Emacs began in the mid-1970s, and work on its direct descendant, GNU Emacs, continues actively as of 2021.")

(with-twidget-buffer "*Twidget Test*"
  (set-window-margins (selected-window) 3 3)
  (twidget-insert
   (propertize "♨ Twidget Test" 'face '(bold :height 1.4)))
  (twidget-insert
   "\n\n" (propertize "Emacs" 'face '(bold :height 1.2))
   "\n\nFrom Wikipedia, the free encyclopedia\n\n")
  (twidget-create 'twidget-text
    :bind 'twidget-test1
    :format twidget-text-format ;; multiple text widget
    :value '("text editors" "GNU Emacs" nil nil "self-documenting")
    :length 5))

twidget-multitext

2.当 :textarea 属性的值为 t 时,表示该控件是一个文本框。文本框输入时会在底部弹出一个 side window。在buffer中显示时会自动在控件前后换行。例子

(defvar notebook-default-content
  "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")

(with-twidget-buffer "*Notebook*"
  (set-window-margins (selected-window) 3 3)
  (twidget-insert (propertize "📗 Notebook" 'face '(bold :height 1.5)))
  (twidget-insert "\n\n")
  (twidget-create 'twidget-text
    :bind 'notebook-note-title
    :format "Note title: [t]"
    :value "Default title")
  (twidget-insert "\n\n")
  (twidget-create 'twidget-text
    :bind 'notebook-note-content
    :format "Note content:\n[t]"
    :value notebook-default-content
    :textarea t) ;; a textarea widget.
  (twidget-insert "\n")
  (twidget-create 'twidget-choice
    :bind 'notebook-album
    :choices '("Default" "life" "study")
    :format "Choose notebook [t] "
    :separator "/"
    :value "Default")
  (twidget-create 'twidget-button
    :value "Add"))

twidget-textarea

3 个赞

试用了一下twidget,遇到了两个问题,不知道哪儿用的不对

  1. tab键只能跳转到第一个widget
  2. 文本控件无法输入

我的测试代码:

(add-to-list 'load-path "~/.emacs.d/packages/twidget")
(add-to-list 'load-path "~/.emacs.d/data/unsync/elpa28/ov-20200326.1042")

(require 'twidget)

(with-twidget-buffer (get-buffer-create "*twidget test*")
  (twidget-insert "\n\n")
  (twidget-create 'twidget-text
    :bind 'card-meaning
    :value "meaning"
    :format "含义: [t1]"
    :plain t
    :action (lambda (value)
              (message "the meaning is %s" value)))
  (twidget-insert "\n\n")
  (twidget-create 'twidget-text
    :bind 'card-context
    :value "context"
    :format "上下文: [t2]"
    :plain t
    :action (lambda (value)
              (message "the context is %s" value)))
  (twidget-insert "\n\n")
  (twidget-create 'twidget-text
    :bind 'card-answer
    :value "abc"
    :format "回答: [t3]"
    :action (lambda (value)
              (message "the answer is %s" value)))
  )

将上面代码保存为twidget.el,emacs -q运行emacs后打开twidget.el,然后eval-buffer

我期望的结果是可以tab跳转到最后一个text控件,在输入区可以输入。

环境:Manjaro Linux + Emacs 28.2