C# Auto-complete for New Objects

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

C# Auto-complete for New Objects

Post by jussij »

This macro will attempt to auto-complete the C# new statement.

So for example give this code (where | indicates the cursor):

Code: Select all

   private static Dictionary<String, int> fs = new|
On hitting the space bar this macro will auto expand the new to be this code:

Code: Select all

   private static Dictionary<String, int> fs = new Dictionary<String, int>(|);
To use this macro edit the C# document type and in the Templates section add a new template with these details:

Code: Select all

       Keyword: new
     Menu Text: New Autocomplete
Expansion Text: $MacroExcute<auto_new.lua>
The macro code is shown below. That code should be saved to the auto_new.lua file in the Zeus zScript folder.

Code: Select all

--
--        Name: C# New Completion
--
--      Author: Jussi Jumppanen
--
--    Language: Lua Macro
--
-- Description: This macro will try to complete the new keyword by adding
--              the type value automatically.
--
--  How To Run: To use this macro define a template in the C# document
--              type using these values:
--
--                         Keyword: new
--                       Menu Text: new autocomplete
--                  Expansion Text: $MacroExcute<auto_new.lua>
--
function trim(s)
    if s ~= nil then
        -- trim the string
        s = s:gsub("^%s*(.-)%s*$", "%1")
    end
    return s
end

function check_trailing(s)
    -- clean the string
    s = trim(s)

    -- the simple test
    if (s == nil) or (string.len(s) == 0) then
        return true
    end

    -- don't trigger on trailing characters but for some few exceptions
    if string.len(s) == 1 then
        local found = string.find(";)", s)

        if (found ~= nil) then
            -- accept these characters
            return true
        end
    end

    return false
end

-- look for the argument in the statement
function find_argument(statement)
    local argument = nil

    if statement ~= nil then
        statement = trim(statement)

        -- watch out for generic items
        if string.match(statement, "<") ~= nil then
            --
            -- Example: 'private static Dictionary<String, int> fs'
            --
            -- look for the complex case first
            argument = string.match(statement, ".*%s(.*<.*>)%s.+")

            if argument == nil then
                --
                -- Examples: 'Dictionary<String, int> fs'
                --
                -- look for the simpler case
                argument = string.match(statement, "(.*<.*>)%s.+")
            end
        else
            --
            -- Example: 'public static FileStream fs'
            --
            -- look for the complex case first
            argument = string.match(statement, ".*%s(.*)%s.+")

            if argument == nil then
                --
                -- Examples: 'FileStream fs'
                --
                -- look for the simpler case
                argument = string.match(statement, "(.*)%s.+")
            end
        end
    end
    return argument
end

function key_macro()
    -- Typical Examples:
    --    FileStream fs = new FileStream();
    --    public FileStream fs = new FileStream();
    --    private FileStream fs = new FileStream();
    --    public static FileStream fs = new FileStream();
    --    private static FileStream fs = new FileStream();
    --    private static List<String> fs = new List<String>();
    --    private static Dictionary<String, int> fs = new Dictionary<String, int>;
    --
    -- NOTE: For the case of a using case statment we do specail close brace processing.
    --   using (StreamWriter writer = new StreamWriter())
    --
    local line_text = get_line_text();

    -- see if the line contains the 'new' keyword
    local has_new, trailing = string.match(line_text, "^%s*(.*)%s*=%s*new(.*)%s*")

    -- see if we found something and also check the trailing string
    if has_new ~= nil and check_trailing(trailing) == true then
        local argument = nil

        -- look for the argument
        local argument = find_argument(has_new)

        if argument ~= nil and string.len(argument) > 0 then
            local eol = ";"

            -- don't add a semi-colon if it's already there
            if trim(trailing) == ";" then
                eol = ""
            end

            -- watch out for the using case
            if string.match(has_new, "%s*using %(") ~= nil then
                -- remove the errant brace
                argument = string.match(argument, "%((.*)")

                -- set the end of line character but watching out for using
                if string.match(trailing, "%)") ~= nil then
                    eol = ""
                else
                    eol = ")"
                end
            end

            if argument ~= nil and string.len(argument) > 0 then
                if string.sub(argument, -1) == "]" then
                    -- Handle these cases:
                    --    byte[] retByteArr = new;
                    --    byte[] retByteArr = new byte[|];
                    --    byte[,] retByteArr = new;
                    --    byte[,] retByteArr = new byte[|,];

                    -- split the argument at the first open brace
                    head, tail = string.match(argument, "(.*)%[(.*)")

                    if head ~= nil and tail ~= nil then
                        -- position the \c cursor location in the middle of the braces
                        print("new " .. head .. "[\\c" .. tail .. eol)
                    else
                        -- output the details using \c to show the cursor location
                         print("new " .. argument .. eol .. "\\c")
                    end
                else
                    -- output the details using \c to show the cursor location
                    print("new " .. argument .. "(\\c)" .. eol)
                end
            else
                -- write out the trigger
                print("new ")
            end
        else
            -- write out the trigger
            print("new ")
        end
    else
        -- write out the trigger
        print("new ")
    end
end

key_macro() -- run the macro
Cheers Jussi
Post Reply