Align Marked Region on Character

This forum allows you to share scripts with other Zeus users. Please do not post bug reports, feature requests or questions to this forum, but rather use it exclusively for posting scripts or for the discussion of scripts that have been posted.
Post Reply
jussij
Site Admin
Posts: 2650
Joined: Fri Aug 13, 2004 5:10 pm

Align Marked Region on Character

Post by jussij »

This macro below will align a marked region based on a user specified character.

For example given this text:

Code: Select all

long_var_name = 25
var = 5
another_value = 10
assignment = 5
very_long_var_name = 25
Marking the above text, running the macro any typing in the '=' character will result in the text being reformated to read as follows:

Code: Select all

long_var_name      = 25
var                = 5
another_value      = 10
assignment         = 5
very_long_var_name = 25
Here is the Lua macro:

Code: Select all

--      Author: Jussi Jumppanen
--
--    Language: Lua Macro
--
-- Description: This macro will align a marked region based on the user
--              supplied character. You can also selectively control
--              which regions of the line that get aligned by using the
--              column marking mode. This macro alligns to the right.

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

    -- macro only works for read/write documents.
    local locked = is_read_only()

    if (locked == 1) or (document == 0) then
        message("This macro only works for writable document files.");
        beep();
        return;
    end

    -- macro only works for marked documents
    local marked = is_marked()

    if marked == 0 then
        message("This macro requires you to mark a region of text.");
        beep();
        return;
    end

    if marked == 1 then
        -- get the marked text details
        top   = get_marked_top()
        left  = get_marked_left()
        range = get_marked_bottom() - top + 1
    end

    if range > 1 then
        screen_update_disable()

        -- save the current cursor
        cursor_save()

        -- the initial value
        local nill = ""

        -- ask for a user provide the alignment character
        local char_data = user_input("Alignment Character:", nill)

        if char_data ~= nill then
            local cursor = -1

            -- remove the markings
            MarkHide()

            -- move to the fist line of the marked text
            set_line_pos(top, left)

            -- the last line number
            local last = top + range - 1

            -- calculate the maximum index value
            for i = top, last, 1 do
                local text = get_line_text(i)

                local found = string.find(text, char_data, cursor_to_index(i, left), 0)

                if (found ~= nil) then
                    -- look for the maximum cursor location
                    cursor = math.max(index_to_cursor(i, found), cursor)

                    -- message_box(0, text .. " : " .. found .. " f: " .. cursor)
                end
            end

            if (cursor > 1) then
                -- apply the padding to all the lines
                for i = top, last, 1 do
                    text = get_line_text(i)

                    local found = string.find(text, char_data, cursor_to_index(i, left), 0)

                    if (found ~= nil) then
                        local cursor_found = index_to_cursor(i, found)

                        -- position the line and cursor location
                        set_line_pos(i, cursor_found)

                        -- add the pad required
                        print(string.rep(" ", cursor - cursor_found))
                    end
                end
            end
        else
            message("Operation cancelled by user.")
        end

        -- restore original cursor
        cursor_restore()

        screen_update_enable()
        screen_update()
    else
        message("More than one line of text needs to be selected.")
        beep();
    end
end

key_macro() -- run the macro
jussij
Site Admin
Posts: 2650
Joined: Fri Aug 13, 2004 5:10 pm

Post by jussij »

The previous macro would align text on the right where as the macro below aligns text on the left.

To understand what this means consider the following code:

Code: Select all

static final int VALUE_FIELD  =  1;
static final int VALUE_METHOD =  2;
static final int VALUE_STATIC_FIELD     =  4;
static final int VALUE_STATIC_METHOD   =  8;
static final int VALUE_CONSTRUCTOR      = 16;
static final int VALUE_STATIC      = 12;
To alight this code on the '=' character using the right biased first macro we get this result:

Code: Select all

static final int VALUE_FIELD            =  1;
static final int VALUE_METHOD           =  2;
static final int VALUE_STATIC_FIELD     =  4;
static final int VALUE_STATIC_METHOD    =  8;
static final int VALUE_CONSTRUCTOR      = 16;
static final int VALUE_STATIC           = 12;
To alight this code on the '=' character using the left biased macro below we get this result:

Code: Select all

static final int VALUE_FIELD         =  1;
static final int VALUE_METHOD        =  2;
static final int VALUE_STATIC_FIELD  =  4;
static final int VALUE_STATIC_METHOD =  8;
static final int VALUE_CONSTRUCTOR   = 16;
static final int VALUE_STATIC        = 12;
Here is the code for the macro:

Code: Select all

--
--        Name: Left Align Marked Area
--
--      Author: Jussi Jumppanen
--
--    Language: Lua Macro
--
-- Description: This macro will align a marked region based on the user
--              supplied character. You can also selectively control
--              which regions of the line that get aligned by using the
--              column marking mode. This macro alligns to the left.

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

    -- macro only works for read/write documents.
    local locked = is_read_only()

    if (locked == 1) or (document == 0) then
        message("This macro only works for writable document files.");
        beep();
        return;
    end

    -- macro only works for marked documents
    local marked = is_marked()

    if marked == 0 then
        message("This macro requires you to mark a region of text.");
        beep();
        return;
    end

    if marked == 1 then
        -- get the marked text details
        top   = get_marked_top()
        left  = get_marked_left()
        range = get_marked_bottom() - top + 1
    end

    if range > 1 then
        screen_update_disable()

        -- save the current cursor
        cursor_save()

        -- the initial value
        local nill = ""

        -- ask for a user provide the alignment character
        local char_data = user_input("Alignment Character:", nill)

        if char_data ~= nill then
            local cursor = -1

            -- the last line number
            local last = top + range - 1

            -- remove the markings
            MarkHide()

            -- move to the fist line of the marked text
            set_line_pos(top, left)

            -- calculate the maximum index value
            for i = top, last, 1 do
                local text = get_line_text(i)

                local found = string.find(text, char_data, cursor_to_index(i, left), 0)

                if (found ~= nil) then

                    local minimum = found - 1

                    if (minimum > 0) then
                        local value = text:sub(minimum, minimum)
                        while (minimum > 0) and (value == ' ') do
                            -- a better value
                            found = minimum + 1

                            -- keep looking
                            minimum = minimum - 1
                            value = text:sub(minimum, minimum)
                        end
                    end

                    -- look for the maximum cursor location
                    cursor = math.max(index_to_cursor(i, found), cursor)
                end
            end

            if (cursor > 1) then
                -- apply the padding to all the lines
                for i = top, last, 1 do
                    text = get_line_text(i)

                    local found = string.find(text, char_data, cursor_to_index(i, left), 0)

                    if (found ~= nil) then
                        local cursor_found = index_to_cursor(i, found)

                        -- position the line and cursor location
                        set_line_pos(i, cursor_found)

                        if (cursor_found > cursor) then
                            -- rwemove the extra padding
                            for i = 1, cursor_found - cursor, 1 do
                                Backspace()
                            end
                        elseif (cursor_found  < cursor) then
                            -- add the pad required
                            print(string.rep(" ", cursor - cursor_found))
                        end
                    end
                end
            end
        else
            message("Operation cancelled by user.")
        end

        -- restore original cursor
        cursor_restore()

        screen_update_enable()
        screen_update()
    else
        message("More than one line of text needs to be selected.")
        beep();
    end
end

key_macro() -- run the macro
Post Reply