Compare commits

..

13 commits

Author SHA1 Message Date
Till Friebe
d566ded402 Release version 1.1.2 2025-08-24 02:52:13 +02:00
Till Friebe
7bd7dd41c0
Merge pull request #20 from TheJusticeMan/master
fixed the colors
2025-08-24 01:41:54 +02:00
Justice Vellacott
185f95f30a I fixed the colors using the css mix function it'll now work on any theme. 2025-08-03 22:23:57 -04:00
friebetill
08e488d425 Release version 1.1.1 2024-02-15 13:39:30 +07:00
Till Friebe
ac4ea85fe0
Merge pull request #13 from blainelewis1/patch-1
Fix bug where files have same name but differing paths
2024-02-15 13:38:53 +07:00
Blaine Lewis
00567dea68
fix bug where files have same name but differing paths 2024-02-08 10:25:22 -05:00
Till Friebe
ad651d827e
Add SyncThing link 2023-11-08 12:52:26 +01:00
friebetill
dd31d3d371 Release version 1.1.0 2023-11-08 02:39:49 +01:00
friebetill
5426feb1e1 Update locked packages 2023-11-08 02:39:03 +01:00
friebetill
fa81f5dd62 Show word differences 2023-11-08 02:37:20 +01:00
friebetill
6cb64e9743 ISSUE-10: Fix diff for some files 2023-11-06 22:16:25 +01:00
friebetill
e51806b299 11: Don't open result page after deletion 2023-11-06 21:16:52 +01:00
Till Friebe
5e3c691266
Remove link to official plugin merge request 2023-05-03 16:37:27 +02:00
9 changed files with 742 additions and 494 deletions

View file

@ -1,6 +1,6 @@
# Obsidian File Diff
<!-- [![Obsidian Downloads](https://img.shields.io/badge/dynamic/json?color=7e6ad6&labelColor=34208c&label=Obsidian%20Downloads&query=$['file-diff'].downloads&url=https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugin-stats.json&)](obsidian://show-plugin?id=file-diff) -->
[![Obsidian Downloads](https://img.shields.io/badge/dynamic/json?color=7e6ad6&labelColor=34208c&label=Obsidian%20Downloads&query=$['file-diff'].downloads&url=https://raw.githubusercontent.com/obsidianmd/obsidian-releases/master/community-plugin-stats.json&)](obsidian://show-plugin?id=file-diff)
![GitHub stars](https://img.shields.io/github/stars/friebetill/obsidian-file-diff?style=flat)
## Commands
@ -17,17 +17,10 @@ alt="GIF of a demo show this plugin" width="900" />
## Motivation
I created this plugin because I use SyncThing and it bothered me to clean up merge conflicts by hand.
I created this plugin because I use [SyncThing](https://syncthing.net/) and it bothered me to clean up merge conflicts by hand.
## Installation
At the moment, the [plugin is in review to be an official plugin](https://github.com/obsidianmd/obsidian-releases/pull/1621) (add a like to get it merged faster). Therefore, it must be installed manually:
1. Download the `main.js`, `styles.css` and `manifest.json` from [the latest release](https://github.com/friebetill/obsidian-file-diff/releases/latest)
2. Move the files to the plugin folder `VaultFolder/.obsidian/plugins/obsidian-file-diff/`
When the plugin is officially release you can follow these steps to install the plugin:
1. Search for "File Diff" in the community plugins of Obsidian
2. Install the plugin
3. Enable the plugin

View file

@ -1,7 +1,7 @@
{
"id": "file-diff",
"name": "File Diff",
"version": "1.0.13",
"version": "1.1.2",
"minAppVersion": "0.15.0",
"description": "Shows the differences between two files..",
"author": "Till Friebe",

View file

@ -1,6 +1,6 @@
{
"name": "obsidian-file-diff",
"version": "1.0.13",
"version": "1.1.2",
"description": "Shows the differences between two files.",
"main": "main.js",
"scripts": {

View file

@ -1,4 +1,4 @@
import { structuredPatch } from 'diff';
import { structuredPatch, diffWords } from 'diff';
import { ItemView, TFile, ViewStateResult, WorkspaceLeaf } from 'obsidian';
import { Difference } from '../data/difference';
import { FileDifferences } from '../data/file_differences';
@ -43,8 +43,6 @@ export class DifferencesView extends ItemView {
private file2Lines: string[];
private lineCount: number;
private wasDeleteModalShown = false;
override getViewType(): string {
@ -88,10 +86,11 @@ export class DifferencesView extends ItemView {
// Add trailing new line as this removes edge cases
.concat('\n')
.split('\n')
// Streamline empty lines at the end as this remove edge cases
// Streamline empty spaces at the end as this remove edge cases
.map((line) => line.trimEnd());
this.file2Lines = this.file2Content
// Add trailing new line as this removes edge cases
// Add trailing new spaces as this removes edge cases
.concat('\n')
.split('\n')
// Streamline empty lines at the end as this remove edge cases
@ -105,18 +104,6 @@ export class DifferencesView extends ItemView {
);
this.fileDifferences = FileDifferences.fromParsedDiff(parsedDiff);
this.lineCount = Math.max(
this.file1Lines.length -
// Count each difference as one line
this.fileDifferences.differences.filter(
(d) => d.file1Lines.length > 0
).length,
this.file2Lines.length -
// Count each difference as one line
this.fileDifferences.differences.filter(
(d) => d.file2Lines.length > 0
).length
);
}
private build(): void {
@ -142,7 +129,8 @@ export class DifferencesView extends ItemView {
private buildLines(container: HTMLDivElement): void {
let lineCount1 = 0;
let lineCount2 = 0;
while (lineCount1 <= this.lineCount || lineCount2 <= this.lineCount) {
const maxLineCount = Math.max(this.file1Lines.length, this.file2Lines.length)
while (lineCount1 <= maxLineCount || lineCount2 <= maxLineCount) {
const difference = this.fileDifferences.differences.find(
// eslint-disable-next-line no-loop-func
(d) =>
@ -176,11 +164,6 @@ export class DifferencesView extends ItemView {
container: HTMLDivElement,
difference: Difference
): void {
const triggerRebuild = async (): Promise<void> => {
await this.updateState();
this.build();
};
if (this.state.showMergeOption) {
new ActionLine({
difference,
@ -188,29 +171,86 @@ export class DifferencesView extends ItemView {
file2: this.state.file2,
file1Content: this.file1Content,
file2Content: this.file2Content,
triggerRebuild,
triggerRebuild: async (): Promise<void> => {
await this.updateState();
this.build();
},
}).build(container);
}
// Draw top diff
for (let i = 0; i < difference.file1Lines.length; i += 1) {
const line = difference.file1Lines[i];
container.createDiv({
// Necessary to give the line a height when it's empty.
text: preventEmptyString(line),
cls: 'file-diff__line file-diff__top-line__bg',
});
const line1 = difference.file1Lines[i];
const line2 = difference.file2Lines[i];
const lineDiv = container.createDiv({ cls: 'file-diff__line file-diff__top-line__bg' });
const diffSpans = this.buildDiffLine(line1, line2, 'file-diff_top-line__character');
// Remove border radius if applicable
if (i < difference.file1Lines.length - 1 || difference.file2Lines.length !== 0) {
lineDiv.classList.add('file-diff__no-bottom-border');
}
if (i !== 0) {
lineDiv.classList.add('file-diff__no-top-border');
}
lineDiv.appendChild(diffSpans);
}
// Draw bottom diff
for (let i = 0; i < difference.file2Lines.length; i += 1) {
const line = difference.file2Lines[i];
container.createDiv({
// Necessary to give the line a height when it's empty.
text: preventEmptyString(line),
cls: 'file-diff__line file-diff__bottom-line__bg',
});
const line1 = difference.file1Lines[i];
const line2 = difference.file2Lines[i];
const lineDiv = container.createDiv({ cls: 'file-diff__line file-diff__bottom-line__bg' });
const diffSpans = this.buildDiffLine(line2, line1, 'file-diff_bottom-line__character');
// Remove border radius if applicable
if ((i == 0 && difference.file1Lines.length > 0) || i > 0) {
lineDiv.classList.add('file-diff__no-top-border');
}
if (i < difference.file2Lines.length - 1) {
lineDiv.classList.add('file-diff__no-bottom-border');
}
lineDiv.appendChild(diffSpans);
}
}
private buildDiffLine(line1: string, line2: string, charClass: string) {
const fragment = document.createElement('div');
if (line1 != undefined && line1.length === 0) {
fragment.textContent = preventEmptyString(line1);
} else if (line1 != undefined && line2 != undefined) {
const differences = diffWords(line2, line1);
for (const difference of differences) {
if (difference.removed) {
continue;
}
const span = document.createElement('span');
// Necessary to give the line a height when it's empty.
span.textContent = preventEmptyString(difference.value);
if (difference.added) {
span.classList.add(charClass);
}
fragment.appendChild(span);
}
} else if(line1 != undefined && line2 == undefined) {
const span = document.createElement('span');
// Necessary to give the line a height when it's empty.
span.textContent = preventEmptyString(line1);
span.classList.add(charClass);
fragment.appendChild(span);
} else {
fragment.textContent = preventEmptyString(line1);
}
return fragment;
}
private scrollToFirstDifference(): void {
if (this.fileDifferences.differences.length === 0) {
return;

View file

@ -54,11 +54,6 @@ export class DeleteFileModal extends Modal {
this.close();
const leaf = this.app.workspace.getLeaf();
if (leaf != null) {
leaf.openFile(this.file1);
}
this.onDone(null);
}
}

View file

@ -146,15 +146,16 @@ export default class FileDiffPlugin extends Plugin {
}
async openDifferencesView(state: ViewState): Promise<void> {
// Closes all leafs (views) of the type VIEW_TYPE_DIFFERENCES
this.app.workspace.detachLeavesOfType(VIEW_TYPE_DIFFERENCES);
const leaf = await this.app.workspace.getLeaf(true);
// Opens a new leaf (view) of the type VIEW_TYPE_DIFFERENCES
const leaf = this.app.workspace.getLeaf(true);
leaf.setViewState({
type: VIEW_TYPE_DIFFERENCES,
active: true,
state,
});
this.app.workspace.revealLeaf(leaf);
}
@ -173,7 +174,7 @@ export default class FileDiffPlugin extends Plugin {
''
);
const originalFile = files.find(
(f) => f.name === originalFileName
(f) => f.name === originalFileName && (file.parent?.path ?? "") === (f.parent?.path ?? "")
);
if (originalFile) {

View file

@ -13,28 +13,38 @@
text-align: right;
}
@media (prefers-color-scheme: light) {
.file-diff__top-line__bg {
background-color: #d9f4ef;
}
.file-diff__bottom-line__bg {
background-color: #d9edff;
}
.file-diff__top-line__bg {
background-color: color-mix(in srgb, var(--background-primary), #0fc 15%);
border-radius: 0.25rem; /* 4px */
}
@media (prefers-color-scheme: dark) {
.file-diff__top-line__bg {
background-color: #25403b;
}
.file-diff_top-line__character {
background-color: color-mix(in srgb, var(--background-primary), #0fc 50%);
border-radius: 0.25rem; /* 4px */
}
.file-diff__bottom-line__bg {
background-color: #25394b;
}
.file-diff__bottom-line__bg {
background-color: color-mix(in srgb, var(--background-primary), #08f 15%);
border-radius: 0.25rem; /* 4px */
}
.file-diff_bottom-line__character {
background-color: color-mix(in srgb, var(--background-primary), #08f 50%);
border-radius: 0.25rem; /* 4px */
}
.file-diff__no-bottom-border {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.file-diff__no-top-border {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.file-diff__action-line {
color: #919191;
color: var(--text-muted);
}
/* Tailwind CSS */

View file

@ -12,5 +12,8 @@
"1.0.10": "0.15.0",
"1.0.11": "0.15.0",
"1.0.12": "0.15.0",
"1.0.13": "0.15.0"
"1.0.13": "0.15.0",
"1.1.0": "0.15.0",
"1.1.1": "0.15.0",
"1.1.2": "0.15.0"
}

1050
yarn.lock

File diff suppressed because it is too large Load diff