How to query the character under the current cursor position or anywhere on the screen in bash - linux

I know that the following statement is a way to query the current cursor position:
echo -en '\033[6n'
Does anyone know how to query the character under the cursor or populate a array with the contents of the current screen/window? I've searched through the ANSI terminal commands however a lot of these are pretty abstract and it doesn't look like they would do this properly. I also looked into doing it with the tcup command with no luck.
Thank you for your help.

An ANSI terminal is not really required to be able to tell you what is on the screen. You're supposed to remember that yourself, if you need the information. The popular ncurses library does that, for example, although it only allows you to export the screen to a file, and the fileformat is not documented. In any event, bash doesn't use ncurses, so it really doesn't know anything about the state of the console.
Most probably, the screen you are talking about is actually an artifact of some terminal emulation program like xterm. Those programs run in userspace, and rarely (if ever) have an external query interface. However, linux does have a console (actually, a number of emulated consoles, but using the display's console mode) and it maintains the display memory for those consoles. And furthermore, it provides an interface for reading the console memory, usually available as /dev/vcsN (for values of N between 0 and the number of virtual consoles linux was compiled with). /dev/vcs0 is the "current" console (the one which is visible).
Most linux distributions restrict access to /dev/vcsN, so if you want to play around with them you'll either need special privileges or you'll need to use root privileges to change the access permissions on the device files. (Ubuntu appears to provide rw access to users in group tty; check ls -l /dev/vcs0 to see how your system does it.) (And, of course, you'll need to find the console :-) Try CtlAlt1; CtlAlt7 will probably give you back your GUI.)
Once you've worked out the access issues, you could do something like cp /dev/vcs0 console_memory to take a look at it. What you'll find is that it is just a 2D array of characters with no newlines, and no indication of what the dimensions are. (You can get the dimensions with an ioctl or by looking at the environment variables $LINES and $COLUMNS.)
You could use /dev/vcsa0 instead; it has a slightly different format using two bytes per character in order to store display attributes (foreground and background colours, mostly) as well as the character. Also, the first four bytes of /dev/vcsaN are the screen dimensions and cursor position (one byte per coordinate), which will save you the work of querying the cursor position.
Note that the console does not support a full Unicode character set. In fact, it can only display 512 different glyphs at once. In order to maximize the available glyph space, Linux may reassign some codes to needed symbols, and this mapping is not part of the console memory. So the code extracted from console memory might not have an obvious mapping to a Unicode code, but it should work fine for standard ANSI characters.

Related

Persistent prompt in Linux (not just shell)

I spent several decades using Digital Equipment Corporation's VMS operating system, and one of the things I really miss is the terminal driver's 'read-with-prompt' functionality.
It would display the prompt and position the cursor for input, as you'd expect, but the prompt was immune to things like CTRL/U, CTRL/R, and CTRL/W. It was an attribute of the read operation, and every time the terminal driver was ready to read from the terminal with this option, it would show the prompt. The user couldn't erase it, so if it went off the screen he'd still know what was being requested.
This is one of the few things that I think VMS did better than U*X -- unless there's a Linuxish way of doing this.
So far I've never found it, but maybe I'm just not looking in the right place.
Is there a way on Linux to read from a tty with a persistent prompt?
Thanks!

What is the tty subsystem for?

By now I have now spent at least 10 hours trying to get my head around the famous blog post by Linus Akesson, and Im still struggling. So let me ask my doubts about tty/ptty as a series of short questions.
1) Is the tty/ptty in user space or kernel space?
2) What is tty/ptty's connection to devices or drivers or some numbering or something?
3) The tty seems to be linked to something called the controlling terminal of a process, What is the relation and is every process related to a terminal?
4) On the whole I still dont understand where the heck this terminal concept fits in. A process wants to read something from the stdio, cant it simply do it from the required device file. What exactly is the problem that the tty intends to take care of?
5) I read somewhere that there are attempts to move the tty from the userspace to the kernel space. Is the tty simply a historical residue than a strong design feature.??
A clarification (which might answer some of your questions):
I think you meant pty (and not ptty) which is pseudo-tty/pseudo-terminal.
A tty (/dev/ttyx) - stands for teletype - is the original terminals (used a line printer for output and a keyboard for input!). A terminal is basically just a user interface device that uses text for input and output.
A pty (/dev/pty/n) is a pseudo-terminal - it's a software implementation that appears to the attached program like a terminal, but instead of communicating directly with a "real" terminal, it transfers the input and output to another program. It's the end point of telnet/SSH or even the GNOME terminal.
For example, when you ssh into a remote machine and run ls, the ls output is sent to a pseudo-terminal, the other side of which is attached to the SSH daemon.
EDIT:
As far as I know, the tty and so pty, are usermode. BUT they represent terminal-driver. What I mean is: the device file /dev/tty1 is the first virtual console. Most code lives in drivers/char, in the files tty_io.c and n_tty.c and vt.c (kernel source). In contrast to character devices in order to open those files tty_open routine is called, and trust me, it's way messier than opening a character device...
Tty/pty stands for terminal drivers mentioned above but they stands for serial ports (the"numbering" you said). I know very little about it so I don't want to say incorrect data... but you can search the net about it (or someone else can continue from here)
EDIT2:
You have changed the question so now it seems like I spoke out of context...
Anyway, tty has many different roles even nowday. Terminal driver is the way user-kernel can "communicate". There are some techniques such as terminal drivers, character device etc.
If you still have a question please comment and don't change the whole post....

