<chapter id="advanced-editing-tools">
<chapterinfo>
<authorgroup>
<author
>&Anders.Lund; &Anders.Lund.mail;</author>
<othercredit role="translator"
><firstname
>Андрей</firstname
><surname
>Балагута</surname
><affiliation
><address
><email
>uj2@mail.ru</email
></address
></affiliation
><contrib
>Перевод на русский</contrib
></othercredit
> 
</authorgroup>
</chapterinfo>
<title
>Дополнительные возможности редактирования</title>

<sect1 id="comment">

<title
>Комментирование</title>

<para
>Команды "Комментировать" и "Раскомментировать", которые доступны из меню <guimenu
> Правка</guimenu
>, позволяют добавить или убрать маркеры комментариев для выделенного блока текста (или для текущей строки, если текст не выделен), при условии, что комментарии поддерживаются форматом редактируемого текста.</para>

<para
>Правила комментирования определяются синтаксисом; таким образом, если подсветка синтаксиса не включена, то команды "Закомментировать" и "Раскомментировать" будут недоступны.</para>

<para
>Некоторые форматы поддерживают только однострочные маркеры комментариев, другие -- только многострочные, третьи -- и те, и другие. Если многострочные маркеры недоступны, то комментирование блока, в котором не до конца выделена последняя строка, будет невозможным.</para>

<para
>Предпочтение отдается комментированию отдельных строк однострочными маркерами, если последние допустимы синтаксисом и если такое комментирование возможно -- это помогает избежать проблем со вложенными комментариями.</para>

<para
>При удалении маркеров комментариев выделение снимается с раскомментированного текста. При удалении маркеров многострочного комментария пробелы снаружи маркеров игнорируются.</para>

<para
><indexterm
><primary
>закомментировать</primary
></indexterm
> Чтобы закомментировать выделенный текст (или активную строку), выберите пункт меню<menuchoice
><guimenu
>Правка</guimenu
><guimenuitem
>Закомментировать</guimenuitem
></menuchoice
> или нажмите соответствующее сочетание клавиш (по умолчанию <keycombo action="simul"
>&Ctrl;<keycap
>#</keycap
></keycombo
>).</para>

<para
><indexterm
><primary
>раскомментировать</primary
></indexterm
> Чтобы удалить маркеры комментариев, выберите пункт меню <menuchoice
><guimenu
>Правка</guimenu
><guimenuitem
>Раскомментировать</guimenuitem
> </menuchoice
> или нажмите соответствующее сочетание клавиш ( по умолчанию <keycombo action="simul"
>&Ctrl;&Shift;<keycap
>#</keycap
></keycombo
>).</para>

</sect1>

<sect1 id="edit-command">

<title
>Команда правки</title>

<para
>Этот инструмент доступен из меню <menuchoice
><guimenu
>Сервис</guimenu
><guimenuitem
>Команда правки...</guimenuitem
></menuchoice
>. Он позволяет использовать небольшой набор <application
>vi</application
>/<application
>vim</application
>-подобных команд при редактировании текста. Это продвинутая возможность для продвинутых и опытных пользователей, но пусть это не пугает вас -- научитесь использовать этот мощный инструмент!</para>

<para
>На текущий момент доступны следующие команды:</para>

<variablelist>
<varlistentry>
<term
><command
>time</command
></term>

<listitem>
<para
>Эта команда позволяет вставить текущее системное время в формате <quote
>HH:MM:SS</quote
>.</para>

<para
>Чтобы использовать ее, откройте диалоговое окно "Команда правки" и наберите слово <userinput
>time</userinput
> в строке ввода.</para>
</listitem>
</varlistentry>

<varlistentry>
<term
><command
>char</command
></term>
<listitem>
<para
>Эта команда позволяет вставить символ по его числовому идентификатору в десятичной, восьмеричной или шестнадцатеричной системах счисления. Чтобы использовать ее, откройте диалоговое окно "Команда правки" и наберите <userinput
>char: [number]</userinput
> в строке ввода, после чего нажмите кнопку <guibutton
>OK</guibutton
>.</para
> 

<example>
<title
>Примеры использования команды <command
>char</command
></title>

<para
>Введите: <userinput
>char:234</userinput
></para>
<para
>Получите: <computeroutput
>ê</computeroutput
></para>
<para
>Введите: <userinput
>char:0x1234</userinput
></para>
<para
>Получите: <computeroutput
>ê</computeroutput
></para>
<para
>Введите: <userinput
>char:1232</userinput
></para>
<para
>Получите: <computeroutput
>ê</computeroutput
></para>
</example>

</listitem>

</varlistentry>

<varlistentry>

<term>
<indexterm
><primary
>замена в стиле sed</primary>
<secondary
>поиск в стиле sed</secondary
></indexterm>
<command
>s///[ig]</command
> <command
>%s///[ig]</command
></term>

<listitem>
<para
>"Типичный пользователь" при виде этих команд обязательно вздрогнет и начнет искать на клавиатуре кнопку "Windows". В самом деле, кому придет в голову искать текст подобным образом? Но вы же не "типичный"? Поэтому попробуем разобраться в этих двух sed-подобных командах. Первая выполняет поиск/замену в текущей строке, вторая -- во всем файле (<command
>%s///</command
>).</para>

