Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> вставка/удаление 4-х пробелов при нажатии, "Ctrl+]"/"Ctrl+[" 
:(
    Опции темы
pythonwin
Дата 25.9.2006, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Всем доброго времени суток!

помогите, пожалуйста сделать вставку отступов на форуме по питону!

есть определённый код - спасибо smartov, но у него есть одна ошибка которую нужно исправиль.

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

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


проблема:
Цитата

Единственная текущая проблема кода - то что он работает с выделением а не с линиями.

Если выделить любой один символ в середине строки и нажать Ctrl+], то пробелы будут добавляться перед этим символом, а не в начало строки.


Код:

Код

<html>
<body>
<script>
var tabSymbol;
//Change this value to needed
//tabSymbol = "    ";//tabulator
tabSymbol = "    ";//4spaces
//tabSymbol = "  ";//2 spaces
//----------
var cachedEvent;
var linesUpdated;
String.prototype.repeat = function(count) { 
    var tmp = this.valueOf();
    for (var i=1; i < count; i++)
    {
        tmp += this.valueOf();
    }
    return tmp;
};
function indentString($str)
{
    if (!$str)
        return "";
    $str_arr = $str.split(/\n/);
    for (var i=0; i < $str_arr.length; i++)
    {
        $str_arr[i] = tabSymbol + $str_arr[i];
    }
    
    linesUpdated = $str_arr.length;
    return $str_arr.join("\n");
}
function unindentString($str)
{
    if (!$str)
        return "";
    $str_arr = $str.split(/\n/);
    for (var i=0; i < $str_arr.length; i++)
    {
        if ($str_arr[i].indexOf(tabSymbol) == 0)
        {
            $str_arr[i] = $str_arr[i].replace(tabSymbol, '');
        }
    }
    linesUpdated = $str_arr.length;
    return $str_arr.join("\n");
}
function indentSelection(targetTextarea, unindent)
{
    if (document.selection) //IE, Opera 9
    {
        range = document.selection.createRange();
        range.text = unindent ? unindentString(range.text) : indentString(range.text);
    } 
    else //Mozilla
    {
        var selStart = targetTextarea.selectionStart;
        var selEnd = targetTextarea.selectionEnd;
        var selection = targetTextarea.value.substr(targetTextarea.selectionStart, targetTextarea.selectionEnd - targetTextarea.selectionStart);
        selection = unindent ? unindentString(selection) : indentString(selection);
        targetTextarea.value = targetTextarea.value.substr(0, targetTextarea.selectionStart) 
            + selection
            + targetTextarea.value.substr(targetTextarea.selectionEnd);
        
        var chars = tabSymbol.repeat(linesUpdated).length;
        selEnd = unindent ? (selEnd-chars) : (selEnd+chars);
        targetTextarea.setSelectionRange(selStart, selEnd);
    }
}
function getEvent(textarea, $event)
{
//219 - [
//221 - ]
    if (cachedEvent == 17 && $event == 219)
    {
        indentSelection(textarea, true);
        cachedEvent = 17;
        return;
    }
    if (cachedEvent == 17 && $event == 221)
    {
        indentSelection(textarea, false);
        cachedEvent = 17;
        return;
    }
    cachedEvent = $event;
}
</script>
<textarea id="asd" style="width:500px;height:500px;" onKeydown="getEvent(this, event.keyCode)">
myarray = new Array();
myarray.push('forum');
myarray.push('vingrad');
myarray.push('ru');
var str;
for (var i=0; i < count(myarray); i++)
{
str += myarray[i];//ident me;
str += '.';//ident me;
}
alert(str);
</textarea>
</body>
</html>


Более подробно:

4 пробела в форуме по питону
PM WWW GTalk Jabber   Вверх
sergejzr
Дата 25.9.2006, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 10
Всего: 360



Модератор: [B]pythonwin, не следует дублировать темы![/B]


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
pythonwin
Дата 25.9.2006, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Цитата(sergejzr @  25.9.2006,  19:15 Найти цитируемый пост)
Модератор: pythonwin, не следует дублировать темы! 

Прошу прощения за это, но это было так задумано:
1) поместил в JS, т.к. проблему в коде могут устранить JS-ники
2) поместил в "Центр помощи", т.к. сюда заходят форумчане, у которых есть свободное время + есть желание помочь ближнему. smile
3) устал нажимать 4 пробела в форуме по питону smile - решение вынести проблему из "обсуждения форума" было обосновано, тем что разработка в "27" остановилась, а проблема тормозит развитие форума по Python. smile
PM WWW GTalk Jabber   Вверх
pythonwin
Дата 25.9.2006, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



решение этой проблемы поможет развитию форума по питону! smile

Это сообщение отредактировал(а) pythonwin - 26.9.2006, 11:51
PM WWW GTalk Jabber   Вверх
Cr@$h
Дата 26.9.2006, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: нет
Всего: 41



