Reputation: 14374
I like to do use this in my scripts:
cat("Saving...")
do_something_slow()
cat("\rSaved\n")
The problem is that the carriage return is applied without erasing the rest of the line, so I get this:
Savedg...
To fix it I can do:
cat("\rSaved\033[K\n")
but it's kind of ugly. Is there a simpler way?
Upvotes: 2
Views: 791
Reputation: 3623
I like to use message()
instead of cat()
for generating messages. For example:
cat("Saving..."); cat("\rSaved\n")
returns:
Savdg...
While:
message("Saving..."); message("\rSaved\n")
returns:
Saving...
Saved
Edit:
Inspired by @gauden answer, another function could be:
replaceMessage <- function(x, width = 80)
{
message("\r", rep(" ", times = width - length(x)), "\r", appendLF = F)
message(x, appendLF = F)
}
And then:
replaceMessage("Saving..."); Sys.sleep(1); replaceMessage("Saved\n")
Note:
While replaceMessage()
behaves as expected in Linux and Rterm on Windows, it behaves strangely in my Rgui (2.15.0, Windows x64). Specifically, Saving...
is never displayed, and after Saved
is displayed, the cursor is moved width
spaces (in the example, 80 spaces) to the right. I am not sure why.
Upvotes: 5
Reputation: 10923
Assuming you want the messages to all appear serially on one line, how about something whimsical?
cleancat <- function(astring, width=80) {
# Reserves a line of 80 (default) characters
# and uses it for serial updates
require("stringr")
astring <- paste("\r", astring, sep="")
cat(str_pad(astring, 80, "right"))
# pretend to do something slow
# delete this line if cleancat is used in production
Sys.sleep(0.5)
}
# imitate printing a series of updates
test <- lapply(c("Saving -",
"Saving \\",
"Saving |",
"Saving /",
"Saving -",
"Saving \\",
"Saving |",
"Saving /",
"Saved"), cleancat)
Of course, you would need to load the stringr
package and set up the cleancat
function in your environment which you might think is even uglier...
Upvotes: 6