UIBridge._nvim_event_loop()   F
last analyzed

Complexity

Conditions 12

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 12
c 2
b 0
f 1
dl 0
loc 37
rs 2.7855

4 Methods

Rating   Name   Duplication   Size   Complexity  
A UIBridge.on_request() 0 2 1
A UIBridge.on_setup() 0 2 1
F UIBridge.on_notification() 0 27 9
C UIBridge.apply_updates() 0 24 7

How to fix   Complexity   

Complexity

Complex classes like UIBridge._nvim_event_loop() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""Bridge for connecting a UI instance to nvim."""
2
import sys
3
from threading import Semaphore, Thread
4
from traceback import format_exc
5
6
7
class UIBridge(object):
8
9
    """UIBridge class. Connects a Nvim instance to a UI class."""
10
11
    def connect(self, nvim, ui, profile=None, notify=False):
12
        """Connect nvim and the ui.
13
14
        This will start loops for handling the UI and nvim events while
15
        also synchronizing both.
16
        """
17
        self._notify = notify
18
        self._error = None
19
        self._nvim = nvim
20
        self._ui = ui
21
        self._profile = profile
22
        self._sem = Semaphore(0)
23
        t = Thread(target=self._nvim_event_loop)
24
        t.daemon = True
25
        t.start()
26
        self._ui_event_loop()
27
        if self._error:
28
            print(self._error)
29
        if self._profile:
30
            print(self._profile)
31
32
    def exit(self):
33
        """Disconnect by exiting nvim."""
34
        self.detach()
35
        self._call(self._nvim.quit)
36
37
    def input(self, input_str):
38
        """Send input to nvim."""
39
        self._call(self._nvim.input, input_str)
40
41
    def resize(self, columns, rows):
42
        """Send a resize request to nvim."""
43
        self._call(self._nvim.ui_try_resize, columns, rows)
44
45
    def attach(self, columns, rows, rgb):
46
        """Attach the UI to nvim."""
47
        self._call(self._nvim.ui_attach, columns, rows, rgb)
48
49
    def detach(self):
50
        """Detach the UI from nvim."""
51
        self._call(self._nvim.ui_detach)
52
53
    def _call(self, fn, *args):
54
        self._nvim.async_call(fn, *args)
55
56
    def _ui_event_loop(self):
57
        self._sem.acquire()
58
        # if self._profile:
59
            # import StringIO
60
            # import cProfile
61
            # import pstats
62
            # pr = cProfile.Profile()
63
            # pr.enable()
64
        # self._ui.start(self)
65
        # if self._profile:
66
            # pr.disable()
67
            # s = StringIO.StringIO()
68
            # ps = pstats.Stats(pr, stream=s)
69
            # ps.strip_dirs().sort_stats(self._profile).print_stats(30)
70
            # self._profile = s.getvalue()
71
72
    def _nvim_event_loop(self):
73
        def on_setup():
74
            self._sem.release()
75
76
        def on_request(method, args):
77
            raise Exception('Not implemented')
78
79
        def on_notification(method, updates):
80
            def apply_updates():
81
                if self._notify:
82
                    sys.stdout.write('attached\n')
83
                    sys.stdout.flush()
84
                    self._notify = False
85
                try:
86
                    for update in updates:
87
                        # import sys
88
                        # l = [','.join([str(a) for a in args])
89
                        #      for args in update[1:]]
90
                        # print >> sys.stderr, update[0], ' '.join(l)
91
                        try:
92
                            nvim_handler = getattr(self._ui, 'nvim_handler')
93
                            handler = getattr(nvim_handler, '_nvim_' + update[0])
94
                        except AttributeError as err:
95
                            pass
96
                        else:
97
                            for args in update[1:]:
98
                                handler(*args)
99
                except Exception as err :
100
                    print('ERROR OCCURED, unfortunalety no traceback..')
101
                    import pdb;pdb.set_trace()
102
                    self._error = format_exc()
103
                    self._call(self._nvim.quit)
104
            if method == 'redraw':
105
                self._ui.schedule_screen_update(apply_updates)
106
107
        self._nvim.run_loop(on_request, on_notification, on_setup)
108
        self._ui.quit()
109