لقد قمت ببناء وسياق Claude Code Context داخل Neovim

لقد كنت أستخدم الذكاء الاصطناعي للمساعدة في الترميز لفترة من الوقت الآن ، لكن الذهاب ذهابًا وإيابًا بين الكود و AI كان مملاً – حتى مع إعداد محسّن للغاية. لذلك قمت بدمج مساعدتي الرقمية ، كاي ، مباشرة في نيوفم.
المشكلة
عند العمل مع AI لتحرير التعليمات البرمجية ، فأنت تريد عادةً أحد هذه الإجراءات:
- يستبدل رمز محدد مع نسخة محسنة
- أدخل رمز جديد يعتمد على السياق
- عرض معلومات دون تعديل أي شيء
تجعلك معظم عمليات تكامل الذكاء الاصطناعي تخبرهم بالضبط بما يجب فعله. كاي يحدد إلى حد ما من الطريقة التي تسأل بها.
كيف تعمل
يعتمد هذا الأمر برمته على قدرة في رمز Claud على نحو كبير خضع لانتقاء. أنا فقط أفكر في وضع خط الأوامر.
- يمكنك أن تنشر في هذا الشيء
- يمكنك إعطائها سلسلة بعد ذلك وسوف تذهب وتنفذ فقط
- يمكنك حتى التحكم في كيفية استخدام سياقات مختلفة وكذا.
claude -p "What's the weather like in San Francisco right now?"
1
على أي حال ، هذا ما يحدث تحت الغطاء. إنه إصدار سطر الأوامر هذا من Claude Code ، ندعو فعليًا مع هذا المكون الإضافي.
بناء
يحتوي المكون الإضافي على قطعتان رئيسيتان:
- البرنامج المساعد لوا ((
kai-neovim.lua) – يتعامل مع تكامل Neovim ، والتحديدات المرئية ، وإدارة المخزن المؤقت - نص شل ((
kai-neovim.sh) – السياق معالجة ويتواصل مع الخلفية الذكاء الاصطناعى
معالجة السياق الذكي

يرسل المكون الإضافي دائمًا المخزن المؤقت بالكامل كسياق ، لكنه يركز بذكاء:
- نص محدد عندما تكون في الوضع المرئي
- موقف المؤشر عندما تكون في الوضع العادي
يوفر هذا النهج سياقًا شاملاً مع تمكين التعديلات الدقيقة المستهدفة بناءً على اختيارك الحالي أو موضع المؤشر.
اكتشاف العمل الذكي
يتيح لك المكون الإضافي إخباره بشكل أساسي بأي شيء ، ويحاول العمل عليه. فيما يلي بعض الأمثلة.
- “استبدال بـ X” → يحل محل الاختيار
- “إضافة تعليق يشرح” → إدراج بعد الاختيار
- “ماذا يفعل هذا؟” → يظهر التحليل في نافذة منبثقة
- “أدخل صورة مناسبة هنا.” → ينشئ صورة مخصصة وإدراجها في هذا الموقع
- “إصلاح الخطأ” → يستبدل بالرمز المصحح
هذا مجرد مجنون تماما. يمكننا فقط إرسال أشياء تعسفية وجعلها نوعًا ما. في الأساس ، تفاعل خط الأوامر مع الذكاء الاصطناعي. وداخل محرر النصوص.
الرمز
هذا هو الكود الأساسي لذلك ، ولكن ضع في اعتبارك أنه عمل مستمر. قد يكون القمامة الكلية. ونعم ، لقد ساعدني Kai في بنائه بالتأكيد.
رمز البرنامج المساعد الرئيسي
حفظ هذا كما ~/.config/nvim/lua/kai-neovim.lua:
local M = {}
-- Function to get visual selection
local function get_visual_selection()
-- Get the visual selection marks
local _, start_row, start_col, _ = unpack(vim.fn.getpos("'<"))
local _, end_row, end_col, _ = unpack(vim.fn.getpos("'>"))
-- Get the lines
local lines = vim.api.nvim_buf_get_lines(0, start_row - 1, end_row, false)
if #lines == 0 then
return ""
end
-- Handle single line selection
if #lines == 1 then
lines(1) = string.sub(lines(1), start_col, end_col)
else
-- Multi-line selection
lines(1) = string.sub(lines(1), start_col)
if end_col > 0 then
lines(#lines) = string.sub(lines(#lines), 1, end_col)
end
end
return table.concat(lines, "\n")
end
-- Function to escape special characters for shell
local function shell_escape(str)
return "'" .. str:gsub("'", "'\"'\"'") .. "'"
end
-- Main function to handle Kai Neovim integration
function M.kai_enhance()
-- Set up subtle blue highlight for the input prompt
vim.cmd('highlight KaiPrompt guifg=#e0e0e0 guibg=#1a1a2e')
-- Get the prompt from user with custom highlighting
vim.cmd('echohl KaiPrompt')
local prompt = vim.fn.input("🤖 Kai: ")
vim.cmd('echohl None')
if prompt == "" then
print("No instruction provided.")
return
end
-- Check if we're in visual mode
local mode = vim.fn.mode()
local is_visual = mode == 'v' or mode == 'V' or mode == ''
-- Get selection if in visual mode, empty string otherwise
local selection = ""
if is_visual then
selection = get_visual_selection()
end
-- Get current file path
local filepath = vim.fn.expand('%:p')
-- Get cursor position
local cursor_row, cursor_col = unpack(vim.api.nvim_win_get_cursor(0))
-- Get entire buffer content
local buffer_content = table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), "\n")
-- Create a temporary file for the context
local context_file = os.tmpname()
local f = io.open(context_file, "w")
f:write("CURRENT FILE: " .. filepath .. "\n\n")
-- Always send the entire buffer
f:write("FULL BUFFER CONTENT:\n" .. buffer_content .. "\n\n")
-- Add cursor position
f:write("CURSOR POSITION: Line " .. cursor_row .. ", Column " .. cursor_col .. "\n\n")
if is_visual then
-- Include selection information when text is selected
local _, start_row, start_col, _ = unpack(vim.fn.getpos("'<"))
local _, end_row, end_col, _ = unpack(vim.fn.getpos("'>"))
f:write("SELECTED TEXT (Lines " .. start_row .. "-" .. end_row .. "):\n" .. selection .. "\n\n")
f:write("MODE: User has selected specific text. Focus on this selection within the context of the entire buffer.\n\n")
else
-- When no selection, note cursor position
f:write("MODE: No selection. User's cursor is at line " .. cursor_row .. ". Make targeted changes based on cursor location unless instructed otherwise.\n\n")
end
f:write("INSTRUCTION: " .. prompt .. "\n")
f:close()
-- Call Kai script
local cmd = string.format(
"~/.config/nvim/scripts/kai-neovim.sh %s %s",
shell_escape(context_file),
shell_escape(prompt)
)
-- Create progress notification (simplified for blog post)
print("🤖 Processing with Kai...")
-- Execute command
local output = vim.fn.system(cmd)
-- Clean up temp file
os.remove(context_file)
-- Parse the action and content from the response
local lines = vim.split(output, '\n', { plain = true })
local action = lines(1)
local content_lines = {}
for i = 2, #lines do
if lines(i) ~= "" or i < #lines then
table.insert(content_lines, lines(i))
end
end
local content = table.concat(content_lines, '\n')
-- Remove any trailing newline
content = content:gsub('\n$', '')
-- Handle different actions
if action == "(ACTION:DISPLAY)" then
-- Create a floating window to display the analysis
local display_buf = vim.api.nvim_create_buf(false, true)
local display_lines = vim.split(content, '\n', { plain = true })
-- Calculate window dimensions
local width = math.min(80, vim.o.columns - 10)
local height = math.min(#display_lines + 2, vim.o.lines - 10)
-- Set buffer content
vim.api.nvim_buf_set_lines(display_buf, 0, -1, false, display_lines)
-- Create floating window
local display_win = vim.api.nvim_open_win(display_buf, true, {
relative = 'editor',
width = width,
height = height,
col = math.floor((vim.o.columns - width) / 2),
row = math.floor((vim.o.lines - height) / 2),
style = 'minimal',
border = 'rounded',
title = ' Kai Analysis ',
title_pos = 'center',
})
-- Set up keymaps to close the window
local close_keys = {'' , 'q', '' }
for _, key in ipairs(close_keys) do
vim.api.nvim_buf_set_keymap(display_buf, 'n', key,
':lua vim.api.nvim_win_close(' .. display_win .. ', true)' ,
{ noremap = true, silent = true })
end
print("Kai analysis complete! Press , q, or to close." )
return
end
-- Perform the appropriate action based on the marker
if is_visual then
if action == "(ACTION:REPLACE)" then
-- Replace the selection
local save_reg = vim.fn.getreg('"')
local save_regtype = vim.fn.getregtype('"')
vim.fn.setreg('"', content, mode == 'V' and 'V' or 'v')
vim.cmd('normal! gv"_d') -- Delete selection without affecting registers
vim.cmd('normal! P') -- Paste before cursor
vim.fn.setreg('"', save_reg, save_regtype)
elseif action == "(ACTION:INSERT_AFTER)" then
-- Insert after the selection
vim.cmd('normal! gv') -- Reselect
vim.cmd('normal! o') -- Go to end of selection
vim.cmd('normal! ') -- Exit visual mode
-- Insert a newline and the content
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
local content_lines_new = vim.split(content, '\n', { plain = true })
-- Insert empty line first, then content
vim.api.nvim_buf_set_lines(0, row, row, false, {""})
vim.api.nvim_buf_set_lines(0, row + 1, row + 1, false, content_lines_new)
end
else
-- Normal mode - insert at cursor position
local content_lines_new = vim.split(content, '\n', { plain = true })
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
-- Insert the lines at cursor position
vim.api.nvim_buf_set_text(0, row - 1, col, row - 1, col, content_lines_new)
end
print("Kai enhancement complete!")
end
-- Set up the keymap
function M.setup()
-- Visual mode mapping
vim.keymap.set('v', 'ai' , M.kai_enhance,
{ noremap = true, silent = true, desc = "Enhance with Kai (intelligent action)" })
-- Normal mode mapping (insert at cursor)
vim.keymap.set('n', 'ai' , M.kai_enhance,
{ noremap = true, silent = true, desc = "Insert Kai text at cursor" })
end
return M
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
نص شل
يخلق ~/.config/nvim/scripts/kai-neovim.sh:
#!/bin/bash
# Kai Neovim Enhancement Script with Intelligent Action Detection
# Usage: kai-neovim.sh
CONTEXT_FILE="$1"
PROMPT="$2"
# Check if claude CLI is available (we use it to communicate with Kai)
if ! command -v claude &> /dev/null; then
echo "Error: Claude CLI not found. Please install it first."
exit 1
fi
# Read the CLAUDE.md files for additional context (project-specific rules for Kai)
GLOBAL_CLAUDE_MD=""
LOCAL_CLAUDE_MD=""
if ( -f "$HOME/.claude/CLAUDE.md" ); then
GLOBAL_CLAUDE_MD=$(cat "$HOME/.claude/CLAUDE.md")
fi
# Find the nearest CLAUDE.md in the project
CURRENT_DIR=$(pwd)
while ( "$CURRENT_DIR" != "/" ); do
if ( -f "$CURRENT_DIR/CLAUDE.md" ); then
LOCAL_CLAUDE_MD=$(cat "$CURRENT_DIR/CLAUDE.md")
break
fi
CURRENT_DIR=$(dirname "$CURRENT_DIR")
done
# Regular text enhancement request - let Kai determine the action
FULL_PROMPT="You are Kai, an AI assistant integrated into Neovim.
CRITICAL CONTEXT FROM CLAUDE.md FILES (FOLLOW THESE RULES EXACTLY):
==================================================
GLOBAL CLAUDE.md:
$GLOBAL_CLAUDE_MD
PROJECT CLAUDE.md:
$LOCAL_CLAUDE_MD
==================================================
CURRENT EDITING CONTEXT:
$(cat "$CONTEXT_FILE")
CRITICAL: INTELLIGENT ACTION DETECTION
You must analyze the user's instruction to determine what they want:
1. If they say things like \"replace with\", \"change to\", \"rewrite as\", \"make this\", \"convert to\" → REPLACE the selected text
2. If they say things like \"write something like this\", \"create a note about\", \"add after\", \"insert\" → INSERT new content (don't replace)
3. If they say things like \"improve\", \"enhance\", \"fix\", \"correct\" → REPLACE with improved version
4. If they say things like \"explain this\", \"what is this\", \"analyze\", \"tell me about\", \"show me\", \"list\", \"count\", \"find\" → DISPLAY information (don't modify file)
IMPORTANT: When working with selected text, focus on that specific text within the context of the entire buffer. When working without selection, make targeted changes at the cursor location.
RESPONSE FORMAT:
You must start your response with ONE of these action markers on its own line:
(ACTION:REPLACE)
(ACTION:INSERT_AFTER)
(ACTION:INSERT_BEFORE)
(ACTION:DISPLAY)
Then on the next line, provide the content:
- For REPLACE/INSERT actions: provide ONLY the text to insert (no explanations)
- For DISPLAY actions: provide the analysis/information to show the user
IMPORTANT INSTRUCTIONS:
- First line must be the action marker
- Follow ALL formatting rules from CLAUDE.md
- Maintain the code style and conventions of the file
- Consider the context when generating content
- You are Kai, the AI assistant integrated into Neovim
User instruction: $PROMPT"
# Get the response with action marker
RESPONSE=$(echo "$FULL_PROMPT" | claude -p) # Using claude CLI to communicate with Kai
# Output the response
echo "$RESPONSE"
# Exit with the command's exit code
exit $?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
لا تنس أن تجعل البرنامج النصي قابل للتنفيذ:
chmod +x ~/.config/nvim/scripts/kai-neovim.sh
1
ملخص
حسنًا ، يجب أن تبدأ ذلك مع الهيكل لتنفيذك.
والآن يمكنك التحدث مباشرة إلى الذكاء الاصطناعي الخاص بك من داخل نيوفم!
