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

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Программы » SciTE - Open Source Text Editor for Windows & Linux

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

Widok (23-11-2010 11:23): Лимит страниц. Продолжаем здесь  Версия для печати • ПодписатьсяДобавить в закладки
На первую страницук этому сообщениюк последнему сообщению

   

BioInfo

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

Код:
--[[--------------------------------------------------
SciTE Smart braces
Version: 1.2.5
Authors: Dmitry Maslov, Julgo, TymurGubayev
-------------------------------------------------
Работает, если:
 
 Подключен в автозагрузку
 В настройках установлено braces.autoclose = 1  
 В настройках установлено braces.open = открывающиеся скобки
 В настройках установлено braces.close = закрывающиеся скобки
 Используется только в русской сборке из-за расширенной функции OnKey
 
-------------------------------------------------
Функционал:
 
 Автозакрытие скобок
 Автозакрытие выделенного текста в скобки
 Особая обработка { и } в cpp: автоматом делает отступ
 
-------------------------------------------------
Логика работы:
 
 Скрипт срабатывает только если braces.autoclose = 1
 
 Если мы вводим символ из braces.open, то автоматически вставляется
 ему пара из braces.close, таким образом, курсор оказывается между скобок
 
 Если мы вводим закрывающуюся скобку из braces.close и следующий символ
 эта же закрывающаяся скобка, то ввод проглатывается и лишняя закрывающаяся
 скобка не печатается
 
 Если у нас выделен текст и мы вводим символ из braces.open
 то текст обрамляется кавычками braces.open - braces.close
 если он уже был обрамлен кавычками, то они снимаются,
 при этом учитывается символ переноса строки, т.е. если выделенный
 текст оканчивается переводом строки, то скобки вставляются до переноса
 строки
 
 Если мы вводим символ { при редактировании файла cpp, то автоматически
 вставляется перенос строки два раза, а после } - курсор при этом оказывается
 в середине, т.е. после первого переноса строки, все отступы сохраняются
 
 Если мы вставляем символ } при редактировании файла cpp, то отступ
 автоматически уменьшается на один
 
 Если мы только что вставили скобку автоматом, то после того
 как нажимаем BACK_SPACE удаляется вставленная скобка, т.е.
 срабатывает как DEL, а не как BACK_SPACE
 
 Если вставляем скобку у которой braces.open == braces.close
 то вставляется пара только если таких скобок четно в строке
 
 ВНИМАНИЕ: В скрипте используется ф-ция string.pattern из COMMON.lua
--]]--------------------------------------------------
 
-- Возвращает текущий символ перевода строки
local function GetEOL()
   
local eol = "\r\n"
   
if editor.EOLMode == SC_EOL_CR then
       
eol = "\r"
   
elseif editor.EOLMode == SC_EOL_LF then
       
eol = "\n"
   
end
    return
eol
end
 
local function
FindCount( text, textToFind )
   
local count = 0;
   
for w in string.gmatch( text, textToFind:pattern() )
   
do
       
count = count + 1
   
end
    return
count
end
 
-- позиция это начало строки (учитывая отступ)
local function IsLineStartPos( pos )
   
return ( editor.LineIndentPosition[editor:LineFromPosition(pos)] == pos )
end
 
-- Получить номер текущей строки
local function GetCurrLineNumber()
   
return editor:LineFromPosition( editor.CurrentPos )
end
 
-- Получить отступ в строке
local function GetLineIndentation( num_line )
   
if ( num_line < 0 ) then num_line = 0 end
    if
( num_line >= editor.LineCount ) then num_line = editor.LineCount - 1 end
    return
( editor.LineIndentation[num_line] / editor.Indent )
end
 
-- последний в строке ?
local function IsInLineEnd( num_line, text )
   
local endpos = editor.LineEndPosition[num_line]
   
if    ( endpos >= string.len( text ) )
       
and
       
string.find( editor:textrange( editor:PositionBefore( endpos - string.len( text ) + 1 ), endpos ), text:pattern() )
   
then
        return true
    end
    return false
end
 
-- последний символ в строке - конец строки?
local function IsEOLlast( text )
   
-- в луа конец строки всегда один символ
--[[    if string.find( text, GetEOL(), string.len( text ) - 1 ) then
        return true
    end
    return false]]
   
