Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Allow to use a newline instead of padding #38

Closed
cryptomilk opened this issue Oct 16, 2021 · 14 comments
Closed

[FEATURE] Allow to use a newline instead of padding #38

cryptomilk opened this issue Oct 16, 2021 · 14 comments
Labels
wontfix This will not be worked on

Comments

@cryptomilk
Copy link
Contributor

cryptomilk commented Oct 16, 2021

Hi,

it would be great to have support to comment out code blocks in C using #if 0, like:

#if 0
/* main */
int main(void)
{
    return 0;
}
#endif

The reason is that also comment blocks can be commented out. Sadly the following doesn't work (yet):

ft.set('c', {'/*%s*/', '#if 0\n%s\n#endif'})

Thanks!

@numToStr
Copy link
Owner

numToStr commented Oct 16, 2021

To be honest, I won't be adding any special support for any specific language. And I don't think new lines in block comments would work like you showed. I tried the following and it worked for me.

ft.c = { '/*%s*/', '#if 0%s#endif' }
-- or
ft.set('c', { '/*%s*/', '#if 0%s#endif' })

If you need the desired result you should add an empty line above and below the code and then do the comments.

2021-10-16.20-34-24.mp4

@cryptomilk
Copy link
Contributor Author

You don't have to support a special language, but allow to set it in the filetype config, like:

ft.set({
    lang = 'c',
    line = { '/*%s*/' },
    block = {
        comment =  '#if 0%s#endif',
        padding = false,
        newline = true,
 })

@numToStr
Copy link
Owner

I think you are mixing block comments with something else. And your use case is totally different and have nothing to do with comments. I hope you know that.

@cryptomilk
Copy link
Contributor Author

cryptomilk commented Oct 16, 2021

In the end it comes down to insert a newline instead of some padding. It might be that you want that, that you have:

--[[
ft.set('c', { '/*%s*/', '#if 0%s#endif' })
ft.set('cpp', { '/*%s*/', '#if 0%s#endif' })
--]]

Currently you get:

--[[ ft.set('c', { '/*%s*/', '#if 0%s#endif' })
ft.set('cpp', { '/*%s*/', '#if 0%s#endif' }) --]]

@cryptomilk cryptomilk changed the title [FEATURE] Add support for C #if 0 #endif comment blocks [FEATURE] Allow to use a newline instead of padding Oct 16, 2021
@numToStr
Copy link
Owner

The problem with new lines is that the plugin is now responsible for adding and removing newlines. And honestly, I don't want to deal with newlines for now 😐 .

@numToStr
Copy link
Owner

To cover your original use case. I made some helpers for you. This is not perfect but it's the best I could do.

local Op = require('Comment.opfunc')
local U = require('Comment.utils')
local A = vim.api

local if_def = '#if 0%s#endif'

function _G.___comment_ifdef(vmode, uncomment)
    local srow, erow = U.get_region(vmode)

    if uncomment then
        A.nvim_buf_set_lines(0, srow - 1, srow, false, { '' })
        A.nvim_buf_set_lines(0, erow - 1, erow, false, { '' })
        return
    end

    local new_srow = srow - 1 -- moving one line upwords
    local new_erow1, new_erow2 = erow + 1, erow + 2 -- moving one line downwards

    A.nvim_buf_set_lines(0, new_srow, new_srow, false, { '' })
    A.nvim_buf_set_lines(0, new_erow1, new_erow1, false, { '' })

    local lines = {
        A.nvim_buf_get_lines(0, new_srow, srow, false)[1],
        A.nvim_buf_get_lines(0, new_erow1, new_erow2, false)[1],
    }

    local lcs, rcs = U.unwrap_cstr(if_def)

    Op.blockwise({
        cfg = { padding = true },
        cmode = U.cmode.comment,
        lcs = lcs,
        rcs = rcs,
        srow = srow,
        erow = new_erow2,
        lines = lines,
    })
end

local opts = { noremap = true, silent = true }

-- This is only for comment. Supports dot-repeat
-- Example: gla{ (comment around curly bracket)
A.nvim_set_keymap('n', 'gl', '<CMD>set operatorfunc=v:lua.___comment_ifdef<CR>g@', opts)

-- Comment/Uncomment in visual mode
A.nvim_set_keymap('x', 'gl', '<ESC><CMD>lua ___comment_ifdef(vim.fn.visualmode(), false)<CR>', opts)
A.nvim_set_keymap('x', 'gL', '<ESC><CMD>lua ___comment_ifdef(vim.fn.visualmode(), true)<CR>', opts)

@numToStr numToStr added the wontfix This will not be worked on label Oct 17, 2021
@cryptomilk
Copy link
Contributor Author

cryptomilk commented Oct 17, 2021

I've implemented it using a post hook now:

local A = vim.api
local C = require('Comment.config'):new()
local U = require('Comment.utils')
local ft = require('Comment.ft')

ft.set('c', {'/*%s*/', '#if 0%s#endif'})
ft.set('cpp', {'/*%s*/', '#if 0%s#endif'})

local post_hook = function(ctx)
    if vim.bo.filetype ~= 'c' and vim.bo.filetype ~= 'cpp' and vim.bo.filetype ~= 'lua' then
        return
    end

    if ctx.range.srow == -1 then
        return
    end

    if ctx.ctype == 1 then
        return
    end

    local cfg = C:get()
    local cstr = ft.get(vim.bo.filetype, ctx.ctype)
    local lcs, rcs = U.unwrap_cstr(cstr)
    local padding = U.get_padding(cfg.padding)
    local lines = A.nvim_buf_get_lines(0, ctx.range.srow - 1, ctx.range.erow, false)

    if ctx.cmode == 1 then
        -- comment
        local str = lines[1]
        local i, j = string.find(str, lcs .. padding)
        lines[1] = string.sub(str, i, j - #padding)
        table.insert(lines, 2, string.sub(str, 0, i - 1) .. string.sub(str, j + #padding, #str))

        str = lines[#lines]
        i, j = string.find(str, rcs)
        lines[#lines] = string.sub(str, 0, i - #padding - 1)
        table.insert(lines, #lines + 1, string.sub(str, i, j))
    elseif ctx.cmode == 2 then
        -- uncomment
        if #lines[1] == 0 and #lines[#lines] == 0 then
            table.remove(lines, 1)
            table.remove(lines, #lines)
        end
    end

    vim.api.nvim_buf_set_lines(0, ctx.range.srow - 1, ctx.range.erow, false, lines)
end

require('Comment').setup({
    post_hook = post_hook,
})

The result looks like:

#if 0
/* main */
int main(void)
{
    return 0;
}
#endif

@numToStr
Copy link
Owner

Just curious, Why do you need config in post_hook?

@cryptomilk
Copy link
Contributor Author

I thought I need it to local lcs, rcs = U.parse_cstr(cfg, ctx), but after reading the functions, it isn't needed.

@numToStr
Copy link
Owner

There is also U.unwrap_cstr() that only deals with commentstring. You might wanna use that instead of U.parse_cstr()

@cryptomilk
Copy link
Contributor Author

I already implemented that, see code above ;-)

@cryptomilk
Copy link
Contributor Author

I need access the config to get cfg.padding.

@numToStr
Copy link
Owner

Just call the following to get the config

require('Comment').get_config()

@rr0gi
Copy link

rr0gi commented Oct 31, 2023

seconding support for newlines (it is a personal preference matter ofc)
(thanks for the hook code but would be nice to have it builtin support \n in commentstring)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

3 participants