Пролог

Как я уже говорил, идеального текстового редактора мне до сих пор не встретилось. Однако максимально приближенный к идеалу - да. Это Nedit, текстовый процессор для X Window. В числе его разработчиков - большой коллектив: Марк Эдел (Mark Edel), Джо Кирьякопулос (Joy Kyriakopulos), Кристофер Конрад (Christopher Conrad) и другие. Распространяется он свободно и бесплатно на условиях GPL.

Редактор Nedit реализован для всех Unix- и Unix-подобных систем, как коммерческих, так и свободных. Он доступен на http://www.nedit.org в виде исходных текстов и бинарных пакетов. Впрочем, пробиться на этот сайт, по крайней мере из России, нелегко. А потому лучше поискать NEdit в каких-нибудь коллекциях Linux-программ, например, на http://linux.tucows.com. Кроме того, его часто стандартно включают в состав дистрибутивов Linux (например, Caldera OpenLinux, Linux Mandrake).

Nedit базируется на библиотеке Motif, имеющей статус коммерческой. Однако для Linux он может быть скомпилирован с использованием свободного аналога этой библиотеки - OpenMotif. Кроме того, распространяемые в составе дистрибутивов бинарные пакеты (rpm и deb) компилируются статически, то есть без необходимости установки каких-либо специфических библиотек вообще.

По назначению Nedit - текстовый редактор для программистов. Однако реализация его такова, что, кроме этого, он может быть использован для множества целей - от элементарного набора текстов до разработки web-страниц и верстки оригинал-макетов в TeX.

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

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

В третьих, для NEdit характерна практически неограниченная настраиваемость, осуществляемая путем подключения скриптов оболочки командной строки и макрокоманд, создаваемых на встроенном языке макросов.

Все эти особенности я и попытаюсь продемонстрировать ниже в этой саге.

Внешний вид и основные возможности

Как и большинство приложений, основанных на библиотеке Motif, Nedit управляется исключительно через меню: инструментальная панель отсутствует, что кому-то может показаться и недостатком. Мне - так нет, это компенсируется достаточным количеством комбинаций горячих клавиш и, главное, возможностью создавать собственные макрокоманды.

И так, основными элементами интерфейса редактора NEdit являются строка заголовка, главное меню, строка состояния (Statistic Line, по умолчанию отключена) и собственно рабочее поле.

В строке заголовка, помимо управляющих элементов окна (определяющихся используемым оконным менеджером), указывается имя текущего файла, а также фиксируется, подвергался ли он изменениям со времени последней записи; в этом случае после имени появляется метка (modofied).

Основные возможности редактора Nedit становятся ясными, если рассмотреть его главное меню. Оно насчитывает, за исключением непременного Help, семь пунктов, для быстрого вызова которых предусмотрена комбинация клавиш Ctrl+подчеркнутая_литера:

  1. File (Ctrl+F);
  2. Edit (Ctrl+E);
  3. Search (Ctrl+S);
  4. Preferences (Ctrl+P);
  5. Shell (Ctrl+L);
  6. Macro (Ctrl+C);
  7. Windows (Ctrl+W).

Большинство действий, соответствующих подпунктам главного меню, также могут быть выполнены с помощью клавишных комбинаций (обычно Ctrl, реже Alt в сочетании с литерой и, иногда, клавишей Shift); что приятно, комбинации эти работают не только при латинской, но и при кириллической раскладке клавиатуры.

Рассмотрим содержание главного меню подробнее. Начиная с пункта первого -

File

Он включает в себя в основном обычные файловые операции, как то:

Переходим у пункту второму -

Edit

Содержание пункта Edit также достаточно тривиально, это:

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

Однако и в NEdit с помощью мыши можно многократно вставлять выделенный фрагмент, так после первой вставки щелчком средней кнопки выделение не снимается, и процедуру можно повторять (или - удалить выделенный фрагмент, нажав клавишу Del, не меняя положения курсора) до фиксации курсора в новой позиции; таковая происходит после нажатия любой из клавиш управления курсором, но не при перемещении по телу документа с помощью линейки скроллинга.

Вообще говоря, в терминологии NEdit различается два типа выделения: первичное (primary, highlighted text) и вторичное (secondary, underlined text), десйствия над которыми различны.

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

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

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

Если описанную операцию выполнить при нажатой клавише Shift, произойдет перемещение выделенного фрагмента. То есть - точно так же, как и при перетаскивании мышью в Windows (drag'n'drop). Прием, насколько мне известно, не имеющий аналогов в других Linux-приложениях, многие из которых не поддерживают drag'n'drop как таковой.

Следующий пункт -

Search

вполне заслуживает отдельного положения в главном мен, поскольку возможности поиска и замены в NEdit чрезвычайно широки. Здесь и поиск введенной последовательности символов ([Shift]Ctrl+F), и повторный поиск ([Shift]Ctrl+G), и поиск фрагмента, идентичного выделенному ([Shift]Ctrl+H). Возможен поиск как буквенных последовательностей (Literal), в том числе и с чувствительностью к регистру (Case Sensitive Literal), так и регулярных выражений (Regular Expression), поиск вперед и назад (Search Forward и Search Backward, соответственно). При этом поддерживается история искомых выражений: клавиша управления курсором Up вызывает появление предыдущей последовательности, клавиша Down - последующего.

Следует отметить, что строка для ввода искомой последовательности может быть выведена не только в диалоговой панели по вызову соотвествтующего пункта меню, но и включена в верхней части окна программы, между строкой меню и строкой состояния (с помощью команды Find Incremental, [Shift]Ctrl+I). В обоих случаях кириллица в строке поиска не отображается, заменяясь знакомой пользователям Windows псевдо-грекофранцузской абракадаброй; тем не менее, самому по себе поиску это отнюдь не мешает - кириллические символы в теле документа находятся исправно.

Разумется, возможна и замена найденных фрагментов (Replace, [Shift]Ctrl+R), и повторная замена (Replace Again, [Shift]Ctrl+T). Опции замены - те же, что и для поиска: с чувствительностью к регистру, с использованием регулярных выражений, вперед и назад, и так далее.

В пункте же Search - переход к строке по ее номеру (Goto Line Number, Ctrl+L) и к выделенному фрагменту (Goto Selected, Ctrl+E), установка закладок (Mark, Alt+M), в качестве которых могут использоваться буквы латинского алфавита (от A до Z), и переход к ранее установленным закладкам (Goto Mark,[Shift]Alt+G) и еще пара пунктов, содержания которых я не очень понял. Это, во-первых, Goto Matching (...) ([Shift]Ctrl+M), не вызывающий никаких действий, и, во-вторых, Find Definition (Ctrl+D), не активизированный вообще.

Переходим к пункту

Preferences

Содержание его вполне понятно, что это настройки, среди которых:

Уже из этого краткого перечня можно представить себе возможности настройки редактора NEdit, о чем я подробнее буду говорить в следующем разделе. Пока же отмечу только, что все эти настройки имеют силу только в текущем сеансе. Чтобы сделать их перманентными, требуется внести соотвесттвующие изменения в пунктах Default Setting (о чем - ниже), и сохранить их (Save Default). Пункт пятый меню - не национальность, и даже не "На что жалуетесь"; напротив, это -

Shell

Shell - достаточно необычный пункт меню текстового редактора. Через него можно, во-первых, запустить на исполнение любую команду или программу. Это делается с помощью подпункта Execute Command (Alt+X), который вызывает нечто вроде минитерминала. В нем может быть введена соответствующая команда оболочки (или любая другая) с любыми требующимися параметрами. Поддерживается, посредством клавиш управления курсором Up и Down, историю команд, правда, только в текущем сеансе.

Во-вторых, через подпункт Execute Command Line (KP Enter, что это за комбинация - я так и не понял) можно определить в качестве команды на запуск строку из текущего документа. Для этого достаточно установить курсор в любое ее место и выбрать соответствующий пункт меню (или набрать вышеприведенную неудобопонятную клавишную комбинацию, вероятно). Разумеется, если строка эта имеет смысл и записана синтаксически правильно. В противном случае в теле документа атоматически появится сообщение об ошибке. Например:

netscape
An error occurred running /usr/lib/netscape/netscape-communicator.
Или даже полная справка по использованию команды, как в случае
ispell Usage: ispell [-dfile | -pfile | -wchars | -Wn | -t | -n | -x | -b | -S | -B | -C | -P | -m | -Lcontext | -M | -N | -Ttype | -V] file .....

и так далее. Разумеется, эта опция наиболее полезна для программистов. Однако и простым смертным она будет весьма нелишней при отладке скриптов командной оболочки. Необходимость в чем может возникнуть при желании нарастить функциональные возможности NEdit.

Дело в том, что скрипты эти могут быть встроены в меню Shell. Некий их набор включен в последнее по умолчанию. Это провекра правописания (spell), статистика (wc, от word count - подсчет строк, слов и знаков), сортировка строк и их нумерация, а также сугубо программистские сценарии - make для сборки программы из набранного исходного текста, expand и unexpand, смысл которых я не очень понимаю. Однако ничто не мешает пополнять меню Shell своими скриптами любого назначения, освободив его от ненужных лично вам элементов. Как - расскажу в одном из следующих разделов.

Кроме Shell, для наращивания функциональности программы служит и пункт

Macro

Этот пункт разделяется на две секции. Первая, стабильная, предназначена для создания и запуска пользовательских макрокоманд. В ней можно видеть:

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

В комплекте с той версией NEdit, которая имеется в моем распоряжении, идут макросы для:

Кроме того, имеется серия языково-зависимых макросов, предназначенных для программирования на C++. Они появляются в меню только при включении соответствующего языкового режима. Однако, как и в случае с Shell, не видно причин, по которым нельзя было бы исключить из меню заведомо не нужные макросы, заменив их собственными. Именно это и будет темой заключительных разделов саги.

А пока посмотрим, что же такое понимается в NEdit под пунктом

Windows

Понимается под этим, как нетрудно догадаться, управление окнами, правда, довольно ограниченное. Во-первых, можно раделить окно с текущим документом на две независимо скроллируемые части (Split Window, Ctrl+2). Только по горизонтали, но зато сколько угодно раз: исходное окно делится ровно пополам, затем каждая полонина - еще пополам, и так далее, насколько хватит разрешения экрана.

Для снятия разделения предназначен пункт Close Pane (Ctrl+1). При этом закрывается та часть окна, в которой находится курсор.

Наконец, в пункте Windows солдержится список открытых в текущем сеансе документов. Каждый из них открывается или создается (через пункты меню File - Open или File - New, соответственно) в своем окне с полным набором его атрибутов (управляющими элементами, меню, строкой состояния и так далее). Однако все они принадлежат текущему сеансу, и, скажем, изменение настроек сказывается на них всех. А переключение между окнами, кроме принятого в данном оконном менеджере, можно осуществить и через их список в пункте меню Windows.

В заключение раздела - несколько слов о

Help

Встроенная помощь редактора NEdit весьма богата, что можно видеть из простого перечисления содержания этого пункта меню. Он содержит:

Кроме перечисленного, в пункте Help содержатся подробные сведения о текущей версии редактора, политике его распространения, приведены списки рассылки и небольшой перечень проблем и ошибок.

Пора, однако, заканчивать с рассмотрением главного меню. Поскольку в NEdit существует еще и меню контекстное (в терминологии NEdit - Window Background Menu), вызываемое, как положено, щелчком правой клавишей мыши на выделенном фрагменте текста. Правда, оно достаточно простое, содержат лишь пункты Undo и Redo, Cut, Copy и Paste, что в комментариях не нуждается. Однако, как будет показано ниже, и оно может быть настроено.

Таким образом, из рассмотрения меню функциональность Nedit в первом приближении становится ясна. Он обладает очень развитыми средствами ввода и редактирования текстов как общего содержания, так и исходных текстов на языках программирования и разметки. Меню его организовано логичным и привычным для пользователя Windows способом, комбинации горячих клавиш многочисленны и обычно имеют простой мнемонический смысл. Все это, вместе с мощной системой помощи, делает NEdit простым в освоении.

К недостаткам Nedit (или, вернее, особенностям, которые могут не нравится), можно отнести отсутствие инструментальной панели с кнопками и открытие каждого файла в собственном окне (а не в том же самом, с перемещением через систему закладок, например). Впрочем, и тот, и другой момент - спорны: отстутствие кнопочной панели, как я уже говорил, компенсируется системой горячих клавиш, а перемещение между отдельными окнами, хотя и приводит к загромождению дисплея, не менее удобно, чем между закладками. Едиственно, не помешала бы возможность аранжировки открытых окон, но этого можно обычно добиться средствами большинства оконных менеджеров.

Еще в Nedit нет штатных средств управления проектом. Хотя бы в элементарном исполнении, то есть в виде открытия и сохранения группы связанных файлов (глав книги, например, или серии web-страниц). Тем не менее, все это не перечеркивает высоких достоинств редактора.

Однако мало было бы проку от богатства возможностей редактирования, если бы они не сопровождались адекватным богатством настроек. Что же, посомтрим, каковы они, возможности настройки.

Настраиваем NEdit

Я уже говорил, большая часть настроек редактора NEdit сконцентрирована в пункте Preference главного меню. И даже кратко перечислил возможности натсройки текущей сесии. Однако нас больше интересует не сиюминутный результат настройки, но ее долгострочная перспектива. Для чего следует рассмотреть подпункт Preference - Default Settings. Содержание его близко подпунктам меню Preference и включает установки:

Большинство из этих пунктов заслуживают того, чтобы задержать на них внимание. Чем мы и займемся, хотя и не в иной несколько последовательности. Но начнем по порядку, с языкового режима -

Language Modes

Как уже говорилось, под этим подразумевается язык не человеческий, а программистский. И список поддерживаемых режимов включает, не считая чисто текстового (Plain), почти все известные мне (и многие неизвестные) языки программирования и разметки. Здесь и C и C++, Java и JavaScript, Ada, Fortran, Pascal, Python, Tcl, awk, языки командных оболочек линии bash и линии csh, языки разметки SGML/HTML и LaTeX, PostScript, SQL и прочая, и прочая, и прочая. Разумеется, есть и режим собственного языка NEdit Macro.

Первое видимое следствие переключения языкового режима - появление подсветки синтаксиса соответствующего языка (если, конечно, эта опция включена, о чем - ниже). Так, по умолчанию в NEdit задействован режим Plain text. В этом случае. скажем, тэги в html-документе, подобном данному, показываются теми же черными (для примера) буквами), что и его содержание. Если же переключиться в режим SGML/HTML, тэги, их аргументы и значения последних заиграют различными цветами. Впрочем, при открытии файла определение его типа обычно происходит автоматически, по расширению (и обычно - правильно), и соответствующий языковый режим включается сам собой.

Однако различие между языковыми режимами не исчерпывается цветовой гаммой. Многие макросы (о которых - в следующем разделе) имеют языковую привязку. И появляются в меню Macro только тогда, когда включается соотвествующий их языку режим.

Разумеется, подсветка синтаксиса необходима в первую очередь программистам. Хотя и всем прочим, хоть иногда просматривающим исходники web-страниц, тоже не вредит. А вот следующая группа настроек

Auto Indent, Wrap и Tabs

предназначена и для простых смертных, так как определяет правила набора текста. Так, Auto Indent - это просто включение или выключение (Off/On) возможности создания автоматических абзацных оступов. Поясню на примере: если вам нужно набрать серию абзацев с общим отступом 7 пунктов от левого края, вы задаете (например, клавишей табулятора) отступ только первого абзаца - во всех остальных при включении (On) опции Auto Indent будет появляться автоматически, до его уничтожения вручную.

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

А вот величина отступа, задаваемого клавишей табуляции, и определяется в пункте Tabs. Здесь нужно просто задать (в знаках) величину отступа при табуляции. Правда с оговоркой - for hardware space, поскольку тут же присутствует и опция - emulate tabs, то есть предполагается, видимо, некая софтверная табуляция; что это такое, к своему стыду, не знаю.

Опция Wrap важна, так как она отражается на ряде других параметров набора текста. Для нее возможны варианты:

Я столь подробно остановился на параметрах переноса слов, потому что они представляются мне одними из наиболее существенных при наборе текста. Особенно если в дальнейшем предполагается экпорт его в текстовый процессор или какую-либо программу верстки. К тому же именно установками пункта Warp определяется реакция на команду меню Edit - Fill Paragraph (Ctrl+J): при установке в позиции Continuous текст в NEdit, независимо от того, в каком режиме переноса слов был набран, будет сконденсирован в единые абзацы, разделами между которыми будут только явные нажатия клавиши Enter.

Не уверен, что выразился вполне внятно, поэтому поясню на примере: некий текст был набран в режиме Auto Newline, после чего выяснилось, что его следует экспортировать в MS Word (или StarOffice для Linux, он в этом отношении ничуть не лучше); чтобы избавить себя в дальнейшем от ручного искоренения символов возврата каретки или головной боли по измышлению автоматизации этого процесса, достаточно просто пройтись по всем абзацам текста, нажимая Ctrl+J - и при включенной опции Continuous мы получим его аккуратно поделенным именно тем образом, что и требуется.

Однако о словах, пожалуй, хватит, пора взяться за их составляющие - буквы, настройка которых осуществляется через

Text Fonts

Этому вопросу я всегда придавал первостепенное значение. Во-первых, из соображений эстетических (грешным делом, люблю красивые шрифты), во-вторых, по причине плохого зрения. Так вот, с точки зрения выбора экранных шрифтов NEdit заслуживает аплодисментов.

При вызове пункта Text Fonts возникает панель с предложением определить основную гарнитуру (по умолчанию - нормального, то есть не курсивного и не полужирного, начертания) и отдельно - гарнитуры для каждого из начертаний (опять же, курсивного, полужирного, и полужирного курсивного). Впрочем, можно нажать экранную клавишу Fill Highlight Fonts from Primary - и тогда все прочие, кроме нормального, начертания унаследуют его гарнитуру.

В строке Primary Font (как, впрочем, и в любой другой) определить гарнитуру (и прочие параметры) экранного шрифта можно вводом вручную, с указанием всех требуемых атрибутов. Однако проще нажать экранную клавишу Browse и выбрать из списка всех доступных системе шрифтов. Каковой осуществляется в панели о трех колонках; в них необходимо явным образом отметить все три доступные для выбора атрибута - Font (то есть гарнитуру), Style (начертание, но нашему) и Size (сиречь кегль), иначе последует сообщение о некорректном определении шрифта.

Что характерно (вернее, не характерно для большинства текстовых редакторов, оперирующих обычно только моноширинными гарнитурами): хотя по умолчанию в списке присутствуют моноширинные шрифты, можно включить также показ шрифтов пропорциональных, и использовать их в свое удовольствие.

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

Customize Menus

Этот подпункт дает возможность настроить три элемента - пункты Shell и Macro главного меню, а также контекстное, или, в терминологии NEdit, фоновое, меню (Window Background Menu), вызываемое правой кнопкой мыши.

При настройке пункта Shell вызывается панель со списком имеющихся команд, которые с помощью соответствующих экранных клавиш могут быть удалены (клавиша Delete), скопированы (клавиша Copy) или перемещены вверх или вниз по списку (клавиши Move^ и Move , соответственно).

В расположенном ниже поле командной строки (Shell Command to Execute) содержится собственно код скрипта командной оболочки. Здесь можно непосредственно руками отредактировать соответствующую команду.

Например, в комплекте NEdit предусмотрен скрипт для проверки орфографии (пункт spell). Каковой, вызывая стандартную программу ispell в окне терминала, имеет вид

cat>spellTmp; xterm -e ispell -x spellTmp; cat spellTmp; rm spellTmp

и, естественно, понимает только английский язык. Однако обучить его русскому языку (или любому другому, при наличии соответствующего словаря) - трудов не составит. Для этого достаточно указать в командной строке параметр -d russian (предпысывающий обращаться при спеллинге именно к русскому, а не какому другому словарю) - и все в порядке.

Заодно, при желании, можно указать и параметры окна терминала (цвет текста и фона, геометрию и так далее). Или - просто заменить вызов xterm на ту терминальную программу, которая вам больше нравится. В реультате чего скрипт проверки орфографии примет селдующий вид (как у меня)

cat>spellTmp; konsole -e ispell -d\
russian -x spellTmp; cat spellTmp; rm spellTmp

Кроме того, в строке Menu Entry можно изменить название скрипта (именно содержимое этой строки и выступает в качестве пункта меню) или организовать иерархическое меню (с помощью знака >), а также привязать скрипт к какому-либо языку (для чего имя его маркируется знаком @ с указанием на последний, например @C++); в последнем случае скрипт будет фигурировать в меню только в том случае, если выбрать соответствующий языковый режим.

Кроме того, в поле Accelerator за скриптом можно закрепить некую комбинацию горячих клавиш. А поле Mnemonic предназначено для ввода литеры, которая будет в меню выделена и послужит для быстрого доступа к команде (с помощью комбинации Alt+литера, что, впрочем, срабатывает далеко не всегда). Можно изменить и ряд условий исполнения команды, о чем будет разговор в соответствующем разделе.

И так можно поступить (при необходимости) с любым из имеющихся в наборе скриптов. Не следует только забывать, завершив редактирование одного, нажимать клавишу Apply перед переходом к следующему - иначе изменения будут утеряны.

Рзумеется, в меню Shell можно включить и скрипты собственного изготовления, для чего в списке имеется пункт New. Однако это будет нашим занятием в одном из следующих разделов.

Сходным образом настраивается и меню Macro. На предназначенной для этого панели также имеется список макрокоманд с кнопками для их удаления, копирования и перемещения вверх и вниз, поле имени (Menu Entry) с возможностью создания многоуровневых иерархических меню (посредством того же знака >), привязкой к языковому режиму и закрепленной клавишной комбинации, а также обширное поле, предназначенное для кода макроса. Доступное для непосредственного редактирования.

Выбрав из списка макросов пункт New, можно нарастить меню собственными командами на языке NEdit Macro. Во-первых, наприсав в поле Macro Command Execute соответствующий код вручную, во-вторых, посредством клавиши Paste Learn/Replay Macro поместив туда запротоколированную (с помощью пунктов меню Macro - Learn Keystrokes или клавишной комбинации Alt+K) последовательность действий. Впрочем, создание макросов будет подробно рассмотрено в следующем разделе.

Абсолютно аналогичным образом можно настроить и конеткстное (или фоновое) меню, вызываемое щелчком правой кнопки мыши на выделенном фрагменте. Как уже говорилось, по умолчанию оно включает привычные для Windows-мигранта пункты Undo, Redo, Cut, Copy и Paste, которые с помощью экранных клавиш Delete, Copy, Move^ и Move можно удалить, скопировать и переместить.

А избрав в списке пункт New, можно пополнить контекстное меню собственными командами, написанными на языке NEdit Macro вручную или посредством протоколирования действий.

Покончив с настройками меню, можно заняться определениями параметров поиска, для чего предназначен пункт

Searching

Я уже говорил, что возможности поиска в редакторе NEdit весьма обширны. А настриваемость придает им еще и гибкость. В пункте Searching присутствует два переключателя:

Третий пункт настройки поиска - режим по умолчанию: Literal (то есть когда искомое значение рассматривается как буквенная последоватлеьность), Case Sensitive (то же, но с чувствительностью к регистру) и Regular Expression (то есть поиск регулярных выражений, представление о синтаксисе которых можно получить из соответствующего пункта меню Help).

Следующая группа настроек -

Syntax Highlighting, Statistics Line, Incremental Search Line и Show Line Numbers

Это - просто переключатели, с помощью которых можно показать или скрыть:

