Skip to content

Commit 8065d83

Browse files
committed
feat(terminal): 新增一批命令行彩蛋
在首页终端里加入更多可以玩的小命令: - cowsay <文本>:让奶牛替你说话(自动折行) - matrix [行数]:数字雨彩蛋 - coin / dice:抛硬币、掷骰子 - fish:一条 ASCII 小鱼 - sl:打错 ls 的火车梗 - vim:退出难的经典梗 同步更新 help 列表、Tab 补全命令表与启动横幅提示。
1 parent 2dd9d84 commit 8065d83

1 file changed

Lines changed: 125 additions & 2 deletions

File tree

‎assets/js/terminal.js‎

Lines changed: 125 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
['term-accent', ' │ │'],
3636
['term-accent', ' ╰──────────────────────────────────────────╯'],
3737
['term-info', ' 欢迎来到 TY 的博客终端。输入 help 查看可用命令。'],
38-
['term-muted', ' 提示:Tab 可补全命令,↑↓ 翻历史,输入 random 随机读一篇。']
38+
['term-muted', ' 提示:Tab 补全,↑↓ 翻历史;试试 cowsay、matrix、coin、fish。']
3939
];
4040

4141
var FORTUNES = [
@@ -92,12 +92,19 @@
9292
['random', '随机打开一篇文章'],
9393
['neofetch', '显示博客系统信息'],
9494
['fortune', '来一句程序员语录'],
95+
['cowsay <文本>', '让奶牛替你说话'],
96+
['matrix [行数]', '看一场数字雨'],
97+
['coin', '抛一枚硬币'],
98+
['dice', '掷一颗骰子'],
99+
['fish', '养一条 ASCII 小鱼'],
95100
['whoami', '我是谁'],
96101
['date', '当前时间'],
97102
['echo <文本>', '复读机'],
98103
['search <关键词>', '跳到站内搜索'],
99104
['theme <dark|light>', '切换主题'],
100105
['clear', '清屏'],
106+
['sl', '(打错 ls 的彩蛋)'],
107+
['vim', '(退出难的梗)'],
101108
['sudo', '你以为呢'],
102109
['exit', '关闭终端']
103110
];
@@ -175,6 +182,114 @@
175182
print(FORTUNES[Math.floor(Math.random() * FORTUNES.length)], 'term-accent');
176183
}
177184

