How do I determine size of ANSI terminal? - terminal

Standard input and output are connected to a terminal that implements ANSI escape sequences, but is of unknown dimensions.
I need to know how big the terminal so to facilitate drawing a full-screen text UI on it. How can I get the size?
The correct size is not loaded into environment variables. I cannot use TIOCGETS; the the call would return success but the values are not correct -- the kernel doesn't know the size either.
There are lots and lots of answers searching stackoverflow, but they all depend on the OS providing the answer one way or anther; but this time that is not true.
The best clue I can find is the DSR command which returns the current cursor position; but there's no move to bottom/right command.

The resize program does this by moving the cursor to a very large column and row; the terminal moves as far as it can, e.g.,
CUP 999 999
Then resize asks where the cursor is:
DSR 6
The terminal replies with the actual cursor position (i.e., the cursor position report CPR), from which resize knows the terminal's size: the cursor is on the lower-right corner.
That's all done using standard (ECMA-48 / VT100) escape sequences. In XTerm Control Sequences (which should apply to your "ANSI" terminal)
CSI Ps n Device Status Report (DSR).
Ps = 6 -> Report Cursor Position (CPR) [row;column].
Result is CSI r ; c R

Related

printf "\033[8;(width);(height)t" works for a specific height and width but is there something more universal

I have a script which is for running as a first run script on different machines and I don't know ahead of time what the width/height of the monitors will be. What I hoping to find is a command like printf "\033[8;(width);(height)t" which is more universal and will expand the terminal to maximum no matter which size monitor is connected to the computer. I had an escape sequence that worked great, but I lost the script along with the code when one of my drives died (I know, backup, backup, and backup again) and can't seem to find that fix again anywhere.
Using the printf "\033[8;(width);(height)t" escape code sequence works if I know in advance what the height and width of the maximized monitor dimensions are (for instance using printf "\033[8;58;238t" will work on my 1920x1080 monitor just fine and will expand as expected) but it is not enough for a larger monitor. Using tput cols and tput lines will give me what the current window dimensions are, but not the maximum dimensions.
I know I can use the keyboard and mouse to do this, but I am strictly looking for something that will expand the window without any other input or key presses, if for no other reason than knowing how to do it and making it work. This needs to execute at the beginning of a bash script on a fresh Ubuntu flavor installation (the script does unique installations and updates). It might be able to work if I could figure out how to get the maximum terminal size possible of a screen into a variable to be used in the code mentioned above.
I have tried echo -ne '\e[9;1t' and printf '\e[9;1t', also echo -ne '\e[10;2t' and printf '\e[10;2t' escape codes to no avail, mentioned at https://terminalguide.namepad.de/seq/ (Control Characters and Escape Sequences) on pages "Alias: Maximize Terminal" and "Maximize Terminal Window". This is one of the few references I can find. Any searching of various ways to ask this question doesn't seem to yield any results and they all seem to rely on knowing ahead of time what the maximum dimensions can be.
Any hints of what I can use for this would be helpful, thank you.
Set the size to a number that is guaranteed to be larger than any existing screen. Pad it some to accommodate for rapidly increasing screen resolutions:
printf "\033[8;99999;99999t"
The window manager should truncate the size to the maximum available area.

Get mouse position in pixels using escape sequences