Правда, для пункта Syntax Highlighting настройке поддается также Recognition Patterns и Text Drawing Styles. Что такое первое - я пока не разобрался, а второе - это приписывание каждому элементу языковых конструкций цвета и шрифтоначертания. Для языка HTML, например, можно определить различные цвета тэгов, их атрибутов и значений последних, комментариев, метатэгов и так далее.

Так же легко понять смысл следующего настраиваемого элемента -

Make Backup Copy и Sort Open Prev. Menu

Это также простые переключатели. Первый разрешает или запрещает создание резервных копий редактируемого файла. Включение его приводит к тому, что при перезаписи измененного документа предыдущая его версия сохраняется в виде файла с расширением *.bck.

С помощью Sort Open Prev. Menu можно включить алфавитную сортировку ранее открывавшихся файлов, входящих в список File - Open Previous. При выключении этой опции файлы в нем следуют в хоронологическом порядке.

Осталось рассмотреть лишь немногие настройки Preferences, такие, как

Warning

Что представляет собой конфигурирование сообщений при закрытии файла или выходе из редактора. Здесь имеется всего два переключателя. Первый отвечает за выдачу предупреждения о несохраненности изменений в закрываемом файле, второй же - разрешает или запрещает сообщение о изменении установок по умолчанию при закрытии программы. На мой взгляд, оба - далеко не лишние, и не худо бы включить их по умолчанию.

Предпоследний пункт нашей программы -

Initial Window Size

Как нетрудно понять, здесь задается размер окна по умолчанию, возникающего при запуске NEdit. Предусмотрено пять вариантов такового:

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

Наконец, финал - настройки

Show Matching (...), Tag Collisions, Popups Under Pointer

Эти опции объединены в один пункт мной произвольно. И исключительно потому, что я пока не разобрался, что они значат. И, следовательно, не скажу о них ничего. Кроме того, что являют они собой (за исключением Tag Collisions) простые переключатели.

Конфигурирование .Xdefaults

Не смотря на некоторую сумбурность описания, из него, надеюсь, ясно, в через меню Preferences - Defaults Settings в NEdit можно настроить почти все. Едиственно, следует не забыть сохранить сделанные изменения, дабы сделать их перманентными (через Preferences - Save Defaults).

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

Отчаиваться не следует - на сей предмет существует метод левой резьбы. То есть - ручной правки конфигурационного файла /$HOME/.Xdefaults, поисывающего особенности X-приложений.

Секции для NEdit в нем нет. Однако создать ее (хотя бы собственными средствами этого редактора) труда не составит. Для этого достаточно вставить такие строки:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! nedit

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
где строки с восклицательными знаками, естественно, не обязательны, служа всего-навсего ограничителями секции, а строка ! nedit - комментарий, дабы не забыть, о чем, собственно, идет речь.

