Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Программы » FAR Manager (часть 6)

Модерирует : gyra, Maz

Maz (26-09-2022 12:52): FAR Manager (часть 7)  Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

   

Victor_VG



Tracker Mod
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору


Код:
-------------------------------------------------------------------------------
--           Работа мышкой с выделением в редакторе. © SimSU
-------------------------------------------------------------------------------
-- Умеет:
--   первая таблица (действие):
--     перемещать курсор за мышкой - команда "SelNone";
--     выделять обычные и вертикальные блоки - "SelNorm", "SelVert";
--     корректировать выделение обычных и вертикальных блоков - "CorNorm" и "CorVert";
--     выделять слово, строку как нормальный, так и как вертикальный блок - "WordNorm", "LineNorm" и "WordVert", "LineVert";
--     перетаскивать блоки, перетаскивать с копированием - "Move", "Copy";
--   вторая таблица (последействие):
--     в буфер обмена вырезать, копировать, добавлять, вырезать с добавлением - "Copy", "Cut", "Add", "CutAdd";
--     удалять, вставлять и обменивать с буфером обмена - "Delete", "Paste" и "Replace".
-- Различает состояния - ключи в соответствующей таблице:
--   одинарный, двойной и т.д. клик мышки в выделенной области "InSel1", "InSel2", ...
--   одинарный, двойной и т.д. клик мышки вне выделенной области "NotSel1", "NotSel2", ...
--   одинарный, двойной и т.д. клик мышки в любой области при отсутствии действий для предыдущих состояний "Click1", "Click2", ...
-- Пример: хотим выделить и вырезать в клипборд вертикальный блок - SimSU.Editor_MouseSelect.MouseSelect({Click1="SelVert"},{Click1="Cut"})
--         ещё хотим по двойному клику выделять и удалять слово - дополним таблицы... SimSU.Editor_MouseSelect.MouseSelect({Click1="SelVert",Click2="WordNorm"},{Click1="Cut",Click2="Delete"})
 
---- Настройки
local function Settings()
-- Начало файла Profile\SimSU\Editor_MouseSelect.cfg
return{
  {-- Обычный блок: при клике в выделении корректируем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  Key="MsLClick";             --Prior=50; --Sort=50;
  Action ={InSel1="CorNorm"; Click1="SelNorm"; Click2="WordNorm"; Click3="LineNorm"};
  id="2718943b-0302-4bab-8db1-1d3369e4bf5d"};
  {-- Вертикальный блок: При клике в выделении корректируем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  Key="MsRClick AltMsLClick"; --Prior=50; --Sort=50;
  Action ={InSel1="CorVert"; Click1="SelVert"; Click2="WordVert"; Click3="LineVert"};
  id="30d9c41b-3b50-4212-8f5f-df0350f2522e"};
  {-- Обычный блок с копированием в буфер: при клике в выделении перетаскиваем копию, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  Key="CtrlMsLClick";         --Prior=50; --Sort=50;
  Action ={InSel1="Copy"; Click1="SelNorm"; Click2="WordNorm"; Click3="LineNorm"   };
  PostAct={               Click1="Copy"   ; Click2="Copy"    ; Click3="Copy"       };
  id="a70c91df-2ea4-4119-870d-f28c0bc7859a"};
  {-- Обычный блок с вырезанием в буфер: при клике в выделении перетаскиваем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  Key="ShiftMsLClick";        --Prior=50; --Sort=50;
  Action ={InSel1="Move"; Click1="SelNorm"; Click2="WordNorm"; Click3="LineNorm"   };
  PostAct={               Click1="Cut"    ; Click2="Cut"     ; Click3="Cut"        };
  id="238dc4e8-0b2d-4f34-9668-2718878ced0f"};
  Timing=250 -- Максимальный интервал (мс) между кликами при превышении которого двойной, тройной и т.д. клик не будет засчитан.
}
-- Конец файла Profile\SimSU\Editor_MouseSelect.cfg
end
 