return (text:sub(-1) == GetEOL())
end
 
-- следующий за позицией текст == text ?
local function nextIs(pos, text)
   
if ( string.find( editor:textrange( pos, editor:PositionAfter( pos + string.len( text ) - 1 ) ), text:pattern() ) ) then
        return true
    end
    return false
end
 
-- следующий символ позиции конец строки?
local function nextIsEOL(pos)
   
if    ( pos == editor.Length )
       
or
       
( nextIs( pos, GetEOL() ) )
   
then
        return true
    end
    return false
end
 
-----------------------------------------------------------------
-- проверяет скобки, заданные bracebegin и braceend в строке s на  
-- сбалансированность: "(x)y(z)" -> true, "x)y(z" -> false
local function BracesBalanced (s, bracebegin, braceend)
   
if (#bracebegin + #braceend) > 2 then
       
--@warn: данная функция не будет работать со "скобками" больше одного символа.
        --@todo: для "длинных" скобок нужно переписать эту функцию на lpeg. Но кому оно надо?..
       
return true
    end
    local
b,e    = s:find("%b"..bracebegin..braceend)
   
local b2 = s:find(bracebegin, 1, true)
   
local e2 = s:find(braceend, 1, true)
   
return (b == b2) and (e == e2)
end -- BracesBalanced
 
local function BlockBraces( bracebegin, braceend )
   
local text, lenght = editor:GetSelText()
   
local selbegin = editor.SelectionStart
   
local selend = editor.SelectionEnd
   
local b, e   = string.find( text, "^%s*"..bracebegin:pattern() )
   
local b2, e2 = string.find( text, braceend:pattern().."%s*$" )
   
local add = ( IsEOLlast( text ) and GetEOL() ) or ""
     
   
editor:BeginUndoAction()
   
if (b and b2) and BracesBalanced( text:sub( e+1, b2-1 ) , bracebegin, braceend ) then
       
text = string.sub( text, e+1, b2-1 )
       
editor:ReplaceSel( text..add )
       
editor:SetSel( selbegin, selbegin + #( text..add ) )
   
else
       
editor:insert( selend - #add, braceend )
       
editor:insert( selbegin, bracebegin )
       
editor:SetSel( selbegin, selend + #( bracebegin..braceend ) )
   
end
   
editor:EndUndoAction()
     
   
return true
end
 
local function
GetIndexFindCharInProps( value, findchar )
   
if findchar then
        local
resIndex = string.find( props[value], findchar:pattern() , 1 )
       
if    ( resIndex ~= nil )
           
and
           
( string.sub( props[value], resIndex,resIndex ) == findchar )
       
then
            return
resIndex
        end
    end
    return nil
end
 
local function
GetCharInProps( value, index )
   
return string.sub( props[value], index, index )
end
 
-- возвращает открывающуюся скобку и закрывающуюся скобку
-- по входящему символу, т.е. например,
-- если на входе ')' то на выходе '(' ')'
-- если на входе '(' то на выходе '(' ')'
local function GetBraces( char )
   
local braceOpen = ''
   
local braceClose = ''
   
local symE = ''
   
local brIdx = GetIndexFindCharInProps( 'braces.open', char )
   
if ( brIdx ~= nil ) then
       
symE = GetCharInProps( 'braces.close', brIdx )
       
if ( symE ~= nil ) then  
           
braceOpen = char
            braceClose = symE
        end
    else
       
brIdx = GetIndexFindCharInProps( 'braces.close', char )
       
if ( brIdx ~= nil ) then
           
symE = GetCharInProps( 'braces.open', brIdx )
           
if ( symE ~= nil ) then  
               
braceOpen = symE
                braceClose = char
            end
        end
    end
    return
braceOpen, braceClose
end
 
local
g_isPastedBraceClose = false
 
-- "умные скобки/кавычки"  
-- возвращает true когда обрабатывать дальше символ не нужно
local function SmartBraces( char )
   
if ( props['braces.autoclose'] == '1' ) then
        local
isSelection = editor.SelectionStart ~= editor.SelectionEnd
       
-- находим парный символ
       
local braceOpen, braceClose = GetBraces(char)
       
if ( braceOpen ~= '' and braceClose ~= '' ) then
           
-- проверяем выделен ли у нас какой либо текст
           
if ( isSelection == true ) then
               
-- делаем обработку по автозакрытию текста скобками
               
return BlockBraces( braceOpen, braceClose )
           
else
               
-- если следующий символ закрывающаяся скобка
                -- и мы ее вводим, то ввод проглатываем
               
local nextsymbol = string.format( "%c", editor.CharAt[editor.CurrentPos] )
               
if    ( GetIndexFindCharInProps( 'braces.close', nextsymbol ) ~= nil )
                   
and
                   
( nextsymbol == char )
               
then  
                   
editor:CharRight()
                   
return true
                end
               
-- если мы ставим открывающуюся скобку и  
                -- следующий символ конец строки или это парная закрывающаяся скобка
                -- то сразу вставляем закрывающуюся скобку
               
if    ( char == braceOpen )
                   
and
                   
( nextIsEOL( editor.CurrentPos ) or nextIs( editor.CurrentPos, braceClose ) )
               
then
                   
-- по волшебному обрабатываем скобку { в cpp
                   
if    ( char == '{' ) and
                       
( editor:GetLexerLanguage() == 'cpp' )
                   
then
                       
editor:BeginUndoAction()
                       
local ln = GetCurrLineNumber()
                       
if    ( ln > 0 and GetLineIndentation( ln ) > GetLineIndentation( ln - 1 ) )
                           
and
                           
( IsLineStartPos( editor.CurrentPos ) )
                           
and  
                           
( not IsInLineEnd( ln-1, '{' ) )
                       
then
                           
editor:BackTab()
                       
end
                       
editor:AddText( '{' )
                       
editor:NewLine()
                       
if ( GetLineIndentation( ln ) == GetLineIndentation( ln + 1 ) ) then
                           
editor:Tab()
                       
end
                        local
pos = editor.CurrentPos
                       
editor:NewLine()
                       
if ( GetLineIndentation( ln + 2 ) == GetLineIndentation( ln + 1 ) ) then
                           
editor:BackTab()
                       
end
                       
editor:AddText( '}' )
                       
editor:GotoPos( pos )
                       
editor:EndUndoAction()
                       
return true
                    end
                   
-- если вставляем скобку с одинаковыми правой и левой, то смотрим есть ли уже открытая в строке
                   
if    ( braceOpen == braceClose )
                       
and
                       
( math.fmod( FindCount( editor:GetCurLine(), braceOpen ), 2 ) == 1 )
                   
then
                        return false
                    end
                   
-- вставляем закрывающуюся скобку
                   
editor:BeginUndoAction()
                   
editor:InsertText( editor.CurrentPos, braceClose )
                   
editor:EndUndoAction()
                   
g_isPastedBraceClose = true
                end
               
-- если мы ставим закрывающуюся скобку
               
if ( char == braceClose ) then
                   
-- "по волшебному" обрабатываем скобку } в cpp
                   
if ( char == '}' ) and
                       
( editor:GetLexerLanguage() == 'cpp' )
                   
then
                       
editor:BeginUndoAction()
                       
if (IsLineStartPos( editor.CurrentPos ) )
                       
then
                           
editor:BackTab()
                       
end
                       
editor:AddText( '}' )
                       
editor:EndUndoAction()
                       
return true
                    end
                end
            end
        end
    end
    return false
end
 
-- Перехватываем функцию редактора OnKey
AddEventHandler("OnKey", function(key, shift, ctrl, alt, char)
   
if ( editor.Focus ) then
        if
( key == 8 and g_isPastedBraceClose == true ) then -- VK_BACK (08)
           
g_isPastedBraceClose = false
           
editor:BeginUndoAction()
           
editor:CharRight()
           
editor:DeleteBack()
           
editor:EndUndoAction()
           
return true
        end
 
       
g_isPastedBraceClose = false
 
        if
( char ~= '' ) then
            return
SmartBraces( char )
       
end
    end
end
)

Всего записей: 83 | Зарегистр. 30-04-2007 | Отправлено: 11:11 01-09-2010
   

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

Компьютерный форум Ru.Board » Компьютеры » Программы » SciTE - Open Source Text Editor for Windows & Linux
Widok (23-11-2010 11:23): Лимит страниц. Продолжаем здесь


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

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

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru