How to get the current text cursor position from Python in a Windows Terminal?
The problem was to locate the various Structure definitions. After having experimented significantly, I've got the following working solution.
#!/usr/bin/env python -u
# -*- coding: UTF-8 -*-
#------------------------------------------------------------------------------
from ctypes import windll, wintypes, Structure, c_short, c_ushort, byref, c_ulong
from readline import console
#------------------------------------------------
# Win32 API
#------------------------------------------------
SHORT = c_short
WORD = c_ushort
DWORD = c_ulong
STD_OUTPUT_HANDLE = DWORD(-11) # $CONOUT
# These are already defined, so no need to redefine.
COORD = wintypes._COORD
SMALL_RECT = wintypes.SMALL_RECT
CONSOLE_SCREEN_BUFFER_INFO = console.CONSOLE_SCREEN_BUFFER_INFO
#------------------------------------------------
# Main
#------------------------------------------------
wk32 = windll.kernel32
hSo = wk32.GetStdHandle(STD_OUTPUT_HANDLE)
GetCSBI = wk32.GetConsoleScreenBufferInfo
def cpos():
csbi = CONSOLE_SCREEN_BUFFER_INFO()
GetCSBI(hSo, byref(csbi))
xy = csbi.dwCursorPosition
return '({},{})'.format(xy.X,xy.Y)
cls='\x1b[H'
print('\n'*61)
print(cls+'12345', end='', flush=True); print(' {}'.format(cpos()), flush=True)
# 12345 (5,503)
Is there a way to get the mouse position within the terminal?
I have solved my problem.
To get events, the bash escape load ESC[?100Xh
, replacing X with a number. The events will then be logged to the console.
How can I get the cursor's position in an ANSI terminal?
You can simply read sys.stdin
yourself to get the value.
I found the answer in a question just like yours, but for one trying to do that from a C program:
http://www.linuxquestions.org/questions/programming-9/get-cursor-position-in-c-947833/
So, when I tried something along that from the Python interactive terminal:
>>> import sys
>>> sys.stdout.write("\x1b[6n");a=sys.stdin.read(10)
]^[[46;1R
>>>
>>> a
'\x1b[46;1R'
>>> sys.stdin.isatty()
True
You will have to use other ANSI tricks/position/reprint to avoid the output actually showing up on the terminal, and prevent blocking on stdin read - but I think it can be done with some trial and error.
get terminal cursor position
Have you tried getyx()
?
Or, if you prefer legacy curses functions, getcurx() and getcury()?
Determine the terminal cursor position with an ANSI sequence in Python 3
Here is a POC snippet, how to read the current cursor position via an ansi/vt100 controll sequence.
curpos.py
import os, re, sys, termios, tty
def getpos():
buf = ""
stdin = sys.stdin.fileno()
tattr = termios.tcgetattr(stdin)
try:
tty.setcbreak(stdin, termios.TCSANOW)
sys.stdout.write("\x1b[6n")
sys.stdout.flush()
while True:
buf += sys.stdin.read(1)
if buf[-1] == "R":
break
finally:
termios.tcsetattr(stdin, termios.TCSANOW, tattr)
# reading the actual values, but what if a keystroke appears while reading
# from stdin? As dirty work around, getpos() returns if this fails: None
try:
matches = re.match(r"^\x1b\[(\d*);(\d*)R", buf)
groups = matches.groups()
except AttributeError:
return None
return (int(groups[0]), int(groups[1]))
if __name__ == "__main__":
print(getpos())
example output
$ python ./curpos.py
(2, 1)
warning
This is not perfect. To make it more robust, a routine which sorts out keystrokes from the user while reading from stdin would be nice.
Related Topics
Difference Between Shell and Environment Variables
Anything Like Dos2Unix for Windows
Recursive Search and Replace in Text Files on MAC and Linux
Run Script with Rc.Local: Script Works, But Not at Boot
Bash: Silently Kill Background Function Process
How to Pass Argument with Exclamation Mark on Linux
How to Set Cron to Display Gui Application
In Bash, How to Add a String After Each Line in a File
Installing Git with Non-Root User Account
How to Prepend a String to the Beginning of Each Line in a File
Does Linux Schedule a Process or a Thread
Using "$Random" to Generate a Random String in Bash
How to Use Xargs to Copy Files That Have Spaces and Quotes in Their Names
Switching Users Inside Docker Image to a Non-Root User
Why Exit Code 141 with Grep -Q
Syntax Error Near Unexpected Token 'Then'