_G.far.lang=far.lang or win.GetEnv("farlang")
-- Встроенные языки / Built-in laguages
local function Messages()
--if far.lang=="Russian" then
-- Начало файла Profile\SimSU\SimSU\Editor_MouseSelectRussian.lng
return{
  -- Обычный блок: при клике в выделении корректируем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  "Выделение обычного блока. © SimSU";
  -- Вертикальный блок: При клике в выделении корректируем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  "Выделение вертикального блока. © SimSU";
  -- Обычный блок с копированием в буфер: при клике в выделении перетаскиваем копию, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  "Выделение с копированием. © SimSU";
  -- Обычный блок с вырезанием в буфер: при клике в выделении перетаскиваем, иначе выделяем, при двойном клике выделить слово, при тройном выделить строку."
  "Выделение с вырезанием. © SimSU";
}
-- Конец файла Profile\SimSU\Editor_MouseSelectRussian.lng
end --end
 
local M=(loadfile(win.GetEnv("FARPROFILE").."\\SimSU\\Editor_MouseSelect"..far.lang..".lng") or Messages)()
local S=(loadfile(win.GetEnv("FARLOCALPROFILE").."\\SimSU\\Editor_MouseSelect.cfg") or loadfile(win.GetEnv("FARPROFILE").."\\SimSU\\Editor_MouseSelect.cfg") or Settings)()
 
local SimSU= _G.SimSU or {}
-------------------------------------------------------------------------------
S.Timing = S.Timing==nil and Settings().Timing or S.Timing
 
local Editor=Editor
local Sel=Editor.Sel
local Pos=Editor.Pos
local Set=Editor.Set
local editorGetInfo=editor.GetInfo
 
local function GetInfo()
-- Расширение функции editor.GetInfo, чтобы знать координаты окна редактора в фаре и состяние строк заголовка и клавишь, а также полосы прокрутки.
  local EdInf=editorGetInfo()
  EdInf.TitleBar=Far.Cfg_Get("Editor","ShowTitleBar")=="true" and 1 or 0 -- Строка статуса включена?
  EdInf.KeyBar=Far.KeyBar_Show(0)                                        -- Кейбар включен?
  EdInf.ScrollBar=Set(15)                                                -- Скролбар включен?
                                                                         -------------------------------------------
  local C=far.AdvControl("ACTL_GETCURSORPOS")                            -- (X1,Y1)                               --
  EdInf.X1=C.X-(EdInf.CurTabPos-EdInf.LeftPos)                           --                                       --
  EdInf.Y1=C.Y-(EdInf.CurLine-EdInf.TopScreenLine)-EdInf.TitleBar        --       Координаты окна редактора       --
  EdInf.X2=C.X-(EdInf.CurTabPos-EdInf.LeftPos)    +EdInf.WindowSizeX     --                                       --
  EdInf.Y2=C.Y-(EdInf.CurLine-EdInf.TopScreenLine)+EdInf.WindowSizeY     --                               (X2,Y2) --
                                                                         -------------------------------------------
  return EdInf
end
 
local function InEditorMouse()
-- Проверка - мышка в тексте?
  local EdInf=GetInfo()
  return Mouse.X>=EdInf.X1 and Mouse.Y>=EdInf.Y1+EdInf.TitleBar and Mouse.X<=EdInf.X2-EdInf.ScrollBar and Mouse.Y<=EdInf.Y2-EdInf.KeyBar -- Кликнули в текст, значит разрешим макрос.
end
 
local function MouseToText()
-- Пересчёт экранных координат мышки в координаты текста.
  local EdInf = GetInfo()
  local X1 = EdInf.LeftPos
  local Y1 = EdInf.TopScreenLine
  local X2 = X1+EdInf.WindowSizeX-EdInf.ScrollBar
  local Y2 = Y1+EdInf.WindowSizeY-EdInf.KeyBar
  local Xm = X1+Mouse.X-EdInf.X1               ;  Xm = Xm<X1 and X1 or Xm>X2 and X2 or Xm
  local Ym = Y1+Mouse.Y-EdInf.Y1-EdInf.TitleBar;  Ym = Ym<Y1 and Y1 or Ym>Y2 and Y2 or Ym
  return Xm,Ym,X1,Y1,X2,Y2 -- Координаты мышки и экрана в тексте
end
 
