Skip to content

Instantly share code, notes, and snippets.

@weshouman
Last active December 20, 2023 11:15
Show Gist options
  • Save weshouman/a48205ce44c1b58eb27291503c38b61b to your computer and use it in GitHub Desktop.
Save weshouman/a48205ce44c1b58eb27291503c38b61b to your computer and use it in GitHub Desktop.
Nautilus meld extension

This gist is now packaged and maintained at weshouman/nautilus-meld-compare-extension


Nautilus Meld Extension

Overview

This Nautilus extension allows us to easily compare files and directories using the Meld comparison tool directly from the Nautilus context menu. The extension adds new menu items that let you set a "left" file or directory for comparison and then compare a "right" file or directory against it.

Features

  • Set a file or directory as the "left" item for comparison.
  • Compare another file or directory as the "right" item against the previously set "left" item.
  • Directly compare two selected files or directories.

Installation

Prerequisites

  • Ubuntu (or any GNOME-based Linux distribution)
  • Nautilus File Manager
  • Python 3.x
  • Meld
  • Nautilus Python bindings (apt install python3-nautilus)
  • For new Ubuntu releases, for example 23.10, not the case for 22.04: one needs to change the signature of get_file_items from get_file_items(self, window, files) to get_file_items(self, files), fix reference

Steps

  1. mkdir -p ~/.local/share/nautilus-python/extensions/
  2. Place the .py extension file in ~/.local/share/nautilus-python/extensions/.
  3. Restart Nautilus:
    nautilus -q && nautilus --no-desktop
    

Usage

Scenario 1

  • Right-click on a file or directory and choose "Set as Left File to Compare" or "Set as Left Directory to Compare."
  • Right-click on another file or directory to see an option to compare it to the previously set "left" item.

Scenario 2

  • Right-click on 2 files or 2 directories and compre both.
import os
from gi.repository import Nautilus, GObject
class MeldExtension(GObject.GObject, Nautilus.MenuProvider):
def __init__(self):
GObject.Object.__init__(self) # Initialize the GObject type system
self.left_file = None
self.left_dir = None
def menu_activate_cb(self, menu, file1, file2):
os.system(f"meld \"{file1}\" \"{file2}\" &")
def set_left_cb(self, menu, file, is_directory):
if is_directory:
self.left_dir = file
else:
self.left_file = file
def get_file_items(self, window, files):
print(GObject._version)
items = []
if len(files) == 1:
file = files[0]
is_directory = file.is_directory()
left = self.left_dir if is_directory else self.left_file
if left:
item = Nautilus.MenuItem(
name=f"MeldExtension::Compare_{'Dir' if is_directory else 'File'}",
label=f"Compare to '{left.get_name()}'",
tip=f"Compare selected {'directory' if is_directory else 'file'} with the left {'directory' if is_directory else 'file'} using Meld"
)
item.connect("activate", self.menu_activate_cb, left.get_location().get_path(), file.get_location().get_path())
items.append(item)
item = Nautilus.MenuItem(
name=f"MeldExtension::Set_Left_{'Dir' if is_directory else 'File'}",
label=f"Set as Left {'Directory' if is_directory else 'File'} to Compare",
tip=f"Set selected {'directory' if is_directory else 'file'} as the left {'directory' if is_directory else 'file'} for comparison using Meld"
)
item.connect("activate", self.set_left_cb, file, is_directory)
items.append(item)
elif len(files) == 2:
file1, file2 = files
# If both are of the same type
if file1.is_directory() == file2.is_directory():
item = Nautilus.MenuItem(
name="MeldExtension::Compare_Two",
label=f"Compare Selected {'Directories' if file1.is_directory() else 'Files'}",
tip=f"Compare the two selected {'directories' if file1.is_directory() else 'files'} using Meld"
)
item.connect("activate", self.menu_activate_cb, file1.get_location().get_path(), file2.get_location().get_path())
items.append(item)
return items
@weshouman
Copy link
Author

that sounds pretty cool (and even much deeper than my knowledge 😄 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment