Skip to content

Commit b69acf4

Browse files
committed
Support windows with Invoke-WebRequest + HttpIt helper function
1 parent d689c7d commit b69acf4

File tree

1 file changed

+84
-79
lines changed

1 file changed

+84
-79
lines changed

plugin/copilot_chat.vim

Lines changed: 84 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ scriptencoding utf-8
33
let s:plugin_dir = expand('<sfile>:p:h:h')
44
let s:device_token_file = s:plugin_dir . "/.device_token"
55
let s:chat_token_file = s:plugin_dir . "/.chat_token"
6+
let s:token_headers = [
7+
\ 'Accept: application/json',
8+
\ 'User-Agent: GithubCopilot/1.155.0',
9+
\ 'Accept-Encoding: gzip,deflate,br',
10+
\ 'Editor-Plugin-Version: copilot.vim/1.16.0',
11+
\ 'Editor-Version: Neovim/0.6.1',
12+
\ 'Content-Type: application/json',
13+
\ ]
614

715
function! CopilotChat()
816
" Open a new split window for the chat
@@ -31,78 +39,93 @@ function! SubmitChatMessage()
3139
call AsyncRequest(l:message)
3240
endfunction
3341

34-
function! GetBearerToken()
35-
let l:token_url = 'https://github.com/login/device/code'
36-
37-
let l:token_headers = [
38-
\ 'Accept: application/json',
39-
\ 'User-Agent: GithubCopilot/1.155.0',
40-
\ 'Accept-Encoding: gzip,deflate,br',
41-
\ 'Editor-Plugin-Version: copilot.vim/1.16.0',
42-
\ 'Editor-Version: Neovim/0.6.1',
43-
\ 'Content-Type: application/json',
44-
\ ]
45-
let l:token_data = json_encode({
46-
\ 'client_id': 'Iv1.b507a08c87ecfe98',
47-
\ 'scope': 'read:user'
48-
\ })
49-
50-
" Construct the curl command for token setup
51-
let l:curl_cmd = 'curl -s -X POST --compressed '
52-
for header in l:token_headers
53-
let l:curl_cmd .= '-H "' . header . '" '
54-
endfor
55-
let l:curl_cmd .= "-d '" . l:token_data . "' " . l:token_url
56-
57-
" Execute the curl command
58-
let l:response = system(l:curl_cmd)
59-
60-
" Check for errors in the response
61-
if v:shell_error != 0
62-
echom 'Error: ' . v:shell_error
63-
return ''
42+
function HttpIt(method, url, headers, body)
43+
if has("win32")
44+
let l:ps_cmd = 'powershell -Command "'
45+
let l:ps_cmd .= '$headers = @{'
46+
for header in a:headers
47+
let [key, value] = split(header, ": ")
48+
let l:ps_cmd .= "'" . key . "'='" . value . "';"
49+
endfor
50+
let l:ps_cmd .= "};"
51+
if a:method != "GET"
52+
let l:ps_cmd .= '$body = ConvertTo-Json @{'
53+
for obj in keys(a:body)
54+
let l:ps_cmd .= obj . "='" . a:body[obj] . "';"
55+
endfor
56+
let l:ps_cmd .= "};"
57+
endif
58+
let l:ps_cmd .= "Invoke-WebRequest -Uri '" . a:url . "' -Method " .a:method . " -Headers $headers -Body $body -ContentType 'application/json' | Select-Object -ExpandProperty Content"
59+
let l:ps_cmd .= '"'
60+
let l:response = system(l:ps_cmd)
61+
else
62+
let l:token_headers = [
63+
\ 'Accept: application/json',
64+
\ 'User-Agent: GithubCopilot/1.155.0',
65+
\ 'Accept-Encoding: gzip,deflate,br',
66+
\ 'Editor-Plugin-Version: copilot.vim/1.16.0',
67+
\ 'Editor-Version: Neovim/0.6.1',
68+
\ 'Content-Type: application/json',
69+
\ ]
70+
let l:token_data = json_encode(a:body)
71+
72+
" Construct the curl command for token setup
73+
let l:curl_cmd = 'curl -s -X POST --compressed '
74+
for header in a:headers
75+
let l:curl_cmd .= '-H "' . header . '" '
76+
endfor
77+
let l:curl_cmd .= "-d '" . l:token_data . "' " . l:token_url
78+
79+
let l:response = system(l:curl_cmd)
80+
81+
" Check for errors in the response
82+
if v:shell_error != 0
83+
echom 'Error: ' . v:shell_error
84+
return ''
85+
endif
6486
endif
87+
return l:response
88+
endfunction
89+
90+
function! GetDeviceToken()
91+
let l:token_url = 'https://github.com/login/device/code'
92+
let l:headers = [
93+
\ 'Accept: application/json',
94+
\ 'User-Agent: GithubCopilot/1.155.0',
95+
\ 'Accept-Encoding: gzip,deflate,br',
96+
\ 'Editor-Plugin-Version: copilot.vim/1.16.0',
97+
\ 'Editor-Version: Neovim/0.6.1',
98+
\ 'Content-Type: application/json',
99+
\ ]
100+
let l:data = {
101+
\ 'client_id': 'Iv1.b507a08c87ecfe98',
102+
\ 'scope': 'read:user'
103+
\ }
104+
105+
return HttpIt("POST", l:token_url, l:headers, l:data)
106+
endfunction
65107

