mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-21 16:05:02 +02:00
Clean up previous PR
This commit is contained in:
@@ -226,9 +226,7 @@ extern bool init_mouse(PyObject *module);
|
|||||||
extern bool init_kittens(PyObject *module);
|
extern bool init_kittens(PyObject *module);
|
||||||
extern bool init_logging(PyObject *module);
|
extern bool init_logging(PyObject *module);
|
||||||
extern bool init_png_reader(PyObject *module);
|
extern bool init_png_reader(PyObject *module);
|
||||||
#ifdef __unix__
|
|
||||||
extern bool init_utmp(PyObject *module);
|
extern bool init_utmp(PyObject *module);
|
||||||
#endif
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
extern int init_CoreText(PyObject *);
|
extern int init_CoreText(PyObject *);
|
||||||
extern bool init_cocoa(PyObject *module);
|
extern bool init_cocoa(PyObject *module);
|
||||||
@@ -296,9 +294,7 @@ PyInit_fast_data_types(void) {
|
|||||||
if (!init_freetype_render_ui_text(m)) return NULL;
|
if (!init_freetype_render_ui_text(m)) return NULL;
|
||||||
#endif
|
#endif
|
||||||
if (!init_fonts(m)) return NULL;
|
if (!init_fonts(m)) return NULL;
|
||||||
#if defined(__unix__)
|
|
||||||
if (!init_utmp(m)) return NULL;
|
if (!init_utmp(m)) return NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
CellAttrs a;
|
CellAttrs a;
|
||||||
#define s(name, attr) { a.val = 0; a.attr = 1; PyModule_AddIntConstant(m, #name, shift_to_first_set_bit(a)); }
|
#define s(name, attr) { a.val = 0; a.attr = 1; PyModule_AddIntConstant(m, #name, shift_to_first_set_bit(a)); }
|
||||||
|
|||||||
@@ -3,10 +3,16 @@
|
|||||||
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
import termios
|
||||||
|
import time
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from typing import Callable, Dict, Generator, Iterable, Set, Tuple
|
from typing import (
|
||||||
|
IO, Callable, Dict, Generator, Iterable, Optional, Set, Tuple
|
||||||
|
)
|
||||||
|
|
||||||
from kittens.tui.operations import colored, styled
|
from kittens.tui.operations import colored, styled
|
||||||
|
|
||||||
@@ -15,6 +21,7 @@ from .conf.utils import KeyAction
|
|||||||
from .constants import (
|
from .constants import (
|
||||||
extensions_dir, is_macos, is_wayland, kitty_base_dir, kitty_exe, shell_path
|
extensions_dir, is_macos, is_wayland, kitty_base_dir, kitty_exe, shell_path
|
||||||
)
|
)
|
||||||
|
from .fast_data_types import num_users
|
||||||
from .options.types import Options as KittyOpts, defaults
|
from .options.types import Options as KittyOpts, defaults
|
||||||
from .options.utils import MouseMap
|
from .options.utils import MouseMap
|
||||||
from .rgb import Color, color_as_sharp
|
from .rgb import Color, color_as_sharp
|
||||||
@@ -152,84 +159,58 @@ def compare_opts(opts: KittyOpts, print: Callable) -> None:
|
|||||||
print('\n\t'.join(sorted(colors)))
|
print('\n\t'.join(sorted(colors)))
|
||||||
|
|
||||||
|
|
||||||
is_linux = sys.platform in ('linux', 'linux2')
|
class IssueData:
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
if is_linux:
|
self.uname = os.uname()
|
||||||
import socket
|
self.s, self.n, self.r, self.v, self.m = self.uname
|
||||||
import time
|
self.hostname = self.o = socket.gethostname()
|
||||||
import re
|
_time = time.localtime()
|
||||||
import termios
|
self.formatted_time = self.d = time.strftime('%a %b %d %Y', _time)
|
||||||
from .fast_data_types import num_users
|
self.formatted_date = self.t = time.strftime('%H:%M:%S', _time)
|
||||||
from typing import IO
|
|
||||||
|
|
||||||
|
|
||||||
class IssueData:
|
|
||||||
uname: os.uname_result
|
|
||||||
hostname: str
|
|
||||||
formatted_date: str
|
|
||||||
formatted_time: str
|
|
||||||
tty_name: str
|
|
||||||
baud_rate: int
|
|
||||||
num_users: int
|
|
||||||
def __init__(self):
|
|
||||||
self.uname = os.uname()
|
|
||||||
self.hostname = socket.gethostname()
|
|
||||||
_time = time.localtime()
|
|
||||||
self.formatted_time = time.strftime('%a %b %d %Y', _time)
|
|
||||||
self.formatted_date = time.strftime('%H:%M:%S', _time)
|
|
||||||
try:
|
|
||||||
self.tty_name = format_tty_name(os.ttyname(sys.stdin.fileno()))
|
|
||||||
except OSError:
|
|
||||||
self.tty_name = '(none)'
|
|
||||||
self.baud_rate = termios.tcgetattr(sys.stdin.fileno())[5]
|
|
||||||
self.num_users = num_users()
|
|
||||||
|
|
||||||
|
|
||||||
# https://kernel.googlesource.com/pub/scm/utils/util-linux/util-linux/+/v2.7.1/login-utils/agetty.c#790
|
|
||||||
issue_mappings = {
|
|
||||||
# ctx = IssueData
|
|
||||||
's': lambda ctx: ctx.uname.sysname,
|
|
||||||
'n': lambda ctx: ctx.uname.nodename,
|
|
||||||
'r': lambda ctx: ctx.uname.release,
|
|
||||||
'v': lambda ctx: ctx.uname.version,
|
|
||||||
'm': lambda ctx: ctx.uname.machine,
|
|
||||||
'o': lambda ctx: ctx.hostname,
|
|
||||||
'd': lambda ctx: ctx.formatted_date,
|
|
||||||
't': lambda ctx: ctx.formatted_time,
|
|
||||||
'l': lambda ctx: ctx.tty_name,
|
|
||||||
'b': lambda ctx: ctx.baud_rate,
|
|
||||||
'u': lambda ctx: ctx.num_users,
|
|
||||||
'U': lambda ctx: str(ctx.num_users) + ' user' + ('' if ctx.num_users == 1 else 's'),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def translate_issue_char(ctx: IssueData, char: str) -> str:
|
|
||||||
assert len(char) == 1
|
|
||||||
try:
|
try:
|
||||||
return issue_mappings[char](ctx)
|
self.tty_name = format_tty_name(os.ttyname(sys.stdin.fileno()))
|
||||||
except KeyError:
|
except OSError:
|
||||||
return char
|
self.tty_name = '(none)'
|
||||||
|
self.l = self.tty_name # noqa
|
||||||
|
self.baud_rate = termios.tcgetattr(sys.stdin.fileno())[5]
|
||||||
|
self.b = str(self.baud_rate)
|
||||||
|
try:
|
||||||
|
self.num_users = num_users()
|
||||||
|
except RuntimeError:
|
||||||
|
self.num_users = -1
|
||||||
|
self.u = str(self.num_users)
|
||||||
|
self.U = self.u + ' user' + ('' if self.num_users == 1 else 's')
|
||||||
|
|
||||||
|
|
||||||
def format_tty_name(raw: str) -> str:
|
def translate_issue_char(ctx: IssueData, char: str) -> str:
|
||||||
return re.sub(r'^/dev/([^/]+)/([^/]+)$', r'\1\2', raw)
|
try:
|
||||||
|
return str(getattr(ctx, char)) if len(char) == 1 else char
|
||||||
|
except AttributeError:
|
||||||
|
return char
|
||||||
|
|
||||||
|
|
||||||
def print_issue(issue_file: IO[str], print_fn) -> None:
|
def format_tty_name(raw: str) -> str:
|
||||||
last_char = None
|
return re.sub(r'^/dev/([^/]+)/([^/]+)$', r'\1\2', raw)
|
||||||
issue_data = IssueData()
|
|
||||||
while this_char := issue_file.read(1):
|
|
||||||
if last_char == '\\':
|
def print_issue(issue_file: IO[str], print_fn: Callable) -> None:
|
||||||
print_fn(translate_issue_char(issue_data, this_char), end='')
|
last_char: Optional[str] = None
|
||||||
elif last_char is not None:
|
issue_data = IssueData()
|
||||||
print_fn(last_char, end='')
|
while True:
|
||||||
# `\\\a` should not match the last two slashes,
|
this_char = issue_file.read(1)
|
||||||
# so make it look like it was `\?\a` where `?`
|
if not this_char:
|
||||||
# is some character other than `\`.
|
break
|
||||||
last_char = None if last_char == '\\' else this_char
|
if last_char == '\\':
|
||||||
if last_char is not None:
|
print_fn(translate_issue_char(issue_data, this_char), end='')
|
||||||
|
elif last_char is not None:
|
||||||
print_fn(last_char, end='')
|
print_fn(last_char, end='')
|
||||||
|
# `\\\a` should not match the last two slashes,
|
||||||
|
# so make it look like it was `\?\a` where `?`
|
||||||
|
# is some character other than `\`.
|
||||||
|
last_char = None if last_char == '\\' else this_char
|
||||||
|
if last_char is not None:
|
||||||
|
print_fn(last_char, end='')
|
||||||
|
|
||||||
|
|
||||||
def debug_config(opts: KittyOpts) -> str:
|
def debug_config(opts: KittyOpts) -> str:
|
||||||
@@ -241,7 +222,7 @@ def debug_config(opts: KittyOpts) -> str:
|
|||||||
if is_macos:
|
if is_macos:
|
||||||
import subprocess
|
import subprocess
|
||||||
p(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip())
|
p(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip())
|
||||||
if is_linux and os.path.exists('/etc/issue'):
|
if os.path.exists('/etc/issue'):
|
||||||
with open('/etc/issue', encoding='utf-8', errors='replace') as f:
|
with open('/etc/issue', encoding='utf-8', errors='replace') as f:
|
||||||
print_issue(f, p)
|
print_issue(f, p)
|
||||||
if os.path.exists('/etc/lsb-release'):
|
if os.path.exists('/etc/lsb-release'):
|
||||||
|
|||||||
51
kitty/utmp.c
51
kitty/utmp.c
@@ -1,50 +1,35 @@
|
|||||||
#if defined(__unix__)
|
|
||||||
|
|
||||||
#define PY_SSIZE_T_CLEAN
|
#include "data-types.h"
|
||||||
#include <Python.h>
|
#ifdef __unix__
|
||||||
#include <stdbool.h>
|
#include <utmpx.h>
|
||||||
|
|
||||||
#include <utmp.h>
|
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
num_users(PyObject *const self, PyObject *const args) {
|
num_users(PyObject *const self UNUSED, PyObject *const args UNUSED) {
|
||||||
(void)self; (void)args;
|
|
||||||
size_t users = 0;
|
size_t users = 0;
|
||||||
|
struct utmpx *ut;
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
#ifdef UTENT_REENTRANT
|
setutxent();
|
||||||
struct utmp *result = NULL;
|
while ((ut = getutxent())) {
|
||||||
struct utmp buffer = { 0, };
|
if (ut->ut_type == USER_PROCESS) users++;
|
||||||
while (true) {
|
|
||||||
if (getutent_r(&buffer, &result) == -1) {
|
|
||||||
Py_BLOCK_THREADS
|
|
||||||
return PyErr_SetFromErrno(PyExc_OSError);
|
|
||||||
}
|
|
||||||
if (result == NULL) { break; }
|
|
||||||
if (result->ut_type == USER_PROCESS) { users++; }
|
|
||||||
}
|
}
|
||||||
#else
|
endutxent();
|
||||||
struct utmp *ut;
|
|
||||||
setutent();
|
|
||||||
while ((ut = getutent())) {
|
|
||||||
if (ut->ut_type == USER_PROCESS) {
|
|
||||||
users++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
endutent();
|
|
||||||
#endif
|
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
return PyLong_FromSize_t(users);
|
return PyLong_FromSize_t(users);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static PyObject*
|
||||||
|
num_users(PyObject *const self UNUSED, PyObject *const args UNUSED) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Counting the number of users is not supported");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static PyMethodDef UtmpMethods[] = {
|
static PyMethodDef methods[] = {
|
||||||
{"num_users", num_users, METH_NOARGS, "Get the number of users using UTMP data" },
|
{"num_users", num_users, METH_NOARGS, "Get the number of users using UTMP data" },
|
||||||
{ NULL, NULL, 0, NULL },
|
{ NULL, NULL, 0, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
init_utmp(PyObject *module) {
|
init_utmp(PyObject *module) {
|
||||||
// 0 = success
|
return PyModule_AddFunctions(module, methods) == 0;
|
||||||
return PyModule_AddFunctions(module, UtmpMethods) == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
Reference in New Issue
Block a user