185+
function cowsay(text) {
186+
var msg = String(text || '').trim();
187+
if (!msg) { msg = '哞~ 你好呀!'; }
188+
// 控制气泡宽度,避免太长撑破布局
189+
var MAX = 28;
190+
var lines = [];
191+
var cur = '';
192+
// 按字符简单折行(中文/英文都按单字符切)
193+
Array.prototype.forEach.call(msg, function (ch) {
194+
if (cur.length >= MAX) { lines.push(cur); cur = ''; }
195+
cur += ch;
196+
});
197+
if (cur) { lines.push(cur); }
198+
var width = Math.max(3, lines.reduce(function (m, l) { return Math.max(m, l.length); }, 0));
199+
200+
var top = ' ' + repeat('_', width + 2);
201+
var bottom = ' ' + repeat('-', width + 2);
202+
lines.forEach(function (l, i) {
203+
var pad = repeat(' ', width - l.length);
204+
if (lines.length === 1) {
205+
print(' < ' + esc(l) + ' >', 'term-info');
206+
} else if (i === 0) {
207+
print(' / ' + esc(l) + pad + ' \\', 'term-info');
208+
} else if (i === lines.length - 1) {
209+
print(' \\ ' + esc(l) + pad + ' /', 'term-info');
210+
} else {
211+
print(' | ' + esc(l) + pad + ' |', 'term-info');
212+
}
213+
});
214+
print(top, 'term-muted');
215+
print(' \\ ^__^', 'term-ascii');
216+
print(' \\ (oo)\\_______', 'term-ascii');
217+
print(' (__)\\ )\\/\\', 'term-ascii');
218+
print(' ||----w |', 'term-ascii');
219+
print(' || ||', 'term-ascii');
220+
print(bottom, 'term-muted');
221+
}
222+
223+
function repeat(ch, n) {
224+
return new Array(n + 1).join(ch);
225+
}
226+
227+
function matrix(arg) {
228+
var rows = parseInt(arg, 10);
229+
if (!rows || rows < 1) { rows = 8; }
230+
if (rows > 30) { rows = 30; }
231+
var glyphs = '01あいうえおカキクケコサシスセソ¥$#@%&*';
232+
for (var i = 0; i < rows; i++) {
233+
var s = '';
234+
var len = 18 + Math.floor(Math.random() * 24);
235+
for (var j = 0; j < len; j++) {
236+
s += Math.random() < 0.12 ? ' ' : glyphs[Math.floor(Math.random() * glyphs.length)];
237+
}
238+
print('<span class="term-ascii">' + esc(s) + '</span>', null);
239+
}
240+
print('(Matrix 彩蛋。输入 clear 结束这场雨。)', 'term-muted');
241+
}
242+
243+
function coin() {
244+
var face = Math.random() < 0.5;
245+
print('🪙 ' + (face ? '正面' : '反面') + '(' + (face ? 'heads' : 'tails') + ')', 'term-ok');
246+
}
247+
248+
function dice() {
249+
var n = 1 + Math.floor(Math.random() * 6);
250+
var faces = ['', '⚀', '⚁', '⚂', '⚃', '⚄', '⚅'];
251+
print('🎲 掷出了 ' + n + ' 点 ' + faces[n], 'term-ok');
252+
}
253+
254+
function fish() {
255+
var art = [
256+
['term-info', ' /`·.¸'],
257+
['term-info', ' /¸...¸`:·'],
258+
['term-info', ' ¸.·´ ¸ `·.¸.·´)'],
259+
['term-ascii', ': © ):´; ¸ {'],
260+
['term-info', ' `·.¸ `· ¸.·´\\`·¸)'],
261+
['term-info', ' `\\\\´´\\¸.·´']
262+
];
263+
print('你的小鱼:', 'term-ok');
264+
art.forEach(function (row) { print(row[1], row[0]); });
265+
print('(它正游过你的终端。输入 clear 放它回大海。)', 'term-muted');
266+
}
267+
268+
function sl() {
269+
var art = [
270+
['term-warn', ' ==== ________'],
271+
['term-warn', ' _D _| |_______/ \\__I_I_____===__|_________|'],
272+
['term-warn', ' |(_)--- | H\\________/ | | =|___ ___|'],
273+
['term-warn', ' / | | H | | | | ||_| |_||'],
274+
['term-warn', ' | | | H |__--------------------| [___] |'],
275+
['term-warn', ' | ________|___H__/__|_____/[][]~\\_______| |'],
276+
['term-warn', ' |/ | |-----------I_____I [][] [] D |=======|__']
277+
];
278+
print('你输的是 sl,不是 ls 😄 不过没关系,火车来了:', 'term-warn');
279+
art.forEach(function (row) { print(row[1], row[0]); });
280+
print('—— 这列小火车开走了。下次记得 ls。', 'term-muted');
281+
}
282+
283+
function vim() {
284+
var msgs = [
285+
'你想退出 vim?先试试 :q! 吧。哦对,这里连 vim 都没有,你自由了。',
286+
'退出 vim 的正确姿势:<Esc> :q! <Enter>。或者直接拔电源。',
287+
'你不是第一个卡在 vim 里的人。放心,这里真的没有 vim。',
288+
'vim 不可怕,可怕的是以为自己在 vim 里却退不出来。你安全了。'
289+
];
290+
print(msgs[Math.floor(Math.random() * msgs.length)], 'term-accent');
291+
}
292+
178293
function whoami() {
179294
print('TY —— 程序员 / 折腾爱好者 / 博客主', null);
180295
print('GitHub: <a href="https://github.com/tyuecode" target="_blank" rel="noopener">github.com/tyuecode</a>', null);
@@ -257,6 +372,13 @@
257372
case 'random': random(); break;
258373
case 'neofetch': case 'fetch': neofetch(); break;
259374
case 'fortune': case 'quote': fortune(); break;
375+
case 'cowsay': cowsay(args.join(' ')); break;
376+
case 'matrix': matrix(args[0]); break;
377+
case 'coin': coin(); break;
378+
case 'dice': dice(); break;
379+
case 'fish': fish(); break;
380+
case 'sl': sl(); break;
381+
case 'vim': case 'vi': vim(); break;
260382
case 'whoami': whoami(); break;
261383
case 'date': dateCmd(); break;
262384
case 'echo': echoCmd(args); break;
@@ -277,7 +399,8 @@
277399
var historyIndex = -1;
278400

279401
var COMMANDS = ['help', 'ls', 'cat', 'random', 'neofetch', 'fortune',
280-
'whoami', 'date', 'echo', 'search', 'theme dark', 'theme light', 'clear', 'sudo', 'exit'];
402+
'cowsay', 'matrix', 'coin', 'dice', 'fish', 'whoami', 'date', 'echo',
403+
'search', 'theme dark', 'theme light', 'clear', 'sl', 'vim', 'sudo', 'exit'];
281404

282405
input.addEventListener('keydown', function (e) {
283406
if (e.key === 'Enter') {

0 commit comments

Comments
 (0)