yaroslavyaroslav/Diffable

Calling diffable inline from custom command

Closed this issue · 5 comments

I'm trying to show all inline diffs after calling the diffable command with argument inline. Like this I think it's easier to compare two files, because from default I'll only see a yellow line in front of each changed line.

{
  "keys": ["ctrl+alt+d"],
  "command": "chain",
  "args": {
    "commands": [
      ["diffable", {"action": "inline"}],
      ["select_all"],
      ["toggle_inline_diff"]
    ]
  }
}

With the key map I want to call the diffable command with the inline argument, select the whole text and then toggle the inline diffs. Sadly the diffable command doesn't do anything. If I call diffable with clear, then it works fine.

Selecting the text and toggling the inline diffs also works fine.

Maybe you know why ["diffable", {"action": "inline"}] doesn't work. Also it could be an option for the plugin to automatically show all inline diffs.

Yeah, there's such spontaneous discussion in sibling issue arisen already, with quite like this solution as a work around.

Actually I saw this way of chaining ST commands on a user side for the first time, thanks for highlighting that here, so I need to dug in to how it works under the hood and to figure out why it fails. First guess is that ST don't knows on what of 2 buffers it should apply the select_all and toggle_inline_diff commands.

The select_all and toggle_inline_diff is working fine. I just can't get ["diffable", {"action": "inline"}] to work.
If I create something like this:

{
  "keys": ["ctrl+alt+d"],
  "command": "chain",
  "args": {
    "commands": [
      ["diffable", {"action": "clear"}],
      ["select_all"]
    ]
  }
}

Then it clears the created diffs and selects the text (for sure this doesn't make sense it was just for testing)

Calling this also works fine (at least for the currently selected file)

{
  "keys": ["ctrl+alt+d"],
  "command": "chain",
  "args": {
    "commands": [
      ["select_all"],
      ["toggle_inline_diff"]
    ]
  }
}

This is a wired shit happening here. The JSON bellow never gets diffable run function called, even though is_enabled function within the same class yields on each keypress with True response. But if just drop the toggle_inline_diff command from this chain it starts working well. So firstly I can not confirm your claim that it's the specific attribute related issue.

{
  "keys": ["ctrl+alt+d"],
  "command": "chain",
  "args": {
    "commands": [
      ["diffable"],
      ["select_all"],
      ["toggle_inline_diff"] // drop me and everything goes well.
    ]
  }
},

Tbh, I have no effort to debug this one further, error descriptiveness certainly never was a strong part of ST.

So I just put this very sequence in the plugin instead, there where I have better control over execution flow. I think this would be released within 2 weeks regarding my current work load.

Also, if you have enough efforts and passion about that, you a more than welcome to provide a PR with that chain by yourself, the plugin code is just a few lines of code and its logic is straightforward.

I'm not sure how to do a pull request, but I found a working solution for the problem.
This is the solution:

In Diffable.sublime-settings I've added this code:

// If the diff hunks should be visible automatically
// - If true, diff hunks will be visible (depends on `two_panes_mode` and `left_to_right`)
// - If false, diff hunks wont be visible on default
// used for inline mode
// calling diffable again hides the diff hunks
"toggle_diff_hunks": true,

In diffable.py I've added this function:

def toggle_inline_diff(self, view):
    sel = view.sel()
    old_sel = list(sel)
    sel.clear()
    sel.add(Region(0, view.size()))
    view.run_command("toggle_inline_diff", {"args": {"prefer_hide": True}})
    sel.clear()
    sel.add_all(old_sel)

And this is how I used the function:

if action == 'inline':
    if self.settings.get("two_panes_mode"):
        view_2.set_reference_document(text_left)
        view_1.set_reference_document(text_right)
        if self.settings.get("auto_show_diff_hunks"):
            self.toggle_inline_diff(view_2)
            self.toggle_inline_diff(view_1)
        
    else:
        if self.settings.get("left_to_right"):
            view_2.set_reference_document(text_left)
            if self.settings.get("auto_show_diff_hunks"):
                self.toggle_inline_diff(view_2)
        else:
            view_1.set_reference_document(text_right)
            if self.settings.get("auto_show_diff_hunks"):
                self.toggle_inline_diff(view_1)

I hope this helps.

Thanks a lot, I try to paste it and test during this week