AizuDemy

Bikin Plugin AI Autocomplete Neovim Sendiri Pakai Lua dan Ollama Lokal

Bikin Plugin AI Autocomplete Neovim Sendiri Pakai Lua dan Ollama Lokal
IKLAN
IDCloudHost
๐ŸŽง
Dengarkan Artikel Ini
Suara AI Otomatis โ€ข 8 mnt baca baca
โšก TL;DR

Poin Kunci Artikel Ini:

  • Kapan Terakhir Kali Kode Rahasia Anda Terkirim ke Cloud?
  • Bagi yang terikat aturan NDA ketat atau menangani proyek internal kantor, momen itu rasanya mirip seperti gak sengaja membeberkan isi dompet di keramaian.
  • Layanan AI autocomplete keren berbasis cloud seperti GitHub Copilot memang bikin kita ketagihan karena produktivitas melonjak.
๐Ÿ“‹ Daftar Isi Materi Tutup โ–ด

Kapan Terakhir Kali Kode Rahasia Anda Terkirim ke Cloud?

Pernah gak sih tiba-tiba panik pas lagi asyik ngetik konfigurasi database produksi atau algoritma rahasia perusahaan, terus sadar kalau plugin AI autocomplete di editor kamu lagi sibuk ngirim potongan kode itu ke server publik di luar negeri? Bagi yang terikat aturan NDA ketat atau menangani proyek internal kantor, momen itu rasanya mirip seperti gak sengaja membeberkan isi dompet di keramaian.

Layanan AI autocomplete keren berbasis cloud seperti GitHub Copilot memang bikin kita ketagihan karena produktivitas melonjak. Tapi di balik kemudahan itu, ada harga mahal yang harus dibayar: privasi data yang rawan, ketergantungan penuh pada koneksi internet, plus biaya langganan bulanan yang makin lama makin menguras kantong.

Untungnya, ada jalan pintas yang jauh lebih aman dan gratis. Kita bisa menjalankan model bahasa raksasa (LLM) khusus coding langsung di laptop sendiri pakai Ollama, lalu menyambungkannya secara mulus ke Neovim memanfaatkan bahasa Lua. Artikel ini bakal menuntun kamu meracik plugin AI autocomplete lokal dari nol sampai siap dipakai harian.

1. Kenapa Kombinasi Neovim, Lua, dan Ollama Itu Pas Banget?

Bayangkan Neovim sebagai mobil balap rakitan sendiri: ringan, cepat, dan setiap komponennya bisa kamu bongkar pasang sesuai selera. Sejak versi 0.5 diluncurkan, Neovim menjadikan Lua sebagai bahasa konfigurasi utama menggantikan Vimscript yang agak rumit. Eksekusi Lua di Neovim ditopang oleh arsitektur LuaJIT yang super kencang, sehingga kita bisa mengakses event loop sistem operasi secara langsung lewat modul vim.loop (atau vim.uv jika kamu sudah pakai Neovim 0.10 ke atas).

Di sisi lain, Ollama hadir seperti garasi pintar tempat menyimpan berbagai mesin LLM lokal modern seperti CodeLlama, DeepSeek-Coder, atau Qwen2.5-Coder. Ollama menyediakan antarmuka REST API lokal yang sangat praktis di alamat http://localhost:11434. Saat kita mengawinkan Neovim, Lua, dan Ollama, kita mendapatkan tiga keuntungan besar sekaligus:

  • Privasi 100% Terjaga: Seluruh teks dan konteks baris kode kamu tidak akan pernah keluar dari harddisk laptop. Aman total untuk proyek rahasia kantor atau lingkungan jaringan tertutup (air-gapped).
  • Bebas Biaya Tagihan: Tak perlu lagi pusing memikirkan kartu kredit atau sewa API bulanan. Manfaatkan saja kekuatan GPU atau CPU laptop yang sudah ada.
  • Bebas Kustomisasi: Kamu memegang kendali penuh. Ingin mengubah prompt sistem, membatasi panjang baris yang dibaca, atau memilih model AI yang berbeda untuk bahasa C dan Python? Semuanya bisa diatur sesuai keinginan.

2. Memahami Arsitektur Asynchronous via vim.loop

Salah satu jebakan batman saat pemula membuat plugin Neovim adalah menjalankan proses I/O secara synchronous (blocking). Bayangkan jika plugin kamu mengirim HTTP request ke Ollama dan menunggu jawaban selesai sebelum mengembalikan kontrol ke editor. Setiap kali AI berpikir selama satu detik, layar Neovim kamu bakal membeku total (freeze). Tombol keyboard tidak merespons, kursor mati, dan pengalaman mengetik berubah jadi mimpi buruk.

Agar proses mengetik tetap mulus tanpa lag, kita wajib memakai pendekatan asynchronous menggunakan vim.loop. Dengan cara ini, Neovim akan menyuruh proses latar belakang (misalnya perintah curl) untuk mengambil jawaban AI, sementara kamu tetap bebas ngetik tanpa gangguan sedikit pun. Setelah AI selesai berpikir, hasilnya baru disisipkan secara halus ke dalam editor.

