SOURCE

console 命令行工具 X clear

                    
>
console
var $ = function (s) {
    return document.querySelector(s)
}
var $$ = function (s) {
    return document.querySelectorAll(s)
}
var on = function (obj, type, listener, usercapture) {
    usercapture = usercapture ? false : usercapture
    obj.addEventListener(type, listener, usercapture)
}
var off = function (obj, type, listener) {
    obj.removeEventListener(type, listener)
}
var factories = {};
var define = function(modsname,factory) {
    factories[modsname] = factory;
}
var require = function(mods,callback) {
    let result = mods.map(function(name){
        return factories[name]();
    });
    callback.apply(null,result);
}
var matchColor = (function () {
    let keywords = ['break', 'else', 'new', 'var',
        'case', 'finally', 'return', 'void',
        'catch', 'for', 'switch', 'while',
        'continue', 'function', 'with',
        'default', 'if', 'throw', 'delete', 'in',
        'try', 'do', 'instranceof', 'typeof', 'let',
        'const', 'debugger', 'class', 'typeof', 'break'];
    let identifier = /^[a-zA-Z_$]+[a-zA-Z0-9_$]*/;
    let string = /[`'"]+[^`"']*[`'"]+/;
    let number = /^[0-9]+$/;
    function match(str) {
        if (keywords.indexOf(str) != -1) {
            return 'keyword';
        } else if (number.test(str) || (str == 'true' || str == 'false')) {
            return 'bool';
        } else if (identifier.test(str)) {
            return 'identifier';
        } else if (string.test(str)) {
            return 'str';
        } else {
            return 'common';
        }
    }
    return match;
})();
var split = (function () {
    let inline = {
        identifier: /^[a-zA-Z_$]+[a-zA-Z0-9_$]+/,
        str: /^[`'"]+[^`"']*[`'"]+/,
        char: /^[^\~\!@#\$\%\^\&\*\(\)\_\-\+\=\[\]\{\}\:\;\<\,\>\.\?\/\\\|\s]+/,
        space: /^\s+/,
        punct: /^[\~\!@#\%\^\&\*\(\)\-\+\=\[\]\{\}\:\;\<\,\>\.\?\/\\\|]/,
    }
    function split(str) {
        if (!str || typeof str != 'string') {
            return false;
        }
        let substr = str
        let cap = null
        let arr = []
        let len = 0;
        let matches = '';
        let n = 0;
        while (substr) {
            if ((cap = inline.identifier.exec(substr))) {
                matches = cap[0]
                len = matches.length
                arr.push(matches)
                substr = substr.slice(len)
            }
            if ((cap = inline.str.exec(substr))) {
                matches = cap[0]
                len = matches.length
                arr.push(matches)
                substr = substr.slice(len)
            }
            if ((cap = inline.char.exec(substr))) {
                matches = cap[0]
                len = matches.length
                arr.push(matches)
                substr = substr.slice(len)
            }
            if ((cap = inline.space.exec(substr))) {
                matches = cap[0]
                len = matches.length
                arr.push(matches)
                substr = substr.slice(len)
            }
            if ((cap = inline.punct.exec(substr))) {
                matches = cap[0]
                len = matches.length
                arr.push(matches)
                substr = substr.slice(len)
            }
            n++;
            if (n > 500) {
                break;
            }
        }
        return arr;
    }
    return split;
})();
var parseElement = (function () {
    function parse(ary) {
        let arr = ary;
        let elems = [];
        for (let i = 0; i < arr.length; i++) {
            let str = `<span class="${matchColor(arr[i])}">${arr[i].replace(/\s/g, '&nbsp;')}</span>`;
            elems.push(str)
        }
        let line = `<div class="line"><span>${elems.join("")}</span></div>`;
        return line;
    }
    return parse;
})();
var parseHTML = function (str) {
    let arr = split(str);
    return parseElement(arr);
}
var measurer = (function () {
    let ctx = document.createElement('canvas').getContext('2d');
    let object = {
        measure(str) {
            ctx.font = this.font;
            return ctx.measureText(str).width;
        },
        font: '14px Consolas',
        setFont(font) {
            this.font = font;
        }
    }
    return object;
})();
var code = (function () {
    let codes = ['let a = 10;']
    let substrfront = '';
    let substrend = codes[0] ? codes[0] : '';
    return {
        initCode(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        getLineData(n, callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return codes[n]
        },
        setFront(str, callback) {
            substrfront = str;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setEnd(str, callback) {
            substrend = str;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        getFront(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return substrfront;
        },
        getEnd(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return substrend;
        },
        writeLine(n, data, callback) {
            codes[n] = data;
            if (callback && typeof callback == 'function') {
                callback();
            }
        }
    }
})();
var cursor = (function () {
    let cursor = $('.cursor');
    let interval = null;
    let timeout = null;
    let col = 0;
    let row = 0;
    return {
        initCursor(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        getCursor(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return cursor
        },
        setPositionX(x, callback) {
            cursor.style.left = x + 'px'
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setPositionY(y, callback) {
            cursor.style.top = y + 'px'
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setPosition(x, y, callback) {
            cursor.style.left = x + 'px';
            cursor.style.top = y + 'px';
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        cursorHide(callback) {
            clearInterval(interval);
            cursor.style.visibility = 'hidden';
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        cursorShow(callback) {
            cursor.style.visibility = 'visible'
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        start(callback) {
            interval = setInterval(function () {
                let ishide = cursor.style.visibility == 'hidden'
                if (ishide) {
                    cursor.style.visibility = 'visible'
                } else {
                    cursor.style.visibility = 'hidden'
                }
            }, 550);
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        debounce(callback) {
            clearInterval(interval)
            clearTimeout(timeout)
            let that = this;
            this.cursorShow();
            timeout = setTimeout(function () {
                that.start()
            }, 200);
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        getRow(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return row;
        },
        getCol(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return col;
        },
        addCol(callback) {
            col++;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        subCol(callback) {
            col--;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        addRow(callback) {
            row++;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        subRow(callback) {
            row--;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setCol(c, callback) {
            col = c;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setRow(r, callback) {
            row = r;
            if (callback && typeof callback == 'function') {
                callback();
            }
        }
    }
})();

var inputarea = (function () {
    let inputarea = $('.inputarea');
    return {
        initInputarea(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        getInputElem(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return inputarea
        },
        focus(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            inputarea.focus();
        },
        blur(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            inputarea.blur();
        },
        setPositionX(x, callback) {
            inputarea.style.left = x + 'px';
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setPositionY(y, callback) {
            inputarea.style.top = y + 'px'
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setPosition(x, y, callback) {
            inputarea.style.left = x + 'px';
            inputarea.style.top = y + 'px';
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        writeLine(data, callback) {
            inputarea.value = data;
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        setSelectionRange(start, end) {
            inputarea.setSelectionRange(start, end);
        },
        getValue(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return inputarea.value;
        },
        getSelectionStart(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return inputarea.selectionStart;
        }
    }
})();

var codearea = (function () {
    let lines = $('.lines');
    let root = $('#root');
    return {
        getLinesElem(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return lines;
        },
        getRootElem(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
            return root;
        },
        initCodearea(callback) {
            if (callback && typeof callback == 'function') {
                callback();
            }
        },
        writeLine(data, callback) {
            lines.innerHTML = data;
        },
    }
})();

function Main() {
    cursor.initCursor(function () {
        cursor.cursorHide()
    })
    codearea.initCodearea(function () {
        let lines = codearea.getLinesElem()
        let root = codearea.getRootElem()
        function eventInit() {
            on(root, 'click', function () {
                inputarea.focus()
            });
        }
        eventInit();

        function codeInit() {
            let line = parseHTML(code.getLineData(0));
            lines.innerHTML = line;
        }
        codeInit();
    });
    inputarea.initInputarea(function () {
        let row = cursor.getRow();
        let data = code.getLineData(row);
        inputarea.writeLine(data)
        function eventInit() {
            let inputElem = inputarea.getInputElem();
            let moveInline = function () {
                let row = cursor.getRow();
                let col = cursor.getCol();
                let line = code.getLineData(row);
                if (col > line.length) {
                    cursor.setCol(line.length);
                }
                if (col < 0) {
                    cursor.setCol(0);
                }
                row = cursor.getRow();
                col = cursor.getCol();
                line = code.getLineData(row);
                let frontstr = line.slice(0, col);
                let endstr = line.slice(col);
                code.setEnd(endstr);
                code.setFront(frontstr, function () {
                    let frontwidth = measurer.measure(code.getFront());
                    cursor.setPositionX(frontwidth);
                    inputarea.setPositionX(frontwidth);
                    inputarea.setSelectionRange(col, col);
                });
            }
            let backspace = function () {
                let front = code.getFront();
                let end = code.getEnd();
                let row = cursor.getRow();
                front = front.slice(0, front.length - 1);
                code.setFront(front);
                let data = front + end;
                code.writeLine(row, data);
                let line = parseHTML(code.getLineData(row));
                codearea.writeLine(line)
                inputarea.writeLine(data);
                cursor.subCol(function () {
                    let frontwidth = measurer.measure(code.getFront());
                    let col = cursor.getCol();
                    cursor.setPositionX(frontwidth);
                    inputarea.setPositionX(frontwidth);
                    inputarea.setSelectionRange(col, col);
                });
            }
            let input = function () {
                let value = inputarea.getValue();
                let row = cursor.getRow();
                let col = inputarea.getSelectionStart();
                cursor.setCol(col, function () {
                    let col = cursor.getCol();
                    let front = value.slice(0, col);
                    code.setFront(front);
                    let frontwidth = measurer.measure(code.getFront());
                    cursor.setPositionX(frontwidth);
                    inputarea.setPositionX(frontwidth);
                });
                code.writeLine(row, value);
                codearea.writeLine(parseHTML(value));
            }
            let del = function () {
                let front = code.getFront();
                let end = code.getEnd();
                let row = cursor.getRow();
                end = end.slice(1);
                code.setEnd(end);
                let data = front + end;
                code.writeLine(row, data);
                let line = parseHTML(code.getLineData(row));
                codearea.writeLine(line)
                inputarea.writeLine(data);
                let frontwidth = measurer.measure(code.getFront());
                let col = cursor.getCol();
                cursor.setPositionX(frontwidth);
                inputarea.setPositionX(frontwidth);
                inputarea.setSelectionRange(col, col);
            }
            let end = function () {
                let row = cursor.getRow();
                let len = code.getLineData(row).length;
                cursor.setCol(len, function () {
                    let col = cursor.getCol();
                    let line = code.getLineData(row);
                    code.setFront(line);
                    code.setEnd("");
                    let frontwidth = measurer.measure(code.getFront());
                    cursor.setPositionX(frontwidth);
                    inputarea.setPositionX(frontwidth);
                    inputarea.setSelectionRange(col, col);
                })
            }
            let home = function () {
                let row = cursor.getRow();
                cursor.setCol(0, function () {
                    let col = cursor.getCol();
                    let line = code.getLineData(row);
                    code.setFront("");
                    code.setEnd(line);
                    let frontwidth = measurer.measure(code.getFront());
                    cursor.setPositionX(frontwidth);
                    inputarea.setPositionX(frontwidth);
                    inputarea.setSelectionRange(col, col);
                })
            }
            on(inputElem, 'input', function () {
                cursor.debounce()
                input();
            })
            on(inputElem, 'focus', function () {
                cursor.cursorShow()
                cursor.start(function () {
                    let col = cursor.getCol();
                    inputarea.setSelectionRange(col, col);
                });
            })
            on(inputElem, 'blur', function () {
                cursor.cursorHide()
            });
            on(inputElem, 'keydown', function (e) {
                let keys = [
                    'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown',
                    'Home', 'End', 'Backspace', 'Delete', 'Enter'
                ]
                let key = e.key
                if (keys.includes(key)) {
                    e.preventDefault()
                }
            });
            on(inputElem, 'mousedown', function (e) {
                e.preventDefault()
            })
            on(inputElem, 'keydown', function (e) {
                let key = e.key;
                if (key == 'ArrowLeft') {
                    cursor.debounce();
                    cursor.subCol(moveInline);
                } else if (key == 'ArrowRight') {
                    cursor.debounce();
                    cursor.addCol(moveInline);
                } else if (key == 'ArrowUp') {
                    cursor.debounce();

                } else if (key == 'ArrowDown') {
                    cursor.debounce();
                }
            });
            on(inputElem, 'keydown', function (e) {
                let key = e.key;
                if (key == 'Backspace') {
                    cursor.debounce();
                    backspace();
                } else if (key == 'Delete') {
                    cursor.debounce();
                    del();
                } else if (key == 'End') {
                    cursor.debounce();
                    end();
                } else if (key == 'Home') {
                    cursor.debounce();
                    home();
                }
            });
        }
        eventInit();
    });
}
Main()
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=, initial-scale=">
	<meta http-equiv="X-UA-Compatible" content="">
	<title></title>
</head>
<body>
	<div id="root">
        <div class="lines"></div>
        <textarea name="" class="inputarea" spellcheck="false" wrap="off" cols="" rows=""></textarea>
        <div class="cursor"></div>
    </div>
</body>
</html>
* {
    margin: 0;
    padding: 0;
}
#root {
    font-size: 14px;
    overflow: hidden;
    position: absolute;
    width: 100%;
    height: 100%;
    background: rgb(40, 44, 52);
    line-height: 20px;
    font-family: Consolas;
}
.inputarea {
    position: absolute;
    top: 0;
    left: 0;
    resize: none;
    box-sizing: border-box;
    height: 20px;
    width: 1px;
    opacity: 0;
}
.cursor {
    position: absolute;
    left: 0;
    top: 0;
    width: 0px;
    height: 20px;
    border-left: 2px solid red;
    box-sizing: border-box;
}
.lines .line {
    user-select: none;
    white-space: nowrap;
    height: 20px;
    cursor: text;
}
.keyword {
    color: #c678dd;
}
.identifier {
    color: #e06c75;
}
.bool {
    color: #d19a66;
}
.str {
    color: #98c379;
}
.common {
    color: #abb2bf;
}