The builtin `join_lines` command is too slow.
Description
The builtin join_lines is too slow.
import re
import sublime_plugin
class ReJoinLinesCommand(sublime_plugin.TextCommand):
def run(self, edit):
selections = list(self.view.sel())
for selection in reversed(selections):
content = self.view.substr(selection)
new_str = re.sub(r'\n\s*', ' ', content)
self.view.replace(edit, selection, new_str)
The re_join_lines command provided above is a simple version of join_lines. For joining lines of non empty selection regions, its functionality is not exactly the same as join_lines, but roughly the same. For a 700-line code selection, it is 1000 times faster than join_lines, this is very strange.
>>> timeit.timeit(lambda:view.run_command('re_join_lines'), number=1)
0.005591699999058619
>>> timeit.timeit(lambda:view.run_command('join_lines'), number=1)
5.893734800001766
Environment
- Build: 4116
- Operating system and version: Windows 10
I believe that the original join_lines command is implemented natively as I couldn't find it in the Default package.
Which is an issue because we don't know how much of the original functionality is your version missing. One thing missing for sure is ability to join lines with empty selection - that doesn't work with your version.
There is also some "smart" functionality missing from the original which makes it either add or not add white space when joining lines. For example when joining:
[
1,
2,
3
]
would produce:
[1, 2, 3 ]
which is still not ideal due to the trailing space but still better than adding space for each item.
I believe that the original
join_linescommand is implemented natively as I couldn't find it in the Default package.Which is an issue because we don't know how much of the original functionality is your version missing. One thing missing for sure is ability to join lines with empty selection - that doesn't work with your version.
Yes, my version is too simple, it dose not work in empty selections, misses handling for multiple selections in a single line. But the number 1000 is too large. As far as I know, VSC has no such problem.
For a 700-line code selection, it is 1000 times faster than join_lines
Can you share this code?
This kind of code is everywhere. You can select a region of hundreds of lines of code and try it out. I believe that you'll notice a noticeable lag.
@rwols
The undo operation to the join_lines command is also costly.
>>> timeit.timeit(lambda:view.run_command('join_lines'), number=1)
5.900341100001242
>>> timeit.timeit(lambda:view.run_command('undo'), number=1)
5.82682449999993
>>> timeit.timeit(lambda:view.run_command('re_join_lines'), number=1)
0.005585900002188282
>>> timeit.timeit(lambda:view.run_command('undo'), number=1)
0.014367700001457706