使用 deepseek, claude, gemini,ollama 或者流行大模型进行代码补全,欢迎大家试用 minuet-ai.el

贴下自己的配置,没有任何保证,仅供参考

我平常用 codestral, 仅在非 emacs-lisp-mode 下使用补全

(require 'minuet)
(fun-my-bind-key-global "C-c p Z" #'minuet-configure-provider)
(fun-my-bind-key-keymap prog-mode-map "M-i" #'minuet-show-suggestion)
(fun-my-bind-key-keymap prog-mode-map "M-s-i" #'minuet-complete-with-minibuffer)
(fun-my-bind-key-keymap minuet-active-mode-map "M-i" #'minuet-accept-suggestion)
(fun-my-bind-key-keymap minuet-active-mode-map "M-p" #'minuet-previous-suggestion)
(fun-my-bind-key-keymap minuet-active-mode-map "M-n" #'minuet-next-suggestion)
(fun-my-bind-key-keymap minuet-active-mode-map "M-a" #'minuet-accept-suggestion-line)
(fun-my-bind-key-keymap minuet-active-mode-map "M-e" #'minuet-dismiss-suggestion)
(fun-my-bind-key-keymap minuet-active-mode-map "C-g" #'minuet-dismiss-suggestion)

(defun fun-my-record-buffer-modified-tick (&optional start end len)
  "Add to `after-change-functions'. This function should only be used in minuet-auto-suggestion-mode."
  (setq-local var-my-buffer-modified-tick (buffer-modified-tick (current-buffer)))
  (if (timerp var-my-buffer-modified-tick-timer)
      (cancel-timer var-my-buffer-modified-tick-timer)
    )
  (setq-local var-my-buffer-modified-tick-timer
              ;; ensure time delay here is greater than `minuet-auto-suggestion-throttle-delay' + `minuet-auto-suggestion-debounce-delay'
              (run-with-timer 6 nil
                              #'(lambda (buf)
                                  (when (buffer-live-p buf)
                                    (with-current-buffer buf
                                      (setq-local var-my-buffer-modified-tick 0)
                                      (setq-local var-my-buffer-modified-tick-timer nil)
                                      )
                                    )
                                  )
                              (current-buffer)
                              )
              )
  )

(defun fun-my-special-hook-for-minuet-auto-suggestion-mode ()
  "Hook function when enabling or disabling `minuet-auto-suggestion-mode'"
  (if minuet-auto-suggestion-mode
      (progn
        (defvar-local var-my-buffer-modified-tick nil
          "buffer-local variable to store result of `buffer-modified-tick'"
          )
        (defvar-local var-my-buffer-modified-tick-timer nil
          "timer to reset `var-my-buffer-modified-tick' to zero, which means buffer is not changed for a some time."
          )
        (add-to-list 'after-change-functions #'fun-my-record-buffer-modified-tick)
        )
    (setq-local after-change-functions (delq #'fun-my-record-buffer-modified-tick after-change-functions))
    )
  )
(add-hook 'minuet-auto-suggestion-mode-hook #'fun-my-special-hook-for-minuet-auto-suggestion-mode)

(defun fun-my-minuet-block-auto-suggest-p ()
  (cond
   (view-mode
    t
    )
   (buffer-read-only
    t
    )
   ((not (buffer-modified-p))
    t
    )
   ((equal var-my-buffer-modified-tick 0)
    t
    )
   (t
    nil)
   )
  )

(add-to-list 'minuet-auto-suggestion-block-functions #'fun-my-minuet-block-auto-suggest-p)

(setq minuet-provider 'codestral
      minuet-auto-suggestion-throttle-delay 1.2
      minuet-auto-suggestion-debounce-delay 0.6
      )
;; gemini
(plist-put minuet-gemini-options :model var-my-llm-model-gemini-code-completion)
(plist-put minuet-gemini-options :api-key (fun-my-authinfo-get-entry "gemini" "apikey"))
(minuet-set-optional-options minuet-gemini-options
                             :generationConfig
                             '(:maxOutputTokens 256
                                                :topP 0.9
                                                ;; disable thinking for faster completion retrieval.
                                                ;; :thinkingConfig (:thinkingBudget 0)
                                                ))
(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")])
;; openrouter
(plist-put minuet-openai-compatible-options :end-point "https://openrouter.ai/api/v1/chat/completions")
(plist-put minuet-openai-compatible-options :api-key (fun-my-authinfo-get-entry "openrouter.ai" "apikey"))
(plist-put minuet-openai-compatible-options :model var-my-llm-model-openrouter-code-completion)
;; optional settings
;; (minuet-set-optional-options minuet-openai-compatible-options :max_tokens 256)
;; (minuet-set-optional-options minuet-openai-compatible-options :top_p 0.9))
;; codestral
(plist-put minuet-codestral-options :api-key (fun-my-authinfo-get-entry "codestral" "apikey"))
;; optional settings
;; (minuet-set-optional-options minuet-codestral-options :stop ["\n\n"])
;; (minuet-set-optional-options minuet-codestral-options :max_tokens 256)

(defun fun-my-special-hook-for-enable-minuet ()
  (if (derived-mode-p 'emacs-lisp-mode)
      (minuet-auto-suggestion-mode -1)
    (minuet-auto-suggestion-mode 1)
    )
  )

;; do not enable auto suggest mode if using expensive/slow models
(defvar var-my-llm-model-expensive '(var-my-llm-model-gemini-code-completion))
(let ((provider (symbol-name minuet-provider)))
  (let ((popts (symbol-value (intern (format "minuet-%s-options" provider)))))
    (if (member (plist-get popts :model) var-my-llm-model-expensive)
        (setq minuet-request-timeout 10)
      (add-hook 'prog-mode-hook #'fun-my-special-hook-for-enable-minuet)
      )
    )
  )
1 个赞