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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
--!A cross-platform build utility based on Lua
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-- Copyright (C) 2015-present, Xmake Open Source Community.
--
-- @author ruki
-- @file curses.lua
--
-- define module: curses
local curses = curses or {}
-- load modules
local os = require("base/os")
local log = require("ui/log")
-- get color from the given name
function curses.color(name)
if name == 'black' then return curses.COLOR_BLACK
elseif name == 'red' then return curses.COLOR_RED
elseif name == 'green' then return curses.COLOR_GREEN
elseif name == 'yellow' then return curses.COLOR_YELLOW
elseif name == 'blue' then return curses.COLOR_BLUE
elseif name == 'magenta' then return curses.COLOR_MAGENTA
elseif name == 'cyan' then return curses.COLOR_CYAN
elseif name == 'white' then return curses.COLOR_WHITE
else return curses.COLOR_BLACK
end
end
-- is color?
local colors = {black = true, red = true, green = true, yellow = true, blue = true, magenta = true, cyan = true, white = true}
function curses.iscolor(name)
return colors[name] or colors[name:sub(3) or ""]
end
-- get attr from the given name
function curses.attr(name)
if name == 'normal' then return curses.A_NORMAL
elseif name == 'standout' then return curses.A_STANDOUT
elseif name == 'underline' then return curses.A_UNDERLINE
elseif name == 'reverse' then return curses.A_REVERSE
elseif name == 'blink' then return curses.A_BLINK
elseif name == 'dim' then return curses.A_DIM
elseif name == 'bold' then return curses.A_BOLD
elseif name == 'protect' then return curses.A_PROTECT
elseif name == 'invis' then return curses.A_INVIS
elseif name == 'alt' then return curses.A_ALTCHARSET
else return curses.A_NORMAL
end
end
-- get acs character from the given name
function curses.acs(name)
if name == 'block' then return curses.ACS_BLOCK
elseif name == 'board' then return curses.ACS_BOARD
elseif name == 'btee' then return curses.ACS_BTEE
elseif name == 'bullet' then return curses.ACS_BULLET
elseif name == 'ckboard' then return curses.ACS_CKBOARD
elseif name == 'darrow' then return curses.ACS_DARROW
elseif name == 'degree' then return curses.ACS_DEGREE
elseif name == 'diamond' then return curses.ACS_DIAMOND
elseif name == 'gequal' then return curses.ACS_GEQUAL
elseif name == 'hline' then return curses.ACS_HLINE
elseif name == 'lantern' then return curses.ACS_LANTERN
elseif name == 'larrow' then return curses.ACS_LARROW
elseif name == 'lequal' then return curses.ACS_LEQUAL
elseif name == 'llcorner' then return curses.ACS_LLCORNER
elseif name == 'lrcorner' then return curses.ACS_LRCORNER
elseif name == 'ltee' then return curses.ACS_LTEE
elseif name == 'nequal' then return curses.ACS_NEQUAL
elseif name == 'pi' then return curses.ACS_PI
elseif name == 'plminus' then return curses.ACS_PLMINUS
elseif name == 'plus' then return curses.ACS_PLUS
elseif name == 'rarrow' then return curses.ACS_RARROW
elseif name == 'rtee' then return curses.ACS_RTEE
elseif name == 's1' then return curses.ACS_S1
elseif name == 's3' then return curses.ACS_S3
elseif name == 's7' then return curses.ACS_S7
elseif name == 's9' then return curses.ACS_S9
elseif name == 'sterling' then return curses.ACS_STERLING
elseif name == 'ttee' then return curses.ACS_TTEE
elseif name == 'uarrow' then return curses.ACS_UARROW
elseif name == 'ulcorner' then return curses.ACS_ULCORNER
elseif name == 'urcorner' then return curses.ACS_URCORNER
elseif name == 'vline' then return curses.ACS_VLINE
elseif type(name) == 'string' and #name == 1 then
return name
else
return ' '
end
end
-- calculate attr from the attributes list
--
-- local attr = curses.calc_attr("bold")
-- local attr = curses.calc_attr("yellow")
-- local attr = curses.calc_attr{ "yellow", "ongreen" }
-- local attr = curses.calc_attr{ "yellow", "ongreen", "bold" }
-- local attr = curses.calc_attr{ curses.color_pair("yellow", "green"), "bold" }
--
function curses.calc_attr(attrs)
-- curses.calc_attr(curses.A_BOLD)
-- curses.calc_attr(curses.color_pair("yellow", "green"))
local atype = type(attrs)
if atype == "number" then
return attrs
-- curses.calc_attr("bold")
-- curses.calc_attr("yellow")
elseif atype == "string" then
if curses.iscolor(attrs) then
local color = attrs
if color:startswith("on") then
color = color:sub(3)
end
return curses.color_pair(color, color)
end
return curses.attr(attrs)
-- curses.calc_attr{ "yellow", "ongreen", "bold" }
-- curses.calc_attr{ curses.color_pair("yellow", "green"), "bold" }
elseif atype == "table" then
local v = 0
local set = {}
local fg = nil
local bg = nil
for _, a in ipairs(attrs) do
if not set[a] and a then
set[a] = true
if type(a) == "number" then
v = v + a
elseif curses.iscolor(a) then
if a:startswith("on") then
bg = a:sub(3)
else
fg = a
end
else
v = v + curses.attr(a)
end
end
end
if fg or bg then
v = v + curses.color_pair(fg or bg, bg or fg)
end
return v
else
return 0
end
end
-- get attr from the color pair
curses._color_pair = curses._color_pair or curses.color_pair
function curses.color_pair(fg, bg)
-- get foreground and backround color
fg = curses.color(fg)
bg = curses.color(bg)
-- attempt to get color from the cache first
local key = fg .. ':' .. bg
local colors = curses._COLORS or {}
if colors[key] then
return colors[key]
end
-- no colors?
if not curses.has_colors() then
return 0
end
-- update the colors count
curses._NCOLORS = (curses._NCOLORS or 0) + 1
-- init the color pair
if not curses.init_pair(curses._NCOLORS, fg, bg) then
os.raise("failed to initialize color pair (%d, %s, %s)", curses._NCOLORS, fg, bg)
end
-- get the color attr
local attr = curses._color_pair(curses._NCOLORS)
-- save to cache
colors[key] = attr
curses._COLORS = colors
-- ok
return attr
end
-- set cursor state
curses._cursor_set = curses._cursor_set or curses.cursor_set
function curses.cursor_set(state)
if curses._CURSOR_STATE ~= state then
curses._CURSOR_STATE = state
curses._cursor_set(state)
end
end
-- has mouse?
function curses.has_mouse()
return curses.KEY_MOUSE and true or false
end
-- return module: curses
return curses
|