Skip to content

Commit

Permalink
Added diff highlighting.
Browse files Browse the repository at this point in the history
  • Loading branch information
DrRetro2033 committed Nov 7, 2024
1 parent 0c9b809 commit ae2e3e2
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 13 deletions.
12 changes: 12 additions & 0 deletions bin/arceus.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'extensions.dart';
import 'version_control/constellation.dart';

class Arceus {
static String get _appDataPath => _getAppDataPath();
Expand Down Expand Up @@ -47,6 +48,17 @@ class Arceus {
}
}

static Constellation? getConstellationFromPath(String path) {
List<String> pathList = path.fixPath().split('/');
while (pathList.length > 1) {
if (Directory("${pathList.join('/')}/.constellation").existsSync()) {
return Constellation(path: pathList.join('/'));
}
pathList.removeLast();
}
return null;
}

static void addConstellation(String name, String path) {
if (doesConstellationExist(name: name)) {
throw Exception("Constellation already exists");
Expand Down
1 change: 0 additions & 1 deletion bin/cli.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:ansix/ansix.dart';
import 'package:dart_console/dart_console.dart';

class Cli {
static final Console _console = Console();
static int get windowWidth => stdout.terminalColumns;
static int get windowHeight => stdout.terminalLines;
static int _lastWindowWidth = 0;
Expand Down
99 changes: 91 additions & 8 deletions bin/hex_editor/editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import '../cli.dart';
import '../version_control/dossier.dart';

enum Views {
jumpToAddress,
byteViewer,
dataFooter,
changeLog,
Expand All @@ -17,9 +18,10 @@ enum Formats { u8, u16, u32, u64 }

class HexEditor {
final Plasma _primaryFile;
Plasma? _secondaryFile;
Map<int, int> differences = {};
final keyboard = KeyboardInput();
Views currentView = Views.byteViewer;
HexEditor(this._primaryFile);
ByteData get data => _primaryFile.data;
Endian dataEndian = Endian.little;
static const int _minDataHeight = 7;
Expand All @@ -32,6 +34,13 @@ class HexEditor {
final List<int> byte32Color = [100, 100, 100];
final List<int> byte64Color = [80, 80, 80];

HexEditor(this._primaryFile) {
if (_primaryFile.isTracked()) {
_secondaryFile = _primaryFile.findOlderVersion();
differences = _primaryFile.getDifferences(_secondaryFile!);
}
}

/// # `String` getByteAt(int address)
/// ## Get the byte at the given address as a hex string.
String getByteAt(int address) {
Expand Down Expand Up @@ -66,7 +75,30 @@ class HexEditor {

// Write address at bottom left.
Cli.moveCursorToBottomLeft();
stdout.write("Address: 0x${address.toRadixString(16)} ");
stdout.write("A".underline.bold);
stdout.write("ddress: ");
if (currentView == Views.jumpToAddress) {
if (_currentValue != null) {
int? x;
if (_currentValue!.startsWith("0x")) {
x = int.tryParse(_currentValue!.substring(2), radix: 16);
} else {
x = int.tryParse(_currentValue!);
}

if (x != null && x >= 0 && x < data.lengthInBytes) {
stdout.write(_currentValue!.bgBrightMagenta.black);
} else {
stdout.write(_currentValue!.bgBrightRed.black);
error = true;
}
} else {
stdout.write("0x${address.toRadixString(16)}".bgBrightMagenta.black);
}
} else {
stdout.write("0x${address.toRadixString(16)}");
}
stdout.write(" ");
stdout.write(getValues(address));
}

Expand Down Expand Up @@ -95,7 +127,8 @@ class HexEditor {
for (int x = startLine * 16 < 0 ? 0 : startLine * 16;
x < data.lengthInBytes && x < endLine * 16;
x += 16) {
final line = StringBuffer("");
// 16 bytes per line, with a gap between every eight bytes.
final line = StringBuffer(""); // The line to be printed
line.write("${x.toRadixString(16).padLeft(8, "0")}\t"); // Address Labels
for (int leftHalf = 0; leftHalf < 8; leftHalf++) {
// Left Half of 16 bytes
Expand Down Expand Up @@ -282,6 +315,8 @@ class HexEditor {
}
if (_primaryFile.unsavedChanges().containsKey(byteAddress)) {
value = value.brightYellow;
} else if (differences.containsKey(byteAddress)) {
value = value.brightCyan;
}
return value;
}
Expand All @@ -300,6 +335,10 @@ class HexEditor {
_currentValue = null;
render();
break;
case 'a':
currentView = Views.jumpToAddress;
render();
break;
}
return quit;
}
Expand Down Expand Up @@ -333,6 +372,9 @@ class HexEditor {
break;
case ControlCharacter.ctrlS:
_primaryFile.save();
if (_secondaryFile != null) {
differences = _primaryFile.getDifferences(_secondaryFile!);
}
render();
break;
default:
Expand Down Expand Up @@ -380,11 +422,7 @@ class HexEditor {
render();
break;
case ControlCharacter.backspace:
if (_currentValue != null && _currentValue!.isNotEmpty) {
_currentValue =
_currentValue!.substring(0, _currentValue!.length - 1);
render();
}
_backspaceCurrentValue();
break;
case ControlCharacter.enter:
if (_currentValue != null && !error && _currentValue!.isNotEmpty) {
Expand Down Expand Up @@ -417,6 +455,49 @@ class HexEditor {
}
}

void _jumpToAddressView(Key key) {
if (!key.isControl) {
_currentValue ??= "";
_currentValue = _currentValue! + key.char;
render();
}
switch (key.controlChar) {
case ControlCharacter.backspace:
_backspaceCurrentValue();
case ControlCharacter.ctrlQ:
currentView = Views.byteViewer;
_currentValue = null;
render();
break;
case ControlCharacter.enter:
if (_currentValue != null && !error && _currentValue!.isNotEmpty) {
try {
if (_currentValue!.startsWith("0x")) {
_currentValue = _currentValue!.substring(2);
address = int.parse(_currentValue!, radix: 16);
} else {
address = int.parse(_currentValue!);
}
_currentValue = null;
currentView = Views.byteViewer;
render();
} catch (e) {
Cli.clearTerminal();
rethrow;
}
}
default:
break;
}
}

void _backspaceCurrentValue() {
if (_currentValue != null && _currentValue!.isNotEmpty) {
_currentValue = _currentValue!.substring(0, _currentValue!.length - 1);
render();
}
}

Future<ByteData> interact() async {
int lastHeight = 1;
int lastWidth = 1;
Expand All @@ -430,6 +511,8 @@ class HexEditor {
case Views.dataFooter:
_dataFooterView(key);
break;
case Views.jumpToAddress:
_jumpToAddressView(key);
default:
break;
}
Expand Down
6 changes: 3 additions & 3 deletions bin/version_control/constellation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,14 @@ class Starmap {
List<String> _getEndingHashes() {
List<String> endings = [];
for (String hash in childMap.keys) {
if (childMap[hash]!.isEmpty) {
if (childMap[hash]!.isEmpty && hash.isNotEmpty) {
endings.add(hash);
}
}
return endings;
}

Star _getMostRecentStar() {
Star getMostRecentStar() {
List<String> endings = _getEndingHashes();
if (endings.isEmpty) {
throw Exception("WHAT? How are there no ending stars?");
Expand All @@ -281,7 +281,7 @@ class Starmap {
operator [](Object hash) {
if (hash is String) {
if (hash == "recent") {
return _getMostRecentStar();
return getMostRecentStar();
} else if (hash == "root") {
return root;
} else if (hash.startsWith("back")) {
Expand Down
42 changes: 41 additions & 1 deletion bin/version_control/dossier.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:ansix/ansix.dart';
import 'package:cli_spin/cli_spin.dart';
import '../extensions.dart';
import '../arceus.dart';
import 'constellation.dart';

/// # `class` `Dossier`
/// ## A wrapper for the internal and external file systems.
Expand Down Expand Up @@ -162,8 +163,14 @@ class Dossier {
}
}

/// # `enum` `Origin`
/// ## The origin of a `Plasma` object.
/// The origin can either internal (from a star) or external (from the current directory).
enum Origin { internal, external }

/// # `class` `Plasma`
/// ## A wrapper for the internal and external file systems.
/// Its called plasma because its one of the building blocks of a star.
class Plasma {
Star? star;
String? pathInStar;
Expand All @@ -173,7 +180,7 @@ class Plasma {
final Origin origin;

/// # `Plasma`(`ByteData` data)
/// DO NOT CALL THIS DIRECTLY, USE ONE OF THE FACTORY METHODS.
/// DO NOT CALL THIS DIRECTLY, USE ONE OF THE FACTORY METHODS ([Plasma.fromFile], [Plasma.fromStar]).
Plasma(this.data, this.origin, {this.star, this.file, this.pathInStar}) {
_originalData = Uint8List.fromList(data.buffer.asUint8List().toList())
.buffer
Expand Down Expand Up @@ -243,4 +250,37 @@ class Plasma {
}
return changes;
}

/// # `Map<int, int>` getDifferences(Plasma other)
/// ## Compares the current plasma to another plasma.
/// Returns a map of the differences between the two plasmas.
/// The keys are the addresses of the differences, and the values are the values at those addresses in the current plasma.
Map<int, int> getDifferences(Plasma other) {
Map<int, int> differences = {};
for (int i = 0; i < data.lengthInBytes; ++i) {
if (i >= _originalData!.lengthInBytes) {
differences[i] = data.getUint8(i);
} else if (data.getUint8(i) != other.data.getUint8(i)) {
differences[i] = data.getUint8(i);
}
}
return differences;
}

Plasma? findOlderVersion() {
if (origin == Origin.internal) {
if (star!.parent != null) {
return Plasma.fromStar(star!.parent!, pathInStar!);
}
} else if (origin == Origin.external) {
if (Arceus.doesConstellationExist(path: file!.path)) {
Constellation x = Arceus.getConstellationFromPath(file!.path)!;
print(file!.path.fixPath().replaceFirst("${x.path}/", ""));
return x.starmap
?.getMostRecentStar()
.getPlasma(file!.path.fixPath().replaceFirst("${x.path}/", ""));
}
}
return null;
}
}
5 changes: 5 additions & 0 deletions bin/version_control/star.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:convert';
import 'constellation.dart';
import 'users.dart';
import 'dart:io';
import '../version_control/dossier.dart';

/// # `class` Star
/// ## Represents a star in the constellation.
Expand Down Expand Up @@ -142,6 +143,10 @@ class Star {
return archive;
}

Plasma getPlasma(String pathOfFileInStar) {
return Plasma.fromStar(this, pathOfFileInStar);
}

void _fromStarFileData(String data) {
fromJson(jsonDecode(data));
}
Expand Down
1 change: 1 addition & 0 deletions src/squirrel
Submodule squirrel added at c02bf2

0 comments on commit ae2e3e2

Please sign in to comment.