Теперь дело за малым - нужно создать наполнение секции. Это можно сделать по наитию (и методом проб и ошибок), как в первом варианте этой заметки. А можно обратиться к системе помощи - тому самому ее пункту, где говорится о конфирурировании NEdit и, в частности, о ресурсах X Window (Help - Customizing - X Resources.

Здесь можно найти список почти всех параметров, которые не подлежат изменению через меню Preferences, но которые в принципе можно (хотя и не все - нужно) изменить. Не могу похвастаться, что я разобрался со всеми. И потому приведу этот список полностью, оставив без перевода и комментариев строки, смысл которых пока остается для меня неясным (надеюсь со временем ликвидировать эти прорехи):

nedit.tagFile: (not defined)
Насколько я смог понять, нечто, имеющее отношение к программированию на C. Оригинальный комментарий таков: The name of a file of the type produced by Exuberant Ctags or the Unix ctags command, which NEdit will load at startup time (see Features for Programmers). The tag file provides a database from which NEdit can automatically open files containing the definition of a particular subroutine or data type.
nedit.shell: /bin/csh
Указание на оболочку командной строки, скрипты которой выполняются через меню Shell. Вероятно, хотя пока и не проверено, можно указать и bash, и что-нибудь еще.
nedit.wordDelimiters: .,/\\`'!@#%^&*()-=+{}[]":;<>?
Знаки, маркирующие (в дополнение к пробелам и табуляции) границы между словами при их выделении мышью (двойным щелчком на слове) или премещении курсора комбинацией клавиш Ctrl+Стрелки
nedit.remapDeleteKey: False Указание значения True переопределяет клавишу Delete как Backspace. Комментарий гласит, что это может быть полезно при работе с клавиатурами систем DEC (вероятно, имеется в виду что-то вроде PDP или VAX) и Macintosh. Для пользователей PC, по-моему, практического значения не имеет.
nedit.stdOpenDialog: False
Возвращение значения True устанавливает стандартный для приложений, основанных на Motif, стиль диалоговых панелей. За незнакомством с последним, смысл опции не вполне понимаю.
nedit.bgMenuButton: [Shift][Ctrl][Meta][Alt][Btn3Down]
Способ доступа к контекстному (или фоновому) меню. По умолчанию для этой цели служит, как и в Windows, правая (третья - отсюда Button 3) кнопка мыши. Однако можно использовать и любой из четырех других вариантов (правда, клавиша Meta, по-моему - это из области Mac?).
nedit.maxPrevOpenFiles: 30
Максимальное количество файлов в списке, вызываемом через меню File - Open Previous (то есть ранее открывавшихся или создававшихся). Насколько мне удалось понять, значение это сверху ограничено только размерами дисплея и его разрешением - при большом количестве список уходит за пределы видимости. Список открывавшихся ранее документов хранится в конфигурационном файле /$HOME/.neditdb.
nedit.printCommand: (system specific)
Этот параметр и серия следующих за ним определяют условия печати документов из редактора NEdit. По умолчанию все они используют системные установки. Насколько я понимаю, лучше их таковыми и оставить, если нет везких причин для иного решения. И понимания, как его реализовать (у меня такового понимания нет).
nedit.printCopiesOption: (system specific)
nedit.printQueueOption: (system specific)
nedit.printNameOption: (system specific)
nedit.printHostOption: (system specific)
nedit.printDefaultQueue: (system specific)
nedit.printDefaultHost: (system specific)
К этим пунктам относится сказанное в предыдущем комментарии.
nedit.multiClickTime: (system specific)
Время ожидания второго щелчка кнопкой мыши, в течении которого он счиается за двойной. Здесь логично сохранить системную установку - не зря же вы ее делали для всех приложений.
nedit*scrollBarPlacement: BOTTOM_LEFT
Эта строка описывает положение и вид полосы прокрутки. При значении в примере (как ни старнно, это не значение по умолчанию - уже при первом запуске NEdit полоса прокрутки располагается справа) она должна располагаться вдоль левой границы окна и прокручиваться вперед смещением ползунка сверху вниз. Другие возможные значения : BOTTOM_RIGHT, TOP_LEFT и TOP_RIGHT; в двух последних случаях прямой скроллинг осуществляется движением ползунка снизу вверх.
nedit*text.autoWrapPastedText: False
По умолчанию запрещает автоматический перенос слов при наборе текста. Лучше так и оставить - настроить различные опции переноса слов для каждого конкретного сдучая проще настроить через меню Preferences - Wrap (или Preferences - Default Settings - Wrap), как было описано выше.
nedit*text.heavyCursor: False
Смысл этой строки не очень понял. Когда я вставлял ее в первозданном виде, курсор у меня просто исчезал вообще. Оригинальный комментарий: For monitors with poor resolution or users who have difficulty seeing the cursor, makes the cursor in the text editing area of the window heavier and darker.
nedit*text.foreground: black
Переходим к самому интересному - нстройке цветовой гаммы. Это - цвет шрифта набираемого текста. Смысл значения, думаю, понятен, а от рекомендаций воздержусь - товарищей нет на цвет и шритфа.
nedit*text.background: white
В этой строке определяется цвет фона редактируемого поля.
nedit*text.selectForeground: black
А здесь определяется цвет текста выделенного первичным способом (левой кнопкой мыши или стрелками указателя курсора при нажатой клавише Shift) фрагмента.
nedit*text.selectBackground: gray80
Определение цвета фона выделенного первичным способом фрагмента. Следует заметить только, что число после наименования цвета обозанчает яркость (saturation) его в процентах. То есть gray80 - это светло-серый, а, скажем, gray20 - темно-серый. Во всех относящихся к цветовой гамме пунктах возможны также значения имени цвета с прилагателными - light или dark.
nedit*text.highlightForeground: white
Смысла этой строки (в отличие от следующей) не понял: изменение цвета в ней у меня не дает никакого видимого эффекта. Потому привожу оригинальный комментарий: Foreground (text) color for highlights (parenthesis flashing) in the text editing area of the NEdit window.
nedit*text.highlightBackground: red
Насколько установлено эмпирически, определяет цвет подсветки парных элементов (например, открывающей скобки при фиксации курсора на закрывающей). Оригинальный комментарий: Color for highlights (parenthesis flashing) in the text editing area of the NEdit window.
nedit*text.cursorForeground: black
Ну, понятно, просто цвет курсора.
nedit*text.lineNumForeground: gray47
Цвет, которым передается нумерация строк (если эта опция включена).
nedit*text.blinkRate: 600
А это частота мерцания курсора в миллисекундах. Если установить значение 0, курсор мерцать не будет.
nedit*text.Translations:
Не понял, оригинальный комментарий таков: Modifies key bindings (see below). Однако "below" я ничего по этому поводу не обнаружил, по карйней мере в этом разделе.
nedit*foreground: black
Задает цвет текста меню и диалоговых панелей.
nedit*background: gray70
А здесь определяем цвет фона меню, диалоговых панелей и полосы прокрутки.
nedit*fontList: helvetica-bold-14
В этой строке можно, наконец, определить гарнитуру, начертание и кегль шрифта интерфейсных элементов. За исключением шрифта в полях, скажем имен файлов при их открытии или сохранении, или в полях ввода кода и параметров в диалогах настройки меню, например (ни в том, ни в другом случае изменить шрифт мне не удалось). Не оказывает эта строка (также как и настройка через меню) и на шрифт вывода сообщений системы помощи, о чем скажу ниже.
nc.autoStart: False
Этот и следующий параметр, судя по всему, имеют отношение к применению NEdit в системах клиент/сервер. Смысла не понял, привожу оригинальный комментарий: Whether the nc program should automatically start an NEdit server (without prompting the user) if an appropriate server is not found.
nc.serverCommand: nedit -server
Оригинальный комментарий: Command used by the nc program to start an NEdit server. Далее следует фраза такого содержания, которую я понял как предложение использовать всякого рода расширения имен элементов, такие, как .background и т.д., для изменения цветов, шрифтов и прочих характеристик следующих далее элементов:
nedit*statsForm
Предлагает поределить вышеуказанные характеристики для статусной строки и строки поиска. При желании одна характеристика может распространяться на оба элемента, для этого вместо (.) следует использовать (*). Например, строка
nedit*statsForm*background: gray
задает для них единый серый цвет фона.
nedit*menuBar
В этой и нижеследующих строках можно по той же модели определить характеристики линии главного меню,
nedit*textHorScrollBar
... полосы горизонтальной...
nedit*textVertScrollBar
... и вертикальной прокрутки.
nedit*helpText
Эта строка, якобы, позволяет определить характеристики окна системы помощи. Однако у меня строка вида
nedit*helpText*fontList: -cronyx-fixed-medium-r-*-*-20-*-*-*-*-*-koi8-r
на шрифт сообщений Help'а никакого действия не оказала.

Тем не менее, эту проблему удалось победить методом ползучего эмпиризма, а именно, поместив собственноручно сконструированную строку

nedit*font: -cronyx-fixed-medium-r-*-*-20-*-*-*-*-*-koi8-r

Не возьмусь судить, насколько она синтаксически грамотна, но, по крайней мере, после этого шрифт сообщений в окне помощи действительно изменился.

Как можно видеть, в секцию !nedit файла /$HOME/.Xdefaults можно внести изрядное количество строк. Но можно - не значит нужно. Достаточно ограничиться только теми строками, определяющими характеристики, не устраивающие вас по умолчанию. Так, я ограничился настройкой шрифтов текста, меню и системы помощи, а также цветовой гаммы рабочаго поля и интерфесных элементов - и прекрасно себя чувствую. Настолько, что рискнул в приложении 2 привести в качестве примера фрагмент своего файла /$HOME/.Xdefaults. Каковой, изменив при желании, можно просто поместить в свою конфигурацию. За чистоту синтаксиса поручиться не могу, но за работоспособность - готов.

Таким образом, редактированием файла /$HOME/.Xdefaults удается настроить то немногое, что не получается настроить через главное меню. Однако в домашнем каталоге пользователя можно обнаружить еще два конфигурационных файла, имеющих отношение к NEdit -

Файлы .nedit и .neditdb

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

Содержание файла .nedit составляет описание тех самых параметров, которые настраиваются через главное меню Preferences - Default Settings. К коему и следует, как гласит комментарий, прибегать для его изменения. Тем не менее он доступен и для ручного редактирования, что, как и всякую свободу выбора, следует расценить только положительно.

Начальная (после комментариев) строка файла - указание на номер версии:

nedit.fileVersion: 5.1

Затем следуют секции описания настраиваемых меню Shell, Macro и контекстного:

nedit.shellCommands: \
    spell:Alt+B:s:EX:\n\
    ...
nedit.macroCommands: \
    Headers>header1:F1::: {\n\
    ...
nedit.bgMenuCommands: \
    Undo:::: {\n\
    ...

соответственно. Описывать их содержимое я не буду. Скажу только, что первая строка после заглавия секции содежит название скрипта или макроса (в том самом виде, как оно отображается в соответствующем меню (так, для приведенного макроса - двухуровневом, Headers>header1). Затем, разделяясь двоеточиями, следуют всякого рода дополнительные сведения, такие, как закрепленная клавишная комбинация или мнемоническое обозначение.

Следующие секции

nedit.highlightPatterns: C:Default\n\
    C++:Default\n\
    ...
nedit.languageModes:     C:.c .h::::::".,/\\`'!|@#%^&*()-=+{}[]"":;<>?~"\n\
    C++:.cc .hh .C .H .i .cxx
    ...
nedit.styles:     Plain:black:Plain\n\
    Comment:gray20:Italic\n\
    ...

определяет разнообразные параметры (подсветка, отступы и т.д.) для различных языковых режимов.

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

Ну а файл .neditdb - это просто список (задумичво называемый базой данных) ранее открывавшихся файлов с указанием полных абсолютных путей. Что характерно, в списке пункта меню File - Open Previous они даются без дублирования - все же буквы db в названии присутствуют не зря.

Наращиваем мускулы
Макросы и Shell

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

Вкратце о возможности создания собственных макросов (путем написания их кода руками) я уже упоминал. Однако есть и другой способ, который для начала может оказаться более простым - протоколирование действий. Для этого требуется всего-навсего:

Запротоколированная последовательность действий будет фуркционировать в течение данного сеанса работы с NEdit. И может быть вызвана первый раз через меню Macro - Reply Keystrokes и, в дальнейшем, через Macro - Repeat. Однако при следующем запуске NEdit будет утрачена.

Чтобы этого не случилось, следует сохнанить ее в меню для потомства. Для этого, успешно завершив протоклирование данного макроса, отправляемся в меню Preferences, выбираем там пункт Default Settings, а в нем - опцию Customize Menu. Каковая, в свою очередь обнаруживает, как уже говорилось, пункт Macro Menu, вызывающий панель Macro Commands.

В списке доступных команд (в левой части панели) фиксируемся на пункте New. В поле Menu Entry задаем название команды и, при необходимости, название более высокого уровня для группы сходных команд, например, таким образом:

Group commands>Command1

(без пробелов перед и после знака >). Здесь же можно приписать команду к какому-либо из доступных языковых режимов, например,

Group commands>Command1@SGML/HTML

будет указывать, что данная команда активизируется только при выборе языкового режима SGML/HTML.

Затем заполняем поле Accelerator. Здесь за нашей командой можно закремить какую-либо клавишу (из числа, например, функциональных, или Windows-клавиш) или их комбинацию: например, сочетание клавиш Alt или Ctrl, возможно, в сочетании с Shift, с какой-либо буквой, желательно, имеющей мнемонический смысл.

Для этого достаточно просто зафиксировать зафиксировать курсор в поле Accelerator и нажать требуемую клавишу (например, F12) или их комбинацию (скажем, Ctrl+литера). Следует только внимательно следить, чтобы эта клавишная комбинация не использовалась для вызолва штатных функций NEdit: в этом случае приоритет в любом случае будет за последними, а, возможно, клавишная комбинация не будет вызывать ни старого, ни нового закремленного действия.

Вслед за этим можно заполнить поле Mnemonic, введя в него какую-либо букву из имени нашей команды (как оно указано в поле Menu Entry). При вызове меню буква эта будет подчеркнута и, теоретически, может использоваться для быстрого вызова команды (сочетанием ее с клавишей Alt). Однако на деле это работает далеко не всегда. Вернее, почти всегда не работает, поскольку болшинство букв латинского алфавита уже задействованы для штатных команд NEdit.

Наконец, последнее из предварительных действие - это включение, по потребности, переключателя Requires Selection. Он предназначен для команд, которые осуществимы только с предварительно выделенными фрагментами (типа компирования, вырезания и т.д.).

А вот теперь нажимаем экранную клавишу Paste Learn/Replay Macro (правой части панели). И текст макроса волшебным образом появляется в поле Macro Command to Execute. Где может быть любым образом отредатирован, дополнен, сокращен и т.д. После чего жмем клавишу OK, выходя их режима редактирования Macro Menu - и с удовольствием и пользой применяем новую функцию на практике. Если все работает нормально - сохранаяем текущюю ситуацию через Preferences - Save Defaults для увековечивания внесенных нами изменений.

Каковые, как уже говорилось, фиксируются в секции

nedit.macroCommands:

файла .nedit из пользовательского каталога. Где также могут быть отредактированы непосредственно.

Таким образом можно насытить меню редактора NEdit командами для выполнения чсто требуемых, но отстутствующих в штатном комплекте действий. Например, как будет показано ниже, для ввода тэгов HTML. Однако и этого может показаться недостаточным для полного счастья. Нпример, возникнет потребность в систематическом исполнении каких-либо внешних программ. Например, команд оболочки.

Конечно, на сей предмет можно прибегнуть к стандартному окну термиала - во-первых, к строке минитерминала (вызываемой через меню Shell - Execute Command, или клавишной комбинацией (Alt+X) - во-вторых, и к непосредственному вводу команд в поле редактирования NEdit с последующим их запуском (через меню Shell - Execute Command Line) - в третьих. Однако все это - не предел комфорта.

К тому же подчас необходимо, чтобы команда оболочки выполнялась в отношении редактируемого в данный момент в NEdit документа. Примером чего служит приведенная в прошлом разделе команда ispell для проверки орфографии. И тут нам на помощь приходит возможность редактирования меню Shell (через Preferences - Default Settings - Customize Menu - Shell Menu).

Выбрав соотвествующие пункты приведенной последовательности, вызываем панель Shell Commands и выбираем из списка доступных команд пункт New. Подобно тому, как это проделывалось для макросов, заполняем поля Menu Entry, то есть имени команды (также, возможно, иерархически построенного и привязанного к языковому режиму), Acceleretor (для закремления комбинаций клавиш) и Mnemonic (для выделения литеры быстрого вызова).

Затем определяемся c входными элементами команды в строке переключателей Command Input. Здесь можно предписать команде исполняться для выделенного фрагмента (selection), текущего окна (window), каждого элемента документа (either) или ни для чего (none). Объяснить смысл каждого переключателя в общем виде я несколько затрудняюсь, но на практике смысл их в отношении каждой конкретной команды обычно достаточно прозрачен.

Аналогично - и с выходными элементами команды. Каковые могут быть показаны в текущем или новом окне, а также в виде диалоговой панели.

Следующая ниже группа переключателей при у3становке в положение On предписывает:

Определившись и с этим, можно непосредственно задавать команду вместе со всеми требуемыми параметрами и их значениями. Это делается в поле ввода команды (Shell Command to Execute), точно также, как в командной строке консоли или терминального окна.

Однако можно и набрать команду непосредственно в поле редактирования NEdit, после чего просто скопировать (с помощью мыши или клавишных комбинаций) ее в поле ввода команды. Преимущество последнего способа в том, что предварительно (с помощью меню Shell Execute Command Line) можно проверить работоспособность команды и, руководствуясь сообщениями об ошибках, ее отредактировать. Можно, разумеется, и просто скопировать успешно запускаемую команду и окна терминала...

Завершив создание новой команды, принимаем введенные изменений (через экранную кнопку Apply) или выходим из режима редактирования Shell через OK. А, выполнив проверку правильности созданной команды, сохраняем ситуацию (через Save Defaults) для использования в дальнейшем.

Пример применения
HTML-редактор своими руками

Не могу поручиться, что в преедыдущем разделе внятно изложил возможности NEdit по созданию и редактированию макрокоманд и команд оболочки. И потому попробую проиллюстрировать эти возможности на конкретном примере - создании серии связных директив для составлению не оченб сложных (и преимущественно текстовых) html-документов.

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

И так, перед нами (то есть вашим покорным слугой) стоит задача составления "из головы" достаточно длинных и относительно структурированных документов, предназначенных в первую голову для размещения в Сети. При этом не исключается возможность, что они в дальнейшем будут воплощены и на бумаге в виде журнальных или книжных публикаций (для чего может потребоваться импорт документа в текстовый процессор или программу верстки). Что нужно для комфортного выполнения этой работы?

Путей - несколько. Можно:

И потому оптимальным представляется составление документа в текстовом редакторе с одновременной разметкой html-тэгами. Но проставлять их вручную, даже если помнишь все наизусть, - занятие достаточно нудное. И посему возникает естественное желание его автоматизировать. Благо NEdit с его развитым макроязыком и простыми средствами его применения такую возможность обеспечивает.

Для начала определимся, какие тэги требуются для каждодневного использования. Это:

Вот в такой последовательности и будем создавать соответствующие макросы. Включаем режим протоколирования (через меню Macro - Learn Keystrokes или комбинацию Alt+K) и просто-напросто набираем с клавиатуры последовательность символов

<h1></h1>

Для обеспечения непрерывности набора логично вернуть курсор в позицию между открывающим и закрывающим тэгами, для чего соответствующее количество раз нажимаем клавишу Left. После чего завершаем протоколирование (через меню Macro - Finish Learn или повторным нажатием Alt+K), через меню Macro Replay Keystrokes (или - комбинацию Ctrl+K) проверяем правильность исполнения и переходим в меню Preferences - Default Settings - Customize Menu - Macro Menu.

В появившейся панели Macro Commands указываем в поле Menu Entry

Headers>header1

в поле Accelerator приписываем команде клавишу вызова (например, F1, благо она не закреплена за вызовом помощи), при желании определяем мнемоническую литеру (хотя большого смысла в этом я не вижу) и смело жмем на экранную кнопку Paste Learn/Reply Macro. В результате в поле Macro Command to Execute появляется код вроде следующего:

insert_string("<")
insert_string("h")
insert_string("1")
insert_string(">")
insert_string("<")
insert_string("/")
insert_string("h")
insert_string("1")
insert_string(">")
backward_character()
backward_character()
backward_character()
backward_character()
backward_character()

Поскольку проверку правильности макрокоманды мы уже произвели, нажимаем Apply для ее включения в список и переходим к следующему пункту нашей программы. Конечно, можно повторить протоколирование набора для тэгов заголовков всех уровней последовательно. Но проще - с помощью экранной клавиши Copy скопировать только что созднанный макрос, изменить в поле Menu Entry ее название с header1 на header2, закремить за ней клавишу F2 и в поле Paste Learn/Reply Macro отредактировать код вручную, заменив строки

insert_string("1")
на
insert_string("2")

И подобную процедуру повторить для заголовков всех потребных уровней (вряд ли число их превысит четыре).

Затем переходим к созданию макросов для наиболее часто требующихся при наборе тэгов параграфа и разрыва строки. Порядок действий - идентичный: протоколирование ввода тэга, вызов панели Macro Commands, описание имени команды (с учетом ее положения в иерархическом меню), закрепление свободной комбинации горячих клавиш, помещение "заученного" кода макроса в поле команд для исполнения, включение новой макрокоманды в список доступных. И так - для всех тэгов, которые представляются нам требуемыми при повседневном использовании...

Завершив создание макросов, следует не забыть увековечить их в меню с помощью Preferences - Save Defaults. Псоле чего они будут доступны в последующих сеансах NEdit, поскольку размещаются в секции nedit.macroCommands: файла .nedit.

В приложении 2 я привожу содержимое этой секции после того, как я разработал серию макросов для своих личных целей. Не судите строго: с точки зрения программиста-профессионала, ничего замечательного там не содержится. Но а) этот процесс занял у меня считанные минуты, и б) результатов его мне вполне хватает в 90 случаях из 100.

