Skip to content

Commit 4776c2f

Browse files
author
deathaxe
committed
Merge branch 'development'
2 parents 96e8615 + babb1a9 commit 4776c2f

10 files changed

+176
-166
lines changed

.github/workflows/ci.yaml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: CI
2+
on: [push, pull_request]
3+
4+
jobs:
5+
tests:
6+
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v3
10+
- name: Set up Python
11+
uses: actions/setup-python@v3
12+
with:
13+
python-version: 3.8
14+
- name: Install Universal CTags
15+
run: sudo apt-get install universal-ctags
16+
- name: Install PyTest
17+
run: pip install pytest
18+
- name: Run PyTest
19+
run: pytest .
20+

.python-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.8

.travis.yml

-12
This file was deleted.

Default.sublime-commands

-16
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,12 @@
66
{
77
"caption": "CTags: Show Symbols (file)",
88
"command": "show_symbols",
9-
"context": [
10-
{
11-
"key": "selector",
12-
"match_all": true,
13-
"operand": "source -source.css",
14-
"operator": "equal"
15-
}
16-
]
179
},
1810
{
1911
"caption": "CTags: Show Symbols (all)",
2012
"command": "show_symbols",
2113
"args": {
2214
"type": "multi"
2315
},
24-
"context": [
25-
{
26-
"key": "selector",
27-
"match_all": true,
28-
"operand": "source -source.css",
29-
"operator": "equal"
30-
}
31-
]
3216
}
3317
]

Main.sublime-menu

