Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Обсуждение форума > внедрение вставки/удалении 4-х пробелов


Автор: pythonwin 4.10.2006, 13:44
Всем привет!

предлагаю внедрить/установить готовый скрипт (пример работы на http://www.404.googlepages.com/indent-in-textarea-by-zeroglif.html)

скрипт тестировался на FF/Mozilla/IE/Opera

задача:
Цитата

А можно сделать так, чтобы при нажатии "Ctrl+]" в начало строки добавлялось 4 пробела, а при нажатии "Ctrl+[" - удалялось? Желательно чтобы это возможность работала и для целых блоков кода на питоне.


более подробно:
http://forum.vingrad.ru/index.php?showtopic=113416&view=all

код примера:
Код

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>

    
        <meta http-equiv="content-type" content="text/html; charset=windows-1250">
        <meta name="generator" content="PSPad editor, www.pspad.com">
        <script src="indent-in-textarea-by-zeroglif.js" type="text/javascript"></script>
        <style type="text/css">
        textarea {font-family:Consolas,Courier New;font-size:14px;font-weight:bold}
        </style><title>Indent-in-textarea-by-Zeroglif</title></head><body>
        <form>
            <textarea cols="80" rows="20" wrap="off">    function A(o) {
        var i = 0, a, b;
        for (; i &lt; o.length; i++) {
            if (o[i].type == 'text') {
                o[i].up = a ? (a.dn = i, b) : -1;
                o[i].onkeydown = B;
                a = o[i], b = i;
            }
        }
    }
    function B(e) {
        var t = (e = e || event).target || e.srcElement, k = e.keyCode, n;
        n = (k == 40) ? t.dn : k == 38 ? t.up : -1;
        if (n &gt;= 0) t.form.elements[n].focus();
    }
            </textarea>
        </form>
    </body></html>


код indent-in-textarea-by-zeroglif.js
Код

var ZRGLF=function(){var p='    ';function I(){E(document.getElementsByTagName('textarea')[0],'keydown',F,1);}function E(o,e,f,s){var p='',b=['remove','add','detach','attach'];(o[b[s]+'EventListener']||(p='on',o[b[s+2]+'Event']))(p+e,f,false);}function F(){var e=arguments[0],n=e.target,a=(e.ctrlKey&&String.fromCharCode(e.keyCode).match(/^\u00FD|\]|\u042A$/i)),b=(e.ctrlKey&&String.fromCharCode(e.keyCode).match(/^\u00FB|\[|\u0425$/i));if(a||b){if(document.selection){var r=document.selection.createRange(),o=window.opera,r2,t,c='character';function F(m,n){var r2=r.duplicate(),l=r.text.length,s=(n)?-1:1,i=0;r2[m](c,s);while(r2.text.length>l&&r2.text.charAt(n||r2.text.length-1)!=((o)?'\n':'\r')){l=r2.text.length;r2[m](c,s);i--;}return i;}r.moveStart(c,F('moveStart','0'));(((r2=r.duplicate()).moveEnd(c,1),r2.text.length)-r.text.length!=3)?r.moveEnd(c,-F('moveEnd')):r.moveEnd(c,-1);r.text=(t=(b)?r.text.split('\n'+p).join('\n').replace(eval('/^'+p+'/'),''):p+r.text.split('\n').join('\n'+p));r.moveStart(c,(!o)?t.split('\r').length-t.length-1:-t.length);r.select();}else{var ss='selectionStart',se='selectionEnd',x=n[ss],y=n[se],l=n.value.length,z;x=(n[ss]=n.value.slice(0,x).lastIndexOf('\n')+1);y=(n[se]=(((z=n.value.slice(y,l)).indexOf('\n')!=-1)?y+z.indexOf('\n'):l));if(a){n.value=n.value.slice(0,x)+p+n.value.slice(x,y).split('\n').join('\n'+p)+n.value.slice(y,l);n[ss]=x;n[se]=y+n.value.length-l;}else{n.value=n.value.slice(0,x)+n.value.slice(x,y).split('\n'+p).join('\n').replace(eval('/^'+p+'/'),'')+n.value.slice(y,n.value.length);n[ss]=x;n[se]=y-(l-n.value.length);}}e.preventDefault?e.preventDefault():e.returnValue=false;return false;}}window.onload=I;}();


Автор: pythonwin 4.10.2006, 15:03
код с коментариями:
http://forum.vingrad.ru/index.php?showtopic=113416&view=findpost&p=877326

Автор: pythonwin 4.10.2006, 15:47
Код

    var ZRGLF = function () {
        /* собсно это и есть типа индент такой, 4 пробела, можно и 2 или 20...*/
        var p = '    ';
        /* инициализирующая функция, в ней вызов функции, прикрепляющей обработчик,
        первый аргумент - textarea, меняем его по-желанию или добавляем вызовы*/
        function I() {   
            E(document.getElementsByTagName('textarea')[0], 'keydown', F, 1);
        }
        /* функция, прикрепляющая обработчик, выглядит стрёмно, но я к ней привык
        последний параметр (s) может быть числом 1 (прикрепить) или 0 (открепить), 
        но этому скрипту это по-барабану, объяснил, чтоб не пугались, остальные 
        параметры обычные - объект, имя события, функция*/
        function E(o, e, f, s) {
            var p = '', b = ['remove', 'add', 'detach', 'attach'];
            (o[b[s]+'EventListener'] || (p = 'on', o[b[s+2]+'Event']))(p + e, f, false);
        }
        /* основная функция, в ней всё и происходит*/
        function F() {
            /* e - это объект события, он автоматом приходит в эту функцию первым аргументом,
            a - кнопки индента, b - кнопки анинтдента, n - textarea*/
            var e  = arguments[0],
                n = e.target,
                a = (e.ctrlKey && String.fromCharCode(e.keyCode).match(/^\u00FD|\]|\u042A$/i)),
                b = (e.ctrlKey && String.fromCharCode(e.keyCode).match(/^\u00FB|\[|\u0425$/i));           
            if (a || b) {
                /* если IE или Opera (они поддерживают selection)*/
                if (document.selection) {
                    var r = document.selection.createRange(), o = window.opera, r2, t, c = 'character';
                    /* идея в том, чтобы выделить ПОЛНОСТЬЮ строку (строки), где стоит курсор или где 
                    местами есть выделение, соответственно нам нужно расширить текстовый диапазон налево (направо) до
                    метки новой строки (\r в IE) или (\n в Opera) или до начала/конца textarea value. Функция работает
                    так: создаём дубликат диапазона, расширяем этот дубликат на 1 символ влево (вправо).
                    Затем запускаем цикл, который должен остановиться, когда мы или упрёмся в метку новой строки или
                    в начало (конец) textarea value. В цикле наращивается число шагов (i), на это самое число мы 
                    должны потом сдвинуть реальный диапазон (не дубликат). Параметр m - это или 'moveStart' (идём налево) 
                    или 'moveEnd' (идём направо), в первом случае шаг отрицательный, во втором - наоборот.*/                   
                    function F(m, n) {
                        var r2 = r.duplicate(), l = r.text.length, s = (n) ? -1 : 1, i = 0;
                        r2[m](c, s);
                        while (r2.text.length > l &&
                            r2.text.charAt(n || r2.text.length - 1) != ((o) ? '\n' : '\r')) {
                            l = r2.text.length;
                            r2[m](c, s);
                            i--;
                        } 
                       return i;
                    }
                    /* расширяем диапазон влево*/
                    r.moveStart(c, F('moveStart', '0'));
                    /* расширяем диапазон вправо, но предварительно определяем, не зацепили ли мы выделением скрытый
                    символ \r справа, для этого создаём дубликат, делаем шаг вправо на один символ и сразу сравниваем длины
                    текста в дубликате и текста в оригинале. Если разница = 3, то мы зацепили \r. В этом случае нам нет
                    необходимости расширять диапазон вправо, а нужно сделать один шаг влево, чтобы убрать \r из диапазона*/
                    (((r2 = r.duplicate()).moveEnd(c, 1), r2.text.length) - r.text.length != 3)
                        ? r.moveEnd(c, - F('moveEnd'))
                        : r.moveEnd(c, -1);
                    /*тут всё просто, меняем текст внутри текстового диапазона в зависимости от нажатых кнопок*/
                    r.text = (t = (b) 
                        ? r.text.split('\n' + p).join('\n').replace(eval('/^' + p + '/'), '')
                        : p + r.text.split('\n').join('\n' + p));
                    /*двигаем диапазон, для Оперы на длину нового текста, а для IE с поправкой на скрытые \r*/
                    r.moveStart(c, (!o)
                        ? t.split('\r').length - t.length - 1
                        : - t.length);
                    /*выделяем*/
                    r.select();
                /* если FF, Seamonkey и проч... (не поддерживают selection)*/
                } else {
                    /*по-моему всё более-менее понятно, выделяем вставляем, снова выделяем*/
                    var ss = 'selectionStart', se = 'selectionEnd', x = n[ss], y = n[se], l = n.value.length, z;                                   
                    x = (n[ss] = n.value.slice(0, x).lastIndexOf('\n') + 1);
                    y = (n[se] = (((z = n.value.slice(y, l)).indexOf('\n') != -1) ? y + z.indexOf('\n') : l));
                    if (a) {
                        n.value = n.value.slice(0, x) + p + n.value.slice(x, y).split('\n').join('\n' + p) + n.value.slice(y, l);
                        n[ss] = x;
                        n[se] = y + n.value.length - l;
                    } else {
                        n.value = n.value.slice(0, x) + n.value.slice(x, y).split('\n' + p).join('\n').replace(eval('/^' + p + '/'), '') + n.value.slice(y, n.value.length);                  
                        n[ss] = x;
                        n[se] = y - (l - n.value.length);
                    }               
                }
                /*отменяем стандартные действия для выбранных кнопок, Опера подглючивает*/                 
                e.preventDefault ? e.preventDefault() : e.returnValue = false;
                return false;
            }
        }
        /*вешаем обработчик на окно*/
        window.onload = I;
    /*вызываем самоё себя*/
    }();

Автор: Cr@$h 5.10.2006, 01:12
Полностью поддерживаю. Слежу за этими темами с самого начала. На ИЕ сам тестировал. Очень удобно для написания кода прямо на форуме.

Включите, пожалуйста, код в обработку этих комбинаций на всех форумах. Очень прошу. После внедрения я или кто-то другой хорошо, чтобы разместил новость в мире Vingrad.
Вещь полезная, и многие, уверен, сразу её оценят.

Автор: pythonwin 5.10.2006, 07:52
Cr@$h, думаю что у админов есть сильные сомнения - нужно ли. smile

то что есть код - это полдела - нужно ещё "внедрить"! smile

Cr@$h, за поддерку спасибо!

Автор: smartov 5.10.2006, 12:34
Я тоже за. Не хватает этой фичи. Не очень то удобно пробелами идентировать.

Автор: sergejzr 5.10.2006, 12:42
Точто он сам посебе работает - хороши конечно. Вопрос в том, насколько это будет гармонировать с сущ. скриптами форума. Там и так хендлеров на поле ввода понавешено. Сделайте тестовую страничку форума и прикрепите туда скрипт. Потом тесты. Потом посмотрим...

Автор: pythonwin 5.10.2006, 13:02
Цитата(sergejzr @  5.10.2006,  19:42 Найти цитируемый пост)
Точто он сам посебе работает - хороши конечно. Вопрос в том, насколько это будет гармонировать с сущ. скриптами форума. Там и так хендлеров на поле ввода понавешено. Сделайте тестовую страничку форума и прикрепите туда скрипт. Потом тесты. Потом посмотрим...


а где можно взять эту тестовую страничку?

Автор: sergejzr 5.10.2006, 13:08
[Ctrl+s]

Автор: pythonwin 5.10.2006, 13:21
Цитата(sergejzr @  5.10.2006,  20:08 Найти цитируемый пост)
[Ctrl+s] 

хорошо! smile

правда я JS не так хорошо знаю чтобы самому изменять код. smile

Автор: sergejzr 5.10.2006, 13:22
Ну кто-то должен это сделать.

Автор: Girder 5.10.2006, 13:23
Кода много... очень много...

PS: Тем более работает он кривовато...

PS2: А вообще... что бы добавить пару пробелов(или удалить)... то в текущих скриптах енто пара строк кода(ну... чуть по больше). Но полезности в ентой возможности... имхо 0.

Автор: pythonwin 5.10.2006, 13:32
Girder, ты на питоне програмировал?

Автор: sergejzr 5.10.2006, 13:41
Girder, если надо, то надо smile К тому же это только в питонском разделе будет вставлятся. Просто ребята должны дать готовый модульный вариант а-ля взять и поставить. А пока здесь только реализация самого алгоритма. Никто из нас адаптацией заниматься не будет..

Автор: Girder 5.10.2006, 14:02
Цитата(pythonwin @  5.10.2006,  14:32 Найти цитируемый пост)
Girder, ты на питоне програмировал? 
Я конечно... дико извеняюсь... а при чем здесь питон и код на форуме?  smile 

Автор: sergejzr 5.10.2006, 14:07
Girder, там фроматирование кода играет роль для языка. Им действительно тяжело форматировать ручками в нашей форме ответа..

Автор: pythonwin 5.10.2006, 14:14
Цитата(sergejzr @  5.10.2006,  21:07 Найти цитируемый пост)
Girder, там фроматирование кода играет роль для языка. Им действительно тяжело форматировать ручками в нашей форме ответа..

верно! smile

Автор: Girder 5.10.2006, 14:46
Цитата(sergejzr @  5.10.2006,  15:07 Найти цитируемый пост)
Girder, там фроматирование кода играет роль для языка. Им действительно тяжело форматировать ручками в нашей форме ответа.. 

Енто я понял... а разве при вставке готового кода в форму... с форматированием траблы?
Или есть необходимость писать много строк... прям в форме? user posted image

Автор: sergejzr 5.10.2006, 14:49
Цитата(Girder @  5.10.2006,  12:46 Найти цитируемый пост)
Или есть необходимость писать много строк... прям в форме? user posted image 

Я лично только в 30% ответов пользуюсь ИДЕ или компилятором. Обычно прямо в форму ответа пишу.

Автор: sergejzr 5.10.2006, 14:51
Это не во всех форумах надо ведь.

Автор: Girder 5.10.2006, 14:52
В любом случаи... добавить хоткей можно(если так уж нужно).
Да и кода... там не много добавиться.


Автор: pythonwin 5.10.2006, 14:55
Цитата(sergejzr @  5.10.2006,  21:51 Найти цитируемый пост)
Это не во всех форумах надо ведь.

почему? 4 пробела можно будет использовать и в других форумах и при вводе/редактировании не только кода питона!

Автор: sergejzr 5.10.2006, 14:57
Вообще моя идея была наоборот, как можно больше разделить код (типа как с подСветкой сейчас)


Добавлено @ 14:58 
Цитата(pythonwin @  5.10.2006,  12:55 Найти цитируемый пост)
почему? 4 пробела можно будет использовать и в других форумах и при вводе/редактировании не только кода питона!

Это не нужно никому в других форумах. Было бы гораздо прикольнее, если бы таб работал smile

Автор: pythonwin 5.10.2006, 14:58
Цитата(sergejzr @  5.10.2006,  21:57 Найти цитируемый пост)
Вообще моя идея была наоборот, как можно больше разделить код (типа как с подСветкой сейчас)

а если я буду писать код питона в php или JS?

4 пробела работать будут?

Автор: sergejzr 5.10.2006, 15:05
Цитата(pythonwin @  5.10.2006,  12:58 Найти цитируемый пост)
а если я буду писать код питона в php или JS?

Можно это подвесить на скрипт подсветки кстати... Неплохое расширение функциональности... Горячие клавиши в зависимости от языка..

Автор: pythonwin 5.10.2006, 15:09
Цитата(sergejzr @  5.10.2006,  22:05 Найти цитируемый пост)

Можно это подвесить на скрипт подсветки кстати... Неплохое расширение функциональности... Горячие клавиши в зависимости от языка..

идея хорошая - только у нас пока нет модуля (Sardar может возьмется если у него время свободное будет, но думаю его одного нехватит) smile

Автор: Girder 5.10.2006, 15:21
Оформляйте голосование... нужны или не нужны... такие возможности. Через голосование... имхо быстрее будет результат по нужности такой фичи smile



Автор: pythonwin 5.10.2006, 15:29
Цитата(Girder @  5.10.2006,  22:21 Найти цитируемый пост)
Оформляете голосование... нужны или не нужны... такие возможности.

опрос в форуме по питону создавать?

Автор: albertn 5.10.2006, 16:21
Цитата(Girder @  5.10.2006,  14:46 Найти цитируемый пост)
Енто я понял... а разве при вставке готового кода в форму... с форматированием траблы?

Просто еще программа может быть с табуляцией, а с ней всегда проблемы.

Автор: pythonwin 5.10.2006, 16:33
Цитата(albertn @  5.10.2006,  23:21 Найти цитируемый пост)

Просто еще программа может быть с табуляцией, а с ней всегда проблемы.

Да, бывает, что вставляешь из shell или IDE уже отлаженный код в форум, а когда его копируешь обратно - начинается ругань.

Автор: Cr@$h 6.10.2006, 17:59
Цитата(sergejzr @  5.10.2006,  15:57 Найти цитируемый пост)
Это не нужно никому в других форумах. Было бы гораздо прикольнее, если бы таб работал 

Цитата(albertn @  5.10.2006,  17:21 Найти цитируемый пост)
Просто еще программа может быть с табуляцией, а с ней всегда проблемы.

Возможно среда вставляет табуляцию, а не 4 пробела.
Цитата(sergejzr @  5.10.2006,  15:57 Найти цитируемый пост)
Это не нужно никому в других форумах. Было бы гораздо прикольнее, если бы таб работал 

Если бы можно было поставить таб, то ему (Tab и Shift+Tab) проще питонистов обучить. Тут другое, например, по табу в ИЕ идёт перемещение по элементам интерфейса.

Автор: pythonwin 9.10.2006, 11:19
пока у меня мало время - занят сильно - как освобожусь стану дальше толкать внедрение, хотя если кто-нибудь поможет, то буду только благодарен. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)