1# encoding: utf-8
2"""
3Utilities for working with terminals.
4
5Authors:
6
7* Brian E. Granger
8* Fernando Perez
9* Alexander Belchenko (e-mail: bialix AT ukr.net)
10"""
11
12# Copyright (c) IPython Development Team.
13# Distributed under the terms of the Modified BSD License.
14
15import os
16import sys
17import warnings
18from shutil import get_terminal_size as _get_terminal_size
19
20# This variable is part of the expected API of the module:
21ignore_termtitle = True
22
23
24
25if os.name == 'posix':
26 def _term_clear():
27 os.system('clear')
28elif sys.platform == 'win32':
29 def _term_clear():
30 os.system('cls')
31else:
32 def _term_clear():
33 pass
34
35
36
37def toggle_set_term_title(val):
38 """Control whether set_term_title is active or not.
39
40 set_term_title() allows writing to the console titlebar. In embedded
41 widgets this can cause problems, so this call can be used to toggle it on
42 or off as needed.
43
44 The default state of the module is for the function to be disabled.
45
46 Parameters
47 ----------
48 val : bool
49 If True, set_term_title() actually writes to the terminal (using the
50 appropriate platform-specific module). If False, it is a no-op.
51 """
52 global ignore_termtitle
53 ignore_termtitle = not(val)
54
55
56def _set_term_title(*args,**kw):
57 """Dummy no-op."""
58 pass
59
60
61def _restore_term_title():
62 pass
63
64
65_xterm_term_title_saved = False
66
67
68def _set_term_title_xterm(title):
69 """ Change virtual terminal title in xterm-workalikes """
70 global _xterm_term_title_saved
71 # Only save the title the first time we set, otherwise restore will only
72 # go back one title (probably undoing a %cd title change).
73 if not _xterm_term_title_saved:
74 # save the current title to the xterm "stack"
75 sys.stdout.write("\033[22;0t")
76 _xterm_term_title_saved = True
77 sys.stdout.write('\033]0;%s\007' % title)
78
79
80def _restore_term_title_xterm():
81 # Make sure the restore has at least one accompanying set.
82 global _xterm_term_title_saved
83 if not _xterm_term_title_saved:
84 warnings.warn(
85 "Expecting xterm_term_title_saved to be True, but is not; will not restore terminal title.",
86 stacklevel=1,
87 )
88 return
89
90 sys.stdout.write('\033[23;0t')
91 _xterm_term_title_saved = False
92
93
94if os.name == 'posix':
95 TERM = os.environ.get('TERM','')
96 if TERM.startswith('xterm'):
97 _set_term_title = _set_term_title_xterm
98 _restore_term_title = _restore_term_title_xterm
99elif sys.platform == 'win32':
100 import ctypes
101
102 SetConsoleTitleW = ctypes.windll.kernel32.SetConsoleTitleW
103 SetConsoleTitleW.argtypes = [ctypes.c_wchar_p]
104
105 def _set_term_title(title):
106 """Set terminal title using ctypes to access the Win32 APIs."""
107 SetConsoleTitleW(title)
108
109
110def set_term_title(title):
111 """Set terminal title using the necessary platform-dependent calls."""
112 if ignore_termtitle:
113 return
114 _set_term_title(title)
115
116
117def restore_term_title():
118 """Restore, if possible, terminal title to the original state"""
119 if ignore_termtitle:
120 return
121 _restore_term_title()
122
123
124def get_terminal_size(defaultx: int = 80, defaulty: int = 25) -> tuple[int, int]:
125 return _get_terminal_size((defaultx, defaulty))