我正在 Elisp 中编写自己的模式。它基本上是一个简单的 CRUD 应用程序,显示可以通过迷你缓冲区进行操作的数据行。我想为这些行创建一个视图,它看起来像 emacs 包管理器:数据列很好地对齐。实现这种观点的最佳方法是什么?
菲尔斯的回答让我走上了正轨。不过,没有任何教程或简单的示例,所以我创建了一个。下面是一个列表列表模式派生的示例,它具有静态数据并可以打印当前列的 ID:
(define-derived-mode mymode tabulated-list-mode "mymode" "Major mode My Mode, just a test"
(setq tabulated-list-format [("Col1" 18 t)
("Col2" 12 nil)
("Col3" 10 t)
("Col4" 0 nil)])
(setq tabulated-list-padding 2)
(setq tabulated-list-sort-key (cons "Col3" nil))
(tabulated-list-init-header))
(defun print-current-line-id ()
(interactive)
(message (concat "current line ID is: " (tabulated-list-get-id))))
(defun my-listing-command ()
(interactive)
(pop-to-buffer "*MY MODE*" nil)
(mymode)
(setq tabulated-list-entries (list
(list "1" ["1" "2" "3" "4"])
(list "2" ["a" "b" "c" "d"])))
(tabulated-list-print t))
如果您查看您提到的包列表函数的代码,您会发现它使用派生自
package-menu-mode
的 tabulated-list-mode
。
find-function
RET package-menu-mode
RETtabulated-list-mode
RET我一直使用组织模式来完成此类任务。
这应该是您开发的起点,因为您已经有了不错的表格。
除了 tabulated-list 之外,还有 tblui.el,它提供了
tblui-define
一个宏,可以相当快速地创建 tabulated-list-mode
的派生主要模式。
除了更容易获取表格视图之外,它还提供了一种与 Magit 弹出窗口集成的简单方法。因此,您可以添加快速快捷键并按操作对它们进行分组。因此,创建基于“应用程序”的列表列表更简单。
tabulated-list 提供了获取该点的行条目或行 id 所需的函数:
(tabulated-list-get-entry)
和 (tabulated-list-get-id)
使用
(elt n entry)
获取第 n 列的内容(从零开始)
这是一个简单的例子...
(tblui-define ocodo/gh-run-list-tblui
"GitHub Workflow Runlist"
"Display workflow runs in a tabulated list."
ocodo/gh-run-list-entries-provider
[("startedAt" 15 nil)
("url" 1 nil)
("status" 10 nil)
("event" 10 nil)
("workflowName" 15 nil)]
((:key "w"
:name ocood/gh-run-list-browse
:funcs ((?W "Browse URL for current run" ocodo/gh-run-list-browse-row-url)))))
(ocodo/gh-run-list-entries-provider)
(defun ocodo/gh-run-list-browse-row-url ()
"Open the url for the current row."
(interactive)
(shell-command-to-string
(format "open \"%s\""
(elt (tabulated-list-get-entry) 1))))
我不会太深入地研究将 JSON 转换为 tblui 条目。
但是 tl;dr 是,您可以从(
(json-parse-string JSON-STRING)
的输出)映射 vector
的 alists
,转换为 list
的 lists
,其中包含条目 id (car)
和 vector
列值 (cdr)
。
我们定义的列需要与行向量中值的列位置匹配。因此,在我们的示例中,行条目如下所示:
;;(id [vector of col values])
(list 0 ["10m ago" "https://github.com/org/repo/actions/runs/60324234205" "completed" "push" "MyFlow"])
结构上:
(list
(list 0 [... column values ...])
(list 1 [... column values ...])
(list 2 [... column values ...])
(list 3 [... column values ...])
;; ... etc ...
)