Skip to content

Commit

Permalink
less: Support pipe input
Browse files Browse the repository at this point in the history
Signed-off-by: iipeace <[email protected]>
  • Loading branch information
iipeace committed Oct 5, 2023
1 parent 5379e6d commit 81d94bb
Showing 1 changed file with 164 additions and 50 deletions.
214 changes: 164 additions & 50 deletions guider/guider.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
__credits__ = "Peace Lee"
__license__ = "GPLv2"
__version__ = "3.9.8"
__revision__ = "231004"
__revision__ = "231005"
__maintainer__ = "Peace Lee"
__email__ = "[email protected]"
__repository__ = "https://github.com/iipeace/guider"
Expand Down Expand Up @@ -28094,6 +28094,12 @@ def splitFile(

@staticmethod
def doLess(inputArg=None):
pipeInput = None
stdin = sys.stdin
wbuf = []
cursor = 0
lastWord = ""

# check input #
if inputArg:
if type(inputArg) is not list:
Expand All @@ -28104,46 +28110,75 @@ def doLess(inputArg=None):
inputArg = str(SysMgr.inputParam).split(",")
inputArg = UtilMgr.cleanItem(inputArg, True)
else:
SysMgr.printErr("no input for PATH")
return -1
# check stdin pipe #
SysMgr.setBlock(sys.stdin, False)
if not sys.stdin.readline():
SysMgr.printErr("no input for PATH")
return -1

# convert input files #
inputArg = UtilMgr.getFileList(inputArg, sort=True, exceptDir=True)
if not inputArg:
SysMgr.printErr("no target file")
return -1
# set file descriptors #
pipeInput = sys.stdin
freeFd = SysMgr.getFreeFd()
os.dup2(1, freeFd)
stdin = os.fdopen(freeFd, "r")

wbuf = []
cursor = 0
def _printPage(wbuf, cursor):
SysMgr.clearScreen()
SysMgr.printPipe(
wbuf[cursor : cursor + SysMgr.ttyRows - 2], pager=False
)

# print files #
for path in inputArg:
fsize = UtilMgr.getFileSizeStr(path)
SysMgr.printStat(r"start reading '%s%s'..." % (path, fsize))
def _readPipe(wbuf, pipeInput):
while 1:
l = pipeInput.readline()
if not l:
break
wbuf.append(l)

try:
lines = SysMgr.readFile(path).split("\n")
wbuf += [
twoLine,
"%s%s <%s lines>" % (
path, fsize, UtilMgr.convNum(len(lines))
),
twoLine,
]
wbuf += lines
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr("failed to less '%s%s'" % (path, fsize), True)
continue
if pipeInput:
# read data from stdin pipe #
_readPipe(wbuf, pipeInput)

# clear screen and print a page #
SysMgr.clearScreen()
SysMgr.printPipe(
wbuf[cursor : cursor + SysMgr.ttyRows - 1], pager=False
)
_printPage(wbuf, cursor)
else:
# convert input files #
inputArg = UtilMgr.getFileList(inputArg, sort=True, exceptDir=True)
if not inputArg:
SysMgr.printErr("no target file")
return -1

# print files #
for path in inputArg:
fsize = UtilMgr.getFileSizeStr(path)
SysMgr.printStat(r"start reading '%s%s'..." % (path, fsize))

try:
lines = SysMgr.readFile(path).split("\n")
wbuf += [
twoLine,
"%s%s <%s lines>"
% (path, fsize, UtilMgr.convNum(len(lines))),
twoLine,
]
wbuf += lines
except SystemExit:
sys.exit(0)
except:
SysMgr.printErr(
"failed to less '%s%s'" % (path, fsize), True
)
continue

# clear screen and print a page #
_printPage(wbuf, cursor)

def _handleInput(key, cursor, wbuf, lastWord):
if key:
k = key[0]
else:
k = ""

def _handleInput(k, cursor, wbuf):
if k == "q":
sys.exit(0)
elif k == "f":
Expand All @@ -28153,39 +28188,77 @@ def _handleInput(k, cursor, wbuf):
elif k == "g":
cursor = 0
elif k == "G":
cursor = len(wbuf) - 1
elif k == "\x1b[D":
cursor = len(wbuf)
elif k in ("\x1b[D", "j"):
cursor -= 1
elif k in ("\x1b[C", ""):
elif k in ("\x1b[C", "", "k"):
cursor += 1
elif k.isdigit():
cursor = long(k)
elif k == "p":
sys.stdout.write(
"< last line: %s >" % UtilMgr.convNum(len(wbuf))
)
sys.stdout.flush()
stdin.readline()
elif k == "/" or (lastWord and k in ("n", "N")):
# update word #
idx = -1
if k == "/":
lastWord = key[1:]

# set indexes #
if k == "N":
src = cursor - 1
des = 0
inc = -1
else:
src = cursor + 2
des = len(wbuf)
inc = 1

# find word #
for i in xrange(src, des, inc):
if lastWord in wbuf[i]:
cursor = idx = i - 1
break

# print error #
if idx == -1:
sys.stdout.write("< not found: %s >" % lastWord)
sys.stdout.flush()
stdin.readline()

return cursor, lastWord
elif key.isdigit():
cursor = long(key)

# update cursor #
if cursor < 0:
cursor = 0
elif cursor >= len(wbuf) - SysMgr.ttyRows:
cursor = max(len(wbuf) - SysMgr.ttyRows, 0)
elif cursor > len(wbuf) - SysMgr.ttyRows + 1:
cursor = max(len(wbuf) - SysMgr.ttyRows, 0) + 2

return cursor
return cursor, lastWord

# handle input #
while 1:
try:
sys.stdout.write(": ")
sys.stdout.flush()

# read input #
k = sys.stdin.readline()
# read input from stdin #
k = stdin.readline()

# read data from stdin pipe #
if pipeInput:
_readPipe(wbuf, pipeInput)

# handle key #
cursor = _handleInput(k.strip(), cursor, wbuf)
cursor, lastWord = _handleInput(
k.strip(), cursor, wbuf, lastWord
)

# clear screen and print a page #
SysMgr.clearScreen()
SysMgr.printPipe(
wbuf[cursor : cursor + SysMgr.ttyRows - 1], pager=False
)
_printPage(wbuf, cursor)
except SystemExit:
sys.exit(0)
except:
Expand Down Expand Up @@ -28269,6 +28342,23 @@ def readProcStat(fd, name, obj, attr, err=False, retry=True):
SysMgr.printOpenWarn(bufPath)
return buf

@staticmethod
def getFreeFd(pid="self"):
try:
return (
long(
sorted(
os.listdir("%s/self/fd" % SysMgr.procPath),
key=lambda x: long(x),
)[-1]
)
+ 1
)
except SystemExit:
sys.exit(0)
except:
return -1

@staticmethod
def getNrFd(pid):
# get the number of fds #
Expand Down Expand Up @@ -36776,6 +36866,19 @@ def _getDesc(s, t=0):
-o <DIR|FILE> set output path
-m <ROWS:COLS:SYSTEM> set terminal size
-v verbose

Keys:
f Move to Next Page
b Move to Prev Page
g Move to First Page
G Move to Last Page
k Move to Next Line
j Move to Prev Line
/ Search Line
n Search Next Line
N Search Prev Line
p Print Last Line
q Quit
"""

helpStr += """
Expand Down Expand Up @@ -46992,7 +47095,17 @@ def printPipe(line="", newline=True, flush=False, pager=True, trim=True):
elif not SysMgr.isTopMode() or SysMgr.isHelpMode():
try:
if SysMgr.isLinux or SysMgr.isDarwin:
if UtilMgr.which("less"):
# internal less #
if SysMgr.isLinux and "LESS" in SysMgr.environList:
# run less as pager #
ecmd = os.path.join(
SysMgr.getExeName(SysMgr.pid), SysMgr.getPyPath()
)
ecmd += " less"
SysMgr.pipeForPager = os.popen(ecmd, "w")
SysMgr.setPipeSize(SysMgr.pipeForPager)
# external less #
elif UtilMgr.which("less"):
# defopt = '-FRSXMQi'
defopt = "-FRXMQi"

Expand All @@ -47013,6 +47126,7 @@ def printPipe(line="", newline=True, flush=False, pager=True, trim=True):

# set signals to prevent abnormal terminal status #
SysMgr.setDefaultSignal()
# outernal more #
elif UtilMgr.which("more"):
# run more as pager #
SysMgr.pipeForPager = os.popen("more", "w")
Expand Down

0 comments on commit 81d94bb

Please sign in to comment.