I built a OS X command line tool in Swift (same problem in Objective-C) for downloading certain files. I am trying to update the command line with download progress. Unfortunately, I cannot prevent the print statement to jump to the next line.
According to my research, the carriage return \r
should jump to the beginning of the same line (while \n
would insert a new line).
All tests have been performed in the OS X Terminal app, not the Xcode console.
let logString = String(format: "%2i%% %.2fM \r", percentage, megaBytes)
print(logString)
Still, the display inserts a new line. How to prevent this?
Note: This won't work in Xcode's debugger window because it's not a real terminal emulator and doesn't fully support escape sequences. So, to test things, you have to compile it and then manually run it in a Terminal window.
\r
should work to move to the beginning of the current line in most terminals, but you should also take a look at VT100 Terminal Control Escape Sequences. They work by sending an escape character, \u{1B}
in Swift, and then a command. (Warning: they make some pretty ugly string definitions)
One that you'll probably need is \u{1B}[K
which clears the line from the current cursor position to the end. If you don't do this and your progress output varies in length at all, you'll get artifacts left over from previous print statements.
Some other useful ones are:
\u{1B}[\(y);\(x)H
Note: x
and y
are Int
s inserted with string interpolation.
\u{1B}7
\u{1B}8
\u{1B}[2J
You can also do interesting things like set text foreground and background colors.
If for some reason you can't get \r
to work, you could work around it by saving the cursor state/position just before you print your logString
and then restoring it after:
let logString = String(format: "\u{1B}7%2i%% %.2fM \u{1B}8", percentage, megaBytes)
print(logString)
Or by moving to a pre-defined (x, y) position, before printing it:
let x = 0
let y = 1 // Rows typically start at 1 not 0, but it depends on the terminal and shell
let logString = String(format: "\u{1B}[\(y);\(x)H%2i%% %.2fM ", percentage, megaBytes)
print(logString)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With