93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
import shutil
|
|
import textwrap
|
|
|
|
|
|
def resolve_abbrev(needle, strings, lower=False):
|
|
"""Return a full-length string matching a substring from the beginning.
|
|
|
|
Parameters
|
|
----------
|
|
needle : str
|
|
Substring of one of several `strings`.
|
|
strings : str or iterable of str
|
|
Full-length strings, one of which should begin with `needle`.
|
|
lower : bool, optional
|
|
Convert needle to lowercase before matching.
|
|
|
|
Returns
|
|
-------
|
|
str
|
|
String in `strings` that begins with `needle` if there is no ambiguity.
|
|
If there is not exactly one match, the function will return `needle`.
|
|
|
|
"""
|
|
if isinstance(strings, str):
|
|
strings = [strings]
|
|
strings = tuple(strings)
|
|
|
|
if lower:
|
|
needle = needle.lower()
|
|
|
|
matches = [f for f in strings if f.startswith(needle)]
|
|
return matches[0] if len(matches) == 1 else needle
|
|
|
|
|
|
def rewrap_text(text, width=None, hard='\t\n', hard_indent=0, end=''):
|
|
"""Rewrap text such that lines fill the available horizontal space.
|
|
|
|
Reformats individual paragraphs of a text body, considering subsequent
|
|
lines with identical indentation as paragraphs. For unspecified width, the
|
|
function will attempt to determine the extent of the terminal.
|
|
|
|
Parameters
|
|
----------
|
|
text : str
|
|
Text to rewrap.
|
|
width : int, optional
|
|
Maximum line width. None means the width of the terminal as determined
|
|
by `textwrap`, defaulting to 80 characters for background processes.
|
|
hard : str, optional
|
|
String interpreted as a hard break when terminating a line. Useful for
|
|
inserting a line break without changing the indentation level. Must end
|
|
with a line break and will be removed from the output text.
|
|
hard_indent : int, optional
|
|
Number of additional whitespace characters by which to indent the lines
|
|
following a hard break. See `hard`.
|
|
end : str, optional
|
|
Append to the reformatted text.
|
|
|
|
Returns
|
|
-------
|
|
out : str
|
|
Reformatted text.
|
|
|
|
"""
|
|
# Inputs.
|
|
if width is None:
|
|
width = shutil.get_terminal_size().columns
|
|
lines = text.splitlines(keepends=True)
|
|
|
|
# Merge lines to paragraphs.
|
|
pad = []
|
|
pad_hard = []
|
|
par = []
|
|
for i, line in enumerate(lines):
|
|
ind = len(line) - len(line.lstrip())
|
|
if i == 0 or ind != pad[-1] or lines[i - 1].endswith(hard):
|
|
par.append('')
|
|
pad.append(ind)
|
|
pad_hard.append(ind)
|
|
|
|
if line.endswith(hard):
|
|
line = line.replace(hard, '\n')
|
|
pad_hard[-1] += hard_indent
|
|
par[-1] += line[ind:]
|
|
|
|
# Reformat paragraphs.
|
|
for i, _ in enumerate(par):
|
|
par[i] = textwrap.fill(
|
|
par[i], width,
|
|
initial_indent=' ' * pad[i], subsequent_indent=' ' * pad_hard[i],
|
|
)
|
|
|
|
return '\n'.join(par) + end
|