aboutsummaryrefslogtreecommitdiff
path: root/core/terminal/internal_os.odin
blob: 127cbae54820eace28b57d62ef5415f2e0ce22e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#+build !freestanding
#+build !js
#+private
package terminal

import "base:runtime"
import "core:os"
import "core:strings"

// Reference documentation:
//
// - [[ https://no-color.org/ ]]
// - [[ https://github.com/termstandard/colors ]]
// - [[ https://invisible-island.net/ncurses/terminfo.src.html ]]

get_no_color :: proc() -> bool {
	buf: [128]u8
	if no_color, err := os.lookup_env(buf[:], "NO_COLOR"); err == nil {
		return no_color != ""
	}
	return false
}

get_environment_color :: proc() -> Color_Depth {
	buf: [128]u8
	// `COLORTERM` is non-standard but widespread and unambiguous.
	if colorterm, err := os.lookup_env(buf[:], "COLORTERM"); err == nil {
		// These are the only values that are typically advertised that have
		// anything to do with color depth.
		if colorterm == "truecolor" || colorterm == "24bit" {
			return .True_Color
		}
	}

	if term, err := os.lookup_env(buf[:], "TERM"); err == nil {
		if strings.contains(term, "-truecolor") {
			return .True_Color
		}
		if strings.contains(term, "-256color") {
			return .Eight_Bit
		}
		if strings.contains(term, "-16color") {
			return .Four_Bit
		}

		// The `terminfo` database, which is stored in binary on *nix
		// platforms, has an undocumented format that is not guaranteed to be
		// portable, so beyond this point, we can only make safe assumptions.
		//
		// This section should only be necessary for terminals that do not
		// define any of the previous environment values.
		//
		// Only a small sampling of some common values are checked here.
		switch term {
		case "ansi", "konsole", "putty", "rxvt", "rxvt-color", "screen",
		     "st", "tmux", "vte", "xterm", "xterm-color":
			return .Three_Bit
		}
	}

	return .None
}

@(init)
init_terminal :: proc "contextless" () {
	_init_terminal()

	context = runtime.default_context()

	// We respect `NO_COLOR` specifically as a color-disabler but not as a
	// blanket ban on any terminal manipulation codes, hence why this comes
	// after `_init_terminal` which will allow Windows to enable Virtual
	// Terminal Processing for non-color control sequences.
	if !get_no_color() {
		color_enabled = color_depth > .None
	}
}

@(fini)
fini_terminal :: proc "contextless" () {
	_fini_terminal()
}