codemirror-rails 5.13.2 → 5.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/codemirror/rails/version.rb +2 -2
  3. data/vendor/assets/javascripts/codemirror.js +55 -42
  4. data/vendor/assets/javascripts/codemirror/addons/comment/comment.js +9 -2
  5. data/vendor/assets/javascripts/codemirror/addons/edit/closebrackets.js +1 -1
  6. data/vendor/assets/javascripts/codemirror/addons/fold/brace-fold.js +8 -8
  7. data/vendor/assets/javascripts/codemirror/addons/fold/xml-fold.js +3 -3
  8. data/vendor/assets/javascripts/codemirror/addons/hint/show-hint.js +25 -38
  9. data/vendor/assets/javascripts/codemirror/addons/hint/sql-hint.js +2 -2
  10. data/vendor/assets/javascripts/codemirror/addons/lint/lint.js +2 -1
  11. data/vendor/assets/javascripts/codemirror/addons/scroll/simplescrollbars.js +9 -6
  12. data/vendor/assets/javascripts/codemirror/addons/search/match-highlighter.js +24 -27
  13. data/vendor/assets/javascripts/codemirror/addons/search/search.js +5 -2
  14. data/vendor/assets/javascripts/codemirror/addons/tern/tern.js +2 -2
  15. data/vendor/assets/javascripts/codemirror/keymaps/sublime.js +3 -21
  16. data/vendor/assets/javascripts/codemirror/keymaps/vim.js +24 -25
  17. data/vendor/assets/javascripts/codemirror/modes/clike.js +34 -29
  18. data/vendor/assets/javascripts/codemirror/modes/clojure.js +59 -3
  19. data/vendor/assets/javascripts/codemirror/modes/crystal.js +1 -1
  20. data/vendor/assets/javascripts/codemirror/modes/css.js +6 -6
  21. data/vendor/assets/javascripts/codemirror/modes/django.js +8 -8
  22. data/vendor/assets/javascripts/codemirror/modes/dtd.js +6 -6
  23. data/vendor/assets/javascripts/codemirror/modes/ebnf.js +1 -1
  24. data/vendor/assets/javascripts/codemirror/modes/haml.js +3 -3
  25. data/vendor/assets/javascripts/codemirror/modes/htmlmixed.js +1 -1
  26. data/vendor/assets/javascripts/codemirror/modes/jade.js +3 -3
  27. data/vendor/assets/javascripts/codemirror/modes/javascript.js +15 -9
  28. data/vendor/assets/javascripts/codemirror/modes/markdown.js +11 -21
  29. data/vendor/assets/javascripts/codemirror/modes/mathematica.js +1 -0
  30. data/vendor/assets/javascripts/codemirror/modes/mbox.js +129 -0
  31. data/vendor/assets/javascripts/codemirror/modes/pegjs.js +6 -6
  32. data/vendor/assets/javascripts/codemirror/modes/perl.js +1 -1
  33. data/vendor/assets/javascripts/codemirror/modes/php.js +1 -1
  34. data/vendor/assets/javascripts/codemirror/modes/powershell.js +396 -0
  35. data/vendor/assets/javascripts/codemirror/modes/properties.js +1 -1
  36. data/vendor/assets/javascripts/codemirror/modes/puppet.js +1 -1
  37. data/vendor/assets/javascripts/codemirror/modes/python.js +20 -28
  38. data/vendor/assets/javascripts/codemirror/modes/sas.js +315 -0
  39. data/vendor/assets/javascripts/codemirror/modes/slim.js +4 -4
  40. data/vendor/assets/javascripts/codemirror/modes/sparql.js +1 -1
  41. data/vendor/assets/javascripts/codemirror/modes/sql.js +10 -2
  42. data/vendor/assets/javascripts/codemirror/modes/tiddlywiki.js +78 -128
  43. data/vendor/assets/javascripts/codemirror/modes/verilog.js +1 -1
  44. data/vendor/assets/javascripts/codemirror/modes/vhdl.js +1 -1
  45. data/vendor/assets/javascripts/codemirror/modes/webidl.js +195 -0
  46. data/vendor/assets/javascripts/codemirror/modes/xquery.js +1 -1
  47. data/vendor/assets/javascripts/codemirror/modes/yacas.js +204 -0
  48. data/vendor/assets/stylesheets/codemirror.css +1 -1
  49. data/vendor/assets/stylesheets/codemirror/addons/lint/lint.css +2 -2
  50. data/vendor/assets/stylesheets/codemirror/themes/icecoder.css +4 -4
  51. metadata +6 -1
