mkcolor

  1 // Definition modified from the Rust standard library
  2 // XXX: This is missing the stability/internal attributes
  3 /// The `Option` type.
  4 ///
  5 /// ```
  6 /// let my_opt = Some(5);
  7 /// ```
  8 #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
  9 pub enum Option<T> {
 10     /// No value
 11     None,
 12     /// Some value `T`
 13     Some(T),
 14 }
 15 
 16 impl<T> Option<T> {
 17     /// Maps an `Option<T>` to `Option<U>` by applying a function
 18     /// to a contained value.
 19     #[inline]
 20     pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
 21         match self {
 22             Some(x) => Some(f(x)),
 23             None => None,
 24         }
 25     }
 26 }
  1 // Create a new color object with the given RGB values, and, if present,
  2 // the given ANSI index.
  3 function newColor(r, g, b, idx) {
  4     let col = { r: r, g: g, b: b };
  5     let rStr = col.r.toString(16).padStart(2, '0').toUpperCase();
  6     let gStr = col.g.toString(16).padStart(2, '0').toUpperCase();
  7     let bStr = col.b.toString(16).padStart(2, '0').toUpperCase();
  8     col.hex = `#${rStr}${gStr}${bStr}`;
  9     col.text = `#${rStr}${gStr}${bStr}`;
 10 
 11     if (idx) {
 12         col.idx = idx;
 13         col.text += ` (ANSI ${idx})`;
 14     }
 15 
 16     return col;
 17 }
 demo.rs  demo.js  Editor Demo  UI Demo X
    1                
    2                
    3 the cursor is here
    4 
    5 check out visual mode
    6 
    7 looking for something?
    8 maybe it's already here
    9 
   10 (matching parens)
   11 
   12 Looks like thsi word is spelled wrong
   13 lowercase words get flagged too
   14 the word vim is a "rare" word
   15 and "okay" is a "local" word
   16 
   17 # Heading 1$
-  18 these paragraphs have 'list' set$
|  19 $
|  20 ## Heading 1.1$
|+ 21 +---- 2 lines: this paragraph is folded
   22 $
   23 
-- 24 this line was deleted
   25 this line changed this text
++ 26 this line was added
   27 
>> 28 this line has an error in it
   29 
~
~
Editor Demo3,15           All
 demo.rs  demo.js  Editor Demo  UI Demo X
this screen shows     |
various other Vim-    |  f
specific UI elements  |  foo        
                      |  foobar     
                      |  fun        
                      |  function   
                      |
                      |
                      |
                      |
                      |
                      |
                      |
                      |
inactive status        active status
W10: Warning: Changing a readonly file
E37: No write since last change (add ! to override)
-- INSERT --
-- More --

one-file              another-file          a-third-file
one-directory/        another-directory/
one-file  another-file  a-third-file
Contrast ratio: 21
Main background: #000
Main text: #FFF
Comments: #FFF
Identifiers: #FFF
Literals: #FFF
Type names: #FFF
Keywords: #FFF
Preprocessor: #FFF
Special tokens: #FFF
Titles: #FFF
TODO markers: #220
Syntax errors: #200
'showmode' message: #FFF
"More" prompt: #FFF
Directories in file listings: #FFF
Incorrect spelling: #FFF
Incorrect capitalization: #FFF
Rare words: #FFF
Locally-defined words: #FFF
End-of-file marker: #444
End-of-line marker: #AAA
Deleted lines: #200
Changed lines: #222
Changed text: #000
Added lines: #020
Cursor: #FFF
Cursor line: #111
Cursor column: #111
Visual selection: #222
Incremental search: #222
Search results: #222
Matching parentheses: #222
Warning messages: #200
Error messages: #200
Tab-completion menu selection: #DDD
Line number background: #000
Line number text: #FFF
Cursor line number background: #000
Cursor line number text: #FFF
Status line background: #FFF
Status line text: #000
Inactive status line background: #FFF
Inactive status line text: #000
Tab line background: #000
Tab line text: #FFF
Selected tab background: #FFF
Selected tab text: #000
Tab line blank space: #222
Folded text background: #000
Folded text: #FFF
Fold column background: #000
Fold column text: #FFF
Sign column background: #000
Sign column text: #FFF
Vertical split background: #FFF
Vertical split text: #000
Popup menu background: #FFF
Popup menu text: #000
Popup menu selection background: #DDD
Popup menu selection text: #000
Popup menu scrollbar: #DDD
Popup menu scrollbar position: #FFF

Contrast with background:
UI frame background contrast (against main background):

*May increase calculation time


Source code

mkcolor is an experiment in randomly generating text-editor color schemes. Using the WCAG definition of contrast ratio, the CIELAB color space, and a lot of random numbers, this code can (most of the time) generate something that is pretty legible, according to some basic parameters.

When generating a color scheme, the base contrast ratio between the background color and the main foreground color is displayed, alongside all the other colors generated. The color list is available in case you would like to use a generated color scheme in your own editor or project.

In addition to settings that tweak things like the minimum acceptable contrast ratio or restraints on whether certain categories of colors should be "distinct", an option is available to use 8-bit ANSI terminal color codes instead of 24-bit RGB color. This allows you to use these colors in a terminal text editor, like non-GUI Vim. When this setting is active, the ANSI code for any given color will be given alongside its 24-bit hex code.

When deciding whether two colors are "distinct", mkcolor uses both the contrast ratio as well as a Euclidean distance in the CIELAB color space. If the contrast ratio between two text colors is greater than 1.06 and the CIELAB distance is greater than 20, then two colors are considered "distinct". For two highlight colors, or when comparing a highlight color against the main background, the contrast ratio needs to be greater than 1.008, and the CIELAB distance greater than 10. All highlight colors still need to maintain the requested minimum contrast ratio with all text colors, so the "distinction" criteria are loosened to prevent runaway situations with a high contrast ratio forbidding any color scheme.

The experimental "tweak the main background" feature uses a random walk in the CIELAB color space to take the main background color and create a new one that's similar to it. It won't work while "Use ANSI terminal colors" is enabled because doing so creates colors that are outside the ANSI 256-color space. Selecting either option will disable the other one until it has been deselected. (If you know how to do color-space conversions to the closest ANSI 8-bit color, get in touch! The source code is available at the link above.)

This project owes its inspiration and existence to a number of resources, including (but not limited to):