1
- from asyncio . events import AbstractEventLoop
2
- from concurrent . futures import Executor
1
+ from asyncio import gather
2
+ from functools import wraps
3
3
from multiprocessing import cpu_count
4
- from pathlib import Path
4
+ from pathlib import Path , PurePath
5
5
from platform import uname
6
6
from string import Template
7
- from sys import executable
7
+ from sys import executable , exit
8
8
from textwrap import dedent
9
9
from time import monotonic
10
- from typing import Any , MutableMapping , Optional , cast
10
+ from typing import Any , MutableMapping , Optional , Sequence , Tuple , cast
11
11
12
- from pynvim import Nvim
13
- from pynvim .api .common import NvimError
14
- from pynvim_pp .client import Client
15
12
from pynvim_pp .highlight import highlight
16
- from pynvim_pp .lib import threadsafe_call , write
17
- from pynvim_pp .logging import log , with_suppress
18
- from pynvim_pp .rpc import RpcCallable , RpcMsg , nil_handler
13
+ from pynvim_pp .logging import log , suppress_and_log
14
+ from pynvim_pp .nvim import Nvim , conn
15
+ from pynvim_pp .rpc import MsgType
16
+ from pynvim_pp .types import Method , NoneType , NvimError , RPCallable
19
17
from std2 .pickle .types import DecodeError
20
- from std2 .sched import ticker
21
- from std2 .types import AnyFun
18
+ from std2 .sched import aticker
22
19
23
20
from ._registry import ____
24
21
from .consts import RENDER_RETRIES
25
- from .registry import autocmd , enqueue_event , event_queue , rpc
22
+ from .registry import autocmd , enqueue_event , queue , rpc
26
23
from .settings .load import initial as initial_settings
27
24
from .settings .localization import init as init_locale
28
25
from .settings .types import Settings
29
26
from .state .load import initial as initial_state
30
- from .state .types import State
31
27
from .transitions .autocmds import save_session
32
28
from .transitions .redraw import redraw
33
- from .transitions .schedule_update import schedule_update
29
+ from .transitions .schedule_update import scheduled_update
34
30
from .transitions .types import Stage
35
31
from .transitions .version_ctl import vc_refresh
36
32
33
+ assert ____ or True
37
34
38
- def _profile (nvim : Nvim , t1 : float ) -> None :
35
+ _CB = RPCallable [Optional [Stage ]]
36
+
37
+
38
+ async def _profile (t1 : float ) -> None :
39
39
t2 = monotonic ()
40
40
info = uname ()
41
41
msg = f"""
@@ -47,99 +47,90 @@ def _profile(nvim: Nvim, t1: float) -> None:
47
47
Version { info .version }
48
48
Python { Path (executable ).resolve (strict = True )}
49
49
"""
50
- write (nvim , dedent (msg ))
51
-
52
-
53
- class ChadClient (Client ):
54
- def __init__ (self , pool : Executor ) -> None :
55
- self ._pool = pool
56
- self ._handlers : MutableMapping [str , RpcCallable ] = {}
57
- self ._state : Optional [State ] = None
58
- self ._settings : Optional [Settings ] = None
59
-
60
- def on_msg (self , nvim : Nvim , msg : RpcMsg ) -> Any :
61
- event_queue .put (msg )
62
- return None
63
-
64
- def wait (self , nvim : Nvim ) -> int :
65
- def cont () -> bool :
66
- assert isinstance (nvim .loop , AbstractEventLoop )
67
- nvim .loop .set_default_executor (self ._pool )
68
-
69
- atomic , specs = rpc .drain (nvim .channel_id )
70
- self ._handlers .update (specs )
71
- try :
72
- self ._settings = initial_settings (nvim , specs )
73
- except DecodeError as e :
74
- tpl = """
75
- Some options may have changed.
76
- See help doc on Github under [docs/CONFIGURATION.md]
77
-
78
-
79
- ${e}
80
- """
81
- ms = Template (dedent (tpl )).substitute (e = e )
82
- write (nvim , ms , error = True )
83
- return False
84
- else :
85
- hl = highlight (* self ._settings .view .hl_context .groups )
86
- (atomic + autocmd .drain () + hl ).commit (nvim )
87
-
88
- self ._state = initial_state (
89
- nvim , pool = self ._pool , settings = self ._settings
90
- )
91
- init_locale (self ._settings .lang )
92
- return True
50
+ await Nvim .write (dedent (msg ))
51
+
52
+
53
+ async def _sched (settings : Settings ) -> None :
54
+ await enqueue_event (vc_refresh .method )
55
+
56
+ async for _ in aticker (settings .polling_rate , immediately = False ):
57
+ await enqueue_event (scheduled_update .method )
58
+ await enqueue_event (vc_refresh .method )
59
+ await enqueue_event (save_session .method )
60
+
61
+
62
+ def _trans (handler : _CB ) -> _CB :
63
+ @wraps (handler )
64
+ async def f (* params : Any ) -> None :
65
+ await enqueue_event (handler .method , * params )
66
+
67
+ return cast (_CB , f )
68
+
93
69
70
+ async def _default (_ : MsgType , method : Method , params : Sequence [Any ]) -> None :
71
+ await enqueue_event (method , * params )
72
+
73
+
74
+ async def init (socket : PurePath ) -> None :
75
+ async with conn (socket , default = _default ) as client :
76
+ atomic , handlers = rpc .drain ()
94
77
try :
95
- go = threadsafe_call (nvim , cont )
96
- except Exception as e :
97
- log .exception ("%s" , e )
98
- return 1
78
+ settings = await initial_settings (handlers .values ())
79
+ except DecodeError as e :
80
+ tpl = """
81
+ Some options may have changed.
82
+ See help doc on Github under [docs/CONFIGURATION.md]
83
+
84
+
85
+ ${e}
86
+ """
87
+ ms = Template (dedent (tpl )).substitute (e = e )
88
+ await Nvim .write (ms , error = True )
89
+ exit (1 )
99
90
else :
100
- if not go :
101
- return 1
102
- else :
103
- settings = cast (Settings , self ._settings )
91
+ hl = highlight (* settings .view .hl_context .groups )
92
+ await (atomic + autocmd .drain () + hl ).commit (NoneType )
93
+ state = await initial_state (settings )
94
+
95
+ init_locale (settings .lang )
96
+
97
+ transitions : MutableMapping [Method , _CB ] = {}
98
+
99
+ for f in handlers .values ():
100
+ ff = _trans (f )
101
+ client .register (ff )
102
+ transitions [ff .method ] = ff
103
+
104
+ async def cont () -> None :
105
+ nonlocal state
104
106
t1 , has_drawn = monotonic (), False
105
107
106
- def sched () -> None :
107
- enqueue_event (vc_refresh )
108
- for _ in ticker (settings .polling_rate , immediately = False ):
109
- enqueue_event (schedule_update )
110
- enqueue_event (vc_refresh )
111
- enqueue_event (save_session )
112
-
113
- self ._pool .submit (sched )
114
-
115
- while True :
116
- msg : RpcMsg = event_queue .get ()
117
- name , args = msg
118
- handler = cast (
119
- AnyFun [Optional [Stage ]], self ._handlers .get (name , nil_handler (name ))
120
- )
121
-
122
- def cdraw () -> None :
123
- nonlocal has_drawn
124
- if stage := handler (nvim , self ._state , settings , * args ):
125
- self ._state = stage .state
126
-
127
- for _ in range (RENDER_RETRIES - 1 ):
128
- try :
129
- redraw (nvim , state = self ._state , focus = stage .focus )
130
- except NvimError :
131
- pass
108
+ while True :
109
+ with suppress_and_log ():
110
+ msg : Tuple [Method , Sequence [Any ]] = await queue ().get ()
111
+ method , params = msg
112
+ if handler := cast (Optional [_CB ], handlers .get (method )):
113
+ if stage := await handler (state , settings , * params ):
114
+ state = stage .state
115
+
116
+ for _ in range (RENDER_RETRIES - 1 ):
117
+ try :
118
+ await redraw (state , focus = stage .focus )
119
+ except NvimError :
120
+ pass
121
+ else :
122
+ break
123
+ else :
124
+ try :
125
+ await redraw (state , focus = stage .focus )
126
+ except NvimError as e :
127
+ log .warn ("%s" , e )
128
+
129
+ if settings .profiling and not has_drawn :
130
+ has_drawn = True
131
+ await _profile (t1 = t1 )
132
+
132
133
else :
133
- break
134
- else :
135
- try :
136
- redraw (nvim , state = self ._state , focus = stage .focus )
137
- except NvimError as e :
138
- log .warn ("%s" , e )
139
-
140
- if settings .profiling and not has_drawn :
141
- has_drawn = True
142
- _profile (nvim , t1 = t1 )
143
-
144
- with with_suppress ():
145
- threadsafe_call (nvim , cdraw )
134
+ assert False , msg
135
+
136
+ await gather (cont (), _sched (settings ))
0 commit comments