summary refs log tree commit diff stats
path: root/lib/pure/terminal.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2009-06-08 08:06:25 +0200
committerAndreas Rumpf <rumpf_a@web.de>2009-06-08 08:06:25 +0200
commit4d4b3b1c04d41868ebb58bd9ccba7b303007e900 (patch)
tree909ed0aad0b145733521f4ac2bfb938dd4b43785 /lib/pure/terminal.nim
parentce88dc3e67436939b03f97e624c11ca6058fedce (diff)
downloadNim-4d4b3b1c04d41868ebb58bd9ccba7b303007e900.tar.gz
version0.7.10
Diffstat (limited to 'lib/pure/terminal.nim')
-rw-r--r--lib/pure/terminal.nim310
1 files changed, 310 insertions, 0 deletions
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
new file mode 100644
index 000000000..42bd80cb4
--- /dev/null
+++ b/lib/pure/terminal.nim
@@ -0,0 +1,310 @@
+#

+#

+#            Nimrod's Runtime Library

+#        (c) Copyright 2009 Andreas Rumpf

+#

+#    See the file "copying.txt", included in this

+#    distribution, for details about the copyright.

+#

+

+## This module contains a few procedures to control the *terminal* 

+## (also called *console*). On UNIX, the implementation simply uses ANSI escape 

+## sequences and does not depend on any other module, on Windows it uses the

+## Windows API.

+## Changing the style is permanent even after program termination! Use the

+## code ``system.addQuitProc(resetAttributes)`` to restore the defaults.

+

+when defined(windows):

+  import windows, os

+  

+  var 

+    conHandle: THandle

+  # = createFile("CONOUT$", GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0)

+    

+  block:

+    var hTemp = GetStdHandle(STD_OUTPUT_HANDLE())

+    if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(),

+                       addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0:

+      OSError()

+    

+  proc getCursorPos(): tuple [x,y: int] = 

+    var c: TCONSOLE_SCREEN_BUFFER_INFO

+    if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0: OSError()

+    return (int(c.dwCursorPosition.x), int(c.dwCursorPosition.y))

+    

+  proc getAttributes(): int16 = 

+    var c: TCONSOLE_SCREEN_BUFFER_INFO

+    # workaround Windows bugs: try several times

+    if GetConsoleScreenBufferInfo(conHandle, addr(c)) != 0: 

+      return c.wAttributes

+    else:

+      OSError()

+    return 0x70'i16 # ERROR: return white background, black text

+    

+  var

+    oldAttr = getAttributes()

+

+proc setCursorPos*(x, y: int) =

+  ## sets the terminal's cursor to the (x,y) position. (0,0) is the 

+  ## upper left of the screen. 

+  when defined(windows):

+    var c: TCoord

+    c.x = int16(x)

+    c.y = int16(y)

+    if SetConsoleCursorPosition(conHandle, c) == 0: OSError()

+  else:

+    stdout.write("\e[" & $y & ';' & $x & 'f')

+
+proc setCursorXPos*(x: int) =

+  ## sets the terminal's cursor to the x position. The y position is
+  ## not changed.

+  when defined(windows):

+    var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO

+    var hStdout = conHandle

+    if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()

+    var origin = scrbuf.dwCursorPosition

+    origin.x = int16(x)

+    if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()
+  else:

+    stdout.write("\e[" & $x & 'G')

+
+when defined(windows):
+  proc setCursorYPos*(y: int) =

+    ## sets the terminal's cursor to the y position. The x position is
+    ## not changed. **Warning**: This is not supported on UNIX!

+    when defined(windows):

+      var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO

+      var hStdout = conHandle

+      if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()

+      var origin = scrbuf.dwCursorPosition

+      origin.y = int16(y)

+      if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()
+    else:

+      nil

+

+proc CursorUp*(count=1) = 

+  ## Moves the cursor up by `count` rows.

+  when defined(windows):

+    var p = getCursorPos()

+    dec(p.y, count)

+    setCursorPos(p.x, p.y)

+  else:

+    stdout.write("\e[" & $count & 'A')

+

+proc CursorDown*(count=1) = 

+  ## Moves the cursor down by `count` rows.

+  when defined(windows):

+    var p = getCursorPos()

+    inc(p.y, count)

