@@ -36,62 +36,6 @@ function! copilot#HttpRequest(url, options, ...) abort
3636 return call (' copilot#Call' , [' httpRequest' , extend ({' url' : a: url , ' timeout' : 30000 }, a: options )] + a: 000 )
3737endfunction
3838
39- unlet ! s: github
40- function ! s: OAuthToken () abort
41- if exists (' s:github' )
42- return get (s: github , ' oauth_token' , ' ' )
43- endif
44- if getfsize (s: config_hosts ) > 0
45- try
46- let s: github = get (json_decode (join (readfile (s: config_hosts ))), ' github.com' , {})
47- catch
48- let s: github = {}
49- endtry
50- else
51- return ' '
52- endif
53- return get (s: github , ' oauth_token' , {})
54- endfunction
55-
56- function ! s: OAuthUser (token) abort
57- if len (a: token )
58- let user_response = copilot#HttpRequest (' https://api.github.com/user' , {' headers' : {' Authorization' : ' Bearer ' . a: token }})
59- let user_data = s: JsonBody (user_response)
60- if get (user_response, ' status' ) == 200 && has_key (user_data, ' login' )
61- return user_data.login
62- endif
63- endif
64- return ' '
65- endfunction
66-
67- function ! s: OAuthSave (token, user ) abort
68- unlet ! s: terms_accepted
69- if len (a: token ) && len (a: user )
70- let s: github = {' oauth_token' : a: token , ' user' : a: user }
71- call writefile (
72- \ [json_encode ({" github.com" : s: github })],
73- \ s: config_hosts )
74- return 1
75- endif
76- let s: github = {}
77- call delete (s: config_hosts )
78- endfunction
79-
80- function ! s: OAuthUserCallback (token, response) abort
81- try
82- let user_data = s: JsonBody (a: response )
83- if get (a: response , ' status' ) == 200 && has_key (user_data, ' login' )
84- let s: github = {' oauth_token' : a: token , ' user' : user_data.login}
85- endif
86- catch
87- call copilot#logger#Exception ()
88- endtry
89- endfunction
90-
91- if ! exists (' s:github' ) && $CODESPACES == # ' true' && len ($GITHUB_TOKEN )
92- let s: github = {' oauth_token' : $GITHUB_TOKEN , ' user' : empty ($GITHUB_USER ) ? ' codespace-user' : $GITHUB_USER }
93- endif
94-
9539function ! s: StatusNotification (params, ... ) abort
9640 let status = get (a: params , ' status' , ' ' )
9741 if status == ? ' error'
@@ -143,9 +87,6 @@ function! copilot#Notify(method, params, ...) abort
14387 return call (agent.Notify, [a: method , a: params ] + a: 000 )
14488endfunction
14589
146- let s: terms_version = ' 2021-10-14'
147- unlet ! s: terms_accepted
148-
14990function ! s: ReadTerms () abort
15091 let file = s: config_root . ' /terms.json'
15192 try
@@ -160,23 +101,6 @@ function! s:ReadTerms() abort
160101 return {}
161102endfunction
162103
163- function ! s: TermsAccepted (force_reload) abort
164- if exists (' s:terms_accepted' ) && ! a: force_reload
165- return s: terms_accepted
166- endif
167- call s: OAuthToken ()
168- let file = s: config_root . ' /terms.json'
169- if exists (' s:github.user' ) && filereadable (file )
170- try
171- let s: terms_accepted = s: ReadTerms ()[s: github .user ].version >= s: terms_version
172- return s: terms_accepted
173- catch
174- endtry
175- endif
176- let s: terms_accepted = 0
177- return s: terms_accepted
178- endfunction
179-
180104function ! copilot#NvimNs () abort
181105 return nvim_create_namespace (' github-copilot' )
182106endfunction
@@ -235,15 +159,11 @@ endfunction
235159
236160function ! copilot#Enabled () abort
237161 return get (g: , ' copilot_enabled' , 1 )
238- \ && s: TermsAccepted (0 )
239162 \ && empty (s: BufferDisabled ())
240163 \ && empty (copilot#Agent ().StartupError ())
241164endfunction
242165
243166function ! copilot#Complete (... ) abort
244- if ! s: TermsAccepted (0 )
245- return {}
246- endif
247167 if exists (' g:_copilot_timer' )
248168 call timer_stop (remove (g: , ' _copilot_timer' ))
249169 endif
@@ -551,57 +471,6 @@ function! copilot#Accept(...) abort
551471 endif
552472endfunction
553473
554- function ! s: DeviceResponse (result, login_data, poll_response) abort
555- let data = s: JsonBody (a: poll_response )
556- let should_cancel = get (get (s: , ' login_data' , {}), ' device_code' , ' ' ) !=# a: login_data .device_code
557- if has_key (data, ' access_token' )
558- if ! should_cancel
559- unlet s: login_data
560- endif
561- let response = copilot#HttpRequest (
562- \ ' https://api.github.com/copilot_internal/token' ,
563- \ {' headers' : {' Authorization' : ' Bearer ' . data.access_token}})
564- if response.status == # 403
565- let a: result .success = 0
566- let a: result .error = " You don't have access to GitHub Copilot. Join the waitlist by visiting https://copilot.github.com"
567- else
568- let a: result .user = s: OAuthUser (data.access_token)
569- let a: result .success = ! empty (a: result .user )
570- if a: result .success
571- call s: OAuthSave (data.access_token, a: result .user )
572- else
573- let a: result .error = " Could not retrieve GitHub user."
574- endif
575- endif
576- elseif should_cancel
577- let a: result .success = 0
578- let a: result .error = " Something went wrong."
579- elseif has_key (a: result , ' success' )
580- return
581- elseif index ([' authorization_pending' , ' slow_down' ], get (data, ' error' , ' ' )) != -1
582- call timer_start ((get (data, ' interval' , a: login_data .interval)+ 1 ) * 1000 , function (' s:DevicePoll' , [a: result , a: login_data ]))
583- elseif has_key (data, ' error_description' )
584- let a: result .success = 0
585- let a: result .error = data.error_description
586- unlet ! s: login_data
587- echohl ErrorMsg
588- echomsg ' Copilot: ' . data.error_description
589- echohl NONE
590- else
591- let a: result .success = 0
592- let a: result .error = " Something went wrong."
593- endif
594- endfunction
595-
596- let s: client_id = " Iv1.b507a08c87ecfe98"
597-
598- function ! s: DevicePoll (result, login_data, timer) abort
599- call copilot#HttpRequest (
600- \ ' https://github.com/login/oauth/access_token?grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=' . a: login_data .device_code . ' &client_id=' . s: client_id ,
601- \ {' headers' : {' Accept' : ' application/json' }},
602- \ function (' s:DeviceResponse' , [a: result , a: login_data ]))
603- endfunction
604-
605474function ! s: BrowserCallback (into, code) abort
606475 let a: into .code = a: code
607476endfunction
@@ -651,7 +520,7 @@ endfunction
651520function ! s: EnabledStatusMessage () abort
652521 let buf_disabled = s: BufferDisabled ()
653522 if ! s: has_ghost_text && bufwinid (' copilot://' ) == -1
654- return " Neovim 0.6 prerelease required to support ghost text"
523+ return " Neovim 0.6 required to support ghost text"
655524 elseif ! copilot#IsMapped ()
656525 return ' <Tab> map has been disabled or is claimed by another plugin'
657526 elseif ! get (g: , ' copilot_enabled' , 1 )
@@ -678,12 +547,14 @@ function! s:VerifySetup() abort
678547 return
679548 endif
680549
681- if empty (s: OAuthToken ())
550+ let status = copilot#Call (' checkStatus' , {})
551+
552+ if ! has_key (status, ' user' )
682553 echo ' Copilot: Not authenticated. Invoke :Copilot setup'
683554 return
684555 endif
685556
686- if ! s: TermsAccepted ( 1 )
557+ if status.status == # ' NoTelemetryConsent '
687558 echo ' Copilot: Telemetry terms not accepted. Invoke :Copilot setup'
688559 return
689560 endif
@@ -716,15 +587,12 @@ function! s:commands.status(opts) abort
716587endfunction
717588
718589function ! s: commands .signout (opts) abort
719- unlet ! s: github
720- if empty ( s: OAuthToken () )
721- echo ' Copilot: Not signed in '
590+ let status = copilot#Call ( ' checkStatus ' , {})
591+ if has_key (status, ' user ' )
592+ echo ' Copilot: Signed out as GitHub user ' . status. user
722593 else
723- let user = get (s: github , ' user' , ' <unknown>' )
724- let s: github = {}
725- echo ' Copilot: Signed out as GitHub user ' . user
594+ echo ' Copilot: Not signed in'
726595 endif
727- call delete (s: config_hosts )
728596 call copilot#Call (' signOut' , {})
729597endfunction
730598
@@ -736,72 +604,60 @@ function! s:commands.setup(opts) abort
736604
737605 let browser = copilot#Browser ()
738606
739- if empty (s: OAuthToken ()) || a: opts .bang
740- let response = copilot#HttpRequest (' https://github.com/login/device/code' , {
741- \ ' method' : ' POST' ,
742- \ ' headers' : {' Accept' : ' application/json' },
743- \ ' json' : {' client_id' : s: client_id , ' scope' : ' read:user' }})
744- let data = s: JsonBody (response)
745- let s: login_data = data
746- let @+ = data.user_code
747- let @* = data.user_code
748- echo " First copy your one-time code: " . data.user_code
607+ if has_key (copilot#Call (' checkStatus' , {}), ' user' )
608+ let data = {}
609+ else
610+ let data = copilot#Call (' signInInitiate' , {})
611+ endif
612+
613+ if has_key (data, ' verificationUri' )
614+ let uri = data.verificationUri
615+ let @+ = data.userCode
616+ let @* = data.userCode
617+ echo " First copy your one-time code: " . data.userCode
749618 try
750619 if len (&mouse )
751620 let mouse = &mouse
752621 set mouse =
753622 endif
754623 if get (a: opts , ' bang' )
755- echo " In your browser, visit " . data.verification_uri
624+ echo " In your browser, visit " . uri
756625 elseif len (browser)
757626 echo " Press ENTER to open GitHub in your browser"
758627 let c = getchar ()
759628 while c isnot # 13 && c isnot # 10 && c isnot # 0
760629 let c = getchar ()
761630 endwhile
762631 let status = {}
763- call copilot#job#Stream (browser + [data.verification_uri ], v: null , v: null , function (' s:BrowserCallback' , [status]))
632+ call copilot#job#Stream (browser + [uri ], v: null , v: null , function (' s:BrowserCallback' , [status]))
764633 let time = reltime ()
765634 while empty (status) && reltimefloat (reltime (time)) < 5
766635 sleep 10 m
767636 endwhile
768637 if get (status, ' code' , browser[0 ] !=# ' xdg-open' ) != 0
769- echo " Failed to open browser. Visit " . data.verification_uri
638+ echo " Failed to open browser. Visit " . uri
770639 else
771- echo " Opened " . data.verification_uri
640+ echo " Opened " . uri
772641 endif
773642 else
774- echo " Could not find browser. Visit " . data.verification_uri
643+ echo " Could not find browser. Visit " . uri
775644 endif
776645 echo " Waiting (could take up to 5 seconds)"
777- let result = {}
778- call timer_start ((data.interval+ 1 ) * 1000 , function (' s:DevicePoll' , [result, data]))
779- try
780- while ! has_key (result, ' success' )
781- sleep 100 m
782- endwhile
783- finally
784- if ! has_key (result, ' success' )
785- let result.success = 0
786- let result.error = " Interrupt"
787- endif
788- redraw
789- endtry
646+ let request = copilot#Request (' signInConfirm' , {' userCode' : data.userCode}).Wait ()
790647 finally
791648 if exists (' mouse' )
792649 let &mouse = mouse
793650 endif
794651 endtry
795- if ! result.success
796- return ' echoerr ' . string (' Copilot: Authentication failure: ' . result .error )
652+ if request.status == # ' error '
653+ return ' echoerr ' . string (' Copilot: Authentication failure: ' . request .error .message )
797654 endif
798655 endif
799656
800- if ! exists (' s:github.user' )
801- return ' echoerr ' . string (' Copilot: Something went wrong retrieving GitHub user.' )
802- endif
657+ let status = copilot#Call (' checkStatus' , {})
658+ let user = status.user
803659
804- if ! s: TermsAccepted ( 1 )
660+ if status.status == # ' NoTelemetryConsent '
805661 let terms_url = " https://github.co/copilot-telemetry-terms"
806662 echo " I agree to these telemetry terms as part of the GitHub Copilot technical preview."
807663 echo " <" . terms_url . " >"
@@ -825,14 +681,10 @@ function! s:commands.setup(opts) abort
825681 endif
826682 endwhile
827683 redraw
828- let terms = s: ReadTerms ()
829- let terms[s: github .user ] = {' version' : s: terms_version }
830- call writefile ([json_encode (terms)], s: config_root . ' /terms.json' )
831- unlet ! s: terms_accepted
684+ call copilot#Call (' recordTelemetryConsent' , {})
832685 endif
833686
834- call copilot#Call (' checkStatus' , {})
835- echo ' Copilot: Authenticated as GitHub user ' . s: github .user
687+ echo ' Copilot: Authenticated as GitHub user ' . user
836688endfunction
837689
838690function ! s: commands .help (opts) abort
@@ -904,9 +756,10 @@ endfunction
904756function ! copilot#Command (line1, line2, range , bang , mods, arg) abort
905757 let cmd = matchstr (a: arg , ' ^\%(\\.\|\S\)\+' )
906758 let arg = matchstr (a: arg , ' \s\zs\S.*' )
759+ let opts = copilot#Call (' checkStatus' , {})
907760 try
908761 if empty (cmd)
909- if empty ( s: OAuthToken ()) || ! s: TermsAccepted ( 1 )
762+ if opts.status !=# ' OK ' && opts.status !=# ' MaybeOK '
910763 let cmd = ' setup'
911764 else
912765 let cmd = ' panel'
@@ -919,7 +772,7 @@ function! copilot#Command(line1, line2, range, bang, mods, arg) abort
919772 if ! has_key (s: commands , tr (cmd, ' -' , ' _' ))
920773 return ' echoerr ' . string (' Copilot: unknown command ' . string (cmd))
921774 endif
922- let opts = {' line1' : a: line1 , ' line2' : a: line2 , ' range' : a: range , ' bang' : a: bang , ' mods' : a: mods , ' arg' : arg}
775+ call extend ( opts, {' line1' : a: line1 , ' line2' : a: line2 , ' range' : a: range , ' bang' : a: bang , ' mods' : a: mods , ' arg' : arg})
923776 let retval = s: commands [tr (cmd, ' -' , ' _' )](opts)
924777 if type (retval) == v: t_string
925778 return retval
0 commit comments