@@ -105,7 +105,7 @@
105
105
  }
106
106
 
107
107
  function nameCompletion(cur, token, result, editor) {
108
- // Try to complete table, colunm names and return start position of completion
108
+ // Try to complete table, column names and return start position of completion
109
109
  var useBacktick = false;
110
110
  var nameParts = [];
111
111
  var start = token.start;
@@ -241,7 +241,7 @@
241
241
  var defaultTableName = options && options.defaultTable;
242
242
  var disableKeywords = options && options.disableKeywords;
243
243
  defaultTable = defaultTableName && getTable(defaultTableName);
244
- keywords = keywords || getKeywords(editor);
244
+ keywords = getKeywords(editor);
245
245
 
246
246
  if (defaultTableName && !defaultTable)
247
247
  defaultTable = findTableByAlias(defaultTableName, editor);
@@ -204,7 +204,8 @@
204
204
 
205
205
  var annotations = [];
206
206
  for (var i = 0; i < spans.length; ++i) {
207
- annotations.push(spans[i].__annotation);
207
+ var ann = spans[i].__annotation;
208
+ if (ann) annotations.push(ann);
208
209
  }
209
210
  if (annotations.length) popupTooltips(annotations, e);
210
211
  }
@@ -59,10 +59,10 @@
59
59
  CodeMirror.on(this.node, "DOMMouseScroll", onWheel);
60
60
  }
61
61
 
