Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions st3/sublime_lib/view_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ def guard_read_only(self):
else:
yield

@define_guard
@contextmanager
def guard_auto_indent(self):
settings = self.view.settings()
if settings.get('auto_indent'):
settings.set('auto_indent', False)
yield
settings.set('auto_indent', True)
else:
yield

@define_guard
def guard_validity(self):
if not self.view.is_valid():
Expand Down Expand Up @@ -95,25 +106,23 @@ def _read(self, begin, end, size):
@guard_validity
@guard_selection
@guard_read_only
@guard_auto_indent
def write(self, s):
"""Insert the string `s` into the view and return the number of
characters inserted. The string will be inserted immediately before the
cursor.
cursor. It will not be auto-indented.

Note: Because Sublime may convert tabs to spaces, the number of
characters inserted may not match the length of the argument.
"""
# This is a hack to get around auto-indentation.
old_size = self.view.size()
self.view.run_command('insert_snippet', {
'contents': '$sublime_lib__insert_text',
'sublime_lib__insert_text': s,
})
self.view.run_command('insert', {'characters': s})
return self.view.size() - old_size

def print(self, *objects, **kwargs):
"""Shorthand for ``print(*objects, file=self, **kwargs)``."""
print(*objects, file=self, **kwargs)
def print(self, *objects, sep=' ', end='\n'):
"""Shorthand for :func:`print()` passing this ViewStream as the `file`
argument."""
print(*objects, file=self, sep=sep, end=end)

def flush(self):
"""Do nothing. (The stream is not buffered.)"""
Expand Down
62 changes: 56 additions & 6 deletions tests/test_view_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from sublime_lib import ViewStream

from unittest import TestCase
from io import UnsupportedOperation
from io import UnsupportedOperation, StringIO


class TestViewStream(TestCase):
Expand Down Expand Up @@ -48,11 +48,12 @@ def test_write_size(self):
self.assertEqual(size, self.stream.view.size())

def test_no_indent(self):
text = "Hello\n World\n!"
text = " "

self.stream.view.settings().set('auto_indent', True)
self.stream.write(text)
self.assertContents(text)
self.stream.write("\n")
self.assertContents(text + "\n")

def test_clear(self):
self.stream.write("Some text")
Expand Down Expand Up @@ -109,17 +110,66 @@ def test_readline(self):
self.assertEqual(text, "World")
self.assertEqual(self.stream.tell(), 12)

def test_write_only(self):
def test_write_read_only_failure(self):
self.stream.view.set_read_only(True)

self.assertRaises(ValueError, self.stream.write, 'foo')
self.assertRaises(ValueError, self.stream.clear)

def test_write_read_only_success(self):
self.stream.view.set_read_only(True)
self.stream.force_writes = True
self.assertEqual(self.stream.write('foo'), 3)

self.stream.write('foo')
self.assertContents('foo')

self.stream.clear()
self.assertContents('')

def _compare_print(self, *args, **kwargs):
s = StringIO()
print(*args, file=s, **kwargs)

self.stream.clear()
self.stream.print(*args, **kwargs)

self.assertContents(s.getvalue())

self.stream.clear()
print(*args, file=self.stream, **kwargs)

self.assertContents(s.getvalue())

def test_print(self):
text = "Hello, World!"
number = 42

self._compare_print(text, number)
self._compare_print(text, number, sep=',', end=';')
self._compare_print(text, number, sep='', end='')

def test_print_no_indent(self):
text = " "

self.stream.view.settings().set('auto_indent', True)
self.stream.print(text)
self.assertContents(text + "\n")

def test_print_read_only_failure(self):
self.stream.view.set_read_only(True)

self.assertRaises(ValueError, self.stream.print, 'foo')
self.assertRaises(ValueError, self.stream.clear)

def test_print_read_only_success(self):
self.stream.view.set_read_only(True)
self.stream.force_writes = True

self.stream.print('foo')
self.assertContents("foo\n")

self.stream.clear()
self.assertEqual(self.stream.view.size(), 0)
self.assertContents('')

def test_unsupported(self):
self.assertRaises(UnsupportedOperation, self.stream.detach)
Expand Down