Skip to content

Support advanced multiline strings in lua e.g. --[=[ something ]=] #7

Closed

Description

@Corey-Keller

Just from reading the readme it sounds like this might be possible using the pre_hook, but I'm not sure exactly how I'd go about it.

I have copied the text below from my kommentary request for the same functionality (b3nj5m1n/kommentary#67)


Lua supports semi-arbitrary multiline comment strings in the form of matching numbers of equals signs. Meaning --[==[, --[===[, and --[=[ will only end the comment when it encounters ]==], ]===], and ]=] respectively.

It would be a great idea to match an opening regex like --\[\(=*\)\[ (or --\[(=*)\[ in PCRE style just to make sure it's clear) to the closing ]\1] (using the capture group from the opening regex to guarantee the same number of =)

This may not be as important when creating the comments, but is important to effectively uncomment them.

Activity

  1. numToStr commented on Oct 7, 2021

    @numToStr
    Owner

    Honestly, when I was searching through kommentary issues, I saw your request there 😄 .

    Currently, I also don't know how to solve this but this is certainly going to be fun to implement. Would you mind sharing any kind of guide where I can read more about those comments?

  2. Corey-Keller commented on Oct 7, 2021

    @Corey-Keller
    Author

    Honestly, when I was searching through kommentary issues, I saw your request there smile .

    Currently, I also don't know how to solve this but this is certainly going to be fun to implement. Would you mind sharing any kind of guide where I can read more about those comments?

    It's actually a string feature that applies to any string in double brackets [[ like this one ]], which lua just extends to block comments.

    [===[ This lets me put '[[', ']=]', or ']======]' (or any double bracket with 0+ '=' in the middle, so long as it's not the same as the surrounding one) inside this string without issue. ]===]

    http://lua-users.org/wiki/StringsTutorial

  3. numToStr commented on Oct 7, 2021

    @numToStr
    Owner

    Interesting I'll try to implement this. Once I handled some edge cases in the current logic. I'll update here once I start working on it :)

  4. kylechui commented on Aug 6, 2022

    @kylechui

    Hi there, I'm a big fan of this plugin and would very much like to have this as a feature; far too many times I've decided to comment out a few lines just to find that some nested comment breaks compatibility. I don't really know much about the internal code structure, but I'm willing to try my hand at making this a reality. AFAIK Lua patterns aren't PCRE, but I was playing around with the Tree-sitter playground and think that if you converted a comment to a single string, you could pattern-match it like the following:

    -- Extract the comment text from a Tree-sitter node
    local comment = "--[[ some comment\nmore text\n ]=]"
    -- Match it and capture the amount of equal signs
    local ok, _, open, close = comment:find("^--%[(=*)%[.-%](=*)%]$")
    -- Check if a match is found, and if the equals signs are "balanced"
    if ok and (#open == #close) then
        local count = #open + 1
        local comment = {
            "--[" .. ("="):rep(count) .. "[",
            "]" .. ("="):rep(count) .. "]",
        }
    end

    Obviously it would be a lot more involved, but hopefully somebody could give me a few pointers around the codebase?

  5. numToStr commented on Aug 6, 2022

    @numToStr
    Owner

    The main reason that I didn't make the commenstring, inside the plugin, regex based because I need compatibility and ability to fallback to vim.bo.commenstring. And sometimes I also need the actual length of the left and right side the commenstring for string.sub. Which results to, obviously, no regex and pattern matching.

    I think, the only way to pull this off is using pre_hook and vim.v.count (to control the no. of =)

  6. kylechui commented on Aug 6, 2022

    @kylechui

    I don't think I'm quite following why having vim.bo.commenstring as a fallback implies that pattern matching is infeasible. As for your other point, would finding the length of the match groups in str.find not find the lengths of the left/right comment pair for you? I hope I'm not coming across as rude, I'm just trying to better understand the situation

  7. numToStr commented on Aug 7, 2022

    @numToStr
    Owner

    I don't think I'm quite following why having vim.bo.commenstring as a fallback implies that pattern matching is infeasible. As for your other point, would finding the length of the match groups in str.find not find the lengths of the left/right comment pair for you?

    I was wrong about the length and string.sub part. After taking a another look in the code; the reason the left/right part should be kept static is to be able to comment the line initially. https://github.com/numToStr/Comment.nvim/blob/master/lua/Comment/utils.lua#L195

    And I believe your, earlier, snippet doesn't consider the initial commenting.

    I hope I'm not coming across as rude, I'm just trying to better understand the situation

    Nope, not at all. On the contrary, i quite enjoy a healthy discussion.

  8. kylechui commented on Aug 7, 2022

    @kylechui

    After taking a another look in the code; the reason the left/right part should be kept static is to be able to comment the line initially.

    Oh wow this is a bit similar to the internals for my plugin haha. I'm afraid I still don't quite get why the left/right part has to be static in order to comment the line; the code snippet you sent seems like it would work just fine if the left/right were different, since you're just appending strings to the beginning/end of a table.

  9. numToStr commented on Aug 7, 2022

    @numToStr
    Owner

    the code snippet you sent seems like it would work just fine if the left/right were different, since you're just appending strings to the beginning/end of a table.

    I don't think so, let me ask you how would you append a pattern i.e "^--%[(=*)%.-%%]$" to a string/line? Just curious.

  10. kylechui commented on Aug 7, 2022

    @kylechui

    Ah, let me try and rephrase what my initial idea was:

    • The user passes in some selection and calls one of the commenting functions
    • The plugin traverses the selection for all nodes of type comment that are contained in the selection, and uses Lua pattern-matching to discern how many equals signs there are in the open/closing comment block (0 or more)
    • The plugin computes what's the first unused number, then creates a new static string pair based on it
    • The plugin surrounds the text selection with the comment pair

    Sorry if I'm still misunderstanding the underlying code structure (and so over-simplifying the problem), but this is just one of the ideas that I thought of

  11. numToStr commented on Aug 7, 2022

    @numToStr
    Owner

    The plugin traverses the selection for all nodes of type comment that are contained in the selection, and uses Lua pattern-matching to discern how many equals signs there are in the open/closing comment block (0 or more)

    I am assuming you are talking about treesitter for nodes calculation; Inside the plugin treesitter is only used for calculating embedded language and this sounds way more work. And about the pattern, I have to store the pattern and I have to remind myself of the use-case.

    So TBH, everything sounds complicated and requires more maintenance on my end (for something that I probably never use).

    Anyway, here is a brief architecture of the plugin

    - start
    
    - Pick commentstring either linewise/blockwise from one of the following places 
        1. pre_hook (if string is returned)
        2. stored inside the plugin using treesitter
        3. vim.bo.commentstring
    
    > Every is_comment check below is made using the commentstring calculated in the above step
    
    - Checking the range
        - when linewise
            1. if every line is commented
                1.1 uncomment
    
            2. else
                2.1 find the column no. to start the comment from (need to respect the indentation)
                2.2 comment
    
        - when blockwise
            1. if the first line or start of the block is commented with LHS
               and the last line or end of the block is commented with RHS
               1.1 uncomment
    
            2. else
                2.1 Prepend the LHS into the first line
                2.2 Append the RHS into the last line
    
        > When doing visual block I can't preprend or append,
        > so in this case we need to slice and concat the line,
        > putting RHS and LHS into right place when doing comment
        > and removing LHS and RHS when uncomment
    
    - end
    

    Edit: I hope this will give you an idea of how things are implemented inside the plugin :)

  12. kylechui commented on Aug 7, 2022

    @kylechui

    Thanks for the high-level description! Yeah it does seem like quite a bit of extra work, especially because it seems like this would need to be "hard-coded" to a certain extent for Lua in particular. I can't really think of any other programming languages at the moment that have this sort of behavior. Your point about code maintenance makes sense; thanks for taking the time to explain your thought processes and for such a great plugin!

  13. numToStr commented on Aug 13, 2022

    @numToStr
    Owner

    I am moving this from issues to discussion for other people to come up with solution for this. As I think it might be not feasible to support this natively.

  14. Repository owner locked and limited conversation to collaborators on Aug 13, 2022
  15. converted this issue into a discussion #203 on Aug 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew featurehelp wantedExtra attention is needed

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions