大家好!我很高兴向大家正式发布 minuet-ai.el 插件。此前我曾在帖子中分享过直接调用大模型进行代码补全的方案,现在这个项目终于与大家见面了。
minuet-ai.el 是 Emacs 代码补全插件,其主要特点是:
- 直接通过 curl 调用大语言模型进行代码补全
- 支持两种补全模式:
- 基于 chat LLM 的 prompt building 方式,解析 LLM 的回答并构建补全方案。
- 通过 openai completion API 实现的 fill-in-the-middle (FIM) 方式
目前支持的模型包括:
- OpenAI
- Claude
- Gemini
- Codestral
- 所有兼容 OpenAI chat API 的模型(如 Fireworks、DeepSeek、Ollama)
- 所有兼容 OpenAI completion API 的模型(如 DeepSeek、Ollama)
插件提供了简单的配置方案,默认使用 DeepSeek 模型(需要提前设置 DEEPSEEK_API_KEY
环境变量)。此外,还有 Ollama 和 Gemini 的实例配置
默认使用 deepseek:
(straight-use-package '(minuet :host github :repo "milanglacier/minuet-ai.el"))
(use-package minuet
:init
(general-define-key
;; use completion-in-region for completion
"M-y" #'minuet-completion-region
;; use overlay for completion
"M-p" #'minuet-previous-suggestion ;; invoke completion or cycle to next completion
"M-n" #'minuet-next-suggestion ;; invoke completion or cycle to previous completion
"M-A" #'minuet-accept-suggestion ;; accept whole completion
"M-a" #'minuet-accept-suggestion-line ;; accept current line completion
"M-e" #'minuet-dismiss-suggestion)
;; 如需启用自动补全
;; 注意:即使不启用 minuet-auto-suggestion-mode,也可以手动触发补全
(add-hook 'prog-mode-hook #'minuet-auto-suggestion-mode)
:config
(setq minuet-provider 'openai-fim-compatible)
)
Ollama 版本
(use-package minuet
:init
(general-define-key
;; use completion-in-region for completion
"M-y" #'minuet-completion-region
;; use overlay for completion
"M-p" #'minuet-previous-suggestion ;; invoke completion or cycle to next completion
"M-n" #'minuet-next-suggestion ;; invoke completion or cycle to previous completion
"M-A" #'minuet-accept-suggestion ;; accept whole completion
"M-a" #'minuet-accept-suggestion-line ;; accept current line completion
"M-e" #'minuet-dismiss-suggestion)
;; 如需启用自动补全
;; 注意:即使不启用 minuet-auto-suggestion-mode,也可以手动触发补全
(add-hook 'prog-mode-hook #'minuet-auto-suggestion-mode)
:config
(setq minuet-provider 'openai-fim-compatible)
(plist-put minuet-openai-fim-compatible-options :end-point "http://localhost:11434/v1/completions")
;; an arbitrary non-null environment variable as placeholder
(plist-put minuet-openai-fim-compatible-options :name "Ollama")
(plist-put minuet-openai-fim-compatible-options :api-key "TERM")
(plist-put minuet-openai-fim-compatible-options :model "qwen2.5-coder:3b")
)
Gemini 版本
(use-package minuet
:init
(general-define-key
;; use completion-in-region for completion
"M-y" #'minuet-completion-region
;; use overlay for completion
"M-p" #'minuet-previous-suggestion ;; invoke completion or cycle to next completion
"M-n" #'minuet-next-suggestion ;; invoke completion or cycle to previous completion
"M-A" #'minuet-accept-suggestion ;; accept whole completion
"M-a" #'minuet-accept-suggestion-line ;; accept current line completion
"M-e" #'minuet-dismiss-suggestion)
;; 如需启用自动补全
;; 注意:即使不启用 minuet-auto-suggestion-mode,也可以手动触发补全
(add-hook 'prog-mode-hook #'minuet-auto-suggestion-mode)
:config
(setq minuet-provider 'gemini)
(minuet-set-optional-options minuet-gemini-options
:generationConfig
'(:maxOutputTokens 256
:topP 0.9))
(minuet-set-optional-options minuet-gemini-options
:safetySettings
[(:category "HARM_CATEGORY_DANGEROUS_CONTENT"
:threshold "BLOCK_NONE")
(:category "HARM_CATEGORY_HATE_SPEECH"
:threshold "BLOCK_NONE")
(:category "HARM_CATEGORY_HARASSMENT"
:threshold "BLOCK_NONE")
(:category "HARM_CATEGORY_SEXUALLY_EXPLICIT"
:threshold "BLOCK_NONE")])
)
最后上效果图:
欢迎大家试用,并感谢一切反馈和建议!