+    setCursorPos(p.x, p.y)

+  else:

+    stdout.write("\e[" & $count & 'B')

+

+proc CursorForward*(count=1) = 

+  ## Moves the cursor forward by `count` columns.

+  when defined(windows):

+    var p = getCursorPos()

+    inc(p.x, count)

+    setCursorPos(p.x, p.y)

+  else:

+    stdout.write("\e[" & $count & 'C')

+

+proc CursorBackward*(count=1) = 

+  ## Moves the cursor backward by `count` columns.

+  when defined(windows):

+    var p = getCursorPos()

+    dec(p.x, count)

+    setCursorPos(p.x, p.y)

+  else:

+    stdout.write("\e[" & $count & 'D')

+  

+when true:

+  nil

+else:

+  proc EraseLineEnd* =

+    ## Erases from the current cursor position to the end of the current line.

+    when defined(windows):

+      nil

+    else:

+      stdout.write("\e[K")

+  

+  proc EraseLineStart* =

+    ## Erases from the current cursor position to the start of the current line.

+    when defined(windows):

+      nil

+    else:

+      stdout.write("\e[1K")

+  

+  proc EraseDown* =

+    ## Erases the screen from the current line down to the bottom of the screen.

+    when defined(windows):

+      nil

+    else:

+      stdout.write("\e[J")

+  

+  proc EraseUp* =

+    ## Erases the screen from the current line up to the top of the screen.

+    when defined(windows):

+      nil

+    else:

+      stdout.write("\e[1J")

+  

+proc EraseLine* =

+  ## Erases the entire current line.

+  when defined(windows):

+    var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO

+    var numwrote: DWORD

+    var hStdout = conHandle

+    if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()

+    var origin = scrbuf.dwCursorPosition

+    origin.x = 0'i16

+    if SetConsoleCursorPosition(conHandle, origin) == 0: OSError()

+    var ht = scrbuf.dwSize.Y - origin.Y

+    var wt = scrbuf.dwSize.X - origin.X

+    if FillConsoleOutputCharacter(hStdout,' ', ht*wt, 

+                                  origin, addr(numwrote)) == 0:

+      OSError()

+    if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt,

+                                  scrbuf.dwCursorPosition, addr(numwrote)) == 0:

+      OSError()

+  else:

+    stdout.write("\e[2K")
+    setCursorXPos(0)

+

+proc EraseScreen* =

+  ## Erases the screen with the background colour and moves the cursor to home.

+  when defined(windows):

+    var scrbuf: TCONSOLE_SCREEN_BUFFER_INFO

+    var numwrote: DWORD

+    var origin: TCoord # is inititalized to 0, 0 

+    var hStdout = conHandle

+    if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0: OSError()

+    if FillConsoleOutputCharacter(hStdout, ' ', scrbuf.dwSize.X*scrbuf.dwSize.Y,

+                                  origin, addr(numwrote)) == 0:

+      OSError()

+    if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes,

+                                  scrbuf.dwSize.X * scrbuf.dwSize.Y, 

+                                  origin, addr(numwrote)) == 0:

+      OSError()

+    setCursorXPos(0)

+  else:

+    stdout.write("\e[2J")

+

+proc ResetAttributes* {.noconv.} = 

+  ## resets all attributes; it is advisable to register this as a quit proc

+  ## with ``system.addQuitProc(resetAttributes)``. 

+  when defined(windows):

+    discard SetConsoleTextAttribute(conHandle, oldAttr)

+  else:

+    stdout.write("\e[0m")

+

+type

+  TStyle* = enum         ## different styles for text output

+    styleBright = 1,     ## bright text

+    styleDim,            ## dim text

+    styleUnknown,        ## unknown

+    styleUnderscore = 4, ## underscored text

+    styleBlink,          ## blinking/bold text

+    styleReverse,        ## unknown

+    styleHidden          ## hidden text

+

+when not defined(windows):

+  var

+    gFG = 0

+    gBG = 0

+

+proc WriteStyled*(txt: string, style: set[TStyle] = {styleBright}) = 

+  ## writes the text `txt` in a given `style`.

+  when defined(windows):

+    var a = 0'i16

+    if styleBright in style: a = a or int16(FOREGROUND_INTENSITY)

+    if styleBlink in style: a = a or int16(BACKGROUND_INTENSITY)

