How clear the printed content in terminal and print to the same line?

I can print(1) to print to the terminal. But I want clear the 1 that I just printed and on the same line in the terminal print(2). Is that possible?

3 Likes

Printing '\r' character will virtually clear the current line in most terminals.

6 Likes

You can try using ANSI codes (to my understanding, an ancient standard of terminal manipulation), here is a code of a function that overwrites the last line and prints something new

#source: https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences
# a more complete description of the codes used.

function overprint(str)  
    print("\u1b[1F")
    #Moves cursor to beginning of the line n (default 1) lines up   
    print(str)   #prints the new line
   print("\u1b[0K") 
   # clears  part of the line.
   #If n is 0 (or missing), clear from cursor to the end of the line. 
   #If n is 1, clear from cursor to beginning of the line. 
   #If n is 2, clear entire line. 
   #Cursor position does not change. 

    println() #prints a new line, i really don't like this arcane codes
end

#testing
println(1)
println(2)
println(3)
println(4)
println(5)
println("this is the number six")
overprint(7)
println(8)

Output:

1
2
3
4
5
7
8
5 Likes

The standard library REPL has some terminal support standardized, eg see REPL.Terminals.clear_line.

5 Likes

How you actually use it? ?REPL.Terminals.clear_line wasn’t very helpful

2 Likes

Per https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences:

print("ayy")
print("\e[2K") # clear whole line
print("\e[1G") # move cursor to column 1
print("lmao")

You should now see just “lmao” on the current (or maybe previous, if in the REPL) line. Personally, I find using escape codes manually much easier and more predictable than trying to re-using functionality that wasn’t designed for the use-case that I have in mind.

2 Likes

I’d like to take offense to this statement as a terminal lover, but I can understand that these sequences appear cryptic. Note, however, that ANSI escape codes are used in a variety of modern terminal-first programs to great effect, and so the term “archaic” is maybe not accurate. “ancient” is actually accurate, but doesn’t really matter anyway.

EDIT:

This is also incorrect, based on what the OP requested:

So escape code F would not be what you want to use, since that assumes you’re already on the next line. Instead, G is best used here, as a print() will not necessarily advance the terminal by a newline.

1 Like

I just want to point out that “ancient” and “archaic” don’t really mean the same thing.

3 Likes

Yes, the package cannot be accused of being overdocumented :wink: I would try something like

import REPL.Terminals
terminal = Terminals.TTYTerminal("", stdin, stdout, stderr)

function f(terminal)
    print("this message will self-destruct in 5 seconds")
    sleep(5)
    REPL.Terminals.clear_line(terminal)
    print("bang")
end

f(terminal)

but I am not an expert on this.

6 Likes

It is also possible to use the functions defined in REPL.Terminals, instead of using the escape sequences directly (the functions just print the sequences anyway):

import REPL
terminal = REPL.Terminals.TTYTerminal(string(), stdin, stdout, stderr)
println()  # Dummy line
for i in (1, "two", :III, "||||")
	REPL.Terminals.cmove_left(terminal, length(string(i)))
	REPL.Terminals.cmove_line_up(terminal)
	println(i)
	sleep(0.5)
end
println("Watch the final number dissapear above me")
sleep(0.5)
REPL.Terminals.cmove_line_up(terminal, 2)
REPL.Terminals.clear_line(terminal)
REPL.Terminals.cmove_line_down(terminal, 3)  # If not, next input is above previous output, which looks funny

This was discovered as I was writing up Overwriting previous terminal output with built-in functions.