Skip to content

Commit

Permalink
Reformat using black
Browse files Browse the repository at this point in the history
  • Loading branch information
deathaxe committed Jan 6, 2024
1 parent 0dd98fd commit 4328efc
Show file tree
Hide file tree
Showing 11 changed files with 647 additions and 533 deletions.
348 changes: 189 additions & 159 deletions plugins/cmds.py

Large diffs are not rendered by default.

136 changes: 77 additions & 59 deletions plugins/ctags.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,36 @@
#

TAGS_RE = re.compile(
r'(?P<symbol>[^\t]+)\t'
r'(?P<filename>[^\t]+)\t'
r"(?P<symbol>[^\t]+)\t"
r"(?P<filename>[^\t]+)\t"
r'(?P<ex_command>(/.+/|\?.+\?|\d+));"\t'
r'(?P<type>[^\t\r\n]+)'
r'(?:\t(?P<fields>.*))?'
r"(?P<type>[^\t\r\n]+)"
r"(?:\t(?P<fields>.*))?"
)

# column indexes
SYMBOL = 0
FILENAME = 1

MATCHES_STARTWITH = 'starts_with'
MATCHES_STARTWITH = "starts_with"

PATH_ORDER = [
'function', 'class', 'struct',
"function",
"class",
"struct",
]

PATH_IGNORE_FIELDS = (
'file', 'access', 'signature', 'language', 'line', 'inherits')
PATH_IGNORE_FIELDS = ("file", "access", "signature", "language", "line", "inherits")

TAG_PATH_SPLITTERS = ('/', '.', '::', ':')
TAG_PATH_SPLITTERS = ("/", ".", "::", ":")

#
# Functions
#

# Helper functions


def splits(string, *splitters):
"""
Split a string on a number of splitters.
Expand All @@ -61,9 +63,11 @@ def splits(string, *splitters):
if string:
yield string


# Tag processing functions

def parse_tag_lines(lines, order_by='symbol', tag_class=None, filters=None):

def parse_tag_lines(lines, order_by="symbol", tag_class=None, filters=None):
"""
Parse and sort a list of tags.
Expand All @@ -88,7 +92,7 @@ def parse_tag_lines(lines, order_by='symbol', tag_class=None, filters=None):
if isinstance(line, Tag): # handle both text and tag objects
line = line.line

line = line.rstrip('\r\n')
line = line.rstrip("\r\n")

search_obj = TAGS_RE.search(line)

Expand Down Expand Up @@ -116,6 +120,7 @@ def parse_tag_lines(lines, order_by='symbol', tag_class=None, filters=None):

return tags_lookup


def post_process_tag(tag):
"""
Process 'EX Command'-related elements of a tag.
Expand Down Expand Up @@ -160,12 +165,13 @@ def post_process_tag(tag):
"""
tag.update(process_fields(tag))

tag['ex_command'] = process_ex_cmd(tag)
tag["ex_command"] = process_ex_cmd(tag)

tag.update(create_tag_path(tag))

return tag


def process_ex_cmd(tag):
"""
Process the 'ex_command' element of a tag dictionary.
Expand All @@ -177,12 +183,13 @@ def process_ex_cmd(tag):
:returns: updated 'ex_command' dictionary entry
"""
ex_cmd = tag.get('ex_command')
ex_cmd = tag.get("ex_command")

if ex_cmd.isdigit(): # if a line number, do nothing
return ex_cmd
else: # else a regex, so unescape
return re.sub(r"\\(\$|/|\^|\\)", r'\1', ex_cmd[2:-2]) # unescape regex
else: # else a regex, so unescape
return re.sub(r"\\(\$|/|\^|\\)", r"\1", ex_cmd[2:-2]) # unescape regex


def process_fields(tag):
"""
Expand All @@ -197,19 +204,20 @@ def process_fields(tag):
:returns: dict containing the key-value pairs from the field element, plus
a list of keys for said pairs
"""
fields = tag.get('fields')
fields = tag.get("fields")

if not fields: # do nothing
return {}

