如何在Emacs Lisp中创建列视图?

17

我正在使用Elisp编写自己的模式。它基本上是一个简单的crud应用程序,显示可以通过minibuffer操作的数据行。我想为这些行创建一个视图,看起来像emacs包管理器:数据列整齐地对齐。实现这样的视图的最佳方式是什么?

4个回答

26

phils 的回答让我找到了方向。虽然没有任何教程或简单的例子,但我创建了一个。这是一个带有静态数据并可以打印当前列 ID 的 tabulated-list-mode 派生示例:

(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))

2

如果您查看您提到的包列表功能的代码,您会发现它使用了package-menu-mode,该模式派生自tabulated-list-mode

  • M-x find-function RET package-menu-mode RET
  • C-hf tabulated-list-mode RET

0

我经常使用org-mode来完成这种任务。

因为你已经有了漂亮的表格,所以这应该是你开发的起点。


0
除了tabulated-list之外,还有tblui.el,它提供了一个宏tblui-define,可以快速创建一个派生自tabulated-list-mode的主模式。
除了更容易获取表格视图之外,它还提供了一种与magit弹出窗口集成的简单方法。因此,您可以添加快捷键并按操作进行分组。因此,创建基于表格的“应用程序”更加简单。
这是一个简单的示例...
(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" ;; tiny popup
                :name browse-row-url
                :funcs ((?W "Browse URL for current run" ocodo/gh-run-list-browse-row-url)))))

这些条目必须由一个函数提供,我们正在使用。
(ocodo/gh-run-list-entries-provider)

这个功能会获取并转换一个 GitHub 的 JSON 运行列表,并使其适用于 tabulated-list(下面会详细介绍)。
对于弹出窗口功能,我们还有一个小型的弹出窗口定义,它调用一个函数来在行上打开一个 URL。
(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))))

tabulated-list提供了你在某个位置获取行条目或行ID所需的函数:
(tabulated-list-get-entry)和(tabulated-list-get-id)
使用(elt n entry)来获取第n列(从零开始)的内容
数据转换
我不会深入探讨如何将JSON转换为tblui条目。
但是简而言之,你需要从(json-parse-string JSON-STRING)的输出中映射一个包含关联列表(alists)的向量(vector),然后将其转换为包含条目ID(car)和列值向量(cdr)的列表(list)。
我们定义的列需要与行向量中的值的列位置相匹配。所以,在我们的例子中,行条目将会是这样的:
;;(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 ... 
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接