local function MouseMove(SelMode,Xb,Yb)
-- Функция обработки движения мышки.
  local MM=mmode(1,1) -- Запретим перерисовку экрана.
  local EOL=Set(7,1) -- Разрешим "курсор за пределами строки".
  local Xm,Ym,X1,Y1,X2,Y2 = MouseToText()
  if not ((SelMode==1 or SelMode==2) and Xb and Yb) then Xb=Xm; Yb=Ym end -- За начало примем текущие координаты.
  while Mouse.Button~=0 do
    if SelMode==1 or SelMode==2 then
      -- Выделение. И магия для табов с вертикальными блоками.
      Pos(1,1,Yb); Pos(1,4-SelMode,Xb); Sel(SelMode+1,0)
      Pos(1,1,Ym); Pos(1,4-SelMode,Xm); Sel(SelMode+1,1)
    end
    Pos(1,5,X1); Pos(1,4,Y1) -- Координаты экрана в тексте.
    Pos(1,3,Xm); Pos(1,1,Ym) -- Координаты мышки в тексте.
    mmode(1,mmode(1,0),Pos(1,2)) -- Перерисуем экран. Двинем курсор для колорера(v.1.2.11.0).
    mf.waitkey(1)
    Xm,Ym,X1,Y1,X2,Y2 = MouseToText() -- Новые координаты.
    -- Скроллирование.
    if Xm==X1 and X1>1 then X1=X1-1; Xm=X1 elseif Xm==X2                     then X1=X1+1; Xm=X2+1 end
    if Ym==Y1 and Y1>1 then Y1=Y1-1; Ym=Y1 elseif Ym==Y2 and Ym<Editor.Lines then Y1=Y1+1; Ym=Y2+1 end
  end
  Set(7,EOL) -- Восстановим состояние "курсор за пределами строки".
  mmode(1,MM) -- Восстановим состояние отрисовки.
end
 
local function ClickInSel()
-- Функция проверки на клик в выделенной области.
  local Xm,Ym = MouseToText()
  local St=Sel(0,4); local Yb= St==0 and Ym or Sel(0,0); local Xb= St==0 and Xm or Sel(0,1); local Ye= St==0 and Ym or Sel(0,2); local Xe= St==0 and Xm or Sel(0,3) -- Тип и координаты выделения.
  local Sl=(St==0 or (St>0 and Ym<=Ye and Ym>=Yb)) -- Курсор в строках где есть выделение.
  local Sp=(Sl and ((St==2 and Xm>=Xb and Xm<=Xe) or (St==1 and ((Yb~=Ye and Ym==Yb and Xm>=Xb) or (Yb~=Ye and Ym==Ye and Xm<=Xe) or (Yb==Ye and Xm>=Xb and Xm<=Xe) or (Yb~=Ye and Ym~=Yb and Ym~=Ye))))) -- Курсор точно в выделении.
  if not Sp then
    Xb=nil; Yb=nil -- Если кликнули не в выделенной области, то считаем, что и выделения нет.
  else
    if (Xb-Xm)^2+(Yb-Ym)^2<(Xe-Xm)^2+(Ye-Ym)^2 then Xb,Yb = Xe,Ye end -- За начало выделенной области примем её дальний от места клика угол.
  end
  return Xb,Yb -- Координаты начала выделенного блока и координаты экрана.
end
 
local function SelWord(SelectType,Line,Column)
-- Функция выделения слова.
  local St= SelectType or 1
  local Xc,Yc
  if Line and Column then Yc,Xc = Line,Column else Xc,Yc = MouseToText() end
  Pos(1,1,Yc); Pos(1,3,Xc)
  local s=Editor.Value; local Xct=Editor.RealPos
  local Xe=Xct while s:sub(Xe,Xe):find("[%w_]") do Xe=Xe+1 end-- Ищем конец слова c курсором.
  local Xb=Xct while s:sub(Xb-1,Xb-1):find("[%w_]") do Xb=Xb-1 end -- Ищем начало слова c курсором.
  Pos(1,2,Xb); Sel(St+1,0); Pos(1,2,Xe); Sel(St+1,1) -- Выделяем найденное слово, если слово не нашли, то выделение просто снимется из-за равенства Beg и End.
  mmode(1,mmode(1,0),Pos(1,2,Xct)) -- Перерисуем экран. Двинем курсор для колорера.
end
 
local function SelLine(SelectType,Line,Column)
-- Функция выделения строки.
  local St= SelectType or 1
  local Xc,Yc
  if Line then Yc=Line; Xc= Column or Editor.CurPos else  Xc,Yc = MouseToText() end
  local Yb=Yc; local Ye= St==1 and Yc<Editor.Lines and Yc+1 or Yc
  Pos(1,1,Yc); local s=Editor.Value
  local Xb=1; local Xe= Yb~=Ye and 1 or s:len()+1
  Pos(1,1,Yb); Pos(1,2,Xb); Sel(St+1,0); Pos(1,1,Ye); Pos(1,2,Xe); Sel(St+1,1)
  Pos(1,1,Yc) -- Координаты курсора в тексте.
  mmode(1,mmode(1,0),Pos(1,2,Xc)) -- Перерисуем экран. Двинем курсор для колорера.