Что, опять-таки, подтверждает величие и силу редактора NEdit: можно представить себе, как способен настроить его для своих задач человек с достаточной программистской квалификацией...

Чего еще хотелось бы от несложного html-редактора? Ну конечно, визуализации производимых изменений в каком-либо внешнем браузере. Каковым, с большой долей вероятности, будет Netscape Navigator текущей версии.

Для этого мы прибегнем к настройке меню Shell (Preferences - Default Settings - Customize Menu - Shell Menu). В соотвествтующей панели определяем, как рассказывалось ранее, поле имени команды; если есть желание просматривать плоды своих трудов в разных браузерах, можно создать иерархическое меню вроде

Browser>netscape
Browser>lynx
Browser>opera

оставляя, скорее всего, пустыми поля Accelerator и Mnemonic (не столь это частая процедура, вызов внешнего браузера, чтобы тратить на нее драгоценную клавишную комбинацию, коих и так не в избытке).

А затем вводим в поле Shell Command to Execute строку

konsole -e netscape % 

или иную любимую терминальную программу в качестве первого элемента (xterm. rxvt, etc.). И ни в коем случае не забыв параметр %, предписывающией Netscape отображать именно редактируемый в NEdit файл.

Теперь разбираемся с переключателями. В линейке Command Input логично отметить значение None (иначе есть риск получить по закрытии Netscape пустой файл), в линейке Command Output - значение same window. Кроме того, не худо включить также опцию записи текущего файла перед выполнением команды (Save file before executing command).

