aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml2
-rw-r--r--CHANGELOG.md13
-rw-r--r--docs/classes/bitflags.html2
-rw-r--r--docs/examples/compat.lua.html2
-rw-r--r--docs/examples/flag_debugging.lua.html2
-rw-r--r--docs/examples/password_input.lua.html2
-rw-r--r--docs/examples/read.lua.html2
-rw-r--r--docs/examples/readline.lua.html2
-rw-r--r--docs/examples/spinner.lua.html2
-rw-r--r--docs/examples/spiral_snake.lua.html2
-rw-r--r--docs/examples/terminalsize.lua.html2
-rw-r--r--docs/index.html2
-rw-r--r--docs/modules/system.html15
-rw-r--r--docs/topics/01-introduction.md.html2
-rw-r--r--docs/topics/02-development.md.html2
-rw-r--r--docs/topics/03-terminal.md.html2
-rw-r--r--docs/topics/CHANGELOG.md.html15
-rw-r--r--docs/topics/LICENSE.md.html2
-rw-r--r--rockspecs/luasystem-0.6.3-1.rockspec85
-rw-r--r--spec/04-term_spec.lua10
-rw-r--r--src/core.c2
-rw-r--r--src/term.c15
-rw-r--r--system/init.lua33
23 files changed, 183 insertions, 35 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b90b7de..5b3d31a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -97,7 +97,7 @@ jobs:
97 97
98 - uses: hishamhm/gh-actions-luarocks@master 98 - uses: hishamhm/gh-actions-luarocks@master
99 with: 99 with:
100 luaRocksVersion: "3.11.0" 100 luaRocksVersion: "3.12.0"
101 101
102 - name: test dependencies 102 - name: test dependencies
103 run: | 103 run: |
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4107d6..3b00fb6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,9 +27,20 @@ The scope of what is covered by the version number excludes:
27 27
28## Version history 28## Version history
29 29
30### version 0.6.3, released 11-Jul-2025
31
32- Fix: maximum key-delay, reduced from 0.2 to 0.1 seconds to reduce slugginess feel on some key presses.
33 See [#69](https://github.com/lunarmodules/luasystem/pull/69).
34- Fix: `readansi` now only reports printable chars as characters
35 See [#70](https://github.com/lunarmodules/luasystem/pull/70).
36- Fix: readkey now ignores Windows scancodes if received.
37 See [#74](https://github.com/lunarmodules/luasystem/pull/74).
38- Fix: readkey now passes errors on.
39 See [#74](https://github.com/lunarmodules/luasystem/pull/74).
40
30### version 0.6.2, released 15-Apr-2025 41### version 0.6.2, released 15-Apr-2025
31 42
32 - Fix: autotermrestore didn't work because its metatable was overwritten. 43- Fix: autotermrestore didn't work because its metatable was overwritten.
33 44
34### version 0.6.1, released 13-Apr-2025 45### version 0.6.1, released 13-Apr-2025
35 46
diff --git a/docs/classes/bitflags.html b/docs/classes/bitflags.html
index e11e39a..7637aeb 100644
--- a/docs/classes/bitflags.html
+++ b/docs/classes/bitflags.html
@@ -298,7 +298,7 @@ return <code>false</code> if the flags are checked.
298</div> <!-- id="main" --> 298</div> <!-- id="main" -->
299<div id="about"> 299<div id="about">
300<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 300<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
301<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 301<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
302</div> <!-- id="about" --> 302</div> <!-- id="about" -->
303</div> <!-- id="container" --> 303</div> <!-- id="container" -->
304</body> 304</body>
diff --git a/docs/examples/compat.lua.html b/docs/examples/compat.lua.html
index ab4caab..ca4e489 100644
--- a/docs/examples/compat.lua.html
+++ b/docs/examples/compat.lua.html
@@ -112,7 +112,7 @@
112</div> <!-- id="main" --> 112</div> <!-- id="main" -->
113<div id="about"> 113<div id="about">
114<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 114<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
115<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 115<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
116</div> <!-- id="about" --> 116</div> <!-- id="about" -->
117</div> <!-- id="container" --> 117</div> <!-- id="container" -->
118</body> 118</body>
diff --git a/docs/examples/flag_debugging.lua.html b/docs/examples/flag_debugging.lua.html
index 3fd5cd7..dba4471 100644
--- a/docs/examples/flag_debugging.lua.html
+++ b/docs/examples/flag_debugging.lua.html
@@ -80,7 +80,7 @@
80</div> <!-- id="main" --> 80</div> <!-- id="main" -->
81<div id="about"> 81<div id="about">
82<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 82<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
83<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 83<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
84</div> <!-- id="about" --> 84</div> <!-- id="about" -->
85</div> <!-- id="container" --> 85</div> <!-- id="container" -->
86</body> 86</body>
diff --git a/docs/examples/password_input.lua.html b/docs/examples/password_input.lua.html
index 65d6e17..342b066 100644
--- a/docs/examples/password_input.lua.html
+++ b/docs/examples/password_input.lua.html
@@ -132,7 +132,7 @@ useful for reading secrets from the user.
132</div> <!-- id="main" --> 132</div> <!-- id="main" -->
133<div id="about"> 133<div id="about">
134<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 134<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
135<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 135<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
136</div> <!-- id="about" --> 136</div> <!-- id="about" -->
137</div> <!-- id="container" --> 137</div> <!-- id="container" -->
138</body> 138</body>
diff --git a/docs/examples/read.lua.html b/docs/examples/read.lua.html
index 3e29b64..4995bda 100644
--- a/docs/examples/read.lua.html
+++ b/docs/examples/read.lua.html
@@ -143,7 +143,7 @@ sys.<span class="function-name">setnonblock</span>(<span class="global">io</span
143</div> <!-- id="main" --> 143</div> <!-- id="main" -->
144<div id="about"> 144<div id="about">
145<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 145<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
146<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 146<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
147</div> <!-- id="about" --> 147</div> <!-- id="about" -->
148</div> <!-- id="container" --> 148</div> <!-- id="container" -->
149</body> 149</body>
diff --git a/docs/examples/readline.lua.html b/docs/examples/readline.lua.html
index 265021e..493de2c 100644
--- a/docs/examples/readline.lua.html
+++ b/docs/examples/readline.lua.html
@@ -549,7 +549,7 @@ sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</
549</div> <!-- id="main" --> 549</div> <!-- id="main" -->
550<div id="about"> 550<div id="about">
551<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 551<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
552<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 552<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
553</div> <!-- id="about" --> 553</div> <!-- id="about" -->
554</div> <!-- id="container" --> 554</div> <!-- id="container" -->
555</body> 555</body>
diff --git a/docs/examples/spinner.lua.html b/docs/examples/spinner.lua.html
index 6141dd5..6e2d63a 100644
--- a/docs/examples/spinner.lua.html
+++ b/docs/examples/spinner.lua.html
@@ -137,7 +137,7 @@ sys.<span class="function-name">setnonblock</span>(<span class="global">io</span
137</div> <!-- id="main" --> 137</div> <!-- id="main" -->
138<div id="about"> 138<div id="about">
139<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 139<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
140<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 140<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
141</div> <!-- id="about" --> 141</div> <!-- id="about" -->
142</div> <!-- id="container" --> 142</div> <!-- id="container" -->
143</body> 143</body>
diff --git a/docs/examples/spiral_snake.lua.html b/docs/examples/spiral_snake.lua.html
index 8432fb1..97d5f77 100644
--- a/docs/examples/spiral_snake.lua.html
+++ b/docs/examples/spiral_snake.lua.html
@@ -145,7 +145,7 @@ codes for moving the cursor around.
145</div> <!-- id="main" --> 145</div> <!-- id="main" -->
146<div id="about"> 146<div id="about">
147<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 147<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
148<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 148<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
149</div> <!-- id="about" --> 149</div> <!-- id="about" -->
150</div> <!-- id="container" --> 150</div> <!-- id="container" -->
151</body> 151</body>
diff --git a/docs/examples/terminalsize.lua.html b/docs/examples/terminalsize.lua.html
index 610803b..d3486bb 100644
--- a/docs/examples/terminalsize.lua.html
+++ b/docs/examples/terminalsize.lua.html
@@ -110,7 +110,7 @@ sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.
110</div> <!-- id="main" --> 110</div> <!-- id="main" -->
111<div id="about"> 111<div id="about">
112<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 112<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
113<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 113<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
114</div> <!-- id="about" --> 114</div> <!-- id="about" -->
115</div> <!-- id="container" --> 115</div> <!-- id="container" -->
116</body> 116</body>
diff --git a/docs/index.html b/docs/index.html
index a4446a7..e901d08 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -142,7 +142,7 @@
142</div> <!-- id="main" --> 142</div> <!-- id="main" -->
143<div id="about"> 143<div id="about">
144<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 144<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
145<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 145<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
146</div> <!-- id="about" --> 146</div> <!-- id="about" -->
147</div> <!-- id="container" --> 147</div> <!-- id="container" -->
148</body> 148</body>
diff --git a/docs/modules/system.html b/docs/modules/system.html
index 6840b85..0a2447e 100644
--- a/docs/modules/system.html
+++ b/docs/modules/system.html
@@ -1051,7 +1051,7 @@ sequences will be buffered internally and returned one byte at a time.
1051 the character that was received (can be multi-byte), or a complete ANSI sequence</li> 1051 the character that was received (can be multi-byte), or a complete ANSI sequence</li>
1052 <li> 1052 <li>
1053 <span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span> 1053 <span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
1054 the type of input: <code>&quot;char&quot;</code> for a single key, <code>&quot;ansi&quot;</code> for an ANSI sequence</li> 1054 the type of input: <code>&quot;ctrl&quot;</code> for 0-31 and 127 bytes, <code>&quot;char&quot;</code> for other UTF-8 characters, <code>&quot;ansi&quot;</code> for an ANSI sequence</li>
1055 </ol> 1055 </ol>
1056 <h3>Or</h3> 1056 <h3>Or</h3>
1057 <ol> 1057 <ol>
@@ -1070,6 +1070,15 @@ sequences will be buffered internally and returned one byte at a time.
1070 1070
1071 1071
1072 1072
1073 <h3>Usage:</h3>
1074 <ul>
1075 <pre class="example"><span class="keyword">local</span> key, keytype = system.<span class="function-name">readansi</span>(<span class="number">5</span>)
1076<span class="keyword">if</span> keytype == <span class="string">"char"</span> <span class="keyword">then</span> ... <span class="keyword">end</span> <span class="comment">-- printable character
1077</span><span class="keyword">if</span> keytype ~= <span class="string">"char"</span> <span class="keyword">then</span> ... <span class="keyword">end</span> <span class="comment">-- non-printable character or sequence
1078</span><span class="keyword">if</span> keytype == <span class="string">"ansi"</span> <span class="keyword">then</span> ... <span class="keyword">end</span> <span class="comment">-- a multi-byte sequence, but not a UTF8 character
1079</span><span class="keyword">if</span> keytype ~= <span class="string">"ansi"</span> <span class="keyword">then</span> ... <span class="keyword">end</span> <span class="comment">-- a valid UTF8 character (which includes control characters)
1080</span><span class="keyword">if</span> keytype == <span class="string">"ctrl"</span> <span class="keyword">then</span> ... <span class="keyword">end</span> <span class="comment">-- a single-byte ctrl character (0-31, 127)</span></pre>
1081 </ul>
1073 1082
1074</dd> 1083</dd>
1075 <dt> 1084 <dt>
@@ -1079,7 +1088,7 @@ sequences will be buffered internally and returned one byte at a time.
1079 <dd> 1088 <dd>
1080 Reads a single byte from the console, with a timeout. 1089 Reads a single byte from the console, with a timeout.
1081 This function uses <code>fsleep</code> to wait until either a byte is available or the timeout is reached. 1090 This function uses <code>fsleep</code> to wait until either a byte is available or the timeout is reached.
1082 The sleep period is exponentially backing off, starting at 0.0125 seconds, with a maximum of 0.2 seconds. 1091 The sleep period is exponentially backing off, starting at 0.0125 seconds, with a maximum of 0.1 seconds.
1083 It returns immediately if a byte is available or if <code>timeout</code> is less than or equal to <code>0</code>.</p> 1092 It returns immediately if a byte is available or if <code>timeout</code> is less than or equal to <code>0</code>.</p>
1084 1093
1085<p> Using <a href="../modules/system.html#readansi">system.readansi</a> is preferred over this function. Since this function can leave stray/invalid 1094<p> Using <a href="../modules/system.html#readansi">system.readansi</a> is preferred over this function. Since this function can leave stray/invalid
@@ -1509,7 +1518,7 @@ This function will sleep, without doing a busy-loop and wasting CPU cycles.
1509</div> <!-- id="main" --> 1518</div> <!-- id="main" -->
1510<div id="about"> 1519<div id="about">
1511<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 1520<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
1512<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 1521<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
1513</div> <!-- id="about" --> 1522</div> <!-- id="about" -->
1514</div> <!-- id="container" --> 1523</div> <!-- id="container" -->
1515</body> 1524</body>
diff --git a/docs/topics/01-introduction.md.html b/docs/topics/01-introduction.md.html
index 5667e71..264aa71 100644
--- a/docs/topics/01-introduction.md.html
+++ b/docs/topics/01-introduction.md.html
@@ -84,7 +84,7 @@ independence.</p>
84</div> <!-- id="main" --> 84</div> <!-- id="main" -->
85<div id="about"> 85<div id="about">
86<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 86<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
87<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 87<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
88</div> <!-- id="about" --> 88</div> <!-- id="about" -->
89</div> <!-- id="container" --> 89</div> <!-- id="container" -->
90</body> 90</body>
diff --git a/docs/topics/02-development.md.html b/docs/topics/02-development.md.html
index 2432c98..15efe55 100644
--- a/docs/topics/02-development.md.html
+++ b/docs/topics/02-development.md.html
@@ -84,7 +84,7 @@ pass locally, and do not rely on CI only.</p>
84</div> <!-- id="main" --> 84</div> <!-- id="main" -->
85<div id="about"> 85<div id="about">
86<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 86<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
87<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 87<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
88</div> <!-- id="about" --> 88</div> <!-- id="about" -->
89</div> <!-- id="container" --> 89</div> <!-- id="container" -->
90</body> 90</body>
diff --git a/docs/topics/03-terminal.md.html b/docs/topics/03-terminal.md.html
index a7b600a..27772ac 100644
--- a/docs/topics/03-terminal.md.html
+++ b/docs/topics/03-terminal.md.html
@@ -220,7 +220,7 @@ For an example see <a href="../examples/password_input.lua.html"><code>examples/
220</div> <!-- id="main" --> 220</div> <!-- id="main" -->
221<div id="about"> 221<div id="about">
222<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 222<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
223<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 223<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
224</div> <!-- id="about" --> 224</div> <!-- id="about" -->
225</div> <!-- id="container" --> 225</div> <!-- id="container" -->
226</body> 226</body>
diff --git a/docs/topics/CHANGELOG.md.html b/docs/topics/CHANGELOG.md.html
index 8cd2966..9603abd 100644
--- a/docs/topics/CHANGELOG.md.html
+++ b/docs/topics/CHANGELOG.md.html
@@ -106,6 +106,19 @@
106<p><a name="Version_history"></a></p> 106<p><a name="Version_history"></a></p>
107<h2>Version history</h2> 107<h2>Version history</h2>
108 108
109<h3>version 0.6.3, released 11-Jul-2025</h3>
110
111<ul>
112 <li>Fix: maximum key-delay, reduced from 0.2 to 0.1 seconds to reduce slugginess feel on some key presses.
113 See <a href="https://github.com/lunarmodules/luasystem/pull/69">#69</a>.</li>
114 <li>Fix: <code>readansi</code> now only reports printable chars as characters
115 See <a href="https://github.com/lunarmodules/luasystem/pull/70">#70</a>.</li>
116 <li>Fix: readkey now ignores Windows scancodes if received.
117 See <a href="https://github.com/lunarmodules/luasystem/pull/74">#74</a>.</li>
118 <li>Fix: readkey now passes errors on.
119 See <a href="https://github.com/lunarmodules/luasystem/pull/74">#74</a>.</li>
120</ul>
121
109<h3>version 0.6.2, released 15-Apr-2025</h3> 122<h3>version 0.6.2, released 15-Apr-2025</h3>
110 123
111<ul> 124<ul>
@@ -221,7 +234,7 @@
221</div> <!-- id="main" --> 234</div> <!-- id="main" -->
222<div id="about"> 235<div id="about">
223<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 236<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
224<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 237<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
225</div> <!-- id="about" --> 238</div> <!-- id="about" -->
226</div> <!-- id="container" --> 239</div> <!-- id="container" -->
227</body> 240</body>
diff --git a/docs/topics/LICENSE.md.html b/docs/topics/LICENSE.md.html
index 90bdaa3..c0b9b93 100644
--- a/docs/topics/LICENSE.md.html
+++ b/docs/topics/LICENSE.md.html
@@ -94,7 +94,7 @@ SOFTWARE.</p>
94</div> <!-- id="main" --> 94</div> <!-- id="main" -->
95<div id="about"> 95<div id="about">
96<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> 96<i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i>
97<i style="float:right;">Last updated 2025-04-17 09:50:39 </i> 97<i style="float:right;">Last updated 2025-07-11 22:55:05 </i>
98</div> <!-- id="about" --> 98</div> <!-- id="about" -->
99</div> <!-- id="container" --> 99</div> <!-- id="container" -->
100</body> 100</body>
diff --git a/rockspecs/luasystem-0.6.3-1.rockspec b/rockspecs/luasystem-0.6.3-1.rockspec
new file mode 100644
index 0000000..e70373f
--- /dev/null
+++ b/rockspecs/luasystem-0.6.3-1.rockspec
@@ -0,0 +1,85 @@
1local package_name = "luasystem"
2local package_version = "0.6.3"
3local rockspec_revision = "1"
4local github_account_name = "lunarmodules"
5local github_repo_name = "luasystem"
6
7
8package = package_name
9version = package_version.."-"..rockspec_revision
10
11source = {
12 url = "git+https://github.com/"..github_account_name.."/"..github_repo_name..".git",
13 branch = (package_version == "scm") and "master" or nil,
14 tag = (package_version ~= "scm") and "v"..package_version or nil,
15}
16
17description = {
18 summary = 'Platform independent system calls for Lua.',
19 detailed = [[
20 Adds a Lua API for making platform independent system calls.
21 ]],
22 license = 'MIT <http://opensource.org/licenses/MIT>',
23 homepage = "https://github.com/"..github_account_name.."/"..github_repo_name,
24}
25
26dependencies = {
27 'lua >= 5.1',
28}
29
30local function make_platform(plat)
31 local defines = {
32 linux = { },
33 unix = { },
34 macosx = { },
35 win32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
36 mingw32 = { "WINVER=0x0600", "_WIN32_WINNT=0x0600" },
37 }
38 local libraries = {
39 linux = { "rt" },
40 unix = { },
41 macosx = { },
42 win32 = { "advapi32", "winmm", "bcrypt" },
43 mingw32 = { },
44 }
45 local libdirs = {
46 linux = nil,
47 unix = nil,
48 macosx = nil,
49 win32 = nil,
50 mingw32 = { },
51 }
52 return {
53 modules = {
54 ['system.core'] = {
55 sources = {
56 'src/core.c',
57 'src/compat.c',
58 'src/time.c',
59 'src/environment.c',
60 'src/random.c',
61 'src/term.c',
62 'src/bitflags.c',
63 'src/wcwidth.c',
64 },
65 defines = defines[plat],
66 libraries = libraries[plat],
67 libdirs = libdirs[plat],
68 },
69 },
70 }
71end
72
73build = {
74 type = 'builtin',
75 platforms = {
76 linux = make_platform('linux'),
77 unix = make_platform('unix'),
78 macosx = make_platform('macosx'),
79 win32 = make_platform('win32'),
80 mingw32 = make_platform('mingw32'),
81 },
82 modules = {
83 ['system.init'] = 'system/init.lua',
84 },
85}
diff --git a/spec/04-term_spec.lua b/spec/04-term_spec.lua
index 0ce0033..5dea046 100644
--- a/spec/04-term_spec.lua
+++ b/spec/04-term_spec.lua
@@ -902,6 +902,14 @@ describe("Terminal:", function()
902 end) 902 end)
903 903
904 904
905 it("reads a control byte for single-byte control characters", function()
906 setbuffer("\000\031\127")
907 assert.are.same({"\000", "ctrl"}, {system.readansi(0)})
908 assert.are.same({"\031", "ctrl"}, {system.readansi(0)})
909 assert.are.same({"\127", "ctrl"}, {system.readansi(0)})
910 end)
911
912
905 it("reads a multi-byte characters one at a time", function() 913 it("reads a multi-byte characters one at a time", function()
906 setbuffer(string.char(226, 130, 172) .. -- "€" single 914 setbuffer(string.char(226, 130, 172) .. -- "€" single
907 string.char(240, 159, 154, 128)) -- "🚀" double 915 string.char(240, 159, 154, 128)) -- "🚀" double
@@ -952,7 +960,7 @@ describe("Terminal:", function()
952 960
953 it("returns a single <esc> character if no sequence is found", function() 961 it("returns a single <esc> character if no sequence is found", function()
954 setbuffer("\27") 962 setbuffer("\27")
955 assert.are.same({"\27", "char"}, {system.readansi(0)}) 963 assert.are.same({"\27", "ctrl"}, {system.readansi(0)})
956 end) 964 end)
957 965
958 966
diff --git a/src/core.c b/src/core.c
index 7776de4..34e19d8 100644
--- a/src/core.c
+++ b/src/core.c
@@ -4,7 +4,7 @@
4#include <lua.h> 4#include <lua.h>
5#include <lauxlib.h> 5#include <lauxlib.h>
6 6
7#define LUASYSTEM_VERSION "LuaSystem 0.6.2" 7#define LUASYSTEM_VERSION "LuaSystem 0.6.3"
8 8
9#ifdef _WIN32 9#ifdef _WIN32
10#define LUAEXPORT __declspec(dllexport) 10#define LUAEXPORT __declspec(dllexport)
diff --git a/src/term.c b/src/term.c
index 6927bd9..0325208 100644
--- a/src/term.c
+++ b/src/term.c
@@ -908,7 +908,18 @@ static int lst_readkey(lua_State *L) {
908 } 908 }
909 909
910 wchar_t wc = _getwch(); 910 wchar_t wc = _getwch();
911 // printf("----\nread wchar_t: %x\n", wc); 911 // printf("----\nread wchar_t: %x\n", (unsigned int)wc);
912
913 if (wc == 0x00 || wc == 0xE0) {
914 // printf("Ignoring scan code: %x\n", (unsigned int)wc);
915 // On Windows, especially with key-repeat, we can get native scancodes even if we've set the console
916 // to ANSI mode. Something, something, terminal not keeping up... These are not valid wide characters,
917 // so we ignore them. Scan codes start with either 0x00 or 0xE0, and have a follow up byte, which we all ignore.
918 // These codes are unique, so we do not risk dropping valid data.
919 _getwch(); // Discard 2nd half of the scan code
920 return 0;
921 }
922
912 if (wc == WEOF) { 923 if (wc == WEOF) {
913 lua_pushnil(L); 924 lua_pushnil(L);
914 lua_pushliteral(L, "read error"); 925 lua_pushliteral(L, "read error");
@@ -929,7 +940,7 @@ static int lst_readkey(lua_State *L) {
929 } 940 }
930 941
931 wchar_t wc2 = _getwch(); 942 wchar_t wc2 = _getwch();
932 // printf("read wchar_t 2: %x\n", wc2); 943 // printf("read wchar_t 2: %x\n", (unsigned int)wc2);
933 if (wc2 == WEOF) { 944 if (wc2 == WEOF) {
934 lua_pushnil(L); 945 lua_pushnil(L);
935 lua_pushliteral(L, "read error"); 946 lua_pushliteral(L, "read error");
diff --git a/system/init.lua b/system/init.lua
index 9c86c4a..9b71d4d 100644
--- a/system/init.lua
+++ b/system/init.lua
@@ -239,7 +239,7 @@ end
239do 239do
240 --- Reads a single byte from the console, with a timeout. 240 --- Reads a single byte from the console, with a timeout.
241 -- This function uses `fsleep` to wait until either a byte is available or the timeout is reached. 241 -- This function uses `fsleep` to wait until either a byte is available or the timeout is reached.
242 -- The sleep period is exponentially backing off, starting at 0.0125 seconds, with a maximum of 0.2 seconds. 242 -- The sleep period is exponentially backing off, starting at 0.0125 seconds, with a maximum of 0.1 seconds.
243 -- It returns immediately if a byte is available or if `timeout` is less than or equal to `0`. 243 -- It returns immediately if a byte is available or if `timeout` is less than or equal to `0`.
244 -- 244 --
245 -- Using `system.readansi` is preferred over this function. Since this function can leave stray/invalid 245 -- Using `system.readansi` is preferred over this function. Since this function can leave stray/invalid
@@ -256,19 +256,23 @@ do
256 end 256 end
257 257
258 local interval = 0.0125 258 local interval = 0.0125
259 local key = system._readkey() 259 local ok
260 local key, err = system._readkey()
260 while key == nil and timeout > 0 do 261 while key == nil and timeout > 0 do
261 local ok, err = (fsleep or system.sleep)(math.min(interval, timeout)) 262 if err then
263 return nil, err
264 end
265 ok, err = (fsleep or system.sleep)(math.min(interval, timeout))
262 if not ok then 266 if not ok then
263 return nil, err 267 return nil, err
264 end 268 end
265 timeout = timeout - interval 269 timeout = timeout - interval
266 interval = math.min(0.2, interval * 2) 270 interval = math.min(0.1, interval * 2)
267 key = system._readkey() 271 key, err = system._readkey()
268 end 272 end
269 273
270 if key then 274 if key or err then
271 return key 275 return key, err
272 end 276 end
273 return nil, "timeout" 277 return nil, "timeout"
274 end 278 end
@@ -290,13 +294,20 @@ do
290 -- @tparam number timeout the timeout in seconds. 294 -- @tparam number timeout the timeout in seconds.
291 -- @tparam[opt=system.sleep] function fsleep the function to call for sleeping. 295 -- @tparam[opt=system.sleep] function fsleep the function to call for sleeping.
292 -- @treturn[1] string the character that was received (can be multi-byte), or a complete ANSI sequence 296 -- @treturn[1] string the character that was received (can be multi-byte), or a complete ANSI sequence
293 -- @treturn[1] string the type of input: `"char"` for a single key, `"ansi"` for an ANSI sequence 297 -- @treturn[1] string the type of input: `"ctrl"` for 0-31 and 127 bytes, `"char"` for other UTF-8 characters, `"ansi"` for an ANSI sequence
294 -- @treturn[2] nil in case of an error 298 -- @treturn[2] nil in case of an error
295 -- @treturn[2] string error message; `"timeout"` if the timeout was reached. 299 -- @treturn[2] string error message; `"timeout"` if the timeout was reached.
296 -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far. 300 -- @treturn[2] string partial result in case of an error while reading a sequence, the sequence so far.
297 -- The function retains its own internal buffer, so on the next call the incomplete buffer is used to 301 -- The function retains its own internal buffer, so on the next call the incomplete buffer is used to
298 -- complete the sequence. 302 -- complete the sequence.
299 -- @within Terminal_Input 303 -- @within Terminal_Input
304 -- @usage
305 -- local key, keytype = system.readansi(5)
306 -- if keytype == "char" then ... end -- printable character
307 -- if keytype ~= "char" then ... end -- non-printable character or sequence
308 -- if keytype == "ansi" then ... end -- a multi-byte sequence, but not a UTF8 character
309 -- if keytype ~= "ansi" then ... end -- a valid UTF8 character (which includes control characters)
310 -- if keytype == "ctrl" then ... end -- a single-byte ctrl character (0-31, 127)
300 function system.readansi(timeout, fsleep) 311 function system.readansi(timeout, fsleep)
301 if type(timeout) ~= "number" then 312 if type(timeout) ~= "number" then
302 error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2) 313 error("arg #1 to readansi, expected timeout in seconds, got " .. type(timeout), 2)
@@ -320,7 +331,7 @@ do
320 if key2 == nil then 331 if key2 == nil then
321 -- no key available, return the escape key, on its own 332 -- no key available, return the escape key, on its own
322 sequence = nil 333 sequence = nil
323 return string.char(key), "char" 334 return string.char(key), "ctrl"
324 335
325 elseif key2 == 91 then 336 elseif key2 == 91 then
326 -- "[" means it is for sure an ANSI sequence 337 -- "[" means it is for sure an ANSI sequence
@@ -351,10 +362,10 @@ do
351 else 362 else
352 -- check UTF8 length 363 -- check UTF8 length
353 utf8_length = key < 128 and 1 or key < 224 and 2 or key < 240 and 3 or key < 248 and 4 364 utf8_length = key < 128 and 1 or key < 224 and 2 or key < 240 and 3 or key < 248 and 4
354 if utf8_length == 1 then 365 if utf8_length == 1 then
355 -- single byte character 366 -- single byte character
356 utf8_length = nil 367 utf8_length = nil
357 return string.char(key), "char" 368 return string.char(key), ((key <= 31 or key == 127) and "ctrl" or "char")
358 else 369 else
359 -- UTF8 sequence detected 370 -- UTF8 sequence detected
360 sequence = { key } 371 sequence = { key }