# split the fields string into a dictionary of key-value pairs
result = dict(f.split(':', 1) for f in fields.split('\t'))
result = dict(f.split(":", 1) for f in fields.split("\t"))

# append all keys to the dictionary
result['field_keys'] = sorted(result.keys())
result["field_keys"] = sorted(result.keys())

return result


def create_tag_path(tag):
"""
Create a tag path entry for a tag dictionary.
Expand All @@ -226,9 +234,9 @@ def create_tag_path(tag):
:returns: dict containing the 'tag_path' entry
"""
field_keys = tag.get('field_keys', [])[:]
field_keys = tag.get("field_keys", [])[:]
fields = []
tag_path = ''
tag_path = ""

# sort field arguments related to path order in correct order
for field in PATH_ORDER:
Expand All @@ -242,22 +250,23 @@ def create_tag_path(tag):
# convert list of fields to dot-joined string, dropping any "ignore" fields
for field in fields:
if field not in PATH_IGNORE_FIELDS:
tag_path += (tag.get(field) + '.')
tag_path += tag.get(field) + "."

# append symbol as last item in string
tag_path += tag.get('symbol')
tag_path += tag.get("symbol")

# split string on seperators and append tag filename to resulting list
splitup = ([tag.get('filename')] +
list(splits(tag_path, *TAG_PATH_SPLITTERS)))
splitup = [tag.get("filename")] + list(splits(tag_path, *TAG_PATH_SPLITTERS))

# convert list to tuple
result = {'tag_path': tuple(splitup)}
result = {"tag_path": tuple(splitup)}

return result


# Tag building/sorting functions


