consider the command
A | B | C | D
when you process it in up, split the command at the | and process each one separately. that is first run
A;
save the output into a buffer (BA)
then pipe BA into B, save that into BB, and so on, until you have 4 buffers containing the outputs of A; A|B; A|B|C; and A|B|C|D;
now when the user edits, you can see which section is changed. say the user changes the command C into C1, so the pipeline becomes: A|B|C1|D
at this point you can pipe buffer BB (which has the output from A|B) into C1; write that into a new buffer BC1; and pipe that into D;
the old buffers C and D can be removed at this point, or you can keep them around in case the user undoes their change and goes back to an old version.
greetings, eMBee.