merge the textmate demo into babi
This commit is contained in:
69
babi/textmate_demo.py
Normal file
69
babi/textmate_demo.py
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import argparse
|
||||||
|
from typing import Optional
|
||||||
|
from typing import Sequence
|
||||||
|
|
||||||
|
from babi.highlight import Compiler
|
||||||
|
from babi.highlight import Grammars
|
||||||
|
from babi.highlight import highlight_line
|
||||||
|
from babi.theme import Style
|
||||||
|
from babi.theme import Theme
|
||||||
|
from babi.user_data import prefix_data
|
||||||
|
from babi.user_data import xdg_config
|
||||||
|
|
||||||
|
|
||||||
|
def print_styled(s: str, style: Style) -> None:
|
||||||
|
color_s = ''
|
||||||
|
undo_s = ''
|
||||||
|
if style.fg is not None:
|
||||||
|
color_s += '\x1b[38;2;{r};{g};{b}m'.format(**style.fg._asdict())
|
||||||
|
undo_s += '\x1b[39m'
|
||||||
|
if style.bg is not None:
|
||||||
|
color_s += '\x1b[48;2;{r};{g};{b}m'.format(**style.bg._asdict())
|
||||||
|
undo_s += '\x1b[49m'
|
||||||
|
if style.b:
|
||||||
|
color_s += '\x1b[1m'
|
||||||
|
undo_s += '\x1b[22m'
|
||||||
|
if style.i:
|
||||||
|
color_s += '\x1b[3m'
|
||||||
|
undo_s += '\x1b[23m'
|
||||||
|
if style.u:
|
||||||
|
color_s += '\x1b[4m'
|
||||||
|
undo_s += '\x1b[24m'
|
||||||
|
print(f'{color_s}{s}{undo_s}', end='', flush=True)
|
||||||
|
|
||||||
|
|
||||||
|
def _highlight_output(theme: Theme, compiler: Compiler, filename: str) -> int:
|
||||||
|
state = compiler.root_state
|
||||||
|
|
||||||
|
if theme.default.bg is not None:
|
||||||
|
print('\x1b[48;2;{r};{g};{b}m'.format(**theme.default.bg._asdict()))
|
||||||
|
with open(filename) as f:
|
||||||
|
for line_idx, line in enumerate(f):
|
||||||
|
first_line = line_idx == 0
|
||||||
|
state, regions = highlight_line(compiler, state, line, first_line)
|
||||||
|
for start, end, scope in regions:
|
||||||
|
print_styled(line[start:end], theme.select(scope))
|
||||||
|
print('\x1b[m', end='')
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv: Optional[Sequence[str]] = None) -> int:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--theme', default=xdg_config('theme.json'))
|
||||||
|
parser.add_argument('--grammar-dir', default=prefix_data('grammar_v1'))
|
||||||
|
parser.add_argument('filename')
|
||||||
|
args = parser.parse_args(argv)
|
||||||
|
|
||||||
|
with open(args.filename) as f:
|
||||||
|
first_line = next(f, '')
|
||||||
|
|
||||||
|
theme = Theme.from_filename(args.theme)
|
||||||
|
|
||||||
|
grammars = Grammars(args.grammar_dir)
|
||||||
|
compiler = grammars.compiler_for_file(args.filename, first_line)
|
||||||
|
|
||||||
|
return _highlight_output(theme, compiler, args.filename)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
exit(main())
|
||||||
@@ -32,6 +32,7 @@ python_requires = >=3.6.1
|
|||||||
[options.entry_points]
|
[options.entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
babi = babi.main:main
|
babi = babi.main:main
|
||||||
|
babi-textmate-demo = babi.textmate_demo:main
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
exclude =
|
exclude =
|
||||||
|
|||||||
84
tests/textmate_demo_test.py
Normal file
84
tests/textmate_demo_test.py
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from babi.textmate_demo import main
|
||||||
|
|
||||||
|
THEME = {
|
||||||
|
'colors': {'foreground': '#ffffff', 'background': '#000000'},
|
||||||
|
'tokenColors': [
|
||||||
|
{'scope': 'bold', 'settings': {'fontStyle': 'bold'}},
|
||||||
|
{'scope': 'italic', 'settings': {'fontStyle': 'italic'}},
|
||||||
|
{'scope': 'underline', 'settings': {'fontStyle': 'underline'}},
|
||||||
|
{'scope': 'comment', 'settings': {'foreground': '#1e77d3'}},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
GRAMMAR = {
|
||||||
|
'scopeName': 'source.demo',
|
||||||
|
'fileTypes': ['demo'],
|
||||||
|
'patterns': [
|
||||||
|
{'match': r'\*[^*]*\*', 'name': 'bold'},
|
||||||
|
{'match': '/[^/]*/', 'name': 'italic'},
|
||||||
|
{'match': '_[^_]*_', 'name': 'underline'},
|
||||||
|
{'match': '#.*', 'name': 'comment'},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def theme_grammars(tmpdir):
|
||||||
|
theme = tmpdir.join('config/theme.json').ensure()
|
||||||
|
theme.write(json.dumps(THEME))
|
||||||
|
grammars = tmpdir.join('grammar_v1').ensure_dir()
|
||||||
|
grammars.join('source.demo.json').write(json.dumps(GRAMMAR))
|
||||||
|
return theme, grammars
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic(theme_grammars, tmpdir, capsys):
|
||||||
|
theme, grammars = theme_grammars
|
||||||
|
|
||||||
|
f = tmpdir.join('f.demo')
|
||||||
|
f.write('*bold*/italic/_underline_# comment\n')
|
||||||
|
|
||||||
|
assert not main((
|
||||||
|
'--theme', str(theme), '--grammar-dir', str(grammars),
|
||||||
|
str(f),
|
||||||
|
))
|
||||||
|
|
||||||
|
out, _ = capsys.readouterr()
|
||||||
|
|
||||||
|
assert out == (
|
||||||
|
'\x1b[48;2;0;0;0m\n'
|
||||||
|
'\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m\x1b[1m'
|
||||||
|
'*bold*'
|
||||||
|
'\x1b[39m\x1b[49m\x1b[22m'
|
||||||
|
'\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m\x1b[3m'
|
||||||
|
'/italic/'
|
||||||
|
'\x1b[39m\x1b[49m\x1b[23m'
|
||||||
|
'\x1b[38;2;255;255;255m\x1b[48;2;0;0;0m\x1b[4m'
|
||||||
|
'_underline_'
|
||||||
|
'\x1b[39m\x1b[49m\x1b[24m'
|
||||||
|
'\x1b[38;2;30;119;211m\x1b[48;2;0;0;0m'
|
||||||
|
'# comment'
|
||||||
|
'\x1b[39m\x1b[49m\x1b'
|
||||||
|
'[38;2;255;255;255m\x1b[48;2;0;0;0m\n\x1b[39m\x1b[49m'
|
||||||
|
'\x1b[m'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic_with_blank_theme(theme_grammars, tmpdir, capsys):
|
||||||
|
theme, grammars = theme_grammars
|
||||||
|
theme.write('{}')
|
||||||
|
|
||||||
|
f = tmpdir.join('f.demo')
|
||||||
|
f.write('*bold*/italic/_underline_# comment\n')
|
||||||
|
|
||||||
|
assert not main((
|
||||||
|
'--theme', str(theme), '--grammar-dir', str(grammars),
|
||||||
|
str(f),
|
||||||
|
))
|
||||||
|
|
||||||
|
out, _ = capsys.readouterr()
|
||||||
|
|
||||||
|
assert out == '*bold*/italic/_underline_# comment\n\x1b[m'
|
||||||
Reference in New Issue
Block a user