Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

WIP: Fix electron freezing #2478

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//deploy/core/node_modules/*
!/deploy/core/node_modules/lighttabledeploy/core/node_modules/lighttable/cljs/
/deploy/core/node_modules/*
!/deploy/core/node_modules/lighttable
/deploy/core/node_modules/clojurescript/cljsDeps/
/target/
/deploy/plugins/
Expand All @@ -12,3 +12,4 @@
/builds/
.idea
*.iml
Lighttable-plugin-metadata-1e53959/*
6 changes: 3 additions & 3 deletions deploy/core/LightTable.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
</div>
<div id="wrapper" style="opacity:0;">
</div>
<script src="node_modules/lighttable/util/keyevents.js" type="text/javascript"> </script>
<script src="node_modules/lighttable/util/throttle.js" type="text/javascript"> </script>
<script src="lighttable/util/keyevents.js" type="text/javascript"> </script>
<script src="lighttable/util/throttle.js" type="text/javascript"> </script>
<script type="text/javascript">
var script = document.createElement("script");
script.type = "text/javascript";
script.async = false;
script.src= "node_modules/lighttable/bootstrap.js";
script.src= "lighttable/bootstrap.js";
document.body.appendChild(script);
script.onload = function() {
try {
Expand Down
2 changes: 2 additions & 0 deletions deploy/core/codemirror_addons/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
These are custom CodeMirror addons. Some are forks of original addons and may eventually be merged
upstream.
90 changes: 90 additions & 0 deletions deploy/core/codemirror_addons/overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE

// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.

(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["/../node_modules/codemirror/lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.overlayMode = function(base, overlay, combine) {
return {
startState: function() {
return {
base: CodeMirror.startState(base),
overlay: CodeMirror.startState(overlay),
basePos: 0, baseCur: null,
overlayPos: 0, overlayCur: null,
streamSeen: null
};
},
copyState: function(state) {
return {
base: CodeMirror.copyState(base, state.base),
overlay: CodeMirror.copyState(overlay, state.overlay),
basePos: state.basePos, baseCur: null,
overlayPos: state.overlayPos, overlayCur: null
};
},

token: function(stream, state) {
if (stream != state.streamSeen ||
Math.min(state.basePos, state.overlayPos) < stream.start) {
state.streamSeen = stream;
state.basePos = state.overlayPos = stream.start;
}

if (stream.start == state.basePos) {
state.baseCur = base.token(stream, state.base);
state.basePos = stream.pos;
}
if (stream.start == state.overlayPos) {
stream.pos = stream.start;
state.overlayCur = overlay.token(stream, state.overlay);
state.overlayPos = stream.pos;
}
stream.pos = Math.min(state.basePos, state.overlayPos);

// state.overlay.combineTokens always takes precedence over combine,
// unless set to null
if (state.overlayCur == null) return state.baseCur;
else if (state.baseCur != null &&
state.overlay.combineTokens ||
combine && state.overlay.combineTokens == null)
return state.baseCur + " " + state.overlayCur;
else return state.overlayCur;
},

indent: base.indent && function(state, textAfter, line) {
return base.indent(state.base, textAfter, line);
},
electricChars: base.electricChars,

innerMode: function(state) { return {state: state.base, mode: base}; },

blankLine: function(state) {
var baseToken, overlayToken;
if (base.blankLine) baseToken = base.blankLine(state.base);
if (overlay.blankLine) overlayToken = overlay.blankLine(state.overlay);

return overlayToken == null ?
baseToken :
(combine && baseToken != null ? baseToken + " " + overlayToken : overlayToken);
}
};
};

});
153 changes: 153 additions & 0 deletions deploy/core/codemirror_addons/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Define search commands. Depends on dialog.js or another
// implementation of the openDialog method.

// Replace works a little oddly -- it will do the replace on the next
// Ctrl-G (or whatever is bound to findNext) press. You prevent a
// replace by making sure the match is no longer selected when hitting
// Ctrl-G.

(function() {
function searchOverlay(query) {
if (typeof query == "string") {
var ignoreCase = query == query.toLowerCase();
return {token: function(stream) {
if (stream.match(query, true, ignoreCase)) return "searching";
stream.next();
if(!stream.skipTo(query.charAt(0))) {
if(!ignoreCase || !stream.skipTo(query.charAt(0).toUpperCase())) {
stream.skipToEnd();
}
}
}};
}
return {token: function(stream) {
if (stream.match(query)) return "searching";
while (!stream.eol()) {
stream.next();
if (stream.match(query, false)) break;
}
}};
}

function SearchState() {
this.posFrom = this.posTo = this.query = null;
this.overlay = null;
}
function getSearchState(cm) {
return cm._searchState || (cm._searchState = new SearchState());
}
function getSearchCursor(cm, query, pos) {
// Heuristic: if the query string is all lowercase, do a case insensitive search.
return cm.getSearchCursor(query, pos, typeof query == "string" && query == query.toLowerCase());
}
function isRegex(s) {
if(s instanceof RegExp) return true;
return s.match(/^\/(.+)\/([a-z]*)$/);
}
function parseQuery(query) {
var ignoreCase = query == query.toLowerCase();
var isRE = isRegex(query);
try {
var rx = new RegExp(isRE[1], isRE[2].indexOf("i") == -1 ? "" : "i");
if(isRE && !"".match(rx)) {
return rx;
} else {
return query;
}
} catch (e) {
return query;
}
}
function doSearch(cm, query, rev) {
var state = getSearchState(cm);
cm.operation(function() {
if(!query) {
clearSearch(cm);
return;
}
if (state.rawQuery == query) return;
clearSearch(cm, false);
state.rawQuery = query;
state.query = parseQuery(query);
cm.removeOverlay(state.overlay);
state.overlay = searchOverlay(state.query);
cm.addOverlay(state.overlay);
state.posFrom = state.posTo = cm.getCursor();
if(!state.origPos) {
state.origPos = state.posFrom;
}
findNext(cm, rev, true);
});
}
function findNext(cm, rev, allowCurrent) {cm.operation(function() {
var state = getSearchState(cm);
var startingPoint = state.posTo;

if(!state.query) { return; }

if(allowCurrent) {
startingPoint = state.origPos ? state.origPos : state.posFrom;
} else {
state.origPos = null;
if(rev) {
startingPoint = state.posFrom;
}
}

var cursor = getSearchCursor(cm, state.query, startingPoint);
if (!cursor.find(rev)) {
cursor = getSearchCursor(cm, state.query, rev ? {line: cm.lineCount() - 1} : {line: 0, ch: 0});
if (!cursor.find(rev)) return;
}
//cm.setSelection(cursor.from(), cursor.to());
cm.setCursor(cursor.from());

if(state.mark) { state.mark.clear(); }
state.mark = cm.markText(cursor.from(), cursor.to(), {className: "searching-current"});
state.posFrom = cursor.from(); state.posTo = cursor.to();
});}
function clearSearch(cm, hard) {cm.operation(function() {
var state = getSearchState(cm);
if (!state.query) return;
if (hard) { state.origPos = null; }
state.query = null;
state.rawQuery = null;
if(state.mark) { state.mark.clear(); }
cm.removeOverlay(state.overlay);
});}


function replace(cm, text, rev, all) {
if (all) {
cm.operation(function() {
var state = getSearchState(cm);
for (var cursor = getSearchCursor(cm, state.query); cursor.find(rev);) {
if (typeof state.query != "string") {
var match = cm.getRange(cursor.from(), cursor.to()).match(query);
cursor.replace(text.replace(/\$(\d)/, function(_, i) {return match[i];}));
} else cursor.replace(text);
}
});
} else {
var state = getSearchState(cm);
var cursor = getSearchCursor(cm, state.query, state.posFrom);
if(cursor.findNext(rev)) {
cm.setSelection(cursor.from(), cursor.to());
var match = {};
if(isRegex(state.query)) {
match = cm.getRange(cursor.from(), cursor.to()).match(state.query);
}
cursor.replace(typeof state.query == "string" ? text :
text.replace(/\$(\d)/, function(_, i) {return match[i];}));
}
}
}

CodeMirror.commands.find = function(cm, query, rev) { doSearch(cm, query, rev);};
CodeMirror.commands.findNext = findNext;
CodeMirror.commands.findPrev = function(cm, rev) {findNext(cm, !rev);};
CodeMirror.commands.clearSearch = function(cm) { clearSearch(cm, true); };
CodeMirror.commands.getSearchState = getSearchState;
CodeMirror.commands.replace = replace;
CodeMirror.commands.replaceAll = function(cm, query, replace) { replace(cm, query, replace, true); };
})();
43 changes: 43 additions & 0 deletions deploy/core/codemirror_addons/show-hint.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
CodeMirror.positionHint = function(cm, hints, from) {
hints.classList.add("CodeMirror-hints");

// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var pos = cm.cursorCoords(from);
var left = pos.left, top = pos.bottom, below = true;
hints.style.left = left + "px";
hints.style.bottom = "";
hints.style.top = top + "px";
// If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
var box = hints.getBoundingClientRect();
var overlapX = box.right - winW, overlapY = box.bottom - winH;
if (overlapX > 0) {
if (box.right - box.left > winW) {
hints.style.width = (winW - 5) + "px";
overlapX -= (box.right - box.left) - winW;
}
hints.style.left = (left = pos.left - overlapX) + "px";
}
if (overlapY > 0) {
var height = box.bottom - box.top;
if (box.top - (pos.bottom - pos.top) - height > 0) {
overlapY = height + (pos.bottom - pos.top);
below = false;
hints.style.top = "";
hints.style.bottom = winH - pos.top + 5 + "px";
} else if (height > winH) {
hints.style.height = (winH - 5) + "px";
overlapY -= height - winH;
hints.style.top = (top = pos.bottom - overlapY) + "px";
}
}
document.body.appendChild(hints);
};

CodeMirror.ensureHintVisible = function(cm, hints, node) {
if (node.offsetTop < hints.scrollTop)
hints.scrollTop = node.offsetTop - 3;
else if (node.offsetTop + node.offsetHeight > hints.scrollTop + hints.clientHeight)
hints.scrollTop = node.offsetTop + node.offsetHeight - hints.clientHeight + 3;
};