-
Notifications
You must be signed in to change notification settings - Fork 921
WIP: Fix electron freezing #2478
base: develop
Are you sure you want to change the base?
Changes from 2 commits
55552b6
6b37d26
66c9a97
5f9a0f3
5442e92
1ac0375
17c9c5f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
var opposites = { | ||
"(": ")", | ||
"[": "]", | ||
"{": "}", | ||
")": "(", | ||
"]": "[", | ||
"}": "{" | ||
}; | ||
|
||
var chars = /[^\s\)\]\}]/; | ||
|
||
//{:+ {:app [:foo (:blah "asdf" {:foo 234}) :zomg]}} | ||
//var example = "{:+ {:app [(:lt.objs.style/set-skin \"dark\")\n (:lt.plugins.vim/map-keys {\"-\" \"$\",\n \"0\" \"^\",\n \"<BS>\" \"<PageUp>\",\n \"<Space>\" \"<PageDown>\",\n \"j\" \"gj\",\n \"k\" \"gk\"})\n :lt.objs.intro/show-new-file \n ],\n\n :editor [:lt.plugins.vim/activate-vim\n :lt.objs.editor/no-wrap\n :lt.plugins.rainbow-parens/rainbow-parens\n :lt.plugins.auto-complete/auto-show-on-input\n (:lt.objs.style/set-theme \"ibdknox\")],\n\n :editor.behaviors [:lt.plugins.rainbow-parens/rainbow-parens],\n\n :editor.clj [:lt.plugins.rainbow-parens/rainbow-parens],\n\n :editor.clj.instarepl [:lt.plugins.rainbow-parens/rainbow-parens\n (:lt.objs.langs.clj/print-length 1000)],\n\n :editor.cljs [:lt.plugins.rainbow-parens/rainbow-parens],\n\n :editor.javascript [(:lt.plugins.jshint/jshint-options {:maxparams false})\n :lt.plugins.jshint/on-save],\n\n :editor.keymap [:lt.plugins.rainbow-parens/rainbow-parens],\n\n :editor.markdown [:lt.objs.editor/wrap],\n\n :editor.plaintext [:lt.objs.editor/wrap],\n\n :editor.python [(:lt.objs.style/set-theme \"tomorrow-night\")],\n\n :files [(:lt.objs.files/file-types [{:exts [:wisp],\n :mime \"text/x-clojurescript\",\n :name \"Wisp\",\n :tags [:editor.wisp]}])]},\n\n :- {:app [:lt.objs.intro/show-intro]}}\n"; | ||
|
||
|
||
//{:+ {:app {"a" [:foo]}}} | ||
|
||
// parseFlat(new CodeMirror.StringStream("[[:app :foo :bar] [:zomg :baz 234 \"hi how are you?\"]]")); | ||
function parseFlat(stream) { | ||
|
||
var state = { level: 0, stack: []}; | ||
var errors = []; | ||
var entries = []; | ||
var curEntry; | ||
|
||
stream.eatSpace(); | ||
while(stream.peek()) { | ||
var ch = stream.next(); | ||
|
||
if (ch == "\"") { | ||
stream.start = stream.pos - 1; | ||
state.mode = "string"; | ||
var pos = stream.pos; | ||
var next, escaped = false; | ||
while ((next = stream.next()) != null) { | ||
if (next == "\"" && !escaped) { | ||
|
||
state.mode = false; | ||
break; | ||
} | ||
escaped = !escaped && next == "\\"; | ||
} | ||
|
||
if(state.level === 2) { | ||
curEntry.tokens.push({start: stream.start, end: stream.pos, value: stream.current(), type: "string"}); | ||
} | ||
|
||
} else if (ch == ";") { // comment | ||
stream.skipTo("\n"); // rest of the line is a comment | ||
|
||
} else if (ch == "(" || ch == "[" || ch == "{") { | ||
state.stack.push({type: ch, pos: stream.pos}); | ||
state.level++; | ||
if(state.level === 2) { | ||
curEntry = {start: stream.pos - 1, | ||
tokens: []}; | ||
entries.push(curEntry); | ||
} else if(state.level === 3) { | ||
curEntry.tokens.push({start: stream.pos - 1, | ||
type: "collection", | ||
tokens: []}); | ||
} else if(state.level === 4) { | ||
var lastToken = curEntry.tokens[curEntry.tokens.length - 1]; | ||
lastToken.tokens.push({start: stream.pos - 1, | ||
type: "collection", | ||
tokens: []}); | ||
} | ||
|
||
} else if (ch == ")" || ch == "]" || ch == "}") { | ||
if(state.stack.length && state.stack[state.stack.length - 1].type == opposites[ch]) { | ||
state.stack.pop(); | ||
state.level--; | ||
|
||
if(state.level === 1) { | ||
curEntry.end = stream.pos; | ||
} else if(state.level === 2) { | ||
curEntry.tokens[curEntry.tokens.length - 1].end = stream.pos; | ||
stream.start = stream.pos; | ||
} else if(state.level === 3) { | ||
var lastToken = curEntry.tokens[curEntry.tokens.length - 1]; | ||
lastToken.tokens[lastToken.tokens.length - 1].end = stream.pos; | ||
stream.start = stream.pos; | ||
} | ||
|
||
} else { | ||
var expected = "the end of the file"; | ||
if(state.stack[state.stack.length - 1]) { | ||
var expected = opposites[state.stack[state.stack.length - 1].type]; | ||
} | ||
errors.push({error: "Unmatched delimiter " + ch + " expected to see " + expected + "", from: stream.start, to: stream.pos}); | ||
} | ||
|
||
|
||
} else if ( ch == ":" ) { | ||
stream.start = stream.pos - 1; | ||
stream.eatWhile(chars); | ||
if(state.level === 2) { | ||
curEntry.tokens.push({start: stream.start, end: stream.pos, value: stream.current(), type: "keyword"}); | ||
} else if(state.level === 3) { | ||
var lastToken = curEntry.tokens[curEntry.tokens.length - 1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'lastToken' is already defined. |
||
lastToken.tokens.push({start: stream.start, end: stream.pos, value: stream.current(), type: "keyword"}); | ||
} | ||
stream.start = stream.pos; | ||
} else if(ch.match(chars)) { | ||
stream.start = stream.pos - 1; | ||
var pos = stream.pos; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'pos' is already defined. |
||
stream.eatWhile(chars); | ||
if(state.level === 2) { | ||
curEntry.tokens.push({start: stream.start, end: stream.pos, value: stream.current(), type: "atom"}); | ||
} else if(state.level === 3) { | ||
var lastToken = curEntry.tokens[curEntry.tokens.length - 1]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'lastToken' is already defined. |
||
lastToken.tokens.push({start: stream.start, end: stream.pos, value: stream.current(), type: "keyword"}); | ||
} | ||
stream.start = stream.pos; | ||
} | ||
} | ||
|
||
return {errors: errors, entries: entries}; | ||
} | ||
|
||
exports.parseFlat = parseFlat; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
var fs = require("fs"); | ||
var funcs = {}; | ||
var ltpath = ""; | ||
|
||
var _send = function(obj, msg, res, format) { | ||
format = format || "json"; | ||
process.send({msg: cljs.core.name(msg), res: res, obj:obj, format: format}); | ||
}; | ||
|
||
var argsArray = function(args) { | ||
var final = []; | ||
for(var i = 0; i < args.length; i++) { | ||
final.push(args[i]); | ||
} | ||
return final; | ||
}; | ||
|
||
var lttools = { | ||
watch: function(exp, meta) { | ||
_send(meta.obj, cljs.core.keyword(meta.ev), cljs.core.pr_str(cljs.core.js__GT_clj({result: exp, meta: meta}, cljs.core.keyword("keywordize-keys"), true)), "clj"); | ||
} | ||
}; | ||
|
||
process.on("message", function(m) { | ||
try { | ||
switch(m.msg) { | ||
case "init": | ||
ltpath = m.ltpath; | ||
global.eval(fs.readFileSync(ltpath + "/core/node_modules/clojurescript/cljsDeps.js").toString()); | ||
cljs.core._STAR_print_fn_STAR_ = function(x) { | ||
var final = clojure.string.trim(x); | ||
if(x != "\n") { | ||
console.log(final); | ||
} | ||
}; | ||
_send(m.obj, "connect"); | ||
break; | ||
case "register": | ||
eval("funcs['" + m.name + "'] = " + m.func); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eval can be harmful. |
||
break; | ||
case "call": | ||
m.params.unshift(m); | ||
funcs[m.name].apply(null, m.params); | ||
break; | ||
} | ||
} catch (e) { | ||
console.error(e.stack); | ||
} | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
var fs = require('fs'); | ||
var _path = require('path'); | ||
|
||
var curtime = function() { | ||
return (new Date()).getTime(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing semicolon. |
||
|
||
var walk = function(path,options){ | ||
|
||
var start = curtime(); | ||
var allPaths = []; | ||
if(path.push) { | ||
var queue = path; | ||
} else { | ||
var queue = [path]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'queue' is already defined. |
||
} | ||
var stat = null; | ||
var children = null; | ||
var child = null; | ||
var isDir = null; | ||
var filter = options.filter; | ||
var limit = options.limit; | ||
var cur = null; | ||
var limited = false; | ||
var basename = null; | ||
|
||
while(cur = queue.shift()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'queue' used out of scope. |
||
|
||
try { | ||
children = fs.readdirSync(cur); | ||
} catch(e) { | ||
console.error("Couldn't read dir " + cur); | ||
continue; | ||
} | ||
|
||
for(var i = 0; i < children.length; i++) { | ||
basename = children[i]; | ||
child = _path.join(cur, basename); | ||
try { | ||
stat = fs.statSync(child); | ||
} catch(e) { | ||
try { | ||
stat = fs.lstatSync(child); | ||
} catch(e) { | ||
continue; | ||
} | ||
} | ||
isDir = stat.isDirectory(); | ||
|
||
if(isDir) { | ||
basename += _path.sep; | ||
} | ||
|
||
if(!filter || !basename.match(filter)) { | ||
if(isDir) { | ||
queue.push(child); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'queue' used out of scope. |
||
} else if(!limit || allPaths.length <= limit) { | ||
allPaths.push(child); | ||
} else { | ||
queue = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'queue' used out of scope. |
||
limited = true; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
return {time: curtime() - start, | ||
paths: allPaths, | ||
total: allPaths.length, | ||
limited: limited}; | ||
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing semicolon. |
||
|
||
module.exports = walk; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
(function(window) { | ||
|
||
const ipcRenderer = require("electron"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'const' is available in ES6 (use 'esversion: 6') or Mozilla JS extensions (use moz). |
||
|
||
function toArray(arrayLike) { | ||
var final = []; | ||
for(var i = 0, len = arrayLike.length; i < len; i++) { | ||
final.push(arrayLike.item(i)); | ||
} | ||
return final; | ||
} | ||
|
||
ipcRenderer.on("editor.eval.css", function(args) { | ||
var nodeName = args.name.replace(/\./, "-"); | ||
var code = args.code; | ||
var styleElem = document.createElement("style"); | ||
styleElem.type = "text/css" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing semicolon. |
||
styleElem.id = nodeName; | ||
styleElem.innerHTML = code; | ||
var prev = document.getElementById(nodeName); | ||
if(prev) { | ||
prev.parentNode.removeChild(prev); | ||
} else { | ||
var link = toArray(document.head.querySelectorAll("link")).filter(function(cur) { | ||
return cur.href.indexOf(args.name) > -1; | ||
}); | ||
if(link[0]) { | ||
link[0].parentNode.removeChild(link[0]); | ||
} | ||
} | ||
document.head.appendChild(styleElem); | ||
}); | ||
|
||
|
||
ipcRenderer.on("editor.eval.cljs.exec", function(args) { | ||
for(var i = 0; i < args.results.length; i++) { | ||
var data = args.results[i]; | ||
var meta = args.results[i].meta; | ||
meta.verbatim = true; | ||
try { | ||
var res = eval.call(window, args.results[i].code); | ||
if(window.cljs) { | ||
ipcRenderer.sendToHost("browser-raise", [args.client, "editor.eval.cljs.result", {result: cljs.core.pr_str(res), meta: meta}]); | ||
} else { | ||
ipcRenderer.sendToHost("browser-raise", [args.client, "editor.eval.cljs.result", {result: safeStringify(res), meta: meta}]); | ||
} | ||
} catch (e) { | ||
var exdata = cljs.core.ex_data(e); | ||
var error = ""; | ||
if (exdata) { | ||
error = e.message + ": " + cljs.core.pr_str(exdata); | ||
} else { | ||
error = cljs.core.pr_str(e); | ||
} | ||
|
||
if(e.stack) { | ||
error += "\n" + e.stack; | ||
} | ||
ipcRenderer.sendToHost("browser-raise", [args.client, "editor.eval.cljs.exception", {ex: error, meta: meta}]); | ||
} | ||
} | ||
}); | ||
|
||
window.addEventListener("hashchange", function(e) { | ||
ipcRenderer.sendToHost("browser-event", ["hashchange", {href: window.location.href, hash: window.location.hash}]); | ||
}); | ||
|
||
function replacer(key, value) { | ||
if(window.jQuery && value instanceof jQuery) { | ||
return "[jQuery $(" + value.selector + ")]"; | ||
} | ||
if(value instanceof Element) { | ||
return "[Element " + value.tagName.toLowerCase() + (value.id != "" ? "#" : "") + value.id + "]"; | ||
} | ||
if(value instanceof Array) { | ||
return value; | ||
} | ||
if(typeof(value) == "object") { | ||
if(cache.indexOf(value) > -1) { | ||
return "circular"; | ||
} | ||
cache.push(value); | ||
return value; | ||
} | ||
if(typeof value == "function") { | ||
return "[function]"; | ||
} | ||
return value; | ||
} | ||
|
||
function safeStringify(res) { | ||
cache = []; | ||
return JSON.stringify(res, replacer); | ||
} | ||
|
||
window.lttools = { | ||
watch: function(exp, meta) { | ||
if(meta.ev == "editor.eval.cljs.watch") { | ||
var final = cljs.core.pr_str(exp); | ||
} else { | ||
meta["no-inspect"] = true; | ||
var final = safeStringify(exp); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'final' is already defined. |
||
} | ||
ipcRenderer.sendToHost("browser-raise", [meta.obj, meta.ev, {result: final, meta: meta}]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'final' used out of scope. |
||
return exp; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing semicolon. |
||
|
||
|
||
})(window); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'expected' is already defined.