redguardtoo / diff-lisp

Diff files&strings in pure Emacs Lisp.
GNU General Public License v3.0
6 stars 0 forks source link

Awesome package, how about make it smarter? #2

Closed suliveevil closed 1 year ago

suliveevil commented 1 year ago

I have this Alfred Workflow on macOS:

https://github.com/monkeycz/alfred-fastdiff

fastdiff

It use only one keybinding choose a and b.

The default hotkey is  + \. Step 1, Select a file or text segment then press the hotkey. Step 2, Select another file or text segment then press the hotkey. Well, the vimdiff will be launched in a new tab page of Terminal/iTerm2 and diff your selected.

How to setup diff-lisp like this? Thank you very much!

import os, tempfile, time

tempfile_pool = set()

def get_compare_file_path(query):
    if query and query[0] == "/" and os.path.exists(query):
        return query
    else:
        f = tempfile.NamedTemporaryFile(mode="w", prefix="fastdiff-")
        f.write(query)
        f.flush()
        tempfile_pool.add(f)
        return f.name

def main():
    query = """{query}"""

    if not query:
        print("Please select a file or text segment.")
        return

    transfer_file_path = "/tmp/fastdiff"

    if os.path.exists(transfer_file_path):
        transfer_content = open(transfer_file_path, "r").read()

        a_file_path = get_compare_file_path(transfer_content)
        b_file_path = get_compare_file_path(query)

        if os.path.exists(
            "/Applications/Xcode.app/Contents/Applications/FileMerge.app"
        ):
            os.system(
                """
opendiff "%s" "%s"
            """
                % (a_file_path, b_file_path)
            )
        elif os.path.exists(
            "/Applications/Xcode-beta.app/Contents/Applications/FileMerge.app"
        ):
            os.system(
                """
opendiff "%s" "%s"
            """
                % (a_file_path, b_file_path)
            )
        elif os.path.exists("/Applications/iTerm2.app"):
            os.system(
                """
app_existed=$(cat << EOB >> /tmp/app_existed.scpt; osascript /tmp/app_existed.scpt "ITRM"; rm /tmp/app_existed.scpt;
on run(argv)
    try
        set appCreator to argv as string
    on error
        set appCreator to ""
    end try
    tell application "System Events"
        set appInstances to count (every process whose creator type is appCreator)
        if appInstances > 0 then
            set appExisted to true
        else
            set appExisted to false
        end if
    end tell
    return appExisted
end run
EOB)
$(cat << EOB >> /tmp/launch_iterm2.scpt; osascript /tmp/launch_iterm2.scpt "$app_existed"; rm /tmp/launch_iterm2.scpt;
on run(argv)
    try
        set appExisted to argv as string
    on error
        set appExisted to "true"
    end try
    tell application "iTerm2"
        activate
        if appExisted is "true" then
            set _term to current terminal
            try
                get _term
            on error
                set _term to (make new terminal)
            end try
            tell _term
                launch session "Default"
                set _session to current session
            end tell
        else
            try
                set _session to current session of current terminal
            on error
                set _term to (make new terminal)
                tell _term
                    launch session "Default"
                    set _session to current session
                end tell
            end try
        end if
        tell _session
            write text "vimdiff \\"%s\\" \\"%s\\"; exit;"
        end tell
    end tell
end run
EOB)
            """
                % (a_file_path, b_file_path)
            )
        else:
            os.system(
                """
$(cat << EOB >> /tmp/launch_terminal.scpt; osascript /tmp/launch_terminal.scpt; rm /tmp/launch_terminal.scpt;
on run(argv)
    tell application "Terminal"
        activate
        set currentTab to do script "vimdiff \\"%s\\" \\"%s\\"; exit;"
    end tell
end run
EOB)
            """
                % (a_file_path, b_file_path)
            )
        time.sleep(2)

        os.remove(transfer_file_path)

        print("Get diff `right` context. Diffing...")
    else:
        open(transfer_file_path, "w").write(query)
        print("Get diff `left` content.")

try:
    main()
except Exception as e:
    print("Error: %s" % e)
redguardtoo commented 1 year ago

I don't think diff-lisp is fit for your workflow, it does not provide UI like vimdiff. But there are other packages in Emacs similar to vimdiff

In Emacs, most people use ediff.

You can use Emacs cli, emacs --eval "(ediff-files \"/path/file1\" \"/path/file2\")" to trigger ediff through shell.

suliveevil commented 1 year ago

The point is repeatable/reusable keybinding, not UI or what diff tools to choose 😂

diff

https://github.com/jdtsmith/mlscroll/issues/16#issuecomment-1328165610

suliveevil commented 1 year ago

Take C-x C-d as default keybinding:

First trigger, diff-lisp get A, second trigger, diff-lisp get B.

suliveevil commented 1 year ago
(defvar diff-lisp-set-a-and-b nil)
(defun diff-lisp-set-a-and-b ()
  (interactive)
  (if (eq diff-lisp-set-a-and-b nil)
      (progn
        (diff-lisp-mark-selected-text-as-a)
    (setq diff-lisp-set-a-and-b t)
        )
    (progn
      (diff-lisp-diff-a-and-b)
      (setq diff-lisp-set-a-and-b nil)
      ))
  )
(keymap-global-set "s-/" #'diff-lisp-set-a-and-b)