Все, принимаем изменения (экранной клавишей Apply) и проверяем действие команды. Если все нормально, выбор из меню Shell пункта netscape должен вызвать появление сначала терминального окна, а затем - окна браузера Netscape Navigator, отображающего редактируемый файл в текущем его состоянии. Если да - сохраняем ситуацию (через меню Preferences - Save Defaults) и с гордым и независимым видом пользуемся собственноручно созданным html-редактором...

Эпилог

Подводя итоги, можно сказать, что по своим возможностям и настраиваемости NEdit вплотную приближается к emacs (а учитывая возможность сколь угодно широкого наращивания функциональности пунктов меню Shell и Macro - возможно, и не уступает). В то же время он предоставляет пользователю удобный и привычный интерфейс, лишенный архаических особенностей как emacs, так и vi.

Недостатки NEdit я уже отмечал: это отстутствие инструментальной панели и истинно многооконного интерфейса, а также средств управления проектом. Однако первые два замечания - спорны, а последняя функция в элементарном исполнении, то есть в виде открытия и сохранения группы связанных файлов (глав книги, например, или серии web-страниц), как мне представляется, можно реализовать с помощью встраиваемых в меню сценариев оболочки и макрокоманд. Тем более, что зачатки управления проектом, в виде возможности открытия файла при выделении его в редактируемом тексте, имеются.

Короче говоря, если NEdit и не отвечает в полной мере идеалу текстового редактора, то вплотную к нему приближается. На мой взгляд, это один из лучших редакторов вообще и, пожалуй, лучший на платформе Linux. Дополнительное достоинство его - отсутствие привязки к конкретной графической среде (типа KDE или GNOME) и представленность во всех Unix-системах.

В общем, этот редактор мне так понравился, что я без тени сомнения добавил его в список любимых программ, о которых, как и о любимых женщинах, буду помнить всю жизнь. Надо сказать, что за десять лет околокомпьютерного существования список этот (программ, как, впрочем, и женщин) отнюдь не велик. Ранее в нем были QuattroPro для DOS (не для Windows) от электронных таблиц, Lotus AmiPro - от текстовых процессоров, Surfer в обоих своих (DOS и Windows) ипостасях. Теперь в этом списке - и NEdit.

А написал я все это по двум причинам. Во-первых - к вящей, как уже говорил, славе редактора NEdit. Во-вторых, руководствуясь шкурным интересом: вдруг кто-нибудь, обладающий должной квалификацией, заинтересуется программой и напишет к ней достаточное кличество качественных наборов макросов на все случаи жизни. Конечно, такая коллекция присутствует на www.nedit.org, но достучаться от нее из России - нелегко, и потому о ее возможностях сказать что-либо затрудняюсь.

Приложение 1
Комбинации горячих клавиш и их краткое описание

Модифицирующие клавиши

Ctrl: в сочетании с другими клавишами расширяет сферу их применения. Например, нажатие клавишщи Home перемещает курсор в начало строки, тогда как в сочетании с нажатием клавиши Ctrl (то есть Ctrl+Home - в начало документа.

Shift: расширяет выделение относительно позиции курсора при нажатии клавиш управления последним (аналогично действию клавиши Shift в Windows).

Alt: используется, в частности, для выделения колонок и прямоугольных фрагментов. (For the effects of modifier keys on mouse button presses, see the section titled "Using the Mouse")

Прочие клавиши

Escape: прекращение текущей операции, аналогично выбору клавиши Cancel в диалоговых панелях.

Backspace: действует обычным образом, то есть удаляет символ перед позицией курсора.

Ctrl+Backspace: удаление слова перед позицией курсора.

Arrows:

Ctrl+Return: перевод каретки с автоматическим созданием абзацного отступа, как в предыдущей строке; действие аналогично включению опции Auto Indent.

Shift+Return: перевод каретки без автоматического создания абзацного отступа, если включена опция Auto Indent.

Ctrl+Tab: вставка ascii-символа табуляции.

Alt+Ctrl+c: вставка управляющего кода, эквивалентного клавише "с".

Ctrl+/: выделение всего документа; соответствует меню Edit - Select All или комбинации menu Ctrl+A.

Ctrl+\: "развыделение", если так можно выразиться, всего документа; то есть действие, обратное комбинации Ctrl+/.

Ctrl+U: удаление части строки от позиции курсора до ее начала.

Стандартные PC-клавиши

Ctrl+Insert: копирование выделенного (первичным методом) фрагмента в буфер; аналогично действию меню Edit - Copy или клавишной комбинации Ctrl+C; введено для совместимости со стандартом клавишных комбинаций приложений Motif.

Shift+Ctrl+: помещение выделенного (первичным методом) фрагмента в позицию курсора.

Delete: действует обычным образом, то есть удаляет символ после позиции курсора.

Ctrl+Delete: удаляет часть строки от позиции курсора до конца.

Shift+Delete: удаление выделенного фрагмента с помещением его в буфер (подобно команде Cut в большинстве Windows-приложений); аналогично действию через меню Edit - Cut или комбинации клавиш Ctrl+X).

Shift+Ctrl+Delete: удаление выделенного первичным методом фрагмента, то же, что просто Delete.

