Ejemplo n.º 1
0
class SyncParent(_Parent):
    def _start_process(self):
        from deoplete.child import Child
        self._child = Child(self._vim)

    def merge_results(self, context):
        results = self._child._merge_results(context, queue_id=None)
        return (results['is_async'],
                results['merged_results']) if results else (False, [])

    def _put(self, name, args):
        self._child.main(name, args, queue_id=None)
Ejemplo n.º 2
0
def main(serveraddr):
    vim = attach_vim(serveraddr)
    from deoplete.util import error_tb
    child = None
    try:
        from deoplete.child import Child
        child = Child(vim)
        while 1:
            child.main()
    except Exception:
        error_tb(vim, 'Error in child')
    return
Ejemplo n.º 3
0
class SingleParent(_Parent):
    def _start_process(self):
        from deoplete.child import Child
        self._child = Child(self._vim)

    def merge_results(self, context):
        results = self._child._merge_results(context, queue_id=None)
        return (results['is_async'],
                results['merged_results']) if results else (False, [])

    def _put(self, name, args):
        self._child.main(name, args, queue_id=None)
Ejemplo n.º 4
0
class SyncParent(_Parent):
    def _start_process(self) -> None:
        from deoplete.child import Child
        self._child = Child(self._vim)

    def merge_results(self, context: UserContext) -> typing.Tuple[typing.Any]:
        results = self._child._merge_results(context, queue_id=None)
        ret = (results['is_async'], results['is_async'],
               results['merged_results']) if results else (False, [])
        return ret  # type: ignore

    def _put(self, name: str,
             args: typing.List[typing.Any]) -> typing.Optional[str]:
        self._child.main(name, args, queue_id=None)
        return None
Ejemplo n.º 5
0
class Parent(logger.LoggingMixin):
    def __init__(self, vim, context):
        self.name = 'parent'

        self._vim = vim
        self._hnd = None
        self._stdin = None
        self._child = None
        self._queue_id = ''
        self._prev_pos = []
        self._queue_in = Queue()
        self._queue_out = Queue()
        self._packer = msgpack.Packer(use_bin_type=True,
                                      encoding='utf-8',
                                      unicode_errors='surrogateescape')
        self._unpacker = msgpack.Unpacker(encoding='utf-8',
                                          unicode_errors='surrogateescape')
        self._start_process(context)

    def enable_logging(self):
        self._put('enable_logging', [])
        self.is_debug_enabled = True

    def add_source(self, path):
        self._put('add_source', [path])

    def add_filter(self, path):
        self._put('add_filter', [path])

    def set_source_attributes(self, context):
        self._put('set_source_attributes', [context])

    def set_custom(self, custom):
        self._put('set_custom', [custom])

    def merge_results(self, context):
        if self._child:
            results = self._put('merge_results', [context])
        else:
            if context['position'] == self._prev_pos and self._queue_id:
                # Use previous id
                queue_id = self._queue_id
            else:
                queue_id = self._put('merge_results', [context])
                if not queue_id:
                    return (False, [])

            get = self._get(queue_id)
            if not get:
                # Skip the next merge_results
                self._queue_id = queue_id
                self._prev_pos = context['position']
                return (True, [])
            self._queue_id = ''
            results = get[0]
        return (results['is_async'],
                results['merged_results']) if results else (False, [])

    def on_event(self, context):
        self._put('on_event', [context])

    def _start_process(self, context):
        if self._vim.vars['deoplete#num_processes'] > 1:
            # Parallel

            startupinfo = None
            if os.name == 'nt':
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

            self._hnd = self._vim.loop.create_task(
                self._vim.loop.subprocess_exec(
                    partial(Process, self),
                    self._vim.vars.get('python3_host_prog', 'python3'),
                    context['dp_main'],
                    self._vim.vars['deoplete#_serveraddr'],
                    stderr=None,
                    cwd=context['cwd'],
                    startupinfo=startupinfo))
        else:
            # Serial
            from deoplete.child import Child
            self._child = Child(self._vim)

    def _put(self, name, args):
        queue_id = str(time.time())

        if self._child:
            return self._child.main(name, args, queue_id)

        if not self._hnd:
            return None

        msg = self._packer.pack({
            'name': name,
            'args': args,
            'queue_id': queue_id
        })
        self._queue_in.put(msg)

        if self._stdin:
            try:
                while not self._queue_in.empty():
                    self._stdin.write(self._queue_in.get_nowait())
            except BrokenPipeError as e:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._hnd = None
        return queue_id

    def _get(self, queue_id):
        if not self._hnd:
            return []

        outs = []
        while not self._queue_out.empty():
            outs.append(self._queue_out.get_nowait())
        return [x for x in outs if x['queue_id'] == queue_id]

    def _on_connection(self, transport):
        self._stdin = transport.get_pipe_transport(0)

    def _on_output(self, fd, data):
        self._unpacker.feed(data)
        for child_out in self._unpacker:
            self._queue_out.put(child_out)
