Add argument split_lines for when you just want the whole text.

Calling '\n'.join(pipeable.input()) is not great because in many
situations, you're splitting text and joining it back together again
for no reason. With this option, we can let the code do the right
thing, and use pipeable as a general-purpose inputter in
more situations.
This commit is contained in:
voussoir 2021-08-17 14:00:11 -07:00
parent db8c6e42e3
commit cb5228fe0c
No known key found for this signature in database
GPG key ID: 5F7554F8C26DACCB

View file

@ -95,19 +95,19 @@ def input(
input_prompt=None, input_prompt=None,
read_files=False, read_files=False,
skip_blank=False, skip_blank=False,
split_lines=True,
strip=False, strip=False,
): ):
''' '''
Given an argument (probably from the command line), resolve it into a Given an argument (probably from the command line), resolve it into an
generator of lines. iterable of lines if split_lines is True, or return the whole text.
If the arg is in CLIPBOARD_STRINGS, the contents of the clipboard are taken If the arg is in CLIPBOARD_STRINGS, the contents of the clipboard are taken.
and split into lines.
If the arg is in INPUT_STRINGS, input is read from stdin with an optional If the arg is in INPUT_STRINGS, input is read from stdin with an optional
input_prompt that is only shown during non-pipe input (actual typing). input_prompt. The prompt is only shown during non-pipe input (typing).
If read_files is True and the arg is the path to an existing file, the file If read_files is True and the arg is the path to an existing file, the file
is read as utf-8 lines. is read as utf-8 text.
If none of the above, then the argument is taken literally. If none of the above, then the argument string is taken literally.
Resolution is not recursive: if the clipboard contains the name of a file, Resolution is not recursive: if the clipboard contains the name of a file,
it won't be read, etc. it won't be read, etc.
@ -117,7 +117,7 @@ def input(
strip is False, then all-whitespace lines will still be yielded). If you're strip is False, then all-whitespace lines will still be yielded). If you're
modifying input but overall maintaining its original structure, you probably modifying input but overall maintaining its original structure, you probably
want these both False. If you're just crunching numbers you probably want want these both False. If you're just crunching numbers you probably want
them both True. them both True. If split_lines is False then these are not relevant.
So, your calling code should not have to make any adjustments -- just call So, your calling code should not have to make any adjustments -- just call
this function however is appropriate for your data sink and enjoy. this function however is appropriate for your data sink and enjoy.
@ -129,24 +129,35 @@ def input(
if arg_lower in INPUT_STRINGS: if arg_lower in INPUT_STRINGS:
lines = multi_line_input(prompt=input_prompt) lines = multi_line_input(prompt=input_prompt)
if not split_lines:
text = '\n'.join(lines)
elif arg_lower in CLIPBOARD_STRINGS: elif arg_lower in CLIPBOARD_STRINGS:
import pyperclip import pyperclip
lines = pyperclip.paste().splitlines() text = pyperclip.paste()
if split_lines:
lines = text.splitlines()
elif read_files and os.path.isfile(arg): elif read_files and os.path.isfile(arg):
lines = open(arg, 'r', encoding='utf-8') with open(arg, 'r', encoding='utf-8') as handle:
lines = (line.rstrip('\r\n') for line in lines) text = handle.read()
if split_lines:
lines = text.splitlines()
else: else:
lines = arg.splitlines() text = arg
if split_lines:
lines = text.splitlines()
for line in lines: if not split_lines:
if strip: return text
line = line.strip()
if skip_blank and not line: if strip:
continue lines = (line.strip() for line in lines)
yield line if skip_blank:
lines = (line for line in lines if line)
return lines
def input_many(args, *input_args, **input_kwargs): def input_many(args, *input_args, **input_kwargs):
''' '''