mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-15 13:07:52 +02:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0923d6ecee | ||
|
|
defda41861 | ||
|
|
66c51798b8 | ||
|
|
ff966f667c | ||
|
|
96be8dcb2c | ||
|
|
892d3df6eb | ||
|
|
54e79a6901 | ||
|
|
7d0c05e20d | ||
|
|
421ae6d289 | ||
|
|
3af501b715 | ||
|
|
c73d6913da | ||
|
|
f7cb3e3f9e |
@@ -196,12 +196,15 @@ class Selection: # {{{
|
||||
if y == b[0]:
|
||||
endx = max(0, min(b[1], endx))
|
||||
l = line(y)
|
||||
is_continued = l.is_continued()
|
||||
if endx - startx >= linebuf.xnum - 1:
|
||||
l = str(l).rstrip(' ')
|
||||
else:
|
||||
l = ''.join(l[x] for x in range(startx, endx + 1))
|
||||
if not is_continued and startx == 0 and len(lines) > 0:
|
||||
l = '\n' + l
|
||||
lines.append(l)
|
||||
return '\n'.join(lines)
|
||||
return ''.join(lines)
|
||||
# }}}
|
||||
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ type_map = {
|
||||
'window_border_width': float,
|
||||
'wheel_scroll_multiplier': float,
|
||||
'visual_bell_duration': float,
|
||||
'enable_audio_bell': to_bool,
|
||||
'click_interval': float,
|
||||
'mouse_hide_wait': float,
|
||||
'cursor_blink_interval': float,
|
||||
|
||||
@@ -15,7 +15,7 @@ from .fast_data_types import (
|
||||
GLFW_KEY_LEFT_SUPER, GLFW_KEY_RIGHT_SUPER)
|
||||
|
||||
appname = 'kitty'
|
||||
version = (0, 2, 0)
|
||||
version = (0, 2, 1)
|
||||
str_version = '.'.join(map(str, version))
|
||||
_plat = sys.platform.lower()
|
||||
isosx = 'darwin' in _plat
|
||||
|
||||
10
kitty/gl.h
10
kitty/gl.h
@@ -141,10 +141,14 @@ _glewInit(PyObject UNUSED *self) {
|
||||
PyErr_Format(PyExc_RuntimeError, "GLEW init failed: %s", glewGetErrorString(err));
|
||||
return NULL;
|
||||
}
|
||||
if(!GLEW_ARB_texture_storage) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "OpenGL is missing the required ARB_texture_storage extension");
|
||||
return NULL;
|
||||
#define ARB_TEST(name) \
|
||||
if (!GLEW_ARB_##name) { \
|
||||
PyErr_Format(PyExc_RuntimeError, "The OpenGL driver on this system is missing the required extension: ARB_%s", #name); \
|
||||
return NULL; \
|
||||
}
|
||||
ARB_TEST(texture_storage);
|
||||
ARB_TEST(texture_buffer_object_rgb32);
|
||||
#undef ARB_TEST
|
||||
#endif
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
@@ -50,12 +50,6 @@ def rkey(name, a, b):
|
||||
return bytearray(key_as_bytes(name).replace(a, b))
|
||||
|
||||
|
||||
control_codes[defines.GLFW_KEY_UP] = rkey('cuu1', b'[', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_DOWN] = rkey('cud1', b'[', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_LEFT] = rkey('cub1', b'[', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_RIGHT] = rkey('cuf1', b'[', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_HOME] = rkey('khome', b'O', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_END] = rkey('kend', b'O', b'[1;5')
|
||||
control_codes[defines.GLFW_KEY_PAGE_UP] = rkey('kpp', b'~', b';5~')
|
||||
control_codes[defines.GLFW_KEY_PAGE_DOWN] = rkey('knp', b'~', b';5~')
|
||||
control_codes[defines.GLFW_KEY_DELETE] = rkey('kdch1', b'~', b';5~')
|
||||
@@ -75,6 +69,10 @@ rmkx_key_map.update({
|
||||
defines.GLFW_KEY_HOME: b'\033[H',
|
||||
defines.GLFW_KEY_END: b'\033[F',
|
||||
})
|
||||
for sk in 'UP DOWN LEFT RIGHT HOME END'.split():
|
||||
sk = getattr(defines, 'GLFW_KEY_' + sk)
|
||||
control_codes[sk] = rmkx_key_map[sk].replace(b'[', b'[1;5')
|
||||
|
||||
cursor_key_mode_map = {True: smkx_key_map, False: rmkx_key_map}
|
||||
|
||||
|
||||
|
||||
@@ -91,6 +91,9 @@ repaint_delay 10
|
||||
# seconds. Set to zero to disable.
|
||||
visual_bell_duration 0.0
|
||||
|
||||
# Enable/disable the audio bell. Useful in environments that require silence.
|
||||
enable_audio_bell yes
|
||||
|
||||
# The modifier keys to press when clicking with the mouse on URLs to open the URL
|
||||
open_url_modifiers ctrl+shift
|
||||
|
||||
|
||||
18
kitty/line.c
18
kitty/line.c
@@ -200,6 +200,14 @@ as_ansi(Line* self) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
is_continued(Line* self) {
|
||||
#define is_continued_doc "Return the line's continued flag"
|
||||
PyObject *ans = self->continued ? Py_True : Py_False;
|
||||
Py_INCREF(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
__repr__(Line* self) {
|
||||
PyObject *s = as_unicode(self);
|
||||
@@ -305,7 +313,8 @@ cursor_from(Line* self, PyObject *args) {
|
||||
return (PyObject*)ans;
|
||||
}
|
||||
|
||||
void line_clear_text(Line *self, unsigned int at, unsigned int num, int ch) {
|
||||
void
|
||||
line_clear_text(Line *self, unsigned int at, unsigned int num, int ch) {
|
||||
const char_type repl = ((char_type)ch & CHAR_MASK) | (1 << ATTRS_SHIFT);
|
||||
for (index_type i = at; i < MIN(self->xnum, at + num); i++) {
|
||||
self->chars[i] = (self->chars[i] & ATTRS_MASK_WITHOUT_WIDTH) | repl;
|
||||
@@ -323,7 +332,8 @@ clear_text(Line* self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char) {
|
||||
void
|
||||
line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char) {
|
||||
char_type attrs = CURSOR_TO_ATTRS(cursor, 1);
|
||||
color_type col = (cursor->fg & COL_MASK) | ((color_type)(cursor->bg & COL_MASK) << COL_SHIFT);
|
||||
decoration_type dfg = cursor->decoration_fg & COL_MASK;
|
||||
@@ -390,7 +400,8 @@ left_shift(Line *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
void line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor) {
|
||||
void
|
||||
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor) {
|
||||
char_type attrs;
|
||||
if (cursor == NULL) {
|
||||
attrs = (((self->chars[at] >> ATTRS_SHIFT) & ~3) | (width & 3)) << ATTRS_SHIFT;
|
||||
@@ -470,6 +481,7 @@ static PyMethodDef methods[] = {
|
||||
METHOD(set_attribute, METH_VARARGS)
|
||||
METHOD(as_base_text, METH_NOARGS)
|
||||
METHOD(as_ansi, METH_NOARGS)
|
||||
METHOD(is_continued, METH_NOARGS)
|
||||
METHOD(width, METH_O)
|
||||
METHOD(basic_cell_data, METH_O)
|
||||
|
||||
|
||||
@@ -98,6 +98,14 @@ def option_parser():
|
||||
default=None,
|
||||
help=_('Replay previously dumped commands')
|
||||
)
|
||||
a(
|
||||
'--debug-gl',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=_('Debug OpenGL commands. This will cause all OpenGL calls'
|
||||
' to check for errors instead of ignoring them. Useful'
|
||||
' when debugging rendering problems.')
|
||||
)
|
||||
a(
|
||||
'--window-layout',
|
||||
default=None,
|
||||
@@ -226,7 +234,7 @@ def main():
|
||||
opts = load_config(*config, overrides=overrides)
|
||||
change_wcwidth(not opts.use_system_wcwidth)
|
||||
glfw_set_error_callback(on_glfw_error)
|
||||
enable_automatic_opengl_error_checking(False)
|
||||
enable_automatic_opengl_error_checking(args.debug_gl)
|
||||
if not glfw_init():
|
||||
raise SystemExit('GLFW initialization failed')
|
||||
try:
|
||||
|
||||
@@ -157,6 +157,7 @@ class Sprites:
|
||||
return glGenBuffers(1)
|
||||
|
||||
def set_sprite_map(self, buf_id, data, usage=GL_STREAM_DRAW):
|
||||
self.bind_sprite_map(buf_id)
|
||||
glNamedBufferData(buf_id, sizeof(data), addressof(data), usage)
|
||||
|
||||
def bind_sprite_map(self, buf_id):
|
||||
|
||||
@@ -108,11 +108,12 @@ class Window:
|
||||
wakeup()
|
||||
|
||||
def bell(self):
|
||||
try:
|
||||
with open('/dev/tty', 'wb') as f:
|
||||
f.write(b'\007')
|
||||
except EnvironmentError:
|
||||
pass # failure to beep is not critical
|
||||
if self.opts.enable_audio_bell:
|
||||
try:
|
||||
with open('/dev/tty', 'wb') as f:
|
||||
f.write(b'\007')
|
||||
except EnvironmentError:
|
||||
pass # failure to beep is not critical
|
||||
if self.opts.visual_bell_duration > 0:
|
||||
self.start_visual_bell_at = monotonic()
|
||||
glfw_post_empty_event()
|
||||
|
||||
@@ -7,6 +7,15 @@ These are typically in the form of new or re-purposed escape codes. While these
|
||||
extensions are currently kitty specific, it would be nice to get some of them
|
||||
adopted more broadly, to push the state of terminal emulators forward.
|
||||
|
||||
The goal of these extensions is to be as small an unobtrusive as possible,
|
||||
while filling in some gaps in the existing xterm protocol. In particular, one
|
||||
of the goals of this specification is explicitly not to "re-imagine" the tty.
|
||||
The tty should remain what it is -- a device for efficiently processing text
|
||||
received as a simple byte stream. Another objective is to only move the minimum
|
||||
possible amount of extra functionality into the terminal program itself. This
|
||||
is to make it as easy to implement these protocol extensions as possible,
|
||||
thereby hopefully encouraging their widespread adoption.
|
||||
|
||||
If you wish to discuss these extensions, propose additions/changes to them
|
||||
please do so by opening issues in the github bug tracker.
|
||||
|
||||
@@ -19,9 +28,6 @@ in terminal editors such as vim and emacs to display red, wavy underlines under
|
||||
mis-spelled words and/or syntax errors. This is done by re-purposing some SGR escape codes
|
||||
that are not used in modern terminals (https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes)
|
||||
|
||||
Setting the width and/or height to zero means that no drawing is done and the
|
||||
cursor position remains unchanged.
|
||||
|
||||
To change the underline style from straight line to curl (this used to be the
|
||||
code for rapid blinking text, only previous use I know of was in MS-DOS ANSI.sys):
|
||||
|
||||
|
||||
18
setup.py
18
setup.py
@@ -88,8 +88,9 @@ def get_python_flags(cflags):
|
||||
return libs
|
||||
|
||||
|
||||
def init_env(debug=False, asan=False):
|
||||
def init_env(debug=False, asan=False, native_optimizations=True):
|
||||
global cflags, ldflags, cc, ldpaths
|
||||
native_optimizations = native_optimizations and not asan and not debug
|
||||
ccver = cc_version()
|
||||
stack_protector = '-fstack-protector'
|
||||
if ccver >= (4, 9):
|
||||
@@ -106,8 +107,11 @@ def init_env(debug=False, asan=False):
|
||||
cflags = os.environ.get(
|
||||
'OVERRIDE_CFLAGS', (
|
||||
'-Wextra -Wno-missing-field-initializers -Wall -std=c99 -D_XOPEN_SOURCE=700'
|
||||
' -pedantic-errors -Werror {} -DNDEBUG -fwrapv {} {} -pipe'
|
||||
).format(optimize, stack_protector, missing_braces)
|
||||
' -pedantic-errors -Werror {} -DNDEBUG -fwrapv {} {} -pipe {}'
|
||||
).format(
|
||||
optimize, stack_protector, missing_braces, '-march=native'
|
||||
if native_optimizations else ''
|
||||
)
|
||||
)
|
||||
cflags = shlex.split(cflags
|
||||
) + shlex.split(sysconfig.get_config_var('CCSHARED'))
|
||||
@@ -263,8 +267,8 @@ def find_c_files():
|
||||
return tuple(ans), tuple(headers)
|
||||
|
||||
|
||||
def build(args):
|
||||
init_env(args.debug, args.asan)
|
||||
def build(args, native_optimizations=True):
|
||||
init_env(args.debug, args.asan, native_optimizations)
|
||||
compile_c_extension(
|
||||
'kitty/fast_data_types', args.incremental, *find_c_files()
|
||||
)
|
||||
@@ -361,10 +365,10 @@ def main():
|
||||
sys.executable, sys.executable, os.path.join(base, 'test.py')
|
||||
)
|
||||
elif args.action == 'linux-package':
|
||||
build(args)
|
||||
build(args, native_optimizations=False)
|
||||
package(args)
|
||||
elif args.action == 'osx-bundle':
|
||||
build(args)
|
||||
build(args, native_optimizations=False)
|
||||
package(args, for_bundle=True)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user