Edit in JSFiddle

<textarea id="target-textarea" spellcheck="false">Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.
    Test lorem ipsum dolor sit amet.
    Test lorem ipsum dolor sit amet.
    Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.
Test lorem ipsum dolor sit amet.</textarea>

<button onclick="_tab(document.getElementById('target-textarea'));">Tab</button>
<button onclick="_untab(document.getElementById('target-textarea'));">Untab</button>
(function() {

    var tabCharacter = '    '; // Use `\t` or multiple space character

    var select = function(start, end, target) {
        target.focus();
        target.setSelectionRange(start, end);
    };

    window._tab = function(target) {

        var start = target.selectionStart,
            end = target.selectionEnd,
            value = target.value,
            selections = value.substring(start, end).split('\n');

        for (var i = 0, len = selections.length; i < len; ++i) {
            selections[i] = tabCharacter + selections[i];
        }

        target.value = value.substring(0, start) + selections.join('\n') + value.substring(end);

        // re-select text after tabbing
        var selectEnd = (end + (tabCharacter.length * selections.length));
        if (start == end) {
            select(selectEnd, selectEnd, target);
        } else {
            select(start, selectEnd, target);
        }

    };

    window._untab = function(target) {

        var start = target.selectionStart,
            end = target.selectionEnd,
            value = target.value,
            pattern = new RegExp("^" + tabCharacter),
            edits = 0;

        if (start == end) { // single line

            while (start > 0) {
                if(value.charAt(start) == '\n') {
                    start++;
                    break;
                }
                start--;
            }

            var portion = value.substring(start, end),
                matches = portion.match(pattern);

            if (matches) {
                target.value = value.substring(0, start) + portion.replace(pattern, "") + value.substring(end);
                end--;
            }

            // set caret position after tabbing
            var selectEnd = end <= start ? end : end - tabCharacter.length + 1;
            select(selectEnd, selectEnd, target);

        } else { // multiline

            var selections = value.substring(start, end).split('\n');

            for (var i = 0, len = selections.length; i < len; ++i) {
                if (selections[i].match(pattern)) {
                    edits++;
                    selections[i] = selections[i].replace(pattern, "");
                }
            }

            target.value = value.substring(0, start) + selections.join('\n') + value.substring(end);

            // re-select text after tabbing
            select(start, (edits > 0 ? end - (tabCharacter.length * edits) : end), target);

        }

    };

})();