end
 
local function MouseSelect(Action,PostAct)
-- Функция работы мышкой с выделением в редакторе. © SimSU
  local NumClick=1
  local PA=true
  while NumClick do
    local Act = Action ~=nil and ((Sel(0,4)>0 and ClickInSel() and Action ["InSel"..NumClick]) or (Sel(0,4)>0 and not ClickInSel() and Action ["NotSel"..NumClick]) or Action ["Click"..NumClick])
    local PAct= PostAct~=nil and ((Sel(0,4)>0 and ClickInSel() and PostAct["InSel"..NumClick]) or (Sel(0,4)>0 and not ClickInSel() and PostAct["NotSel"..NumClick]) or PostAct["Click"..NumClick])
    if     Act=="SelNorm"  then MouseMove(1)
    elseif Act=="SelVert"  then MouseMove(2)
    elseif Act=="SelNone"  then MouseMove(0)
    elseif Act=="CorNorm"  then local Xb,Yb = ClickInSel(); MouseMove(1,Xb,Yb)
    elseif Act=="CorVert"  then local Xb,Yb = ClickInSel(); MouseMove(2,Xb,Yb)
    elseif Act=="WordNorm" then SelWord(1)
    elseif Act=="WordVert" then SelWord(2)
    elseif Act=="LineNorm" then SelLine(1)
    elseif Act=="LineVert" then SelLine(2)
    elseif Act=="Move"     then local PB=Set(2,1); MouseMove(0); Keys("CtrlM"); Set(2,PB); PA=false
    elseif Act=="Copy"     then local PB=Set(2,1); MouseMove(0); Keys("CtrlP"); Set(2,PB); PA=false
    end
    if     PA and PAct=="Copy"    then mf.clip(1,Editor.SelValue)
    elseif PA and PAct=="Cut"     then mf.clip(1,Editor.SelValue); editor.DeleteBlock() --Keys("CtrlD")
    elseif PA and PAct=="Add"     then mf.clip(2,Editor.SelValue)
    elseif PA and PAct=="CutAdd"  then mf.clip(2,Editor.SelValue); editor.DeleteBlock() --Keys("CtrlD")
    elseif PA and PAct=="Delete"  then editor.DeleteBlock() -- Keys("CtrlD")
    elseif PA and PAct=="Paste"   then Keys("CtrlV")
    elseif PA and PAct=="Replace" then local s=Editor.SelValue; editor.DeleteBlock() Keys("CtrlV"); mf.clip(1,s)
    end
    local VK=mf.waitkey(S.Timing)
    NumClick= VK:find("Click",1,true) and NumClick+1 or nil
  end
end;
 
-------------------------------------------------------------------------------
local Editor_MouseSelect={
  GetInfo      = GetInfo      ;
  InEditorMouse= InEditorMouse;
  MouseToText  = MouseToText  ;
  MouseMove    = MouseMove    ;
  ClickInSel   = ClickInSel   ;
  SelWord      = SelWord      ;
  SelLine      = SelLine      ;
  MouseSelect  = MouseSelect  ;
}
local function filename(args) return MouseSelect(args[1],args[2]) end
-------------------------------------------------------------------------------
if _filename then return filename(...) end
if not Macro then return {Editor_MouseSelect=Editor_MouseSelect} end
SimSU.Editor_MouseSelect=Editor_MouseSelect; _G.SimSU=SimSU
-------------------------------------------------------------------------------
 
for i=1,#S do
Macro {id=S[i].id;
  area="Editor"; key=S[i].Key; priority=S[i].Prior; sortpriority=S[i].Sort; description=M[i];
  condition=function() return InEditorMouse() end;
  action=function() return MouseSelect(S[i].Action,S[i].PostAct) end;
}
end
 

Всего записей: 33205 | Зарегистр. 31-07-2002 | Отправлено: 12:50 24-06-2021 | Исправлено: Victor_VG, 13:08 24-06-2021
   

На первую страницук этому сообщениюк последнему сообщению

Компьютерный форум Ru.Board » Компьютеры » Программы » FAR Manager (часть 6)
Maz (26-09-2022 12:52): FAR Manager (часть 7)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru