Python script simulating compose key - python

I would like to make a Python script for Linux that brings up a prompt, allows the user to enter some keystrokes, and then prints a special character into whatever GUI-based program/widget happens to have the focus after my Python script exits (which takes the focus after the prompt goes away). Note that 'whatever program I happen to be using' is not particularly a program I made myself.
Is this possible? If so, how?
I know how to make a prompt, do keybindings and all that. I know how to use both xclip and xsel to copy stuff to the clipboard and I imagine paste, too (though I haven't had the need to paste with them, before). Is there a way to use them or something else to paste into the program that has the focus after my program (as opposed to merely pasting into my program)?
Basically, I'm trying to simulate the compose key with a Python program because the compose key doesn't always work, anymore, on Xubuntu 14.04 for some reason (just sometimes, and temporarily). It worked fine in previous versions all the time. If I had a Python program that could do this, then I wouldn't have to worry about whether the compose key would work on any future Xubuntu versions.

Well, I found the answer before I was done asking.
sudo apt-get install xautomation
xte 'keydown Alt_L' 'key Tab' 'keyup Alt_L' 'keydown Control_L' 'usleep 200000' 'key v' 'keyup Control_L'
You can surmise the rest. I just need to have Python execute the xte command above after I enter the keystrokes.

I wrote something here that might be helpful for this:
https://github.com/gvb1234/simulate-compose-key
it intercepts the Multi_Key if the focus is in a particular app, and does some fancy things with the next few keys, if they form a valid compose sequence.
This could be easily modified to call xdotool (or directly from python) to send the proper utf8 character to the window in focus.

Related

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.

Adobe Brackets and running Ruby/Python programs

so I have been trying out various text editors and IDE's recently to see what I like. I really like the web developer side of Brackets, which is what I think it was designed for, but was also messing around with some of the extensions for building and running Python/Ruby programs.
I have tried this, which honestly doesn't seem to do anything from what I can tell:
https://github.com/vhornets/brackets-builder
And this, which adds a run button to Brackets for running the program:
https://github.com/jadbox/brackets-integrated-development
The latter seems to work alright... until you make a small program that asks for user input then the program never runs, the program disappears, and then you have to restart Brackets to get it back. The code I have used is the following:
puts"Please enter your name: "
n = gets. chomp
Or
n = input("Please enter your name: ")
Any idea what might be causing this? I asked the developer, but haven't heard back. I'd probably use Brackets exclusively if it wasn't for that issue.
Tried Sublime Text 3 for a little while, but didn't like the lack of a Brackets like live preview plugin. However, it looks like it runs Python/Ruby (in addition to Java and C/C++) code without issue.
You might want to try a generic extension for running command line tools, such as one of these:
Command Line Shortcuts
Brackets Build System
Command Runner
Brackets Shell access
Brackets Terminal
The Brackets Builder you mentioned above - looks like you choose Edit > Edit Builder to configure the commands you want, and then you can press Ctrl-Alt-B to run them.
Brackets Builder has worked best for me "right out of the box". However, I run into the same problem as you (when wanting to perform console inputs) in both Brackets AND Sublime, but NOT in SciTE.
A good clean work around inside Brackets, for when you need to test programs with console inputs, is to load the extension "Open project in terminal", which will allow you to open a terminal right from your current project folder and run your python script. This allowed me to run your case from Brackets with very little hassle, and of course, it works great in a real terminal.
To make this approach even easier, I've asked the developers on GitHub, thru a raised issue, if they can add support for more terminal programs in Windows, such as ConEmu, and if they could allow intial command line arguments to be loaded, which would make this type of work that you want to do even more seamless and fast. I'll update my post once I see any improvements or alternatives to all the above points.

Python: Executing selected statements

I am new to python programming... Just wanted to know does IDLE has a concept of 'executing selected statements'??
F5 runs the whole program... Is there any way to do this?
No, not now. Since you are at least the second person to ask this, I added the idea to my personal list of possible enhancements. However, while running a selection would not be a problem, producing accurate tracebacks for exception would be. Doing so is an essential part of Python's operation.
Currently, one can disable code that you need to not run by commenting it out (Alt-F3) or by making it a string. One can stop execution after a particular statement by adding 1/0. Or you can copy code to a new editor window.
Do you have a specific use case in mind, or are you just wondering?
Install Spyder, with its dependecies, and you will have wonderful FREE IDE !
You will have another solution, is to use IPython Notebook, where you will be able to use your Internet Browser to run python codes!:

Linux: write to stdin of python interpreter process and have that process evaluate input as code

I am running gnu linux (Linux Mint to be specific). The following is my desired workflow:
I open vim in (say) process 1000 and then start up a python interpreter in process 1001.
I write some code in vim and then select certain lines and then write those lines to the file /proc/1001/fd/0.
At this point I would like the python interpreter to interpret this as code and execute it as if it were typed in directly.
This does not work as desired. Instead the text is displayed on the interpreter's screen, but it is not executed (similar to when error messages of subprocesses are displayed in bash). I presume this has something to do with the fact that my workflow isn't playing well with readline (or some sort of equivalent library). Or my problem might just be that the python interpreter was never designed to be used this way (for presumably security and other reasons).
I understand there are many IDEs with similar functionality, but I was hoping that something simple might work. I'm curious if it's something that can be fixed or if there is something fundamental that I'm misunderstanding.
It exists and it's called vim-slime
The only requirement is that you run the Python interpreter inside tmux or screen, or even better: byobu
Installing the vim-slime plugin is easy if you're using vim-pathogen:
cd ~/.vim/bundle
git clone git://github.com/jpalardy/vim-slime.git
See the vim-slime page for configuration details, but if you're using tmux, simply add the following to your .vimrc and re-start Vim:
let g:slime_target = "tmux"
Trying it out
Type in some Python code inside Vim:
def fib():
a, b = 0, 1
while 1:
yield a
a, b = b, a + b
Then press Ctrl-c-Ctrl-c to tell vim-slime to send the contents of your current buffer to another window. The first time you run it, vim-slime will ask you which screen/tmux window to send it to, but after that, press the key-sequence and it will send it wherever you told it to the first time.
vim-slime is visual-mode aware, too! If you only want to send a few lines to Python, enter visual-line mode with V, highlight the lines you want, and press the same Ctrl-c-Ctrl-c key sequence to send just those line.

Start Another Program From Python >Separately<

I'm trying to run an external, separate program from Python. It wouldn't be a problem normally, but the program is a game, and has a Python interpreter built into it. When I use subprocess.Popen, it starts the separate program, but does so under the original program's Python instance, so that they share the first Python console. I can end the first program fine, but I would rather have separate consoles (mainly because I have the console start off hidden, but it gets shown when I start the program from Python with subprocess.POpen).
I would like it if I could start the second program wholly on its own, as though I just 'double-clicked on it'. Also, os.system won't work because I'm aiming for cross-platform compatibility, and that's only available on Windows.
I would like it if I could start the second program wholly on its own, as though I just 'double-clicked on it'.
As of 2.7 and 3.3, Python doesn't have a cross-platform way to do this. A new shutil.open method may be added in the future (possibly not under that name); see http://bugs.python.org/issue3177 for details. But until then, you'll have to write your own code for each platform you care about.
Fortunately, what you're trying to do is simpler and less general than what shutil.open is ultimately hoped to provide, which means it's not that hard to code:
On OS X, there's a command called open that does exactly what you want: "The open command opens a file (or a directory or URL), just as if you had double-clicked the file's icon." So, you can just popen open /Applications/MyGame.app.
On Windows, the equivalent command is start, but unfortunately, that's part of the cmd.exe shell rather than a standalone program. Fortunately, Python comes with a function os.startfile that does the same thing, so just os.startfile(r'C:\Program Files\MyGame\MyGame.exe').
On FreeDesktop-compatible *nix systems (which includes most modern linux distros, etc.), there's a very similar command called xdg-open: "xdg-open opens a file or URL in the user's preferred application." Again, just popen xdg-open /usr/local/bin/mygame.
If you expect to run on other platforms, you'll need to do a bit of research to find the best equivalent. Otherwise, for anything besides Mac and Windows, I'd just try to popen xdg-open, and throw an error if that fails.
See http://pastebin.com/XVp46f7X for an (untested) example.
Note that this will only work to run something that actually can be double-clicked to launch in Finder/Explorer/Nautilus/etc. For example, if you try to launch './script.py', depending on your settings, it may just fire up a text editor with your script in it.
Also, on OS X, you want to run the .app bundle, not the UNIX executable inside it. (In some cases, launching a UNIX executable—whether inside an .app bundle or standalone—may work, but don't count on it.)
Also, keep in mind that launching a program this way is not the same as running it from the command line—in particular, it will inherit its environment, current directory/drive, etc. from the Windows/Launch Services/GNOME/KDE/etc. session, not from your terminal session. If you need more control over the child process, you will need to look at the documentation for open, xdg-open, and os.startfile and/or come up with a different solution.
Finally, just because open/xdg-open/os.startfile succeeds doesn't actually mean that the game started up properly. For example, if it launches and then crashes before it can even create a window, it'll still look like success to you.
You may want to look around PyPI for libraries that do what you want. http://pypi.python.org/pypi/desktop looks like a possibility.
Or you could look through the patches in issue 3177, and pick the one you like best. As far as I know, they're all pure Python, and you can easily just drop the added function in your own module instead of in os or shutil.
As a quick hack, you may be able to (ab)use webbrowser.open. "Note that on some platforms, trying to open a filename using this function, may work and start the operating system’s associated program. However, this is neither supported nor portable." In particular, IIRC, it will not work on OS X 10.5+. However, I believe that making a file: URL out of the filename actually does work on OS X and Windows, and also works on linux for most, but not all, configurations. If so, it may be good enough for a quick&dirty script. Just keep in mind that it's not documented to work, it may break for some of your users, it may break in the future, and it's explicitly considered abuse by the Python developers, so I wouldn't count on it for anything more serious. And it will have the same problems launching 'script.py' or 'Foo.app/Contents/MacOS/foo', passing env variables, etc. as the more correct method above.
Almost everything else in your question is both irrelevant and wrong:
It wouldn't be a problem normally, but the program is a game, and has a Python interpreter built into it.
That doesn't matter. If the game were writing to stdout from C code, it would do the exact same thing.
When I use subprocess.Popen, it starts the separate program, but does so under the original program's Python instance
No it doesn't. It starts an entirely new process, whose embedded Python interpreter is an entirely new instance of Python. You can verify that by, e.g., running a different version of Python than the game embeds.
so that they share the first Python console.
No they don't. They may share the same tty/cmd window, but that's not the same thing.
I can end the first program fine, but I would rather have separate consoles (mainly because I have the console start off hidden, but it gets shown when I start the program from Python with subprocess.POpen).
You could always pipe the child's stdout and stderr to, e.g., a logfile, which you could then view separately from the parent process's output, if you wanted to. But I think this is going off on a tangent that has nothing to do with what you actually care about.
Also, os.system won't work because I'm aiming for cross-platform compatibility, and that's only available on Windows.
Wrong; os.system is available on "Unix, Windows"--which is probably everywhere you care about. However, it won't work because it runs the child program in a subshell of your script, using the same tty. (And it's got lots of other problems—e.g., blocking until the child finishes.)
When I use subprocess.Popen, it starts the separate program, but does so under the original program's Python instance...
Incorrect.
... so that they share the first Python console.
This is the crux of your problem. If you want it to run in another console then you must run another console and tell it to run your program instead.
... I'm aiming for cross-platform compatibility ...
Sorry, there's no cross-platform way to do it. You'll need to run the console/terminal appropriate for the platform.

Categories

Resources