ttyscan 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ttyscan-0.0.2/.gitignore +218 -0
- ttyscan-0.0.2/LICENSE +21 -0
- ttyscan-0.0.2/PKG-INFO +263 -0
- ttyscan-0.0.2/README.rst +236 -0
- ttyscan-0.0.2/pyproject.toml +63 -0
- ttyscan-0.0.2/test_ttyscan.py +527 -0
- ttyscan-0.0.2/ttyscan.py +805 -0
ttyscan-0.0.2/.gitignore
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
# Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# UV
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# uv.lock
|
|
102
|
+
|
|
103
|
+
# poetry
|
|
104
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
105
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
106
|
+
# commonly ignored for libraries.
|
|
107
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
108
|
+
# poetry.lock
|
|
109
|
+
# poetry.toml
|
|
110
|
+
|
|
111
|
+
# pdm
|
|
112
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
113
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
114
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
115
|
+
# pdm.lock
|
|
116
|
+
# pdm.toml
|
|
117
|
+
.pdm-python
|
|
118
|
+
.pdm-build/
|
|
119
|
+
|
|
120
|
+
# pixi
|
|
121
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
122
|
+
# pixi.lock
|
|
123
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
124
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
125
|
+
.pixi
|
|
126
|
+
|
|
127
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
128
|
+
__pypackages__/
|
|
129
|
+
|
|
130
|
+
# Celery stuff
|
|
131
|
+
celerybeat-schedule
|
|
132
|
+
celerybeat.pid
|
|
133
|
+
|
|
134
|
+
# Redis
|
|
135
|
+
*.rdb
|
|
136
|
+
*.aof
|
|
137
|
+
*.pid
|
|
138
|
+
|
|
139
|
+
# RabbitMQ
|
|
140
|
+
mnesia/
|
|
141
|
+
rabbitmq/
|
|
142
|
+
rabbitmq-data/
|
|
143
|
+
|
|
144
|
+
# ActiveMQ
|
|
145
|
+
activemq-data/
|
|
146
|
+
|
|
147
|
+
# SageMath parsed files
|
|
148
|
+
*.sage.py
|
|
149
|
+
|
|
150
|
+
# Environments
|
|
151
|
+
.env
|
|
152
|
+
.envrc
|
|
153
|
+
.venv
|
|
154
|
+
env/
|
|
155
|
+
venv/
|
|
156
|
+
ENV/
|
|
157
|
+
env.bak/
|
|
158
|
+
venv.bak/
|
|
159
|
+
|
|
160
|
+
# Spyder project settings
|
|
161
|
+
.spyderproject
|
|
162
|
+
.spyproject
|
|
163
|
+
|
|
164
|
+
# Rope project settings
|
|
165
|
+
.ropeproject
|
|
166
|
+
|
|
167
|
+
# mkdocs documentation
|
|
168
|
+
/site
|
|
169
|
+
|
|
170
|
+
# mypy
|
|
171
|
+
.mypy_cache/
|
|
172
|
+
.dmypy.json
|
|
173
|
+
dmypy.json
|
|
174
|
+
|
|
175
|
+
# Pyre type checker
|
|
176
|
+
.pyre/
|
|
177
|
+
|
|
178
|
+
# pytype static type analyzer
|
|
179
|
+
.pytype/
|
|
180
|
+
|
|
181
|
+
# Cython debug symbols
|
|
182
|
+
cython_debug/
|
|
183
|
+
|
|
184
|
+
# PyCharm
|
|
185
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
186
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
187
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
188
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
189
|
+
# .idea/
|
|
190
|
+
|
|
191
|
+
# Abstra
|
|
192
|
+
# Abstra is an AI-powered process automation framework.
|
|
193
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
194
|
+
# Learn more at https://abstra.io/docs
|
|
195
|
+
.abstra/
|
|
196
|
+
|
|
197
|
+
# Visual Studio Code
|
|
198
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
199
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
200
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
201
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
202
|
+
# .vscode/
|
|
203
|
+
# Temporary file for partial code execution
|
|
204
|
+
tempCodeRunnerFile.py
|
|
205
|
+
|
|
206
|
+
# Ruff stuff:
|
|
207
|
+
.ruff_cache/
|
|
208
|
+
|
|
209
|
+
# PyPI configuration file
|
|
210
|
+
.pypirc
|
|
211
|
+
|
|
212
|
+
# Marimo
|
|
213
|
+
marimo/_static/
|
|
214
|
+
marimo/_lsp/
|
|
215
|
+
__marimo__/
|
|
216
|
+
|
|
217
|
+
# Streamlit
|
|
218
|
+
.streamlit/secrets.toml
|
ttyscan-0.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jeff Quast
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ttyscan-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ttyscan
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: Queries a terminal emulator for its type, size and capabilities
|
|
5
|
+
Project-URL: Homepage, https://github.com/jquast/ttyscan
|
|
6
|
+
Author-email: Jeff Quast <contact@jeffquast.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Keywords: capability,colorterm,console,curses,query,serial,setupterm,ssh,telnet,terminal,terminfo,tty,xtgettcap
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Operating System :: POSIX
|
|
15
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
24
|
+
Classifier: Topic :: Terminals
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Description-Content-Type: text/x-rst
|
|
27
|
+
|
|
28
|
+
| |pypi_downloads| |codecov| |windows| |linux| |mac| |bsd|
|
|
29
|
+
|
|
30
|
+
ttyscan
|
|
31
|
+
=======
|
|
32
|
+
|
|
33
|
+
*ttyscan* queries a terminal emulator for its type, size and capabilities, creating a
|
|
34
|
+
curses-compatible `terminfo(5)`_ file entry if necessary, and exports any corrected values of
|
|
35
|
+
``TERM``, ``COLORTERM``, ``LINES``, ``COLUMNS``, and optionally ``TERMCAP`` environment variables.
|
|
36
|
+
|
|
37
|
+
Problem
|
|
38
|
+
-------
|
|
39
|
+
|
|
40
|
+
ncurses_ does not support XTGETTCAP, and so `terminfo(5)`_ files for some terminals must be
|
|
41
|
+
deployed to remote systems by system operators in some circumstances.
|
|
42
|
+
|
|
43
|
+
Curses programs fail to start until those files are deployed or an alternate ``TERM`` is exported.
|
|
44
|
+
All kinds of errors and warnings may be raised until this is done, some examples::
|
|
45
|
+
|
|
46
|
+
$ tmux attach
|
|
47
|
+
missing or unsuitable terminal: xterm-kitty
|
|
48
|
+
|
|
49
|
+
$ irssi
|
|
50
|
+
setupterm() failed for TERM=xterm-kitty: 0
|
|
51
|
+
Can't initialize screen handling.
|
|
52
|
+
|
|
53
|
+
$ htop
|
|
54
|
+
Error opening terminal: xterm-kitty.
|
|
55
|
+
|
|
56
|
+
$ python -c 'import curses;curses.setupterm()'
|
|
57
|
+
Traceback (most recent call last):
|
|
58
|
+
File "<string>", line 1, in <module>
|
|
59
|
+
_curses.error: setupterm: could not find terminal
|
|
60
|
+
|
|
61
|
+
$ git log -p
|
|
62
|
+
WARNING: terminal is not fully functional
|
|
63
|
+
Press RETURN to continue
|
|
64
|
+
|
|
65
|
+
Solution
|
|
66
|
+
--------
|
|
67
|
+
|
|
68
|
+
*ttyscan* creates the missing `terminfo(5)` file using the ``XTGETTCAP`` (``DCS +q``) terminal query
|
|
69
|
+
protocol when supported, and suggests a new ``TERMINFO`` environment value for export, allowing
|
|
70
|
+
legacy calls to curses of `setupterm(3)`_ to succeed::
|
|
71
|
+
|
|
72
|
+
$ ttyscan -vft
|
|
73
|
+
ttyscan: probing terminal via XTGETTCAP ...
|
|
74
|
+
ttyscan: size via dual CPR: 28x100
|
|
75
|
+
ttyscan: XTGETTCAP supported, terminal: rio; received 204 caps (10 bool, 5 num, 185 str) in 1523ms
|
|
76
|
+
ttyscan: writing /home/jq/.config/ttyscan/terminfo/r/rio
|
|
77
|
+
export COLORTERM=truecolor
|
|
78
|
+
export TERM=rio
|
|
79
|
+
export LINES=28
|
|
80
|
+
export COLUMNS=100
|
|
81
|
+
export TERMINFO=/home/jq/.config/ttyscan/terminfo
|
|
82
|
+
export TERMCAP='rio|XTGETTCAP-discovered terminal::am::ut::hs::km::5i::mi::ms::NP::xn::Co#256::co#80::it#8::li#24::pa#32767::ac=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~::bl=^G::mb=\E[5m::md=\E[1m::vi=\E[?25l::cl=\E[H\E[2J::ve=\E[?12l\E[?25h::cr=\r::cs=\E[%i%p1%d;%p2%dr::le=\b::DO=\E[%p1%dB::do=\n::nd=\E[C::cm=\E[%i%p1%d;%p2%dH::up=\E[A::vs=\E[?12;25h::dC=\E[P::mh=\E[2m::dl=\E[M::ds=\E]2;^G::ec=\E[%p1%dX::cd=\E[J::ce=\E[K::cb=\E[1K::vb=\E[?5h$<100/>\E[?5l::fs=^G::ho=\E[H::ch=\E[%i%p1%dG::ta=\t::st=\EH::al=\E[L::sf=\n::mk=\E[8m::is=\E[!p\E[?3;4l\E[4l\E>::K2=\EOE::kb=^?::kB=\E[Z::kl=\EOD::kd=\EOB::kr=\EOC::ku=\EOA::kD=\E[3~::@7=\EOF::@8=\EOM::k1=\EOP::k0=\E[21~::F1=\E[23~::F2=\E[24~::k2=\EOQ::k3=\EOR::k4=\EOS::k5=\E[15~::k6=\E[17~::k7=\E[18~::k8=\E[19~::k9=\E[20~::kh=\EOH::kI=\E[2~::kH=\E[1;2B::kN=\E[6~::kP=\E[5~::op=\E[39;49m::rp=%p1%c\E[%p2%{1}%-%db::mr=\E[7m::sr=\EM::ZR=\E[23m::ae=\E(B::te=\E[?1049l\E[23;0;0t::ei=\E[4l::ke=\E[?1l\E>::se=\E[27m::ue=\E[24m::r1=\Ec\E]104^G::r2=\E[!p\E[?3;4l\E[4l\E>::sa=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m::me=\E(B\E[m::ZH=\E[3m::as=\E(0::ti=\E[?1049h\E[22;0;0t::im=\E[4h::ks=\E[?1h\E=::so=\E[7m::us=\E[4m::ct=\E[3g::ts=\E]2;::cv=\E[%i%p1%dd:'
|
|
83
|
+
|
|
84
|
+
$ eval `ttyscan`
|
|
85
|
+
|
|
86
|
+
$ echo $TERM, $TERMINFO
|
|
87
|
+
rio, /home/jquast/.config/ttyscan/terminfo
|
|
88
|
+
|
|
89
|
+
$ file -b /home/jquast/.config/ttyscan/terminfo/r/rio
|
|
90
|
+
Compiled terminfo entry "rio"
|
|
91
|
+
|
|
92
|
+
$ python -c 'import curses;curses.setupterm()'; echo $?
|
|
93
|
+
0
|
|
94
|
+
|
|
95
|
+
CLI Arguments
|
|
96
|
+
-------------
|
|
97
|
+
|
|
98
|
+
::
|
|
99
|
+
|
|
100
|
+
usage: ttyscan [-h] [-v] [-f] [-t]
|
|
101
|
+
|
|
102
|
+
Export terminal capabilities discovered via XTGETTCAP
|
|
103
|
+
|
|
104
|
+
options:
|
|
105
|
+
-h, --help show this help message and exit
|
|
106
|
+
-v, --verbose Print diagnostic information to stderr
|
|
107
|
+
-f, --force Force export of all values even if unchanged
|
|
108
|
+
-t, --termcap Also export TERMCAP value
|
|
109
|
+
|
|
110
|
+
*ttyscan* saves a `terminfo(5)`_ file to $XDG_CONFIG_HOME/ttyscan/terminfo or
|
|
111
|
+
~/.config/ttyscan/terminfo, and does not re-query or re-create it when it already exists from
|
|
112
|
+
previous executions, unless ``--force`` argument is used.
|
|
113
|
+
|
|
114
|
+
Typical total execution time is 200ms. The default timeout query can be changed by environment
|
|
115
|
+
value TTYSCAN_QUERY_TIMEOUT=1.0 (float), in seconds. If timeout is reached, terminal response may
|
|
116
|
+
"bleed" into subsequent programs, (like a shell prompt).
|
|
117
|
+
|
|
118
|
+
Installation
|
|
119
|
+
------------
|
|
120
|
+
|
|
121
|
+
.. code-block:: shell
|
|
122
|
+
|
|
123
|
+
pip install ttyscan
|
|
124
|
+
|
|
125
|
+
*ttyscan* requires Python3.8+.
|
|
126
|
+
|
|
127
|
+
ttyscan.py_ is a stand-alone python file, it does not require pip to install, you can copy this
|
|
128
|
+
single file directly from source and execute it from source, eg. ``python ~/bin/ttyscan.py``
|
|
129
|
+
|
|
130
|
+
Motive
|
|
131
|
+
------
|
|
132
|
+
|
|
133
|
+
Naturally, transferring your ``$HOME/.terminfo`` folder to a remote machine is the best solution.
|
|
134
|
+
|
|
135
|
+
However, enterprise systems, bastion hosts, cloud systems, web consoles, hypervisors, radio, and
|
|
136
|
+
serial ports can be challenging places or protocol layers through which to deploy terminfo files.
|
|
137
|
+
|
|
138
|
+
Some workarounds include exporting a generally-compatible ``TERM=xterm-256color`` or ``xterm`` with
|
|
139
|
+
sometimes minor corruption of screen output, missed interpretation of keyboard input such as
|
|
140
|
+
backspace or delete, or a small reduction of features such as italic or underlined text or number of
|
|
141
|
+
colors.
|
|
142
|
+
|
|
143
|
+
**And so this tool is not often needed** except for the **very serious** terminal connoisseur.
|
|
144
|
+
|
|
145
|
+
It serves as a demonstration: that a full terminal capability database *can* be transferred using
|
|
146
|
+
XTGETTCAP_ for many modern terminals, supporting modern `terminfo(5)`_ and legacy `termcap(5)`_. It
|
|
147
|
+
|
|
148
|
+
My hope is that `setupterm(3)`_ may negotiate with full XTGETTCAP_ support at some point in the
|
|
149
|
+
future, and that this utility is not commonly used or required!
|
|
150
|
+
|
|
151
|
+
Scope
|
|
152
|
+
-----
|
|
153
|
+
|
|
154
|
+
At time of this writing (May 2026), the ucs-detect_ dataset of 42 terminals shows three categories
|
|
155
|
+
of support for ``XTGETTCAP``:
|
|
156
|
+
|
|
157
|
+
- **Full** ``XTGETTCAP`` capability support: contour_, foot_, ghostty_, kitty_, rio, and wezterm
|
|
158
|
+
transmit their complete terminfo boolean, numeric, and string capabilities via XTGETTCAP_.
|
|
159
|
+
|
|
160
|
+
*ttyscan* produces terminfo files for only these terminals. *ttyscan* may also discover a
|
|
161
|
+
preferred ``TERM`` from ``TN``, and ``COLORTERM=truecolor`` from ``RGB``.
|
|
162
|
+
|
|
163
|
+
- **Partial** ``XTGETTCAP`` capability support: XTerm_, iterm2, mlterm, AbsoluteTelnet/SSH, GNOME
|
|
164
|
+
Terminal, LXTerminal, terminator, termit, and xfce4-terminal report only ``TN``, ``Co``, and
|
|
165
|
+
``RGB``.
|
|
166
|
+
|
|
167
|
+
*ttyscan* may only discover preferred ``TERM`` from ``TN``, and ``COLORTERM=truecolor`` from
|
|
168
|
+
``RGB``.
|
|
169
|
+
|
|
170
|
+
XTerm_ supports only keyboard sequences in addition to ``TN``, ``Co``, and ``RGB``. It does not
|
|
171
|
+
report *all* capabilities, and so a `terminfo(5)`_ entry cannot be built. However,
|
|
172
|
+
``TERM=xterm-256color`` and ``TERM=xterm`` are the most ubiquitous terminal name, you should be
|
|
173
|
+
just fine.
|
|
174
|
+
|
|
175
|
+
- **None**: alacritty (refuses: `alacritty/vte#98`_), bobcat, cmd.exe, ConEmu, cool-retro-term,
|
|
176
|
+
Extraterm, Hyper, Konsole (requested: `KDE#507017`_), linux fbdev, mintty, PuTTY, QTerminal,
|
|
177
|
+
rxvt-unicode, screen, securecrt, st, Tabby, Apple Terminal, Terminal.exe (planned:
|
|
178
|
+
`microsoft/terminal#17735`_), terminology, tmux (passthrough: `tmux/tmux#3755`_), libvterm, VS
|
|
179
|
+
Code (xterm.js, proposal: `xtermjs/xterm.js#4107`_), weston-terminal, and zutty.
|
|
180
|
+
|
|
181
|
+
Architecture
|
|
182
|
+
------------
|
|
183
|
+
|
|
184
|
+
*ttyscan* uses the following,
|
|
185
|
+
|
|
186
|
+
- ``XTGETTCAP`` field ``TN`` is used to correct ``TERM`` when unmatched.
|
|
187
|
+
- ``XTGETTCAP`` field ``RGB`` is used to correct ``COLORTERM`` when unmatched.
|
|
188
|
+
- all capability strings, keyboard and screen, when provided by ``XTGETTCAP``.
|
|
189
|
+
- DEC Private Mode 2048 (In-Band Resize) to determine the window size
|
|
190
|
+
- Or failing that, using Cursor Position Report sequence like done in XTerm's `resize.c
|
|
191
|
+
<https://github.com/joejulian/xterm/blob/master/resize.c>`_
|
|
192
|
+
|
|
193
|
+
Details
|
|
194
|
+
-------
|
|
195
|
+
|
|
196
|
+
The difference of *Full* and *Partial* ``XTGETTCAP`` support is best described by foot_:
|
|
197
|
+
|
|
198
|
+
``XTGETTCAP`` is an escape sequence initially introduced by XTerm_, and also implemented (and extended,
|
|
199
|
+
to some degree) by Kitty.
|
|
200
|
+
|
|
201
|
+
Applications using this feature do not need to use the classic, file-based, terminfo definition.
|
|
202
|
+
|
|
203
|
+
XTerm's implementation (as of XTerm-370) only supports querying key (as in keyboard keys)
|
|
204
|
+
capabilities, and three custom capabilities:
|
|
205
|
+
|
|
206
|
+
``TN`` - terminal name
|
|
207
|
+
``Co`` - number of colors (alias for the colors capability)
|
|
208
|
+
``RGB`` - number of bits per color channel (different semantics from the RGB capability in file-based
|
|
209
|
+
terminfo definitions!).
|
|
210
|
+
|
|
211
|
+
Kitty has extended this, and also supports querying all integer and string capabilities.
|
|
212
|
+
|
|
213
|
+
Foot supports this, and extends it even further, to also include boolean capabilities.
|
|
214
|
+
This means foot's entire terminfo can be queried via ``XTGETTCAP``.
|
|
215
|
+
|
|
216
|
+
Further, all of ``TERM``, ``COLORTERM``, ``LINES``, or ``COLUMNS`` may not be transmitted by all
|
|
217
|
+
software or protocols, some examples:
|
|
218
|
+
|
|
219
|
+
- ssh does not forward ``COLORTERM`` unless configured using ``SendEnv`` in `ssh_config(5)`_ and
|
|
220
|
+
``AcceptEnv`` in `sshd_config(5)`_.
|
|
221
|
+
- serial does not forward any; ``TERM`` is defined by host `agetty(8)`_ configuration, for example.
|
|
222
|
+
- rlogin can forward all but ``COLORTERM``.
|
|
223
|
+
- telnet can forward all, but IAC NAWS and NEW-ENVIRON capability varies by software.
|
|
224
|
+
- websocket cannot forward any without customization, often used in-browser.
|
|
225
|
+
|
|
226
|
+
*ttyscan* detects when these variables are unset or do not match values and re-exports the corrected
|
|
227
|
+
values when they differ.
|
|
228
|
+
|
|
229
|
+
.. _`agetty(8)`: https://linux.die.net/man/8/agetty
|
|
230
|
+
.. _`alacritty/vte#98`: https://github.com/alacritty/vte/issues/98
|
|
231
|
+
.. _contour: https://github.com/contour-terminal/contour
|
|
232
|
+
.. _foot: https://codeberg.org/dnkl/foot#xtgettcap
|
|
233
|
+
.. _ghostty: https://mitchellh.com/writing/ghostty-devlog-004
|
|
234
|
+
.. _`KDE#507017`: https://bugs.kde.org/show_bug.cgi?id=507017
|
|
235
|
+
.. _kitty: https://sw.kovidgoyal.net/kitty/kittens/query_terminal/
|
|
236
|
+
.. _`microsoft/terminal#17735`: https://github.com/microsoft/terminal/issues/17735
|
|
237
|
+
.. _ncurses: https://invisible-island.net/ncurses/
|
|
238
|
+
.. _`setupterm(3)`: https://linux.die.net/man/3/setupterm
|
|
239
|
+
.. _`ssh_config(5)`: https://linux.die.net/man/5/ssh_config
|
|
240
|
+
.. _`sshd_config(5)`: https://linux.die.net/man/5/sshd_config
|
|
241
|
+
.. _`termcap(5)`: https://linux.die.net/man/5/termcap
|
|
242
|
+
.. _`terminfo(5)`: https://linux.die.net/man/5/terminfo
|
|
243
|
+
.. _`tmux/tmux#3755`: https://github.com/tmux/tmux/issues/3755
|
|
244
|
+
.. _`ttyscan.py`: https://github.com/jquast/ttyscan/blob/master/ttyscan.py
|
|
245
|
+
.. _ucs-detect: https://ucs-detect.readthedocs.io/results.html#terminal-capabilities
|
|
246
|
+
.. _XTerm: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Device-Control-functions:DCS-plus-q-Pt-ST.F95
|
|
247
|
+
.. _`xtermjs/xterm.js#4107`: https://github.com/xtermjs/xterm.js/issues/4107
|
|
248
|
+
.. _XTGETTCAP: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h4-Device-Control-functions:DCS-plus-q-Pt-ST.F95
|
|
249
|
+
|
|
250
|
+
.. |pypi_downloads| image:: https://img.shields.io/pypi/dm/ttyscan.svg?logo=pypi
|
|
251
|
+
:alt: Downloads
|
|
252
|
+
:target: https://pypi.org/project/ttyscan/
|
|
253
|
+
.. |codecov| image:: https://codecov.io/gh/jquast/ttyscan/branch/master/graph/badge.svg
|
|
254
|
+
:alt: codecov.io Code Coverage
|
|
255
|
+
:target: https://codecov.io/gh/jquast/ttyscan/
|
|
256
|
+
.. |linux| image:: https://img.shields.io/badge/Linux-yes-success?logo=linux
|
|
257
|
+
:alt: Linux supported
|
|
258
|
+
.. |windows| image:: https://img.shields.io/badge/Windows-yes-success?logo=windows
|
|
259
|
+
:alt: Windows supported
|
|
260
|
+
.. |mac| image:: https://img.shields.io/badge/MacOS-yes-success?logo=apple
|
|
261
|
+
:alt: MacOS supported
|
|
262
|
+
.. |bsd| image:: https://img.shields.io/badge/BSD-yes-success?logo=freebsd
|
|
263
|
+
:alt: BSD supported
|