מימוש Add To Chat ב vim
ככל שהכלים הופכים יותר מתוחכמים ככה אנחנו מגלים שנהיה יותר קל לעבוד עם הכלים הפשוטים. בכל מקרה שיטת העבודה הנוכחית שלי עם הכלים האלה היא שילוב של:
לתת לסוכן שליטה מלאה, מתחילים במצב תכנון, מדברים על התוכנית ועוברים לממש. אני עובר על הקוד עם git status ו git diff אחרי שהכל מומש והבדיקות עברו.
לקרוא בעצמי קוד ולשאול את הסוכן שאלות קטנות או לתת לו לבנות קטעי קוד קטנים.
לפתוח דפדפן להצביע על דברים על המסך ולשאול את הסוכן איפה הקוד שמגדיר אותם.
כשחשבתי על חיבור AI ל vim התחלתי בחיפוש תוסף שיאפשר לי לסמן קטעי קוד ולשאול עליהם שאלות. מצאתי אחד שנקרא CopilotChat אבל מאוד לא נהניתי ממנו. ואז הבנתי שבעצם סוכן שורת פקודה יכול להשתלב מצוין בתהליך העבודה. זה עובד ככה:
מתוך neovim פותחים split, בצד אחד מפעילים terminal ובצד השני הקוד.
בתוך ה terminal מפעילים את קלוד קוד או קופיילוט או קודקס.
הממשק של הסוכן כבר כולל מנגנון לבחירת קבצים אם לוחצים @ מתוך הפרומפט אבל גם לקרסר וגם ל VS Code יש עוד כפתור בו אני משתמש המון שנקרא Add To Chat, כלומר מסמנים קוד בעורך לוחצים Add To Chat וזה מוסיף את קטע הקוד לשיחה עם הסוכן. מסתבר שבכלל לא מסובך לממש את זה ב neovim. זה הקוד שרשמתי בתוך init.vim:
lua << EOF
-- Define the function globally (or locally if you prefer)
function SendContextToTerminal()
-- 1. Get the current buffer info and selection marks
-- Note: When triggered via ":" command from visual mode, visual mode exits
-- automatically, populating the '< and '> marks.
local filepath = vim.fn.expand('%:.') -- Relative path to CWD
local start_line = vim.fn.line("'<")
local end_line = vim.fn.line("'>")
-- Format: path/to/file:40-59
local context_string = string.format("%s:%d-%d ", filepath, start_line, end_line)
-- 2. Find the terminal split
local term_chan = nil
local term_win = nil
-- Iterate over all open windows to find a terminal
for _, win in ipairs(vim.api.nvim_list_wins()) do
local buf = vim.api.nvim_win_get_buf(win)
if vim.bo[buf].buftype == 'terminal' then
term_chan = vim.bo[buf].channel
term_win = win
break
end
end
if not term_chan then
vim.notify("No terminal split found.", vim.log.levels.WARN)
return
end
-- 3. Send text to the terminal
vim.api.nvim_chan_send(term_chan, context_string)
-- 4. Switch to terminal window and enter Insert mode
vim.api.nvim_set_current_win(term_win)
vim.cmd('startinsert')
end
-- Create a user command so you can type :SendContext
vim.api.nvim_create_user_command('SendContext', SendContextToTerminal, {})
-- Set a keybinding for Visual Mode
-- We use :<C-u> to clear the range usually inserted by visual mode,
-- then call the lua function. The : command naturally exits visual mode, setting the marks.
vim.keymap.set("v", "<leader>ai", ":<C-u>lua SendContextToTerminal()<CR>", { silent = true, desc = "Send selection context to terminal" })
EOF
הפונקציה מחפשת את הקוד המסומן, מחפשת את ה terminal ושולחת את שם הקובץ ומספרי השורה לסוכן קידוד שרץ במסוף. הגדרתי גם קיצור מקלדת שקל לזכור leader ואז ai.
בינתיים הקוד עובד לי מעולה עם קופיילוט משורת הפקודה או קלוד קוד. לקלוד קוד יש גם חיבור לכרום אם אתם ממש רוצים להחליף את קרסר או שאפשר לחזור לקרסר בשביל לשלב דברים מתוך הדפדפן בשיחה.