Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Ghost
    @ghost~5ecbd51dd73408ce4fe4d3e9
    Hi @rvantonder , thank you for the explanation!
    I was interested in a more general solution, but using a fix set of rewrite rules is also a feasible solution in my case.
    Ghost
    @ghost~5ecbd51dd73408ce4fe4d3e9

    The usecase I have is that I'm trying to add some "macros" to Bash, allowing to express stuff more easily with some syntactic sugar. Where I'd use a counter is the following transformation.

    From: (not 100% valid bash)

    function my_fun(a, b, c) {
     ... 
    }

    To: (bash)

    function my_fun() {
      local a=$1
      local b=$2
      local c=$3
      ...
    }
    Rijnard van Tonder
    @rvantonder
    Got it, thanks for sharing. Will keep this in mind when adding new things! I collect these use cases in a doc to help decide what to do next.
    Ghost
    @ghost~5ecbd51dd73408ce4fe4d3e9
    Hi @rvantonder , Is it possible to make this solution https://bit.ly/2XoFLkv work with the case where there's only 1 element in the list? When I add that case, it seems that it matches for all cases: bit.ly/3cB3fqT
    Juan Luis Guerrero Minero
    @juanluelguerre
    @rvantonder , ok, understood. Thanks a lot.
    The point here is create same out path tree (dynamically) if the "comby" already replace something.
    Rijnard van Tonder
    @rvantonder

    Is it possible to make this solution https://bit.ly/2XoFLkv work with the case where there's only 1 element in the list?

    @dodie given the bash context you shared, I lean towards just using the fact that one element is probably an alphanumeric string (so you can use :[[1]]) or alphanumeric and punctuation (use :[1.]), so it won't match across whitespace and thus match all cases. Ex bit.ly/2XZLsVa

    Soon you'll also be able to use regex instead of the syntax above, if the character sets above aren't good enough. There is also another way, but it is more roundabout.

    Ghost
    @ghost~5ecbd51dd73408ce4fe4d3e9
    Thanks!
    Juan Luis Guerrero Minero
    @juanluelguerre
    Hi, Any idea about why a "Timeout" coming up when running COMBY for a folder with one simple .java files (11Kb)? Even if with "-timeout" option to 60secs or 90secs.
    Rijnard van Tonder
    @rvantonder
    Sounds strange :) Care to share your pattern? If not, by any chance does it start with :[_] ...?
    Juan Luis Guerrero Minero
    @juanluelguerre
    Here you are:
    -> :[?string] :[[var]] = ":[? ]:[select] :[query]":[rest] + ":[_]";
    It a simple match to find "SELECT xxx" in .java files to replace it for new best practices sentences :)
    Rijnard van Tonder
    @rvantonder
    Ah OK, cool. So yes I think it is to do with that first :[?string] which is similar to starting a match with :[_] and this is usually not something the pattern actually wants to do. For example, it means here that "potentially match anything or nothing before a :[[var]]", which means a lot of different cases might end up being checked. I'm pretty sure there is a better way to do this--do you have a concrete code to show what type of thing might be optional in the :[?string] :[[var]] part?
    Rijnard van Tonder
    @rvantonder

    For example, I suspect starting with something like this could help:

    String :[[v]] = "SELECT :[_]"

    and then expand it to cover cases where there is append with +, or something more specific inside the SELECT string

    Juan Luis Guerrero Minero
    @juanluelguerre
    Ok, understood, I'm going to review it according your explanations. I'll let you know if I can get it ;) Thanks a lot !
    Sergey Kostyaev
    @s-kostyaev
    Hi all.
    I have a question: how to mathch * as part of hole?
    it doesn't work for me
    I have created simple wrapper for Emacs - https://github.com/s-kostyaev/comby.el
    And now trying to implement simple refactoring for golang like this:
          (defun my-go-extract-function (beg end)
            (interactive "r")
            (let ((default-directory (project-root (project-current)))
                  (sel (buffer-substring-no-properties beg end))
                  (name (read-string "function name: "))
                  (comby-show-changes nil))
              (comby-run (concat "{:[before]" sel ":[after]}")
                         (concat "{:[before]\n" name "()\n:[after]}\n\n"
                                 "func " name "() {\n" sel "\n}")
                         ".go"
                         :changed-file-func #'my-comby-go-after-file-change)))
    
          (defun my-go-extract-method (beg end)
            (interactive "r")
            (let ((default-directory (project-root (project-current)))
                  (sel (buffer-substring-no-properties beg end))
                  (name (read-string "method name: "))
                  (comby-show-changes nil))
              (comby-run (concat "func (:[name] :[type]) :[definition] {:[before]" sel ":[after]}")
                         (concat "func (:[name] :[type]) :[definition] {:[before]\n:[name]." name "()\n:[after]}\n\n"
                                 "func (:[name] :[type]) " name "() {\n" sel "\n}")
                         ".go"
                         :changed-file-func #'my-comby-go-after-file-change)))
    Sergey Kostyaev
    @s-kostyaev
    first one works good enough. But second one creates new method with value receiver instead of pointer receiver (a MyType) instead of (a *MyType)
    Matching * works outside of the [hole], but I would like to use it for both pointer receiver and value receiver)
    Sergey Kostyaev
    @s-kostyaev
    And thank you for this cool project!
    Rijnard van Tonder
    @rvantonder

    Hey @s-kostyaev that looks really cool! Could you give an example of the match template and code that don't work for you when trying to match *? It works for me and in the playground (example: https://bit.ly/312dXEJ), and I'm wondering if maybe the way that the pattern is constructed in this part is maybe not doing what's expected:

    func (:[name] :[type]) :[definition] {:[before]" sel ":[after]}

    Like, maybe this concatenation of sel and before/after is causing some problem.

    Just another debugging though, the other thing to check is to make sure to invoke comby to parse the file or selection as Go
    Rijnard van Tonder
    @rvantonder
    For making sure the file is parsed with the right parser, it is safe to assume you can use the file extension and pass it like -matcher .go or -matcher .py. If comby doesn't recognize the extension, you can use -matcher .generic.
    sogaiu
    @sogaiu
    @s-kostyaev comby.el looks neat -- thanks for making and sharing it!
    Sergey Kostyaev
    @s-kostyaev
    I have found the root of my problem. It match first definition of method. Can I make :[prevCode] greedy?
    Rijnard van Tonder
    @rvantonder
    I'm not sure I follow, do you need :[prevCode] for something? You can ignore the things to not match by using just the match template starting with func. If I'm missing something can you explain what you're trying to get in the result?
    Example, without :[prevCode] bit.ly/3hL9V9X
    OK I think I follow what the problem is, if you want that match template to match each function
    Sergey Kostyaev
    @s-kostyaev
    I want to match last one before v.Y = v.Y * f - the selection in that case
    Rijnard van Tonder
    @rvantonder
    Yep, the issue is with using returnValues. What you're looking for is the smallest match (closes), but the holes used here will continue matching more, from left-to-right (and returnValues captures things you're not interested in). In general, this is not a question of greediness/laziness, even if returnValues was greedy, the semantics means that it will continue matching left to right, just like .* and .*? does not mean it will match the smallest (tightest) matching string: https://stackoverflow.com/a/21478871
    In general, with the regex problem, you can either use lookahead/look-behind (if the engine supports it) or try make matching more restricted. Usually it is complex and problematic to use lookahead/lookbehind.
    So then the question is what can we do about this in Comby? Based on what is currently possible, my suggestion is to restrict matches. What this means is that you will unfortunately need to use multiple match templates, but all of them together will precisely match what you care about (for function extraction/rewriting and so on).
    Sergey Kostyaev
    @s-kostyaev
    So I can't write "general match pattern" for this case?
    Rijnard van Tonder
    @rvantonder

    These three variants, together, will give you precise matches:
    func (:[name] :[type]) :[methodName.](:[args]) {:[body]}
    func (:[name] :[type]) :[methodName.](:[args]) :[[return]] {:[body]}
    func (:[name] :[type]) :[methodName.](:[args]) (:[multipleReturns]) {:[body]}

    This will guarantee that methodName matches identifiers and not across lines/whitespace. We need three variants to match the three syntactic variants that are possible for Go return values (nothing, one value, or many).

    So I can't write "general match pattern" for this case?

    I don't think it's possible to do that with Comby's current capabilities. I know the multi-pattern thing is awkward, but optional holes are not good enough to deal with this problem

    The good news I can offer is that I'll soon at regular expressions to holes, and then you should be able to right one general pattern, as follows:
    Sergey Kostyaev
    @s-kostyaev

    The good news I can offer is that I'll soon at regular expressions to holes, and then you should be able to right one general pattern

    I look forward to it

    For now I can try to implement look-behind on Emacs side and use one of this 3 patterns. Thank you.
    Rijnard van Tonder
    @rvantonder

    Ok :-) Just to show you what the regex solution would look like, you would do something like this to match the optional receiver part:

    func (:[receiver]) :[[method]](:[args]) :[ret~[\w\s,()]*]{:[body]}

    In this case the ret hole matches the regex [\w\s,()]*, so something that 'looks like' a return value, and is optional. Of course, you will lose the structural properties of matching balanced things here, so it is good to be careful, but it would work well in this case.

    it is possible to use on the https://staging.comby.live server, here's the example:

    This message was deleted
    Whoops that link won't work it doesn't use staging.
    Ok sorry about this, but just go to this link and make it point to staging.comby.live instead of comby.live: bit.ly/3fPQM4z (I'll fix the link sharing here later)
    If you build from source you can also develop against this regex-supported version of comby, you can grab it from this branch: comby-tools/comby#162. The syntax works like I described, the only reason I haven't merged it yet is because there are some whitespace cases to fix.
    Sergey Kostyaev
    @s-kostyaev
    Thank you) I think I'll try this branch.
    Rijnard van Tonder
    @rvantonder
    Sounds good :-)
    Hopefully I can release this in the next week or two 🤞
    Sergey Kostyaev
    @s-kostyaev
    Will wait)
    Rijnard van Tonder
    @rvantonder
    Ok, I can ping you and I'll let you know. Otherwise, I can just release/merge soon and fix the missing parts after, as they are fairly specific and not so important to handle.
    Sergey Kostyaev
    @s-kostyaev
    As you wish) I already subscribed to this PR.