Skip to content

Commit

Permalink
refactor: format the entire codebase using isort and yapf.
Browse files Browse the repository at this point in the history
  • Loading branch information
wookayin committed Dec 25, 2023
1 parent 7ffd4bd commit d31e2bb
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 129 deletions.
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ profile = "black"
single_line_exclusions = ['typing', 'typing_extensions']
extra_standard_library = ['typing_extensions']
known_third_party = []

[tool.yapf]
# see https://github.com/google/yapf#knobs
based_on_style = "pep8"
indent_width = 4
spaces_before_comment = 2

[tool.yapfignore]
ignore_patterns = ['test/data/*.py']
79 changes: 45 additions & 34 deletions rplugin/python3/semshi/handler.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
from __future__ import annotations

from typing import Optional

from collections import defaultdict
import threading
import time
from collections import defaultdict
from typing import Optional

import pynvim
import pynvim.api

from pynvim.api import Nvim, Buffer
from pynvim.api import Buffer, Nvim

from . import plugin
from .node import SELECTED, Node, hl_groups
from .parser import Parser, UnparsableError
from .util import logger, debug_time, lines_to_code
from .node import Node, SELECTED, hl_groups

from .util import debug_time, lines_to_code, logger

ERROR_SIGN_ID = 314000
ERROR_HL_ID = 313000
Expand All @@ -27,6 +24,7 @@ class BufferHandler:
The handler runs the parser, adds and removes highlights, keeps tracks of
which highlights are visible and which ones need to be added or removed.
"""

def __init__(self, buf: Buffer, vim: Nvim, options: plugin.Options):
self._buf = buf
self._vim = vim
Expand Down Expand Up @@ -120,10 +118,12 @@ def _wait_for(self, func, sync=False):
return func()
event = threading.Event()
res = None

def wrapper():
nonlocal res
res = func()
event.set()

self._vim.async_call(wrapper)
event.wait()
return res
Expand All @@ -135,8 +135,10 @@ def _wrap_async(self, func):
function call happens from other threads.
Related issue: https://github.com/numirias/semshi/issues/25
"""

def wrapper(*args, **kwargs):
return self._vim.async_call(func, *args, **kwargs)

return wrapper

def _update_loop(self):
Expand All @@ -153,7 +155,7 @@ def _update_loop(self):
self._add_visible_hls()
self._viewport_changed = False
except Exception:
import traceback # pylint: disable=import-outside-toplevel
import traceback # pylint: disable=import-outside-toplevel
logger.error('Exception: %s', traceback.format_exc())
raise

Expand Down Expand Up @@ -258,16 +260,14 @@ def syntax_error(self) -> Optional[SyntaxError]:
return self._parser.syntax_errors[-1]

def _place_sign(self, id, line, name):
self._wrap_async(self._vim.command)(
'sign place %d line=%d name=%s buffer=%d' % (
id, line, name, self._buf_num),
async_=True)
command = self._wrap_async(self._vim.command)
command('sign place %d line=%d name=%s buffer=%d' %
(id, line, name, self._buf_num),
async_=True)

def _unplace_sign(self, id):
self._wrap_async(self._vim.command)(
'sign unplace %d buffer=%d' % (
id, self._buf_num),
async_=True)
command = self._wrap_async(self._vim.command)
command('sign unplace %d buffer=%d' % (id, self._buf_num), async_=True)

@debug_time(None, lambda _, a, c: '+%d, -%d' % (len(a), len(c)))
def _update_hls(self, add, clear):
Expand All @@ -282,8 +282,8 @@ def _add_hls(self, node_or_nodes):
if not isinstance(node_or_nodes, list):
buf.add_highlight(*node_or_nodes)
return
self._call_atomic_async(
[('nvim_buf_add_highlight', (buf, *n)) for n in node_or_nodes])
self._call_atomic_async([('nvim_buf_add_highlight', (buf, *n))
for n in node_or_nodes])

@debug_time(None, lambda _, nodes: '%d nodes' % len(nodes))
def _clear_hls(self, node_or_nodes):
Expand All @@ -295,13 +295,14 @@ def _clear_hls(self, node_or_nodes):
return
# Don't specify line range to clear explicitly because we can't
# reliably determine the correct range
self._call_atomic_async(
[('nvim_buf_clear_highlight', (buf, *n)) for n in node_or_nodes])
self._call_atomic_async([('nvim_buf_clear_highlight', (buf, *n))
for n in node_or_nodes])

def _call_atomic_async(self, calls):
# Need to update in small batches to avoid
# https://github.com/neovim/python-client/issues/310
batch_size = 3000