+    if styleReverse in style: a = a or 0x4000'i16 # COMMON_LVB_REVERSE_VIDEO

+    if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE

+    var old = getAttributes()

+    discard SetConsoleTextAttribute(conHandle, old or a)

+    stdout.write(txt)

+    discard SetConsoleTextAttribute(conHandle, old)

+  else:

+    for s in items(style):

+      stdout.write("\e[" & $ord(s) & 'm')

+    stdout.write(txt)

+    resetAttributes()

+    if gFG != 0: 

+      stdout.write("\e[" & $ord(gFG) & 'm')  

+    if gBG != 0:

+      stdout.write("\e[" & $ord(gBG) & 'm')

+

+type

+  TForegroundColor* = enum ## terminal's foreground colors

+    fgBlack = 30,          ## black

+    fgRed,                 ## red

+    fgGreen,               ## green

+    fgYellow,              ## yellow

+    fgBlue,                ## blue

+    fgMagenta,             ## magenta

+    fgCyan,                ## cyan

+    fgWhite                ## white

+

+  TBackgroundColor* = enum ## terminal's background colors

+    bgBlack = 40,          ## black

+    bgRed,                 ## red

+    bgGreen,               ## green

+    bgYellow,              ## yellow

+    bgBlue,                ## blue

+    bgMagenta,             ## magenta

+    bgCyan,                ## cyan

+    bgWhite                ## white

+  

+proc setForegroundColor*(fg: TForegroundColor, bright=false) = 

+  ## sets the terminal's foreground color

+  when defined(windows):

+    var old = getAttributes() and not 0x0007 

+    if bright: 

+      old = old or FOREGROUND_INTENSITY

+    const lookup: array [TForegroundColor, int] = [

+      0,

+      (FOREGROUND_RED),

+      (FOREGROUND_GREEN),

+      (FOREGROUND_RED or FOREGROUND_GREEN),

+      (FOREGROUND_BLUE),

+      (FOREGROUND_RED or FOREGROUND_BLUE),

+      (FOREGROUND_BLUE or FOREGROUND_GREEN),

+      (FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)]

+    discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[fg]))

+  else:

+    gFG = ord(fg)

+    if bright: inc(gFG, 60)

+    stdout.write("\e[" & $gFG & 'm')

+

+proc setBackgroundColor*(bg: TBackgroundColor, bright=false) = 

+  ## sets the terminal's background color

+  when defined(windows):

+    var old = getAttributes() and not 0x0070

+    if bright: 

+      old = old or BACKGROUND_INTENSITY

+    const lookup: array [TBackgroundColor, int] = [

+      0,

+      (BACKGROUND_RED),

+      (BACKGROUND_GREEN),

+      (BACKGROUND_RED or BACKGROUND_GREEN),

+      (BACKGROUND_BLUE),

+      (BACKGROUND_RED or BACKGROUND_BLUE),

+      (BACKGROUND_BLUE or BACKGROUND_GREEN),

+      (BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)]

+    discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[bg]))

+  else:

+    gBG = ord(bg)

+    if bright: inc(gBG, 60)

+    stdout.write("\e[" & $gBG & 'm')

+

+when isMainModule:

+  system.addQuitProc(resetAttributes)

+  write(stdout, "never mind")

+  eraseLine()

+  #setCursorPos(2, 2)

+  writeStyled("styled text ", {styleBright, styleBlink, styleUnderscore})

+  setBackGroundColor(bgCyan, true)

+  setForeGroundColor(fgBlue)

+  writeln(stdout, "ordinary text")

+

vabit.com> 2009-11-24 00:41:16 +0100 committer hut <hut@lavabit.com> 2009-11-24 00:41:16 +0100 better implementation of directories/files' href='/akspecs/ranger/commit/test/tc_directory.py?h=v1.5.0&id=fae694a03ebb52888a747010fcb92fa43b33b4a8'>fae694a0 ^
fe179145 ^
fae694a0 ^
9506fb8e ^

f6f26231 ^
4c05e43d ^
f6f26231 ^







9506fb8e ^
fae694a0 ^

f6f26231 ^










4c05e43d ^

fae694a0 ^

fe179145 ^
5822dff7 ^

fe179145 ^
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118