diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2024-06-20 23:16:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-20 23:16:29 +0200 |
commit | bb4fd73c317cc88beb5e58c1abf52138abed107f (patch) | |
tree | 35b774efc97d820a908424a5bc2452e0d6bf12a8 /docs/examples | |
parent | c1a64c1b75f97cef97965b3bd9a941564a6270bd (diff) | |
download | luasystem-0.4.0.tar.gz luasystem-0.4.0.tar.bz2 luasystem-0.4.0.zip |
Release v0.4.0 (#24)v0.4.0
Diffstat (limited to 'docs/examples')
-rw-r--r-- | docs/examples/compat.lua.html | 119 | ||||
-rw-r--r-- | docs/examples/flag_debugging.lua.html | 87 | ||||
-rw-r--r-- | docs/examples/password_input.lua.html | 139 | ||||
-rw-r--r-- | docs/examples/read.lua.html | 150 | ||||
-rw-r--r-- | docs/examples/readline.lua.html | 552 | ||||
-rw-r--r-- | docs/examples/spinner.lua.html | 144 | ||||
-rw-r--r-- | docs/examples/spiral_snake.lua.html | 152 | ||||
-rw-r--r-- | docs/examples/terminalsize.lua.html | 117 |
8 files changed, 1460 insertions, 0 deletions
diff --git a/docs/examples/compat.lua.html b/docs/examples/compat.lua.html new file mode 100644 index 0000000..a0abafe --- /dev/null +++ b/docs/examples/compat.lua.html | |||
@@ -0,0 +1,119 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><strong>compat.lua</strong></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>compat.lua</h2> | ||
69 | <pre> | ||
70 | <span class="comment">-- This example shows how to remove platform differences to create a | ||
71 | </span><span class="comment">-- cross-platform level playing field. | ||
72 | </span> | ||
73 | <span class="keyword">local</span> sys = <span class="global">require</span> <span class="string">"system"</span> | ||
74 | |||
75 | |||
76 | |||
77 | <span class="keyword">if</span> sys.windows <span class="keyword">then</span> | ||
78 | <span class="comment">-- Windows holds multiple copies of environment variables, to ensure <code>getenv</code> | ||
79 | </span> <span class="comment">-- returns what <code>setenv</code> sets we need to use the <a href="../modules/system.html#getenv">system.getenv</a> instead of | ||
80 | </span> <span class="comment">-- <a href="https://www.lua.org/manual/5.4/manual.html#pdf-os.getenv">os.getenv</a>. | ||
81 | </span> <span class="global">os</span>.getenv = sys.getenv <span class="comment">-- luacheck: ignore | ||
82 | </span> | ||
83 | <span class="comment">-- Set console output to UTF-8 encoding. | ||
84 | </span> sys.<span class="function-name">setconsoleoutputcp</span>(sys.CODEPAGE_UTF8) | ||
85 | |||
86 | <span class="comment">-- Set up the terminal to handle ANSI escape sequences on Windows. | ||
87 | </span> <span class="keyword">if</span> sys.<span class="function-name">isatty</span>(<span class="global">io</span>.stdout) <span class="keyword">then</span> | ||
88 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
89 | <span class="keyword">end</span> | ||
90 | <span class="keyword">if</span> sys.<span class="function-name">isatty</span>(<span class="global">io</span>.stderr) <span class="keyword">then</span> | ||
91 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stderr, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stderr) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
92 | <span class="keyword">end</span> | ||
93 | <span class="keyword">if</span> sys.<span class="function-name">isatty</span>(<span class="global">io</span>.stdin) <span class="keyword">then</span> | ||
94 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.ENABLE_VIRTUAL_TERMINAL_INPUT) | ||
95 | <span class="keyword">end</span> | ||
96 | |||
97 | |||
98 | <span class="keyword">else</span> | ||
99 | <span class="comment">-- On Posix, one can set a variable to an empty string, but on Windows, this | ||
100 | </span> <span class="comment">-- will remove the variable from the environment. To make this consistent | ||
101 | </span> <span class="comment">-- across platforms, we will remove the variable from the environment if the | ||
102 | </span> <span class="comment">-- value is an empty string. | ||
103 | </span> <span class="keyword">local</span> old_setenv = sys.setenv | ||
104 | <span class="keyword">function</span> sys.<span class="function-name">setenv</span>(name, value) | ||
105 | <span class="keyword">if</span> value == <span class="string">""</span> <span class="keyword">then</span> value = <span class="keyword">nil</span> <span class="keyword">end</span> | ||
106 | <span class="keyword">return</span> <span class="function-name">old_setenv</span>(name, value) | ||
107 | <span class="keyword">end</span> | ||
108 | <span class="keyword">end</span></pre> | ||
109 | |||
110 | |||
111 | </div> <!-- id="content" --> | ||
112 | </div> <!-- id="main" --> | ||
113 | <div id="about"> | ||
114 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
115 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
116 | </div> <!-- id="about" --> | ||
117 | </div> <!-- id="container" --> | ||
118 | </body> | ||
119 | </html> | ||
diff --git a/docs/examples/flag_debugging.lua.html b/docs/examples/flag_debugging.lua.html new file mode 100644 index 0000000..38f506a --- /dev/null +++ b/docs/examples/flag_debugging.lua.html | |||
@@ -0,0 +1,87 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><strong>flag_debugging.lua</strong></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>flag_debugging.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span> <span class="string">"system"</span> | ||
71 | |||
72 | <span class="comment">-- Print the Windows Console flags for stdin | ||
73 | </span>sys.<span class="function-name">listconsoleflags</span>(<span class="global">io</span>.stdin) | ||
74 | |||
75 | <span class="comment">-- Print the Posix termios flags for stdin | ||
76 | </span>sys.<span class="function-name">listtermflags</span>(<span class="global">io</span>.stdin)</pre> | ||
77 | |||
78 | |||
79 | </div> <!-- id="content" --> | ||
80 | </div> <!-- id="main" --> | ||
81 | <div id="about"> | ||
82 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
83 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
84 | </div> <!-- id="about" --> | ||
85 | </div> <!-- id="container" --> | ||
86 | </body> | ||
87 | </html> | ||
diff --git a/docs/examples/password_input.lua.html b/docs/examples/password_input.lua.html new file mode 100644 index 0000000..4234fbb --- /dev/null +++ b/docs/examples/password_input.lua.html | |||
@@ -0,0 +1,139 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><strong>password_input.lua</strong></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>password_input.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span> <span class="string">"system"</span> | ||
71 | |||
72 | <span class="global">print</span> <span class="string">[[ | ||
73 | |||
74 | This example shows how to disable the "echo" of characters read to the console, | ||
75 | useful for reading secrets from the user. | ||
76 | |||
77 | ]]</span> | ||
78 | |||
79 | <span class="comment">--- Function to read from stdin without echoing the input (for secrets etc). | ||
80 | </span><span class="comment">-- It will (in a platform agnostic way) disable echo on the terminal, read the | ||
81 | </span><span class="comment">-- input, and then re-enable echo. | ||
82 | </span><span class="comment">-- @param ... Arguments to pass to <code>io.stdin:read()</code> | ||
83 | </span><span class="comment">-- @return the results of <code>io.stdin:read(...)</code> | ||
84 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">read_secret</span>(...) | ||
85 | <span class="keyword">local</span> w_oldflags, p_oldflags | ||
86 | |||
87 | <span class="keyword">if</span> sys.<span class="function-name">isatty</span>(<span class="global">io</span>.stdin) <span class="keyword">then</span> | ||
88 | <span class="comment">-- backup settings, configure echo flags | ||
89 | </span> w_oldflags = sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) | ||
90 | p_oldflags = sys.<span class="function-name">tcgetattr</span>(<span class="global">io</span>.stdin) | ||
91 | <span class="comment">-- set echo off to not show password on screen | ||
92 | </span> <span class="global">assert</span>(sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, w_oldflags - sys.CIF_ECHO_INPUT)) | ||
93 | <span class="global">assert</span>(sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, { lflag = p_oldflags.lflag - sys.L_ECHO })) | ||
94 | <span class="keyword">end</span> | ||
95 | |||
96 | <span class="keyword">local</span> secret, err = <span class="global">io</span>.stdin:<span class="function-name">read</span>(...) | ||
97 | |||
98 | <span class="comment">-- restore settings | ||
99 | </span> <span class="keyword">if</span> sys.<span class="function-name">isatty</span>(<span class="global">io</span>.stdin) <span class="keyword">then</span> | ||
100 | <span class="global">io</span>.stdout:<span class="function-name">write</span>(<span class="string">"\n"</span>) <span class="comment">-- Add newline after reading the password | ||
101 | </span> sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, w_oldflags) | ||
102 | sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, p_oldflags) | ||
103 | <span class="keyword">end</span> | ||
104 | |||
105 | <span class="keyword">return</span> secret, err | ||
106 | <span class="keyword">end</span> | ||
107 | |||
108 | |||
109 | |||
110 | <span class="comment">-- Get username | ||
111 | </span><span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"Username: "</span>) | ||
112 | <span class="keyword">local</span> username = <span class="global">io</span>.stdin:<span class="function-name">read</span>(<span class="string">"*l"</span>) | ||
113 | |||
114 | <span class="comment">-- Get the secret | ||
115 | </span><span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"Password: "</span>) | ||
116 | <span class="keyword">local</span> password = <span class="function-name">read_secret</span>(<span class="string">"*l"</span>) | ||
117 | |||
118 | <span class="comment">-- Get domainname | ||
119 | </span><span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"Domain : "</span>) | ||
120 | <span class="keyword">local</span> domain = <span class="global">io</span>.stdin:<span class="function-name">read</span>(<span class="string">"*l"</span>) | ||
121 | |||
122 | |||
123 | <span class="comment">-- Print the results | ||
124 | </span><span class="global">print</span>(<span class="string">""</span>) | ||
125 | <span class="global">print</span>(<span class="string">"Here's what we got:"</span>) | ||
126 | <span class="global">print</span>(<span class="string">" username: "</span> .. username) | ||
127 | <span class="global">print</span>(<span class="string">" password: "</span> .. password) | ||
128 | <span class="global">print</span>(<span class="string">" domain : "</span> .. domain)</pre> | ||
129 | |||
130 | |||
131 | </div> <!-- id="content" --> | ||
132 | </div> <!-- id="main" --> | ||
133 | <div id="about"> | ||
134 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
135 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
136 | </div> <!-- id="about" --> | ||
137 | </div> <!-- id="container" --> | ||
138 | </body> | ||
139 | </html> | ||
diff --git a/docs/examples/read.lua.html b/docs/examples/read.lua.html new file mode 100644 index 0000000..c7697d3 --- /dev/null +++ b/docs/examples/read.lua.html | |||
@@ -0,0 +1,150 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><strong>read.lua</strong></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>read.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span> <span class="string">"system"</span> | ||
71 | |||
72 | <span class="global">print</span> <span class="string">[[ | ||
73 | |||
74 | This example shows how to do a non-blocking read from the cli. | ||
75 | |||
76 | ]]</span> | ||
77 | |||
78 | <span class="comment">-- setup Windows console to handle ANSI processing | ||
79 | </span><span class="keyword">local</span> of_in = sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) | ||
80 | <span class="keyword">local</span> of_out = sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) | ||
81 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
82 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) + sys.CIF_VIRTUAL_TERMINAL_INPUT) | ||
83 | |||
84 | <span class="comment">-- setup Posix terminal to use non-blocking mode, and disable line-mode | ||
85 | </span><span class="keyword">local</span> of_attr = sys.<span class="function-name">tcgetattr</span>(<span class="global">io</span>.stdin) | ||
86 | <span class="keyword">local</span> of_block = sys.<span class="function-name">getnonblock</span>(<span class="global">io</span>.stdin) | ||
87 | sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, <span class="keyword">true</span>) | ||
88 | sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, { | ||
89 | lflag = of_attr.lflag - sys.L_ICANON - sys.L_ECHO, <span class="comment">-- disable canonical mode and echo | ||
90 | </span>}) | ||
91 | |||
92 | <span class="comment">-- cursor sequences | ||
93 | </span><span class="keyword">local</span> get_cursor_pos = <span class="string">"\27[6n"</span> | ||
94 | |||
95 | |||
96 | |||
97 | <span class="global">print</span>(<span class="string">"Press a key, or 'A' to get cursor position, 'ESC' to exit"</span>) | ||
98 | <span class="keyword">while</span> <span class="keyword">true</span> <span class="keyword">do</span> | ||
99 | <span class="keyword">local</span> key, keytype | ||
100 | |||
101 | <span class="comment">-- wait for a key | ||
102 | </span> <span class="keyword">while</span> <span class="keyword">not</span> key <span class="keyword">do</span> | ||
103 | key, keytype = sys.<span class="function-name">readansi</span>(<span class="global">math</span>.huge) | ||
104 | <span class="keyword">end</span> | ||
105 | |||
106 | <span class="keyword">if</span> key == <span class="string">"A"</span> <span class="keyword">then</span> <span class="global">io</span>.<span class="function-name">write</span>(get_cursor_pos); <span class="global">io</span>.<span class="function-name">flush</span>() <span class="keyword">end</span> | ||
107 | |||
108 | <span class="comment">-- check if we got a key or ANSI sequence | ||
109 | </span> <span class="keyword">if</span> keytype == <span class="string">"char"</span> <span class="keyword">then</span> | ||
110 | <span class="comment">-- just a key | ||
111 | </span> <span class="keyword">local</span> b = key:<span class="function-name">byte</span>() | ||
112 | <span class="keyword">if</span> b < <span class="number">32</span> <span class="keyword">then</span> | ||
113 | key = <span class="string">"."</span> <span class="comment">-- replace control characters with a simple "." to not mess up the screen | ||
114 | </span> <span class="keyword">end</span> | ||
115 | |||
116 | <span class="global">print</span>(<span class="string">"you pressed: "</span> .. key .. <span class="string">" ("</span> .. b .. <span class="string">")"</span>) | ||
117 | <span class="keyword">if</span> b == <span class="number">27</span> <span class="keyword">then</span> | ||
118 | <span class="global">print</span>(<span class="string">"Escape pressed, exiting"</span>) | ||
119 | <span class="keyword">break</span> | ||
120 | <span class="keyword">end</span> | ||
121 | |||
122 | <span class="keyword">elseif</span> keytype == <span class="string">"ansi"</span> <span class="keyword">then</span> | ||
123 | <span class="comment">-- we got an ANSI sequence | ||
124 | </span> <span class="keyword">local</span> seq = { key:<span class="function-name">byte</span>(<span class="number">1</span>, #key) } | ||
125 | <span class="global">print</span>(<span class="string">"ANSI sequence received: "</span> .. key:<span class="function-name">sub</span>(<span class="number">2</span>,-<span class="number">1</span>), <span class="string">"(bytes: "</span> .. <span class="global">table</span>.<span class="function-name">concat</span>(seq, <span class="string">", "</span>)..<span class="string">")"</span>) | ||
126 | |||
127 | <span class="keyword">else</span> | ||
128 | <span class="global">print</span>(<span class="string">"unknown key type received: "</span> .. <span class="global">tostring</span>(keytype)) | ||
129 | <span class="keyword">end</span> | ||
130 | <span class="keyword">end</span> | ||
131 | |||
132 | |||
133 | |||
134 | <span class="comment">-- Clean up afterwards | ||
135 | </span>sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, <span class="keyword">false</span>) | ||
136 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, of_out) | ||
137 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, of_in) | ||
138 | sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, of_attr) | ||
139 | sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, of_block)</pre> | ||
140 | |||
141 | |||
142 | </div> <!-- id="content" --> | ||
143 | </div> <!-- id="main" --> | ||
144 | <div id="about"> | ||
145 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
146 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
147 | </div> <!-- id="about" --> | ||
148 | </div> <!-- id="container" --> | ||
149 | </body> | ||
150 | </html> | ||
diff --git a/docs/examples/readline.lua.html b/docs/examples/readline.lua.html new file mode 100644 index 0000000..7895a81 --- /dev/null +++ b/docs/examples/readline.lua.html | |||
@@ -0,0 +1,552 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><strong>readline.lua</strong></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>readline.lua</h2> | ||
69 | <pre> | ||
70 | <span class="comment">--- An example class for reading a line of input from the user in a non-blocking way. | ||
71 | </span><span class="comment">-- It uses ANSI escape sequences to move the cursor and handle input. | ||
72 | </span><span class="comment">-- It can be used to read a line of input from the user, with a prompt. | ||
73 | </span><span class="comment">-- It can handle double-width UTF-8 characters. | ||
74 | </span><span class="comment">-- It can be used asynchroneously if <a href="../modules/system.html#sleep">system.sleep</a> is patched to yield to a coroutine scheduler. | ||
75 | </span> | ||
76 | <span class="keyword">local</span> sys = <span class="global">require</span>(<span class="string">"system"</span>) | ||
77 | |||
78 | |||
79 | <span class="comment">-- Mapping of key-sequences to key-names | ||
80 | </span><span class="keyword">local</span> key_names = { | ||
81 | [<span class="string">"\27[C"</span>] = <span class="string">"right"</span>, | ||
82 | [<span class="string">"\27[D"</span>] = <span class="string">"left"</span>, | ||
83 | [<span class="string">"\127"</span>] = <span class="string">"backspace"</span>, | ||
84 | [<span class="string">"\27[3~"</span>] = <span class="string">"delete"</span>, | ||
85 | [<span class="string">"\27[H"</span>] = <span class="string">"home"</span>, | ||
86 | [<span class="string">"\27[F"</span>] = <span class="string">"end"</span>, | ||
87 | [<span class="string">"\27"</span>] = <span class="string">"escape"</span>, | ||
88 | [<span class="string">"\9"</span>] = <span class="string">"tab"</span>, | ||
89 | [<span class="string">"\27[Z"</span>] = <span class="string">"shift-tab"</span>, | ||
90 | } | ||
91 | |||
92 | <span class="keyword">if</span> sys.windows <span class="keyword">then</span> | ||
93 | key_names[<span class="string">"\13"</span>] = <span class="string">"enter"</span> | ||
94 | <span class="keyword">else</span> | ||
95 | key_names[<span class="string">"\10"</span>] = <span class="string">"enter"</span> | ||
96 | <span class="keyword">end</span> | ||
97 | |||
98 | |||
99 | <span class="comment">-- Mapping of key-names to key-sequences | ||
100 | </span><span class="keyword">local</span> key_sequences = {} | ||
101 | <span class="keyword">for</span> k, v <span class="keyword">in</span> <span class="global">pairs</span>(key_names) <span class="keyword">do</span> | ||
102 | key_sequences[v] = k | ||
103 | <span class="keyword">end</span> | ||
104 | |||
105 | |||
106 | <span class="comment">-- bell character | ||
107 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">bell</span>() | ||
108 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"\7"</span>) | ||
109 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
110 | <span class="keyword">end</span> | ||
111 | |||
112 | |||
113 | <span class="comment">-- generate string to move cursor horizontally | ||
114 | </span><span class="comment">-- positive goes right, negative goes left | ||
115 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">cursor_move_horiz</span>(n) | ||
116 | <span class="keyword">if</span> n == <span class="number">0</span> <span class="keyword">then</span> | ||
117 | <span class="keyword">return</span> <span class="string">""</span> | ||
118 | <span class="keyword">end</span> | ||
119 | <span class="keyword">return</span> <span class="string">"\27["</span> .. (n > <span class="number">0</span> <span class="keyword">and</span> n <span class="keyword">or</span> -n) .. (n > <span class="number">0</span> <span class="keyword">and</span> <span class="string">"C"</span> <span class="keyword">or</span> <span class="string">"D"</span>) | ||
120 | <span class="keyword">end</span> | ||
121 | |||
122 | |||
123 | <span class="comment">-- -- generate string to move cursor vertically | ||
124 | </span><span class="comment">-- -- positive goes down, negative goes up | ||
125 | </span><span class="comment">-- local function cursor_move_vert(n) | ||
126 | </span><span class="comment">-- if n == 0 then | ||
127 | </span><span class="comment">-- return "" | ||
128 | </span><span class="comment">-- end | ||
129 | </span><span class="comment">-- return "\27[" .. (n > 0 and n or -n) .. (n > 0 and "B" or "A") | ||
130 | </span><span class="comment">-- end | ||
131 | </span> | ||
132 | |||
133 | <span class="comment">-- -- log to the line above the current line | ||
134 | </span><span class="comment">-- local function log(...) | ||
135 | </span><span class="comment">-- local arg = { n = select("#", ...), ...} | ||
136 | </span><span class="comment">-- for i = 1, arg.n do | ||
137 | </span><span class="comment">-- arg[i] = tostring(arg[i]) | ||
138 | </span><span class="comment">-- end | ||
139 | </span><span class="comment">-- arg = " " .. table.concat(arg, " ") .. " " | ||
140 | </span> | ||
141 | <span class="comment">-- io.write(cursor_move_vert(-1), arg, cursor_move_vert(1), cursor_move_horiz(-#arg)) | ||
142 | </span><span class="comment">-- end | ||
143 | </span> | ||
144 | |||
145 | <span class="comment">-- UTF8 character size in bytes | ||
146 | </span><span class="comment">-- @tparam number b the byte value of the first byte of a UTF8 character | ||
147 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">utf8size</span>(b) | ||
148 | <span class="keyword">return</span> b < <span class="number">128</span> <span class="keyword">and</span> <span class="number">1</span> <span class="keyword">or</span> b < <span class="number">224</span> <span class="keyword">and</span> <span class="number">2</span> <span class="keyword">or</span> b < <span class="number">240</span> <span class="keyword">and</span> <span class="number">3</span> <span class="keyword">or</span> b < <span class="number">248</span> <span class="keyword">and</span> <span class="number">4</span> | ||
149 | <span class="keyword">end</span> | ||
150 | |||
151 | |||
152 | |||
153 | <span class="keyword">local</span> utf8parse <span class="keyword">do</span> | ||
154 | <span class="keyword">local</span> utf8_value_mt = { | ||
155 | __tostring = <span class="keyword">function</span>(self) | ||
156 | <span class="keyword">return</span> <span class="global">table</span>.<span class="function-name">concat</span>(self, <span class="string">""</span>) | ||
157 | <span class="keyword">end</span>, | ||
158 | } | ||
159 | |||
160 | <span class="comment">-- Parses a UTF8 string into list of individual characters. | ||
161 | </span> <span class="comment">-- key 'chars' gets the length in UTF8 characters, whilst # returns the length | ||
162 | </span> <span class="comment">-- for display (to handle double-width UTF8 chars). | ||
163 | </span> <span class="comment">-- in the list the double-width characters are followed by an empty string. | ||
164 | </span> <span class="comment">-- @tparam string s the UTF8 string to parse | ||
165 | </span> <span class="comment">-- @treturn table the list of characters | ||
166 | </span> <span class="keyword">function</span> <span class="function-name">utf8parse</span>(s) | ||
167 | <span class="keyword">local</span> t = <span class="global">setmetatable</span>({ chars = <span class="number">0</span> }, utf8_value_mt) | ||
168 | <span class="keyword">local</span> i = <span class="number">1</span> | ||
169 | <span class="keyword">while</span> i <= #s <span class="keyword">do</span> | ||
170 | <span class="keyword">local</span> b = s:<span class="function-name">byte</span>(i) | ||
171 | <span class="keyword">local</span> w = <span class="function-name">utf8size</span>(b) | ||
172 | <span class="keyword">local</span> char = s:<span class="function-name">sub</span>(i, i + w - <span class="number">1</span>) | ||
173 | t[#t + <span class="number">1</span>] = char | ||
174 | t.chars = t.chars + <span class="number">1</span> | ||
175 | <span class="keyword">if</span> sys.<span class="function-name">utf8cwidth</span>(char) == <span class="number">2</span> <span class="keyword">then</span> | ||
176 | <span class="comment">-- double width character, add empty string to keep the length of the | ||
177 | </span> <span class="comment">-- list the same as the character width on screen | ||
178 | </span> t[#t + <span class="number">1</span>] = <span class="string">""</span> | ||
179 | <span class="keyword">end</span> | ||
180 | i = i + w | ||
181 | <span class="keyword">end</span> | ||
182 | <span class="keyword">return</span> t | ||
183 | <span class="keyword">end</span> | ||
184 | <span class="keyword">end</span> | ||
185 | |||
186 | |||
187 | |||
188 | <span class="comment">-- inline tests for utf8parse | ||
189 | </span><span class="comment">-- do | ||
190 | </span><span class="comment">-- local t = utf8parse("aä½ b好c") | ||
191 | </span><span class="comment">-- assert(t[1] == "a") | ||
192 | </span><span class="comment">-- assert(t[2] == "ä½ ") -- double width | ||
193 | </span><span class="comment">-- assert(t[3] == "") | ||
194 | </span><span class="comment">-- assert(t[4] == "b") | ||
195 | </span><span class="comment">-- assert(t[5] == "好") -- double width | ||
196 | </span><span class="comment">-- assert(t[6] == "") | ||
197 | </span><span class="comment">-- assert(t[7] == "c") | ||
198 | </span><span class="comment">-- assert(#t == 7) -- size as displayed | ||
199 | </span><span class="comment">-- end | ||
200 | </span> | ||
201 | |||
202 | |||
203 | <span class="comment">-- readline class | ||
204 | </span> | ||
205 | <span class="keyword">local</span> readline = {} | ||
206 | readline.__index = readline | ||
207 | |||
208 | |||
209 | <span class="comment">--- Create a new readline object. | ||
210 | </span><span class="comment">-- @tparam table opts the options for the readline object | ||
211 | </span><span class="comment">-- @tparam[opt=""] string opts.prompt the prompt to display | ||
212 | </span><span class="comment">-- @tparam[opt=80] number opts.max_length the maximum length of the input (in characters, not bytes) | ||
213 | </span><span class="comment">-- @tparam[opt=""] string opts.value the default value | ||
214 | </span><span class="comment">-- @tparam[opt=<code>#value</code>] number opts.position of the cursor in the input | ||
215 | </span><span class="comment">-- @tparam[opt={"\10"/"\13"}] table opts.exit_keys an array of keys that will cause the readline to exit | ||
216 | </span><span class="comment">-- @treturn readline the new readline object | ||
217 | </span><span class="keyword">function</span> readline.<span class="function-name">new</span>(opts) | ||
218 | <span class="keyword">local</span> value = <span class="function-name">utf8parse</span>(opts.value <span class="keyword">or</span> <span class="string">""</span>) | ||
219 | <span class="keyword">local</span> prompt = <span class="function-name">utf8parse</span>(opts.prompt <span class="keyword">or</span> <span class="string">""</span>) | ||
220 | <span class="keyword">local</span> pos = <span class="global">math</span>.<span class="function-name">floor</span>(opts.position <span class="keyword">or</span> (#value + <span class="number">1</span>)) | ||
221 | pos = <span class="global">math</span>.<span class="function-name">max</span>(<span class="global">math</span>.<span class="function-name">min</span>(pos, (#value + <span class="number">1</span>)), <span class="number">1</span>) | ||
222 | <span class="keyword">local</span> len = <span class="global">math</span>.<span class="function-name">floor</span>(opts.max_length <span class="keyword">or</span> <span class="number">80</span>) | ||
223 | <span class="keyword">if</span> len < <span class="number">1</span> <span class="keyword">then</span> | ||
224 | <span class="global">error</span>(<span class="string">"max_length must be at least 1"</span>, <span class="number">2</span>) | ||
225 | <span class="keyword">end</span> | ||
226 | |||
227 | <span class="keyword">if</span> value.chars > len <span class="keyword">then</span> | ||
228 | <span class="global">error</span>(<span class="string">"value is longer than max_length"</span>, <span class="number">2</span>) | ||
229 | <span class="keyword">end</span> | ||
230 | |||
231 | <span class="keyword">local</span> exit_keys = {} | ||
232 | <span class="keyword">for</span> _, key <span class="keyword">in</span> <span class="global">ipairs</span>(opts.exit_keys <span class="keyword">or</span> {}) <span class="keyword">do</span> | ||
233 | exit_keys[key] = <span class="keyword">true</span> | ||
234 | <span class="keyword">end</span> | ||
235 | <span class="keyword">if</span> exit_keys[<span class="number">1</span>] == <span class="keyword">nil</span> <span class="keyword">then</span> | ||
236 | <span class="comment">-- nothing provided, default to Enter-key | ||
237 | </span> exit_keys[<span class="number">1</span>] = key_sequences.enter | ||
238 | <span class="keyword">end</span> | ||
239 | |||
240 | <span class="keyword">local</span> self = { | ||
241 | value = value, <span class="comment">-- the default value | ||
242 | </span> max_length = len, <span class="comment">-- the maximum length of the input | ||
243 | </span> prompt = prompt, <span class="comment">-- the prompt to display | ||
244 | </span> position = pos, <span class="comment">-- the current position in the input | ||
245 | </span> drawn_before = <span class="keyword">false</span>, <span class="comment">-- if the prompt has been drawn | ||
246 | </span> exit_keys = exit_keys, <span class="comment">-- the keys that will cause the readline to exit | ||
247 | </span> } | ||
248 | |||
249 | <span class="global">setmetatable</span>(self, readline) | ||
250 | <span class="keyword">return</span> self | ||
251 | <span class="keyword">end</span> | ||
252 | |||
253 | |||
254 | |||
255 | <span class="comment">-- draw the prompt and the input value, and position the cursor. | ||
256 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">draw</span>(self, redraw) | ||
257 | <span class="keyword">if</span> redraw <span class="keyword">or</span> <span class="keyword">not</span> self.drawn_before <span class="keyword">then</span> | ||
258 | <span class="comment">-- we are at start of prompt | ||
259 | </span> self.drawn_before = <span class="keyword">true</span> | ||
260 | <span class="keyword">else</span> | ||
261 | <span class="comment">-- we are at current cursor position, move to start of prompt | ||
262 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-(#self.prompt + self.position))) | ||
263 | <span class="keyword">end</span> | ||
264 | <span class="comment">-- write prompt & value | ||
265 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="global">tostring</span>(self.prompt) .. <span class="global">tostring</span>(self.value)) | ||
266 | <span class="comment">-- clear remainder of input size | ||
267 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="global">string</span>.<span class="function-name">rep</span>(<span class="string">" "</span>, self.max_length - self.value.chars)) | ||
268 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-(self.max_length - self.value.chars))) | ||
269 | <span class="comment">-- move to cursor position | ||
270 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-(#self.value + <span class="number">1</span> - self.position))) | ||
271 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
272 | <span class="keyword">end</span> | ||
273 | |||
274 | |||
275 | <span class="keyword">local</span> handle_key <span class="keyword">do</span> <span class="comment">-- keyboard input handler | ||
276 | </span> | ||
277 | <span class="keyword">local</span> key_handlers | ||
278 | key_handlers = { | ||
279 | left = <span class="keyword">function</span>(self) | ||
280 | <span class="keyword">if</span> self.position == <span class="number">1</span> <span class="keyword">then</span> | ||
281 | <span class="function-name">bell</span>() | ||
282 | <span class="keyword">return</span> | ||
283 | <span class="keyword">end</span> | ||
284 | |||
285 | <span class="keyword">local</span> new_pos = self.position - <span class="number">1</span> | ||
286 | <span class="keyword">while</span> self.value[new_pos] == <span class="string">""</span> <span class="keyword">do</span> <span class="comment">-- skip empty strings; double width chars | ||
287 | </span> new_pos = new_pos - <span class="number">1</span> | ||
288 | <span class="keyword">end</span> | ||
289 | |||
290 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-(self.position - new_pos))) | ||
291 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
292 | self.position = new_pos | ||
293 | <span class="keyword">end</span>, | ||
294 | |||
295 | right = <span class="keyword">function</span>(self) | ||
296 | <span class="keyword">if</span> self.position == #self.value + <span class="number">1</span> <span class="keyword">then</span> | ||
297 | <span class="function-name">bell</span>() | ||
298 | <span class="keyword">return</span> | ||
299 | <span class="keyword">end</span> | ||
300 | |||
301 | <span class="keyword">local</span> new_pos = self.position + <span class="number">1</span> | ||
302 | <span class="keyword">while</span> self.value[new_pos] == <span class="string">""</span> <span class="keyword">do</span> <span class="comment">-- skip empty strings; double width chars | ||
303 | </span> new_pos = new_pos + <span class="number">1</span> | ||
304 | <span class="keyword">end</span> | ||
305 | |||
306 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(new_pos - self.position)) | ||
307 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
308 | self.position = new_pos | ||
309 | <span class="keyword">end</span>, | ||
310 | |||
311 | backspace = <span class="keyword">function</span>(self) | ||
312 | <span class="keyword">if</span> self.position == <span class="number">1</span> <span class="keyword">then</span> | ||
313 | <span class="function-name">bell</span>() | ||
314 | <span class="keyword">return</span> | ||
315 | <span class="keyword">end</span> | ||
316 | |||
317 | <span class="keyword">while</span> self.value[self.position - <span class="number">1</span>] == <span class="string">""</span> <span class="keyword">do</span> <span class="comment">-- remove empty strings; double width chars | ||
318 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-<span class="number">1</span>)) | ||
319 | self.position = self.position - <span class="number">1</span> | ||
320 | <span class="global">table</span>.<span class="function-name">remove</span>(self.value, self.position) | ||
321 | <span class="keyword">end</span> | ||
322 | <span class="comment">-- remove char itself | ||
323 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(-<span class="number">1</span>)) | ||
324 | self.position = self.position - <span class="number">1</span> | ||
325 | <span class="global">table</span>.<span class="function-name">remove</span>(self.value, self.position) | ||
326 | self.value.chars = self.value.chars - <span class="number">1</span> | ||
327 | <span class="function-name">draw</span>(self) | ||
328 | <span class="keyword">end</span>, | ||
329 | |||
330 | home = <span class="keyword">function</span>(self) | ||
331 | <span class="keyword">local</span> new_pos = <span class="number">1</span> | ||
332 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(new_pos - self.position)) | ||
333 | self.position = new_pos | ||
334 | <span class="keyword">end</span>, | ||
335 | |||
336 | [<span class="string">"end"</span>] = <span class="keyword">function</span>(self) | ||
337 | <span class="keyword">local</span> new_pos = #self.value + <span class="number">1</span> | ||
338 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(new_pos - self.position)) | ||
339 | self.position = new_pos | ||
340 | <span class="keyword">end</span>, | ||
341 | |||
342 | delete = <span class="keyword">function</span>(self) | ||
343 | <span class="keyword">if</span> self.position > #self.value <span class="keyword">then</span> | ||
344 | <span class="function-name">bell</span>() | ||
345 | <span class="keyword">return</span> | ||
346 | <span class="keyword">end</span> | ||
347 | |||
348 | key_handlers.<span class="function-name">right</span>(self) | ||
349 | key_handlers.<span class="function-name">backspace</span>(self) | ||
350 | <span class="keyword">end</span>, | ||
351 | } | ||
352 | |||
353 | |||
354 | <span class="comment">-- handles a single input key/ansi-sequence. | ||
355 | </span> <span class="comment">-- @tparam string key the key or ansi-sequence (from <a href="../modules/system.html#readansi">system.readansi</a>) | ||
356 | </span> <span class="comment">-- @tparam string keytype the type of the key, either "char" or "ansi" (from <a href="../modules/system.html#readansi">system.readansi</a>) | ||
357 | </span> <span class="comment">-- @treturn string status the status of the key handling, either "ok", "exit_key" or an error message | ||
358 | </span> <span class="keyword">function</span> <span class="function-name">handle_key</span>(self, key, keytype) | ||
359 | <span class="keyword">if</span> self.exit_keys[key] <span class="keyword">then</span> | ||
360 | <span class="comment">-- registered exit key | ||
361 | </span> <span class="keyword">return</span> <span class="string">"exit_key"</span> | ||
362 | <span class="keyword">end</span> | ||
363 | |||
364 | <span class="keyword">local</span> handler = key_handlers[key_names[key] <span class="keyword">or</span> <span class="keyword">true</span> ] | ||
365 | <span class="keyword">if</span> handler <span class="keyword">then</span> | ||
366 | <span class="function-name">handler</span>(self) | ||
367 | <span class="keyword">return</span> <span class="string">"ok"</span> | ||
368 | <span class="keyword">end</span> | ||
369 | |||
370 | <span class="keyword">if</span> keytype == <span class="string">"ansi"</span> <span class="keyword">then</span> | ||
371 | <span class="comment">-- we got an ansi sequence, but dunno how to handle it, ignore | ||
372 | </span> <span class="comment">-- print("unhandled ansi: ", key:sub(2,-1), string.byte(key, 1, -1)) | ||
373 | </span> <span class="function-name">bell</span>() | ||
374 | <span class="keyword">return</span> <span class="string">"ok"</span> | ||
375 | <span class="keyword">end</span> | ||
376 | |||
377 | <span class="comment">-- just a single key | ||
378 | </span> <span class="keyword">if</span> key < <span class="string">" "</span> <span class="keyword">then</span> | ||
379 | <span class="comment">-- control character | ||
380 | </span> <span class="function-name">bell</span>() | ||
381 | <span class="keyword">return</span> <span class="string">"ok"</span> | ||
382 | <span class="keyword">end</span> | ||
383 | |||
384 | <span class="keyword">if</span> self.value.chars >= self.max_length <span class="keyword">then</span> | ||
385 | <span class="function-name">bell</span>() | ||
386 | <span class="keyword">return</span> <span class="string">"ok"</span> | ||
387 | <span class="keyword">end</span> | ||
388 | |||
389 | <span class="comment">-- insert the key into the value | ||
390 | </span> <span class="keyword">if</span> sys.<span class="function-name">utf8cwidth</span>(key) == <span class="number">2</span> <span class="keyword">then</span> | ||
391 | <span class="comment">-- double width character, insert empty string after it | ||
392 | </span> <span class="global">table</span>.<span class="function-name">insert</span>(self.value, self.position, <span class="string">""</span>) | ||
393 | <span class="global">table</span>.<span class="function-name">insert</span>(self.value, self.position, key) | ||
394 | self.position = self.position + <span class="number">2</span> | ||
395 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(<span class="number">2</span>)) | ||
396 | <span class="keyword">else</span> | ||
397 | <span class="global">table</span>.<span class="function-name">insert</span>(self.value, self.position, key) | ||
398 | self.position = self.position + <span class="number">1</span> | ||
399 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="function-name">cursor_move_horiz</span>(<span class="number">1</span>)) | ||
400 | <span class="keyword">end</span> | ||
401 | self.value.chars = self.value.chars + <span class="number">1</span> | ||
402 | <span class="function-name">draw</span>(self) | ||
403 | <span class="keyword">return</span> <span class="string">"ok"</span> | ||
404 | <span class="keyword">end</span> | ||
405 | <span class="keyword">end</span> | ||
406 | |||
407 | |||
408 | |||
409 | <span class="comment">--- Get_size returns the maximum size of the input box (prompt + input). | ||
410 | </span><span class="comment">-- The size is in rows and columns. Columns is determined by | ||
411 | </span><span class="comment">-- the prompt and the <code>max_length * 2</code> (characters can be double-width). | ||
412 | </span><span class="comment">-- @treturn number the number of rows (always 1) | ||
413 | </span><span class="comment">-- @treturn number the number of columns | ||
414 | </span><span class="keyword">function</span> readline:<span class="function-name">get_size</span>() | ||
415 | <span class="keyword">return</span> <span class="number">1</span>, #self.prompt + self.max_length * <span class="number">2</span> | ||
416 | <span class="keyword">end</span> | ||
417 | |||
418 | |||
419 | |||
420 | <span class="comment">--- Get coordinates of the cursor in the input box (prompt + input). | ||
421 | </span><span class="comment">-- The coordinates are 1-based. They are returned as row and column, within the | ||
422 | </span><span class="comment">-- size as reported by <code>get_size</code>. | ||
423 | </span><span class="comment">-- @treturn number the row of the cursor (always 1) | ||
424 | </span><span class="comment">-- @treturn number the column of the cursor | ||
425 | </span><span class="keyword">function</span> readline:<span class="function-name">get_cursor</span>() | ||
426 | <span class="keyword">return</span> <span class="number">1</span>, #self.prompt + self.position | ||
427 | <span class="keyword">end</span> | ||
428 | |||
429 | |||
430 | |||
431 | <span class="comment">--- Set the coordinates of the cursor in the input box (prompt + input). | ||
432 | </span><span class="comment">-- The coordinates are 1-based. They are expected to be within the | ||
433 | </span><span class="comment">-- size as reported by <code>get_size</code>, and beyond the prompt. | ||
434 | </span><span class="comment">-- If the position is invalid, it will be corrected. | ||
435 | </span><span class="comment">-- Use the results to check if the position was adjusted. | ||
436 | </span><span class="comment">-- @tparam number row the row of the cursor (always 1) | ||
437 | </span><span class="comment">-- @tparam number col the column of the cursor | ||
438 | </span><span class="comment">-- @return results of get_cursor | ||
439 | </span><span class="keyword">function</span> readline:<span class="function-name">set_cursor</span>(row, col) | ||
440 | <span class="keyword">local</span> l_prompt = #self.prompt | ||
441 | <span class="keyword">local</span> l_value = #self.value | ||
442 | |||
443 | <span class="keyword">if</span> col < l_prompt + <span class="number">1</span> <span class="keyword">then</span> | ||
444 | col = l_prompt + <span class="number">1</span> | ||
445 | <span class="keyword">elseif</span> col > l_prompt + l_value + <span class="number">1</span> <span class="keyword">then</span> | ||
446 | col = l_prompt + l_value + <span class="number">1</span> | ||
447 | <span class="keyword">end</span> | ||
448 | |||
449 | <span class="keyword">while</span> self.value[col - l_prompt] == <span class="string">""</span> <span class="keyword">do</span> | ||
450 | col = col - <span class="number">1</span> <span class="comment">-- on an empty string, so move back to start of double-width char | ||
451 | </span> <span class="keyword">end</span> | ||
452 | |||
453 | <span class="keyword">local</span> new_pos = col - l_prompt | ||
454 | |||
455 | <span class="function-name">cursor_move_horiz</span>(self.position - new_pos) | ||
456 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
457 | |||
458 | self.position = new_pos | ||
459 | <span class="keyword">return</span> self:<span class="function-name">get_cursor</span>() | ||
460 | <span class="keyword">end</span> | ||
461 | |||
462 | |||
463 | |||
464 | <span class="comment">--- Read a line of input from the user. | ||
465 | </span><span class="comment">-- It will first print the <code>prompt</code> and then wait for input. Ensure the cursor | ||
466 | </span><span class="comment">-- is at the correct position before calling this function. This function will | ||
467 | </span><span class="comment">-- do all cursor movements in a relative way. | ||
468 | </span><span class="comment">-- Can be called again after an exit-key or timeout has occurred. Just make sure | ||
469 | </span><span class="comment">-- the cursor is at the same position where is was when it returned the last time. | ||
470 | </span><span class="comment">-- Alternatively the cursor can be set to the position of the prompt (the position | ||
471 | </span><span class="comment">-- the cursor was in before the first call), and the parameter <code>redraw</code> can be set | ||
472 | </span><span class="comment">-- to <code>true</code>. | ||
473 | </span><span class="comment">-- @tparam[opt=math.huge] number timeout the maximum time to wait for input in seconds | ||
474 | </span><span class="comment">-- @tparam[opt=false] boolean redraw if <code>true</code> the prompt will be redrawn (cursor must be at prompt position!) | ||
475 | </span><span class="comment">-- @treturn[1] string the input string as entered the user | ||
476 | </span><span class="comment">-- @treturn[1] string the exit-key used to exit the readline (see <code>new</code>) | ||
477 | </span><span class="comment">-- @treturn[2] nil when input is incomplete | ||
478 | </span><span class="comment">-- @treturn[2] string error message, the reason why the input is incomplete, <code>"timeout"</code>, or an error reading a key | ||
479 | </span><span class="keyword">function</span> readline:<span class="function-name">__call</span>(timeout, redraw) | ||
480 | <span class="function-name">draw</span>(self, redraw) | ||
481 | timeout = timeout <span class="keyword">or</span> <span class="global">math</span>.huge | ||
482 | <span class="keyword">local</span> timeout_end = sys.<span class="function-name">gettime</span>() + timeout | ||
483 | |||
484 | <span class="keyword">while</span> <span class="keyword">true</span> <span class="keyword">do</span> | ||
485 | <span class="keyword">local</span> key, keytype = sys.<span class="function-name">readansi</span>(timeout_end - sys.<span class="function-name">gettime</span>()) | ||
486 | <span class="keyword">if</span> <span class="keyword">not</span> key <span class="keyword">then</span> | ||
487 | <span class="comment">-- error or timeout | ||
488 | </span> <span class="keyword">return</span> <span class="keyword">nil</span>, keytype | ||
489 | <span class="keyword">end</span> | ||
490 | |||
491 | <span class="keyword">local</span> status = <span class="function-name">handle_key</span>(self, key, keytype) | ||
492 | <span class="keyword">if</span> status == <span class="string">"exit_key"</span> <span class="keyword">then</span> | ||
493 | <span class="keyword">return</span> <span class="global">tostring</span>(self.value), key | ||
494 | |||
495 | <span class="keyword">elseif</span> status ~= <span class="string">"ok"</span> <span class="keyword">then</span> | ||
496 | <span class="global">error</span>(<span class="string">"unknown status received: "</span> .. <span class="global">tostring</span>(status)) | ||
497 | <span class="keyword">end</span> | ||
498 | <span class="keyword">end</span> | ||
499 | <span class="keyword">end</span> | ||
500 | |||
501 | |||
502 | |||
503 | <span class="comment">-- return readline -- normally we'd return here, but for the example we continue | ||
504 | </span> | ||
505 | |||
506 | |||
507 | |||
508 | <span class="keyword">local</span> backup = sys.<span class="function-name">termbackup</span>() | ||
509 | |||
510 | <span class="comment">-- setup Windows console to handle ANSI processing | ||
511 | </span>sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
512 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) + sys.CIF_VIRTUAL_TERMINAL_INPUT) | ||
513 | <span class="comment">-- set output to UTF-8 | ||
514 | </span>sys.<span class="function-name">setconsoleoutputcp</span>(sys.CODEPAGE_UTF8) | ||
515 | |||
516 | <span class="comment">-- setup Posix terminal to disable canonical mode and echo | ||
517 | </span>sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, { | ||
518 | lflag = sys.<span class="function-name">tcgetattr</span>(<span class="global">io</span>.stdin).lflag - sys.L_ICANON - sys.L_ECHO, | ||
519 | }) | ||
520 | <span class="comment">-- setup stdin to non-blocking mode | ||
521 | </span>sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, <span class="keyword">true</span>) | ||
522 | |||
523 | |||
524 | <span class="keyword">local</span> rl = readline.<span class="function-name">new</span>{ | ||
525 | prompt = <span class="string">"Enter something: "</span>, | ||
526 | max_length = <span class="number">60</span>, | ||
527 | value = <span class="string">"Hello, ä½ -好 World 🚀!"</span>, | ||
528 | <span class="comment">-- position = 2, | ||
529 | </span> exit_keys = {key_sequences.enter, <span class="string">"\27"</span>, <span class="string">"\t"</span>, <span class="string">"\27[Z"</span>}, <span class="comment">-- enter, escape, tab, shift-tab | ||
530 | </span>} | ||
531 | |||
532 | |||
533 | <span class="keyword">local</span> result, key = <span class="function-name">rl</span>() | ||
534 | <span class="global">print</span>(<span class="string">""</span>) <span class="comment">-- newline after input, to move cursor down from the input line | ||
535 | </span><span class="global">print</span>(<span class="string">"Result (string): '"</span> .. result .. <span class="string">"'"</span>) | ||
536 | <span class="global">print</span>(<span class="string">"Result (bytes):"</span>, result:<span class="function-name">byte</span>(<span class="number">1</span>,-<span class="number">1</span>)) | ||
537 | <span class="global">print</span>(<span class="string">"Exit-Key (bytes):"</span>, key:<span class="function-name">byte</span>(<span class="number">1</span>,-<span class="number">1</span>)) | ||
538 | |||
539 | |||
540 | <span class="comment">-- Clean up afterwards | ||
541 | </span>sys.<span class="function-name">termrestore</span>(backup)</pre> | ||
542 | |||
543 | |||
544 | </div> <!-- id="content" --> | ||
545 | </div> <!-- id="main" --> | ||
546 | <div id="about"> | ||
547 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
548 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
549 | </div> <!-- id="about" --> | ||
550 | </div> <!-- id="container" --> | ||
551 | </body> | ||
552 | </html> | ||
diff --git a/docs/examples/spinner.lua.html b/docs/examples/spinner.lua.html new file mode 100644 index 0000000..181cbe5 --- /dev/null +++ b/docs/examples/spinner.lua.html | |||
@@ -0,0 +1,144 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><strong>spinner.lua</strong></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>spinner.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span>(<span class="string">"system"</span>) | ||
71 | |||
72 | <span class="global">print</span> <span class="string">[[ | ||
73 | |||
74 | An example to display a spinner, whilst a long running task executes. | ||
75 | |||
76 | ]]</span> | ||
77 | |||
78 | |||
79 | <span class="comment">-- start make backup, to auto-restore on exit | ||
80 | </span>sys.<span class="function-name">autotermrestore</span>() | ||
81 | <span class="comment">-- configure console | ||
82 | </span>sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) - sys.CIF_ECHO_INPUT - sys.CIF_LINE_INPUT) | ||
83 | <span class="keyword">local</span> of = sys.<span class="function-name">tcgetattr</span>(<span class="global">io</span>.stdin) | ||
84 | sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, { lflag = of.lflag - sys.L_ICANON - sys.L_ECHO }) | ||
85 | sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, <span class="keyword">true</span>) | ||
86 | |||
87 | |||
88 | |||
89 | <span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">hideCursor</span>() | ||
90 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"\27[?25l"</span>) | ||
91 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
92 | <span class="keyword">end</span> | ||
93 | |||
94 | <span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">showCursor</span>() | ||
95 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"\27[?25h"</span>) | ||
96 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
97 | <span class="keyword">end</span> | ||
98 | |||
99 | <span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">left</span>(n) | ||
100 | <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"\27["</span>,n <span class="keyword">or</span> <span class="number">1</span>,<span class="string">"D"</span>) | ||
101 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
102 | <span class="keyword">end</span> | ||
103 | |||
104 | |||
105 | |||
106 | <span class="keyword">local</span> spinner <span class="keyword">do</span> | ||
107 | <span class="keyword">local</span> spin = <span class="string">[[|/-\]]</span> | ||
108 | <span class="keyword">local</span> i = <span class="number">1</span> | ||
109 | spinner = <span class="keyword">function</span>() | ||
110 | <span class="function-name">hideCursor</span>() | ||
111 | <span class="global">io</span>.<span class="function-name">write</span>(spin:<span class="function-name">sub</span>(i, i)) | ||
112 | <span class="function-name">left</span>() | ||
113 | i = i + <span class="number">1</span> | ||
114 | <span class="keyword">if</span> i > #spin <span class="keyword">then</span> i = <span class="number">1</span> <span class="keyword">end</span> | ||
115 | |||
116 | <span class="keyword">if</span> sys.<span class="function-name">readkey</span>(<span class="number">0</span>) ~= <span class="keyword">nil</span> <span class="keyword">then</span> | ||
117 | <span class="keyword">while</span> sys.<span class="function-name">readkey</span>(<span class="number">0</span>) ~= <span class="keyword">nil</span> <span class="keyword">do</span> <span class="keyword">end</span> <span class="comment">-- consume keys pressed | ||
118 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">" "</span>); | ||
119 | <span class="function-name">left</span>() | ||
120 | <span class="function-name">showCursor</span>() | ||
121 | <span class="keyword">return</span> <span class="keyword">true</span> | ||
122 | <span class="keyword">else</span> | ||
123 | <span class="keyword">return</span> <span class="keyword">false</span> | ||
124 | <span class="keyword">end</span> | ||
125 | <span class="keyword">end</span> | ||
126 | <span class="keyword">end</span> | ||
127 | |||
128 | <span class="global">io</span>.stdout:<span class="function-name">write</span>(<span class="string">"press any key to stop the spinner... "</span>) | ||
129 | <span class="keyword">while</span> <span class="keyword">not</span> <span class="function-name">spinner</span>() <span class="keyword">do</span> | ||
130 | sys.<span class="function-name">sleep</span>(<span class="number">0.1</span>) | ||
131 | <span class="keyword">end</span> | ||
132 | |||
133 | <span class="global">print</span>(<span class="string">"Done!"</span>)</pre> | ||
134 | |||
135 | |||
136 | </div> <!-- id="content" --> | ||
137 | </div> <!-- id="main" --> | ||
138 | <div id="about"> | ||
139 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
140 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
141 | </div> <!-- id="about" --> | ||
142 | </div> <!-- id="container" --> | ||
143 | </body> | ||
144 | </html> | ||
diff --git a/docs/examples/spiral_snake.lua.html b/docs/examples/spiral_snake.lua.html new file mode 100644 index 0000000..7ebb838 --- /dev/null +++ b/docs/examples/spiral_snake.lua.html | |||
@@ -0,0 +1,152 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><strong>spiral_snake.lua</strong></li> | ||
45 | <li><a href="../examples/terminalsize.lua.html">terminalsize.lua</a></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>spiral_snake.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span> <span class="string">"system"</span> | ||
71 | |||
72 | <span class="global">print</span> <span class="string">[[ | ||
73 | |||
74 | This example will draw a snake like spiral on the screen. Showing ANSI escape | ||
75 | codes for moving the cursor around. | ||
76 | |||
77 | ]]</span> | ||
78 | |||
79 | <span class="comment">-- backup term settings with auto-restore on exit | ||
80 | </span>sys.<span class="function-name">autotermrestore</span>() | ||
81 | |||
82 | <span class="comment">-- setup Windows console to handle ANSI processing | ||
83 | </span>sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
84 | |||
85 | <span class="comment">-- start drawing the spiral. | ||
86 | </span><span class="comment">-- start from current pos, then right, then up, then left, then down, and again. | ||
87 | </span><span class="keyword">local</span> x, y = <span class="number">1</span>, <span class="number">1</span> <span class="comment">-- current position | ||
88 | </span><span class="keyword">local</span> dx, dy = <span class="number">1</span>, <span class="number">0</span> <span class="comment">-- direction after each step | ||
89 | </span><span class="keyword">local</span> wx, wy = <span class="number">30</span>, <span class="number">30</span> <span class="comment">-- width and height of the room | ||
90 | </span><span class="keyword">local</span> mx, my = <span class="number">1</span>, <span class="number">1</span> <span class="comment">-- margin | ||
91 | </span> | ||
92 | <span class="comment">-- commands to move the cursor | ||
93 | </span><span class="keyword">local</span> move_left = <span class="string">"\27[1D"</span> | ||
94 | <span class="keyword">local</span> move_right = <span class="string">"\27[1C"</span> | ||
95 | <span class="keyword">local</span> move_up = <span class="string">"\27[1A"</span> | ||
96 | <span class="keyword">local</span> move_down = <span class="string">"\27[1B"</span> | ||
97 | |||
98 | <span class="comment">-- create room: 30 empty lines | ||
99 | </span><span class="global">print</span>((<span class="string">"\n"</span>):<span class="function-name">rep</span>(wy)) | ||
100 | <span class="keyword">local</span> move = move_right | ||
101 | |||
102 | <span class="keyword">while</span> wx > <span class="number">0</span> <span class="keyword">and</span> wy > <span class="number">0</span> <span class="keyword">do</span> | ||
103 | sys.<span class="function-name">sleep</span>(<span class="number">0.01</span>) <span class="comment">-- slow down the drawing a little | ||
104 | </span> <span class="global">io</span>.<span class="function-name">write</span>(<span class="string">"*"</span> .. move_left .. move ) | ||
105 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
106 | x = x + dx | ||
107 | y = y + dy | ||
108 | |||
109 | <span class="keyword">if</span> x > wx <span class="keyword">and</span> move == move_right <span class="keyword">then</span> | ||
110 | <span class="comment">-- end of move right | ||
111 | </span> dx = <span class="number">0</span> | ||
112 | dy = <span class="number">1</span> | ||
113 | move = move_up | ||
114 | wy = wy - <span class="number">1</span> | ||
115 | my = my + <span class="number">1</span> | ||
116 | <span class="keyword">elseif</span> y > wy <span class="keyword">and</span> move == move_up <span class="keyword">then</span> | ||
117 | <span class="comment">-- end of move up | ||
118 | </span> dx = -<span class="number">1</span> | ||
119 | dy = <span class="number">0</span> | ||
120 | move = move_left | ||
121 | wx = wx - <span class="number">1</span> | ||
122 | mx = mx + <span class="number">1</span> | ||
123 | <span class="keyword">elseif</span> x < mx <span class="keyword">and</span> move == move_left <span class="keyword">then</span> | ||
124 | <span class="comment">-- end of move left | ||
125 | </span> dx = <span class="number">0</span> | ||
126 | dy = -<span class="number">1</span> | ||
127 | move = move_down | ||
128 | wy = wy - <span class="number">1</span> | ||
129 | my = my + <span class="number">1</span> | ||
130 | <span class="keyword">elseif</span> y < my <span class="keyword">and</span> move == move_down <span class="keyword">then</span> | ||
131 | <span class="comment">-- end of move down | ||
132 | </span> dx = <span class="number">1</span> | ||
133 | dy = <span class="number">0</span> | ||
134 | move = move_right | ||
135 | wx = wx - <span class="number">1</span> | ||
136 | mx = mx + <span class="number">1</span> | ||
137 | <span class="keyword">end</span> | ||
138 | <span class="keyword">end</span> | ||
139 | |||
140 | <span class="global">io</span>.<span class="function-name">write</span>(move_down:<span class="function-name">rep</span>(<span class="number">15</span>)) | ||
141 | <span class="global">print</span>(<span class="string">"\nDone!"</span>)</pre> | ||
142 | |||
143 | |||
144 | </div> <!-- id="content" --> | ||
145 | </div> <!-- id="main" --> | ||
146 | <div id="about"> | ||
147 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
148 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
149 | </div> <!-- id="about" --> | ||
150 | </div> <!-- id="container" --> | ||
151 | </body> | ||
152 | </html> | ||
diff --git a/docs/examples/terminalsize.lua.html b/docs/examples/terminalsize.lua.html new file mode 100644 index 0000000..d7f902d --- /dev/null +++ b/docs/examples/terminalsize.lua.html | |||
@@ -0,0 +1,117 @@ | |||
1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
2 | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
3 | <html> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | ||
5 | <head> | ||
6 | <title>Lua-System docs</title> | ||
7 | <link rel="stylesheet" href="../ldoc.css" type="text/css" /> | ||
8 | </head> | ||
9 | <body> | ||
10 | |||
11 | <div id="container"> | ||
12 | |||
13 | <div id="product"> | ||
14 | <div id="product_logo"></div> | ||
15 | <div id="product_name"><big><b></b></big></div> | ||
16 | <div id="product_description"></div> | ||
17 | </div> <!-- id="product" --> | ||
18 | |||
19 | |||
20 | <div id="main"> | ||
21 | |||
22 | |||
23 | <!-- Menu --> | ||
24 | |||
25 | <div id="navigation"> | ||
26 | <br/> | ||
27 | <h1>Lua-System</h1> | ||
28 | |||
29 | |||
30 | <ul> | ||
31 | <li><a href="../index.html">Index</a></li> | ||
32 | </ul> | ||
33 | |||
34 | |||
35 | |||
36 | <h2>Examples</h2> | ||
37 | <ul class="nowrap"> | ||
38 | <li><a href="../examples/compat.lua.html">compat.lua</a></li> | ||
39 | <li><a href="../examples/flag_debugging.lua.html">flag_debugging.lua</a></li> | ||
40 | <li><a href="../examples/password_input.lua.html">password_input.lua</a></li> | ||
41 | <li><a href="../examples/read.lua.html">read.lua</a></li> | ||
42 | <li><a href="../examples/readline.lua.html">readline.lua</a></li> | ||
43 | <li><a href="../examples/spinner.lua.html">spinner.lua</a></li> | ||
44 | <li><a href="../examples/spiral_snake.lua.html">spiral_snake.lua</a></li> | ||
45 | <li><strong>terminalsize.lua</strong></li> | ||
46 | </ul> | ||
47 | <h2>Modules</h2> | ||
48 | <ul class="nowrap"> | ||
49 | <li><a href="../modules/system.html">system</a></li> | ||
50 | </ul> | ||
51 | <h2>Classes</h2> | ||
52 | <ul class="nowrap"> | ||
53 | <li><a href="../classes/bitflags.html">bitflags</a></li> | ||
54 | </ul> | ||
55 | <h2>Topics</h2> | ||
56 | <ul class=""> | ||
57 | <li><a href="../topics/01-introduction.md.html">1. Introduction</a></li> | ||
58 | <li><a href="../topics/02-development.md.html">2. Development</a></li> | ||
59 | <li><a href="../topics/03-terminal.md.html">3. Terminal functionality</a></li> | ||
60 | <li><a href="../topics/CHANGELOG.md.html">CHANGELOG</a></li> | ||
61 | <li><a href="../topics/LICENSE.md.html">MIT License</a></li> | ||
62 | </ul> | ||
63 | |||
64 | </div> | ||
65 | |||
66 | <div id="content"> | ||
67 | |||
68 | <h2>terminalsize.lua</h2> | ||
69 | <pre> | ||
70 | <span class="keyword">local</span> sys = <span class="global">require</span>(<span class="string">"system"</span>) | ||
71 | |||
72 | sys.<span class="function-name">autotermrestore</span>() <span class="comment">-- set up auto restore of terminal settings on exit | ||
73 | </span> | ||
74 | <span class="comment">-- setup Windows console to handle ANSI processing | ||
75 | </span>sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdout, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdout) + sys.COF_VIRTUAL_TERMINAL_PROCESSING) | ||
76 | sys.<span class="function-name">setconsoleflags</span>(<span class="global">io</span>.stdin, sys.<span class="function-name">getconsoleflags</span>(<span class="global">io</span>.stdin) + sys.CIF_VIRTUAL_TERMINAL_INPUT) | ||
77 | |||
78 | <span class="comment">-- setup Posix to disable canonical mode and echo | ||
79 | </span><span class="keyword">local</span> of_attr = sys.<span class="function-name">tcgetattr</span>(<span class="global">io</span>.stdin) | ||
80 | sys.<span class="function-name">setnonblock</span>(<span class="global">io</span>.stdin, <span class="keyword">true</span>) | ||
81 | sys.<span class="function-name">tcsetattr</span>(<span class="global">io</span>.stdin, sys.TCSANOW, { | ||
82 | lflag = of_attr.lflag - sys.L_ICANON - sys.L_ECHO, <span class="comment">-- disable canonical mode and echo | ||
83 | </span>}) | ||
84 | |||
85 | |||
86 | <span class="comment">-- generate string to move cursor horizontally | ||
87 | </span><span class="comment">-- positive goes right, negative goes left | ||
88 | </span><span class="keyword">local</span> <span class="keyword">function</span> <span class="function-name">cursor_move_horiz</span>(n) | ||
89 | <span class="keyword">if</span> n == <span class="number">0</span> <span class="keyword">then</span> | ||
90 | <span class="keyword">return</span> <span class="string">""</span> | ||
91 | <span class="keyword">end</span> | ||
92 | <span class="keyword">return</span> <span class="string">"\27["</span> .. (n > <span class="number">0</span> <span class="keyword">and</span> n <span class="keyword">or</span> -n) .. (n > <span class="number">0</span> <span class="keyword">and</span> <span class="string">"C"</span> <span class="keyword">or</span> <span class="string">"D"</span>) | ||
93 | <span class="keyword">end</span> | ||
94 | |||
95 | |||
96 | <span class="keyword">local</span> rows, cols | ||
97 | <span class="global">print</span>(<span class="string">"Change the terminal window size, press any key to exit"</span>) | ||
98 | <span class="keyword">while</span> <span class="keyword">not</span> sys.<span class="function-name">readansi</span>(<span class="number">0.2</span>) <span class="keyword">do</span> <span class="comment">-- use readansi to not leave stray bytes in the input buffer | ||
99 | </span> <span class="keyword">local</span> nrows, ncols = sys.<span class="function-name">termsize</span>() | ||
100 | <span class="keyword">if</span> rows ~= nrows <span class="keyword">or</span> cols ~= ncols <span class="keyword">then</span> | ||
101 | rows, cols = nrows, ncols | ||
102 | <span class="keyword">local</span> text = <span class="string">"Terminal size: "</span> .. rows .. <span class="string">"x"</span> .. cols .. <span class="string">" "</span> | ||
103 | <span class="global">io</span>.<span class="function-name">write</span>(text .. <span class="function-name">cursor_move_horiz</span>(-#text)) | ||
104 | <span class="global">io</span>.<span class="function-name">flush</span>() | ||
105 | <span class="keyword">end</span> | ||
106 | <span class="keyword">end</span></pre> | ||
107 | |||
108 | |||
109 | </div> <!-- id="content" --> | ||
110 | </div> <!-- id="main" --> | ||
111 | <div id="about"> | ||
112 | <i>generated by <a href="http://github.com/lunarmodules/LDoc">LDoc 1.5.0</a></i> | ||
113 | <i style="float:right;">Last updated 2024-06-20 23:11:37 </i> | ||
114 | </div> <!-- id="about" --> | ||
115 | </div> <!-- id="container" --> | ||
116 | </body> | ||
117 | </html> | ||