1. Ищет слово под курсором выше по тексту
2. Ищет слово под курсором ниже по тексту
3. Показывает менюшку со всеми строками, которые содержат слово под курсором
"Из коробки" сует себя в меню редактора ФАРа.
Можно оттуда убрать и\или повесить на кнопки
Параметры в начале скрипта.
ВНИМАНИЕ:
- Чтобы корректно рисовались вертикальные молоски в менюшке скрипт нужно сохранить в кодировке UTF8 или выше.
- Не забываем проверить настройки вначале скрипта!
Code: Select all
--[[
==================================================
Search word under cursor up or down
Ctrl+Shift+F6 - search up
Ctrl+Shift+F7 - search down
Grep in current file for all lines contains word under cursor
Known problems in search:
1. Changes "Reverse search" and "Whole words" search options
So, if you use FAR search it affects next ShiftF7
2. Numbers treated as words too
Settings
You can change some parameters in the section below.
================================================== ]]--
local LINE_SHIFT = 10 -- number of lines from screen top to search line
local ALIGN_GREP = true -- if is set will align lines in grep search
local ALIGN_LEFT = true -- if is set left part of line will be aligned to left
local SELECT_GREP = true -- if is set grep result will be selected
local PICKUP_SELECT = true -- if is set selection will be taken instead of word
local ADD_TO_MENU = true -- if is set will add funcions to editors plugin menu
local ADD_TO_HOTKEYS = false -- if is set will register macro hotkeys
local FILES_MASK = "*" -- Files where possible to run functions
-- Function titles (affect plugin menu)
local S_PREV_TITLE = "Prev word under cursor";
local S_NEXT_TITLE = "Next word under cursor";
local S_GREP_TITLE = "Grep word under cursor";
-- Hotkeys
local KEY_PREV = "CtrlShiftF6"
local KEY_NEXT = "CtrlShiftF7"
local KEY_GREP = "CtrlShiftF8"
-- =================================================
Macro { description= S_PREV_TITLE .. " (CtrlShiftF6)";
area="Editor"; key=KEY_PREV; filemask = FILES_MASK; flags="";
condition = function() return ADD_TO_HOTKEYS; end;
action = function() FindPrevWord(); end;
}
Macro { description=S_NEXT_TITLE .. " (CtrlShiftF7)";
area="Editor"; key=KEY_NEXT; filemask = FILES_MASK; flags="";
condition = function() return ADD_TO_HOTKEYS; end;
action = function() FindNextWord() end;
}
Macro { description=S_GREP_TITLE .. " (CtrlShiftF8)";
area="Editor"; key=KEY_GREP; filemask = FILES_MASK; flags="";
condition = function() return ADD_TO_HOTKEYS; end;
action = function() GrepEditorWord() end;
}
-- =================================================
MenuItem { description = "LUA: " .. S_PREV_TITLE;
menu = "Plugins";
area = "Editor";
guid = "A435DF01-AD64-4DD1-8C61-28CB90358817";
text = function() if ADD_TO_MENU then return "LUA: " .. S_PREV_TITLE; else return false; end end;
action = function() GrepEditorWord(); end;
}
MenuItem { description = "LUA: " .. S_NEXT_TITLE;
menu = "Plugins";
area = "Editor";
guid = "A435DF02-AD64-4DD1-8C61-28CB90358817";
text = function() if ADD_TO_MENU then return "LUA: " .. S_NEXT_TITLE; else return false; end end;
action = function() GrepEditorWord(); end;
}
MenuItem { description = "LUA: " .. S_GREP_TITLE;
menu = "Plugins";
area = "Editor";
guid = "A435DF03-AD64-4DD1-8C61-28CB90358817";
text = function() if ADD_TO_MENU then return "LUA: " .. S_GREP_TITLE; else return false; end end;
action = function() GrepEditorWord(); end;
}
--[[ ================================================== ]]--
local SelectionPicked = false
function p(...) if msgbox( "message", string.format( ... ), 0x00020000 ) == 2 then _FAKECALL() end end
function m(...) v,n = far.Show("{TERMINATE SCRIPT}", ...) if v ~= nil and n == 1 then _FAKECALL() end end
function iif(e,v1,v2) if e ~= nil and e == true then return v1; else return v2; end end
-- check char for "wordness"
function isw( s,x )
return string.match( s:sub(x,x), "[%a%d_]" ) ~= nil
end
-- Get word under cursor and set editor position to search NEXT
function GetWord( isup )
--[[
-- Simpler version but it selects symbols as well
Keys("SelWord")
if not Object.Selected then return nil end
local i = editor.GetSelection(nil)
return editor.GetString(-1,i.StartLine,3):sub(i.StartPos,i.EndPos),i.StartPos,i.EndPos
]]--
local i = editor.GetInfo(nil)
local y = i.CurLine
local s = editor.GetString(-1,y,3)
if s:len() == 0 then return nil; end
local x = i.CurPos
local e = 0
local found = false
SelectionPicked = false
if PICKUP_SELECT then
local sel = editor.GetSelection(nil)
--m(sel.BlockType, sel.StartLine, sel.EndLine, sel.StartPos, sel.EndPos)
if sel ~= nil and sel.BlockType ~= 0 and
sel.StartLine <= y and sel.EndLine >= y and sel.StartPos < sel.EndPos then
x = sel.StartPos
e = sel.EndPos
SelectionPicked = true
found = e > x
end
end
if not found then
if not isw(s,x) then
if isup == nil or isup == true and isw(s,x-1) then x = x-1 end
if isup == nil or isup == false and isw(s,x+1) then x = x+1 end
end
if x < 0 or x > s:len() then return nil; end
e = x
while x > 0 and isw(s,x) do x = x-1; end
while isw(s,e) do e = e+1; end
if e <= x then return nil end
x = x+1
e = e-1
end
if isup ~= nil then
if isup then
editor.SetPosition(-1,{CurPos=x})
else
editor.SetPosition(-1,{CurPos=e})
end
end
s = s:sub(x,e)
if s:len() == 0 then return nil end
return s,x,e
end
-- Corrections after search
function Finalize( olds, x, isup )
-- supress "not found" dialog and restore position and selection
if Area.Dialog and Dlg.Id == "00000000-0000-0000-0000-000000000000" then
Keys("Esc");
editor.SetPosition(-1,{CurPos=x})
if olds ~= nil then
editor.Select( nil,
olds.BlockType,
olds.StartLine, olds.StartPos,
olds.EndPos-olds.StartPos+1, olds.EndLine-olds.StartLine+1 )
end
else
-- found, correct position for next search
olds = editor.GetSelection(nil)
if olds ~= nil then
if isup then
editor.SetPosition(-1,{CurPos=olds.StartPos})
else
editor.SetPosition(-1,{CurPos=olds.EndPos})
end
end
end
end
-- Check string at 'y' has 's' word
function FindString( y, s )
local line = editor.GetString(-1,y,3)
if line == nil then return false,nil,nil end
local b,e = line:find(s,1,true )
if b ~= nil then
-- Check word bounds only if word
if not SelectionPicked then
if b > 0 and isw(line,b-1) then b = nil;
elseif isw(line,b+s:len()) then b = nil; end
end
end
if b ~= nil then
return true,line,b;
else
return true,nil,nil;
end
end
function PosInEdit(it,s,doSelect)
editor.SetPosition(-1,{TopScreenLine=it.y-LINE_SHIFT,CurLine=it.y,CurPos=it.x})
if doSelect then
editor.Select(nil, 1, it.y, it.x, s:len(), 1 )
editor.Redraw(nil)
end
end
-- =================================================
function FindPrevWord()
local olds = editor.GetSelection(nil)
local oldx = editor.GetInfo(nil).CurPos
local s = GetWord(true);
if not s then return; end
Keys("F7 ShiftNum7 CtrlD");
print(s);
Keys("AltW Add AltV Add Enter");
Finalize(olds,oldx,true)
end
function FindNextWord()
local olds = editor.GetSelection(nil)
local oldx = editor.GetInfo(nil).CurPos
local s = GetWord(false);
if not s then return; end
Keys("F7 ShiftNum7 CtrlD");
print(s);
Keys("AltW Add AltV Subtract Enter");
Finalize(olds,oldx,false)
end
function GrepEditorWord()
local olds = editor.GetSelection(nil)
local i = editor.GetInfo(nil)
local oldx = i.CurPos
local s,x = GetWord(nil);
if not s then return; end
items = {}
local cn = 1
local n = 1
local ee = true
while( ee ) do
ee, line, nx = FindString(n,s)
if line ~= nil then
items[cn] = { s = line, x = nx, y = n }
cn = cn + 1
end
n = n + 1
end
cn = cn-1
for n=1,cn do if items[n].x > x then x = items[n].x; end; end;
while(true) do
local menu = {}
local mcn = 1
i = editor.GetInfo(nil)
for n=1,cn do
it = items[n]
menu[mcn] = it
if ALIGN_GREP then
menu[mcn].text = string.format(
"%4d¦%" ..
iif( ALIGN_LEFT, "-","" ) ..
tostring(x) ..
"s¦%s",
it.y, it.s:sub(1,it.x-1), it.s:sub(it.x,-1) )
else
menu[mcn].text = string.format( "%4d¦%s", it.y, it.s )
end
menu[mcn].selected = iif(it.y == i.CurLine,true,false);
mcn = mcn+1
end
mcn = mcn-1
it, pos = far.Menu( {Title="Grep (" .. s .. ")", Bottom="Ctrl+A,L Ctrl+Enter"},
menu,
{ {id=1,BreakKey="C+RETURN"}, {id=2,BreakKey="C+A"}, {id=3,BreakKey="C+L"} } )
if it == nil then exit() end
if it.y ~= nul then
PosInEdit(it,s,SELECT_GREP)
exit()
end
if it.id == 1 then
PosInEdit(menu[pos],s,true)
elseif it.id == 2 then
if ALIGN_LEFT then ALIGN_LEFT = false; else ALIGN_LEFT = true; end
elseif it.id == 3 then
if ALIGN_GREP then ALIGN_GREP = false; else ALIGN_GREP = true; end
end
end
end
Обновление:
+ Умеет ходить по редактору из грипа
+ Умеет включать\отключать всякие выравнивания в менюшке
* текст покорректировал
Думал еще группы добавить и инкрементальный поиск но что-то уже лень.
Позже сделаю для С, но если по уму, то кода много будет так что в общем виде вряд ли будет...