def _call_atomic(call_chunk, **kwargs):
# when nvim_call_atomic is actually being executed
# (due to an asynchronous call), the buffer might be gone.
Expand All @@ -311,6 +312,7 @@ def _call_atomic(call_chunk, **kwargs):
self._buf)
return None
return self._vim.api.call_atomic(call_chunk, **kwargs)

call_atomic = self._wrap_async(_call_atomic)
for i in range(0, len(calls), batch_size):
call_atomic(calls[i:i + batch_size], async_=True)
Expand All @@ -322,11 +324,12 @@ def rename(self, cursor, new_name=None):
if cur_node is None:
self._vim.out_write('Nothing to rename here.\n')
return
nodes = list(self._parser.same_nodes(
cur_node,
mark_original=True,
use_target=self._options.self_to_attribute,
))
nodes = list(
self._parser.same_nodes(
cur_node,
mark_original=True,
use_target=self._options.self_to_attribute,
))
num = len(nodes)
if new_name is None:
new_name = self._vim.eval('input("Rename %d nodes to: ")' % num)
Expand Down Expand Up @@ -355,19 +358,25 @@ def goto(self, what, direction=None):
self._goto_error()
return
# pylint: disable=import-outside-toplevel
from ast import ClassDef, FunctionDef, AsyncFunctionDef
from ast import AsyncFunctionDef, ClassDef, FunctionDef
here = tuple(self._vim.current.window.cursor)
if what == 'name':
cur_node = self._parser.node_at(here)
if cur_node is None:
return
locs = sorted([n.pos for n in self._parser.same_nodes(
cur_node, use_target=self._options.self_to_attribute)])
locs = sorted([
n.pos for n in self._parser.same_nodes(
cur_node, use_target=self._options.self_to_attribute)
])
elif what == 'class':
locs = self._parser.locations_by_node_types([ClassDef])
locs = self._parser.locations_by_node_types([
ClassDef,
])
elif what == 'function':
locs = self._parser.locations_by_node_types([FunctionDef,
AsyncFunctionDef])
locs = self._parser.locations_by_node_types([
FunctionDef,
AsyncFunctionDef,
])
elif what in hl_groups:
locs = self._parser.locations_by_hl_group(hl_groups[what])
else:
Expand Down Expand Up @@ -397,8 +406,10 @@ def _goto_error(self):
def _error_pos(self, error):
"""Return a position for the syntax error `error` which is guaranteed
to be a valid position in the buffer."""
offset = max(1, min(error.offset,
len(self._parser.lines[error.lineno - 1]))) - 1
offset = max(1, min(error.offset, \
len(self._parser.lines[error.lineno - 1])
)
) - 1
return (error.lineno, offset)

def show_error(self):
Expand Down
16 changes: 10 additions & 6 deletions rplugin/python3/semshi/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
# e.g. "global" -> "semshiGlobal"
hl_groups: Dict[str, str] = {}


def group(s):
label = 'semshi' + s[0].capitalize() + s[1:]
hl_groups[s] = label
return label


UNRESOLVED = group('unresolved')
ATTRIBUTE = group('attribute')
BUILTIN = group('builtin')
Expand All @@ -35,8 +37,10 @@ class Node:
# Highlight ID counter (chosen arbitrarily)
id_counter = count(314001)

__slots__ = ['id', 'name', 'lineno', 'col', 'end', 'env',
'symname', 'symbol', 'hl_group', 'target', '_tup']
__slots__ = [
'id', 'name', 'lineno', 'col', 'end', 'env', 'symname', 'symbol',
'hl_group', 'target', '_tup'
]

def __init__(self, name, lineno, col, env, target=None, hl_group=None):
self.id = next(Node.id_counter)
Expand Down Expand Up @@ -66,10 +70,10 @@ def update_tup(self):
self._tup = (self.lineno, self.col, self.hl_group, self.name)

def __lt__(self, other):
return self._tup < other._tup # pylint: disable=protected-access
return self._tup < other._tup # pylint: disable=protected-access

def __eq__(self, other):
return self._tup == other._tup # pylint: disable=protected-access
return self._tup == other._tup # pylint: disable=protected-access

