interfaz gráfica de usuario de línea de comando similar a vim

interfaz gráfica de usuario de línea de comando similar a vim

Últimamente, me he estado preguntando cómo funciona la interfaz de usuario de vim, que cuando lo inicias, ocupa toda la ventana de la terminal, en lugar de simplemente imprimir texto y tal vez requerir que ingreses algo y, cuando termine, imprimir otra línea de comando a continuación.

¿Cómo funciona esto, sólo por curiosidad?

Respuesta1

La ventana de terminal es simplemente una emulación de un "Terminal tonta - Wikipedia" que no puede hacer nada más que mostrar líneas de caracteres, tradicionalmente 24 líneas de 80 caracteres ASCII, y los nuevos caracteres se agregan solo al final de la última línea (piense en una máquina de escribir).

Los terminales se volvieron gradualmente "más inteligentes", agregando la capacidad de mover el cursor a una ubicación específica, insertar líneas, mostrar el siguiente carácter en color, etc.

Pero cada fabricante lo hacía a su manera y no existía un estándar único, por lo que cada programa debía incorporar el conocimiento del hardware específico con el que se estaba utilizando. (Recuerdo que me mostraron un programa de interfaz de base de datos en una feria comercial a principios de los años 1980. El presentador dio una lista de aproximadamente una docena de tipos de terminales comunes con los que sabía cómo trabajar, y dijo que por sólo X dólares podían enseñarlo. para manejar cualquier otro tipo que tuviéramos en nuestra empresa).

Mientras tanto, BSD había desarrollado elTermcap - Wikipediabiblioteca para su sistema UNIX. Especificaba una base de datos basada en texto que definía un conjunto de capacidades estándar para cada tipo de terminal y proporcionaba una biblioteca C que utilizaba esta base de datos para determinar el formato apropiado de la cadena para enviar al terminal en función de la TERMvariable de entorno. Por supuesto, no todos los terminales soportaban todas las capacidades, pero eso estaba bien, los programas sabrían usar sólo aquellas capacidades que estuvieran disponibles (por ejemplo, si un terminal no tenía direccionamiento directo, podría haber subido/abajo una línea y hacia la izquierda/ una posición a la derecha).

termcap.small · freebsd/freebsd · GitHubmuestra una entrada de termcap de muestra para un terminal vt100:

vt100|dec-vt100|vt100-am|vt100am|dec vt100:\
        :do=2\E[B:co#80:li#24:cl=50\E[H\E[J:sf=2*\ED:\
        :le=^H:bs:am:cm=5\E[%i%d;%dH:nd=2\E[C:up=2\E[A:\
        :ce=3\E[K:cd=50\E[J:so=2\E[7m:se=2\E[m:us=2\E[4m:ue=2\E[m:\
        :md=2\E[1m:mr=2\E[7m:mb=2\E[5m:me=2\E[m:\
        :is=\E>\E[?1;3;4;5l\E[?7;8h\E[1;24r\E[24;1H:\
        :if=/usr/share/tabset/vt100:nw=2\EE:ho=\E[H:\
        :as=2\E(0:ae=2\E(B:\
        :ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||:\
        :rs=\E>\E[?1;3;4;5l\E[?7;8h:ks=\E[?1h\E=:ke=\E[?1l\E>:\
        :ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=\177:\
        :k0=\EOy:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\EOt:\
        :k6=\EOu:k7=\EOv:k8=\EOl:k9=\EOw:k;=\EOx:@8=\EOM:\
        :K1=\EOq:K2=\EOr:K3=\EOs:K4=\EOp:K5=\EOn:pt:sr=2*\EM:xn:\
        :sc=2\E7:rc=2\E8:cs=5\E[%i%d;%dr:UP=2\E[%dA:DO=2\E[%dB:RI=2\E[%dC:\
        :LE=2\E[%dD:ct=2\E[3g:st=2\EH:ta=^I:ms:bl=^G:cr=^M:eo:it#8:\
        :RA=\E[?7l:SA=\E[?7h:po=\E[5i:pf=\E[4i:

Más tarde, unmaldiciones - WikipediaLa biblioteca fue desarrollada para simplificar el proceso, proporcionando funciones para generar los códigos apropiados con valores específicos. Cualquier programa podría simplemente decir algo como tgoto(capabilities, column, row), y la biblioteca encontraría el tipo de terminal en la TERMvariable de entorno, buscaría las capacidades para ese tipo específico en la base de datos termcap y generaría una cadena que contiene los comandos de terminal apropiados para mover el cursor al lugar especificado. posición.

termcap(3) - páginas del manual de OpenBSDmuestra declaraciones de algunas funciones de libcurses:

#include <curses.h>
#include <term.h>

extern char PC;
extern char * UP;
extern char * BC;
extern short ospeed;

int tgetent(char *bp, const char *name);
int tgetflag(char *id);
int tgetnum(char *id);
char *tgetstr(char *id, char **area);
char *tgoto(const char *cap, int col, int row);
int tputs(const char *str, int affcnt, int (*putc)(int));

Programas, comovi - Wikipedia, utilizó estas bibliotecas para proporcionar un editor que funcionara en cualquier terminal con una pantalla direccionable. Un nuevo tipo de terminal solo requería definir su entrada termcap, y funcionaría automática e instantáneamente con vicualquier otro programa basado en esa biblioteca.

Finalmente termcapfue reemplazado por una versión mejorada llamada terminfo, y cursesfue reemplazado por una nueva versión ncurses, pero los principios subyacentes siguieron siendo los mismos.

Tenga en cuenta que todo esto depende de la capacidad de UNIX para leer un carácter ingresado desde el teclado.sinmostrándolo automáticamente en el terminal. Muchos sistemas operativos de la época no podían hacer esto. Algunos ni siquiera aceptarían entradas desde la terminal hasta que se hubiera ingresado una línea completa (o incluso una pantalla).

Respuesta2

Los programas con una interfaz de usuario textual (TUI) de pantalla completa en sistemas operativos tipo Unix utilizan una biblioteca de posicionamiento del cursor llamada curses.

Esta biblioteca utilizó inicialmente una base de datos de capacidades de terminal conocida como termcapque luego fue reemplazada por un sistema conocido como terminfo.

Las aplicaciones TUI con ventanas en un escritorio GUI utilizan señales de cambio de tamaño de ventana, comosigwinch

información relacionada