Back to this subject (and to Nim).
To **demotomohiro** : Thanks, **-d:nimDontSetUtf8CodePage** does indeed half
the job needed, by creating an executable that does not change Windows console
code-page.
The other half of the job is to have a piece of software that internally uses
UTF-8, so that the same source code works the same in Windows and Linux.
In this context **echo** should be overloaded, so that source code using it
does not have to be changed, but **io** module functions (like **readLine** )
should be left unchanged, since no function used for file I/O should be
tampered with.
So I came up with the following solution:
#console.nim
when system.hostOS == "windows":
import encodings
import rdstdin
import strutils
let consoleEncoding = getCurrentEncoding()
let consoleEncoder = encodings.open(consoleEncoding, "UTF-8") #stdout
let consoleDecoder = encodings.open("UTF-8", consoleEncoding) #stdin
template echo(x: varargs[string, `$`]) {.used.} =
echo consoleEncoder.convert(x.join(""))
template readLineFromStdin(prompt: string): TaintedString {.used.} =
consoleDecoder.convert(readLineFromStdin(prompt).string).TaintedString
template readLineFromStdin(prompt: string; line: var TaintedString): bool
{.used.} =
var ts: TaintedString
result = readLineFromStdin(prompt, ts)
line = consoleDecoder.convert(ts.string).TaintedString
proc readLine(): string {.used.} =
consoleDecoder.convert(stdin.readLine.string)
else:
proc readLine(): string {.used.} = stdin.readLine.string
Run
and
import strutils
import unicode
include console
for cp in readLine().utf8:
echo cp.toHex, ' ', if cp == "\e": "ESC" else: cp
Run
**console** has to be **included** , not **imported** , for overloading to
work.
Now things work on Windows as they should have had from the beginning (that is
like on Linux).
**Input:**
τεστ
Run
**Output:**
CF84 τ
CEB5 ε
CF83 σ
CF84 τ
Run
I wonder why things are not already done this way in Nim, since the way things
are done does not work anyway.