Так или иначе, обсуждение реализации лучше делать в одном месте и лучше в Обсуждении ИМХО. smile 
PM MAIL ICQ   Вверх
Sardar
Дата 26.9.2006, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Нужно селекцией добежать до начала строки, затем как было, разбить по строкам добавить пробелы. Для мозиллы просто, бежим с selectionStart пока не упрёмся в \n (10). Для ИЕ геморно, вчера вечером игрался, так и не порешал безглючно.

Что бы к форуму прикрутить быстро нужно пользовать TextAreaSelectionHelper и HotKeyHandler обьекты. Пример на хоткеи:

Код
HotKeyHandler.keys = {
 //добавляем эти две строки в уже существующий .keys
 "\u00FB": function() { post.indentBlock("    "); },  //ctrl+[
 "\u00FD": function() { post.unindentBlock(); }  //ctrl+]
};


В TextAreaSelectionHelper добавляем два метода indentBlock и unindentBlock. Это кривое ad-hoc решение, т.к. никогда не думал что в TextAreaSelectionHelper потребуеться копировать селекцию. Копия (скрытая, виртуальная, называй как хочешь) селекция нужна для работы с текстом, не меняя позиции реального курсора.

Каркас indent может выглядеть так:
Код
TextAreaSelectionHelper.prototype.indentBlock = function(indchrs) {
  if(this.iesel&&(window.opera || this.iesel.parentElement()==this.target)) {
     //здесь код для IE и опера (те кто поддерживает document.selection)
     //this.iesel - TextRange настоящей селекции, при работе нужно делать .duplicate()
  } else if(this.start>=0&&this.end>=this.start) {
     //mozilla code
     //здесь доступны this.start - начало селекции, this.end - конец селекции в символах
     //this.start нужно отодвинуть до начала строки, просто перебором символов
     //из this.target.value.charAt(this.start--)

     // в мозилле с текстом работаем так:
     var left=this.target.value.substring(0,this.start);  //текст до курсора/селекции
     var right=this.target.value.substr(this.end); //текст после курсора/селекции
     var scont=this.target.value.substring(this.start, this.end); //пусто или отселектированный текст

      //бьём scount по линиям, добавляем префикс indchrs, ставим
      this.target.value=left+scont+right;
      this.target.scrollTop=this.scroll; //необходимо, иначе прыгнем вверх/вниз
      this.target.focus(); //возвращаем фокус если убежал
  }
}


unindentBlock делаем точно также. Редизайном TextAreaSelectionHelper займусь позже (когда найду время smile ).

Собстно для ИЕ глючный может быть таким, читать коменты почему в простых текстовых приложениях docment.selection не рулит (но рулит когда работаем вообще с документом):

Код
//сие предназначено на место комента "здесь код для IE и опера..."
      //Узнать находимся ли мы на новой строке можно только одним способом:
      //пройти назад и посмотреть не лежит ли там символ \r. Символ \n сьедаеться ИЕ полностью.
      //Но! если мы находимся в начале текста (перед первым символом), то поход
      //назад вынесет селекцию из textarea. Эту жуткую хрень тоже надо обрабатывать.
      
      var d = document.getElementById("dbg");
      
      if(this.iesel.text.length == 0) {
          d.innerHTML+="<br>empty";
          var check = this.iesel.duplicate();
          check.moveStart("character", -1);
          if(check.parentElement() != this.target) {//[censored 2] , мы в начале текста!
              d.innerHTML+="<br>fixbegin";
              this.iesel.text = indchrs;
              return;
          } else this.iesel = check;
          d.innerHTML+="<br>on empty sel len: "+check.text.length;
          if(check.text.length == 0)
              check.moveStart("character", -1);
      }
      
      //мы точно имеем минимум 1 символ в селекции, но может быть это \r из предидущей строки
      var ch;
      while(((ch = this.iesel.text.charAt(0)) != '\r' && ch != '\n')) {
          d.innerHTML+="<br>charback: "+ch+", "+ch.charCodeAt(0);
          //двигаем селекцию, но тут кроеться лажа, если мы дойдём до начала текста,
          //то наша селекция может "выпасть" за пределы текстового поля.
          //грёбанные ИЕ программисты, ну нахрена так усложнять то?
          var temp = this.iesel.duplicate(); //ж сколько памяти хавает наверное...
          if(temp.moveStart("character", -1) == 0) break; //хорошо бы тут остановиться, но селекция в ИЕ пойдёт дальше, это условие на моей машине никогда не отрабатывает
          if(temp.parentElement() != this.target) break; //млин таки вылезли за текстовое поле, нафих всё отрубаем
          this.iesel = temp;
      }
      
      //если первый символ это \r, значит мы в середине текста
      if((ch = this.iesel.text.charAt(0)) == '\r' || ch == '\n') {
          d.innerHTML+="<br>forward to suppress line";
          this.iesel.moveStart("character", 1);
      }
      
      //и так у нас есть целиком текст, который можно отодвинуть блоко      
      var lines = this.iesel.text.split(/\n/);
      for (var i=0; i<lines.length; i++)
          lines[i] = indchrs + lines[i];
      this.iesel.text = lines.join("\n");


