summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Quast <contact@jeffquast.com>2015-01-04 00:43:25 -0800
committerJeff Quast <contact@jeffquast.com>2015-01-04 00:43:25 -0800
commitbeaa2907d1dceb9639a7e99d31bb2fd09f43317f (patch)
tree473b8abeb2779afab883e9590d9991a1d94d1a1f
parentecda1a296838ad696ec47dac0370e488c191c917 (diff)
parent8f264cee6c24f3405752652719f73f3d4369bd12 (diff)
downloadblessings-beaa2907d1dceb9639a7e99d31bb2fd09f43317f.tar.gz
Merge pull request #39 from jquast/break-really-long-words
break_long_words=True now supported by term.wrap
-rw-r--r--README.rst1
-rw-r--r--blessed/sequences.py56
-rw-r--r--blessed/tests/accessories.py32
-rw-r--r--blessed/tests/test_wrap.py24
-rw-r--r--docs/conf.py2
-rwxr-xr-xsetup.py4
-rw-r--r--tox.ini3
7 files changed, 89 insertions, 33 deletions
diff --git a/README.rst b/README.rst
index e3c9a42..d805e7d 100644
--- a/README.rst
+++ b/README.rst
@@ -691,6 +691,7 @@ shares the same. See the LICENSE file.
Version History
===============
1.9
+ * enhancement: ``break_long_words=True`` now supported by ``term.wrap``
* workaround: ignore curses.error 'tparm() returned NULL', this occurs
on win32 platforms using PDCurses_ where ``tparm()`` is not
implemented.
diff --git a/blessed/sequences.py b/blessed/sequences.py
index 2862197..8f9ed95 100644
--- a/blessed/sequences.py
+++ b/blessed/sequences.py
@@ -103,7 +103,7 @@ def get_movement_sequence_patterns(term):
re.escape(term.rc),
# clear_screen: clear screen and home cursor
re.escape(term.clear),
- # cursor_up: Up one line
+ # enter/exit_fullscreen: switch to alternate screen buffer
re.escape(term.enter_fullscreen),
re.escape(term.exit_fullscreen),
# forward cursor
@@ -369,6 +369,60 @@ class SequenceTextWrapper(textwrap.TextWrapper):
lines.append(indent + u''.join(cur_line))
return lines
+ def _handle_long_word(self, reversed_chunks, cur_line, cur_len, width):
+ """_handle_long_word(chunks : [string],
+ cur_line : [string],
+ cur_len : int, width : int)
+
+ Handle a chunk of text (most likely a word, not whitespace) that
+ is too long to fit in any line.
+ """
+ # Figure out when indent is larger than the specified width, and make
+ # sure at least one character is stripped off on every pass
+ if width < 1:
+ space_left = 1
+ else:
+ space_left = width - cur_len
+
+ # If we're allowed to break long words, then do so: put as much
+ # of the next chunk onto the current line as will fit.
+ if self.break_long_words:
+ term = self.term
+ chunk = reversed_chunks[-1]
+ if (space_left == 0 or
+ space_left == 1 and chunk == u' '):
+ idx = space_left
+ else:
+ nxt = 0
+ for idx in range(0, len(chunk)):
+ if idx == nxt:
+ # at sequence, point beyond it,
+ nxt = idx + measure_length(chunk[idx:], term)
+ if nxt <= idx:
+ # point beyond next sequence, if any,
+ # otherwise point to next character
+ nxt = idx + measure_length(chunk[idx:], term) + 1
+ if Sequence(chunk[:nxt], term).length() > space_left:
+ break
+ else:
+ idx = space_left
+
+ cur_line.append(reversed_chunks[-1][:idx])
+ reversed_chunks[-1] = reversed_chunks[-1][idx:]
+
+ # Otherwise, we have to preserve the long word intact. Only add
+ # it to the current line if there's nothing already there --
+ # that minimizes how much we violate the width constraint.
+ elif not cur_line:
+ cur_line.append(reversed_chunks.pop())
+
+ # If we're not allowed to break long words, and there's already
+ # text on the current line, do nothing. Next time through the
+ # main loop of _wrap_chunks(), we'll wind up here again, but
+ # cur_len will be zero, so the next line will be entirely
+ # devoted to the long word that we can't handle right now.
+
+
SequenceTextWrapper.__doc__ = textwrap.TextWrapper.__doc__
diff --git a/blessed/tests/accessories.py b/blessed/tests/accessories.py
index 9c06688..408d2e7 100644
--- a/blessed/tests/accessories.py
+++ b/blessed/tests/accessories.py
@@ -30,24 +30,24 @@ SEND_SEMAPHORE = SEMAPHORE = b'SEMAPHORE\n'
RECV_SEMAPHORE = b'SEMAPHORE\r\n'
all_xterms_params = ['xterm', 'xterm-256color']
many_lines_params = [30, 100]
-many_columns_params = [1, 25, 50]
+many_columns_params = [1, 10]
from blessed._binterms import binary_terminals
default_all_terms = ['screen', 'vt220', 'rxvt', 'cons25', 'linux', 'ansi']
-try:
- available_terms = [
- _term.split(None, 1)[0].decode('ascii') for _term in
- subprocess.Popen(["toe"], stdout=subprocess.PIPE, close_fds=True)
- .communicate()[0].splitlines()]
- if not os.environ.get('TEST_ALLTERMS'):
- # we just pick 3 random terminal types, they're all as good as any so
- # long as they're not in the binary_terminals list.
- random.shuffle(available_terms)
- available_terms = available_terms[:3]
- all_terms_params = list(set(available_terms) - (
- set(binary_terminals) if not os.environ.get('TEST_BINTERMS')
- else set())) or default_all_terms
-except OSError:
- all_terms_params = default_all_terms
+if os.environ.get('TEST_ALLTERMS'):
+ try:
+ available_terms = [
+ _term.split(None, 1)[0].decode('ascii') for _term in
+ subprocess.Popen(('toe', '-a'),
+ stdout=subprocess.PIPE,
+ close_fds=True)
+ .communicate()[0].splitlines()]
+ except OSError:
+ all_terms_params = default_all_terms
+else:
+ available_terms = default_all_terms
+all_terms_params = list(set(available_terms) - (
+ set(binary_terminals) if not os.environ.get('TEST_BINTERMS')
+ else set())) or default_all_terms
class as_subprocess(object):
diff --git a/blessed/tests/test_wrap.py b/blessed/tests/test_wrap.py
index dee3ebc..1e12060 100644
--- a/blessed/tests/test_wrap.py
+++ b/blessed/tests/test_wrap.py
@@ -48,18 +48,18 @@ def test_SequenceWrapper_invalid_width():
dict(break_long_words=False,
drop_whitespace=True,
subsequent_indent=' '),
- # dict(break_long_words=True,
- # drop_whitespace=False,
- # subsequent_indent=''),
- # dict(break_long_words=True,
- # drop_whitespace=True,
- # subsequent_indent=''),
- # dict(break_long_words=True,
- # drop_whitespace=False,
- # subsequent_indent=' '),
- # dict(break_long_words=True,
- # drop_whitespace=True,
- # subsequent_indent=' '),
+ dict(break_long_words=True,
+ drop_whitespace=False,
+ subsequent_indent=''),
+ dict(break_long_words=True,
+ drop_whitespace=True,
+ subsequent_indent=''),
+ dict(break_long_words=True,
+ drop_whitespace=False,
+ subsequent_indent=' '),
+ dict(break_long_words=True,
+ drop_whitespace=True,
+ subsequent_indent=' '),
])
def test_SequenceWrapper(all_terms, many_columns, kwargs):
"""Test that text wrapping matches internal extra options."""
diff --git a/docs/conf.py b/docs/conf.py
index 4ab6f41..6975d7f 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -53,7 +53,7 @@ copyright = u'2014 Jeff Quast, 2011 Erik Rose'
# built documents.
#
# The short X.Y version.
-version = '1.9.4'
+version = '1.9.5'
# The full version, including alpha/beta/rc tags.
release = version
diff --git a/setup.py b/setup.py
index 338e2ff..489ebed 100755
--- a/setup.py
+++ b/setup.py
@@ -17,7 +17,7 @@ class SetupDevelop(setuptools.command.develop.develop):
# ensure a virtualenv is loaded,
assert os.getenv('VIRTUAL_ENV'), 'You should be in a virtualenv'
# ensure tox is installed
- subprocess.check_call(('pip', 'install', 'tox'))
+ subprocess.check_call(('pip', 'install', 'tox', 'ipython'))
# install development egg-link
setuptools.command.develop.develop.run(self)
@@ -38,7 +38,7 @@ def main():
setuptools.setup(
name='blessed',
- version='1.9.4',
+ version='1.9.5',
description="A feature-filled fork of Erik Rose's blessings project",
long_description=open(os.path.join(here, 'README.rst')).read(),
author='Jeff Quast',
diff --git a/tox.ini b/tox.ini
index 2c9ee50..5c93fca 100644
--- a/tox.ini
+++ b/tox.ini
@@ -20,7 +20,8 @@ deps = pytest-flakes
commands = {envbindir}/py.test \
--strict --pep8 --flakes \
--junit-xml=results.{envname}.xml --verbose \
- --cov blessed blessed/tests {posargs}
+ --cov blessed blessed/tests --cov-report=term-missing \
+ {posargs}
/bin/mv {toxinidir}/.coverage {toxinidir}/.coverage.{envname}
[testenv:static_analysis]