Doit:
PROC [root: Tioga.Node, tSel: TEditInputOps.Selection] ~ {
start: Tioga.Location ~ [tSel.start.pos.node, IF tSel.start.pos.where=Tioga.NodeItself THEN 0 ELSE MIN[tSel.start.pos.where, TextNode.EndPos[tSel.start.pos.node]]];
end: Tioga.Location ~ [tSel.end.pos.node, IF tSel.end.pos.where=Tioga.NodeItself THEN TextNode.EndPos[tSel.end.pos.node] ELSE MIN[tSel.end.pos.where, TextNode.EndPos[tSel.end.pos.node]]];
len: INT ~ TextNode.LocOffset[start, end, 1, TRUE] + GrainFudge[tSel.granularity];
orgR: ROPE ~ TiogaRopes.RopeFromTioga[node: start.node, start: start.where, length: len, skipCommentNode: FALSE];
orgFN: ROPE ~ NewName["old"];
newFN: ROPE ~ NewName["new"];
outFN: ROPE ~ NewName["out"];
errFN: ROPE ~ NewName["err"];
fullCmd: ROPE ~ Replace[filterCmd, orgFN, newFN];
SetContents[orgFN, orgR !
UXIO.Error => {
Feedback.PutFL[router, oneLiner, $Error, "UXIO.Error[%g, %g] writing old contents", LIST[ [atom[error.code]], [rope[error.explanation]] ]];
GOTO GiveUp};
IO.Error => {
Feedback.PutFL[router, oneLiner, $Error, "IO.Error[%g, %g (%g)] writing old contents", LIST[ [atom[IO.AtomFromErrorCode[ec]]], [rope[msg]], [refAny[details]] ]];
GOTO GiveUp};
];
{ENABLE UNWIND => Delete[orgFN];
Delete[newFN];
{res:
INT ~ UnixSysCallExtensions.Spawn[
cmd: UXStrings.Create[fullCmd],
stdin: UXStrings.Create["/dev/null"],
stdout: UXStrings.Create[outFN],
stderr: UXStrings.Create[errFN] ];
errno: UnixErrno.Errno ~ UnixErrno.GetErrno[];
{ENABLE UNWIND => {Delete[outFN]; Delete[errFN]};
errR: ROPE;
IF res#0
THEN {
Feedback.PutFL[router, oneLiner, $Error, "UnixFilter op (%g) failed, res=%g, errno=%g.", LIST[ [rope[fullCmd]], [integer[res]], [integer[errno.ORD]] ]];
}
ELSE {
errR: ROPE ~ GetContents[errFN];
outR: ROPE ~ GetContents[outFN];
newR: ROPE ~ GetContents[newFN];
p1, p2: Tioga.Location;
looks: TextLooks.Looks;
IF newR=
NIL
THEN {
Feedback.Append[router, oneLiner, $Error, "no results written"];
GOTO GiveUp};
TEditInputOps.Delete[saveForPaste: FALSE];
p1 ¬ p2 ¬ TEditSelection.InsertionPoint[TEditSelection.pSel];
looks ¬ tSel.looks;
TEditSelection.Deselect[primary];
p2.where ¬ p1.where + TextEdit.ReplaceByRope[root: root,
dest: p1.node, start: p1.where, len: 0,
rope: newR, looks: looks, charSet: 0, charProps: NIL,
event: TEditInput.currentEvent].resultLen;
IF p2.where#p1.where
THEN {
tSel.start.pos ¬ p1;
tSel.end.pos ¬ [p2.node, p2.where-1];
tSel.granularity ¬ char;
tSel.pendingDelete ¬ FALSE;
TEditSelection.MakeSelection[tSel, primary];
Feedback.Append[router, oneLiner, $FYI, "Done"];
}
ELSE Feedback.Append[router, oneLiner, $FYI, "Empty result"];
IF outR.Length[]>0 THEN routerStream.PutF1["output: \"%q\"", [rope[outR]] ];
IF errR.Length[]>0 THEN routerStream.PutF1["error: \"%q\"", [rope[errR]] ];
};
}}}--enables--;
Delete[orgFN];
Delete[newFN];
Delete[outFN];
Delete[errFN];
RETURN;
EXITS GiveUp => quit ¬ TRUE;
};