Package Control

The Sublime Text package directory, reassembled.

AhuAIComplete

Inline AI code completion (ghost text) for Sublime Text, with Ollama / OpenAI / OpenAI FIM backends.

AugJulJunMayAprMarFebJan Dec2025 NovOctSep 2026-W38 | installs: 1 | removals: 1 | upgrades: 1 2026-W38 | installs: 1 | removals: 1 | upgrades: 1 2026-W38 | installs: 1 | removals: 1 | upgrades: 1 024 WeeklyInstalls 024 WeeklyUpgrades 2026-W38 | upgrades: 1 1.0.8 / 1.0.7 2026-W32 1.0.6 / 1.0.5 / ... 1.0.6 / 1.0.5 / 1.0.4 / 1.0.3 / 1.0.2 / 1.0.1 / 1.0.0
Installations: 1 in total
Installations minus removals
Upgrades

Links

Versions

1.0.8 (>ST4000) ·
2026-09-17 23:41

More

AhuAIComplete

Inline AI code completion for Sublime Text 4, with the interaction model of Codeium / Copilot: grey ghost text appears at the cursor as you type, Tab accepts it, Esc dismisses it.

No vendor lock-in — a local Ollama instance, DeepSeek, OpenAI, or an internal vLLM / one-api deployment all work as long as the API is compatible. Zero third-party dependencies: Sublime's bundled Python is enough.

You type up to the opening bracket and pause:

typed:       return fib(n-1) + fib(
shown:       n-2)

The n-2) part appears at the cursor as grey ghost text; Tab inserts it.

Installation

Package Control — run Package Control: Install Package and pick AhuAIComplete.

From source, for hacking on the code. Clone the repository straight into the Packages directory; Sublime loads a package in place, so there is nothing to build and no installer to run:

cd ~/Library/Application\ Support/Sublime\ Text/Packages   # macOS
git clone https://github.com/ahu/AIComplete AhuAIComplete

Sublime reloads the package's top-level module when it is saved, but not the submodules under lib/, so a reloader is worth having while working on those — AutomaticPackageReloader does exactly that.

Once installed, run AhuAIComplete: Test Connection from the command palette. It sends one real request and prints the result in the output panel, so a misconfiguration is obvious at a glance.

Configuration

Preferences -> Package Settings -> AhuAIComplete -> Settings.

The default is a local Ollama:

ollama pull qwen2.5-coder:1.5b     # lightweight, fine for everyday use
ollama pull qwen2.5-coder:7b       # noticeably better, if your machine allows

To use a hosted service, change provider and fill in the matching block:

provider API Best for
ollama /api/generate + suffix Local models: private and free
openai_fim /completions + suffix Best for completion: real fill-in-the-middle
openai /chat/completions General fallback: works with any chat model

For example, the DeepSeek fill-in-the-middle endpoint:

{
    "provider": "openai_fim",
    "providers": {
        "openai_fim": {
            "base_url": "https://api.deepseek.com/beta",
            "api_key": "sk-...",
            "model": "deepseek-chat"
        }
    }
}

To keep the key out of the settings file, set the AICOMPLETE_API_KEY or OPENAI_API_KEY environment variable. Note that it must be exported in the shell that launches Sublime; starting the editor from the Dock will not pick it up.

Key bindings

Action macOS Windows / Linux
Accept the whole suggestion Tab Tab
Accept only the next word Ctrl+Option+-> Ctrl+Alt+->
Accept only the next line Ctrl+Option+Down Ctrl+Alt+Down
Dismiss Esc Esc
Request a completion manually Cmd+Shift+Enter Alt+\
Cycle candidates Cmd+Shift+[ / ] Alt+[ / ]

Each platform's bindings live in a single file, so Preferences -> Package Settings -> AhuAIComplete -> Key Bindings shows every shortcut at once.

macOS note: Option plus a key produces a composed character (Option+\ types «), so every shortcut that originally used Option became Cmd+Shift+... on macOS, which always matches. When a key does not work, AhuAIComplete: Request Completion in the command palette does the same thing independently of any key binding.

Tab is only taken over while a suggestion is visible and the autocomplete popup is not showing, so ordinary indentation and snippet navigation are unaffected.

For several candidates, set num_suggestions to 2 or 3 (the default is 3). openai and openai_fim use the API's n parameter to get them in one request; ollama does not support n, so it fires several parallel requests with different seeds instead. Running 3 with a local 1.5b model is cheap. When candidates are available, press Cmd+Shift+[ / ] (Windows / Linux: Alt+[ / ]) to cycle; a badge shows the current index.

How this differs from other completion packages

There is only one goal here — fast inline ghost text — so there is no chat panel, no "edit selection" command, and no setup wizard. Specifics:

A few design notes

Network requests stay off Sublime's async thread. Sublime's async worker is a single-threaded queue; putting HTTP on it would block every plugin's asynchronous events. Requests run on a separate daemon thread and only hop back to the main thread via set_timeout.

Suggestions are reused while you type. If the characters you keep typing match the beginning of the suggestion, it is trimmed in place and displayed again instead of triggering a new request — fewer tokens, no flicker. The 64 characters before the cursor are checksummed first, so edits elsewhere cannot shift the position unnoticed.

Stale responses are always discarded. Every view carries an incrementing token; a response is dropped when the token does not match, when change_count has moved on, or when the cursor is no longer in place.

Model output is cleaned before display. Models ramble, so lib/postprocess.py strips markdown fences, removes a repeated copy of the prefix, drops closing brackets that duplicate the suffix, truncates overly long output, and removes special tokens. This is the key step for completion quality and the focus of the test suite.

Triggering only happens at the end of a line. By default a request is only sent when nothing substantial follows the cursor (trailing whitespace, or closing characters such as ) ] } ; ,). Turn off trigger_only_at_line_end to trigger everywhere.

Tests

python3 tests/test_logic.py     # 41 pure logic tests, no Sublime needed
python3 tests/test_live.py      # hits a real backend, three completion cases
python3 tests/test_live.py ollama qwen2.5-coder:7b   # pick provider / model

Code layout

ai_complete.py          commands and event listeners (Sublime loads only the
                        .py files at the package root)
lib/settings.py         settings access, with environment-variable fallback
lib/context.py          prefix/suffix extraction, language detection,
                        cross-file context, trigger conditions
lib/client.py           HTTP for the three providers, standard library only
lib/postprocess.py      model-output cleaning pipeline
lib/ghost.py            phantom rendering of the grey suggestion
lib/engine.py           debounce, concurrency, stale-response dropping,
                        LRU cache, candidate management
examples/demo.py        scratch file for trying completions by hand
tests/                  pure-logic tests (no Sublime needed) and live tests

Troubleshooting

Enable "debug": true first; the log goes to the Sublime console (Ctrl+`).

Results

Packages