Skip to content

TheLazyCat00/simple-format

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 

Repository files navigation

simple-format

simple-format allows you to search and replace with highlight groups + regex, making it easy to create custom formatting rules. I created this plugin because I wanted a formatter that does not change the whole styling of my code but only removes unnecessary white space.

simple-format.mp4

Installation with lazy.nvim

simple-format does not automatically format on save. Instead, simple-format provides a replace function, which can be called when needed. This allows everybody to have their own formatting logic.

Note

The replace function only modifies the line under the cursor.

{
    "TheLazyCat00/simple-format",
    opts = {
        -- the anchors for search and replace
        -- use uncommon characters or sequences
        injectionOpeningAnchor = "\226\160\128",
        injectionClosingAnchor = "\226\160\129",

        -- the opening and closing tags for the search syntax
        groupStart = "<",
        groupEnd = ">",
    },
    config = function (_, opts)
        local replace = require("simple-format").replace
        replace.setup(opts)

        -- add your own formatting logic
        -- remember to use vim.schedule to prevent neovim from freezing briefly
    end
}

You can also also use the reveal function to inspect the line and see what you need to search for (shown later in my personal config).

Defaults
{
    -- HACK: use uncommon characters as anchors
    injectionOpeningAnchor = "\226\160\128",
    injectionClosingAnchor = "\226\160\129",
    groupStart = "<",
    groupEnd = ">",
}

My personal config

With this config, the plugin always formats when I leave insert mode.

{
    "TheLazyCat00/simple-format",
    event = "BufReadPost",
    opts = {},
    config = function (_, opts)
        local simpleFormat = require("simple-format")
        simpleFormat.setup(opts)
        local replace = simpleFormat.replace

        local function format()
            vim.schedule(function ()
                replace("(<.->) *(<|operator|=.->)","%1 %2")
                replace("(<|operator|=.->) *(<.->)","%1 %2")

                replace("(<.->) *(<|punctuation.delimiter|=,>)", "%1%2")
                replace("(<|punctuation.delimiter|=,>) *(<.->)", "%1 %2")

                replace("(<.-|punctuation.bracket|.-={>) *(<.-|punctuation.bracket|.-=}>)", "%1%2")
                replace("(<.-|punctuation.bracket|.-={>) *(<.*>) *(<.-|punctuation.bracket|.-=}>)","%1 %2 %3")

                replace("(<|punctuation.bracket|=%(>) *(.-) *(<|punctuation.bracket|=%)>)","%1%2%3")
            end)
        end

        vim.api.nvim_create_autocmd("InsertLeave", {
            callback = format,
        })

        vim.api.nvim_create_user_command("Reveal", simpleFormat.reveal, {})
    end
}

Syntax

The syntax for the search and replace arguments have the same syntax as str:gsub in lua. The only difference is that you can also use highlight groups like operator for pattern matching. The syntax goes: groupStart + highlightGroups + "=" + desiredValue + groupEnd. highlightGroups always have | on both the left and right side. So if a word is an operator and a punctuation.bracket the highlightGroups looks like this: |operator|punctuation.bracket|. Let's imagine this "word" would be +. In that case the whole "identifier" would look like this: <|operator|punctuation.bracket|=+>

With the defaults you could for example do <operator=.->. This would match any operator. Here we use regex functionality .- so that we can match for any operator. There are great online resources for learning regex, it's not as hard as it looks. We could also do <operator==>. This would match any operator that has = as its value.

Tip

To see the highlight group under the cursor, do :Inspect.

Examples

These are some useful examples you can use for your own config (assuming you are using the defaults).

  • Formatting lists by putting a space after ,:
    replace("(<|punctuation.delimiter|=,>) *(<.->)", "%1 %2")
    -- Explanation: We wanna search for a punctuation delimiter with
    -- the value ",".
    -- Note that we added .-| and |.- on both sides
    -- so that this works on words with multiple highlight groups
    -- (remember, ".-" matches any string and also empty strings,
    -- so this would work even with only punctuation.delimiter)
    
    -- We need to capture this, so that we can use the value in the replace process:
    -- We do this by putting it in parentheses.
    -- Then we search for a character that is not a white space:
    -- %S means anything that's NOT a white space character (notice the uppercase S).
    -- We also capture this value for later use.
    
    -- Then we replace the string with "%1 %2".
    -- This means that we take capture group 1, put a space and add group 2.
    -- NOTE: Groups get labeled automatically in regex according to the order.
  • Removing spaces between arguments and parentheses:
    -- We need to escape parentheses
    replace("(<|punctuation.bracket|=%(>) *(.-) *(<|punctuation.bracket|=%)>)","%1%2%3")

Contributions are welcome! Feel free to open issues or submit pull requests.

About

Plugin for formatting with custom rules

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages