Giter Club home page Giter Club logo

alacritty's Introduction

Alacritty Logo

Alacritty - A fast, cross-platform, OpenGL terminal emulator

Alacritty - A fast, cross-platform, OpenGL terminal emulator

About

Alacritty is a modern terminal emulator that comes with sensible defaults, but allows for extensive configuration. By integrating with other applications, rather than reimplementing their functionality, it manages to provide a flexible set of features with high performance. The supported platforms currently consist of BSD, Linux, macOS and Windows.

The software is considered to be at a beta level of readiness; there are a few missing features and bugs to be fixed, but it is already used by many as a daily driver.

Precompiled binaries are available from the GitHub releases page.

Join #alacritty on libera.chat if you have questions or looking for a quick help.

Features

You can find an overview over the features available in Alacritty here.

Further information

Installation

Alacritty can be installed by using various package managers on Linux, BSD, macOS and Windows.

Prebuilt binaries for macOS and Windows can also be downloaded from the GitHub releases page.

For everyone else, the detailed instructions to install Alacritty can be found here.

Requirements

  • At least OpenGL ES 2.0
  • [Windows] ConPTY support (Windows 10 version 1809 or higher)

Configuration

You can find the documentation for Alacritty's configuration in man 5 alacritty, or by looking at the website if you do not have the manpages installed.

Alacritty doesn't create the config file for you, but it looks for one in the following locations:

  1. $XDG_CONFIG_HOME/alacritty/alacritty.toml
  2. $XDG_CONFIG_HOME/alacritty.toml
  3. $HOME/.config/alacritty/alacritty.toml
  4. $HOME/.alacritty.toml

Windows

On Windows, the config file should be located at:

%APPDATA%\alacritty\alacritty.toml

Contributing

A guideline about contributing to Alacritty can be found in the CONTRIBUTING.md file.

FAQ

Is it really the fastest terminal emulator?

Benchmarking terminal emulators is complicated. Alacritty uses vtebench to quantify terminal emulator throughput and manages to consistently score better than the competition using it. If you have found an example where this is not the case, please report a bug.

Other aspects like latency or framerate and frame consistency are more difficult to quantify. Some terminal emulators also intentionally slow down to save resources, which might be preferred by some users.

If you have doubts about Alacritty's performance or usability, the best way to quantify terminal emulators is always to test them with your specific usecases.

Why isn't feature X implemented?

Alacritty has many great features, but not every feature from every other terminal. This could be for a number of reasons, but sometimes it's just not a good fit for Alacritty. This means you won't find things like tabs or splits (which are best left to a window manager or terminal multiplexer) nor niceties like a GUI config editor.

License

Alacritty is released under the Apache License, Version 2.0.

alacritty's People

Contributors

a5ob7r avatar aaron1011 avatar algesten avatar atouchet avatar brycefisher avatar cema-sp avatar chrisduerr avatar chrisnc avatar crackedp0t avatar davidhewitt avatar divinegod avatar dspeckhals avatar eijebong avatar hlieberman avatar honza avatar jamessan avatar jwilm avatar kchibisov avatar lukaslueg avatar manishearth avatar matthiaskrgr avatar mbrumlow avatar nickez avatar nixpulvis avatar proski avatar robertgzr avatar siiptuo avatar sodiumjoe avatar trimental avatar zacps avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alacritty's Issues

build is failing

Compiling alacritty v0.1.0 (file:///home/solaraquarion/.cache/pacaur/alacritty-git/src/alacritty-git)
error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Cursor has already been defined in this module
--> src/index.rs:24:59
|
24 | #[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Cursor here

error[E0428]: a type named Cursor has already been defined in this module
--> src/index.rs:25:1
|
24 | #[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
| ----------- previous definition of Cursor here
25 | pub struct Cursor {
| ^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Line has already been defined in this module
--> src/index.rs:33:82
|
33 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Line here

error[E0428]: a type named Line has already been defined in this module
--> src/index.rs:34:1
|
33 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)]
| ----------- previous definition of Line here
34 | pub struct Line(pub usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Column has already been defined in this module
--> src/index.rs:45:82
|
45 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Column here

error[E0428]: a type named Column has already been defined in this module
--> src/index.rs:46:1
|
45 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)]
| ----------- previous definition of Column here
46 | pub struct Column(pub usize);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Flags has already been defined in this module
--> src/term.rs:82:29
|
82 | #[derive(Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Flags here

error[E0428]: a type named Flags has already been defined in this module
--> src/term.rs:81:5
|
81 | bitflags! {
| ^ already defined
82 | #[derive(Serialize, Deserialize)]
| ----------- previous definition of Flags here
|
= note: this error originates in a macro outside of the current crate

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Color has already been defined in this module
--> src/term.rs:91:54
|
91 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Color here

error[E0428]: a type named Color has already been defined in this module
--> src/term.rs:92:5
|
91 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
| ----------- previous definition of Color here
92 | pub enum Color {
| ^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Cell has already been defined in this module
--> src/term.rs:97:39
|
97 | #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Cell here

error[E0428]: a type named Cell has already been defined in this module
--> src/term.rs:98:5
|
97 | #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
| ----------- previous definition of Cell here
98 | pub struct Cell {
| ^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_SizeInfo has already been defined in this module
--> src/term.rs:222:41
|
222 | #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_SizeInfo here

error[E0428]: a type named SizeInfo has already been defined in this module
--> src/term.rs:223:1
|
222 | #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
| ----------- previous definition of SizeInfo here
223 | pub struct SizeInfo {
| ^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Color has already been defined in this module
--> src/ansi.rs:306:73
|
306 | #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Color here

error[E0428]: a type named Color has already been defined in this module
--> src/ansi.rs:307:1
|
306 | #[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
| ----------- previous definition of Color here
307 | pub enum Color {
| ^ already defined

error[E0428]: a type named Config has already been defined in this module
--> src/config.rs:29:1
|
28 | #[derive(Debug, Deserialize)]
| ----------- previous definition of Config here
29 | pub struct Config {
| ^ already defined

error[E0428]: a type named Colors has already been defined in this module
--> src/config.rs:455:1
|
454 | #[derive(Debug, Deserialize)]
| ----------- previous definition of Colors here
455 | pub struct Colors {
| ^ already defined

error[E0428]: a type named PrimaryColors has already been defined in this module
--> src/config.rs:462:1
|
461 | #[derive(Debug, Deserialize)]
| ----------- previous definition of PrimaryColors here
462 | pub struct PrimaryColors {
| ^ already defined

error[E0428]: a type named AnsiColors has already been defined in this module
--> src/config.rs:502:1
|
501 | #[derive(Debug, Deserialize)]
| ----------- previous definition of AnsiColors here
502 | pub struct AnsiColors {
| ^ already defined

error[E0428]: a type named Dpi has already been defined in this module
--> src/config.rs:756:1
|
755 | #[derive(Debug, Deserialize)]
| ----------- previous definition of Dpi here
756 | pub struct Dpi {
| ^ already defined

error[E0428]: a type named FontOffset has already been defined in this module
--> src/config.rs:789:1
|
788 | #[derive(Debug, Deserialize)]
| ----------- previous definition of FontOffset here
789 | pub struct FontOffset {
| ^ already defined

error[E0428]: a type named Font has already been defined in this module
--> src/config.rs:850:1
|
849 | #[derive(Debug, Deserialize)]
| ----------- previous definition of Font here
850 | pub struct Font {
| ^ already defined

error[E0428]: a type named Key has already been defined in this module
--> src/config.rs:1021:1
|
1020 | #[derive(Deserialize, Copy, Clone)]
| ----------- previous definition of Key here
1021 | enum Key {
| ^ already defined

error[E0428]: a value named _IMPL_SERIALIZE_FOR_Grid has already been defined in this module
--> src/grid.rs:32:37
|
32 | #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
| ----------- ^^^^^^^^^ already defined
| |
| previous definition of _IMPL_SERIALIZE_FOR_Grid here

error[E0428]: a type named Grid has already been defined in this module
--> src/grid.rs:33:1
|
32 | #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
| --------- previous definition of Grid here
33 | pub struct Grid {
| ^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Row has already been defined in this module
--> src/grid.rs:224:35
|
224 | #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Row here

error[E0428]: a type named Row has already been defined in this module
--> src/grid.rs:225:1
|
224 | #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
| ----------- previous definition of Row here
225 | pub struct Row(Vec);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ already defined

error[E0428]: a value named _IMPL_DESERIALIZE_FOR_Rgb has already been defined in this module
--> src/lib.rs:70:65
|
70 | #[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)]
| --------- ^^^^^^^^^^^ already defined
| |
| previous definition of _IMPL_DESERIALIZE_FOR_Rgb here

error[E0428]: a type named Rgb has already been defined in this module
--> src/lib.rs:71:1
|
70 | #[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Serialize, Deserialize)]
| ----------- previous definition of Rgb here
71 | pub struct Rgb {
| ^ already defined

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:31:5
|
31 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:35:5
|
35 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:39:5
|
39 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:43:5
|
43 | #[serde(default="true_bool")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:47:5
|
47 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:51:5
|
51 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:55:5
|
55 | #[serde(default)]
| ^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:463:5
|
463 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:465:5
|
465 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:503:5
|
503 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:505:5
|
505 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:507:5
|
507 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:509:5
|
509 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:511:5
|
511 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:513:5
|
513 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:515:5
|
515 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:517:5
|
517 | #[serde(deserialize_with = "rgb_from_hex")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: The attribute serde is currently unknown to the compiler and may have meaning added to it in the future (see issue #29642)
--> src/config.rs:864:5
|
864 | #[serde(deserialize_with="DeserializeFromF32::deserialize_from_f32")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add #![feature(custom_attribute)] to the crate attributes to enable

error: aborting due to 18 previous errors

error: Could not compile alacritty.

Support for ligatures

I would love to see the support for ligatures (an example of their use might be found in https://github.com/tonsky/FiraCode). Please note that i have almost no idea how do they work under the hood, and so i don't know how hard is it to implement support for them, I'm just throwing an idea here.

Anyhow i think this is a great project, congratulation! :)

Scrolling vim in tmux while a separate pane is printing causes corruption

Given this setup

image

Scrolling a vim split while the middle left pane is printing will cause vim to become corrupt as shown in this screenshot:

image

I have a theory that this is because writing to the pty is not synchronized at all. The input thread simply writes to the file descriptor when it has data to write. The only way to test if this is true would be implementing an actual event loop for I/O. The easiest way to do that is dropping mio into the pty thread and sending all writes from the input handling over the mio channel.

Add README

Add a README explaining what the project is, why people should care, and instructions for getting started on supported platforms.

notty

Hey @jwilm, we've talked a bit in the past about alacritty implementing the notty protocol. It seems like alacritty is really coming together, so I wanted to reach out and discuss that possibility.

From my perspective, I'm much more interested in implementing a framework on top of notty on the 'far side' of the TTY than I am interested in implementing a terminal emulator, and notty has stalled for that reason. So a collaboration with alacritty would be strongly in my interest. :-)

What follows are some notes on notty to get the conversation started.

Basics of the notty protocol

A notty escape code is much simpler to parse than an ANSI escape code. It has these parts:

  1. An initializer sequence. Currently it's Escape, Underscore, Left Square Bracket. Its important that it begins Escape, Underscore because this is a reserved space for custom messages, and correctly behaving ANSI terminals will ignore notty escape codes, rather than potentially printing garbage. The left square bracket is to reduce likelyhood of collision with terminal-specific custom commands (ideally it would someday be reserved by a standard for notty).
  2. An op code. In the current protocol this is a hex encoded number, but its not particularly important. Every command has an op code assigned to it.
  3. A sequence of standardized arguments that each op code takes, which have a defined binary format. This would be something like a motion ("left 2 cells", "right to edge of screen", etc) or a text style ("bold", "rgb 0xff7744").
  4. A sequence of base-64'd binary data arguments (currently this is sequential but it could easily be keyed instead). Its important that these be base64'd to avoid escaping issues & also because the TTY is often set to munge \n into \r\n. A command like "draw an image" takes base64'd image data.
  5. The terminating character, which is specified (by ANSI) as U+009C. This needs to be the terminal character to have ANSI terminals ignore this message correctly.

The exact binary representation of sections 2 - 4 are not particularly important in my opinion, we just have to pick something (currently its a mix of hex, b64, and punctuation characters).

Subdividing the character grid

The most interesting thing from a performance perspective in notty is the ability to subdivide the screen into separate grids, so that a program like tmux isn't constantly redrawing the entire grid redundantly.

Ultimately, the result is a tree, the leaves of which are grids. Branches are one of two things:

  1. A "split", with 2 children, dividing a section of the screen along a single axis horizontally or vertically.
  2. A "ring", with N > 1 children, all of which fill the same space of the grid.

The result of this is that every grid will always be rectangular, and you never have to deal with irregularly shaped grids. Here's the data structures used to represent this in notty right now (a little more complex than what I showed at RustConf):

struct ScreenSection<T> {
    region: Region // 4 u32s representing the rows/columns this section takes up
    ring: Ring<Panel<T>>,
}

enum Panel<T> {
     Grid(T),
     Split { left: ScreenSection<T>, right: ScreenSection<T> },
}

// Implements a "rotate_left" "rotate_right" interface
struct Ring<T> {
    top: T,
    rest: Option<VecDeque<T>>,
}

Sandboxing

One problem with developing the complexity of the terminal is that it has no way to isolate different programs from one another - they just write over each other's output. I haven't implemented it, but I'd like the terminal to be able to sandbox processes.

Every sandbox (including the 'root' sandbox that the entire terminal would be in by default) has a session key associated with it. The process can always request the session key for the active sandbox. Just prior to forking, a process can set up a new sandbox in one section of the screen. Unless you have the session key for an outer sandbox, all commands manipulating grids would interact within that sandbox.

Other features of notty

The general thrust of notty is to put more complexity in the terminal layer, so that that logic can be re-used by different terminal applications, instead of everyone having a bespoke implementation of subdividing the screen (for example). To a certain extent, notty also extends the capabilities of the terminal to implement behavior it fundamentally couldn't before.

If you're interested in pursuing this seriously, we can work together to find a balance of features that we're both excited about.

Here are some of the features notty implements or is supposed to implement right now:

  • Images & media on the grid
  • Collapsible sections of the grid
  • Tooltips/dropdown (intended for auto complete)
  • Proper support for all input (key releases, control character key presses, mouse support, etc)
  • "syntactic styles" - the ability for the controlling process to say "style this like a comment/keyword/etc," so users can have one stylesheet that is applied consistently to all their syntax highlighting.
  • Auto-formating hierarchical data with collapsible sections and such (so the terminal receives e.g. a JSON blob and pretty prints it automatically).

Some of these ideas could be implemented at a higher level than the terminal though. The basic idea is to extend the terminal to be a full-featured "text environment," like what one would expect from the graphical component of a modern IDE, so that an ecosystem of "IDE components" can develop within it, like UNIX with more modern UI capabilitilies.

Improve error handling

Review code for error handling prior to 0.1 release. Refactor any uses of unwrap/expect that could reasonably fail in the wild. Related to #22, but this is more general.

  • Shader loading
  • Input handling WRT clipboard

`C-c` panic in fish shell

Reproducing step:

  1. open alacritty and fish
  2. a
  3. C-c

log:

    Finished debug [unoptimized + debuginfo] target(s) in 0.1 secs
     Running `target/debug/alacritty`
device_pixel_ratio: 1
width: 1024, height: 768
Initializing glyph cache
Finished initializing glyph cache in 0.124546754
set_inner_size: 804 x 604
set_inner_size: 804 x 604; pts: 804 x 604
width: 804, height: 604
Cell Size: (10 x 25)
num_cols, num_lines = Column(80), Line(24)
num_cols, num_lines = Column(102), Line(30)
width: 1024, height: 768
num_cols, num_lines = Column(80), Line(24)
width: 804, height: 604
[unhandled osc_start]
[unhandled osc_put] byte='5'
[unhandled osc_put] byte='0'
[unhandled osc_put] byte=';'
[unhandled osc_put] byte='C'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='o'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='S'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='p'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='='
[unhandled osc_put] byte='0'
[unhandled osc_end] byte=0
[unhandled osc_start]
[unhandled osc_put] byte='0'
[unhandled osc_put] byte=';'
[unhandled osc_put] byte='f'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte=' '
[unhandled osc_put] byte=' '
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte='o'
[unhandled osc_put] byte='m'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='q'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='n'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='n'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='l'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='c'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='y'
[unhandled osc_end] byte=0
Set Attribute: Foreground(Black)
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
carriage_return
linefeed
Set Attribute: Foreground(Green)
Set Attribute: Foreground(Black)
Set Attribute: Reset
[Unhandled CSI] action='m', args=[0, 10], intermediates=[]
carriage_return
linefeed
[unhandled osc_start]
[unhandled osc_put] byte='5'
[unhandled osc_put] byte='0'
[unhandled osc_put] byte=';'
[unhandled osc_put] byte='C'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='o'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='S'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='p'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='='
[unhandled osc_put] byte='0'
[unhandled osc_end] byte=0
[unhandled osc_start]
[unhandled osc_put] byte='5'
[unhandled osc_put] byte='0'
[unhandled osc_put] byte=';'
[unhandled osc_put] byte='C'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='o'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='S'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='p'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='='
[unhandled osc_put] byte='0'
[unhandled osc_end] byte=0
[unhandled osc_start]
[unhandled osc_put] byte='0'
[unhandled osc_put] byte=';'
[unhandled osc_put] byte='f'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte=' '
[unhandled osc_put] byte=' '
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='h'
[unhandled osc_put] byte='o'
[unhandled osc_put] byte='m'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='q'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='n'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='n'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='e'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='s'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='u'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='/'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='l'
[unhandled osc_put] byte='a'
[unhandled osc_put] byte='c'
[unhandled osc_put] byte='r'
[unhandled osc_put] byte='i'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='t'
[unhandled osc_put] byte='y'
[unhandled osc_end] byte=0
Set Attribute: Foreground(Black)
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
Set Attribute: Dim
Term got unhandled attr: Dim
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
carriage_return
carriage_return
clear_line: All
Set Attribute: Bold
Set Attribute: Foreground(White)
Set Attribute: Background(Green)
Set Attribute: Foreground(Black)
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
Set Attribute: Bold
Set Attribute: Foreground(Green)
Set Attribute: Bold
Set Attribute: Foreground(Cyan)
Set Attribute: Bold
Set Attribute: Foreground(Blue)
Set Attribute: Bold
Set Attribute: Foreground(Red)
Set Attribute: Bold
Set Attribute: Foreground(Blue)
Set Attribute: Bold
Set Attribute: Foreground(Yellow)
Set Attribute: Foreground(Black)
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
clear_line: Right
backspace
Set Attribute: Foreground(Red)
Set Attribute: Bold
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
Set Attribute: ForegroundSpec(Rgb { r: 85, g: 85, b: 85 })
move_backward: Column(9)
Set Attribute: Foreground(Black)
[unhandled] esc_dispatch params=[], ints=[40], byte='B' (42)
Set Attribute: Reset
Set Attribute: Reverse
Set Attribute: CancelReverse
clear_line: Right
carriage_return
linefeed
backspace
thread 'pty reader' panicked at 'attempt to subtract with overflow', src/index.rs:251
stack backtrace:
   1:     0x563ad40383aa - std::sys::imp::backtrace::tracing::imp::write::hbea47d9dd19b523c
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x563ad403d9af - std::panicking::default_hook::{{closure}}::h6875a2976258b020
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:247
   3:     0x563ad403d5ae - std::panicking::default_hook::h88ffbc5922643264
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:263
   4:     0x563ad403de57 - std::panicking::rust_panic_with_hook::hc790e47d4ecc86cd
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:451
   5:     0x563ad403dce4 - std::panicking::begin_panic::hc066339e2fdc17d1
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:413
   6:     0x563ad403dc09 - std::panicking::begin_panic_fmt::h5912b2d2df332044
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:397
   7:     0x563ad403db97 - rust_begin_unwind
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:373
   8:     0x563ad407a53d - core::panicking::panic_fmt::h561c5ee168a3d2cb
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libcore/panicking.rs:69
   9:     0x563ad407a474 - core::panicking::panic::h194ce5d68a8f28a1
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libcore/panicking.rs:49
  10:     0x563ad3cd1c36 - <alacritty::index::Column as core::ops::SubAssign<usize>>::sub_assign::h0d91353cd4e41af1
                        at /home/quininer/tests/ui/alacritty/src/index.rs:251
  11:     0x563ad3cbee0a - <alacritty::term::Term as alacritty::ansi::Handler>::backspace::h0f69366576cc537e
                        at /home/quininer/tests/ui/alacritty/src/term.rs:573
  12:     0x563ad3cd7322 - <alacritty::ansi::Performer<'a, H> as vte::Perform>::execute::h13c990c23c2f5e84
                        at /home/quininer/tests/ui/alacritty/src/ansi.rs:403
  13:     0x563ad3c5d2d8 - vte::Parser::perform_action::h8e9207d2609e34af
                        at /home/quininer/.cargo/registry/src/github.com-1ecc6299db9ec823/vte-0.1.2/src/lib.rs:190
  14:     0x563ad3c5d8fe - vte::Parser::perform_state_change::h9a56f079e43e56e3
                        at /home/quininer/.cargo/registry/src/github.com-1ecc6299db9ec823/vte-0.1.2/src/lib.rs:167
  15:     0x563ad3c5dc74 - vte::Parser::advance::he199b620df8be155
                        at /home/quininer/.cargo/registry/src/github.com-1ecc6299db9ec823/vte-0.1.2/src/lib.rs:137
  16:     0x563ad3d14bcc - alacritty::ansi::Processor::advance::hef377be56860e454
                        at /home/quininer/tests/ui/alacritty/src/ansi.rs:81
  17:     0x563ad3cac8fe - <alacritty::event_loop::EventLoop<Io>>::pty_read::h1fd65b9f29f2a13b
                        at /home/quininer/tests/ui/alacritty/src/event_loop.rs:192
  18:     0x563ad3cac098 - <alacritty::event_loop::EventLoop<Io>>::spawn::{{closure}}::h0bb425cd2fe8582f
                        at /home/quininer/tests/ui/alacritty/src/event_loop.rs:281
  19:     0x563ad3cdf804 - <std::panic::AssertUnwindSafe<F> as core::ops::FnOnce<()>>::call_once::heccf5411cd66eb39
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:295
  20:     0x563ad3c5cf7f - std::panicking::try::do_call::h546e5663bd72af75
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:356
  21:     0x563ad40468ba - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libpanic_unwind/lib.rs:97
  22:     0x563ad3c5c7db - std::panicking::try::h2364aec27ae8e5f6
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panicking.rs:332
  23:     0x563ad3c5a9e4 - std::panic::catch_unwind::ha436adb5d97f012c
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/panic.rs:351
  24:     0x563ad3c5c34c - std::thread::Builder::spawn::{{closure}}::h9d2c7b9b28783ee1
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/thread/mod.rs:287
  25:     0x563ad3ca46e9 - <F as alloc::boxed::FnBox<A>>::call_box::hbd32ccd14fb32e99
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:595
  26:     0x563ad403cca4 - std::sys::imp::thread::Thread::new::thread_start::h8084b1107992ae5b
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/liballoc/boxed.rs:605
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys_common/thread.rs:21
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/obj/../src/libstd/sys/unix/thread.rs:84
  27:     0x7fc80624e453 - start_thread
  28:     0x7fc805d7a7de - __GI___clone
  29:                0x0 - <unknown>
Goodbye

Optimize pseudo-terminal reading and parsing

The pty reader thread currently looks approximately like this

loop {
    if let Ok(got) = pty.read(&mut buf[..]) {
        let mut terminal = terminal.lock_high();

        for byte in &buf[..got] {
            pty_parser.advance(&mut *terminal, *byte);
        }

        terminal.dirty = true;
        proxy.wakeup_event_loop();
    } else {
        break;
    }
}

Note that this is just a single thread and so reading from the pty and advancing the parser cannot happen in parallel. Instead of this implementation, we should add another thread where the parsing happens. Reader thread will just sit there and read; every time a chunk is available, it sends to the parser thread. Doing this with Vec might eliminate some of the speedup we could otherwise get. I propose a solution using a stack allocated buffer and sending slices to the parser thread. It's possible to send such references to a scoped thread:

let items = [0, 1, 2, 3, 4];
let (tx, rx) = mpsc::channel();

crossbeam::scope(|scope| {
    let handle = scope.spawn(move || {
        while let Ok(item) = rx.recv() {
            // Parser would run here
            println!("item={:?}", item);
        }
    });

    // Reader would read here
    tx.send(&items[0..2]).unwrap();
    tx.send(&items[2..5]).unwrap();
    drop(tx);
});

What's needed then is some sort of wrapper around a chunk of memory that lets a reader read into available slices while sending populated slices to an iterator on the other thread. When the parser thread is done (drops the slice), the slice should be returned to the pool for the reader to use again.

Proper full screen support

Currently there's no full screen support in Alacritty. Doing to with glutin requires recreation of the window and thus recreation of the OpenGL context.

Keybindings Configurable from File

Keybindings are currently hardcoded in src/input.rs. Instead, they should all be specified in the alacritty.yml file. Currently hardcoded keybindings should be added to the default alacritty.yml config.

There's a couple of binding types we need to support

  1. Given a key combination and terminal state, send an escape sequence.
  2. Given a key combination and terminal state, perform a predefined action
    • Actions: copy-selection, paste, toggle-fullscreen

I imagine the config might look something like this

bindings:
  - key: f11
    escape: [23~
  - key: enter
    mods: super # super and cmd are interchangeable modifiers
    action: full-screen
  - mouse: 5
    action: paste
  - key: left arrow
    mode: app-cursor
    escape: OD

Notes on the above config:

  • mods defaults to no mods
  • mode defaults to any mode
  • keys like left arrow would be easy to screw up the identifier for. Better option there?
  • full-screen isn't current supported
  • clipboard stuff isn't currently supported

One thing that's nice about the current approach is bindings for each key are available in a static location. It would be nice to still be able to jump to the binding list for a given key using an array or Vec or match instead of going through a HashMap.

I think the initial implementation of this will be supporting the current keybindings but defined from the config file instead of hard-coded.

Crash when resizing to smaller size

num_cols, num_lines = Column(213), Line(59)
width: 2560, height: 1600
thread 'pty reader' panicked at 'index out of bounds: the len is 59 but the index is 73', ../src/libcollections/vec.rs:1316
note: Run with `RUST_BACKTRACE=1` for a backtrace.
child finished with error '256'

Unfortunately I didn't run with RUST_BACKTRACE. Judging by the indices, the cursor line was beyond the bottom of the screen after resizing.

256 color mode should work

  • Add support for 256 color mode
  • Ref test for the below script

perl script for displaying 256 color squares is here: http://www.robmeerman.co.uk/unix/256colours

inlined here so it's not lost

#!/usr/bin/perl
# Author: Todd Larason <[email protected]>
# $XFree86: xc/programs/xterm/vttests/256colors2.pl,v 1.2 2002/03/26 01:46:43 dickey Exp $

# use the resources for colors 0-15 - usually more-or-less a
# reproduction of the standard ANSI colors, but possibly more
# pleasing shades

# colors 16-231 are a 6x6x6 color cube
for ($red = 0; $red < 6; $red++) {
    for ($green = 0; $green < 6; $green++) {
	for ($blue = 0; $blue < 6; $blue++) {
	    printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\",
		   16 + ($red * 36) + ($green * 6) + $blue,
		   ($red ? ($red * 40 + 55) : 0),
		   ($green ? ($green * 40 + 55) : 0),
		   ($blue ? ($blue * 40 + 55) : 0));
	}
    }
}

# colors 232-255 are a grayscale ramp, intentionally leaving out
# black and white
for ($gray = 0; $gray < 24; $gray++) {
    $level = ($gray * 10) + 8;
    printf("\x1b]4;%d;rgb:%2.2x/%2.2x/%2.2x\x1b\\",
	   232 + $gray, $level, $level, $level);
}


# display the colors

# first the system ones:
print "System colors:\n";
for ($color = 0; $color < 8; $color++) {
    print "\x1b[48;5;${color}m  ";
}
print "\x1b[0m\n";
for ($color = 8; $color < 16; $color++) {
    print "\x1b[48;5;${color}m  ";
}
print "\x1b[0m\n\n";

# now the color cube
print "Color cube, 6x6x6:\n";
for ($green = 0; $green < 6; $green++) {
    for ($red = 0; $red < 6; $red++) {
	for ($blue = 0; $blue < 6; $blue++) {
	    $color = 16 + ($red * 36) + ($green * 6) + $blue;
	    print "\x1b[48;5;${color}m  ";
	}
	print "\x1b[0m ";
    }
    print "\n";
}


# now the grayscale ramp
print "Grayscale ramp:\n";
for ($color = 232; $color < 256; $color++) {
    print "\x1b[48;5;${color}m  ";
}
print "\x1b[0m\n";

launch failed

RUST_BACKTRACE=1 alacritty  101 ↵  1471  20:36:18
device_pixel_ratio: 1
thread 'main' panicked at 'assertion failed: (left == right) (left: 1, right: 0)', font/src/ft/list_fonts.rs:161
stack backtrace:
1: 0x556182a565f3 -
2: 0x556182a5bbed -
3: 0x556182a5b7eb -
4: 0x556182a5c078 -
5: 0x556182a5bf12 -
6: 0x556182a5be50 -
7: 0x556182a2697f -
8: 0x55618297e03c -
9: 0x556182a64996 -
10: 0x556182a5c8f8 -
11: 0x7f15fe914290 - __libc_start_main
12: 0x55618293ac39 -
13: 0x0 -

`alt` key don't work

example:

import curses

def Main(screen):
   while True:
      ch = screen.getch()
      if ch == ord('q'):
         break
      elif ch == 27: # ALT was pressed
         screen.nodelay(True)
         ch2 = screen.getch() # get the key pressed after ALT
         if ch2 == -1:
            break
         else:
            screen.addstr(5, 5, 'ALT+'+str(ch2))
            screen.refresh()
         screen.nodelay(False)

curses.wrapper(Main)

screenshot_20170103_151940

Rendering bug with htop

Still have an issue with scroll regions I think. It would be good to add some ref tests that look at grid content so that we can regression test these things.

Add ref test system

There's been a number of bugs related to scrolling region. It seems like fixing one seems to cause another. Ref tests would allow recording some terminal protocol and then making assertions about the screen state at the end.

Add config for window starting position

Gnome terminal and others support specifying a starting geometry for the screen, usually in terms of chars. So "200x50" is 200 vertical chars and 50 horizontal ones. That plus a pixel offset from top-left of screen lets the user decide how big should the alacritty window be and where should it be placed. With this in config, the window is always where I want it.

Something like this:

window:
  vertical_chars: 50
  horizontal_chars: 100
  starting_x_offset: 100
  starting_y_offset: 100

You could put the fullscreen property (from #38) on the same window block too.

Real text underline support

As part of shipping 0.1, underline support was hacked in by rendering an underscore in the same cell as the character.

Subpixel Font Rendering Background Correction

Subpixel font masks are currently generated against a particular background color, but the fragment shader does not readjust based on the actual background being rendered to. Not having such a correction leads to fuzzy looking fonts.

Colors configurable from file

I've already added the default color scheme to the default config file. It's reproduced below. Colors specified in the config file should actually be loaded and used. That is, this configuration should have an effect.

# Colors
colors:
  # Default colors
  default:
    background: 0x000000
    foreground: 0xeaeaea

  # Normal colors
  normal:
    black: 0x000000
    red: 0xd54e53
    green: 0xb9ca4a
    yellow: 0xe6c547
    blue: 0x7aa6da
    magenta: 0xc397d8
    cyan: 0x70c0ba
    white: 0x424242

  # Bright colors
  bright:
    black: 0x666666
    red: 0xff3334
    green: 0x9ec400
    yellow: 0xe7c547
    blue: 0x7aa6da
    magenta: 0xb77ee0
    cyan: 0x54ced6
    white: 0x2a2a2a

Mouse Integration

Mouse events should be forwarded to the terminal for programs that have mouse integration like htop and vim.

  • trackpad scrolling
  • mousewheel scrolling
  • basic mouse reporting
  • SGR reporting

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.