I'm trying to obtain the position of the mouse in pixels within an application running in a terminal.
The top answer to how to get MouseMove and MouseClick in bash? explains how to get the mouse position, counted in character cells, not in pixels.
I'm looking for a solution which also works if the app is running on a remote server and accessed via SSH (using xdotool will not work in this case, unless ssh -X was used).
I guess the solution will therefore involve escape sequences or an IOCTL.
It's okay if the escape sequences only work with one or few terminal emulators (I can use a detection mechanism to provide a fallback on the terminals which lack support for the escape sequence).
If the escape sequence only works on a few terminal emulators, I'm also curious to know the "group" of escape sequences that allow graphical output on these terminals (e.g. Sixel, Tektronix or ReGIS).
The goal is to embed small GUI elements in mostly text-based applications. It is currently possible on quite a few terminal emulators using Sixel, Tektronix or ReGIS do draw things, and \e[1000h or similar escape codes to get mouse events, unfortunately these mouse events are low-resolution (the coordinates in character cells, not in pixels).
xterm reports the mouse position with pixel resolution with the following escape sequences:
switch on pixel resolution: \e[2;1'z
report mouse position: \e['|
Details are described at http://invisible-island.net/xterm/ctlseqs/ctlseqs.html

VIM center text to screen, with left and right inactive borders

I use vim to edit text files. My screen is too wide and it's cumbersome to always look near left border of screen when editing. If you open a document in MS Office, the page is "centered" instead of left-aligned, and has non-active area borders on RHS and LHS. How do I get similar behavior from vim?
Here are a couple approaches that won't work too well:
First, if you read VIM: Show a 3 character border on left of window or MacVim: how do I set a left gutter (margin) for my buffers?, you might try this:
:set foldcolumn=50
This won't work, because the maximum value of foldcolumn is limited to 12.
Second, if you read How to create a border between the line numbers and text in Vim, you might try using numberwidth instead of foldcolumn:
:set numberwidth=50
But this won't work either, because the maximum value of numberwidth is limited to 10.
The best approach that will work, as far as I've been able to find, is https://superuser.com/q/537584/376367. See that question's answer for more details, but the summary is: create two vertical splits, and edit your file in the middle. If the vertical divider lines and tildes bother you, you could hide them with:
:highlight VertSplit guifg=bg guibg=bg
:highlight NonText guifg=bg
Caution: if you use listchars, they also use NonText highlighting and will also be hidden by this trick.
A plugin which centers the text and removes distractions for you is Goyo, especially useful in combination with Limelight.

How to change font size with shell script?

Is there any way to change the size of the text in shell script ?
I mean dynamically during the execution .
For example I have an image drawn with ASCII code and i want to reduce the size of text .
Now when echo or cat the image it will be shown as the command prompt actual size (the actual font size) .
A couple of comments note that font size/style are under the control of the terminal emulator, and that xterm (and a few others) support escape sequences to change these.
However - almost all terminal emulators (all that you would be likely to encounter) rely upon keeping the characters in a nice row/column grid. All of the characters have the "same" size. If you change the size of the font in xterm, all of the characters on the screen change to the same size. So there is no way to (as OP asks) to reduce the font-size temporarily, e.g., while using ASCII graphics to draw a picture using aalib, etc.
If you want to do something like that, the easiest way to do it is to have the script run its graphics in a separate window, e.g., by splitting it up into one part that starts the window and another script to draw the graphics.
For an alternate via of terminals and fonts, there is always something like 9term (no rows, no columns, no vi).

How to use xmonad in portrait mode/orientation?

How does one use xmonad with the physical screens in portrait orientation?
I have two physical displays and they are both rotated 90 degrees to the right (clockwise with original bottom edges on the left)
I'm on Fedora 21 (3.19.3-200.fc21.x86_64)
I don't know how to tell what window manager is running, but there's a gnome-shell process running...
When I sudo telinit 3 and then startx, xmonad comes up with everything in landscape orientation. I don't know how to change it at that point and I don't know how to make it start in portrait mode.
My .xinitrc file says this
#!/usr/bin/env bash
emacs &
gnome-terminal &
exec xmonad
Thanks in advance for any help!
Well, first of all, your window manager seems to be xmonad ;-).
Independent of that, xrandr does what you need.
Shamelessly taken from here (because SO doesn't accept duplicates from unix.stackexchange.com):
Find your output devices with xrandr (the first word before "connected", you should find two such lines), e.g. eDP1 if the output is
eDP1 connected 1600x900+0+0 (normal left inverted right x axis y axis) 309mm x 174mm
and then have fun with
xrandr --output eDP1 --rotate right
in your .xinitrc.
The original answer notices that by using a NVidia card you may have to add
Option "RandRRotation" "True"
to your xorg.conf (which i cannot verify with my setup).

Resources