Page 1 of 1

Brace Match Find and Select

Posted: Sun Aug 12, 2012 6:38 am
by jussij

Code: Select all

--
--        Name: Matching Brace Select
--
--    Language: Lua Macro
--
-- Description: This Lua macro will try to find the nearest brace character
--              and then select the region from the that brace character to
--              the matching brace character.
--

function find_brace()
    found = 0

    char_current  = get_char_at()
    char_previous = '\0'

    if get_cursor_pos() > 1 then
        char_previous = get_char_at(get_line_pos(),get_cursor_pos()-1)
    end

    -- position the cursor for the brace match that follows
    if char_current  == string.byte('(') or
       char_current  == string.byte('<') or
       char_current  == string.byte('[') or
       char_current  == string.byte('{') then
          found = 1
    elseif
       char_current  == string.byte(')') or
       char_current  == string.byte('>') or
       char_current  == string.byte(']') or
       char_current  == string.byte('}') then
          found = 1
    elseif
       char_previous == string.byte(')') or
       char_previous == string.byte('>') or
       char_previous == string.byte(']') or
       char_previous == string.byte('}') then
          found = 1
    end

    if found == 0 then
        search_options_save()
        REVERSE = 1
        set_search_option("UseCase"   , 0)
        set_search_option("WholeWord" , 1)
        set_search_option("RegExpress", 0)
        set_find_text("{")
        if SearchPrevious() == 1 then
            MoveLineRight()
            found = 1
        end

        if found == 0 then
            set_find_text("{")
            if SearchPrevious() == 1 then
                MoveLineRight()
                found = 1
            end
        end

        if found == 0 then
            set_find_text("<")
            if SearchPrevious() == 1 then
                MoveLineRight()
                found = 1
            end
        end

        if found == 0 then
            set_find_text("(")
            if SearchPrevious() == 1 then
                MoveLineRight()
                found = 1
            end
        end
        search_options_restore()
    end
end

function key_macro()
    -- macro only works for documents
    local document = is_document()

    if document > 0 then
        screen_update_disable()

        -- save the char_current cursor details
        cursor_save()

        -- look for the nearest brace
        find_brace()

        char_current = get_char_at()
        char_previous = '\0'

        if get_cursor_pos() > 1 then
            char_previous = get_char_at(get_line_pos(),get_cursor_pos()-1)
        end

        -- position the cursor for the brace match that follows
        if char_current  == string.byte('(') or
           char_current  == string.byte('<') or
           char_current  == string.byte('[') or
           char_current  == string.byte('{') then
              MoveLineRight()
        elseif
           char_previous == string.byte(')') or
           char_previous == string.byte('>') or
           char_previous == string.byte(']') or
           char_previous == string.byte('}') then
              MoveLineLeft()
        end

        -- turn on marking
        MarkBlockSet()

        -- look for a matching brace
        if BraceMatch() == 1 then
            -- ignore the saved cursor details
            cursor_ignore()

            -- see where we ended up
            char_current = get_char_at()
            char_previous = '\0'

            if get_cursor_pos() > 1 then
                char_previous = get_char_at(get_line_pos(), get_cursor_pos() - 1)
            end

            -- position the cursor inside the brace chracters found
            if char_current  == string.byte('(') or
               char_current  == string.byte('<') or
               char_current  == string.byte('[') or
               char_current  == string.byte('{') then
                  MoveLineRight()
            elseif
                char_previous == string.byte(')') or
                char_previous == string.byte('>') or
                char_previous == string.byte(']') or
                char_previous == string.byte('}') then
                  MoveLineLeft()
            end

            -- marking is done
            MarkBlockReset()
         else
            -- restore the cursor as no matching brace was found
            cursor_restore()

            -- remove the marking
            MarkHide()
         end

        screen_update_enable()
        screen_update()
    else
        message("This macro only works for document files.")
        beep()
    end
end

key_macro() -- run the macro