Struktur Folder Plugin Sederhana

Mari kita buat direktori plugin baru di dalam folder konfigurasi Neovim kamu. Buka terminal dan buat struktur folder seperti ini:

~/.config/nvim/
โ”œโ”€โ”€ lua/
โ”‚   โ””โ”€โ”€ custom/
โ”‚       โ””โ”€โ”€ plugins/
โ”‚           โ””โ”€โ”€ ollama_complete.lua

3. Praktik Coding: Membuat Custom Source untuk nvim-cmp

Mayoritas pengguna Neovim menggunakan nvim-cmp sebagai mesin autocomplete utama. Kita akan membuat sebuah custom source sederhana yang bertugas mengambil saran kode dari endpoint Ollama /api/generate.

Buka berkas ollama_complete.lua yang baru kamu buat, lalu masukkan kode Lua berikut:

local cmp = require('cmp')
local Job = require('plenary.job')

local Source = {}

function Source:new()
  local source = setmetatable({}, { __index = Source })
  return source
end

function Source:is_available()
  return true
end

function Source:get_debug_name()
  return 'ollama'
end

function Source:get_keyword_pattern()
  return [[\%(\k\|\.\)]]
end

function Source:complete(params, callback)
  local cursor_line = params.context.cursor.line
  
  -- Ambil 20 baris di atas kursor sebagai konteks prompt
  local start_line = math.max(0, cursor_line - 20)
  local lines = vim.api.nvim_buf_get_lines(0, start_line, cursor_line, false)
  local prompt_text = table.concat(lines, "\n")

  -- Payload JSON untuk Ollama REST API
  local payload = {
    model = "qwen2.5-coder:1.5b",
    prompt = prompt_text,
    stream = false,
    options = {
      temperature = 0.2,
      num_predict = 64,
    }
  }

  local json_body = vim.fn.json_encode(payload)

  -- Eksekusi curl HTTP POST secara asynchronous
  Job:new({
    command = 'curl',
    args = {
      '-s',
      '-X', 'POST',
      'http://localhost:11434/api/generate',
      '-H', 'Content-Type: application/json',
      '-d', json_body
    },
    on_exit = function(j, return_val)
      if return_val ~= 0 then
        callback({ items = {}, incomplete = false })
        return
      end

      local response_text = table.concat(j:result(), "\n")
      local ok, decoded = pcall(vim.fn.json_decode, response_text)

      if not ok or not decoded or not decoded.response then
        callback({ items = {}, incomplete = false })
        return
      end

      local completion_text = decoded.response
      
      -- Format item agar sesuai dengan standar nvim-cmp
      local items = {
        {
          label = completion_text:sub(1, 40) .. "...",
          insertText = completion_text,
          detail = "[Ollama AI]",
          kind = cmp.lsp.CompletionItemKind.Snippet,
        }
      }

      vim.schedule(function()
        callback({ items = items, incomplete = false })
      end)
    end,
  }):start()
end

cmp.register_source('ollama', Source:new())

Mari kita bedah cara kerja skrip di atas secara praktis:

  • Fungsi Source:complete dipanggil oleh nvim-cmp saat pengguna mengetik di editor.
  • Kita mengambil 20 baris kode terakhir di atas posisi kursor menggunakan vim.api.nvim_buf_get_lines sebagai konteks prompt agar AI mengerti apa yang sedang kita kerjakan.
  • Payload JSON dikirim ke Ollama secara asynchronous lewat objek Job milik library plenary.nvim yang menjalankan perintah curl di latar belakang.
  • Setelah Ollama selesai merespons, hasilnya diformat menjadi item autocomplete dan dikirim balik ke nvim-cmp via fungsi callback.

4. Optimasi Latensi: Mengatasi Kemacetan Request dengan Debouncing

Jika skrip di atas langsung digunakan begitu saja, kamu bakal melihat laptop mulai terasa hangat dan kipas berputar kencang. Mengapa? Karena setiap kali kamu mengetik satu karakter, Neovim akan menembakkan satu request baru ke Ollama. Jika kamu mengetik 10 karakter dalam 2 detik, akan ada 10 proses inferensi AI yang berjalan bersamaan di latar belakang. Latensi bakal membengkak dan laptop jadi lemot.

Analogi sederhananya seperti di restoran: jika kamu memanggil pelayan setiap kali membaca satu kata di menu makanan, pelayan akan bolak-balik ke dapur dan suasana jadi kacau. Lebih baik baca dulu seluruh menu, baru panggil pelayan sekali.

Penerapan Teknik Debouncing dengan Timer Native

Debouncing berfungsi menunda pengiriman request ke Ollama sampai kamu benar-benar berhenti mengetik selama jeda waktu tertentu (misalnya 300 milidetik). Jika kamu mengetik karakter baru sebelum 300ms selesai, timer lama dibatalkan dan diganti timer baru.