62
- Bar.prototype.setPos = function(pos) {
62
+ Bar.prototype.setPos = function(pos, force) {
63
63
  if (pos < 0) pos = 0;
64
64
  if (pos > this.total - this.screen) pos = this.total - this.screen;
65
- if (pos == this.pos) return false;
65
+ if (!force && pos == this.pos) return false;
66
66
  this.pos = pos;
67
67
  this.inner.style[this.orientation == "horizontal" ? "left" : "top"] =
68
68
  (pos * (this.size / this.total)) + "px";
@@ -76,9 +76,12 @@
76
76
  var minButtonSize = 10;
77
77
 
78
78
  Bar.prototype.update = function(scrollSize, clientSize, barSize) {
79
- this.screen = clientSize;
80
- this.total = scrollSize;
81
- this.size = barSize;
79
+ var sizeChanged = this.screen != clientSize || this.total != scrollSize || this.size != barSize
80
+ if (sizeChanged) {
81
+ this.screen = clientSize;
82
+ this.total = scrollSize;
83
+ this.size = barSize;
84
+ }
82
85
 
83
86
  var buttonSize = this.screen * (this.size / this.total);
84
87
  if (buttonSize < minButtonSize) {
@@ -87,7 +90,7 @@
87
90
  }
88
91
  this.inner.style[this.orientation == "horizontal" ? "width" : "height"] =
89
92
  buttonSize + "px";
90
- this.setPos(this.pos);
93
+ this.setPos(this.pos, sizeChanged);
91
94
  };
92
95
 
93
96
  function SimpleScrollbars(cls, place, scroll) {
@@ -16,7 +16,7 @@
16
16
  // highlighted only if the selected text is a word. showToken, when enabled,
17
17
  // will cause the current token to be highlighted when nothing is selected.
18
18
  // delay is used to specify how much time to wait, in milliseconds, before
19
- // highlighting the matches. If annotateScrollbar is enabled, the occurances
19
+ // highlighting the matches. If annotateScrollbar is enabled, the occurences
20
20
  // will be highlighted on the scrollbar via the matchesonscrollbar addon.
21
21
 
22
22
  (function(mod) {
@@ -29,24 +29,20 @@
29
29
  })(function(CodeMirror) {
30
30
  "use strict";
31
31
 
32
- var DEFAULT_MIN_CHARS = 2;
33
- var DEFAULT_TOKEN_STYLE = "matchhighlight";
34
- var DEFAULT_DELAY = 100;
35
- var DEFAULT_WORDS_ONLY = false;
32
+ var defaults = {
33
+ style: "matchhighlight",
34
+ minChars: 2,
35
+ delay: 100,
36
+ wordsOnly: false,
37
+ annotateScrollbar: false,
38
+ showToken: false,
39
+ trim: true
40
+ }
36
41
 
37
42
  function State(options) {
38
- if (typeof options == "object") {
39
- this.minChars = options.minChars;
40
- this.style = options.style;
41
- this.showToken = options.showToken;
42
- this.delay = options.delay;
43
- this.wordsOnly = options.wordsOnly;
44
- this.annotateScrollbar = options.annotateScrollbar;
45
- }
46
- if (this.style == null) this.style = DEFAULT_TOKEN_STYLE;
47
- if (this.minChars == null) this.minChars = DEFAULT_MIN_CHARS;
48
- if (this.delay == null) this.delay = DEFAULT_DELAY;
49
- if (this.wordsOnly == null) this.wordsOnly = DEFAULT_WORDS_ONLY;
43
+ this.options = {}
44
+ for (var name in defaults)
45
+ this.options[name] = (options && options.hasOwnProperty(name) ? options : defaults)[name]
50
46
  this.overlay = this.timeout = null;
51
47
  this.matchesonscroll = null;
52
48
  }
@@ -68,13 +64,13 @@
68
64
  function cursorActivity(cm) {
69
65
  var state = cm.state.matchHighlighter;
70
66
  clearTimeout(state.timeout);
71
- state.timeout = setTimeout(function() {highlightMatches(cm);}, state.delay);
67
+ state.timeout = setTimeout(function() {highlightMatches(cm);}, state.options.delay);
72
68
  }
73
69
 
74
70
  function addOverlay(cm, query, hasBoundary, style) {
75
71
  var state = cm.state.matchHighlighter;
76
72
  cm.addOverlay(state.overlay = makeOverlay(query, hasBoundary, style));
77
- if (state.annotateScrollbar) {
73
+ if (state.options.annotateScrollbar && cm.showMatchesOnScrollbar) {
78
74
  var searchFor = hasBoundary ? new RegExp("\\b" + query + "\\b") : query;
79
75
  state.matchesonscroll = cm.showMatchesOnScrollbar(searchFor, true,
80
76
  {className: "CodeMirror-selection-highlight-scrollbar"});
@@ -86,7 +82,7 @@
86
82
  if (state.overlay) {
87
83
  cm.removeOverlay(state.overlay);
88
84
  state.overlay = null;
89
- if (state.annotateScrollbar) {
85
+ if (state.matchesonscroll) {
90
86
  state.matchesonscroll.clear();
91
87
  state.matchesonscroll = null;
92
88
  }
@@ -97,21 +93,22 @@
97
93
  cm.operation(function() {
98
94
  var state = cm.state.matchHighlighter;
99
95
  removeOverlay(cm);
100
- if (!cm.somethingSelected() && state.showToken) {
101
- var re = state.showToken === true ? /[\w$]/ : state.showToken;
96
+ if (!cm.somethingSelected() && state.options.showToken) {
97
+ var re = state.options.showToken === true ? /[\w$]/ : state.options.showToken;
102
98
  var cur = cm.getCursor(), line = cm.getLine(cur.line), start = cur.ch, end = start;
103
99
  while (start && re.test(line.charAt(start - 1))) --start;
104
100
  while (end < line.length && re.test(line.charAt(end))) ++end;
105
101
  if (start < end)
106
- addOverlay(cm, line.slice(start, end), re, state.style);
102
+ addOverlay(cm, line.slice(start, end), re, state.options.style);
107
103
  return;
108
104
  }
109
105
  var from = cm.getCursor("from"), to = cm.getCursor("to");
110
106
  if (from.line != to.line) return;
111
- if (state.wordsOnly && !isWord(cm, from, to)) return;
112
- var selection = cm.getRange(from, to).replace(/^\s+|\s+$/g, "");
113
- if (selection.length >= state.minChars)
114
- addOverlay(cm, selection, false, state.style);
107
+ if (state.options.wordsOnly && !isWord(cm, from, to)) return;
108
+ var selection = cm.getRange(from, to)
109
+ if (state.options.trim) selection = selection.replace(/^\s+|\s+$/g, "")
110
+ if (selection.length >= state.options.minChars)
111
+ addOverlay(cm, selection, false, state.options.style);
115
112
  });
116
113
  }
117
114
 
@@ -121,7 +121,10 @@
121
121
  persistentDialog(cm, queryDialog, q, function(query, event) {
122
122
  CodeMirror.e_stop(event);
123
123
  if (!query) return;
124
- if (query != state.queryText) startSearch(cm, state, query);
124
+ if (query != state.queryText) {
125
+ startSearch(cm, state, query);
126
+ state.posFrom = state.posTo = cm.getCursor();
127
+ }
125
128
  if (hiding) hiding.style.opacity = 1
126
129
  findNext(cm, event.shiftKey, function(_, to) {
127
130
  var dialog
@@ -193,7 +196,7 @@
193
196
  replaceAll(cm, query, text)
194
197
  } else {
195
198
  clearSearch(cm);
196
- var cursor = getSearchCursor(cm, query, cm.getCursor());
199
+ var cursor = getSearchCursor(cm, query, cm.getCursor("from"));
197
200
  var advance = function() {
198
201
  var start = cursor.from(), match;
199
202
  if (!(match = cursor.findNext())) {
@@ -179,7 +179,7 @@
179
179
  var data = findDoc(ts, doc);
180
180
 
181
181
  var argHints = ts.cachedArgHints;
182
- if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) <= 0)
182
+ if (argHints && argHints.doc == doc && cmpPos(argHints.start, change.to) >= 0)
183
183
  ts.cachedArgHints = null;
184
184
 
185
185
  var changed = data.changed;
@@ -306,7 +306,7 @@
306
306
  ts.request(cm, {type: "type", preferFunction: true, end: start}, function(error, data) {
307
307
  if (error || !data.type || !(/^fn\(/).test(data.type)) return;
308
308
  ts.cachedArgHints = {
309
- start: pos,
309
+ start: start,
310
310
  type: parseFnType(data.type),
311
311
  name: data.exprName || data.name || "fn",
312
312
  guess: data.guess,
@@ -55,6 +55,8 @@
55
55
  cmds[map["Alt-Left"] = "goSubwordLeft"] = function(cm) { moveSubword(cm, -1); };
56
56
  cmds[map["Alt-Right"] = "goSubwordRight"] = function(cm) { moveSubword(cm, 1); };
57
57
 
58
+ if (mac) map["Cmd-Left"] = "goLineStartSmart";
59
+
58
60
  var scrollLineCombo = mac ? "Ctrl-Alt-" : "Ctrl-";
59
61
 
60
62
  cmds[map[scrollLineCombo + "Up"] = "scrollLineUp"] = function(cm) {
@@ -122,6 +124,7 @@
122
124
  }
123
125
  cm.setSelections(newSelection);
124
126
  });
127
+ cm.execCommand("indentAuto");
125
128
  }
126
129
 
127
130
  cmds[map[ctrl + "Enter"] = "insertLineAfter"] = function(cm) { return insertLine(cm, false); };
@@ -417,27 +420,6 @@
417
420
 
418
421
  map[cK + ctrl + "Backspace"] = "delLineLeft";
419
422
 
420
- cmds[map["Backspace"] = "smartBackspace"] = function(cm) {
421
- if (cm.somethingSelected()) return CodeMirror.Pass;
422
-
423
- var cursor = cm.getCursor();
424
- var toStartOfLine = cm.getRange({line: cursor.line, ch: 0}, cursor);
425
- var column = CodeMirror.countColumn(toStartOfLine, null, cm.getOption("tabSize"));
426
- var indentUnit = cm.getOption("indentUnit");
427
-
428
- if (toStartOfLine && !/\S/.test(toStartOfLine) && column % indentUnit == 0) {
429
- var prevIndent = new Pos(cursor.line,
430
- CodeMirror.findColumn(toStartOfLine, column - indentUnit, indentUnit));
431
-
432
- // If no smart delete is happening (due to tab sizing) just do a regular delete
433
- if (prevIndent.ch == cursor.ch) return CodeMirror.Pass;
434
-
435
- return cm.replaceRange("", prevIndent, cursor, "+delete");
436
- } else {
437
- return CodeMirror.Pass;
438
- }
439
- };
440
-
441
423
  cmds[map[cK + ctrl + "K"] = "delLineRight"] = function(cm) {
442
424
  cm.operation(function() {
443
425
  var ranges = cm.listSelections();
@@ -26,7 +26,7 @@
26
26
  * 2. Variable declarations and short basic helpers
27
27
  * 3. Instance (External API) implementation
28
28
  * 4. Internal state tracking objects (input state, counter) implementation
29
- * and instanstiation
29
+ * and instantiation
30
30
  * 5. Key handler (the main command dispatcher) implementation
31
31
  * 6. Motion, operator, and action implementations
32
32
  * 7. Helper functions for the key handler, motions, operators, and actions
@@ -226,6 +226,7 @@
226
226
  { name: 'sort', shortName: 'sor' },
227
227
  { name: 'substitute', shortName: 's', possiblyAsync: true },
228
228
  { name: 'nohlsearch', shortName: 'noh' },
229
+ { name: 'yank', shortName: 'y' },
229
230
  { name: 'delmarks', shortName: 'delm' },
230
231
  { name: 'registers', shortName: 'reg', excludeFromCommandHistory: true },
231
232
  { name: 'global', shortName: 'g' }
@@ -641,7 +642,7 @@
641
642
  jumpList: createCircularJumpList(),
642
643
  macroModeState: new MacroModeState,
643
644
  // Recording latest f, t, F or T motion command.
644
- lastChararacterSearch: {increment:0, forward:true, selectedCharacter:''},
645
+ lastCharacterSearch: {increment:0, forward:true, selectedCharacter:''},
645
646
  registerController: new RegisterController({}),
646
647
  // search history buffer
647
648
  searchHistoryController: new HistoryController({}),
@@ -1047,7 +1048,7 @@
1047
1048
  };
1048
1049
  function HistoryController() {
1049
1050
  this.historyBuffer = [];
1050
- this.iterator;
1051
+ this.iterator = 0;
1051
1052
  this.initialPrefix = null;
1052
1053
  }
1053
1054
  HistoryController.prototype = {
@@ -1372,7 +1373,7 @@
1372
1373
  }
1373
1374
  },
1374
1375
  evalInput: function(cm, vim) {
1375
- // If the motion comand is set, execute both the operator and motion.
1376
+ // If the motion command is set, execute both the operator and motion.
1376
1377
  // Otherwise return.
1377
1378
  var inputState = vim.inputState;
1378
1379
  var motion = inputState.motion;
@@ -1909,7 +1910,7 @@
1909
1910
  },
1910
1911
 
1911
1912
  repeatLastCharacterSearch: function(cm, head, motionArgs) {
1912
- var lastSearch = vimGlobalState.lastChararacterSearch;
1913
+ var lastSearch = vimGlobalState.lastCharacterSearch;
1913
1914
  var repeat = motionArgs.repeat;
1914
1915
  var forward = motionArgs.forward === lastSearch.forward;
1915
1916
  var increment = (lastSearch.increment ? 1 : 0) * (forward ? -1 : 1);
@@ -3002,7 +3003,7 @@
3002
3003
  // Only clip if the selection ends with trailing newline + whitespace
3003
3004
  if (/\n\s*$/.test(selection)) {
3004
3005
  var lines = selection.split('\n');
3005
- // We know this is all whitepsace.
3006
+ // We know this is all whitespace.
3006
3007
  lines.pop();
3007
3008
 
3008
3009
  // Cases:
@@ -3088,9 +3089,9 @@
3088
3089
  }
3089
3090
 
3090
3091
  function recordLastCharacterSearch(increment, args) {
3091
- vimGlobalState.lastChararacterSearch.increment = increment;
3092
- vimGlobalState.lastChararacterSearch.forward = args.forward;
3093
- vimGlobalState.lastChararacterSearch.selectedCharacter = args.selectedCharacter;
3092
+ vimGlobalState.lastCharacterSearch.increment = increment;
3093
+ vimGlobalState.lastCharacterSearch.forward = args.forward;
3094
+ vimGlobalState.lastCharacterSearch.selectedCharacter = args.selectedCharacter;
3094
3095
  }
3095
3096
 
3096
3097
  var symbolToMode = {
@@ -3289,8 +3290,6 @@
3289
3290
  line = cm.getLine(lineNum);
3290
3291
  pos = (dir > 0) ? 0 : line.length;
3291
3292
  }
3292
- // Should never get here.
3293
- throw new Error('The impossible happened.');
3294
3293
  }
3295
3294
 
3296
3295
  /**
@@ -3452,7 +3451,7 @@
3452
3451
  }
3453
3452
 
3454
3453
  // TODO: perhaps this finagling of start and end positions belonds
3455
- // in codmirror/replaceRange?
3454
+ // in codemirror/replaceRange?
3456
3455
  function selectCompanionObject(cm, head, symb, inclusive) {
3457
3456
  var cur = head, start, end;
3458
3457
 
@@ -3783,17 +3782,10 @@
3783
3782
  }
3784
3783
  }
3785
3784
  function makePrompt(prefix, desc) {
3786
- var raw = '';
3787
- if (prefix) {
3788
- raw += '<span style="font-family: monospace">' + prefix + '</span>';
3789
- }
3790
- raw += '<input type="text"/> ' +
3791
- '<span style="color: #888">';
3792
- if (desc) {
3793
- raw += '<span style="color: #888">';
3794
- raw += desc;
3795
- raw += '</span>';
3796
- }
3785
+ var raw = '<span style="font-family: monospace; white-space: pre">' +
3786
+ (prefix || "") + '<input type="text"></span>';
3787
+ if (desc)
3788
+ raw += ' <span style="color: #888">' + desc + '</span>';
3797
3789
  return raw;
3798
3790
  }
3799
3791
  var searchPromptDesc = '(Javascript regexp)';
@@ -4514,14 +4506,21 @@
4514
4506
  if (CodeMirror.commands.save) {
4515
4507
  // If a save command is defined, call it.
4516
4508
  CodeMirror.commands.save(cm);
4517
- } else {
4518
- // Saves to text area if no save command is defined.
4509
+ } else if (cm.save) {
4510
+ // Saves to text area if no save command is defined and cm.save() is available.
4519
4511
  cm.save();
4520
4512
  }
4521
4513
  },
4522
4514
  nohlsearch: function(cm) {
4523
4515
  clearSearchHighlight(cm);
4524
4516
  },
4517
+ yank: function (cm) {
4518
+ var cur = copyCursor(cm.getCursor());
4519
+ var line = cur.line;
4520
+ var lineText = cm.getLine(line);
4521
+ vimGlobalState.registerController.pushText(
4522
+ '0', 'yank', lineText, true, true);
4523
+ },
4525
4524
  delmarks: function(cm, params) {
4526
4525
  if (!params.argString || !trim(params.argString)) {
4527
4526
  showConfirm(cm, 'Argument required');
@@ -11,21 +11,19 @@
11
11
  })(function(CodeMirror) {
12
12
  "use strict";
13
13
 
14
- function Context(indented, column, type, align, prev) {
14
+ function Context(indented, column, type, info, align, prev) {
15
15
  this.indented = indented;
16
16
  this.column = column;
17
17
  this.type = type;
18
+ this.info = info;
18
19
  this.align = align;
19
20
  this.prev = prev;
20
21
  }
21
- function isStatement(type) {
22
- return type == "statement" || type == "switchstatement" || type == "namespace";
23
- }
24
- function pushContext(state, col, type) {
22
+ function pushContext(state, col, type, info) {
25
23
  var indent = state.indented;
26
- if (state.context && isStatement(state.context.type) && !isStatement(type))
24
+ if (state.context && state.context.type != "statement" && type != "statement")
27
25
  indent = state.context.indented;
28
- return state.context = new Context(indent, col, type, null, state.context);
26
+ return state.context = new Context(indent, col, type, info, null, state.context);
29
27
  }
30
28
  function popContext(state) {
31
29
  var t = state.context.type;
@@ -34,15 +32,16 @@ function popContext(state) {
34
32
  return state.context = state.context.prev;
35
33
  }
36
34
 
37
- function typeBefore(stream, state) {
35
+ function typeBefore(stream, state, pos) {
38
36
  if (state.prevToken == "variable" || state.prevToken == "variable-3") return true;
39
- if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, stream.start))) return true;
37
+ if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
38
+ if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
40
39
  }
41
40
 
42
41
  function isTopScope(context) {
43
42
  for (;;) {
44
43
  if (!context || context.type == "top") return true;
45
- if (context.type == "}" && context.prev.type != "namespace") return false;
44
+ if (context.type == "}" && context.prev.info != "namespace") return false;
46
45
  context = context.prev;
47
46
  }
48
47
  }
@@ -147,13 +146,18 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
147
146
  return "comment";
148
147
  }
149
148
 
149
+ function maybeEOL(stream, state) {
150
+ if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
151
+ state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
152
+ }
153
+
150
154
  // Interface
151
155
 
152
156
  return {
153
157
  startState: function(basecolumn) {
154
158
  return {
155
159
  tokenize: null,
156
- context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
160
+ context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
157
161
  indented: 0,
158
162
  startOfLine: true,
159
163
  prevToken: null
@@ -167,36 +171,31 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
167
171
  state.indented = stream.indentation();
168
172
  state.startOfLine = true;
169
173
  }
170
- if (stream.eatSpace()) return null;
174
+ if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
171
175
  curPunc = isDefKeyword = null;
172
176
  var style = (state.tokenize || tokenBase)(stream, state);
173
177
  if (style == "comment" || style == "meta") return style;
174
178
  if (ctx.align == null) ctx.align = true;
175
179
 
176
- if (endStatement.test(curPunc)) while (isStatement(state.context.type)) popContext(state);
180
+ if (endStatement.test(curPunc)) while (state.context.type == "statement") popContext(state);
177
181
  else if (curPunc == "{") pushContext(state, stream.column(), "}");
178
182
  else if (curPunc == "[") pushContext(state, stream.column(), "]");
179
183
  else if (curPunc == "(") pushContext(state, stream.column(), ")");
180
184
  else if (curPunc == "}") {
181
- while (isStatement(ctx.type)) ctx = popContext(state);
185
+ while (ctx.type == "statement") ctx = popContext(state);
182
186
  if (ctx.type == "}") ctx = popContext(state);
183
- while (isStatement(ctx.type)) ctx = popContext(state);
187
+ while (ctx.type == "statement") ctx = popContext(state);
184
188
  }
185
189
  else if (curPunc == ctx.type) popContext(state);
186
190
  else if (indentStatements &&
187
191
  (((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
188
- (isStatement(ctx.type) && curPunc == "newstatement"))) {
189
- var type = "statement";
190
- if (curPunc == "newstatement" && indentSwitch && stream.current() == "switch")
191
- type = "switchstatement";
192
- else if (style == "keyword" && stream.current() == "namespace")
193
- type = "namespace";
194
- pushContext(state, stream.column(), type);
192
+ (ctx.type == "statement" && curPunc == "newstatement"))) {
193
+ pushContext(state, stream.column(), "statement", stream.current());
195
194
  }
196
195
 
197
196
  if (style == "variable" &&
198
197
  ((state.prevToken == "def" ||
199
- (parserConfig.typeFirstDefinitions && typeBefore(stream, state) &&
198
+ (parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
200
199
  isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
201
200
  style = "def";
202
201
 
@@ -209,24 +208,28 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
209
208
 
210
209
  state.startOfLine = false;
211
210
  state.prevToken = isDefKeyword ? "def" : style || curPunc;
211
+ maybeEOL(stream, state);
212
212
  return style;
213
213
  },
214
214
 
215
215
  indent: function(state, textAfter) {
216
- if (state.tokenize != tokenBase && state.tokenize != null) return CodeMirror.Pass;
216
+ if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
217
217
  var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
218
- if (isStatement(ctx.type) && firstChar == "}") ctx = ctx.prev;
218
+ if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
219
+ if (parserConfig.dontIndentStatements)
220
+ while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
221
+ ctx = ctx.prev
219
222
  if (hooks.indent) {
220
223
  var hook = hooks.indent(state, ctx, textAfter);
221
224
  if (typeof hook == "number") return hook
222
225
  }
223
226
  var closing = firstChar == ctx.type;
224
- var switchBlock = ctx.prev && ctx.prev.type == "switchstatement";
227
+ var switchBlock = ctx.prev && ctx.prev.info == "switch";
225
228
  if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
226
229
  while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
227
230
  return ctx.indented
228
231
  }
229
- if (isStatement(ctx.type))
232
+ if (ctx.type == "statement")
230
233
  return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
231
234
  if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
232
235
  return ctx.column + (closing ? 0 : 1);
@@ -386,6 +389,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
386
389
  defKeywords: words("class namespace struct enum union"),
387
390
  typeFirstDefinitions: true,
388
391
  atoms: words("true false null"),
392
+ dontIndentStatements: /^template$/,
389
393
  hooks: {
390
394
  "#": cppHook,
391
395
  "*": pointerHook,
@@ -429,6 +433,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
429
433
  typeFirstDefinitions: true,
430
434
  atoms: words("true false null"),
431
435
  endStatement: /^[;:]$/,
436
+ number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
432
437
  hooks: {
433
438
  "@": function(stream) {
434
439
  stream.eatWhile(/[\w\$_]/);
@@ -531,7 +536,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
531
536
  "=": function(stream, state) {
532
537
  var cx = state.context
533
538
  if (cx.type == "}" && cx.align && stream.eat(">")) {
534
- state.context = new Context(cx.indented, cx.column, cx.type, null, cx.prev)
539
+ state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
535
540
  return "operator"
536
541
  } else {
537
542
  return false
@@ -667,7 +672,7 @@ CodeMirror.defineMode("clike", function(config, parserConfig) {
667
672
 
668
673
  def("text/x-objectivec", {
669
674
  name: "clike",
670
- keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginery BOOL Class bycopy byref id IMP in " +
675
+ keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in " +
671
676
  "inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
672
677
  types: words(cTypes),
673
678
  atoms: words("YES NO NULL NILL ON OFF true false"),