mirror of
				https://github.com/Jermolene/TiddlyWiki5
				synced 2025-11-01 08:03:00 +00:00 
			
		
		
		
	| @@ -675,6 +675,9 @@ $tw.modules.execute = function(moduleName,moduleRoot) { | |||||||
| 			} else if(typeof moduleInfo.definition === "string") { // String | 			} else if(typeof moduleInfo.definition === "string") { // String | ||||||
| 				moduleInfo.exports = _exports; | 				moduleInfo.exports = _exports; | ||||||
| 				$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title); | 				$tw.utils.evalSandboxed(moduleInfo.definition,sandbox,tiddler.fields.title); | ||||||
|  | 				if(sandbox.module.exports) { | ||||||
|  | 					moduleInfo.exports = sandbox.module.exports; //more codemirror workaround | ||||||
|  | 				} | ||||||
| 			} else { // Object | 			} else { // Object | ||||||
| 				moduleInfo.exports = moduleInfo.definition; | 				moduleInfo.exports = moduleInfo.definition; | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -17,8 +17,8 @@ var CODEMIRROR_OPTIONS = "$:/config/CodeMirror", configOptions; | |||||||
| e.g. to allow vim key bindings | e.g. to allow vim key bindings | ||||||
|  { |  { | ||||||
| 	"require": [ | 	"require": [ | ||||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/dialog.js", | 		"$:/plugins/tiddlywiki/codemirror/addon/dialog/dialog.js", | ||||||
| 		"$:/plugins/tiddlywiki/codemirror/addon/searchcursor.js", | 		"$:/plugins/tiddlywiki/codemirror/addon/search/searchcursor.js", | ||||||
| 		"$:/plugins/tiddlywiki/codemirror/keymap/vim.js" | 		"$:/plugins/tiddlywiki/codemirror/keymap/vim.js" | ||||||
| 	], | 	], | ||||||
| 	"configuration": { | 	"configuration": { | ||||||
| @@ -31,7 +31,7 @@ e.g. to allow vim key bindings | |||||||
| var EditTextWidget = require("$:/core/modules/widgets/edit-text.js")["edit-text"]; | var EditTextWidget = require("$:/core/modules/widgets/edit-text.js")["edit-text"]; | ||||||
|  |  | ||||||
| if($tw.browser) { | if($tw.browser) { | ||||||
| 	require("$:/plugins/tiddlywiki/codemirror/codemirror.js"); | 	window.CodeMirror = require("$:/plugins/tiddlywiki/codemirror/lib/codemirror.js"); | ||||||
|  |  | ||||||
| 	configOptions = $tw.wiki.getTiddlerData(CODEMIRROR_OPTIONS,{}); | 	configOptions = $tw.wiki.getTiddlerData(CODEMIRROR_OPTIONS,{}); | ||||||
|  |  | ||||||
| @@ -59,12 +59,11 @@ EditTextWidget.prototype.postRender = function() { | |||||||
| 			lineWrapping: true, | 			lineWrapping: true, | ||||||
| 			lineNumbers: true | 			lineNumbers: true | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
| 	if($tw.browser && window.CodeMirror && this.editTag === "textarea") { | 	if($tw.browser && window.CodeMirror && this.editTag === "textarea") { | ||||||
| 		if(EditTextWidget.configuration) { | 		if(EditTextWidget.configuration) { | ||||||
| 			for (cv in EditTextWidget.configuration) { cm_opts[cv] = EditTextWidget.configuration[cv]; } | 			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() { | 		cm.on("change",function() { | ||||||
| 			self.saveChanges(cm.getValue()); | 			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": [ |   "require": [ | ||||||
|       "$:/plugins/tiddlywiki/codemirror/addon/dialog.js", |       "$:/plugins/tiddlywiki/codemirror/mode/javascript/javascript.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", |       "$:/plugins/tiddlywiki/codemirror/keymap/vim.js", | ||||||
|       "$:/plugins/tiddlywiki/codemirror/keymap/emacs.js" |       "$:/plugins/tiddlywiki/codemirror/keymap/emacs.js" | ||||||
|   ], |   ], | ||||||
|   | |||||||
| @@ -1,6 +1,13 @@ | |||||||
| // Open simple dialogs on top of an editor. Relies on dialog.css.
 | // 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) { |   function dialogDiv(cm, template, bottom) { | ||||||
|     var wrap = cm.getWrapperElement(); |     var wrap = cm.getWrapperElement(); | ||||||
|     var dialog; |     var dialog; | ||||||
| @@ -35,9 +42,11 @@ | |||||||
|     } |     } | ||||||
|     var inp = dialog.getElementsByTagName("input")[0], button; |     var inp = dialog.getElementsByTagName("input")[0], button; | ||||||
|     if (inp) { |     if (inp) { | ||||||
|  |       if (options && options.value) inp.value = options.value; | ||||||
|       CodeMirror.on(inp, "keydown", function(e) { |       CodeMirror.on(inp, "keydown", function(e) { | ||||||
|         if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } |         if (options && options.onKeyDown && options.onKeyDown(e, inp.value, close)) { return; } | ||||||
|         if (e.keyCode == 13 || e.keyCode == 27) { |         if (e.keyCode == 13 || e.keyCode == 27) { | ||||||
|  |           inp.blur(); | ||||||
|           CodeMirror.e_stop(e); |           CodeMirror.e_stop(e); | ||||||
|           close(); |           close(); | ||||||
|           me.focus(); |           me.focus(); | ||||||
| @@ -118,4 +127,4 @@ | |||||||
|     if (duration) |     if (duration) | ||||||
|       doneTimer = setTimeout(close, options.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; |   var Pos = CodeMirror.Pos; | ||||||
| 
 | 
 | ||||||
|   function SearchCursor(doc, query, pos, caseFold) { |   function SearchCursor(doc, query, pos, caseFold) { | ||||||
| @@ -47,6 +55,7 @@ | |||||||
|                   match: match}; |                   match: match}; | ||||||
|       }; |       }; | ||||||
|     } else { // String query
 |     } else { // String query
 | ||||||
|  |       var origQuery = query; | ||||||
|       if (caseFold) query = query.toLowerCase(); |       if (caseFold) query = query.toLowerCase(); | ||||||
|       var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; |       var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;}; | ||||||
|       var target = query.split("\n"); |       var target = query.split("\n"); | ||||||
| @@ -58,33 +67,45 @@ | |||||||
|           this.matches = function() {}; |           this.matches = function() {}; | ||||||
|         } else { |         } else { | ||||||
|           this.matches = function(reverse, pos) { |           this.matches = function(reverse, pos) { | ||||||
|             var line = fold(doc.getLine(pos.line)), len = query.length, match; |             if (reverse) { | ||||||
|             if (reverse ? (pos.ch >= len && (match = line.lastIndexOf(query, pos.ch - len)) != -1) |               var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig); | ||||||
|                         : (match = line.indexOf(query, pos.ch)) != -1) |               var match = line.lastIndexOf(query); | ||||||
|               return {from: Pos(pos.line, match), |               if (match > -1) { | ||||||
|                       to: Pos(pos.line, match + len)}; |                 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 { |       } else { | ||||||
|  |         var origTarget = origQuery.split("\n"); | ||||||
|         this.matches = function(reverse, pos) { |         this.matches = function(reverse, pos) { | ||||||
|           var ln = pos.line, idx = (reverse ? target.length - 1 : 0), match = target[idx], line = fold(doc.getLine(ln)); |           var last = target.length - 1; | ||||||
|           var offsetA = (reverse ? line.indexOf(match) + match.length : line.lastIndexOf(match)); |           if (reverse) { | ||||||
|           if (reverse ? offsetA > pos.ch || offsetA != match.length |             if (pos.line - (target.length - 1) < doc.firstLine()) return; | ||||||
|               : offsetA < pos.ch || offsetA != line.length - match.length) |             if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return; | ||||||
|             return; |             var to = Pos(pos.line, origTarget[last].length); | ||||||
|           for (;;) { |             for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln) | ||||||
|             if (reverse ? !ln : ln == doc.lineCount() - 1) return; |               if (target[i] != fold(doc.getLine(ln))) return; | ||||||
|             line = fold(doc.getLine(ln += reverse ? -1 : 1)); |             var line = doc.getLine(ln), cut = line.length - origTarget[0].length; | ||||||
|             match = target[reverse ? --idx : ++idx]; |             if (fold(line.slice(cut)) != target[0]) return; | ||||||
|             if (idx > 0 && idx < target.length - 1) { |             return {from: Pos(ln, cut), to: to}; | ||||||
|               if (line != match) return; |           } else { | ||||||
|               else continue; |             if (pos.line + (target.length - 1) > doc.lastLine()) return; | ||||||
|             } |             var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length; | ||||||
|             var offsetB = (reverse ? line.lastIndexOf(match) : line.indexOf(match) + match.length); |             if (fold(line.slice(cut)) != target[0]) return; | ||||||
|             if (reverse ? offsetB != line.length - match.length : offsetB != match.length) |             var from = Pos(pos.line, cut); | ||||||
|               return; |             for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln) | ||||||
|             var start = Pos(pos.line, offsetA), end = Pos(ln, offsetB); |               if (target[i] != fold(doc.getLine(ln))) return; | ||||||
|             return {from: reverse ? end : start, to: reverse ? start : end}; |             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 (;;) { |       for (;;) { | ||||||
|         if (this.pos = this.matches(reverse, pos)) { |         if (this.pos = this.matches(reverse, pos)) { | ||||||
|           if (!this.pos.from || !this.pos.to) { console.log(this.matches, this.pos); } |  | ||||||
|           this.atOccurrence = true; |           this.atOccurrence = true; | ||||||
|           return this.pos.match || 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) { |   CodeMirror.defineExtension("getSearchCursor", function(query, pos, caseFold) { | ||||||
|     return new SearchCursor(this.doc, query, pos, caseFold); |     return new SearchCursor(this.doc, query, pos, caseFold); | ||||||
|   }); |   }); | ||||||
|   CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { |   CodeMirror.defineDocExtension("getSearchCursor", function(query, pos, caseFold) { | ||||||
|     return new SearchCursor(this, 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-linenumbers {} | ||||||
| .CodeMirror-linenumber { | .CodeMirror-linenumber { | ||||||
|   font-size: 12px; |   padding: 0 3px 0 5px; | ||||||
|   min-width: 30px; |   min-width: 20px; | ||||||
|   padding: 0 2px 0 2px; |  | ||||||
|   text-align: right; |   text-align: right; | ||||||
|   color: #999; |   color: #999; | ||||||
|  |   -moz-box-sizing: content-box; | ||||||
|  |   box-sizing: content-box; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* CURSOR */ | /* CURSOR */ | ||||||
| 
 | 
 | ||||||
| .CodeMirror div.CodeMirror-cursor { | .CodeMirror div.CodeMirror-cursor { | ||||||
|   border-left: 1px solid black; |   border-left: 1px solid black; | ||||||
|   z-index: 3; |  | ||||||
| } | } | ||||||
| /* Shown when moving in bi-directional text */ | /* Shown when moving in bi-directional text */ | ||||||
| .CodeMirror div.CodeMirror-secondarycursor { | .CodeMirror div.CodeMirror-secondarycursor { | ||||||
| @@ -53,24 +53,29 @@ | |||||||
|   width: auto; |   width: auto; | ||||||
|   border: 0; |   border: 0; | ||||||
|   background: #7e7; |   background: #7e7; | ||||||
|   z-index: 1; |  | ||||||
| } | } | ||||||
| /* Can style cursor different in overwrite (non-insert) mode */ | /* 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; } | .cm-tab { display: inline-block; } | ||||||
| 
 | 
 | ||||||
|  | .CodeMirror-ruler { | ||||||
|  |   border-left: 1px solid #ccc; | ||||||
|  |   position: absolute; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* DEFAULT THEME */ | /* DEFAULT THEME */ | ||||||
| 
 | 
 | ||||||
| .cm-s-default .cm-keyword {color: #708;} | .cm-s-default .cm-keyword {color: #708;} | ||||||
| .cm-s-default .cm-atom {color: #219;} | .cm-s-default .cm-atom {color: #219;} | ||||||
| .cm-s-default .cm-number {color: #164;} | .cm-s-default .cm-number {color: #164;} | ||||||
| .cm-s-default .cm-def {color: #00f;} | .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-2 {color: #05a;} | ||||||
| .cm-s-default .cm-variable-3 {color: #085;} | .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-comment {color: #a50;} | ||||||
| .cm-s-default .cm-string {color: #a11;} | .cm-s-default .cm-string {color: #a11;} | ||||||
| .cm-s-default .cm-string-2 {color: #f50;} | .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 */ |   /* 30px is the magic margin used to hide the element's real scrollbars */ | ||||||
|   /* See overflow: hidden in .CodeMirror */ |   /* See overflow: hidden in .CodeMirror */ | ||||||
|   margin-bottom: -30px; margin-right: -30px; |   margin-bottom: -30px; margin-right: -30px; | ||||||
|   padding-bottom: 30px; padding-right: 30px; |   padding-bottom: 30px; | ||||||
|   height: 100%; |   height: 100%; | ||||||
|   outline: none; /* Prevent dragging from highlighting the element */ |   outline: none; /* Prevent dragging from highlighting the element */ | ||||||
|   position: relative; |   position: relative; | ||||||
| @@ -124,6 +129,9 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | |||||||
| } | } | ||||||
| .CodeMirror-sizer { | .CodeMirror-sizer { | ||||||
|   position: relative; |   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 | /* 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; |   white-space: pre-wrap; | ||||||
|   word-break: normal; |   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 { | .CodeMirror-linebackground { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   left: 0; right: 0; top: 0; bottom: 0; |   left: 0; right: 0; top: 0; bottom: 0; | ||||||
| @@ -237,16 +236,22 @@ div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} | |||||||
| 
 | 
 | ||||||
| .CodeMirror div.CodeMirror-cursor { | .CodeMirror div.CodeMirror-cursor { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   visibility: hidden; |  | ||||||
|   border-right: none; |   border-right: none; | ||||||
|   width: 0; |   width: 0; | ||||||
| } | } | ||||||
| .CodeMirror-focused div.CodeMirror-cursor { | 
 | ||||||
|  | div.CodeMirror-cursors { | ||||||
|  |   visibility: hidden; | ||||||
|  |   position: relative; | ||||||
|  |   z-index: 1; | ||||||
|  | } | ||||||
|  | .CodeMirror-focused div.CodeMirror-cursors { | ||||||
|   visibility: visible; |   visibility: visible; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .CodeMirror-selected { background: #d9d9d9; } | .CodeMirror-selected { background: #d9d9d9; } | ||||||
| .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } | .CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } | ||||||
|  | .CodeMirror-crosshair { cursor: crosshair; } | ||||||
| 
 | 
 | ||||||
| .cm-searching { | .cm-searching { | ||||||
|   background: #ffa; |   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 */ | /* IE7 hack to prevent it from returning funny offsetTops on the spans */ | ||||||
| .CodeMirror span { *vertical-align: text-bottom; } | .CodeMirror span { *vertical-align: text-bottom; } | ||||||
| 
 | 
 | ||||||
|  | /* Used to force a border model for a node */ | ||||||
|  | .cm-force-border { padding-right: .1px; } | ||||||
|  | 
 | ||||||
| @media print { | @media print { | ||||||
|   /* Hide the cursor when printing */ |   /* Hide the cursor when printing */ | ||||||
|   .CodeMirror div.CodeMirror-cursor { |   .CodeMirror div.CodeMirror-cursors { | ||||||
|     visibility: hidden; |     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"; |   "use strict"; | ||||||
| 
 | 
 | ||||||
|   var Pos = CodeMirror.Pos; |   var Pos = CodeMirror.Pos; | ||||||
| @@ -174,7 +181,7 @@ | |||||||
|     if (dup > 1 && event.origin == "+input") { |     if (dup > 1 && event.origin == "+input") { | ||||||
|       var one = event.text.join("\n"), txt = ""; |       var one = event.text.join("\n"), txt = ""; | ||||||
|       for (var i = 1; i < dup; ++i) txt += one; |       for (var i = 1; i < dup; ++i) txt += one; | ||||||
|       cm.replaceSelection(txt, "end", "+input"); |       cm.replaceSelection(txt); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @@ -197,10 +204,15 @@ | |||||||
| 
 | 
 | ||||||
|   function setMark(cm) { |   function setMark(cm) { | ||||||
|     cm.setCursor(cm.getCursor()); |     cm.setCursor(cm.getCursor()); | ||||||
|     cm.setExtending(true); |     cm.setExtending(!cm.getExtending()); | ||||||
|     cm.on("change", function() { cm.setExtending(false); }); |     cm.on("change", function() { cm.setExtending(false); }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   function clearMark(cm) { | ||||||
|  |     cm.setExtending(false); | ||||||
|  |     cm.setCursor(cm.getCursor()); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   function getInput(cm, msg, f) { |   function getInput(cm, msg, f) { | ||||||
|     if (cm.openDialog) |     if (cm.openDialog) | ||||||
|       cm.openDialog(msg + ": <input type=\"text\" style=\"width: 10em\"/>", f, {bottom: true}); |       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
 |   // Actual keymap
 | ||||||
| 
 | 
 | ||||||
|   var keyMap = CodeMirror.keyMap.emacs = { |   var keyMap = CodeMirror.keyMap.emacs = { | ||||||
| @@ -249,13 +266,14 @@ | |||||||
|     }), |     }), | ||||||
|     "Alt-W": function(cm) { |     "Alt-W": function(cm) { | ||||||
|       addToRing(cm.getSelection()); |       addToRing(cm.getSelection()); | ||||||
|  |       clearMark(cm); | ||||||
|     }, |     }, | ||||||
|     "Ctrl-Y": function(cm) { |     "Ctrl-Y": function(cm) { | ||||||
|       var start = cm.getCursor(); |       var start = cm.getCursor(); | ||||||
|       cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste"); |       cm.replaceRange(getFromRing(getPrefix(cm)), start, start, "paste"); | ||||||
|       cm.setSelection(start, cm.getCursor()); |       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, |     "Ctrl-Space": setMark, "Ctrl-Shift-2": setMark, | ||||||
| 
 | 
 | ||||||
| @@ -306,13 +324,7 @@ | |||||||
|     }, |     }, | ||||||
|     "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }), |     "Ctrl-O": repeated(function(cm) { cm.replaceSelection("\n", "start"); }), | ||||||
|     "Ctrl-T": repeated(function(cm) { |     "Ctrl-T": repeated(function(cm) { | ||||||
|       var pos = cm.getCursor(); |       cm.execCommand("transposeChars"); | ||||||
|       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"); |  | ||||||
|     }), |     }), | ||||||
| 
 | 
 | ||||||
|     "Alt-C": repeated(function(cm) { |     "Alt-C": repeated(function(cm) { | ||||||
| @@ -334,7 +346,7 @@ | |||||||
|     "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"), |     "Ctrl-/": repeated("undo"), "Shift-Ctrl--": repeated("undo"), | ||||||
|     "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"), |     "Ctrl-Z": repeated("undo"), "Cmd-Z": repeated("undo"), | ||||||
|     "Shift-Alt-,": "goDocStart", "Shift-Alt-.": "goDocEnd", |     "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", |     "Alt-/": "autocomplete", | ||||||
|     "Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto", |     "Ctrl-J": "newlineAndIndent", "Enter": false, "Tab": "indentAuto", | ||||||
| 
 | 
 | ||||||
| @@ -384,4 +396,4 @@ | |||||||
|   } |   } | ||||||
|   for (var i = 0; i < 10; ++i) regPrefix(String(i)); |   for (var i = 0; i < 10; ++i) regPrefix(String(i)); | ||||||
|   regPrefix("-"); |   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