Changing user input in real time using the cmd module - python

I would like to be able to change characters as the user types text into a (cmd.Cmd) prompt using the cmd python module. So when a user types in a character I would like to be able to process that character and change it in line. Is there a way to use the cmd module to process and replace every character as it is typed or is there another module that I should be using?
edit: This is for running in a Windows environment.

It seems that you are searching to hook keyboard strokes on windows using python. if i am not mistaken in my assumption, hooking is not trivial on python since dll is required.
you may try pyHook, it uses Windows API to do the job.
Here is the API.

I don't see any way to do this with cmd.Cmd either but it would be possible with curses - see Curses Programming with Python. The getch() function will return the keycode but not echo it unless curses has been told to echo() it. That would let you take the keycode and transform it however you liked (e.g. into an 'X' to hide the characters entered as a password) before displaying the character(s) on the screen.
Alternatively, though I haven't used it, the Console module seems to provide equivalent functionality for Python on Windows.

Related

ANSI escape codes not working on IDLE... (python)

I am making a program involving ANSI escape codes, and they were all working fine on replit until I switched back to IDLE (3.9 on both). But it doesn't work:
it should have looked like this:
I have seen several posts before that complain that the IDLE doesn't support these escape sequences because it isn't a terminal, so I tried to do it directly from the cmd but the beastly symbol still appeared, this time as a boxed question mark:
I know that it won't work straight from the IDLE, so I wonder if you can import a software like mintty into python?
Powershell works though...
P.S. please don't tell me to import colorama or something! I really want this to be the way. I also don't have immediate access to iPython (even though I would like to) so it's not really an option for me... unless I have to :D
EDIT: the code I put across the python programs:
import sys, os
os.system("")
CSI = f"{chr(0x1B)}["
print(f"""{CSI}3m{CSI}1m{CSI}4m{CSI}31m
look at this""")
sys.stdout.flush()
# I put the sys.stdout.flush() and os.system("") to try and fix the problem...
The IDLE shell is not a terminal emulator and not intended to be production environment. The decision so far is that is should show program developers what their program's output, without interpretation. This may change in the future but no final decision yet.
If you are on Windows, I believe its console can be put into ANSI mode, but Python does not do that for you. I don't know if program code can do so.
As near as I can tell, there is not wrapper program that turns mintty into an importable python module. It would not make much sense. Rather, you would want to open mintty or a mintty-based terminal-emulator, such as git bash, and open python within that terminal instead of CommandPrompt.
ANSI code is a broad term. You have to specify which code page you are using. For example, my Windows is in Chinese Simplified. Therefore if I want to escape from UTF-8 default in Python, I would put # coding : cp936 on the first or second line of a script. Then it can read and write text files with the simplified Chinese coding.
Second Question:
Could I make a red/green/etc. font for every character and put it as print('...', file=...)? It should be possible because colored emojis exist.
It should work, but I would like to know how I could (if it's possible) automate this with some program that makes a file containing those characters and displays them with the previous print statement.
Cheers!

Python IDLE/Terminal return back after error

When reading a book or just coding on terminal/IDLE it's common to make typo, forgot brace or comma etc. After I got error and all what I wrote before is lost.
Then I have to write down code again..
Is there any way/option to return back all what write before and just edit mistake and continue to code?
In Idle (at least my version, Python 2.7.10 on windows), you can simply copy paste your code. In the python interpreter, you can't afaik, however you can use the up/down arrow keys to recall lines you previously "submitted" (i.e. typed and pressed enter).
If I understood correctly, IDLE is a GUI (graphical user interface - a visual representation of a program rather just through text) made to have a bit more features for programming in Python. You can use IDLE interactively, like in Terminal (a.k.a command line), or use it to write your script rather than in a separate text editor. Then once you save your script/program you can do neat things like run it directly from IDLE. There's nothing more special about the Terminal, you just have to do some more work.
Furthermore, all the code you have written on your GUI is on the cache memory which is used in system to store information recently accessed by a processor. So, I suggest you write again your code you can't recover them without saving.
To avoid these kind of problems use Git!
Git is a version control system that is used for software development and other version control tasks.
IDLE's Shell window is statement rather that line oriented. One can edit any line of a statement before submitting it for execution. After executing, one may recall any statement by either a) placing the cursor anywhere on the statement and hitting Enter, or b) using the history-next and history-prev actions. On Windows, these are bound, by default, to Alt-p and Alt-p. To check on your installation, Select Options => IDLE preferences on the menu. In the dialog, select the Keys tab. Under Custom Key Bindings, find the 'histor-xyz' actions in the alphabetical list.
For short, one-off scripts, I have a scratch file called tem.py. Since I use it often, it is usually accessible via File => Recent files.

Dynamic syntax highlighting in Python

I am writing an interpreter in Python where the user has to type Prolog code and I'd like to implement dynamic syntax highlighting. So far my application (which should be cross-platform) is reading input and printing from/to the command prompt (on Windows). I've been looking at the pygments library, but I have no clue on how to modify the current line (being typed) on the command prompt.
So, I've also been looking at the curses library to implement an UI but that would leave Windows users out. Any suggestions? I just need to implement a quick UI to be able to dynamically highlight what is being typed.
It appears that you can't wait for a return. To deal with input one char at a time you need something like getch.

CLI Front End with Python: How to pass string to a running process?

How to send string/data to STDIN of a running process in python?
i'd like to create a front end for a CLI program. eg. i want to pass multiple string to this Pascal application:
program spam;
var a,b,c:string;
begin
while e <> "no" do
begin
writeln('what is your name?');
readln(a);
writeln('what is your quest?');
readln(b);
writeln('what is your favorite color?');
readln(c);
print(a,b,c);
end;
end.
how do i pass string to this program from python (using subprocess module in python). thankyou. sorry for my english.
If you want to control another interactive program, it could be worth trying the Pexpect module to do so. It is designed to look for prompt messages and so on, and interact with the program. Note that it doesn't currently work directly on Windows - it does work under Cygwin.
A possible non-Cygwin Windows variant is WinPexpect, which I found via this question. One of the answers on that question suggests the latest version of WinPexpect is at http://sage.math.washington.edu/home/goreckc/sage/wexpect/, but looking at the modification dates I think the BitBucket (the first link) is actually the latest.
As Windows terminals are somewhat different to Unix ones, I don't think there is a direct cross-platform solution. However, the WinPexpect docs say the only difference in the API between it and pexpect is the name of the spawn function. You could probably do something like the following (untested) code to get it to work in both:
try:
import pexpect
spawn = pexpect.spawn
except ImportError:
import winpexpect
spawn = winpexpect.winspawn
# NB. Errors may occur when you run spawn rather than (or as
# well as) when you import it, so you may have to wrap this
# up in a try...except block and handle them appropriately.
child = spawn('command and args')

Insert keypresses into the Linux console from Python

I have recently been faced with a rather odd task, one result being the necessity for the ability to use DTMF (aka "Touch Tone") tones to control a non-X Linux computer's terminal. The computer has a modem which can be accessed through ALSA, and therefore the sox "rec" program, which is what I am reading the input through. The computer in question is otherwise completely isolated, having no Ethernet or other network interfaces whatsoever. The Goertzel algorithm implementation I am using works very well, as does the eSpeak speech synthesis engine which is the only source of output; this is supposed to work with any Touch Tone phone. It reads back both input (input being octal digits, one ASCII byte at a time)and whatever the dash shell feeds back -- the prompt, the output from commands, etc., using ASCII mnemonics for control characters.
The current method that I am using for interacting with dash and the programs launched through it is the pexpect module. However, I need it to be able to, on demand, read back the entire contents of the line on which the cursor is positioned, and I do not recall pexpect being able to do this (If it is, I cannot tell.). The only other solution that I can think of is to somehow use Python to either control, or act as, the keyboard and console drivers.
Is this, indeed, the only way to go about it (and if so, is it even possible with Python?), or is there another way of having direct access to the contents of the console?
Edit: Through dumb luck, I just recently found that the SVN version of PExpect has pexpect.screen. However, it does not have any way of actually running a program under it. I'll have to keep an eye on its development.
The simple solution is to use the Linux kernel uinput interface. It allows you to insert keypresses and mouse events into the kernel, exactly as if they came from a physical human interface device. This would basically turn your application into a keyboard/mouse.
Since you are working with Python, I recommend you take a look at the python-uinput module.
If you are comfortable with binary I/O in Python, then you can certainly do the same without any libraries; just check out the /usr/include/linux/uinput.h header file for the structures involved (the interface is completely stable), and perhaps some uinput tutorials in C, too.
Note that accessing the /dev/uinput or /dev/input/uinput device (depending on your distribution) normally requires root privileges. I would personally run the Python service as a user and group dedicated to the service, and modify/add a udev rule (check all files under rules.d) to allow read-write access to the uinput device to that group, something like
SUBSYSTEM=="input", ENV{ID_INPUT}=="", IMPORT{builtin}="input_id"
KERNEL=="uinput", MODE="0660", GROUP="the-dedicated-group"
However, if your Python application simply executes programs, you should make it a terminal emulator -- for example, using this. You can do it too without any extra libraries, using the Python pty; the main work is to however simulate a terminal with ANSI escape sequences, so that applications don't get confused, and the existing terminal emulators have such code.
If you want to manipulate the contents of the console, you probably want to use curses. It's well documented here. Look at window.getch() and window.getyx().

Categories

Resources