Remove delay after first symbol on key hold

When I press and hold a key, a first symbol is typed, then there is a little delay, and then other symbols are typed fast. Something like this:
Same happens in Terminal. Same happens in linux console (tty), even though this delay is smaller there.
I'm working on a console app in Python that uses curses, and it processes the presses of arrow keys and this delay is present there as well.
I want to get rid of this delay, so that when I press and hold a key - it would send signals with uniformly, without any specific delays after first (or whichever) symbol.
How can I do it? Should I use something from the arsenal of curses? Or tinker with some system-wide settings?
EDIT1: I think I've found one way. I can go to keyboard settings and set delay of autorepeat. But it changes it globally and only for my graphical interface. It doesn't change anything in linux console. So, I'm looking fo a way to do it in console as well, and also so it would affect only my app, not the whole system.
and a way for linux console: https://unix.stackexchange.com/questions/58651/adjusting-keyboard-sensitivity-in-a-command-line-terminal
but still looking for an app-only way.

Why is it slower to print directly to console/terminal than redirecting?

Why does it take significantly more time to print multiple lines to the terminal rather than redirecting it to a file which seems to be almost instant ?
Primarily, terminals are just plain slow. For every update, they have to:
Parse and interpret any control codes.
Parse, interpret and render any escape codes.
Interpret and account for any multibyte and composed characters.
Update appropriate screen and scroll buffers.
Render this with appropriate fonts.
and possibly do all of the above over again if you use screen or tmux.
Meanwhile, for redirecting to a file, you just have to:
Dump data into RAM (for later writeback to storage).
This step is so minor that it doesn't even register on the terminal's checklist.
This is not something people optimize for, because the speed of your terminal is rarely an issue. The difference between terminals can be 50x (VGA vs fbcon back in the day), and you can time it with a simple time cat somebigfile.txt.

How to only allowed certain text to be printed on Emacs Console?

This question maybe not related to Emacs only, but to all development environment that use Console for its debugging process. Here is the problem. I use Eshell to run the application we are being developed. It's a J2ME application. And for debugging, we just use System.out.println(). And now, suppose I want to allow only text that started with Eko: to be displayed in the console (interactively), is it possible?
I installed Cygwin in my Windows environment, and try to grep the output like this :
run | grep Eko:. It surely filtered only output with Eko: as the beginning, but it's not interactive. The output suppressed until the application quit. Well, that's useless anyway.
Is it possible to do it? What I mean is, we don't have to touch the application code itself?
I tag to linux also, because maybe some guys in Linux know the answer.
Many thanks!
The short: Try adding --line-buffered to your grep command.
The long: I assume that your application is flushing its output stream with every System.out.println(), and that grep has the lines available to read immediately, but is choosing to buffer output until it has 'enough' output saved up to make writing make sense. (This is typically 4k or 8k of data, which could be several hundred lines, depending upon your line length.)
This buffering makes great sense when the output is another program in the pipeline; reducing needless context switches is a great way to improve program throughput.
But if your printing is slow enough that it doesn't fill the buffer quickly enough for 'real time' output, then switching to line-buffered output might fix it.

Resources