From 6308a6926a52746a34c6f1cc94a502de33fb972a Mon Sep 17 00:00:00 2001 From: Kljh Date: Sat, 16 Aug 2014 20:39:03 +0100 Subject: [PATCH] Added auto scrolling. Current difference is now always in viewport. Added functions get_changes() and scroll_to_change(change) around line 767. Both new review. We shouldn't need to rerun the full diff but I couldn't find how to retrieve the diff results. Scrolling to a given change is quite tricky (musn't break the canvas graph, must have both pane nice). --- lib/mergely.js | 95 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 30 deletions(-) diff --git a/lib/mergely.js b/lib/mergely.js index 1c064c6..a2bc3cb 100644 --- a/lib/mergely.js +++ b/lib/mergely.js @@ -689,75 +689,110 @@ jQuery.extend(Mgly.CodeMirrorDiffView.prototype, { this.settings.rhs(setv.bind(this.editor[this.id + '-rhs'].getDoc())); } + // kljh: register WinMerge style key bindings var self = this; - el.addEventListener("keydown", function(evt) { - if (evt.defaultPrevented) - ;//return; // Should do nothing if the key event was already consumed. + document.body.addEventListener("keydown", function(evt) { + if (evt.defaultPrevented) { + //return; // Should do nothing if the key event was already consumed. + //console.warn("Should do nothing if the key event was already consumed."); + } if (!evt.shiftKey && !evt.altKey && !evt.ctrlKey && !evt.metaKey) return; // if none of Shift, Alt, Ctrl or Meta key is used then do nothing - var shift_key = 16, alt_key = 17, ctrlKey = 18, metaKey = 91; // 13, 27 ? - var up_arrow = 38, down_arrow = 40, left_arrow = 37, right_arrow = 39; + var shift_key=16, alt_key=17, ctrlKey=18, metaKey=91; // enterKey=13, escKey=27 + var up_arrow=38, down_arrow=40, left_arrow=37, right_arrow=39; + var key_h_left=72, key_j_down=74, key_k_up=75, key_h_right=76; if (!evt.key) { // use keyCode as key evt.key = evt.which; } + if (evt.shiftKey && evt.ctrlKey) { + // VI convention : Ctrl + Shif + K/L/J/H + if (evt.which==key_h_left) evt.key = left_arrow; + if (evt.which==key_j_down) evt.key = down_arrow; + if (evt.which==key_k_up) evt.key = up_arrow; + if (evt.which==key_h_right) evt.key = right_arrow; + } switch (evt.key) { + case "Down": case "ArrowDown": case down_arrow: + // !! recalculating the changes !! + var changes = get_changes(); + self.settings.current_diff++; + self.settings.current_diff = Math.min(self.settings.current_diff, changes.length-1); + scroll_to_change(changes[self.settings.current_diff]); + self._changed(self.id + '-lhs', self.id + '-rhs'); break; + case "Up": case "ArrowUp": case up_arrow: + // !! recalculating the changes !! + var changes = get_changes(); + self.settings.current_diff--; self.settings.current_diff = Math.max(self.settings.current_diff, 0); + scroll_to_change(changes[self.settings.current_diff]); + self._changed(self.id + '-lhs', self.id + '-rhs'); break; + case "Left": case "ArrowLeft": case left_arrow: // !! recalculating the changes !! - var editor_name1 = self.id + '-lhs'; - var editor_name2 = self.id + '-rhs'; - var lhs = self.editor[editor_name1].getValue(); - var rhs = self.editor[editor_name2].getValue(); - var d = new Mgly.diff(lhs, rhs, self.settings); - var changes = Mgly.DiffParser(d.normal_form()); + var changes = get_changes(); - var change = changes[self.settings.current_diff]; - self._merge_change(change, "rhs", "lhs"); + self._merge_change(changes[self.settings.current_diff], "rhs", "lhs"); break; + case "Right": case "ArrowRight": case right_arrow: // !! recalculating the changes !! - var editor_name1 = self.id + '-lhs'; - var editor_name2 = self.id + '-rhs'; - var lhs = self.editor[editor_name1].getValue(); - var rhs = self.editor[editor_name2].getValue(); - var d = new Mgly.diff(lhs, rhs, self.settings); - var changes = Mgly.DiffParser(d.normal_form()); + var changes = get_changes(); - var change = changes[self.settings.current_diff]; - self._merge_change(change, "lhs", "rhs"); - break; - case "Enter": - // Do something for "enter" or "return" key press. - break; - case "Escape": - // Do something for "esc" key press. + self._merge_change(changes[self.settings.current_diff], "lhs", "rhs"); break; default: - return; // Quit when this doesn't handle the key event. + return; } // Consume the event for suppressing "double action". - //event.preventDefault(); + event.preventDefault(); }); + + function get_changes() { + var lhs = self.editor[self.id+'-lhs'].getValue(); + var rhs = self.editor[self.id+'-rhs'].getValue(); + var d = new Mgly.diff(lhs, rhs, self.settings); + var changes = Mgly.DiffParser(d.normal_form()); + return changes; + } + + function scroll_to_change(change) { + var led = self.editor[self.id+'-lhs']; + var red = self.editor[self.id+'-rhs']; + + var yref = led.getScrollerElement().offsetHeight * 1/2; // center between 0 and 1/2 + + // using directly CodeMirror breaks canvas alignment + // var ly = led.charCoords({line: Math.max(change["lhs-line-from"],0), ch: 0}, "local").top; + + // calculate scroll offset for current change. Warning: returns relative y position so we scroll to 0 first. + led.scrollTo(null, 0); + red.scrollTo(null, 0); + self._calculate_offsets(self.id+'-lhs', self.id+'-rhs', [change]); + led.scrollTo(null, Math.max(change["lhs-y-start"]-yref, 0)); + red.scrollTo(null, Math.max(change["rhs-y-start"]-yref, 0)); + + // right pane should simply follows + } }, - + _scrolling: function(editor_name) { if (this._skipscroll[editor_name] === true) { // scrolling one side causes the other to event - ignore it