3

Is there a way to modify text already in the terminal but unlike a simple progress bar clearing with \r, by modifying text completely

E.g.

user@machine$ grep -R 'mystuff' .
result1
result2
result3
user@machine$ 

using arrows to e.g. to move a 'virtual' cursor (|)

user@machine$ grep -R 'mystuff' .
|result1
result2
result3
user@machine$ 

and most importantly, without clearing the terminal?

And no, it's not a duplicate of Modifying text in the terminal because it asks for a different kind of text manipulation while the description of the other question specifically asks for a progress bar example.

Dean
  • 6,610
  • 6
  • 40
  • 90
  • In Windows you can read console text by using `GetConsoleScreenBufferInfo` and `ReadConsoleOutputCharacter`, and then `SetConsoleCursorPosition` to position the cursor before output. But the question is about Linux. – Weather Vane Mar 25 '19 at 19:39
  • 1
    This is unrelated to C – machine_1 Mar 25 '19 at 19:47
  • 1
    It obviously is, this is how text editors like nano let you move a cursor up and down to edit. For an example of a tool that does it in shell output, see GNU screen's copy mode. It requires you to know exactly what's on the screen where. You can then [update it by line/column coordinates](https://stackoverflow.com/questions/14259311/set-or-change-vertical-position-of-the-cursor) using escape codes. It's not an easy feat. – that other guy Mar 25 '19 at 19:50
  • No, it is not possible to insert anything afaik. There are codes for clearing part or the whole line and then you can *rewrite* the contents of that line. – Antti Haapala -- Слава Україні Mar 25 '19 at 19:52
  • Possible duplicate of [How to update a printed message in terminal without reprinting](https://stackoverflow.com/q/1337529/608639), [Modifying text in the terminal](https://stackoverflow.com/q/6958972/608639), [How to replace already-printed text in the command prompt?](https://stackoverflow.com/q/7221961/608639), [Updating text displayed on the terminal](https://stackoverflow.com/q/23205280/608639), etc. – jww Mar 26 '19 at 02:29
  • This reminds me of this problem and it's brilliant answer https://stackoverflow.com/a/14259374/112637 (it uses `tput`) – Ar3s Mar 13 '23 at 10:23

1 Answers1

6

You can use escape sequences to perform various actions on the linux terminal. You can learn about this from the following references:

Controlling the terminal directly with escape sequences is very tricky because you must deal with all sorts of border cases and side effects, depending on the actual contents of the terminal and the type of text you display on it (ASCII, UTF-8 or other exotic variants...)

Your use case makes it even more difficult as you must first determine the contents of the terminal produced by unrelated commands such as grep, but also depending on the terminal specific width and height, the shell prompt, etc.

As the co-author and maintainer of qemacs, I can tell you how much of complete nightmare it has been to make the process buffer behave correctly, handling shell and programs output as well as user input in a transparent manner while at the same time making all this contents freely editable in the editor's buffers and windows. You can look at the source files tty.c and shell.c if you are not faint of heart.

Therefore I urge you to reconsider your problem from a different angle:

  • What are you trying to achieve?
  • Can you do it by filtering the output of commands?
  • Can you do it by creating shell aliasses or shell scripts that will post process the commands' output?
  • Can you use emacs, qemacs or some other shell enabled IDE to achieve the desired functionality?
chqrlie
  • 131,814
  • 10
  • 121
  • 189