Ejemplo n.º 6
0
class Parent(logger.LoggingMixin):
    def __init__(self, vim, context):
        self.name = 'parent'

        self._vim = vim
        self._proc = None
        self._child = None
        self._queue_id = ''
        self._prev_pos = []
        self._start_process(context)

    def enable_logging(self):
        self._put('enable_logging', [])
        self.is_debug_enabled = True

    def add_source(self, path):
        self._put('add_source', [path])

    def add_filter(self, path):
        self._put('add_filter', [path])

    def set_source_attributes(self, context):
        self._put('set_source_attributes', [context])

    def set_custom(self, custom):
        self._put('set_custom', [custom])

    def merge_results(self, context):
        if self._child:
            results = self._put('merge_results', [context])
        else:
            if context['position'] == self._prev_pos and (
                    self._queue_id or context['event'] == 'Async'):
                # Use previous id
                queue_id = self._queue_id
            else:
                queue_id = self._put('merge_results', [context])
                if not queue_id:
                    return (False, [])

            get = self._get(queue_id)
            if not get:
                # Skip the next merge_results
                self._queue_id = queue_id
                self._prev_pos = context['position']
                return (True, [])
            self._queue_id = ''
            results = get[0]
        return (results['is_async'],
                results['merged_results']) if results else (False, [])

    def on_event(self, context):
        self._put('on_event', [context])
        if context['event'] == 'VimLeavePre':
            self._stop_process()

    def _start_process(self, context):
        if self._vim.vars['deoplete#num_processes'] > 1:
            # Parallel
            python3 = self._vim.vars.get('python3_host_prog', 'python3')
            self._proc = Process([
                python3, context['dp_main'],
                self._vim.vars['deoplete#_serveraddr']
            ], context, context['cwd'])
        else:
            # Serial
            from deoplete.child import Child
            self._child = Child(self._vim)

    def _stop_process(self):
        if self._proc:
            self._proc.kill()
            self._proc = None

    def _put(self, name, args):
        queue_id = str(time.time())

        if self._proc:
            try:
                self._proc.write({
                    'name': name,
                    'args': args,
                    'queue_id': queue_id
                })
            except BrokenPipeError as e:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._proc.kill()
            return queue_id
        elif self._child:
            return self._child.main(name, args, queue_id)
        else:
            return None

    def _get(self, queue_id):
        if not self._proc:
            return []

        return [
            x for x in self._proc.communicate(0.02)
            if x['queue_id'] == queue_id
        ]
Ejemplo n.º 7
0
class Parent(logger.LoggingMixin):

    def __init__(self, vim, context):
        self.name = 'parent'

        self._vim = vim
        self._hnd = None
        self._stdin = None
        self._child = None
        self._queue_id = ''
        self._loaded_filters = set()
        self._prev_pos = []
        self._queue_in = Queue()
        self._queue_out = Queue()
        self._packer = msgpack.Packer(
            use_bin_type=True,
            encoding='utf-8',
            unicode_errors='surrogateescape')
        self._unpacker = msgpack.Unpacker(
            encoding='utf-8',
            unicode_errors='surrogateescape')
        self._start_process(context)

    def enable_logging(self):
        self._put('enable_logging', [])
        self.is_debug_enabled = True

    def add_source(self, path):
        self._put('add_source', [path])

    def add_filter(self, path):
        if path in self._loaded_filters:
            return
        self._loaded_filters.add(path)

        self._put('add_filter', [path])

    def set_source_attributes(self, context):
        self._put('set_source_attributes', [context])

    def set_custom(self, custom):
        self._put('set_custom', [custom])

    def merge_results(self, context):
        if self._child:
            results = self._put('merge_results', [context])
        else:
            if context['position'] == self._prev_pos and self._queue_id:
                # Use previous id
                queue_id = self._queue_id
            else:
                queue_id = self._put('merge_results', [context])
                if not queue_id:
                    return (False, [])

            get = self._get(queue_id)
            if not get:
                # Skip the next merge_results
                self._queue_id = queue_id
                self._prev_pos = context['position']
                return (True, [])
            self._queue_id = ''
            results = get[0]
        return (results['is_async'],
                results['merged_results']) if results else (False, [])

    def on_event(self, context):
        self._put('on_event', [context])

    def _start_process(self, context):
        num_processes = self._vim.call('deoplete#custom#_get_option',
                                       'num_processes')
        if num_processes != 1:
            # Parallel

            startupinfo = None
            if os.name == 'nt':
                startupinfo = subprocess.STARTUPINFO()
                startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW

            self._hnd = self._vim.loop.create_task(
                self._vim.loop.subprocess_exec(
                    partial(Process, self),
                    self._vim.vars.get('python3_host_prog', 'python3'),
                    dp_main,
                    self._vim.vars['deoplete#_serveraddr'],
                    stderr=None, cwd=context['cwd'], startupinfo=startupinfo))
        else:
            # Serial
            from deoplete.child import Child
            self._child = Child(self._vim)

    def _put(self, name, args):
        queue_id = str(time.time())

        if self._child:
            return self._child.main(name, args, queue_id)

        if not self._hnd:
            return None

        msg = self._packer.pack({
            'name': name, 'args': args, 'queue_id': queue_id
        })
        self._queue_in.put(msg)

        if self._stdin:
            try:
                while not self._queue_in.empty():
                    self._stdin.write(self._queue_in.get_nowait())
            except BrokenPipeError as e:
                error_tb(self._vim, 'Crash in child process')
                error(self._vim, 'stderr=' + str(self._proc.read_error()))
                self._hnd = None
        return queue_id

    def _get(self, queue_id):
        if not self._hnd:
            return []

        outs = []
        while not self._queue_out.empty():
            outs.append(self._queue_out.get_nowait())
        return [x for x in outs if x['queue_id'] == queue_id]