internal.odin 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #+private
  2. package terminal
  3. import "base:runtime"
  4. import "core:os"
  5. import "core:strings"
  6. // Reference documentation:
  7. //
  8. // - [[ https://no-color.org/ ]]
  9. // - [[ https://github.com/termstandard/colors ]]
  10. // - [[ https://invisible-island.net/ncurses/terminfo.src.html ]]
  11. get_no_color :: proc() -> bool {
  12. buf: [128]u8
  13. if no_color, err := os.lookup_env(buf[:], "NO_COLOR"); err == nil {
  14. return no_color != ""
  15. }
  16. return false
  17. }
  18. get_environment_color :: proc() -> Color_Depth {
  19. buf: [128]u8
  20. // `COLORTERM` is non-standard but widespread and unambiguous.
  21. if colorterm, err := os.lookup_env(buf[:], "COLORTERM"); err == nil {
  22. // These are the only values that are typically advertised that have
  23. // anything to do with color depth.
  24. if colorterm == "truecolor" || colorterm == "24bit" {
  25. return .True_Color
  26. }
  27. }
  28. if term, err := os.lookup_env(buf[:], "TERM"); err == nil {
  29. if strings.contains(term, "-truecolor") {
  30. return .True_Color
  31. }
  32. if strings.contains(term, "-256color") {
  33. return .Eight_Bit
  34. }
  35. if strings.contains(term, "-16color") {
  36. return .Four_Bit
  37. }
  38. // The `terminfo` database, which is stored in binary on *nix
  39. // platforms, has an undocumented format that is not guaranteed to be
  40. // portable, so beyond this point, we can only make safe assumptions.
  41. //
  42. // This section should only be necessary for terminals that do not
  43. // define any of the previous environment values.
  44. //
  45. // Only a small sampling of some common values are checked here.
  46. switch term {
  47. case "ansi": fallthrough
  48. case "konsole": fallthrough
  49. case "putty": fallthrough
  50. case "rxvt": fallthrough
  51. case "rxvt-color": fallthrough
  52. case "screen": fallthrough
  53. case "st": fallthrough
  54. case "tmux": fallthrough
  55. case "vte": fallthrough
  56. case "xterm": fallthrough
  57. case "xterm-color":
  58. return .Three_Bit
  59. }
  60. }
  61. return .None
  62. }
  63. @(init)
  64. init_terminal :: proc "contextless" () {
  65. _init_terminal()
  66. context = runtime.default_context()
  67. // We respect `NO_COLOR` specifically as a color-disabler but not as a
  68. // blanket ban on any terminal manipulation codes, hence why this comes
  69. // after `_init_terminal` which will allow Windows to enable Virtual
  70. // Terminal Processing for non-color control sequences.
  71. if !get_no_color() {
  72. color_enabled = color_depth > .None
  73. }
  74. }
  75. @(fini)
  76. fini_terminal :: proc "contextless" () {
  77. _fini_terminal()
  78. }