Page 1 of 1

Align Marked Region on Character

Posted: Tue Jun 21, 2011 3:52 am
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

Posted: Mon Sep 24, 2012 6:09 am
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