def build_ctags(path, cmd=None, tag_file=None, recursive=False, opts=None):
"""
Execute the ``ctags`` command using ``Popen``.
Expand All @@ -275,19 +284,20 @@ def build_ctags(path, cmd=None, tag_file=None, recursive=False, opts=None):
if cmd:
cmd = [cmd]
else:
cmd = ['ctags']
cmd = ["ctags"]

if not os.path.exists(path):
raise IOError('\'path\' is not at valid directory or file path, or '
'is not accessible')
raise IOError(
"'path' is not at valid directory or file path, or " "is not accessible"
)

if os.path.isfile(path):
cwd = os.path.dirname(path)
else:
cwd = path

if tag_file:
cmd.append('-f {0}'.format(tag_file))
cmd.append("-f {0}".format(tag_file))

if opts:
if type(opts) == list:
Expand All @@ -296,24 +306,25 @@ def build_ctags(path, cmd=None, tag_file=None, recursive=False, opts=None):
cmd.append(opts)

if recursive: # ignore any file specified in path if recursive set
cmd.append('-R')
cmd.append("-R")
elif os.path.isfile(path):
filename = os.path.basename(path)
cmd.append(filename)
else: # search all files in current directory
cmd.append(os.path.join(path, '*'))
cmd.append(os.path.join(path, "*"))

# workaround for the issue described here:
# http://bugs.python.org/issue6689
if os.name == 'posix':
cmd = ' '.join(cmd)
if os.name == "posix":
cmd = " ".join(cmd)

# execute the command
check_output(cmd, cwd=cwd, shell=True, stdin=subprocess.PIPE,
stderr=subprocess.STDOUT)
check_output(
cmd, cwd=cwd, shell=True, stdin=subprocess.PIPE, stderr=subprocess.STDOUT
)

if not tag_file: # Exuberant ctags defaults to ``tags`` filename.
tag_file = os.path.join(cwd, 'tags')
tag_file = os.path.join(cwd, "tags")
else:
if os.path.dirname(tag_file) != cwd:
tag_file = os.path.join(cwd, tag_file)
Expand All @@ -323,6 +334,7 @@ def build_ctags(path, cmd=None, tag_file=None, recursive=False, opts=None):

return tag_file


def resort_ctags(tag_file):
"""
Rearrange ctags file for speed.
Expand Down Expand Up @@ -351,60 +363,63 @@ def resort_ctags(tag_file):
"""
meta = []
symbols = []
tmp_file = tag_file + '.tmp'
tmp_file = tag_file + ".tmp"

with codecs.open(tag_file, encoding='utf-8', errors='replace') as file_:
with codecs.open(tag_file, encoding="utf-8", errors="replace") as file_:
for line in file_:
if line.startswith('!_TAG'):
if line.startswith("!_TAG"):
meta.append(line)
continue

# read all valid symbol tags, which contain at least
# read all valid symbol tags, which contain at least
# symbol name and containing file and build a list of tuples
split = line.split('\t')
split = line.split("\t")
if len(split) > FILENAME:
symbols.append((split[FILENAME], split))

# sort inplace to save some RAM with large .tags files
meta.sort()
symbols.sort()

with codecs.open(tmp_file, 'w', encoding='utf-8',
errors='replace') as file_:

with codecs.open(tmp_file, "w", encoding="utf-8", errors="replace") as file_:
# write sourted metadata
file_.writelines(meta)

# followed by sorted list of symbols
for _, split in symbols:
split[FILENAME] = split[FILENAME].lstrip('.\\')
file_.write('\t'.join(split))
split[FILENAME] = split[FILENAME].lstrip(".\\")
file_.write("\t".join(split))

os.remove(tag_file)
os.rename(tmp_file, tag_file)


#
# Models
#


class TagElements(dict):
"""
Model the entries of a tag file.
"""

def __init__(self, *args, **kw):
"""Initialise Tag object"""
dict.__init__(self, *args, **kw)
self.__dict__ = self


class Tag(object):
"""
Model a tag.
This exists mainly to enable different types of sorting.
"""

def __init__(self, line, column=0):
if isinstance(line, bytes): # python 3 compatibility
line = line.decode('utf-8', 'replace')
line = line.decode("utf-8", "replace")
self.line = line
self.column = column

Expand All @@ -421,15 +436,16 @@ def __gt__(self, other):
return False

def __getitem__(self, index):
return self.line.split('\t', self.column + 1)[index]
return self.line.split("\t", self.column + 1)[index]

def __len__(self):
return self.line.count('\t') + 1
return self.line.count("\t") + 1

@property
def key(self):
return self[self.column]


class TagFile(object):
"""
Model a tag file.
Expand All @@ -440,6 +456,7 @@ class TagFile(object):
searching for a retrieving tags, finding tags based on given criteria
(prefix, suffix, exact), getting the directory of a tag and so forth.
"""

file_o = None
mapped = None

Expand Down Expand Up @@ -504,9 +521,8 @@ def open(self):
"""
Open file.
"""
self.file_o = codecs.open(self.path, 'r+b', encoding='utf-8')
self.mapped = mmap.mmap(self.file_o.fileno(), 0,
access=mmap.ACCESS_READ)
self.file_o = codecs.open(self.path, "r+b", encoding="utf-8")
self.mapped = mmap.mmap(self.file_o.fileno(), 0, access=mmap.ACCESS_READ)

def close(self):
"""
Expand Down Expand Up @@ -570,20 +586,22 @@ def tag_class(self):
accessed as class variables (i.e. ``class.variable``, rather than
``dict['variable'])
"""
return type('TagElements', (TagElements,), dict(root_dir=self.dir))
return type("TagElements", (TagElements,), dict(root_dir=self.dir))

def get_tags_dict(self, *tags, **kw):
"""
Return the tags from a tag file as a dict.
"""
filters = kw.get('filters', [])
return parse_tag_lines(self.search(True, *tags),
tag_class=self.tag_class(), filters=filters)
filters = kw.get("filters", [])
return parse_tag_lines(
self.search(True, *tags), tag_class=self.tag_class(), filters=filters
)

def get_tags_dict_by_suffix(self, suffix, **kw):
"""
Return the tags with the given suffix of a tag file as a dict.
"""
filters = kw.get('filters', [])
return parse_tag_lines(self.search_by_suffix(suffix),
tag_class=self.tag_class(), filters=filters)
filters = kw.get("filters", [])
return parse_tag_lines(
self.search_by_suffix(suffix), tag_class=self.tag_class(), filters=filters
)

0 comments on commit 4328efc

Please sign in to comment.