Home: перемещение курсора в начало строки.

Ctrl+Home: перемещение курсора в начало документа.

End: перемещение курсора в конец строки.

Ctrl+End: перемещение курсора в конец документа.

PageUp: перемещение курсора назад на один экран (экранную страницу).

Ctrl+PageUp: довольно заковыристая комбинация, перемещает курсор в пределах абзаца (или истинной строки) влево на столько знаков, сколько имеет место на текущей экранной строке; или, при других опциях переноса слов, на один экран по горизонтали влево.

PageDown: перемещение курсора вперед на один экран (экранную страницу).

Ctrl+PageDown: то же, что и комбинация Ctrl+PageUp, но перемещает курсор, соотвественно, вправо.

F10: якобы активизирует меню для выбора пунктов с клавиатуры посредством клавиш управления курсором и т.д. В моей версии не работает.

Клавишные комбинации, дублирующие пункты меню

Кроме этого, для быстрого вызова пунктов главного меню используется комбинация Alt+подчеркнутая_литера (так называемая Mnemonic).

Приложение 2
Пример секции !nedit в файле .Xdefaults для настройки редактора NEdit

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! nedit
nedit*text.foreground: black
!Задает черный цвет редактируемого текста

nedit*text.background: gray70
!Задает светло-серый (яркость 70%) цвет фона рабочего поля

nedit*text.selectForeground: gray10
!Задает очень темно-серый цвет текста в выделенном фрагменте

nedit*text.selectBackground: gray80
!Задает очень светло-серый цвет фона выделенного фрагмента

nedit*text.highlightForeground: white
!Задает непонятно что. Оставлено в пару следующей строке

nedit*text.highlightBackground: green
!Задает зеленый цвет подсветки парных элементов (например, скобок)

nedit*text.cursorForeground: black
!Задает черный цвет курсора

nedit*text.lineNumForeground: gray47
!Задает среднесерый цвет нумерации строк (которую включаю очень редко)

nedit*text.blinkRate: 600
!Мерцание курсора с частотой 600 миллисекунд

nedit*foreground: black
!Задает цвет текста интерфейсных элементов (меню, панелей и прочего).

nedit*background: gray60
!Задает цвет фона интерфейсных элементов (меню, панелей, строки состояния и прочих)

nedit*fontList: -cronyx-fixed-medium-r-*-*-20-*-*-*-*-*-koi8-r
!Задает шрифт меню

nedit*font: -cronyx-fixed-medium-r-*-*-20-*-*-*-*-*-koi8-r
Задает шрифт сообщений в окне системы помощи

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Приложение 3
Макросы для разметки html-документов

Это разработанная мной коллекция макросов для редактора NEdit, предназначенная для разметки несложных html-документов. Она включает в себя команды для ввода наиболее распространенных структурных тэгов и гиперссылок, то есть того, с чем постоянно сталкиваешься при подготовке существенно текстовых web-страниц. Не претендует ни на изящество кода, ни, даже, на его синтасическую точность, но работоспособны - проверено на собственной шкуре.

nedit.macroCommands: \
! Пункты меню для ввода тэгов рубрик 1-3 порядка (h1-h3)
	Headers>header1:F1::: {\n\
		insert_string("<")\n\
		insert_string("h")\n\
		insert_string("1")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("h")\n\
		insert_string("1")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Headers>header2:F2::: {\n\
		insert_string("<")\n\
		insert_string("h")\n\
		insert_string("2")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("h")\n\
		insert_string("2")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Headers>header3:F3::: {\n\
		insert_string("<")\n\
		insert_string("h")\n\
		insert_string("3")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("h")\n\
		insert_string("3")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
! Эти макросы вводят тэги параграфа и разрыва строки (p и br, соответственно)
	Text>paragraph:Ctrl+P::: {\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("p")\n\
		insert_string(">")\n\
	}\n\
	Text>break:Ctrl+B::: {\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("b")\n\
		insert_string("r")\n\
		insert_string(">")\n\
	}\n\
!Макросы для ввода структурных тэгов strong, emphasis, preformatted text
	Structure>strong:::: {\n\
		insert_string("<")\n\
		insert_string("s")\n\
		insert_string("t")\n\
		insert_string("r")\n\
		insert_string("o")\n\
		insert_string("n")\n\
		insert_string("g")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("s")\n\
		insert_string("t")\n\
		insert_string("r")\n\
		insert_string("o")\n\
		insert_string("n")\n\
		insert_string("g")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Structure>emphasis:::: {\n\
		insert_string("<")\n\
		insert_string("e")\n\
		insert_string("m")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("e")\n\
		insert_string("m")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Structure>preformatted:::: {\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("p")\n\
		insert_string("r")\n\
		insert_string("e")\n\
		insert_string(">")\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("p")\n\
		insert_string("r")\n\
		insert_string("e")\n\
		insert_string(">")\n\
		newline()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
!Этот пункт меню содержит макросы для ввода списков разного рода - маркированных,
! нумерованных, с определениями, а также их элементов
	Lists>unordered list:::: {\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("u")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("u")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Lists>oredered list:::: {\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("o")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("o")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Lists>list item:Ctrl+I::: {\n\
		insert_string("<")\n\
		insert_string("l")\n\
		insert_string("i")\n\
		insert_string(">")\n\
	}\n\
	Lists>definition list:::: {\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("d")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		newline()\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("d")\n\
		insert_string("l")\n\
		insert_string(">")\n\
		newline()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Lists>term:::: {\n\
		insert_string("<")\n\
		insert_string("d")\n\
		insert_string("t")\n\
		insert_string(">")\n\
	}\n\
	Lists>definition:::: {\n\
		insert_string("<")\n\
		insert_string("d")\n\
		insert_string("d")\n\
		insert_string(">")\n\
	}\n\
	Links>local link:Alt+A::: {\n\
		insert_string("<")\n\
		insert_string("a")\n\
		insert_string(" ")\n\
		insert_string("h")\n\
		insert_string("r")\n\
		insert_string("e")\n\
		insert_string("f")\n\
		insert_string("=")\n\
		insert_string("\\"")\n\
		insert_string("\\"")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("a")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
!Ввод тэгов для локальных и удаленных
! (последние - с аргументом target="_blank")
! гиперссылок, а также именованных якорей
	Links>URL:Alt+U::: {\n\
		insert_string("<")\n\
		insert_string("a")\n\
		insert_string(" ")\n\
		insert_string("h")\n\
		insert_string("r")\n\
		insert_string("e")\n\
		insert_string("f")\n\
		insert_string("=")\n\
		insert_string("\\"")\n\
		insert_string("\\"")\n\
		insert_string(" ")\n\
		insert_string("t")\n\
		insert_string("a")\n\
		insert_string("r")\n\
		insert_string("g")\n\
		insert_string("e")\n\
		insert_string("t")\n\
		insert_string("=")\n\
		insert_string("\\"")\n\
		insert_string("_")\n\
		insert_string("b")\n\
		insert_string("l")\n\
		insert_string("a")\n\
		insert_string("n")\n\
		insert_string("k")\n\
		insert_string("\\"")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("a")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n\
	Links>name:::: {\n\
		insert_string("<")\n\
		insert_string("a")\n\
		insert_string(" ")\n\
		insert_string("n")\n\
		insert_string("a")\n\
		insert_string("m")\n\
		insert_string("e")\n\
		insert_string("=")\n\
		insert_string("\\"")\n\
		insert_string("\\"")\n\
		insert_string(">")\n\
		insert_string("<")\n\
		insert_string("/")\n\
		insert_string("a")\n\
		insert_string(">")\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
		backward_character()\n\
	}\n

Этот листинг может быть просто скопирован в секцию

nedit.macroCommands: \

файла .nedit. Для полноты счастья в секцию

nedit.shellCommands: \

можно вставить строки

	netscape:::XS:\n\
		konsole -e netscape %\n\

для просмотра редактируемого html-файла. Разумеется, вместо konsole можно указать любую другую программу эмуляции терминала.

В начало

Copyleft by
Alex Fedorchuk