10
babi/file.py
10
babi/file.py
@@ -226,11 +226,17 @@ class File:
|
||||
self.selection = Selection()
|
||||
self._file_hls: Tuple[FileHL, ...] = ()
|
||||
|
||||
def ensure_loaded(self, status: Status) -> None:
|
||||
def ensure_loaded(self, status: Status, stdin: str) -> None:
|
||||
if self.lines:
|
||||
return
|
||||
|
||||
if self.filename is not None and os.path.isfile(self.filename):
|
||||
if self.filename == '-':
|
||||
status.update('(from stdin)')
|
||||
self.filename = None
|
||||
self.modified = True
|
||||
sio = io.StringIO(stdin)
|
||||
self.lines, self.nl, mixed, self.sha256 = get_lines(sio)
|
||||
elif self.filename is not None and os.path.isfile(self.filename):
|
||||
with open(self.filename, newline='') as f:
|
||||
self.lines, self.nl, mixed, self.sha256 = get_lines(f)
|
||||
else:
|
||||
|
||||
26
babi/main.py
26
babi/main.py
@@ -1,5 +1,7 @@
|
||||
import argparse
|
||||
import curses
|
||||
import os
|
||||
import sys
|
||||
from typing import Optional
|
||||
from typing import Sequence
|
||||
|
||||
@@ -9,9 +11,11 @@ from babi.screen import EditResult
|
||||
from babi.screen import make_stdscr
|
||||
from babi.screen import Screen
|
||||
|
||||
CONSOLE = 'CONIN$' if sys.platform == 'win32' else '/dev/tty'
|
||||
|
||||
def _edit(screen: Screen) -> EditResult:
|
||||
screen.file.ensure_loaded(screen.status)
|
||||
|
||||
def _edit(screen: Screen, stdin: str) -> EditResult:
|
||||
screen.file.ensure_loaded(screen.status, stdin)
|
||||
|
||||
while True:
|
||||
screen.status.tick(screen.margin)
|
||||
@@ -32,13 +36,17 @@ def _edit(screen: Screen) -> EditResult:
|
||||
screen.status.update(f'unknown key: {key}')
|
||||
|
||||
|
||||
def c_main(stdscr: 'curses._CursesWindow', args: argparse.Namespace) -> int:
|
||||
def c_main(
|
||||
stdscr: 'curses._CursesWindow',
|
||||
args: argparse.Namespace,
|
||||
stdin: str,
|
||||
) -> int:
|
||||
with perf_log(args.perf_log) as perf:
|
||||
screen = Screen(stdscr, args.filenames or [None], perf)
|
||||
with screen.history.save():
|
||||
while screen.files:
|
||||
screen.i = screen.i % len(screen.files)
|
||||
res = _edit(screen)
|
||||
res = _edit(screen, stdin)
|
||||
if res == EditResult.EXIT:
|
||||
del screen.files[screen.i]
|
||||
screen.status.clear()
|
||||
@@ -59,8 +67,16 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
|
||||
parser.add_argument('--perf-log')
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if '-' in args.filenames:
|
||||
print('reading stdin...', file=sys.stderr)
|
||||
stdin = sys.stdin.read()
|
||||
tty = os.open(CONSOLE, os.O_RDONLY)
|
||||
os.dup2(tty, sys.stdin.fileno())
|
||||
else:
|
||||
stdin = ''
|
||||
|
||||
with make_stdscr() as stdscr:
|
||||
return c_main(stdscr, args)
|
||||
return c_main(stdscr, args, stdin)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
22
tests/features/stdin_test.py
Normal file
22
tests/features/stdin_test.py
Normal file
@@ -0,0 +1,22 @@
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
from babi.screen import VERSION_STR
|
||||
from testing.runner import PrintsErrorRunner
|
||||
|
||||
|
||||
def test_open_from_stdin():
|
||||
with PrintsErrorRunner('env', 'TERM=screen', 'bash', '--norc') as h:
|
||||
cmd = (sys.executable, '-mcoverage', 'run', '-m', 'babi', '-')
|
||||
babi_cmd = ' '.join(shlex.quote(part) for part in cmd)
|
||||
h.press_and_enter(fr"echo $'hello\nworld' | {babi_cmd}")
|
||||
|
||||
h.await_text(VERSION_STR, timeout=2)
|
||||
h.await_text('<<new file>> *')
|
||||
h.await_text('hello\nworld')
|
||||
|
||||
h.press('^X')
|
||||
h.press('n')
|
||||
h.await_text_missing('<<new file>>')
|
||||
h.press_and_enter('exit')
|
||||
h.await_exit()
|
||||
Reference in New Issue
Block a user