1+ function ! CopilotChat ()
2+ " Open a new split window for the chat
3+ split
4+ enew
5+ setlocal buftype = nofile
6+ setlocal bufhidden = hide
7+ setlocal noswapfile
8+ setlocal nonumber
9+ setlocal norelativenumber
10+ setlocal wrap
11+
12+ " Set the buffer name to indicate it's a chat window
13+ file CopilotChat
14+
15+ " Add initial message
16+ call append (0 , ' Welcome to Copilot Chat! Type your message below:' )
17+
18+ " Move cursor to the end of the buffer
19+ normal ! G
20+ endfunction
21+
22+ function ! SubmitChatMessage ()
23+ " Get the last line of the buffer (user's message)
24+ let l: message = getline (' $' )
25+
26+ " Call the CoPilot API to get a response
27+ let l: response = CopilotAPIRequest (l: message )
28+
29+ " Append the parsed response to the buffer
30+ call append (line (' $' ), ' Copilot: ' . l: response )
31+
32+ " Move cursor to the end of the buffer
33+ normal ! G
34+ endfunction
35+
36+ function ! GetBearerToken ()
37+ " Replace with actual token setup and device registry logic
38+ let l: token_url = ' https://github.com/login/device/code'
39+ " headers = {
40+ " 'accept': 'application/json',
41+ " 'editor-version': 'Neovim/0.6.1',
42+ " 'editor-plugin-version': 'copilot.vim/1.16.0',
43+ " 'content-type': 'application/json',
44+ " 'user-agent': 'GithubCopilot/1.155.0',
45+ " 'accept-encoding': 'gzip,deflate,br'
46+ " }
47+
48+ let l: token_headers = [
49+ \ ' Accept: application/json' ,
50+ \ ' User-Agent: GithubCopilot/1.155.0' ,
51+ \ ' Accept-Encoding: gzip,deflate,br' ,
52+ \ ' Editor-Plugin-Version: copilot.vim/1.16.0' ,
53+ \ ' Editor-Version: Neovim/0.6.1' ,
54+ \ ' Content-Type: application/json' ,
55+ \ ]
56+ let l: token_data = json_encode ({
57+ \ ' client_id' : ' Iv1.b507a08c87ecfe98' ,
58+ \ ' scope' : ' read:user'
59+ \ })
60+
61+ " Construct the curl command for token setup
62+ let l: curl_cmd = ' curl -s -X POST --compressed '
63+ for header in l: token_headers
64+ let l: curl_cmd .= ' -H "' . header . ' " '
65+ endfor
66+ let l: curl_cmd .= " -d '" . l: token_data . " ' " . l: token_url
67+ echom l: curl_cmd
68+
69+ " Execute the curl command
70+ let l: response = system (l: curl_cmd )
71+
72+ " Check for errors in the response
73+ if v: shell_error != 0
74+ echom ' Error: ' . v: shell_error
75+ return ' '
76+ endif
77+
78+ " Parse the response to get the device code and user code
79+ let l: json_response = json_decode (l: response )
80+ let l: device_code = l: json_response .device_code
81+ let l: user_code = l: json_response .user_code
82+ let l: verification_uri = l: json_response .verification_uri
83+
84+ " Display the user code and verification URI to the user
85+ echom ' Please visit ' . l: verification_uri . ' and enter the code: ' . l: user_code
86+
87+ " Wait for the user to complete the device verification
88+ sleep 30
89+
90+ " Poll the token endpoint to get the Bearer token
91+ let l: token_poll_url = ' https://github.com/login/oauth/access_token'
92+ let l: token_poll_data = json_encode ({
93+ \ ' client_id' : ' Iv1.b507a08c87ecfe98' ,
94+ \ ' device_code' : l: device_code ,
95+ \ ' grant_type' : ' urn:ietf:params:oauth:grant-type:device_code'
96+ \ })
97+
98+ " Construct the curl command for token polling
99+ let l: curl_cmd = ' curl -s -X POST --compressed '
100+ for header in l: token_headers
101+ let l: curl_cmd .= ' -H "' . header . ' " '
102+ endfor
103+ let l: curl_cmd .= " -d '" . l: token_poll_data . " ' " . l: token_poll_url
104+
105+ " Execute the curl command
106+ let l: response = system (l: curl_cmd )
107+
108+ " Check for errors in the response
109+ if v: shell_error != 0
110+ echom ' Error: ' . v: shell_error
111+ return ' '
112+ endif
113+
114+ " Parse the response to get the Bearer token
115+ let l: json_response = json_decode (l: response )
116+ let l: bearer_token = l: json_response .access_token
117+ let $COPILOT_BEARER_TOKEN = l: bearer_token
118+
119+ " Return the Bearer token
120+ return l: bearer_token
121+ endfunction
122+
123+ function ! GetChatToken ()
124+ let l: token_url = ' https://api.github.com/copilot_internal/v2/token'
125+ let l: token_headers = [
126+ \ ' Content-Type: application/json' ,
127+ \ ' Editor-Version: vscode/1.80.1' ,
128+ \ ' Authorization: token ' . $COPILOT_BEARER_TOKEN ,
129+ \ ]
130+ let l: token_data = json_encode ({
131+ \ ' client_id' : ' Iv1.b507a08c87ecfe98' ,
132+ \ ' scope' : ' read:user'
133+ \ })
134+
135+ " Construct the curl command for token setup
136+ let l: curl_cmd = ' curl -s -X GET '
137+ for header in l: token_headers
138+ let l: curl_cmd .= ' -H "' . header . ' " '
139+ endfor
140+ let l: curl_cmd .= " -d '" . l: token_data . " ' " . l: token_url
141+
142+ " Execute the curl command
143+ let l: response = system (l: curl_cmd )
144+ echom l: response
145+
146+ " Check for errors in the response
147+ if v: shell_error != 0
148+ echom ' Error: ' . v: shell_error
149+ return ' '
150+ endif
151+
152+ " Parse the response to get the device code and user code
153+ let l: json_response = json_decode (l: response )
154+ return l: json_response .token
155+ endfunction
156+
157+ function ! CopilotAPIRequest (message)
158+ " Replace with actual API call logic
159+ let l: url = ' https://api.githubcopilot.com/chat/completions'
160+ if exists (' $COPILOT_BEARER_TOKEN' )
161+ let l: bearer_token = $COPILOT_BEARER_TOKEN
162+ else
163+ let l: bearer_token = GetBearerToken ()
164+ endif
165+
166+ let l: chat_token = GetChatToken ()
167+ let l: headers = [
168+ \ ' Content-Type: application/json' ,
169+ \ ' Authorization: Bearer ' . l: chat_token ,
170+ \ ' Editor-Version: vscode/1.80.1'
171+ \ ]
172+ let l: messages = [{' content' : a: message , ' role' : ' user' }]
173+ let l: data = json_encode ({
174+ \ ' intent' : v: false ,
175+ \ ' model' : ' gpt-4o' ,
176+ \ ' temperature' : 0 ,
177+ \ ' top_p' : 1 ,
178+ \ ' n' : 1 ,
179+ \ ' stream' : v: true ,
180+ \ ' messages' : l: messages
181+ \ })
182+
183+ " Construct the curl command as a single string
184+ let l: curl_cmd = ' curl -s -X POST '
185+ for header in l: headers
186+ let l: curl_cmd .= ' -H "' . header . ' " '
187+ endfor
188+ let l: curl_cmd .= " -d '" . l: data . " ' " . l: url
189+
190+ " Print the curl command for debugging
191+ echom l: curl_cmd
192+
193+ " Execute the curl command
194+ let l: response = system (l: curl_cmd )
195+
196+ " Print the raw response for debugging
197+ echom ' Response: ' . l: response
198+
199+ " Check for errors in the response
200+ if v: shell_error != 0
201+ echom ' Error: ' . v: shell_error
202+ return ' Error: ' . l: response
203+ endif
204+
205+ " Parse the response
206+ let l: result = ' '
207+ let l: resp_text_lines = split (l: response , " \n " )
208+ for line in l: resp_text_lines
209+ if line = ~ ' ^data: {'
210+ let l: json_completion = json_decode (line [6 :])
211+ try
212+ let l: result .= l: json_completion .choices[0 ].delta.content
213+ catch
214+ let l: result .= ' \\n'
215+ endtry
216+ endif
217+ endfor
218+
219+ " Return the parsed response
220+ return l: result
221+ endfunction
222+
223+ " Map the command to open the chat
224+ command ! CopilotChat call CopilotChat ()
225+
226+ " Map the command to submit a chat message
227+ command ! SubmitChatMessage call SubmitChatMessage ()
228+
229+ " Add key mapping to submit chat message
230+ nnoremap <buffer> <leader> cs :SubmitChatMessage<CR>
0 commit comments