<para
>Вкратце, команды производят поиск текста, заданного <emphasis
>маской поиска</emphasis
> -- регулярным выражением (т.н. regexp) между первым и вторым слешами, и при нахождении выполняет замену выражением, которое задано между вторым и третьим слешами. Круглые скобки в маске поиска позволяют задать <emphasis
>обратные ссылки </emphasis
>. Обратная ссылка -- это регулярное выражение, которое при совпадении заменяется на фактический текст и может быть использовано в маске замены. Чтобы использовать обратную ссылку в маске замены, в нужном месте поставьте бэк-слеш, а за ним номер обратной ссылки по порядку (<userinput
>\1</userinput
> -- для первой пары скобок, <userinput
>\2</userinput
> -- для второй, и т. д.).</para>

<para
>Чтобы найти сами символы-скобки <literal
>(</literal
> или <literal
>)</literal
>, нужно предварить их бэк-слешем: <userinput
>\(\)</userinput
>.</para>

<para
>По умолчанию поиск регистро-независимый. Чтобы он был регистро-зависимым, нужно в конце команды (после последнего слеша) добавить символ <userinput
>i</userinput
>.</para>

<example>

<title
>Замена текста в текущей строке</title>

<para
>Написав гигантский исходник, вы решили его откомпилировать. Но компилятор начал на вас ругаться: класс <classname
>myClass</classname
>, упомянутый в строке 3902, не определен.</para>

<para
>&quot;Черт!&quot;, - думаете вы, -- &quot;да это же мой класс <classname
>MyClass</classname
>&quot;. Вы добираетесь до строки 3902 и, вместо того, чтобы пытаться искать слово в этой длинной строке (а кто сейчас укладывает каждую строчку кода в 60 символов?), вы запускаете диалоговое окно "Команда правки", вводите <userinput
>s/myclass/MyClass/i</userinput
>, жмете <guibutton
>OK</guibutton
>, сохраняете и компилируйте -- успешно и без ошибок.</para>

</example>

<example>
<title
>Замена текста во всем файле</title>

<para
>Представьте себе, что у вас есть файл, в котором вы несколько раз упоминаете некоего человека по имени <quote
>госпожа Иванова</quote
>. Но вдруг вам сообщают, что эта самая госпожа Иванова вчера вышла замуж за господина с редкой фамилией <quote
>Петров</quote
>. Естественно, вам нужно заменить все упоминания о госпоже Ивановой на текст <quote
>госпожа Петрова</quote
>.</para>

<para
>Откройте диалоговое окно "Команда правки" и наберите в строку ввода следующий текст: <userinput
>%s/госпожа Иванова/госпожа Петрова/</userinput
> -- и ваша работа сделана.</para>

</example>

<example>
<title
>Более сложный пример</title>

<para
>Этот пример показывает, как пользоваться <emphasis
>обратными ссылками</emphasis
> и <emphasis
>классами слов</emphasis
> (кто не знает, что это такое, советую ознакомиться с приведенными ниже разделами).</para>

<para
>Допустим, у вас набрана такая строка: <programlisting
>void MyClass::DoStringOps( String      &amp;foo, String &amp;bar String *p, int  &amp;a, int &amp;b )</programlisting>
</para>
<para
>Теперь вы думаете, что это недостаточно "красивый" код, и решаете, что вам нужно использовать спецификатор <constant
>const</constant
> с параметрами, заданными ссылкой (теми, перед которыми стоит амперсанд). Вы также хотите свернуть все пробелы, чтобы между каждым словом был всего один пробел.</para>

<para
>Запустите диалоговое окно "Команда правки" и наберите: <userinput
>s/\s+(\w+)\s+(&amp;)/ const \1 \2/g</userinput
>, и не забудьте нажать кнопку <guibutton
>OK</guibutton
> -- иначе ничего не выйдет. Символ <userinput
>g</userinput
> в конце команды указывает компилятору "пересчитывать" регулярное выражение обратной ссылки каждый раз, когда встречаются совпадения.</para>

<para
>Вывод: <computeroutput
>void MyClass::DoStringOps( const String &amp;foo, const String &amp;bar String *p, const int &amp;a, const int &amp;b )</computeroutput
></para>

<para
>Миссия завершена! Ну, и что же произошло? Мы искали некоторое количество пробелов (<literal
>\s+</literal
>), за которыми идут несколько алфавитных символов (<literal
>\w+</literal
>), следом за ними опять несколько пробелов (<literal
>\s+</literal
>), после которых стоит амперсанд, и по ходу дела сохраняли эти алфавитные символы и амперсанд для использования их в операции замены. После этого мы заменили совпадающие части строки следующей последовательностью: один пробел, за которым идет спецификатор <quote
>const</quote
>, за ним еще один пробел, после которого наши сохраненные символы (<literal
>\1</literal
>), еще один пробел и сохраненный амперсанд (<literal
>\2</literal
>).</para>

<para
>В одном случае алфавитные символы составили слово <quote
>String</quote
>, в другом -- слово <quote
>int</quote
>, т.е. символьный класс <literal
>\w</literal
> с последующим знаком <literal
>+</literal
> определяет символьный набор произвольной длины.</para>

</example>

</listitem>
</varlistentry>

</variablelist>

<warning>
<para
>Это очень мощный инструмент, и, хотя его действие может быть отменено вызовом команды <menuchoice
><guimenuitem
>Отменить действие</guimenuitem
></menuchoice
>, я все же советую немного попрактиковаться, прежде чем использовать команду "всерьез" (если, конечно, вы не знакомы с регулярными выражениями <application
>sed</application
> или Perl).</para>
</warning>

</sect1>

</chapter>