def __hash__(self):
# Currently only required for tests
Expand Down Expand Up @@ -159,8 +163,8 @@ def _make_symname(self, name):
if not name.startswith('__') or name.endswith('__'):
return name
try:
cls = next(t for t in reversed(self.env) if
t.get_type() == 'class')
cls = next(t for t in reversed(self.env)
if t.get_type() == 'class')
except StopIteration:
# Not inside a class, so no candidate for name mangling
return name
Expand Down
19 changes: 12 additions & 7 deletions rplugin/python3/semshi/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ class Parser:
run of `parse()` on changed source code, it returns the nodes that have
been added and removed.
"""
def __init__(self,
exclude: Optional[List[str]] = None,
fix_syntax: bool = True,
):

def __init__(
self,
exclude: Optional[List[str]] = None,
fix_syntax: bool = True,
):
self._excluded = exclude or []
self._fix_syntax = fix_syntax
self._locations = {}
Expand Down Expand Up @@ -165,16 +167,18 @@ def _fix_line(line):
tokens = tokenize(iter([line.encode('utf-8')]).__next__)
prev = None
text = ''

def add_token(token, filler):
nonlocal text, prev
text += (token.start[1] - len(text)) * filler + token.string
prev = token

try:
for token in tokens:
if token.type == INDENT:
text += token.string
elif (token.type == OP and token.string == '.' and prev and
prev.type == NAME):
elif (token.type == OP and token.string == '.' and prev
and prev.type == NAME):
add_token(token, ' ')
elif token.type == NAME and token.string not in kwlist:
if prev and prev.type == OP and prev.string == '.':
Expand Down Expand Up @@ -334,11 +338,12 @@ def locations_by_hl_group(self, group):
class _LocationCollectionVisitor(ast.NodeVisitor):
"""Node vistor which collects the locations of all AST nodes of a given
type."""

def __init__(self, types):
self._types = types
self.locations = []

def visit(self, node):
if type(node) in self._types: # pylint: disable=unidiomatic-typecheck
if type(node) in self._types: # pylint: disable=unidiomatic-typecheck
self.locations.append((node.lineno, node.col_offset))
return self.generic_visit(node)
32 changes: 19 additions & 13 deletions rplugin/python3/semshi/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ def subcommand(func=None, needs_handler=False, silent_fail=True):
error message is printed.
"""
if func is None:
return partial(
subcommand, needs_handler=needs_handler, silent_fail=silent_fail)
return partial(subcommand,
needs_handler=needs_handler,
silent_fail=silent_fail)

@wraps(func)
def wrapper(self, *args, **kwargs):
Expand All @@ -39,6 +40,7 @@ def wrapper(self, *args, **kwargs):
self.echo_error('Semshi is not enabled in this buffer!')
return
func(self, *args, **kwargs)

_subcommands[func.__name__] = wrapper
return wrapper

Expand Down Expand Up @@ -135,13 +137,16 @@ def event_vim_leave(self):
for handler in self._handlers.values():
handler.shutdown()

@pynvim.command('Semshi', nargs='*', # type: ignore
complete='customlist,SemshiComplete',
sync=True)
@pynvim.command(
'Semshi',
nargs='*', # type: ignore
complete='customlist,SemshiComplete',
sync=True,
)
def cmd_semshi(self, args):
if not args:
filetype = cast(pynvim.api.Buffer, self._vim.current.buffer
).options.get('filetype')
filetype = cast(pynvim.api.Buffer,
self._vim.current.buffer).options.get('filetype')
py_filetypes = self._vim.vars.get('semshi#filetypes', [])
if filetype in py_filetypes: # for python buffers
self._vim.command('Semshi status')
Expand All @@ -166,9 +171,10 @@ def func_complete(arg):
def _internal_eval(self, args):
"""Eval Python code in plugin context.
Only used for testing."""
plugin = self # noqa pylint: disable=unused-variable
return eval(args[0]) # pylint: disable=eval-used
Only used for testing.
"""
plugin = self # noqa pylint: disable=unused-variable
return eval(args[0]) # pylint: disable=eval-used

@subcommand
def enable(self):
Expand Down Expand Up @@ -239,7 +245,7 @@ def status(self):
'Semshi is {attached} on (bufnr={bufnr})',
'- current handler: {handler}',
'- handlers: {handlers}',
'- syntax error: {syntax_error}'
'- syntax error: {syntax_error}',
]).format(
attached=attached and "attached" or "detached",
bufnr=str(buffer.number),
Expand Down Expand Up @@ -360,5 +366,5 @@ def _convert_excluded_hl_groups(items: Sequence[str]) -> List[str]:
return [hl_groups[g] for g in items]
except KeyError as e:
# TODO Use err_write instead?
raise ValueError(f'"{e.args[0]}" is an unknown highlight group.'
) from e
raise ValueError(
f'"{e.args[0]}" is an unknown highlight group.') from e
Loading

0 comments on commit d31e2bb

Please sign in to comment.