Сильно не пинать ибо спал вчера 4 часа (сегодня 6, голова гудит...  smile ), а в такой нирване я бывает мыслю не адекватно smile



--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
pythonwin
Дата 27.9.2006, 06:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Цитата(Cr@$h @  27.9.2006,  02:50 Найти цитируемый пост)
Так или иначе, обсуждение реализации лучше делать в одном месте и лучше в Обсуждении ИМХО. smile  

я был вынужден создать ещё темы на разных подфорумах, т.к. в обсуждении тема перестала развиваться. smile + smartov, разрешил размещать код где угодно smile

Добавлено @ 06:39 
Sardar, а есть полный код, чтобы я его потестировал? smile
PM WWW GTalk Jabber   Вверх
Cr@$h
Дата 27.9.2006, 08:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: нет
Всего: 41



Цитата(pythonwin @  27.9.2006,  07:37 Найти цитируемый пост)
я был вынужден создать ещё темы на разных подфорумах, т.к. в обсуждении тема перестала развиваться.  + smartov, разрешил размещать код где угодно 

Хорошо, давайте добивать код в JS.
PM MAIL ICQ   Вверх
pythonwin
Дата 27.9.2006, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Цитата(Cr@$h @  27.9.2006,  15:49 Найти цитируемый пост)

Хорошо, давайте добивать код в JS.

Ура, администрация одобрила! smile
 smile 
PM WWW GTalk Jabber   Вверх
Sardar
Дата 27.9.2006, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(pythonwin @  27.9.2006,  05:37 Найти цитируемый пост)
Sardar, а есть полный код, чтобы я его потестировал?

Да какой полный код, мозилловскую часть напишет любой студент (не напишите сами, сделаю я, но позже). ИЕ'шную часть выложил выше, криво ибо набросок. Ссылкой тут, открываем в IE, ctrl+[ отодвигает как напоминание "не юзать" smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Cr@$h
Дата 27.9.2006, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: нет
Всего: 41



Цитата(pythonwin @  27.9.2006,  12:05 Найти цитируемый пост)
Ура, администрация одобрила!

Скорее, я. smile  Когда код будет готов и отлажен, его нужно будет попросить поставить на обработку этих комбинаций клавиш. Это непременно полезно для всех тематических форумов. Уверен, многих, кто пишет прямо здесь, задалбывает ставить 4 пробела. Идея хорошая, а раз темы по ней ещё живы, значит перспективы радужные. smile Я надеюсь.
PM MAIL ICQ   Вверх
pythonwin
Дата 28.9.2006, 07:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Цитата(Cr@$h @  28.9.2006,  03:08 Найти цитируемый пост)
Уверен, многих, кто пишет прямо здесь, задалбывает ставить 4 пробела.

Согласен! я - один из них. smile

PM WWW GTalk Jabber   Вверх
Cr@$h
Дата 28.9.2006, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Исследователь
***


Профиль
Группа: Участник Клуба
Сообщений: 1693
Регистрация: 3.4.2005
Где: Санкт-Петербург, Россия

Репутация: нет
Всего: 41



Как дело придвигается?
PM MAIL ICQ   Вверх
pythonwin
Дата 29.9.2006, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 2529
Регистрация: 18.4.2006
Где: за компом

Репутация: 1
Всего: 36



Цитата(Cr@$h @  29.9.2006,  04:28 Найти цитируемый пост)
Как дело придвигается? 

уже потестировал и сейчас напишу результаты.

Добавлено @ 08:03 
Sardar, потестировал есть несколько багов:
1) по условию:
Цитата(pythonwin @  25.9.2006,  18:59 Найти цитируемый пост)

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


а в реальности при нажатии "Ctrl+[" пробелы добавляются, хотя должны удаляться smile
2) если выделить блок (одна и более строк) и нажать "Ctrl+[", то после добавления пробелов строка ниже блока перемещается в конец последней строки выделеного блока, который сдвигали.

smile


Это сообщение отредактировал(а) pythonwin - 29.9.2006, 08:04
PM WWW GTalk Jabber   Вверх
Zeroglif
Дата 29.9.2006, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 644
Регистрация: 22.9.2005

Репутация: 28
Всего: 66



Набросал под IE6/OP9 only - http://www.404.googlepages.com/indent_in_textarea.html

- Отступы = 4 пробела.
- Добавляем отступы с помощью TAB или Ctrl+], удаляем с помошью SHIFT+TAB или CTRL+[.
- Если выделения нет, то и блока нет, просто добавляем/удаляем отступы слева от курсора.
- Если выделение есть, то появляется блок, расширяем блок влево (то есть можно не выделять строку полностью).
- Выделение постоянно на виду (мне так удобнее).

Отпишитесь пока, то или не то по функционалу, дальше будем в приличный вид приводить и проч.


PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0904 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.