|
| 1 | +;;; ai-code-kilo.el --- Thin wrapper for Kilo -*- lexical-binding: t; -*- |
| 2 | + |
| 3 | +;; Author: sirmacik <sirmacik@wioo.waw.pl> |
| 4 | +;; SPDX-License-Identifier: Apache-2.0 |
| 5 | + |
| 6 | +;;; Commentary: |
| 7 | +;; |
| 8 | +;; Thin wrapper that reuses `ai-code-backends-infra' to run Kilo. |
| 9 | +;; Provides interactive commands and aliases for the AI Code suite. |
| 10 | +;; |
| 11 | +;; Kilo is a fork of Opencode, an open-source alternative to Claude Code |
| 12 | +;; that provides HTTP server APIs and customization features (LSP, custom |
| 13 | +;; LLM providers, etc.) |
| 14 | +;; See: https://kilo.dev/ |
| 15 | +;; |
| 16 | +;;; Code: |
| 17 | + |
| 18 | +(require 'ai-code-backends) |
| 19 | +(require 'ai-code-backends-infra) |
| 20 | + |
| 21 | + |
| 22 | +(defgroup ai-code-kilo nil |
| 23 | + "Kilo integration via `ai-code-backends-infra.el'." |
| 24 | + :group 'tools |
| 25 | + :prefix "ai-code-kilo-") |
| 26 | + |
| 27 | +(defcustom ai-code-kilo-program "kilo" |
| 28 | + "Path to the Kilo executable." |
| 29 | + :type 'string |
| 30 | + :group 'ai-code-kilo) |
| 31 | + |
| 32 | +(defcustom ai-code-kilo-program-switches nil |
| 33 | + "Command line switches to pass to Kilo on startup." |
| 34 | + :type '(repeat string) |
| 35 | + :group 'ai-code-kilo) |
| 36 | + |
| 37 | +(defcustom ai-code-kilo-extra-env-vars |
| 38 | + '("OTUI_USE_ALTERNATE_SCREEN=main-screen") |
| 39 | + "Extra environment variables passed to the Kilo terminal session. |
| 40 | +`OTUI_USE_ALTERNATE_SCREEN=main-screen' avoids the alternate screen |
| 41 | +buffer so that terminal scrollback is partially preserved." |
| 42 | + :type '(repeat string) |
| 43 | + :group 'ai-code-kilo) |
| 44 | + |
| 45 | +(defconst ai-code-kilo--session-prefix "kilo" |
| 46 | + "Session prefix used in Kilo buffer names.") |
| 47 | + |
| 48 | +(defvar ai-code-kilo--processes (make-hash-table :test 'equal) |
| 49 | + "Hash table mapping Kilo session keys to processes.") |
| 50 | + |
| 51 | +;;;###autoload |
| 52 | +(defun ai-code-kilo (&optional arg) |
| 53 | + "Start Kilo (uses `ai-code-backends-infra' logic). |
| 54 | +With prefix ARG, prompt for CLI args using |
| 55 | +`ai-code-kilo-program-switches' as the default input." |
| 56 | + (interactive "P") |
| 57 | + (let* ((working-dir (ai-code-backends-infra--session-working-directory)) |
| 58 | + (resolved (ai-code-backends-infra--resolve-start-command |
| 59 | + ai-code-kilo-program |
| 60 | + ai-code-kilo-program-switches |
| 61 | + arg |
| 62 | + "Kilo")) |
| 63 | + (command (plist-get resolved :command))) |
| 64 | + (ai-code-backends-infra--toggle-or-create-session |
| 65 | + working-dir |
| 66 | + nil |
| 67 | + ai-code-kilo--processes |
| 68 | + command |
| 69 | + nil |
| 70 | + nil |
| 71 | + nil |
| 72 | + ai-code-kilo--session-prefix |
| 73 | + nil |
| 74 | + ai-code-kilo-extra-env-vars))) |
| 75 | + |
| 76 | +;;;###autoload |
| 77 | +(defun ai-code-kilo-switch-to-buffer (&optional force-prompt) |
| 78 | + "Switch to the Kilo buffer. |
| 79 | +When FORCE-PROMPT is non-nil, prompt to select a session." |
| 80 | + (interactive "P") |
| 81 | + (let ((working-dir (ai-code-backends-infra--session-working-directory))) |
| 82 | + (ai-code-backends-infra--switch-to-session-buffer |
| 83 | + nil |
| 84 | + "No Kilo session for this project" |
| 85 | + ai-code-kilo--session-prefix |
| 86 | + working-dir |
| 87 | + force-prompt))) |
| 88 | + |
| 89 | +;;;###autoload |
| 90 | +(defun ai-code-kilo-send-command (line) |
| 91 | + "Send LINE to Kilo. |
| 92 | +When called interactively, prompts for the command." |
| 93 | + (interactive "sKilo> ") |
| 94 | + (let ((working-dir (ai-code-backends-infra--session-working-directory))) |
| 95 | + (ai-code-backends-infra--send-line-to-session |
| 96 | + nil |
| 97 | + "No Kilo session for this project" |
| 98 | + line |
| 99 | + ai-code-kilo--session-prefix |
| 100 | + working-dir))) |
| 101 | + |
| 102 | +;;;###autoload |
| 103 | +(defun ai-code-kilo-resume (&optional arg) |
| 104 | + "Resume a previous Kilo session. |
| 105 | +
|
| 106 | +This command starts Kilo with the --continue flag to resume |
| 107 | +a specific past session. The CLI will present an interactive list of past |
| 108 | +sessions to choose from. |
| 109 | +
|
| 110 | +If current buffer belongs to a project, start in the project's root |
| 111 | +directory. Otherwise start in the directory of the current buffer file, |
| 112 | +or the current value of `default-directory' if no project and no buffer file. |
| 113 | +
|
| 114 | +With double prefix ARG (\\[universal-argument] \\[universal-argument]), |
| 115 | +prompt for the project directory." |
| 116 | + (interactive "P") |
| 117 | + (let ((ai-code-kilo-program-switches |
| 118 | + (append ai-code-kilo-program-switches '("--continue")))) |
| 119 | + (ai-code-kilo arg) |
| 120 | + (let* ((working-dir (ai-code-backends-infra--session-working-directory)) |
| 121 | + (buffer (ai-code-backends-infra--select-session-buffer |
| 122 | + ai-code-kilo--session-prefix |
| 123 | + working-dir))) |
| 124 | + (when buffer |
| 125 | + (with-current-buffer buffer |
| 126 | + (sit-for 0.5) |
| 127 | + (ai-code-backends-infra--terminal-send-string "") |
| 128 | + (goto-char (point-min))))))) |
| 129 | + |
| 130 | +(provide 'ai-code-kilo) |
| 131 | + |
| 132 | +;;; ai-code-kilo.el ends here |
0 commit comments