mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-10-31 07:32:59 +00:00 
			
		
		
		
	| @@ -675,6 +675,9 @@ $tw.modules.execute = function(moduleName,moduleRoot) { | ||||
| 			} else if(typeof moduleInfo.definition === "string") { // String | ||||
| 				moduleInfo.exports = _exports; | ||||
| 				$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title); | ||||
| 				if(sandbox.module.exports) { | ||||
| 					moduleInfo.exports = sandbox.module.exports; //more codemirror workaround | ||||
| 				} | ||||
| 			} else { // Object | ||||
| 				moduleInfo.exports = moduleInfo.definition; | ||||
| 			} | ||||
|   | ||||
| @@ -17,8 +17,8 @@ var CODEMIRROR_OPTIONS = "$:/config/CodeMirror", configOptions; | ||||
| e.g. to allow vim key bindings | ||||
|  { | ||||
| 	"require": [ | ||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/dialog.js", | ||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/searchcursor.js", | ||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/dialog/dialog.js", | ||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/search/searchcursor.js", | ||||
| 		"$:/plugins/tiddlywiki/codemirror/keymap/vim.js" | ||||
| 	], | ||||
| 	"configuration": { | ||||
| @@ -31,7 +31,7 @@ e.g. to allow vim key bindings | ||||
| var EditTextWidget = require("$:/core/modules/widgets/edit-text.js")["edit-text"]; | ||||
|  | ||||
| if($tw.browser) { | ||||
| 	require("$:/plugins/tiddlywiki/codemirror/codemirror.js"); | ||||
| 	window.CodeMirror = require("$:/plugins/tiddlywiki/codemirror/lib/codemirror.js"); | ||||
|  | ||||
| 	configOptions = $tw.wiki.getTiddlerData(CODEMIRROR_OPTIONS,{}); | ||||
|  | ||||
| @@ -59,12 +59,11 @@ EditTextWidget.prototype.postRender = function() { | ||||
| 			lineWrapping: true, | ||||
| 			lineNumbers: true | ||||
| 		}; | ||||
|  | ||||
| 	if($tw.browser && window.CodeMirror && this.editTag === "textarea") { | ||||
| 		if(EditTextWidget.configuration) { | ||||
| 			for (cv in EditTextWidget.configuration) { cm_opts[cv] = EditTextWidget.configuration[cv]; } | ||||
| 		} | ||||
| 		cm = CodeMirror.fromTextArea(this.domNodes[0], cm_opts); | ||||
| 		cm = window.CodeMirror.fromTextArea(this.domNodes[0], cm_opts); | ||||
| 		cm.on("change",function() { | ||||
| 			self.saveChanges(cm.getValue()); | ||||
| 		}); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,54 +0,0 @@ | ||||
| { | ||||
| 	"tiddlers": [ | ||||
| 		{ | ||||
| 			"file": "codemirror.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/codemirror.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "codemirror.css", | ||||
| 			"fields": { | ||||
| 				"type": "text/css", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/codemirror.css", | ||||
| 				"tags": "[[$:/tags/stylesheet]]" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/dialog.css", | ||||
| 			"fields": { | ||||
| 				"type": "text/css", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/dialog.css", | ||||
| 				"tags": "[[$:/tags/stylesheet]]" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/dialog.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/dialog.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/searchcursor.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/searchcursor.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "keymap/vim.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/keymap/vim.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "keymap/emacs.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/keymap/emacs.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| @@ -10,8 +10,9 @@ For example: | ||||
| ``` | ||||
| { | ||||
|   "require": [ | ||||
|       "$:/plugins/tiddlywiki/codemirror/addon/dialog.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/addon/searchcursor.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/mode/javascript/javascript.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/addon/dialog/dialog.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/addon/search/searchcursor.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/keymap/vim.js", | ||||
|       "$:/plugins/tiddlywiki/codemirror/keymap/emacs.js" | ||||
|   ], | ||||
|   | ||||
| @@ -1,6 +1,13 @@ | ||||
| // Open simple dialogs on top of an editor. Relies on dialog.css.
 | ||||
| 
 | ||||
| (function() { | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS
 | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD
 | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env
 | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   function dialogDiv(cm, template, bottom) { | ||||
|     var wrap = cm.getWrapperElement(); | ||||
|     var dialog; | ||||
| @@ -35,9 +42,11 @@ | ||||
|     } | ||||
|     var inp = dialog.getElementsByTagName("input")[0], button; | ||||
|     if (inp) { | ||||
|       if (options && options.value) inp.value = options.value; | ||||
|       CodeMirror.on(inp, "keydown", function(e) { | ||||
|         if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } | ||||
|         if (e.keyCode == 13 || e.keyCode == 27) { | ||||
|           inp.blur(); | ||||
|           CodeMirror.e_stop(e); | ||||
|           close(); | ||||
|           me.focus(); | ||||
| @@ -118,4 +127,4 @@ | ||||
|     if (duration) | ||||
|       doneTimer = setTimeout(close, options.duration); | ||||
|   }); | ||||
| })(); | ||||
| }); | ||||
							
								
								
									
										117
									
								
								plugins/tiddlywiki/codemirror/lib/addon/edit/matchbrackets.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								plugins/tiddlywiki/codemirror/lib/addon/edit/matchbrackets.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && | ||||
|     (document.documentMode == null || document.documentMode < 8); | ||||
|  | ||||
|   var Pos = CodeMirror.Pos; | ||||
|  | ||||
|   var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; | ||||
|  | ||||
|   function findMatchingBracket(cm, where, strict, config) { | ||||
|     var line = cm.getLineHandle(where.line), pos = where.ch - 1; | ||||
|     var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; | ||||
|     if (!match) return null; | ||||
|     var dir = match.charAt(1) == ">" ? 1 : -1; | ||||
|     if (strict && (dir > 0) != (pos == where.ch)) return null; | ||||
|     var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); | ||||
|  | ||||
|     var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); | ||||
|     if (found == null) return null; | ||||
|     return {from: Pos(where.line, pos), to: found && found.pos, | ||||
|             match: found && found.ch == match.charAt(0), forward: dir > 0}; | ||||
|   } | ||||
|  | ||||
|   // bracketRegex is used to specify which type of bracket to scan | ||||
|   // should be a regexp, e.g. /[[\]]/ | ||||
|   // | ||||
|   // Note: If "where" is on an open bracket, then this bracket is ignored. | ||||
|   // | ||||
|   // Returns false when no bracket was found, null when it reached | ||||
|   // maxScanLines and gave up | ||||
|   function scanForBracket(cm, where, dir, style, config) { | ||||
|     var maxScanLen = (config && config.maxScanLineLength) || 10000; | ||||
|     var maxScanLines = (config && config.maxScanLines) || 1000; | ||||
|  | ||||
|     var stack = []; | ||||
|     var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\]]/; | ||||
|     var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) | ||||
|                           : Math.max(cm.firstLine() - 1, where.line - maxScanLines); | ||||
|     for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { | ||||
|       var line = cm.getLine(lineNo); | ||||
|       if (!line) continue; | ||||
|       var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; | ||||
|       if (line.length > maxScanLen) continue; | ||||
|       if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); | ||||
|       for (; pos != end; pos += dir) { | ||||
|         var ch = line.charAt(pos); | ||||
|         if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { | ||||
|           var match = matching[ch]; | ||||
|           if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); | ||||
|           else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; | ||||
|           else stack.pop(); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null; | ||||
|   } | ||||
|  | ||||
|   function matchBrackets(cm, autoclear, config) { | ||||
|     // Disable brace matching in long lines, since it'll cause hugely slow updates | ||||
|     var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; | ||||
|     var marks = [], ranges = cm.listSelections(); | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); | ||||
|       if (match && cm.getLine(match.from.line).length <= maxHighlightLen) { | ||||
|         var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; | ||||
|         marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); | ||||
|         if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen) | ||||
|           marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (marks.length) { | ||||
|       // Kludge to work around the IE bug from issue #1193, where text | ||||
|       // input stops going to the textare whever this fires. | ||||
|       if (ie_lt8 && cm.state.focused) cm.display.input.focus(); | ||||
|  | ||||
|       var clear = function() { | ||||
|         cm.operation(function() { | ||||
|           for (var i = 0; i < marks.length; i++) marks[i].clear(); | ||||
|         }); | ||||
|       }; | ||||
|       if (autoclear) setTimeout(clear, 800); | ||||
|       else return clear; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   var currentlyHighlighted = null; | ||||
|   function doMatchBrackets(cm) { | ||||
|     cm.operation(function() { | ||||
|       if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} | ||||
|       currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { | ||||
|     if (old && old != CodeMirror.Init) | ||||
|       cm.off("cursorActivity", doMatchBrackets); | ||||
|     if (val) { | ||||
|       cm.state.matchBrackets = typeof val == "object" ? val : {}; | ||||
|       cm.on("cursorActivity", doMatchBrackets); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); | ||||
|   CodeMirror.defineExtension("findMatchingBracket", function(pos, strict, config){ | ||||
|     return findMatchingBracket(this, pos, strict, config); | ||||
|   }); | ||||
|   CodeMirror.defineExtension("scanForBracket", function(pos, dir, style, config){ | ||||
|     return scanForBracket(this, pos, dir, style, config); | ||||
|   }); | ||||
| }); | ||||
| @@ -1,4 +1,12 @@ | ||||
| (function(){ | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS
 | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD
 | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env
 | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   "use strict"; | ||||
|   var Pos = CodeMirror.Pos; | ||||
| 
 | ||||
|   function SearchCursor(doc, query, pos, caseFold) { | ||||
| @@ -47,6 +55,7 @@ | ||||
|                   match: match}; | ||||
|       }; | ||||
|     } else { // String query
 | ||||
|       var origQuery = query; | ||||
|       if (caseFold) query = query.toLowerCase(); | ||||
|       var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; | ||||
|       var target = query.split("\n"); | ||||
| @@ -58,33 +67,45 @@ | ||||
|           this.matches = function() {}; | ||||
|         } else { | ||||
|           this.matches = function(reverse, pos) { | ||||
|             var line = fold(doc.getLine(pos.line)), len = query.length, match; | ||||
|             if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) | ||||
|                         : (match = line.indexOf(query, pos.ch)) != -1) | ||||
|               return {from: Pos(pos.line, match), | ||||
|                       to: Pos(pos.line, match + len)}; | ||||
|             if (reverse) { | ||||
|               var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); | ||||
|               var match = line.lastIndexOf(query); | ||||
|               if (match > -1) { | ||||
|                 match = adjustPos(orig, line, match); | ||||
|                 return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; | ||||
|               } | ||||
|              } else { | ||||
|                var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig); | ||||
|                var match = line.indexOf(query); | ||||
|                if (match > -1) { | ||||
|                  match = adjustPos(orig, line, match) + pos.ch; | ||||
|                  return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)}; | ||||
|                } | ||||
|             } | ||||
|           }; | ||||
|         } | ||||
|       } else { | ||||
|         var origTarget = origQuery.split("\n"); | ||||
|         this.matches = function(reverse, pos) { | ||||
|           var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln)); | ||||
|           var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); | ||||
|           if (reverse ? offsetA > pos.ch || offsetA != match.length | ||||
|               : offsetA < pos.ch || offsetA != line.length - match.length) | ||||
|             return; | ||||
|           for (;;) { | ||||
|             if (reverse ? !ln : ln == doc.lineCount() - 1) return; | ||||
|             line = fold(doc.getLine(ln += reverse ? -1 : 1)); | ||||
|             match = target[reverse ? --idx : ++idx]; | ||||
|             if (idx > 0 && idx < target.length - 1) { | ||||
|               if (line != match) return; | ||||
|               else continue; | ||||
|             } | ||||
|             var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); | ||||
|             if (reverse ? offsetB != line.length - match.length : offsetB != match.length) | ||||
|               return; | ||||
|             var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB); | ||||
|             return {from: reverse ? end : start, to: reverse ? start : end}; | ||||
|           var last = target.length - 1; | ||||
|           if (reverse) { | ||||
|             if (pos.line - (target.length - 1) < doc.firstLine()) return; | ||||
|             if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; | ||||
|             var to = Pos(pos.line, origTarget[last].length); | ||||
|             for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) | ||||
|               if (target[i] != fold(doc.getLine(ln))) return; | ||||
|             var line = doc.getLine(ln), cut = line.length - origTarget[0].length; | ||||
|             if (fold(line.slice(cut)) != target[0]) return; | ||||
|             return {from: Pos(ln, cut), to: to}; | ||||
|           } else { | ||||
|             if (pos.line + (target.length - 1) > doc.lastLine()) return; | ||||
|             var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; | ||||
|             if (fold(line.slice(cut)) != target[0]) return; | ||||
|             var from = Pos(pos.line, cut); | ||||
|             for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) | ||||
|               if (target[i] != fold(doc.getLine(ln))) return; | ||||
|             if (doc.getLine(ln).slice(0, origTarget[last].length) != target[last]) return; | ||||
|             return {from: from, to: Pos(ln, origTarget[last].length)}; | ||||
|           } | ||||
|         }; | ||||
|       } | ||||
| @@ -106,7 +127,6 @@ | ||||
| 
 | ||||
|       for (;;) { | ||||
|         if (this.pos = this.matches(reverse, pos)) { | ||||
|           if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); } | ||||
|           this.atOccurrence = true; | ||||
|           return this.pos.match || true; | ||||
|         } | ||||
| @@ -134,10 +154,33 @@ | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   // Maps a position in a case-folded line back to a position in the original line
 | ||||
|   // (compensating for codepoints increasing in number during folding)
 | ||||
|   function adjustPos(orig, folded, pos) { | ||||
|     if (orig.length == folded.length) return pos; | ||||
|     for (var pos1 = Math.min(pos, orig.length);;) { | ||||
|       var len1 = orig.slice(0, pos1).toLowerCase().length; | ||||
|       if (len1 < pos) ++pos1; | ||||
|       else if (len1 > pos) --pos1; | ||||
|       else return pos1; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { | ||||
|     return new SearchCursor(this.doc, query, pos, caseFold); | ||||
|   }); | ||||
|   CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { | ||||
|     return new SearchCursor(this, query, pos, caseFold); | ||||
|   }); | ||||
| })(); | ||||
| 
 | ||||
|   CodeMirror.defineExtension("selectMatches", function(query, caseFold) { | ||||
|     var ranges = [], next; | ||||
|     var cur = this.getSearchCursor(query, this.getCursor("from"), caseFold); | ||||
|     while (next = cur.findNext()) { | ||||
|       if (CodeMirror.cmpPos(cur.to(), this.getCursor("to")) > 0) break; | ||||
|       ranges.push({anchor: cur.from(), head: cur.to()}); | ||||
|     } | ||||
|     if (ranges.length) | ||||
|       this.setSelections(ranges, 0); | ||||
|   }); | ||||
| }); | ||||
| @@ -32,18 +32,18 @@ | ||||
| } | ||||
| .CodeMirror-linenumbers {} | ||||
| .CodeMirror-linenumber { | ||||
|   font-size: 12px; | ||||
|   min-width: 30px; | ||||
|   padding: 0 2px 0 2px; | ||||
|   padding: 0 3px 0 5px; | ||||
|   min-width: 20px; | ||||
|   text-align: right; | ||||
|   color: #999; | ||||
|   -moz-box-sizing: content-box; | ||||
|   box-sizing: content-box; | ||||
| } | ||||
| 
 | ||||
| /* CURSOR */ | ||||
| 
 | ||||
| .CodeMirror div.CodeMirror-cursor { | ||||
|   border-left: 1px solid black; | ||||
|   z-index: 3; | ||||
| } | ||||
| /* Shown when moving in bi-directional text */ | ||||
| .CodeMirror div.CodeMirror-secondarycursor { | ||||
| @@ -53,24 +53,29 @@ | ||||
|   width: auto; | ||||
|   border: 0; | ||||
|   background: #7e7; | ||||
|   z-index: 1; | ||||
| } | ||||
| /* Can style cursor different in overwrite (non-insert) mode */ | ||||
| .CodeMirror div.CodeMirror-cursor.CodeMirror-overwrite {} | ||||
| div.CodeMirror-overwrite div.CodeMirror-cursor {} | ||||
| 
 | ||||
| .cm-tab { display: inline-block; } | ||||
| 
 | ||||
| .CodeMirror-ruler { | ||||
|   border-left: 1px solid #ccc; | ||||
|   position: absolute; | ||||
| } | ||||
| 
 | ||||
| /* DEFAULT THEME */ | ||||
| 
 | ||||
| .cm-s-default .cm-keyword {color: #708;} | ||||
| .cm-s-default .cm-atom {color: #219;} | ||||
| .cm-s-default .cm-number {color: #164;} | ||||
| .cm-s-default .cm-def {color: #00f;} | ||||
| .cm-s-default .cm-variable {color: black;} | ||||
| .cm-s-default .cm-variable, | ||||
| .cm-s-default .cm-punctuation, | ||||
| .cm-s-default .cm-property, | ||||
| .cm-s-default .cm-operator {} | ||||
| .cm-s-default .cm-variable-2 {color: #05a;} | ||||
| .cm-s-default .cm-variable-3 {color: #085;} | ||||
| .cm-s-default .cm-property {color: black;} | ||||
| .cm-s-default .cm-operator {color: black;} | ||||
| .cm-s-default .cm-comment {color: #a50;} | ||||
| .cm-s-default .cm-string {color: #a11;} | ||||
| .cm-s-default .cm-string-2 {color: #f50;} | ||||
| @@ -115,7 +120,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | ||||
|   /* 30px is the magic margin used to hide the element's real scrollbars */ | ||||
|   /* See overflow: hidden in .CodeMirror */ | ||||
|   margin-bottom: -30px; margin-right: -30px; | ||||
|   padding-bottom: 30px; padding-right: 30px; | ||||
|   padding-bottom: 30px; | ||||
|   height: 100%; | ||||
|   outline: none; /* Prevent dragging from highlighting the element */ | ||||
|   position: relative; | ||||
| @@ -124,6 +129,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | ||||
| } | ||||
| .CodeMirror-sizer { | ||||
|   position: relative; | ||||
|   border-right: 30px solid transparent; | ||||
|   -moz-box-sizing: content-box; | ||||
|   box-sizing: content-box; | ||||
| } | ||||
| 
 | ||||
| /* The fake, visible scrollbars. Used to force redraw during scrolling | ||||
| @@ -198,16 +206,7 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | ||||
|   white-space: pre-wrap; | ||||
|   word-break: normal; | ||||
| } | ||||
| .CodeMirror-code pre { | ||||
|   border-right: 30px solid transparent; | ||||
|   width: -webkit-fit-content; | ||||
|   width: -moz-fit-content; | ||||
|   width: fit-content; | ||||
| } | ||||
| .CodeMirror-wrap .CodeMirror-code pre { | ||||
|   border-right: none; | ||||
|   width: auto; | ||||
| } | ||||
| 
 | ||||
| .CodeMirror-linebackground { | ||||
|   position: absolute; | ||||
|   left: 0; right: 0; top: 0; bottom: 0; | ||||
| @@ -237,16 +236,22 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | ||||
| 
 | ||||
| .CodeMirror div.CodeMirror-cursor { | ||||
|   position: absolute; | ||||
|   visibility: hidden; | ||||
|   border-right: none; | ||||
|   width: 0; | ||||
| } | ||||
| .CodeMirror-focused div.CodeMirror-cursor { | ||||
| 
 | ||||
| div.CodeMirror-cursors { | ||||
|   visibility: hidden; | ||||
|   position: relative; | ||||
|   z-index: 1; | ||||
| } | ||||
| .CodeMirror-focused div.CodeMirror-cursors { | ||||
|   visibility: visible; | ||||
| } | ||||
| 
 | ||||
| .CodeMirror-selected { background: #d9d9d9; } | ||||
| .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } | ||||
| .CodeMirror-crosshair { cursor: crosshair; } | ||||
| 
 | ||||
| .cm-searching { | ||||
|   background: #ffa; | ||||
| @@ -256,9 +261,12 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | ||||
| /* IE7 hack to prevent it from returning funny offsetTops on the spans */ | ||||
| .CodeMirror span { *vertical-align: text-bottom; } | ||||
| 
 | ||||
| /* Used to force a border model for a node */ | ||||
| .cm-force-border { padding-right: .1px; } | ||||
| 
 | ||||
| @media print { | ||||
|   /* Hide the cursor when printing */ | ||||
|   .CodeMirror div.CodeMirror-cursor { | ||||
|   .CodeMirror div.CodeMirror-cursors { | ||||
|     visibility: hidden; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										7587
									
								
								plugins/tiddlywiki/codemirror/lib/codemirror.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7587
									
								
								plugins/tiddlywiki/codemirror/lib/codemirror.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,4 +1,11 @@ | ||||
| (function() { | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS
 | ||||
|     mod(require("../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD
 | ||||
|     define(["../lib/codemirror"], mod); | ||||
|   else // Plain browser env
 | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   "use strict"; | ||||
| 
 | ||||
|   var Pos = CodeMirror.Pos; | ||||
| @@ -174,7 +181,7 @@ | ||||
|     if (dup > 1 && event.origin == "+input") { | ||||
|       var one = event.text.join("\n"), txt = ""; | ||||
|       for (var i = 1; i < dup; ++i) txt += one; | ||||
|       cm.replaceSelection(txt, "end", "+input"); | ||||
|       cm.replaceSelection(txt); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @@ -197,10 +204,15 @@ | ||||
| 
 | ||||
|   function setMark(cm) { | ||||
|     cm.setCursor(cm.getCursor()); | ||||
|     cm.setExtending(true); | ||||
|     cm.setExtending(!cm.getExtending()); | ||||
|     cm.on("change", function() { cm.setExtending(false); }); | ||||
|   } | ||||
| 
 | ||||
|   function clearMark(cm) { | ||||
|     cm.setExtending(false); | ||||
|     cm.setCursor(cm.getCursor()); | ||||
|   } | ||||
| 
 | ||||
|   function getInput(cm, msg, f) { | ||||
|     if (cm.openDialog) | ||||
|       cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true}); | ||||
| @@ -234,6 +246,11 @@ | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   function quit(cm) { | ||||
|     cm.execCommand("clearSearch"); | ||||
|     clearMark(cm); | ||||
|   } | ||||
| 
 | ||||
|   // Actual keymap
 | ||||
| 
 | ||||
|   var keyMap = CodeMirror.keyMap.emacs = { | ||||
| @@ -249,13 +266,14 @@ | ||||
|     }), | ||||
|     "Alt-W": function(cm) { | ||||
|       addToRing(cm.getSelection()); | ||||
|       clearMark(cm); | ||||
|     }, | ||||
|     "Ctrl-Y": function(cm) { | ||||
|       var start = cm.getCursor(); | ||||
|       cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste"); | ||||
|       cm.setSelection(start, cm.getCursor()); | ||||
|     }, | ||||
|     "Alt-Y": function(cm) {cm.replaceSelection(popFromRing());}, | ||||
|     "Alt-Y": function(cm) {cm.replaceSelection(popFromRing(), "around", "paste");}, | ||||
| 
 | ||||
|     "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark, | ||||
| 
 | ||||
| @@ -306,13 +324,7 @@ | ||||
|     }, | ||||
|     "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }), | ||||
|     "Ctrl-T": repeated(function(cm) { | ||||
|       var pos = cm.getCursor(); | ||||
|       if (pos.ch < cm.getLine(pos.line).length) pos = Pos(pos.line, pos.ch + 1); | ||||
|       var from = cm.findPosH(pos, -2, "char"); | ||||
|       var range = cm.getRange(from, pos); | ||||
|       if (range.length != 2) return; | ||||
|       cm.setSelection(from, pos); | ||||
|       cm.replaceSelection(range.charAt(1) + range.charAt(0), "end"); | ||||
|       cm.execCommand("transposeChars"); | ||||
|     }), | ||||
| 
 | ||||
|     "Alt-C": repeated(function(cm) { | ||||
| @@ -334,7 +346,7 @@ | ||||
|     "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"), | ||||
|     "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"), | ||||
|     "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd", | ||||
|     "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": "clearSearch", "Shift-Alt-5": "replace", | ||||
|     "Ctrl-S": "findNext", "Ctrl-R": "findPrev", "Ctrl-G": quit, "Shift-Alt-5": "replace", | ||||
|     "Alt-/": "autocomplete", | ||||
|     "Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto", | ||||
| 
 | ||||
| @@ -384,4 +396,4 @@ | ||||
|   } | ||||
|   for (var i = 0; i < 10; ++i) regPrefix(String(i)); | ||||
|   regPrefix("-"); | ||||
| })(); | ||||
| }); | ||||
							
								
								
									
										517
									
								
								plugins/tiddlywiki/codemirror/lib/keymap/sublime.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										517
									
								
								plugins/tiddlywiki/codemirror/lib/keymap/sublime.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,517 @@ | ||||
| // A rough approximation of Sublime Text's keybindings | ||||
| // Depends on addon/search/searchcursor.js and optionally addon/dialog/dialogs.js | ||||
|  | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
|     mod(require("../lib/codemirror"), require("../addon/search/searchcursor"), require("../addon/edit/matchbrackets")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD | ||||
|     define(["../lib/codemirror", "../addon/search/searchcursor", "../addon/edit/matchbrackets"], mod); | ||||
|   else // Plain browser env | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   "use strict"; | ||||
|  | ||||
|   var map = CodeMirror.keyMap.sublime = {fallthrough: "default"}; | ||||
|   var cmds = CodeMirror.commands; | ||||
|   var Pos = CodeMirror.Pos; | ||||
|   var ctrl = CodeMirror.keyMap["default"] == CodeMirror.keyMap.pcDefault ? "Ctrl-" : "Cmd-"; | ||||
|  | ||||
|   // This is not exactly Sublime's algorithm. I couldn't make heads or tails of that. | ||||
|   function findPosSubword(doc, start, dir) { | ||||
|     if (dir < 0 && start.ch == 0) return doc.clipPos(Pos(start.line - 1)); | ||||
|     var line = doc.getLine(start.line); | ||||
|     if (dir > 0 && start.ch >= line.length) return doc.clipPos(Pos(start.line + 1, 0)); | ||||
|     var state = "start", type; | ||||
|     for (var pos = start.ch, e = dir < 0 ? 0 : line.length, i = 0; pos != e; pos += dir, i++) { | ||||
|       var next = line.charAt(dir < 0 ? pos - 1 : pos); | ||||
|       var cat = next != "_" && CodeMirror.isWordChar(next) ? "w" : "o"; | ||||
|       if (cat == "w" && next.toUpperCase() == next) cat = "W"; | ||||
|       if (state == "start") { | ||||
|         if (cat != "o") { state = "in"; type = cat; } | ||||
|       } else if (state == "in") { | ||||
|         if (type != cat) { | ||||
|           if (type == "w" && cat == "W" && dir < 0) pos--; | ||||
|           if (type == "W" && cat == "w" && dir > 0) { type = "w"; continue; } | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return Pos(start.line, pos); | ||||
|   } | ||||
|  | ||||
|   function moveSubword(cm, dir) { | ||||
|     cm.extendSelectionsBy(function(range) { | ||||
|       if (cm.display.shift || cm.doc.extend || range.empty()) | ||||
|         return findPosSubword(cm.doc, range.head, dir); | ||||
|       else | ||||
|         return dir < 0 ? range.from() : range.to(); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); }; | ||||
|   cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); }; | ||||
|  | ||||
|   cmds[map[ctrl + "Up"] = "scrollLineUp"] = function(cm) { | ||||
|     var info = cm.getScrollInfo(); | ||||
|     if (!cm.somethingSelected()) { | ||||
|       var visibleBottomLine = cm.lineAtHeight(info.top + info.clientHeight, "local"); | ||||
|       if (cm.getCursor().line >= visibleBottomLine) | ||||
|         cm.execCommand("goLineUp"); | ||||
|     } | ||||
|     cm.scrollTo(null, info.top - cm.defaultTextHeight()); | ||||
|   }; | ||||
|   cmds[map[ctrl + "Down"] = "scrollLineDown"] = function(cm) { | ||||
|     var info = cm.getScrollInfo(); | ||||
|     if (!cm.somethingSelected()) { | ||||
|       var visibleTopLine = cm.lineAtHeight(info.top, "local")+1; | ||||
|       if (cm.getCursor().line <= visibleTopLine) | ||||
|         cm.execCommand("goLineDown"); | ||||
|     } | ||||
|     cm.scrollTo(null, info.top + cm.defaultTextHeight()); | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "L"] = "splitSelectionByLine"] = function(cm) { | ||||
|     var ranges = cm.listSelections(), lineRanges = []; | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var from = ranges[i].from(), to = ranges[i].to(); | ||||
|       for (var line = from.line; line <= to.line; ++line) | ||||
|         if (!(to.line > from.line && line == to.line && to.ch == 0)) | ||||
|           lineRanges.push({anchor: line == from.line ? from : Pos(line, 0), | ||||
|                            head: line == to.line ? to : Pos(line)}); | ||||
|     } | ||||
|     cm.setSelections(lineRanges, 0); | ||||
|   }; | ||||
|  | ||||
|   map["Shift-Tab"] = "indentLess"; | ||||
|  | ||||
|   cmds[map["Esc"] = "singleSelectionTop"] = function(cm) { | ||||
|     var range = cm.listSelections()[0]; | ||||
|     cm.setSelection(range.anchor, range.head, {scroll: false}); | ||||
|   }; | ||||
|  | ||||
|   cmds[map[ctrl + "L"] = "selectLine"] = function(cm) { | ||||
|     var ranges = cm.listSelections(), extended = []; | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var range = ranges[i]; | ||||
|       extended.push({anchor: Pos(range.from().line, 0), | ||||
|                      head: Pos(range.to().line + 1, 0)}); | ||||
|     } | ||||
|     cm.setSelections(extended); | ||||
|   }; | ||||
|  | ||||
|   map["Shift-" + ctrl + "K"] = "deleteLine"; | ||||
|  | ||||
|   function insertLine(cm, above) { | ||||
|     cm.operation(function() { | ||||
|       var len = cm.listSelections().length, newSelection = [], last = -1; | ||||
|       for (var i = 0; i < len; i++) { | ||||
|         var head = cm.listSelections()[i].head; | ||||
|         if (head.line <= last) continue; | ||||
|         var at = Pos(head.line + (above ? 0 : 1), 0); | ||||
|         cm.replaceRange("\n", at, null, "+insertLine"); | ||||
|         cm.indentLine(at.line, null, true); | ||||
|         newSelection.push({head: at, anchor: at}); | ||||
|         last = head.line + 1; | ||||
|       } | ||||
|       cm.setSelections(newSelection); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { insertLine(cm, false); }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "Enter"] = "insertLineBefore"] = function(cm) { insertLine(cm, true); }; | ||||
|  | ||||
|   function wordAt(cm, pos) { | ||||
|     var start = pos.ch, end = start, line = cm.getLine(pos.line); | ||||
|     while (start && CodeMirror.isWordChar(line.charAt(start - 1))) --start; | ||||
|     while (end < line.length && CodeMirror.isWordChar(line.charAt(end))) ++end; | ||||
|     return {from: Pos(pos.line, start), to: Pos(pos.line, end), word: line.slice(start, end)}; | ||||
|   } | ||||
|  | ||||
|   cmds[map[ctrl + "D"] = "selectNextOccurrence"] = function(cm) { | ||||
|     var from = cm.getCursor("from"), to = cm.getCursor("to"); | ||||
|     var fullWord = cm.state.sublimeFindFullWord == cm.doc.sel; | ||||
|     if (CodeMirror.cmpPos(from, to) == 0) { | ||||
|       var word = wordAt(cm, from); | ||||
|       if (!word.word) return; | ||||
|       cm.setSelection(word.from, word.to); | ||||
|       fullWord = true; | ||||
|     } else { | ||||
|       var text = cm.getRange(from, to); | ||||
|       var query = fullWord ? new RegExp("\\b" + text + "\\b") : text; | ||||
|       var cur = cm.getSearchCursor(query, to); | ||||
|       if (cur.findNext()) { | ||||
|         cm.addSelection(cur.from(), cur.to()); | ||||
|       } else { | ||||
|         cur = cm.getSearchCursor(query, Pos(cm.firstLine(), 0)); | ||||
|         if (cur.findNext()) | ||||
|           cm.addSelection(cur.from(), cur.to()); | ||||
|       } | ||||
|     } | ||||
|     if (fullWord) | ||||
|       cm.state.sublimeFindFullWord = cm.doc.sel; | ||||
|   }; | ||||
|  | ||||
|   var mirror = "(){}[]"; | ||||
|   function selectBetweenBrackets(cm) { | ||||
|     var pos = cm.getCursor(), opening = cm.scanForBracket(pos, -1); | ||||
|     if (!opening) return; | ||||
|     for (;;) { | ||||
|       var closing = cm.scanForBracket(pos, 1); | ||||
|       if (!closing) return; | ||||
|       if (closing.ch == mirror.charAt(mirror.indexOf(opening.ch) + 1)) { | ||||
|         cm.setSelection(Pos(opening.pos.line, opening.pos.ch + 1), closing.pos, false); | ||||
|         return true; | ||||
|       } | ||||
|       pos = Pos(closing.pos.line, closing.pos.ch + 1); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "Space"] = "selectScope"] = function(cm) { | ||||
|     selectBetweenBrackets(cm) || cm.execCommand("selectAll"); | ||||
|   }; | ||||
|   cmds[map["Shift-" + ctrl + "M"] = "selectBetweenBrackets"] = function(cm) { | ||||
|     if (!selectBetweenBrackets(cm)) return CodeMirror.Pass; | ||||
|   }; | ||||
|  | ||||
|   cmds[map[ctrl + "M"] = "goToBracket"] = function(cm) { | ||||
|     cm.extendSelectionsBy(function(range) { | ||||
|       var next = cm.scanForBracket(range.head, 1); | ||||
|       if (next && CodeMirror.cmpPos(next.pos, range.head) != 0) return next.pos; | ||||
|       var prev = cm.scanForBracket(range.head, -1); | ||||
|       return prev && Pos(prev.pos.line, prev.pos.ch + 1) || range.head; | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "Up"] = "swapLineUp"] = function(cm) { | ||||
|     var ranges = cm.listSelections(), linesToMove = [], at = cm.firstLine() - 1; | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var range = ranges[i], from = range.from().line - 1, to = range.to().line; | ||||
|       if (from > at) linesToMove.push(from, to); | ||||
|       else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; | ||||
|       at = to; | ||||
|     } | ||||
|     cm.operation(function() { | ||||
|       for (var i = 0; i < linesToMove.length; i += 2) { | ||||
|         var from = linesToMove[i], to = linesToMove[i + 1]; | ||||
|         var line = cm.getLine(from); | ||||
|         cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); | ||||
|         if (to > cm.lastLine()) { | ||||
|           cm.replaceRange("\n" + line, Pos(cm.lastLine()), null, "+swapLine"); | ||||
|           var sels = cm.listSelections(), last = sels[sels.length - 1]; | ||||
|           var head = last.head.line == to ? Pos(to - 1) : last.head; | ||||
|           var anchor = last.anchor.line == to ? Pos(to - 1) : last.anchor; | ||||
|           cm.setSelections(sels.slice(0, sels.length - 1).concat([{head: head, anchor: anchor}])); | ||||
|         } else { | ||||
|           cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); | ||||
|         } | ||||
|       } | ||||
|       cm.scrollIntoView(); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "Down"] = "swapLineDown"] = function(cm) { | ||||
|     var ranges = cm.listSelections(), linesToMove = [], at = cm.lastLine() + 1; | ||||
|     for (var i = ranges.length - 1; i >= 0; i--) { | ||||
|       var range = ranges[i], from = range.to().line + 1, to = range.from().line; | ||||
|       if (from < at) linesToMove.push(from, to); | ||||
|       else if (linesToMove.length) linesToMove[linesToMove.length - 1] = to; | ||||
|       at = to; | ||||
|     } | ||||
|     cm.operation(function() { | ||||
|       for (var i = linesToMove.length - 2; i >= 0; i -= 2) { | ||||
|         var from = linesToMove[i], to = linesToMove[i + 1]; | ||||
|         var line = cm.getLine(from); | ||||
|         if (from == cm.lastLine()) | ||||
|           cm.replaceRange("", Pos(from - 1), Pos(from), "+swapLine"); | ||||
|         else | ||||
|           cm.replaceRange("", Pos(from, 0), Pos(from + 1, 0), "+swapLine"); | ||||
|         cm.replaceRange(line + "\n", Pos(to, 0), null, "+swapLine"); | ||||
|       } | ||||
|       cm.scrollIntoView(); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   map[ctrl + "/"] = "toggleComment"; | ||||
|  | ||||
|   cmds[map[ctrl + "J"] = "joinLines"] = function(cm) { | ||||
|     var ranges = cm.listSelections(), joined = []; | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var range = ranges[i], from = range.from(); | ||||
|       var start = from.line, end = range.to().line; | ||||
|       while (i < ranges.length - 1 && ranges[i + 1].from().line == end) | ||||
|         end = ranges[++i].to().line; | ||||
|       joined.push({start: start, end: end, anchor: !range.empty() && from}); | ||||
|     } | ||||
|     cm.operation(function() { | ||||
|       var offset = 0, ranges = []; | ||||
|       for (var i = 0; i < joined.length; i++) { | ||||
|         var obj = joined[i]; | ||||
|         var anchor = obj.anchor && Pos(obj.anchor.line - offset, obj.anchor.ch), head; | ||||
|         for (var line = obj.start; line <= obj.end; line++) { | ||||
|           var actual = line - offset; | ||||
|           if (line == obj.end) head = Pos(actual, cm.getLine(actual).length + 1); | ||||
|           if (actual < cm.lastLine()) { | ||||
|             cm.replaceRange(" ", Pos(actual), Pos(actual + 1, /^\s*/.exec(cm.getLine(actual + 1))[0].length)); | ||||
|             ++offset; | ||||
|           } | ||||
|         } | ||||
|         ranges.push({anchor: anchor || head, head: head}); | ||||
|       } | ||||
|       cm.setSelections(ranges, 0); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "D"] = "duplicateLine"] = function(cm) { | ||||
|     cm.operation(function() { | ||||
|       var rangeCount = cm.listSelections().length; | ||||
|       for (var i = 0; i < rangeCount; i++) { | ||||
|         var range = cm.listSelections()[i]; | ||||
|         if (range.empty()) | ||||
|           cm.replaceRange(cm.getLine(range.head.line) + "\n", Pos(range.head.line, 0)); | ||||
|         else | ||||
|           cm.replaceRange(cm.getRange(range.from(), range.to()), range.from()); | ||||
|       } | ||||
|       cm.scrollIntoView(); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   map[ctrl + "T"] = "transposeChars"; | ||||
|  | ||||
|   function sortLines(cm, caseSensitive) { | ||||
|     var ranges = cm.listSelections(), toSort = [], selected; | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var range = ranges[i]; | ||||
|       if (range.empty()) continue; | ||||
|       var from = range.from().line, to = range.to().line; | ||||
|       while (i < ranges.length - 1 && ranges[i + 1].from().line == to) | ||||
|         to = range[++i].to().line; | ||||
|       toSort.push(from, to); | ||||
|     } | ||||
|     if (toSort.length) selected = true; | ||||
|     else toSort.push(cm.firstLine(), cm.lastLine()); | ||||
|  | ||||
|     cm.operation(function() { | ||||
|       var ranges = []; | ||||
|       for (var i = 0; i < toSort.length; i += 2) { | ||||
|         var from = toSort[i], to = toSort[i + 1]; | ||||
|         var start = Pos(from, 0), end = Pos(to); | ||||
|         var lines = cm.getRange(start, end, false); | ||||
|         if (caseSensitive) | ||||
|           lines.sort(); | ||||
|         else | ||||
|           lines.sort(function(a, b) { | ||||
|             var au = a.toUpperCase(), bu = b.toUpperCase(); | ||||
|             if (au != bu) { a = au; b = bu; } | ||||
|             return a < b ? -1 : a == b ? 0 : 1; | ||||
|           }); | ||||
|         cm.replaceRange(lines, start, end); | ||||
|         if (selected) ranges.push({anchor: start, head: end}); | ||||
|       } | ||||
|       if (selected) cm.setSelections(ranges, 0); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   cmds[map["F9"] = "sortLines"] = function(cm) { sortLines(cm, true); }; | ||||
|   cmds[map[ctrl + "F9"] = "sortLinesInsensitive"] = function(cm) { sortLines(cm, false); }; | ||||
|  | ||||
|   cmds[map["F2"] = "nextBookmark"] = function(cm) { | ||||
|     var marks = cm.state.sublimeBookmarks; | ||||
|     if (marks) while (marks.length) { | ||||
|       var current = marks.shift(); | ||||
|       var found = current.find(); | ||||
|       if (found) { | ||||
|         marks.push(current); | ||||
|         return cm.setSelection(found.from, found.to); | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-F2"] = "prevBookmark"] = function(cm) { | ||||
|     var marks = cm.state.sublimeBookmarks; | ||||
|     if (marks) while (marks.length) { | ||||
|       marks.unshift(marks.pop()); | ||||
|       var found = marks[marks.length - 1].find(); | ||||
|       if (!found) | ||||
|         marks.pop(); | ||||
|       else | ||||
|         return cm.setSelection(found.from, found.to); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   cmds[map[ctrl + "F2"] = "toggleBookmark"] = function(cm) { | ||||
|     var ranges = cm.listSelections(); | ||||
|     var marks = cm.state.sublimeBookmarks || (cm.state.sublimeBookmarks = []); | ||||
|     for (var i = 0; i < ranges.length; i++) { | ||||
|       var from = ranges[i].from(), to = ranges[i].to(); | ||||
|       var found = cm.findMarks(from, to); | ||||
|       for (var j = 0; j < found.length; j++) { | ||||
|         if (found[j].sublimeBookmark) { | ||||
|           found[j].clear(); | ||||
|           for (var k = 0; k < marks.length; k++) | ||||
|             if (marks[k] == found[j]) | ||||
|               marks.splice(k--, 1); | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       if (j == found.length) | ||||
|         marks.push(cm.markText(from, to, {sublimeBookmark: true, clearWhenEmpty: false})); | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-" + ctrl + "F2"] = "clearBookmarks"] = function(cm) { | ||||
|     var marks = cm.state.sublimeBookmarks; | ||||
|     if (marks) for (var i = 0; i < marks.length; i++) marks[i].clear(); | ||||
|     marks.length = 0; | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Alt-F2"] = "selectBookmarks"] = function(cm) { | ||||
|     var marks = cm.state.sublimeBookmarks, ranges = []; | ||||
|     if (marks) for (var i = 0; i < marks.length; i++) { | ||||
|       var found = marks[i].find(); | ||||
|       if (!found) | ||||
|         marks.splice(i--, 0); | ||||
|       else | ||||
|         ranges.push({anchor: found.from, head: found.to}); | ||||
|     } | ||||
|     if (ranges.length) | ||||
|       cm.setSelections(ranges, 0); | ||||
|   }; | ||||
|  | ||||
|   map["Alt-Q"] = "wrapLines"; | ||||
|  | ||||
|   var mapK = CodeMirror.keyMap["sublime-Ctrl-K"] = {auto: "sublime", nofallthrough: true}; | ||||
|  | ||||
|   map[ctrl + "K"] = function(cm) {cm.setOption("keyMap", "sublime-Ctrl-K");}; | ||||
|  | ||||
|   function modifyWordOrSelection(cm, mod) { | ||||
|     cm.operation(function() { | ||||
|       var ranges = cm.listSelections(), indices = [], replacements = []; | ||||
|       for (var i = 0; i < ranges.length; i++) { | ||||
|         var range = ranges[i]; | ||||
|         if (range.empty()) { indices.push(i); replacements.push(""); } | ||||
|         else replacements.push(mod(cm.getRange(range.from(), range.to()))); | ||||
|       } | ||||
|       cm.replaceSelections(replacements, "around", "case"); | ||||
|       for (var i = indices.length - 1, at; i >= 0; i--) { | ||||
|         var range = ranges[indices[i]]; | ||||
|         if (at && CodeMirror.cmpPos(range.head, at) > 0) continue; | ||||
|         var word = wordAt(cm, range.head); | ||||
|         at = word.from; | ||||
|         cm.replaceRange(mod(word.word), word.from, word.to); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   mapK[ctrl + "Backspace"] = "delLineLeft"; | ||||
|  | ||||
|   cmds[mapK[ctrl + "K"] = "delLineRight"] = function(cm) { | ||||
|     cm.operation(function() { | ||||
|       var ranges = cm.listSelections(); | ||||
|       for (var i = ranges.length - 1; i >= 0; i--) | ||||
|         cm.replaceRange("", ranges[i].anchor, Pos(ranges[i].to().line), "+delete"); | ||||
|       cm.scrollIntoView(); | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   cmds[mapK[ctrl + "U"] = "upcaseAtCursor"] = function(cm) { | ||||
|     modifyWordOrSelection(cm, function(str) { return str.toUpperCase(); }); | ||||
|   }; | ||||
|   cmds[mapK[ctrl + "L"] = "downcaseAtCursor"] = function(cm) { | ||||
|     modifyWordOrSelection(cm, function(str) { return str.toLowerCase(); }); | ||||
|   }; | ||||
|  | ||||
|   cmds[mapK[ctrl + "Space"] = "setSublimeMark"] = function(cm) { | ||||
|     if (cm.state.sublimeMark) cm.state.sublimeMark.clear(); | ||||
|     cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); | ||||
|   }; | ||||
|   cmds[mapK[ctrl + "A"] = "selectToSublimeMark"] = function(cm) { | ||||
|     var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); | ||||
|     if (found) cm.setSelection(cm.getCursor(), found); | ||||
|   }; | ||||
|   cmds[mapK[ctrl + "W"] = "deleteToSublimeMark"] = function(cm) { | ||||
|     var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); | ||||
|     if (found) { | ||||
|       var from = cm.getCursor(), to = found; | ||||
|       if (CodeMirror.cmpPos(from, to) > 0) { var tmp = to; to = from; from = tmp; } | ||||
|       cm.state.sublimeKilled = cm.getRange(from, to); | ||||
|       cm.replaceRange("", from, to); | ||||
|     } | ||||
|   }; | ||||
|   cmds[mapK[ctrl + "X"] = "swapWithSublimeMark"] = function(cm) { | ||||
|     var found = cm.state.sublimeMark && cm.state.sublimeMark.find(); | ||||
|     if (found) { | ||||
|       cm.state.sublimeMark.clear(); | ||||
|       cm.state.sublimeMark = cm.setBookmark(cm.getCursor()); | ||||
|       cm.setCursor(found); | ||||
|     } | ||||
|   }; | ||||
|   cmds[mapK[ctrl + "Y"] = "sublimeYank"] = function(cm) { | ||||
|     if (cm.state.sublimeKilled != null) | ||||
|       cm.replaceSelection(cm.state.sublimeKilled, null, "paste"); | ||||
|   }; | ||||
|  | ||||
|   mapK[ctrl + "G"] = "clearBookmarks"; | ||||
|   cmds[mapK[ctrl + "C"] = "showInCenter"] = function(cm) { | ||||
|     var pos = cm.cursorCoords(null, "local"); | ||||
|     cm.scrollTo(null, (pos.top + pos.bottom) / 2 - cm.getScrollInfo().clientHeight / 2); | ||||
|   }; | ||||
|  | ||||
|   cmds[map["Shift-Alt-Up"] = "selectLinesUpward"] = function(cm) { | ||||
|     cm.operation(function() { | ||||
|       var ranges = cm.listSelections(); | ||||
|       for (var i = 0; i < ranges.length; i++) { | ||||
|         var range = ranges[i]; | ||||
|         if (range.head.line > cm.firstLine()) | ||||
|           cm.addSelection(Pos(range.head.line - 1, range.head.ch)); | ||||
|       } | ||||
|     }); | ||||
|   }; | ||||
|   cmds[map["Shift-Alt-Down"] = "selectLinesDownward"] = function(cm) { | ||||
|     cm.operation(function() { | ||||
|       var ranges = cm.listSelections(); | ||||
|       for (var i = 0; i < ranges.length; i++) { | ||||
|         var range = ranges[i]; | ||||
|         if (range.head.line < cm.lastLine()) | ||||
|           cm.addSelection(Pos(range.head.line + 1, range.head.ch)); | ||||
|       } | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   function findAndGoTo(cm, forward) { | ||||
|     var from = cm.getCursor("from"), to = cm.getCursor("to"); | ||||
|     if (CodeMirror.cmpPos(from, to) == 0) { | ||||
|       var word = wordAt(cm, from); | ||||
|       if (!word.word) return; | ||||
|       from = word.from; | ||||
|       to = word.to; | ||||
|     } | ||||
|  | ||||
|     var query = cm.getRange(from, to); | ||||
|     var cur = cm.getSearchCursor(query, forward ? to : from); | ||||
|  | ||||
|     if (forward ? cur.findNext() : cur.findPrevious()) { | ||||
|       cm.setSelection(cur.from(), cur.to()); | ||||
|     } else { | ||||
|       cur = cm.getSearchCursor(query, forward ? Pos(cm.firstLine(), 0) | ||||
|                                               : cm.clipPos(Pos(cm.lastLine()))); | ||||
|       if (forward ? cur.findNext() : cur.findPrevious()) | ||||
|         cm.setSelection(cur.from(), cur.to()); | ||||
|       else if (word) | ||||
|         cm.setSelection(from, to); | ||||
|     } | ||||
|   }; | ||||
|   cmds[map[ctrl + "F3"] = "findUnder"] = function(cm) { findAndGoTo(cm, true); }; | ||||
|   cmds[map["Shift-" + ctrl + "F3"] = "findUnderPrevious"] = function(cm) { findAndGoTo(cm,false); }; | ||||
|  | ||||
|   map["Shift-" + ctrl + "["] = "fold"; | ||||
|   map["Shift-" + ctrl + "]"] = "unfold"; | ||||
|   mapK[ctrl + "0"] = mapK[ctrl + "j"] = "unfoldAll"; | ||||
|  | ||||
|   map[ctrl + "I"] = "findIncremental"; | ||||
|   map["Shift-" + ctrl + "I"] = "findIncrementalReverse"; | ||||
|   map[ctrl + "H"] = "replace"; | ||||
|   map["F3"] = "findNext"; | ||||
|   map["Shift-F3"] = "findPrev"; | ||||
|  | ||||
| }); | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										660
									
								
								plugins/tiddlywiki/codemirror/lib/mode/javascript/javascript.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										660
									
								
								plugins/tiddlywiki/codemirror/lib/mode/javascript/javascript.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,660 @@ | ||||
| // TODO actually recognize syntax of TypeScript constructs | ||||
|  | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
| "use strict"; | ||||
|  | ||||
| CodeMirror.defineMode("javascript", function(config, parserConfig) { | ||||
|   var indentUnit = config.indentUnit; | ||||
|   var statementIndent = parserConfig.statementIndent; | ||||
|   var jsonldMode = parserConfig.jsonld; | ||||
|   var jsonMode = parserConfig.json || jsonldMode; | ||||
|   var isTS = parserConfig.typescript; | ||||
|  | ||||
|   // Tokenizer | ||||
|  | ||||
|   var keywords = function(){ | ||||
|     function kw(type) {return {type: type, style: "keyword"};} | ||||
|     var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); | ||||
|     var operator = kw("operator"), atom = {type: "atom", style: "atom"}; | ||||
|  | ||||
|     var jsKeywords = { | ||||
|       "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, | ||||
|       "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, | ||||
|       "var": kw("var"), "const": kw("var"), "let": kw("var"), | ||||
|       "function": kw("function"), "catch": kw("catch"), | ||||
|       "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), | ||||
|       "in": operator, "typeof": operator, "instanceof": operator, | ||||
|       "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, | ||||
|       "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), | ||||
|       "yield": C, "export": kw("export"), "import": kw("import"), "extends": C | ||||
|     }; | ||||
|  | ||||
|     // Extend the 'normal' keywords with the TypeScript language extensions | ||||
|     if (isTS) { | ||||
|       var type = {type: "variable", style: "variable-3"}; | ||||
|       var tsKeywords = { | ||||
|         // object-like things | ||||
|         "interface": kw("interface"), | ||||
|         "extends": kw("extends"), | ||||
|         "constructor": kw("constructor"), | ||||
|  | ||||
|         // scope modifiers | ||||
|         "public": kw("public"), | ||||
|         "private": kw("private"), | ||||
|         "protected": kw("protected"), | ||||
|         "static": kw("static"), | ||||
|  | ||||
|         // types | ||||
|         "string": type, "number": type, "bool": type, "any": type | ||||
|       }; | ||||
|  | ||||
|       for (var attr in tsKeywords) { | ||||
|         jsKeywords[attr] = tsKeywords[attr]; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return jsKeywords; | ||||
|   }(); | ||||
|  | ||||
|   var isOperatorChar = /[+\-*&%=<>!?|~^]/; | ||||
|   var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; | ||||
|  | ||||
|   function readRegexp(stream) { | ||||
|     var escaped = false, next, inSet = false; | ||||
|     while ((next = stream.next()) != null) { | ||||
|       if (!escaped) { | ||||
|         if (next == "/" && !inSet) return; | ||||
|         if (next == "[") inSet = true; | ||||
|         else if (inSet && next == "]") inSet = false; | ||||
|       } | ||||
|       escaped = !escaped && next == "\\"; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Used as scratch variables to communicate multiple values without | ||||
|   // consing up tons of objects. | ||||
|   var type, content; | ||||
|   function ret(tp, style, cont) { | ||||
|     type = tp; content = cont; | ||||
|     return style; | ||||
|   } | ||||
|   function tokenBase(stream, state) { | ||||
|     var ch = stream.next(); | ||||
|     if (ch == '"' || ch == "'") { | ||||
|       state.tokenize = tokenString(ch); | ||||
|       return state.tokenize(stream, state); | ||||
|     } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { | ||||
|       return ret("number", "number"); | ||||
|     } else if (ch == "." && stream.match("..")) { | ||||
|       return ret("spread", "meta"); | ||||
|     } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { | ||||
|       return ret(ch); | ||||
|     } else if (ch == "=" && stream.eat(">")) { | ||||
|       return ret("=>", "operator"); | ||||
|     } else if (ch == "0" && stream.eat(/x/i)) { | ||||
|       stream.eatWhile(/[\da-f]/i); | ||||
|       return ret("number", "number"); | ||||
|     } else if (/\d/.test(ch)) { | ||||
|       stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); | ||||
|       return ret("number", "number"); | ||||
|     } else if (ch == "/") { | ||||
|       if (stream.eat("*")) { | ||||
|         state.tokenize = tokenComment; | ||||
|         return tokenComment(stream, state); | ||||
|       } else if (stream.eat("/")) { | ||||
|         stream.skipToEnd(); | ||||
|         return ret("comment", "comment"); | ||||
|       } else if (state.lastType == "operator" || state.lastType == "keyword c" || | ||||
|                state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { | ||||
|         readRegexp(stream); | ||||
|         stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla | ||||
|         return ret("regexp", "string-2"); | ||||
|       } else { | ||||
|         stream.eatWhile(isOperatorChar); | ||||
|         return ret("operator", "operator", stream.current()); | ||||
|       } | ||||
|     } else if (ch == "`") { | ||||
|       state.tokenize = tokenQuasi; | ||||
|       return tokenQuasi(stream, state); | ||||
|     } else if (ch == "#") { | ||||
|       stream.skipToEnd(); | ||||
|       return ret("error", "error"); | ||||
|     } else if (isOperatorChar.test(ch)) { | ||||
|       stream.eatWhile(isOperatorChar); | ||||
|       return ret("operator", "operator", stream.current()); | ||||
|     } else { | ||||
|       stream.eatWhile(/[\w\$_]/); | ||||
|       var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; | ||||
|       return (known && state.lastType != ".") ? ret(known.type, known.style, word) : | ||||
|                      ret("variable", "variable", word); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function tokenString(quote) { | ||||
|     return function(stream, state) { | ||||
|       var escaped = false, next; | ||||
|       if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ | ||||
|         state.tokenize = tokenBase; | ||||
|         return ret("jsonld-keyword", "meta"); | ||||
|       } | ||||
|       while ((next = stream.next()) != null) { | ||||
|         if (next == quote && !escaped) break; | ||||
|         escaped = !escaped && next == "\\"; | ||||
|       } | ||||
|       if (!escaped) state.tokenize = tokenBase; | ||||
|       return ret("string", "string"); | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   function tokenComment(stream, state) { | ||||
|     var maybeEnd = false, ch; | ||||
|     while (ch = stream.next()) { | ||||
|       if (ch == "/" && maybeEnd) { | ||||
|         state.tokenize = tokenBase; | ||||
|         break; | ||||
|       } | ||||
|       maybeEnd = (ch == "*"); | ||||
|     } | ||||
|     return ret("comment", "comment"); | ||||
|   } | ||||
|  | ||||
|   function tokenQuasi(stream, state) { | ||||
|     var escaped = false, next; | ||||
|     while ((next = stream.next()) != null) { | ||||
|       if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { | ||||
|         state.tokenize = tokenBase; | ||||
|         break; | ||||
|       } | ||||
|       escaped = !escaped && next == "\\"; | ||||
|     } | ||||
|     return ret("quasi", "string-2", stream.current()); | ||||
|   } | ||||
|  | ||||
|   var brackets = "([{}])"; | ||||
|   // This is a crude lookahead trick to try and notice that we're | ||||
|   // parsing the argument patterns for a fat-arrow function before we | ||||
|   // actually hit the arrow token. It only works if the arrow is on | ||||
|   // the same line as the arguments and there's no strange noise | ||||
|   // (comments) in between. Fallback is to only notice when we hit the | ||||
|   // arrow, and not declare the arguments as locals for the arrow | ||||
|   // body. | ||||
|   function findFatArrow(stream, state) { | ||||
|     if (state.fatArrowAt) state.fatArrowAt = null; | ||||
|     var arrow = stream.string.indexOf("=>", stream.start); | ||||
|     if (arrow < 0) return; | ||||
|  | ||||
|     var depth = 0, sawSomething = false; | ||||
|     for (var pos = arrow - 1; pos >= 0; --pos) { | ||||
|       var ch = stream.string.charAt(pos); | ||||
|       var bracket = brackets.indexOf(ch); | ||||
|       if (bracket >= 0 && bracket < 3) { | ||||
|         if (!depth) { ++pos; break; } | ||||
|         if (--depth == 0) break; | ||||
|       } else if (bracket >= 3 && bracket < 6) { | ||||
|         ++depth; | ||||
|       } else if (/[$\w]/.test(ch)) { | ||||
|         sawSomething = true; | ||||
|       } else if (sawSomething && !depth) { | ||||
|         ++pos; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|     if (sawSomething && !depth) state.fatArrowAt = pos; | ||||
|   } | ||||
|  | ||||
|   // Parser | ||||
|  | ||||
|   var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; | ||||
|  | ||||
|   function JSLexical(indented, column, type, align, prev, info) { | ||||
|     this.indented = indented; | ||||
|     this.column = column; | ||||
|     this.type = type; | ||||
|     this.prev = prev; | ||||
|     this.info = info; | ||||
|     if (align != null) this.align = align; | ||||
|   } | ||||
|  | ||||
|   function inScope(state, varname) { | ||||
|     for (var v = state.localVars; v; v = v.next) | ||||
|       if (v.name == varname) return true; | ||||
|     for (var cx = state.context; cx; cx = cx.prev) { | ||||
|       for (var v = cx.vars; v; v = v.next) | ||||
|         if (v.name == varname) return true; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function parseJS(state, style, type, content, stream) { | ||||
|     var cc = state.cc; | ||||
|     // Communicate our context to the combinators. | ||||
|     // (Less wasteful than consing up a hundred closures on every call.) | ||||
|     cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; | ||||
|  | ||||
|     if (!state.lexical.hasOwnProperty("align")) | ||||
|       state.lexical.align = true; | ||||
|  | ||||
|     while(true) { | ||||
|       var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; | ||||
|       if (combinator(type, content)) { | ||||
|         while(cc.length && cc[cc.length - 1].lex) | ||||
|           cc.pop()(); | ||||
|         if (cx.marked) return cx.marked; | ||||
|         if (type == "variable" && inScope(state, content)) return "variable-2"; | ||||
|         return style; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Combinator utils | ||||
|  | ||||
|   var cx = {state: null, column: null, marked: null, cc: null}; | ||||
|   function pass() { | ||||
|     for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); | ||||
|   } | ||||
|   function cont() { | ||||
|     pass.apply(null, arguments); | ||||
|     return true; | ||||
|   } | ||||
|   function register(varname) { | ||||
|     function inList(list) { | ||||
|       for (var v = list; v; v = v.next) | ||||
|         if (v.name == varname) return true; | ||||
|       return false; | ||||
|     } | ||||
|     var state = cx.state; | ||||
|     if (state.context) { | ||||
|       cx.marked = "def"; | ||||
|       if (inList(state.localVars)) return; | ||||
|       state.localVars = {name: varname, next: state.localVars}; | ||||
|     } else { | ||||
|       if (inList(state.globalVars)) return; | ||||
|       if (parserConfig.globalVars) | ||||
|         state.globalVars = {name: varname, next: state.globalVars}; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Combinators | ||||
|  | ||||
|   var defaultVars = {name: "this", next: {name: "arguments"}}; | ||||
|   function pushcontext() { | ||||
|     cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; | ||||
|     cx.state.localVars = defaultVars; | ||||
|   } | ||||
|   function popcontext() { | ||||
|     cx.state.localVars = cx.state.context.vars; | ||||
|     cx.state.context = cx.state.context.prev; | ||||
|   } | ||||
|   function pushlex(type, info) { | ||||
|     var result = function() { | ||||
|       var state = cx.state, indent = state.indented; | ||||
|       if (state.lexical.type == "stat") indent = state.lexical.indented; | ||||
|       state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); | ||||
|     }; | ||||
|     result.lex = true; | ||||
|     return result; | ||||
|   } | ||||
|   function poplex() { | ||||
|     var state = cx.state; | ||||
|     if (state.lexical.prev) { | ||||
|       if (state.lexical.type == ")") | ||||
|         state.indented = state.lexical.indented; | ||||
|       state.lexical = state.lexical.prev; | ||||
|     } | ||||
|   } | ||||
|   poplex.lex = true; | ||||
|  | ||||
|   function expect(wanted) { | ||||
|     function exp(type) { | ||||
|       if (type == wanted) return cont(); | ||||
|       else if (wanted == ";") return pass(); | ||||
|       else return cont(exp); | ||||
|     }; | ||||
|     return exp; | ||||
|   } | ||||
|  | ||||
|   function statement(type, value) { | ||||
|     if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); | ||||
|     if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); | ||||
|     if (type == "keyword b") return cont(pushlex("form"), statement, poplex); | ||||
|     if (type == "{") return cont(pushlex("}"), block, poplex); | ||||
|     if (type == ";") return cont(); | ||||
|     if (type == "if") { | ||||
|       if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) | ||||
|         cx.state.cc.pop()(); | ||||
|       return cont(pushlex("form"), expression, statement, poplex, maybeelse); | ||||
|     } | ||||
|     if (type == "function") return cont(functiondef); | ||||
|     if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); | ||||
|     if (type == "variable") return cont(pushlex("stat"), maybelabel); | ||||
|     if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), | ||||
|                                       block, poplex, poplex); | ||||
|     if (type == "case") return cont(expression, expect(":")); | ||||
|     if (type == "default") return cont(expect(":")); | ||||
|     if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), | ||||
|                                      statement, poplex, popcontext); | ||||
|     if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); | ||||
|     if (type == "class") return cont(pushlex("form"), className, objlit, poplex); | ||||
|     if (type == "export") return cont(pushlex("form"), afterExport, poplex); | ||||
|     if (type == "import") return cont(pushlex("form"), afterImport, poplex); | ||||
|     return pass(pushlex("stat"), expression, expect(";"), poplex); | ||||
|   } | ||||
|   function expression(type) { | ||||
|     return expressionInner(type, false); | ||||
|   } | ||||
|   function expressionNoComma(type) { | ||||
|     return expressionInner(type, true); | ||||
|   } | ||||
|   function expressionInner(type, noComma) { | ||||
|     if (cx.state.fatArrowAt == cx.stream.start) { | ||||
|       var body = noComma ? arrowBodyNoComma : arrowBody; | ||||
|       if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); | ||||
|       else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); | ||||
|     } | ||||
|  | ||||
|     var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; | ||||
|     if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); | ||||
|     if (type == "function") return cont(functiondef, maybeop); | ||||
|     if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); | ||||
|     if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); | ||||
|     if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); | ||||
|     if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); | ||||
|     if (type == "{") return contCommasep(objprop, "}", null, maybeop); | ||||
|     if (type == "quasi") { return pass(quasi, maybeop); } | ||||
|     return cont(); | ||||
|   } | ||||
|   function maybeexpression(type) { | ||||
|     if (type.match(/[;\}\)\],]/)) return pass(); | ||||
|     return pass(expression); | ||||
|   } | ||||
|   function maybeexpressionNoComma(type) { | ||||
|     if (type.match(/[;\}\)\],]/)) return pass(); | ||||
|     return pass(expressionNoComma); | ||||
|   } | ||||
|  | ||||
|   function maybeoperatorComma(type, value) { | ||||
|     if (type == ",") return cont(expression); | ||||
|     return maybeoperatorNoComma(type, value, false); | ||||
|   } | ||||
|   function maybeoperatorNoComma(type, value, noComma) { | ||||
|     var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; | ||||
|     var expr = noComma == false ? expression : expressionNoComma; | ||||
|     if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); | ||||
|     if (type == "operator") { | ||||
|       if (/\+\+|--/.test(value)) return cont(me); | ||||
|       if (value == "?") return cont(expression, expect(":"), expr); | ||||
|       return cont(expr); | ||||
|     } | ||||
|     if (type == "quasi") { return pass(quasi, me); } | ||||
|     if (type == ";") return; | ||||
|     if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); | ||||
|     if (type == ".") return cont(property, me); | ||||
|     if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); | ||||
|   } | ||||
|   function quasi(type, value) { | ||||
|     if (type != "quasi") return pass(); | ||||
|     if (value.slice(value.length - 2) != "${") return cont(quasi); | ||||
|     return cont(expression, continueQuasi); | ||||
|   } | ||||
|   function continueQuasi(type) { | ||||
|     if (type == "}") { | ||||
|       cx.marked = "string-2"; | ||||
|       cx.state.tokenize = tokenQuasi; | ||||
|       return cont(quasi); | ||||
|     } | ||||
|   } | ||||
|   function arrowBody(type) { | ||||
|     findFatArrow(cx.stream, cx.state); | ||||
|     if (type == "{") return pass(statement); | ||||
|     return pass(expression); | ||||
|   } | ||||
|   function arrowBodyNoComma(type) { | ||||
|     findFatArrow(cx.stream, cx.state); | ||||
|     if (type == "{") return pass(statement); | ||||
|     return pass(expressionNoComma); | ||||
|   } | ||||
|   function maybelabel(type) { | ||||
|     if (type == ":") return cont(poplex, statement); | ||||
|     return pass(maybeoperatorComma, expect(";"), poplex); | ||||
|   } | ||||
|   function property(type) { | ||||
|     if (type == "variable") {cx.marked = "property"; return cont();} | ||||
|   } | ||||
|   function objprop(type, value) { | ||||
|     if (type == "variable") { | ||||
|       cx.marked = "property"; | ||||
|       if (value == "get" || value == "set") return cont(getterSetter); | ||||
|     } else if (type == "number" || type == "string") { | ||||
|       cx.marked = jsonldMode ? "property" : (type + " property"); | ||||
|     } else if (type == "[") { | ||||
|       return cont(expression, expect("]"), afterprop); | ||||
|     } | ||||
|     if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); | ||||
|   } | ||||
|   function getterSetter(type) { | ||||
|     if (type != "variable") return pass(afterprop); | ||||
|     cx.marked = "property"; | ||||
|     return cont(functiondef); | ||||
|   } | ||||
|   function afterprop(type) { | ||||
|     if (type == ":") return cont(expressionNoComma); | ||||
|     if (type == "(") return pass(functiondef); | ||||
|   } | ||||
|   function commasep(what, end) { | ||||
|     function proceed(type) { | ||||
|       if (type == ",") { | ||||
|         var lex = cx.state.lexical; | ||||
|         if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; | ||||
|         return cont(what, proceed); | ||||
|       } | ||||
|       if (type == end) return cont(); | ||||
|       return cont(expect(end)); | ||||
|     } | ||||
|     return function(type) { | ||||
|       if (type == end) return cont(); | ||||
|       return pass(what, proceed); | ||||
|     }; | ||||
|   } | ||||
|   function contCommasep(what, end, info) { | ||||
|     for (var i = 3; i < arguments.length; i++) | ||||
|       cx.cc.push(arguments[i]); | ||||
|     return cont(pushlex(end, info), commasep(what, end), poplex); | ||||
|   } | ||||
|   function block(type) { | ||||
|     if (type == "}") return cont(); | ||||
|     return pass(statement, block); | ||||
|   } | ||||
|   function maybetype(type) { | ||||
|     if (isTS && type == ":") return cont(typedef); | ||||
|   } | ||||
|   function typedef(type) { | ||||
|     if (type == "variable"){cx.marked = "variable-3"; return cont();} | ||||
|   } | ||||
|   function vardef() { | ||||
|     return pass(pattern, maybetype, maybeAssign, vardefCont); | ||||
|   } | ||||
|   function pattern(type, value) { | ||||
|     if (type == "variable") { register(value); return cont(); } | ||||
|     if (type == "[") return contCommasep(pattern, "]"); | ||||
|     if (type == "{") return contCommasep(proppattern, "}"); | ||||
|   } | ||||
|   function proppattern(type, value) { | ||||
|     if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { | ||||
|       register(value); | ||||
|       return cont(maybeAssign); | ||||
|     } | ||||
|     if (type == "variable") cx.marked = "property"; | ||||
|     return cont(expect(":"), pattern, maybeAssign); | ||||
|   } | ||||
|   function maybeAssign(_type, value) { | ||||
|     if (value == "=") return cont(expressionNoComma); | ||||
|   } | ||||
|   function vardefCont(type) { | ||||
|     if (type == ",") return cont(vardef); | ||||
|   } | ||||
|   function maybeelse(type, value) { | ||||
|     if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); | ||||
|   } | ||||
|   function forspec(type) { | ||||
|     if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); | ||||
|   } | ||||
|   function forspec1(type) { | ||||
|     if (type == "var") return cont(vardef, expect(";"), forspec2); | ||||
|     if (type == ";") return cont(forspec2); | ||||
|     if (type == "variable") return cont(formaybeinof); | ||||
|     return pass(expression, expect(";"), forspec2); | ||||
|   } | ||||
|   function formaybeinof(_type, value) { | ||||
|     if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | ||||
|     return cont(maybeoperatorComma, forspec2); | ||||
|   } | ||||
|   function forspec2(type, value) { | ||||
|     if (type == ";") return cont(forspec3); | ||||
|     if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } | ||||
|     return pass(expression, expect(";"), forspec3); | ||||
|   } | ||||
|   function forspec3(type) { | ||||
|     if (type != ")") cont(expression); | ||||
|   } | ||||
|   function functiondef(type, value) { | ||||
|     if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} | ||||
|     if (type == "variable") {register(value); return cont(functiondef);} | ||||
|     if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); | ||||
|   } | ||||
|   function funarg(type) { | ||||
|     if (type == "spread") return cont(funarg); | ||||
|     return pass(pattern, maybetype); | ||||
|   } | ||||
|   function className(type, value) { | ||||
|     if (type == "variable") {register(value); return cont(classNameAfter);} | ||||
|   } | ||||
|   function classNameAfter(_type, value) { | ||||
|     if (value == "extends") return cont(expression); | ||||
|   } | ||||
|   function objlit(type) { | ||||
|     if (type == "{") return contCommasep(objprop, "}"); | ||||
|   } | ||||
|   function afterModule(type, value) { | ||||
|     if (type == "string") return cont(statement); | ||||
|     if (type == "variable") { register(value); return cont(maybeFrom); } | ||||
|   } | ||||
|   function afterExport(_type, value) { | ||||
|     if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } | ||||
|     if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } | ||||
|     return pass(statement); | ||||
|   } | ||||
|   function afterImport(type) { | ||||
|     if (type == "string") return cont(); | ||||
|     return pass(importSpec, maybeFrom); | ||||
|   } | ||||
|   function importSpec(type, value) { | ||||
|     if (type == "{") return contCommasep(importSpec, "}"); | ||||
|     if (type == "variable") register(value); | ||||
|     return cont(); | ||||
|   } | ||||
|   function maybeFrom(_type, value) { | ||||
|     if (value == "from") { cx.marked = "keyword"; return cont(expression); } | ||||
|   } | ||||
|   function arrayLiteral(type) { | ||||
|     if (type == "]") return cont(); | ||||
|     return pass(expressionNoComma, maybeArrayComprehension); | ||||
|   } | ||||
|   function maybeArrayComprehension(type) { | ||||
|     if (type == "for") return pass(comprehension, expect("]")); | ||||
|     if (type == ",") return cont(commasep(expressionNoComma, "]")); | ||||
|     return pass(commasep(expressionNoComma, "]")); | ||||
|   } | ||||
|   function comprehension(type) { | ||||
|     if (type == "for") return cont(forspec, comprehension); | ||||
|     if (type == "if") return cont(expression, comprehension); | ||||
|   } | ||||
|  | ||||
|   // Interface | ||||
|  | ||||
|   return { | ||||
|     startState: function(basecolumn) { | ||||
|       var state = { | ||||
|         tokenize: tokenBase, | ||||
|         lastType: "sof", | ||||
|         cc: [], | ||||
|         lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), | ||||
|         localVars: parserConfig.localVars, | ||||
|         context: parserConfig.localVars && {vars: parserConfig.localVars}, | ||||
|         indented: 0 | ||||
|       }; | ||||
|       if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") | ||||
|         state.globalVars = parserConfig.globalVars; | ||||
|       return state; | ||||
|     }, | ||||
|  | ||||
|     token: function(stream, state) { | ||||
|       if (stream.sol()) { | ||||
|         if (!state.lexical.hasOwnProperty("align")) | ||||
|           state.lexical.align = false; | ||||
|         state.indented = stream.indentation(); | ||||
|         findFatArrow(stream, state); | ||||
|       } | ||||
|       if (state.tokenize != tokenComment && stream.eatSpace()) return null; | ||||
|       var style = state.tokenize(stream, state); | ||||
|       if (type == "comment") return style; | ||||
|       state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; | ||||
|       return parseJS(state, style, type, content, stream); | ||||
|     }, | ||||
|  | ||||
|     indent: function(state, textAfter) { | ||||
|       if (state.tokenize == tokenComment) return CodeMirror.Pass; | ||||
|       if (state.tokenize != tokenBase) return 0; | ||||
|       var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; | ||||
|       // Kludge to prevent 'maybelse' from blocking lexical scope pops | ||||
|       if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { | ||||
|         var c = state.cc[i]; | ||||
|         if (c == poplex) lexical = lexical.prev; | ||||
|         else if (c != maybeelse) break; | ||||
|       } | ||||
|       if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; | ||||
|       if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") | ||||
|         lexical = lexical.prev; | ||||
|       var type = lexical.type, closing = firstChar == type; | ||||
|  | ||||
|       if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); | ||||
|       else if (type == "form" && firstChar == "{") return lexical.indented; | ||||
|       else if (type == "form") return lexical.indented + indentUnit; | ||||
|       else if (type == "stat") | ||||
|         return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); | ||||
|       else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) | ||||
|         return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); | ||||
|       else if (lexical.align) return lexical.column + (closing ? 0 : 1); | ||||
|       else return lexical.indented + (closing ? 0 : indentUnit); | ||||
|     }, | ||||
|  | ||||
|     electricChars: ":{}", | ||||
|     blockCommentStart: jsonMode ? null : "/*", | ||||
|     blockCommentEnd: jsonMode ? null : "*/", | ||||
|     lineComment: jsonMode ? null : "//", | ||||
|     fold: "brace", | ||||
|  | ||||
|     helperType: jsonMode ? "json" : "javascript", | ||||
|     jsonldMode: jsonldMode, | ||||
|     jsonMode: jsonMode | ||||
|   }; | ||||
| }); | ||||
|  | ||||
| CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/); | ||||
|  | ||||
| CodeMirror.defineMIME("text/javascript", "javascript"); | ||||
| CodeMirror.defineMIME("text/ecmascript", "javascript"); | ||||
| CodeMirror.defineMIME("application/javascript", "javascript"); | ||||
| CodeMirror.defineMIME("application/ecmascript", "javascript"); | ||||
| CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); | ||||
| CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); | ||||
| CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); | ||||
| CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); | ||||
| CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); | ||||
|  | ||||
| }); | ||||
							
								
								
									
										75
									
								
								plugins/tiddlywiki/codemirror/lib/tiddlywiki.files
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								plugins/tiddlywiki/codemirror/lib/tiddlywiki.files
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| { | ||||
| 	"tiddlers": [ | ||||
| 		{ | ||||
| 			"file": "codemirror.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/lib/codemirror.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "codemirror.css", | ||||
| 			"fields": { | ||||
| 				"type": "text/css", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/lib/codemirror.css", | ||||
| 				"tags": "[[$:/tags/stylesheet]]" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/dialog/dialog.css", | ||||
| 			"fields": { | ||||
| 				"type": "text/css", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/dialog/dialog.css", | ||||
| 				"tags": "[[$:/tags/stylesheet]]" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/dialog/dialog.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/dialog/dialog.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/edit/matchbrackets.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/edit/matchbrackets.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "addon/search/searchcursor.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/addon/search/searchcursor.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "mode/javascript/javascript.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/mode/javascript/javascript.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "keymap/vim.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/keymap/vim.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "keymap/sublime.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/keymap/sublime.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		},{ | ||||
| 			"file": "keymap/emacs.js", | ||||
| 			"fields": { | ||||
| 				"type": "application/javascript", | ||||
| 				"title": "$:/plugins/tiddlywiki/codemirror/keymap/emacs.js", | ||||
| 				"module-type": "library" | ||||
| 			} | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Jeremy Ruston
					Jeremy Ruston