Редактор: поиск/замена целыми словами с регулярными выражениями

Здесь обсуждается всё, что касается макросов.
Post Reply
User avatar
HaRT
Moderator
Posts: 10863
Joined: Tue 30 Aug, 2005 17:21
Has thanked: 221 times
Been thanked: 358 times

Редактор: поиск/замена целыми словами с регулярными выражениями

Post by HaRT »

Поскольку при поиске/замене в редакторе с “[x] Regular expressions” значение опции “[x] Whole words” игнорируется, я написал макрос, который позволяет сгладить это неудобство, пусть и не очень красивым способом — при включении галки “Только целые слова” изменяет регэксп дописыванием в начало и конец так, чтобы текст по нему находился только между границами слова (и чтобы номера/имена групп при этом не менялись); при выключении галки те префикс и суффикс убираются. И всё это происходит, только если включена опция “Регулярные выражения”.
  1. -- See http:// forum.farmanager.com/viewtopic.php?p=137190#p137190
  2.  
  3. -- TODO extend to various RESearch dialogs
  4.  
  5. local SEARCH_TXT_ITEM_POS =  5  -- in both Search and Replace
  6.  
  7. local WHLWRD_CHK_ITEM_POS = 10  -- in both Search and Replace
  8.  
  9. local REGEXP_CHK_ITEM_POS = 12  -- in both Search and Replace
  10.  
  11.  
  12.  
  13. Macro {
  14.  
  15.   description = 'Search/Replace: smart toggle Whole Words for RegExp';
  16.  
  17.   area = 'Dialog'; key = 'AltW';
  18.  
  19.   condition = function()
  20.  
  21.     return ( Dlg.Id == far.Guids.EditorSearchId or
  22.  
  23.              Dlg.Id == far.Guids.EditorReplaceId )
  24.  
  25.          and Dlg.GetValue(REGEXP_CHK_ITEM_POS) ~= 0
  26.  
  27.   end;
  28.  
  29.   action = function()
  30.  
  31.     local prefix, suffix = '\\b(?:', ')\\b'
  32.  
  33.     local searchText = Dlg.GetValue(SEARCH_TXT_ITEM_POS)
  34.  
  35.     if Dlg.GetValue(WHLWRD_CHK_ITEM_POS) == 0 then
  36.  
  37.       searchText = prefix .. searchText .. suffix
  38.  
  39.     else
  40.  
  41.       local prefLen, suffLen = prefix:len(), suffix:len()
  42.  
  43.       if searchText:sub( 1, prefLen ) == prefix and
  44.  
  45.          searchText:sub( -suffLen, -1 ) == suffix then
  46.  
  47.         searchText = searchText:sub( prefLen + 1, -( suffLen + 1 ) )
  48.  
  49.       else
  50.  
  51.         searchText = nil  -- flag that no change is required
  52.  
  53.       end
  54.  
  55.     end
  56.  
  57.     if searchText ~= nil then
  58.  
  59.       Dlg.SetFocus(SEARCH_TXT_ITEM_POS)
  60.  
  61.       Keys('CtrlY')  -- TODO preserve caret position, selection, etc
  62.  
  63.       print(searchText)
  64.  
  65.     end
  66.  
  67.     Keys('AKey');
  68.  
  69.   end;
  70.  
  71. }
Прошу покритиковать. (Про идиому “condExpr and trueExpr or falseExpr” и про сравнение с nil знаю.)

Пожелание: хорошо бы аналогичную логику спрятать под капотом, чтобы поиск целыми словами просто работал и с регэкспами, притом не засоряя их.
Last edited by HaRT on Thu 01 Jan, 1970 01:00, edited 0 times in total.
Reason: Добавлены константы из far.Guids; вычеркнуто неактуальное, добавлено пожелание к разработчикам.
Фар есть инструмент, а не нянька. © 2009 DrKnS
Shmuel
Posts: 6836
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 530 times

Редактор: поиск/замена целыми словами с регулярными выражениями

Post by Shmuel »

HaRT wrote: Прошу покритиковать.
Вроде и критиковать нечего, всё нормально.
В качестве мелкого усовершенствования, можно использовать стандартные имена гуидов, например far.Guids.EditorSearchId. Эти имена можно оперативно получить следующим макросом:
fps
Posts: 267
Joined: Wed 20 Apr, 2005 06:39
Has thanked: 27 times
Been thanked: 14 times

Редактор: поиск/замена целыми словами с регулярными выражениями

Post by fps »

Если опцию выбирать мышкой, то не работает :)
Post Reply

Return to “Обсуждение макросов”