+3-20
Original file line numberDiff line numberDiff line change
@@ -22,39 +22,22 @@
2222
"command": "rebuild_tags"
2323
},
2424
{
25+
"caption": "Show Symbols (file)",
2526
"command": "show_symbols",
26-
"context": [
27-
{
28-
"key": "selector",
29-
"match_all": true,
30-
"operand": "source -source.css",
31-
"operator": "equal"
32-
}
33-
]
3427
},
3528
{
29+
"caption": "Show Symbols (all)",
30+
"command": "show_symbols",
3631
//"arg_comment": "TODO",
3732
"args": {
3833
"type": "multi"
3934
},
40-
"caption": "Show Symbols (all)",
41-
"command": "show_symbols",
42-
"context": [
43-
{
44-
"key": "selector",
45-
"match_all": true,
46-
"operand": "source -source.css",
47-
"operator": "equal"
48-
}
49-
]
5035
}
5136
]
5237
}
5338
]
5439
},
5540
{
56-
"caption": "Preferences",
57-
"mnemonic": "n",
5841
"id": "preferences",
5942
"children":
6043
[

README.rst

+6-9
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22
CTags
33
=====
44

5-
.. image:: https://travis-ci.org/SublimeText/CTags.svg?branch=development
6-
:target: https://travis-ci.org/SublimeText/CTags
5+
.. image:: https://github.com/SublimeText/CTags/actions/workflows/ci.yaml/badge.svg
76

87
About
98
=====
109

11-
This `Sublime Text 2/3`_ package provides support for working with tags
10+
This `Sublime Text`_ package provides support for working with tags
1211
generated by `Exuberant CTags`_
1312

14-
.. _Sublime Text 2/3: http://sublimetext.com/
13+
.. _Sublime Text: http://sublimetext.com/
1514
.. _Exuberant CTags: http://ctags.sourceforge.net/
1615

1716
The ctags command is searched for on the system PATH. It works by doing a
@@ -25,11 +24,9 @@ See this `forum thread`_ for a bit of historical background on the Sublime Text
2524
Installation
2625
============
2726

28-
The easiest way to install this plugin, is to use the `Package Control`_
29-
plugin, by `Will Bond`_
27+
The easiest way to install this plugin, is to use the `Package Control`_ .
3028

31-
.. _Package Control: http://wbond.net/sublime_packages/package_control/
32-
.. _Will Bond: http://wbond.net/
29+
.. _Package Control: http://packagecontrol.io/
3330

3431
Alternatively, the plugin can be installed manually using one of the following
3532
methods.
@@ -159,7 +156,7 @@ can be edited like any other ``.sublime-settings`` file
159156

160157
or::
161158

162-
"command" : "C:\Users\<username>\Downloads\CTags\ctag.exe"
159+
"command" : "C:\\Users\\<username>\\Downloads\\CTags\\ctag.exe"
163160

164161
The rest of the options are fairly self explanatory.
165162

ctags.py

+54-22
Original file line numberDiff line numberDiff line change
@@ -341,31 +341,51 @@ def resort_ctags(tag_file):
341341
If not exists, create an empty array and store in the
342342
dictionary with the file name as key
343343
Save the line to this list
344-
Create a new ``[tagfile]_sorted_by_file`` file
344+
Create a new ``tagfile`` file
345345
For each key in the sorted dictionary
346346
For each line in the list indicated by the key
347347
Split the line on tab character
348-
Remove the prepending ``.\`` from the ``file_name`` part of
348+
Remove the prepending ``.`` from the ``file_name`` part of
349349
the tag
350350
Join the line again and write the ``sorted_by_file`` file
351351
352352
:param tag_file: The location of the tagfile to be sorted
353353
354354
:returns: None
355355
"""
356-
keys = {}
356+
meta = []
357+
symbols = []
358+
tmp_file = tag_file + '.tmp'
357359

358360
with codecs.open(tag_file, encoding='utf-8', errors='replace') as file_:
359361
for line in file_:
360-
keys.setdefault(line.split('\t')[FILENAME], []).append(line)
362+
if line.startswith('!_TAG'):
363+
meta.append(line)
364+
continue
365+
366+
# read all valid symbol tags, which contain at least
367+
# symbol name and containing file and build a list of tuples
368+
split = line.split('\t')
369+
if len(split) > FILENAME:
370+
symbols.append((split[FILENAME], split))
371+
372+
# sort inplace to save some RAM with large .tags files
373+
meta.sort()
374+
symbols.sort()
361375

362-
with codecs.open(tag_file+'_sorted_by_file', 'w', encoding='utf-8',
376+
with codecs.open(tmp_file, 'w', encoding='utf-8',
363377
errors='replace') as file_:
364-
for k in sorted(keys):
365-
for line in keys[k]:
366-
split = line.split('\t')
367-
split[FILENAME] = split[FILENAME].lstrip('.\\')
368-
file_.write('\t'.join(split))
378+
379+
# write sourted metadata
380+
file_.writelines(meta)
381+
382+
# followed by sorted list of symbols
383+
for _, split in symbols:
384+
split[FILENAME] = split[FILENAME].lstrip('.\\')
385+
file_.write('\t'.join(split))
386+
387+
os.remove(tag_file)
388+
os.rename(tmp_file, tag_file)
369389

370390
#
371391
# Models
@@ -393,16 +413,26 @@ def __init__(self, line, column=0):
393413
self.column = column
394414

395415
def __lt__(self, other):
396-
return self.line.split('\t')[self.column] < other
416+
try:
417+
return self.key < other
418+
except IndexError:
419+
return False
397420

398421
def __gt__(self, other):
399-
return self.line.split('\t')[self.column] > other
422+
try:
423+
return self.key > other
424+
except IndexError:
425+
return False
400426

401427
def __getitem__(self, index):
402-
return self.line.split('\t')[index]
428+
return self.line.split('\t', self.column + 1)[index]
403429

404430
def __len__(self):
405-
return len(self.line.split('\t'))
431+
return self.line.count('\t') + 1
432+
433+
@property
434+
def key(self):
435+
return self[self.column]
406436

407437
class TagFile(object):
408438
"""
@@ -443,6 +473,8 @@ def __getitem__(self, index):
443473
result = self.mapped.readline() # get a complete line
444474

445475
result = result.strip()
476+
if not result:
477+
raise IndexError("Invalid tag at index %d." % index)
446478

447479
return Tag(result, self.column)
448480

@@ -476,7 +508,7 @@ def open(self):
476508
"""
477509
Open file.
478510
"""
479-
self.file_o = codecs.open(self.path, 'r+b', encoding='ascii')
511+
self.file_o = codecs.open(self.path, 'r+b', encoding='utf-8')
480512
self.mapped = mmap.mmap(self.file_o.fileno(), 0,
481513
access=mmap.ACCESS_READ)
482514

@@ -500,20 +532,21 @@ def search(self, exact_match=True, *tags):
500532
if not tags:
501533
while self.mapped.tell() < self.mapped.size():
502534
result = Tag(self.mapped.readline().strip(), self.column)
503-
yield(result)
535+
if result.line:
536+
yield result
504537
return
505538

506539
for key in tags:
507540
left_index = bisect.bisect_left(self, key)
508541
if exact_match:
509542
result = self[left_index]
510543
while result.line and result[result.column] == key:
511-
yield(result)
544+
yield result
512545
result = Tag(self.mapped.readline().strip(), self.column)
513546
else:
514547
result = self[left_index]
515548
while result.line and result[result.column].startswith(key):
516-
yield(result)
549+
yield result
517550
result = Tag(self.mapped.readline().strip(), self.column)
518551

519552
def search_by_suffix(self, suffix):
@@ -529,10 +562,9 @@ def search_by_suffix(self, suffix):
529562
:returns: matching tags
530563
"""
531564
for line in self.file_o:
532-
if line.split('\t')[self.column].endswith(suffix):
533-
yield Tag(line)
534-
else:
535-
continue
565+
tag = Tag(line, self.column)
566+
if tag.key.endswith(suffix):
567+
yield tag
536568

537569
def tag_class(self):
538570
"""

0 commit comments

Comments
 (0)