4.2.39 Escape sequence
A string of bit combinations that is used for control purposes in code extension procedures. The first of these bit combinations represents the control function ESCAPE.
— ECMA-48 Control Functions for Coded Character Sets
The situation
You are working on some script that outputs on the terminal. Also, wget, apt-get and similar software comes to your mind. They have fancy output! now you want it too.
Google a little and finish on stack overflow where someone has a magic sequence…
A Python Magic sequence of text
For Python, one of the magic sequences is:
sys.stdout.write("\r\x1b[K"+your_updated_string)
How this works?
Okay. If you just want a class to represent a rotating stick skip this part, and go to the end.
In this section, I explain what is everything on that magic sequence. First from sequence-explanation, then the other way around.
>>Sequence explanation
\r
Escape sequence for a Carriage Return (Go to the beginning of the line).
\x1b[
Code for CSI (Control Sequence Introducer, nothing to do with the TV-series. check Wikipedia). It is formed by the hexadecimal escape value 1b (\x1b) followed by [.
K
is the Escape sequence code to Erase the line.
>>From the beginning
I need a escape sequence to erase the line and rewrite something. In my case I want to rewrite the line with the next step on the spinner sequence.
Checking ECMA-048, the function ERASE IN LINE (section 8.3.41) seems suitable. According to the document, this control function is represented by:
CSI (Ps) 04/11
CSI
is the control sequence: \x1b[
. (Escape [)
(Ps)
stands for Single selective Parameter (Parameter single). And in this function it has a default value of 0.
0 – the active presentation position and the character positions up to the end of the line are put into the erased state
— ECMA-48 Control Functions for Coded Character Sets
The other possible Ps values deal with deleting the whole line. In this case, given that the cursor has to return at the start of the line to output the next animation step, I will just send the cursor to the beginning and then erase the line.
04/11
represents the hexadecimal value of K (0x4B). 04 is the column number and 11 the row number of the K character on an 8 bit code table. Check page 12 of ECMA-043, there’s something like:
It is all set. The terminal has to recieve:
- Return to start of the line (Carriage Return)
- Delete from position to the end of the line
- Set new step on the animation
"\r\x1b[k"+newstepchar
Ta-Dah!
Rotating Stick Class
The code and some comment is on a Git Gist here. 🙂
import sys import threading import time class cSpinner(threading.Thread): """ Print things to one line dynamically """ chars = ["\\","|","/","-"] index = 0 keeprunning = True def run(self): while self.keeprunning: self.printing(self.chars[self.index%len(self.chars)]) time.sleep(0.1) self.index +=1 def printing(self,data): sys.stdout.write("\r\x1b[K"+data.__str__()) sys.stdout.flush() def stop(self): self.keeprunning = False
Just create an instance of cSpinner and call start to make it run.
Maybe you want a cooler spinner, check this stack overflow thread.
Pingback: DBPedia World | Castells