Berikut cara menyisipkan teknik debouncing menggunakan timer bawaan vim.loop:

local timer = vim.loop.new_timer()
local pending_job = nil

local function trigger_debounced_ollama(prompt, callback_fn)
  timer:stop()
  
  if pending_job then
    pending_job:shutdown()
    pending_job = nil
  end

  timer:start(300, 0, vim.schedule_wrap(function()
    local payload = vim.fn.json_encode({
      model = "qwen2.5-coder:1.5b",
      prompt = prompt,
      stream = false
    })

    pending_job = Job:new({
      command = 'curl',
      args = {
        '-s', '-X', 'POST', 'http://localhost:11434/api/generate',
        '-H', 'Content-Type: application/json',
        '-d', payload
      },
      on_exit = function(j, code)
        pending_job = nil
        if code == 0 then
          local res = table.concat(j:result(), "\n")
          local ok, data = pcall(vim.fn.json_decode, res)
          if ok and data and data.response then
            callback_fn(data.response)
          end
        end
      end
    })
    pending_job:start()
  end))
end

Streaming Token vs Single Payload

Selain debouncing, kamu juga bisa memanfaatkan fitur streaming response (NDJSON) dari Ollama. Jika kamu memakai model AI yang agak berat (seperti ukuran 7B parameters), menunggu seluruh kalimat selesai dibuat bisa memakan waktu 2-3 detik.

Dengan mengaktifkan opsi stream = true, Ollama akan mengirimkan jawaban per kata (token). Kita bisa menangkap setiap token yang datang lalu menyisipkannya langsung di depan kursor sebagai bayangan teks (virtual text) menggunakan API vim.api.nvim_buf_set_extmark. Efeknya, saran AI langsung terlihat secara real-time seperti halnya GitHub Copilot asli.

5. Memilih Model LLM Lokal yang Pas untuk Hardware Kamu

Kunci utama agar pengalaman coding tetap nyaman adalah memilih model yang seimbang antara kecepatan dan kecerdasan, disesuaikan dengan spesifikasi komputer yang kamu miliki:

  • Qwen2.5-Coder 1.5B: Pilihan paling pas untuk laptop standar tanpa GPU diskrit atau RAM terbatas. Prosesnya super cepat, hemat konsumsi VRAM/RAM (~2GB), dan sangat responsif untuk penyelesaian sintaks dasar.
  • DeepSeek-Coder 1.3B: Memiliki pemahaman sintaksis yang luar biasa tajam untuk bahasa seperti C++, Rust, Python, dan TypeScript. Latensinya sangat rendah.
  • CodeLlama 7B atau Qwen2.5-Coder 7B: Pilihan terbaik jika kamu memiliki laptop dengan GPU dedicated (minimal VRAM 6GB ke atas). Model ini sangat andal menyelesaikan fungsi rumit dan mampu memahami konteks kode yang panjang.

6. Pengaturan Keybinding Agar Workflow Tetap Mulus

Agar alur mengetik tidak terganggu oleh pop-up autocomplete AI yang muncul sembarangan, ada baiknya kamu mengatur tombol pintas (keybinding) manual. Dengan begitu, AI hanya akan bekerja saat kamu memang memanggilnya.

Tambahkan konfigurasi keybinding berikut di dalam file konfigurasi Neovim kamu:

vim.keymap.set('i', '', function()
  require('cmp').complete({ config = { sources = { { name = 'ollama' } } } })
end, { silent = true, desc = "Trigger AI Autocomplete" })

vim.keymap.set('i', '', function()
  if require('cmp').visible() then
    require('cmp').confirm({ select = true })
  end
end, { silent = true, desc = "Accept AI Completion" })

Dengan kombinasi di atas, kamu cukup menekan Ctrl + g di Mode Insert saat butuh ide kelanjutan kode, lalu tekan Ctrl + y untuk menerima saran dari AI.

Kesimpulan & Langkah Selanjutnya

Bikin plugin AI autocomplete sendiri di Neovim ternyata tidak serumit yang dibayangkan, bukan? Dengan memadukan kelincahan Lua, arsitektur async vim.loop, dan mesin lokal Ollama, kamu kini punya asisten coding pribadi yang super cepat, 100% privat, dan tanpa biaya bulanan sama sekali.

Tunggu apa lagi? Buka terminal kamu sekarang, jalankan perintah ollama run qwen2.5-coder:1.5b, pasang skrip Lua di atas, dan nikmati sensasi koding canggih berbasis AI tanpa perlu khawatir kode rahasia kamu bocor ke cloud!

A
Aizu Dev

Tim penulis AizuDemy yang menyajikan tutorial teknologi, cloud, dan pengembangan perangkat lunak dalam Bahasa Indonesia.

๐Ÿ’ฌ Komentar (0)

Tulis Komentar

๐Ÿ“– Artikel Terkait