(defgroup ollama-complete nil "Ollama Code Completion." :group 'completion) (require 'plz) (defcustom ollama-complete-host "http://localhost:11434" "URL of local ollama service." :type 'url) (defcustom ollama-complete-model "qwen2.5-coder:3b-instruct-q4_K_M" "Model to use for Fill-in-Middle completion.") (defvar ollama-complete--options '(("temperature" . 0) ("top_p" . 0.5) ("num_predict" . 30))) (defvar ollama-complete--overlay nil) (defvar ollama-complete--overlay-buffer nil "Buffer in which the overlay is placed.") (defun ollama-complete--fill-in-middle () "Ask ollama to generate response for fill-in-middle prompt." (interactive) (let ((prompt (concat "<|fim_prefix|>" (concat (buffer-substring-no-properties (point-min) (point)) (concat "<|fim_suffix|>" (concat (buffer-substring-no-properties (point) (point-max)) "<|fim_middle|>")))))) (setq ollama-complete--overlay-buffer (current-buffer)) (message "overlay-buffer: %s" ollama-complete--overlay-buffer) (plz 'post (concat ollama-complete-host "/api/generate") :body (json-encode `(("model" . "qwen2.5-coder:3b-instruct-q4_K_M") ("raw" . t) ("stream" . :json-false) ("options" . ,ollama-complete--options) ("prompt" . ,prompt) )) :as #'json-read :then (lambda (alist) (message "Ollama: FIM Completion: %s" (alist-get 'response alist)) (ollama-complete--make-overlay (alist-get 'response alist)))) ) ) (defun ollama-complete--make-overlay (string) "make overlay showign STRING at POS, or move existing overlay there." (interactive) (if ollama-complete--overlay-buffer (with-current-buffer ollama-complete--overlay-buffer (message "make-overlay %d \"%s\" %s" (point) string ollama-complete--overlay-buffer) (if ollama-complete--overlay (move-overlay ollama-complete--overlay (point) (point) ollama-complete--overlay-buffer) (setq ollama-complete--overlay (make-overlay (point) (point) ollama-complete--overlay-buffer)) (overlay-put ollama-complete--overlay 'window (selected-window)) (overlay-put ollama-complete--overlay 'after-string (propertize string 'face 'font-lock-comment-face)) (add-text-properties 0 1 '(cursor 1) string) ollama-complete--overlay))) ) (defun ollama-complete--hide-overlay () "Hide temporary completion candidate overlay." (interactive) (when ollama-complete--overlay (delete-overlay ollama-complete--overlay) (setq ollama-complete--overlay nil) (setq ollama-complete--overlay-buffer nil)) ) (defun ollama-complete--insert-completion () "Hide temporary completion candidate overlay." (interactive) (when ollama-complete--overlay (let ((completion (overlay-get ollama-complete--overlay 'after-string))) (set-text-properties 0 (length completion) nil completion) (goto-char (overlay-start ollama-complete--overlay)) (insert (substring-no-properties completion))) (ollama-complete--hide-overlay))) (provide 'ollama-complete)