66-
" Parse the response to get the device code and user code
108+
function! GetBearerToken()
109+
let l:response = GetDeviceToken()
67110
let l:json_response = json_decode(l:response)
68111
let l:device_code = l:json_response.device_code
69112
let l:user_code = l:json_response.user_code
70113
let l:verification_uri = l:json_response.verification_uri
71114

72-
" Display the user code and verification URI to the user
73115
echo 'Please visit ' . l:verification_uri . ' and enter the code: ' . l:user_code
74116
call input("Press Enter to continue...\n")
75117

76-
" Poll the token endpoint to get the Bearer token
77118
let l:token_poll_url = 'https://github.com/login/oauth/access_token'
78-
let l:token_poll_data = json_encode({
79-
\ 'client_id': 'Iv1.b507a08c87ecfe98',
80-
\ 'device_code': l:device_code,
81-
\ 'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'
82-
\ })
83-
84-
" Construct the curl command for token polling
85-
let l:curl_cmd = 'curl -s -X POST --compressed '
86-
for header in l:token_headers
87-
let l:curl_cmd .= '-H "' . header . '" '
88-
endfor
89-
let l:curl_cmd .= "-d '" . l:token_poll_data . "' " . l:token_poll_url
90-
91-
" Execute the curl command
92-
let l:response = system(l:curl_cmd)
93-
94-
" Check for errors in the response
95-
if v:shell_error != 0
96-
echom 'Error: ' . v:shell_error
97-
return ''
98-
endif
99-
100-
" Parse the response to get the Bearer token
101-
let l:json_response = json_decode(l:response)
119+
let l:token_poll_data = {
120+
\ 'client_id': 'Iv1.b507a08c87ecfe98',
121+
\ 'device_code': l:device_code,
122+
\ 'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'
123+
\ }
124+
let l:access_token_response = HttpIt("POST", l:token_poll_url, s:token_headers, l:token_poll_data)
125+
let l:json_response = json_decode(l:access_token_response)
102126
let l:bearer_token = l:json_response.access_token
103127
call writefile([l:bearer_token], s:device_token_file)
104128

105-
" Return the Bearer token
106129
return l:bearer_token
107130
endfunction
108131

@@ -113,29 +136,11 @@ function! GetChatToken(bearer_token)
113136
\ 'Editor-Version: vscode/1.80.1',
114137
\ 'Authorization: token ' . a:bearer_token,
115138
\ ]
116-
let l:token_data = json_encode({
139+
let l:token_data = {
117140
\ 'client_id': 'Iv1.b507a08c87ecfe98',
118141
\ 'scope': 'read:user'
119-
\ })
120-
121-
" Construct the curl command for token setup
122-
let l:curl_cmd = 'curl -s -X GET '
123-
for header in l:token_headers
124-
let l:curl_cmd .= '-H "' . header . '" '
125-
endfor
126-
let l:curl_cmd .= "-d '" . l:token_data . "' " . l:token_url
127-
128-
" Execute the curl command
129-
let l:response = system(l:curl_cmd)
130-
"echo l:response
131-
132-
" Check for errors in the response
133-
if v:shell_error != 0
134-
echom 'Error: ' . v:shell_error
135-
return ''
136-
endif
137-
138-
" Parse the response to get the device code and user code
142+
\ }
143+
let l:response = HttpIt("GET", l:token_url, l:token_headers, l:token_data)
139144
let l:json_response = json_decode(l:response)
140145
return l:json_response.token
141146
endfunction

0 commit comments

Comments
 (0)