Python Inquirer Module: Remove Choices When Done (Using Curses) - python-3.x

NOTE: Although I give a lot of info on Inquirer, I'm pretty sure that most of it won't apply (just being safe). For my actual question about curses, its at the bottom.
I'm using the Inquirer module in Python 3 to allow the user to select a value from a list. I run this:
import inquirer
choice = inquirer.prompt([inquirer.List("size",message="Which size do you need?",choices=["Large", "Medium", "Small"])
And I'm given this:
[?] What size do you need?: Medium
Large
> Medium
Small
And using the up and down keys, I can change my selection, and hit enter to choose, after which the "choice" variable contains the value I selected. The issue is: Once the selection is done, the choices still show. I want to delete them when done. I'm currently using ANSI Escape Codes to delete the choices from onscreen when done, where x is the number of choices:
import sys
for i in range (x+1):
sys.stdout.write('\x1b[1A')
sys.stdout.write('\x1b[2K')
Which leaves the printed text as:
[?] What size do you need?: Medium
The issue is, ANSI escape codes aren't universal. I want to use a solution that works on all terminals, preferably curses, but curses isn't very friendly to new users, so I was wondering if anyone knew how to use curses to "delete x lines above current position". Thanks!

curses, as such, would erase the whole display (which is probably not what you want). A low-level terminfo/termcap approach might seem promising, but while ECMA-48 does define a sequence (ED, with parameter 1) which erases above the current position, there is no predefined terminfo/termcap capability which corresponds to this. All that you will find there is the capability for erasing to the end of the screen, or erasing the whole screen.
"ANSI sequences" is an obsolete term. Referring to ECMA-48, you could do
sys.stdout.write('\x1b[1J')
after moving the cursor to the last location you would like to erase.

Related

How to create linux tui like this one on the picture

Could someone share how can i create tui like this one with input boxex and search ?
What do i need?
Normally programmers use a ready to use library like ncurses.
You can also do it by hand if you really have to much time. To get for example the border lines of a dialog window you have to take a look at the current code page your terminal is emulating, for example: Code Page 850. As you can see, you will find single and double line boarders and also crossings and so on. Now you have to move your cursor to a given position, print that char from the code page and ... lots of work. Moving cursors itself can also be done by simple chars from your emulated terminal by using escape codes.
As said: Instead of doing it all by hand, simply use a lib like ncurses.
You can use some python libraries like pyTermTk or textual, there is wide selection of
libraries to choose from.

Add formatting to certain lines that begin with specific strings in Sublime Text 3?

I am working with a fixed-width file where all lines start with certain strings to denote what they contain.
TXX 12345 1111
TXY 123 1 2222
TXZ 1 2 3 4 5
What I want to happen is that I want to be able to add rulers or any form of formatting to rows that start with the specified text. (For example, I want to be able to set the line to red if the line starts with TXX, but blue if the row starts wtih TXY and so on)
What is the first step towards being able to do this?
Generally speaking, most roads here lead to a plugin of some sort that's doing work for you, though conceivably you could also get some coloring going using a custom syntax definition and alterations to your color scheme.
Which one is the correct one depends on circumstance and what works best for you. The following are some samples, which will work with the output you provided above but which could probably be made more robust (again depending on your use case); think proof of concept stuff.
Rulers
Rulers can only be applied to the file as a whole, not to specific lines. So for something like that you're looking at a plugin which, every time the cursor moves, tries to look at the current line to see what it is and then sets up rulers based on knowing what the line looks like.
A quick example of that is the following; the event listener will only apply to files that have the _fixed_rulers setting applied; simplistically, while you have your file open you can enter view.settings().set("_fixed_rulers", True) in the Sublime console, or if you have a syntax you could put the setting into syntax specific settings, etc.
import sublime
import sublime_plugin
def _get_rulers(line):
if line.startswith('TXX'):
return [4, 10]
if line.startswith('TXY'):
return [4, 8, 10]
if line.startswith('TXZ'):
return [4, 6, 8, 10, 12]
return []
class RulerListener(sublime_plugin.ViewEventListener):
#classmethod
def is_applicable(cls, settings):
return settings.get("_fixed_rulers", False)
def on_selection_modified_async(self):
# Cursor position of the first selection; get the full text of the
# line its on
pt = self.view.sel()[0].b
line = self.view.substr(self.view.line(pt))
self.view.settings().set("rulers", _get_rulers(line))
Since there can be multiple selections but rulers are not line specific, this uses the line the first cursor (based on position, not selection order) and applies rulers to the file based on that.
Regions
Colors can be applied to regions of content via a plugin, in a variety of styles (outlined only, underlined, filled, etc), and the API also allows you to find text regions via regex.
So it's also possible to have regions assigned that give things the color you want. A simple example of that would be this command, which will add/update the regions in the file that's active when you execute the color_line_regions command.
import sublime
import sublime_plugin
class ColorLineRegionsCommand(sublime_plugin.TextCommand):
def run(self, edit):
v = self.view
v.add_regions('_txx', v.find_all('^TXX.*$'), 'region.redish')
v.add_regions('_txy', v.find_all('^TXY.*$'), 'region.bluish')
v.add_regions('_txz', v.find_all('^TXZ.*$'), 'region.purplish')
This example is hard coded and requires you to manually invoke the command; you could also have this trigger in response to a file with a specific name opening, and so on.
As defined here this is a one time thing; if you are actively modifying the content of files, adding or changing lines will not adjust regions unless you run the command again (or, have an event listener listen for on_modified_async and trigger this after a delay, etc).
Syntax Definition
Another potential option is creating a custom syntax definition that recognizes the content of the file and applies the appropriate scopes to color things.
This is a much more complex option (the example below is very bare bones and not nearly production ready, but is a good simple test) in that it requires you to construct the syntax definition, but can yield good results if you put in the work.
What you would actually want to do is create your own custom scopes in your syntax, probably with much more robust rules, and then augment your color scheme to match those. Here we're just hackily using scopes that equate to the proper colors if you happen to be using Mariana as your color scheme.
%YAML 1.2
---
# See http://www.sublimetext.com/docs/syntax.html
file_extensions:
- fixed
scope: text.plain.fixed
name: Fixed Field Data
contexts:
main:
- match: '^TXX.*'
scope: variable.language.python
- match: '^TXY.*'
scope: variable.function.python
- match: '^TXZ.*'
scope: keyword.declaration.class.python
A Mix
The ultimate solution may be a mixture of these; perhaps you want the syntax to provide colors and the rulers plugin to make things easier to view as well (as a bonus, with a custom syntax you can have syntax specific settings, which makes the first plugin easy to deploy when files open).
The above examples just scratch the surface; be sure to check out the API Reference for information on how the plugins are working and for more details. There are also a variety of videos that teach how to create and use plugins on my YouTube channel.

Creating a 4-5 character column along the left margin in vim

As a bit of context, I am considering making a plugin for vim that would inline specific debugging and/or profiling information on along the left margin (ideally left of the numbers column) which would need to be 4-5 characters wide. However, I cannot find any means to accomplish this. I've searched around, and the closest thing I can find is vimscript code for inserting signs in the sign column, but the sign column is fixed at 2 characters wide.
I've considered the possibility of making my own makeshift column (to the right of the numbers column, in the normally editable text area) and somehow marking it as readonly, but that doesn't seem possible either- from what I've read, the entire buffer must be readonly or not; you can't have just a portion as readonly.
For completeness here's an example. I would like to programmatically insert a 4-5 character column before some text (with numbers set)
1 Text buffer
2 with some
3 text
to make
My 1 Text buffer
own 2 with some
text 3 text
Is there any way to accomplish this task?
The built-in feature for this is the sign column, but yes it is limited to two characters.
Depending on your use cases, it might be okay to enhance the signs with a tooltip popup (:help balloon-eval explicitly mentions This feature allows a debugger, or other external tool, to display dynamic information based on where the mouse is pointing.), or maybe place the additional information in the quickfix or location list.
Modification of the actual buffer has many downsides (as it effectively prevents editing, and Vim's main purpose is just that). What some plugins do is showing a scratch (that is: unpersisted, unmodifiable) buffer in a vertical split, and setting the 'scrollbind' option so that its contents follow the original buffer. For an example, have a look at the VCSCommand plugin, which uses this for annotating a buffer with commit information.

dialog/whiptail radiolist consistence

So basically I am trying to rewrite a bash script which uses dialog --radiolist for choosing locale,keyboard,time. At the moment the tag is a number that corresponds to a local (I created a hashtable for it). But because I have, and want to keep it that way for now, around 100 locales it gets messy at the end.
What I wanna achieve is to make it more compact without having to add or add an artificial, non visible item that might easily translate to its tag. (as a tag I would put the locale name)
What I have tried:
1. Noobish thing but I though that there might be some way to include empty like NULL in ASCII or 0, blank space etc, but dialog would always make it visible.
2. Exclude the item at all and finish on on/off but instead on/off takes place of item (not surprisingly if options are as follow --radiolist text height width list-height [ tag item status ])
3. Instead of letting the dialog on exit write to the output the name of the chosen locale I created an output statement myself.
I had red a lot about dialog and whiptail(http://linux.die.net/man/1/dialog, http://linuxcommand.org/lc3_adv_dialog.php) but always end up with having to add tag and an item. Would appreciate any suggestions and maybe some info if there is easily plug-gable dialog/whiptail compatible libs.
Thank You in advance
Perhaps you overlooked the --no-tags option (see manpage):
--no-tags
Some widgets (checklist, inputmenu, radiolist, menu) display a
list with two columns (a "tag" and "description"). The tag is
useful for scripting, but may not help the user. The --no-tags
option (from Xdialog) may be used to suppress the column of tags
from the display. Unlike the --no-items option, this does not
affect the data which is read from the script.
The question mentions whiptail and consistency, which could refer to consistency across dialog and whiptail. There is none, since
whiptail provides fewer options than dialog (inevitably, there will be differences, since there is no one-one mapping possible)
consistency as such between the two is done in dialog occasionally to help with compatibility (the reverse is not true).

xterm dump of full scrollable window content

I want to know if anyone does know a way to dump or copy the whole lot of viewable messages in a xterm window on linux. The very important thing is I don't want to know how to send a command out and kapture its output for stream 1 and 2 as well as the input, as this is well known to me.
I may explain for what this is needed. You do something and expect not any complications but than you got pages of msg's als err msg or normal output. To be able to see later after it you should be able to get them in a file and as long as you are able to scroll that all back and forther with your mouse it is sure the data is there some where. But the time may be not to scroll and screenshot and scroll ....
I would be glad to help me out in such cases and it would be fine to have the full view including all your own typing and all the msg's in same order as you watch it when you scroll it back.
I don't really know where this is stored and how you could get that saved. I know that I could dump the whole lot of Memory and search it for a part of the xterm window, but that is a bit over the top I think.
There is a control sequence, which I had forgotten. This question reminded me. In XTerm Control Sequences, it is noted "print all pages":
CSI ? Pm i
Media Copy (MC, DEC-specific).
Ps = 1 -> Print line containing cursor.
Ps = 4 -> Turn off autoprint mode.
Ps = 5 -> Turn on autoprint mode.
Ps = 1 0 -> Print composed display, ignores DECPEX.
Ps = 1 1 -> Print all pages.
That dates from 1999 (patch #119), so you likely have it in your xterm. You could do this in a shell command like this:
printf '\033[?11i'
A comment mentions the page Hidden gems of xterm, which uses the corresponding action print-everything (something that can be executed via the translations resource). It is in the manual page, of course. The same comment points to Extra characters in XTerm printerCommand output, which mentions the resource printAttributes. By default, the control sequences for the printer tell xterm to send extra control characters (to reconstruct video attributes). The resource can be modified (set to 0) to suppress that. That is even older (patch #74).
Without that — Conceivably one could construct an application which used the X SendEvent protocol to construct a series of events which would be interpreted as xterm actions to scroll back, select text and copy it chunk-by-chunk via the clipboard. You could even write it in Perl (there is a module for X protocol). But seriously, no.
If you want to capture text which was written to xterm, you can do this by preparing before the text is needed by different methods (see manual):
turn on the xterm logging feature (not that user-friendly because it generates the filename). This can be enabled using the "Log to File (logging)" menu entry.
use the printer control sequences to write lines as they are written (again, not that friendly, though there is a menu entry to turn it on and off, "Redirect to Printer (print-redir)")
use script to capture all output to the terminal. I use this, because it works with any terminal on any POSIX-like system (even Cygwin).
Each of these methods produces a file containing escape/control sequences, which requires filtering out. The hypothetical program using SendEvent could in principle eliminate that.

Resources