New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support truecolor in a terminal #6936
Conversation
I don't mind the feature but IMO |
Example's code: import terminal
const Nim = "Efficient and expressive programming."
var
fg = colYellow
bg = colBlue
int = 1.0
for i in 1..10:
styledEcho bgColor, bg, fgColor, fg, Nim
int -= 0.05
fg = intensity(fg, int)
styledEcho resetStyle @Araq |
Hmm, my point was that |
I added the setForegroundColor*(stdout, color) and setBackgroundColor*(color: Color) templates only for consistency, because there is already setForegroundColor*(fg: ForegroundColor, bright = false), setBackgroundColor*(bg: BackgroundColor, bright=false) and others. |
Maybe it's still useful to someone: Colours in terminal :) |
If Windows does not support it, make it not compile on Windows, this should all be within an |
Windows support added. (Tested on Windows 10 in VirtualBox). |
lib/pure/terminal.nim
Outdated
var | ||
trueColorIsSupported = false | ||
fgSetColor = true | ||
colorsFGCache = initTable[Color, string]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaks multi-threading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is done?
lib/pure/terminal.nim
Outdated
from strutils import toLowerAscii | ||
import tables | ||
import colors | ||
export colors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think terminal
should export colors
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/pure/terminal.nim
Outdated
when defined(windows): | ||
var mode: DWORD = 0 | ||
discard getConsoleMode(getStdHandle(STD_OUTPUT_HANDLE), addr(mode)) | ||
mode = mode or ENABLE_VIRTUAL_TERMINAL_PROCESSING |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change ... Previously no escape sequences were interpreted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe to add (enable|disable|isSupported)TrueColor procs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change, please don't do this at initialization but only if requested via enableTrueColor
.
lib/pure/terminal.nim
Outdated
trueColorIsSupported = setConsoleMode(getStdHandle(STD_OUTPUT_HANDLE), mode) != 0 | ||
else: | ||
when compileOption("taintmode"): | ||
trueColorIsSupported = string(getEnv("COLORTERM")).toLowerAscii() in ["truecolor", "24bit"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version works for a disabled taint mode too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
lib/windows/winlean.nim
Outdated
@@ -1059,6 +1059,28 @@ else: | |||
lpNumberOfEventsRead: ptr cint): cint | |||
{.stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".} | |||
|
|||
const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are all terminal specific and so should be in terminal.nim.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Hanging a tests on AppVeyor after last commit :( |
lib/pure/terminal.nim
Outdated
@@ -677,3 +750,18 @@ when not defined(testing) and isMainModule: | |||
stdout.setForeGroundColor(fgBlue) | |||
stdout.writeLine("ordinary text") | |||
stdout.resetAttributes() | |||
|
|||
fgSetColor = true | |||
colorsFGCache = initTable[Color, string]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only works for the main thread. ;-)
lib/pure/terminal.nim
Outdated
styleCache = newTable[int, string]() | ||
|
||
fgSetColor = true | ||
colorsFGCache = newTable[Color, string]() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This only runs for the main thread!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I really do not understand what is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
He means that the colorsFGCache
will only be initialised in the main thread. If you try using it from another thread it will be nil
and your code will likely fail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
I looked at the code in the /tests/parallel/tsendtwice.nim.
It works there. Or not?
Maybe disable caching when the thread mode is defined? |
… term_truecolor
Corrections for Windows. |
Hm, true color for Windows < 10 probably can be used with a non-standard terminals, e.g. ConEmu. |
Added support for non-standard terminals. |
var | ||
fg = colYellow | ||
bg = colBlue | ||
int = 1.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a variable called 'int' that is of type float? Come on. ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
intensity :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be changed. Don't name your variables after types.
changelog.md
Outdated
bg = colBlue | ||
int = 1.0 | ||
|
||
enableTrueColor() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be called enableTrueColors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Quite looking forward to a merge on this pull request. 👍 |
|
||
proc setForegroundColor*(f: File, color: Color) = | ||
## Sets the terminal's foreground true color. | ||
if trueColorIsEnabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be assert(trueColorIsEnabled, "enableTrueColors() must be called before setForegroundColor")
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Because a true color may be used for debugging with a colored messages.
|
||
proc setBackgroundColor*(f: File, color: Color) = | ||
## Sets the terminal's background true color. | ||
if trueColorIsEnabled: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same answer.
styleCache: Table[int, string] | ||
|
||
var | ||
trueColorIsSupported {.threadvar.}: bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These threadvars are still not correct!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't understand: why a threadvars in other modules are correct?
lib/pure/terminal.nim
Outdated
fgSetColor = true | ||
|
||
when defined(windows): | ||
import os |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this logic should be moved into enableTrueColors
!
gFG = 0 | ||
gBG = 0 | ||
gFG {.threadvar.}: int | ||
gBG {.threadvar.}: int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is far too many global thread variables in this module (and this isn't your fault). But these should all be put into a single State
object, eventually at least.
gFG {.threadvar.}: int | ||
gBG {.threadvar.}: int | ||
|
||
proc getStyleStr(style: int): string = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're losing type safety here. The styleCache
can be changed to an array[Style, string]
Currently for *nix only.
Example output (in Konsole):