Linux command line application with persistent interface - linux

How do programs (specifically in Linux) like top keep their interface on the screen without it scrolling? Do they create a new screen session, or is there a standard library for creating GUIs like that? If they do use screen, then why is the output still written to stdout when I exit top?

There is a standard library, it is called ncurses. But there's no need to use it - the console_codes(4) man page describes how to do such things by writing special character sequences to a terminal (emulator), and curses is nothing but a wrapper around that.
To clear the screen like top does, you'll need to echo ESC [ 2 J to the terminal to clear it, followed by ESC [ H to reset the cursor to the origin, i.e.
echo -ne "\033[2J\033[H"
Note that top might actually be more intelligent and not redraw the entire screen but only the parts which changed. See the manual page for more details. (You can do more fancy stuff with console codes, like changing colors, underline, bold, or even use the mouse in x terminals.)

Related

When you press right arrow in terminal during a process "^[[C" shows up. What it means anyway?

If you happen to press arrows in Linux terminal while running a mysql query or inside a window where you have a server running a series of characters pop up. The same thing happens if you press the arrows + SHIFT or F2, F3, F4, etc. But if you press other keys they will show up as you would expect.
It is obvious to me that these sequence of characters were created following certain order. So what are they? What do they represent? Who came up with them ? Which computer language do they come from? They look archaic and useless...Should we drop them in the future? Or are they really useful?
4 Arrows
^[[A^[[B^[[C^[[D
SHIFT + Arrows
[[1;2A^[[1;2B^[[1;2C^[[1;2D
F2-F6
^[OQ^[OR^[OS^[[15~^[[17~
I searched for an answer to my questions on the web to no avail.
Actually, that is from a terminal emulator. The Linux console produces different characters.
In either case, those are generally referred to as ANSI escape sequences, which are sent by special keys (function-keys or cursor-keys), usually in the same type of "archaic" form which applications use to control the terminal.
The particular set you have quoted are documented in XTerm Control Sequences, and are recognized by terminal applications such as ncurses. The corresponding information in ncurses is stored in its terminal database, e.g., this entry (you may have to follow a few links to see all of this).
With that, you may have enough keywords to use with web-searches.

How to implement proper mouse support in a terminal / terminfo entry?

I've implemented a terminal emulator and a corresponding terminfo entry that allows me to run ncurses programs like emacs, mc (midnight commander) or tig (git browser). I want to add mouse support to the terminal, most notably to position the cursor in emacs by clicking into the window. After a lot of googling and some help on stackoverflow I learned about the required terminfo fields (most notably kmous) and control (e.g. \E[?1000h) and "key" (\E[M...) sequences and implemented mouse button events in my terminal. I've written a small ncurses program that goes something like this:
initscr ();
clear ();
noecho ();
cbreak ();
keypad (stdscr, TRUE);
mousemask (ALL_MOUSE_EVENT, NULL);
if (has_mouse ())
{
while (1)
{
switch (getch ())
{
case KEY_MOUSE:
if (getmouse (&event) == OK)
{
printf ("mouse event 0x%x at %i,%i\n", event.bstate, event.x, event.y);
This program works fine on xterm and my terminal, so both my terminal and its terminfo entry can't be completely wrong.
However, mc appears to not recognize mouse support in my terminal, does not even issue any \E[?1000h sequence to activate it and is therefore utterly confused by the mouse button events my terminal sends (even without \E[?1000hactivation).
What am I missing?
Someone pointed out this problem recently (though the question was not mentioned):
20181124
+ modify the initialization checks for mouse so that the xterm+sm+1006
block will work with terminal descriptions not mentioning xterm
(report by Tomas Janousek).
The problem was that the code would use the kmous capability if TERM had "xterm", and otherwise would default to the original xterm mouse protocol (which didn't have "any event" capability). That probably was overlooked for quite a while due to inertia (people using the "xterm" terminal descriptions with other terminals).
The ncurses manual page does say what's intended:
Because there are no standard terminal responses that would serve to
identify terminals which support the xterm mouse protocol, ncurses assumes that if your $TERM environment variable contains "xterm", or
kmous is defined in the terminal description, then the terminal may
send mouse events.

Tmux: pane title (#T) is reported as "fg" rather than something more informative

Is there a way to get Tmux to show a more informative pane name?
If in a particular pane I have suspended a process and come back to it (with Zsh that's invoking it with either fg or something like %2), that is what the pane's title becomes rather than its real title (which might be vim ~/somepath/somefile.
You have some bit of zsh configuration that is doing this for you (probably a “preexec” command).
I have seen oh-my-zsh cause a similar problem. If you are using it, then you might try putting DISABLE_AUTO_TITLE=true in one of your configuration files. Otherwise, it will rename the window to be the first word of every command that you enter.

Focus follow mouse in vim

I am aware that the mousefocus option is only supposed to work in gVim. But I was wondering, if it's possible to have the console Vim switch to different windows in response to mouse clicks, would it be not possible to easily add following mouse movement to it, too?
I'm an xmonad user, I love the focus following the pointer feature, I do a lot of pdf viewing and browsing while writing in Vim, and I'd be so much happier if I didn't have to keep mentally switching back and forth between two different types of focus changing.
If that's completely not possible, I guess opening new Vim windows (as with :split) in new instances of the terminal is no easier to do?
It would not be at all simple to add this. Using the mouse within the terminal works by vim sending control codes to the terminal requesting that mouse actions be sent as part of the input stream. Terminals only report clicks not changes in the pointer position, so vim has no way of knowing where the mouse is.
With major changes it would likely be possible for a vim with X support to get pointer activity directly from the X server, but that would likely be reported by pixel rather than by character so further work would need to be done before it could determine which vim window is currently under the pointer.
set mouse=a
should do the trick but it will probably depend on your terminal emulator. See :help 'mouse'.
This works for Windows 7/Cygwin 32bit mintty/vim 7.3: (I DO NOT use gvim!)
Having installed this: http://ehiti.de/katmouse/, I can scroll the window under my cursor without having to have clicked to select a window, click-selecting of single vim-windows works, too. It does not pull the vim window to the foreground, if another window overlaps it, if that is what you desire. Still it can be scrolled without click-selecting it first.
So:
Check if there exists a software paket for your distribution, that implements your desired mouse behavior on the OS level. When this works for my self-compiled vim in cygwin, it might very well work with console vim on linux, too.
This post here serves as evidence, that it is possible at all, that is the reason this was not made a comment. When I am on linux again I will investigate this further and update this post, but that might take a while.
On set mouse=a: The vim help states you a need a terminal capable of handling mouse inputs, further information can be found here. :help ttymouse might also be helpful, i.e. if you have a xterm-compliant console, but :help term is set to something else.
UPDATE: (Freshly installed Fedora 19 with packages, no self-compiled stuff.)
Fedora 19 + se mouse=a = scrolling in single console vim window with several buffers opened next to each other independently works, too. Window manager used is LXDE.

Why does vim connect to X by default?

The man page says vim -X disables clipboard and window title operation. Is that all we get for vim connecting to X?
I find it a bit surprising, since the default settings slow down vim's startup significantly for me, and I've never needed the clipboard/window title behavior.
This is not gvim, by the way.
My educated guess would be, that it's because most people nowadays use terminal emulators in graphical environments, so it would be useful to behave like nice citizen of such an environment, providing more of a consistency in how various applications look or work.
As a bonus it's more vim-like to use * register for interrogating clipboard.
And more foolproof. I remember graphical terminal emulators where the only way to select text was the old fashioned mouse selection. Given that vim buffer in terminal would not scroll when you selected part of the terminal (as technically selection occurred outside vim in the realm of terminal emulator, and vim was not even aware it's currently taking place) it would not be possible to copy to clipboard anything spanning more than screen could currently hold. And even then it might not work the way you'd want depending on line wrapping settings.
But that is not the problem if editor has connection to system clipboard. Just copy any text you like to * register in the vim-way, and then you have it in system clipboard.
It's still just my speculation.

Resources