如何在 emacs 中显示自动完成选项?

发布于 2024-07-27 02:09:27 字数 2820 浏览 4 评论 0原文

我正在为 haxe 编程语言研究 emacs 中的自动完成实现。

我已经弄清楚如何获取我想要呈现的自动完成列表。 该列表的格式为:

'((name1 type1 desc1)
  (name2 type2 desc2) ...

我想向用户列表显示,其中包含光标位置后格式为“name1 type1”的文本(如自动完成模式)以及迷你缓冲区中当前所选项目的 desc。 用户应该能够像自动完成模式一样选择完成或放弃。

当用户选择某项时,name1 应插入到光标位置。

最好/最简单的方法是什么? 是否有一些标准的 emacs 方法可以做到这一点,或者我应该自己编写一些代码?

编辑:我有函数可以根据缓冲区获取自动完成候选列表。 现在我正在努力如何将其集成到自动完成模式中。 由于 get-completes 是繁重的操作,我想仅当光标位于“.”上时才触发它。 特点。

这是我的代码。

(defun get-completes-from-haxe (hxml-file file pos)
  (let* ((completion-buffer (get-buffer-create "*haxe-completions*"))
         (cmd (concat "cd " (file-name-directory hxml-file)  "; haxe " hxml-file " --display " file "@" (number-to-string pos))))
    (ignore-errors
      (shell-command cmd completion-buffer)
      (let ((clist (xml-parse-region 1 (buffer-size completion-buffer) completion-buffer))
            (completes nil))
        (dolist (s (cddar clist))
          (when (listp s)
            (let* ((item (cdr s))
                   (name (cdaar item))
                   (type (car (cddadr item)))
                   (desc (cdddr item)))
              (setf completes (cons name completes)))))
        completes))))

(defun file-find-upwards (buffer file-name)
  ;; Chase links in the source file and search in the dir where it  points.
  (setq dir-name (or (and (buffer-file-name buffer)
                          (file-name-directory (file-chase-links
                                                (buffer-file-name buffer))))
                     default-directory))
  ;; Chase links before visiting the file.  This makes it easier to
  ;; use a single file for several related directories.
  (setq dir-name (file-chase-links dir-name))
  (setq dir-name (expand-file-name dir-name))
  ;; Move up in the dir hierarchy till we find a change log file.
  (let ((file1 (concat dir-name file-name))
        parent-dir)
    (while (and (not (file-exists-p file1))
                (progn (setq parent-dir
                             (file-name-directory
                              (directory-file-name
                               (file-name-directory file1))))
                       ;; Give up if we are already at the root dir.
                       (not (string= (file-name-directory file1)
                                     parent-dir))))
      ;; Move up to the parent dir and try again.
      (setq file1 (expand-file-name file-name parent-dir)))
    ;; If we found the file in a parent dir, use that.  Otherwise,
    ;; return nil
    (if (or (get-file-buffer file1) (file-exists-p file1))
        file1
      nil)))


(defun get-candidate-list (buffer pos)
  (get-completes-from-haxe 
   (file-find-upwards buffer "compile.hxml") 
   (buffer-file-name buffer) 
   pos))

I'm working on autocompletion implementation in emacs for haxe programming language.

I already figured out how to obtain list of autocompletions which I wants to present. The list is in format:

'((name1 type1 desc1)
  (name2 type2 desc2) ...

I want to display to user list containing text in format "name1 type1" after cursor position (like in autocomplete-mode) and desc for currently selected item in minibuffer. User should be able to select completion or give up like in auto-complete mode.

When user select something, name1 should be inserted at cursor position.

What is the best/easiest way to do this? Is there some standard emacs way to do this, or I should code something on my own?

EDIT: I have functions to get the list of autocomplete candidates based on buffer. Now I'm struggling how to integrate that to autocomplete-mode. Since get-completes is heavy operation, I would like to trigger it only if cursor is on "." character.

Here's the code I have.

(defun get-completes-from-haxe (hxml-file file pos)
  (let* ((completion-buffer (get-buffer-create "*haxe-completions*"))
         (cmd (concat "cd " (file-name-directory hxml-file)  "; haxe " hxml-file " --display " file "@" (number-to-string pos))))
    (ignore-errors
      (shell-command cmd completion-buffer)
      (let ((clist (xml-parse-region 1 (buffer-size completion-buffer) completion-buffer))
            (completes nil))
        (dolist (s (cddar clist))
          (when (listp s)
            (let* ((item (cdr s))
                   (name (cdaar item))
                   (type (car (cddadr item)))
                   (desc (cdddr item)))
              (setf completes (cons name completes)))))
        completes))))

(defun file-find-upwards (buffer file-name)
  ;; Chase links in the source file and search in the dir where it  points.
  (setq dir-name (or (and (buffer-file-name buffer)
                          (file-name-directory (file-chase-links
                                                (buffer-file-name buffer))))
                     default-directory))
  ;; Chase links before visiting the file.  This makes it easier to
  ;; use a single file for several related directories.
  (setq dir-name (file-chase-links dir-name))
  (setq dir-name (expand-file-name dir-name))
  ;; Move up in the dir hierarchy till we find a change log file.
  (let ((file1 (concat dir-name file-name))
        parent-dir)
    (while (and (not (file-exists-p file1))
                (progn (setq parent-dir
                             (file-name-directory
                              (directory-file-name
                               (file-name-directory file1))))
                       ;; Give up if we are already at the root dir.
                       (not (string= (file-name-directory file1)
                                     parent-dir))))
      ;; Move up to the parent dir and try again.
      (setq file1 (expand-file-name file-name parent-dir)))
    ;; If we found the file in a parent dir, use that.  Otherwise,
    ;; return nil
    (if (or (get-file-buffer file1) (file-exists-p file1))
        file1
      nil)))


(defun get-candidate-list (buffer pos)
  (get-completes-from-haxe 
   (file-find-upwards buffer "compile.hxml") 
   (buffer-file-name buffer) 
   pos))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

柒七 2024-08-03 02:09:27

我建议使用优秀的 AutoComplete 包: http://www.emacswiki.org/emacs/AutoComplete

您可以定义自动完成的自定义源,这看起来相当简单。

I'd suggest the excellent package AutoComplete: http://www.emacswiki.org/emacs/AutoComplete

You can define custom sources for autocomplete and it seems fairly straight forward.

dawn曙光 2024-08-03 02:09:27

为什么要不断重新发明轮子? 公司模式支持几种语言

Why keep reinventing wheels? company-mode has support for a few languages

浴红衣 2024-08-03 02:09:27

来自 ido.el 的 ido-completing-read 是另一种方法。

它的一个有用的功能是您可以使用正则表达式来过滤掉候选者,并且您可以动态地打开和关闭此功能。 请参阅 ido.el 了解更多详细信息。

The ido-completing-read from ido.el is another way to do it.

An useful feature of it is that you can use regular expressions to filter out the candidates, and you can toggle this feature on and off on the fly. See ido.el for more details.

九局 2024-08-03 02:09:27

ido 包具有方便的完成功能,称为“ido-completing-read”。 例如,这里有一个简单的调整,可以使其逐行显示列表:

(defun x-ido-completing-read
  (prompt choices &optional predicate require-match initial-input hist def)
  (let* ((indent (concat "\n" (make-string (length prompt) ? )))
         (ido-decorations
         `("" "" ,indent ,(concat indent "...")
           "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]")))
    (ido-completing-read prompt choices predicate require-match initial-input hist def)))

ido package has convenient completion functionality called 'ido-completing-read'. For example, here's a simple tweak to make it show lists in a line-by-line basis:

(defun x-ido-completing-read
  (prompt choices &optional predicate require-match initial-input hist def)
  (let* ((indent (concat "\n" (make-string (length prompt) ? )))
         (ido-decorations
         `("" "" ,indent ,(concat indent "...")
           "[" "]" " [No match]" " [Matched]" " [Not readable]" " [Too big]")))
    (ido-completing-read prompt choices predicate require-match initial-input hist def)))
笑脸一如从前 2024-08-03 02:09:27

在 yasnippet 代码(可从 google 代码获取)内,他们使用 Jaeyoun Chung 的“dropdown-list.el”来显示可以在此时使用的可能片段。 这会在光标位置提供一个弹出(类似工具提示)菜单,您可以使用箭头键进行选择并输入,也可以按数字进行选择。

http://www.emacswiki.org/emacs/dropdown-list.el

Inside the yasnippet code, available from google code, they use 'dropdown-list.el' by Jaeyoun Chung to display the possible snippets that could be used at point. This gives a popup (tooltip-like) menu at the cursor position you can select with the arrow keys and enter or you can select by number.

http://www.emacswiki.org/emacs/dropdown-list.el

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文