Comparing changes
Open a pull request
|
|
marijnh |
Bump version number post-3.18
|
17aa8e1
|
|||
|
|
marijnh |
Note 3.18 in releases.html
|
8a57cc0
|
|||
|
|
marijnh |
Remove unused file
|
bc07cbd
|
|
|
marijnh |
Make shift-delete/shift-backspace behavior match non-shift behavior
Closes #1839 |
6c62022
|
|||
|
|
marijnh |
Don't bind shift-delete, only shift-backspace
See 6c62022 |
3e12cbd
|
|||
|
|
marijnh |
[hardwrap addon] Add
|
ca167af
|
|||
|
|
marijnh |
[hardwrap addon] Fix bugginess when wrapping multiple paragraphs
|
3386198
|
|||
|
|
marijnh |
[real-world uses] Add Codio
|
27b22ca
|
|||
|
|
marijnh |
[real-world uses] Fix misspelled url
|
fd85ce1
|
|||
|
|
santec + marijnh |
[sql_mode] added keywords
* added keywords from mysql & mariadb recent versions |
437eb7c
|
|||
|
|
marijnh |
[themes] Move error style to bottom to give it precedence
|
39499fd
|
|||
|
|
marijnh |
[xml mode] Leave old style intact when adding error style
Fixes a problem with matchtags getting confused. Closes #1841 |
a6c2e01
|
|||
|
|
marijnh |
[xml mode] Leave tag tokenizer when encountering '<'
Issue #1841 |
49c881a
|
|
|
jdar + marijnh |
adding gherkin mode
|
11f4a8a
|
|||
|
|
marijnh |
[gherkin mode] Remove double mime definition
|
af772f9
|
|
|
0b10011 + marijnh |
[css] Fix indentation issue in SCSS mode with mixin variables (closes #…
…1846). Also improve handling of parentheses and curly braces. |
94ccdb5
|
|||
|
|
0b10011 + marijnh |
[css] Add tests for indentation
|
e6ca873
|
|||
|
|
marijnh |
[css mode] Clean up whitespace
Kill all tabs. Issue #1851 |
8b7a8e0
|
|||
|
|
brettz9 + marijnh |
[manual] Fix incorrect mention of class used by matchtag addon
|
d0a82f4
|
|||
|
|
marijnh |
[real-world uses] Add PrinBit, complete.ly
|
92b92f9
|
|
|
marijnh |
[real-world uses] Add Liveweave
|
6e101a8
|
|
|
marijnh |
[real-world uses] Add Puzzlescript
|
23ce2a2
|
|
|
brandonwamboldt + marijnh |
Remove bower version
|
82b62f3
|
|||
|
|
marijnh |
Add swapDoc event, make foldgutter addon listen for it
Issue #1865 |
06220c5
|
|||
|
|
spacelis + marijnh |
[vim keymap] Fix yanking the last line.
When the last line in an editor has no newline char at the end, yanking it line-wise should append one. So the last char will not be dropped when pasting it. |
b6ff3b9
|
|||
|
|
MaximKraev + marijnh |
[less mode] Support for the comments addon
|
2a82cfb
|
|||
|
|
brandonwamboldt + marijnh |
[smartymixed mode] Smarty tags in HTML attributes break
Closes #1768 |
c3e84e6
|
|
|
mbonaci + marijnh |
[mbo theme] Add
|
1a1646d
|
|||
|
|
nagaozen + marijnh |
[sql mode] Add text/x-mssql MIME
|
30287f9
|
|
|
MasseGuillaume + marijnh |
[solarized theme] show active line
|
d0eefcc
|
|
|
marijnh |
Add missing g flag to .replace regexp
|
f27cfd0
|
|||
|
|
marijnh |
[real-world uses] Add compilejava.net
|
390a47e
|
|||
|
|
peterkroon + marijnh |
[less mode] improve highlighting, indentation
Better handling of attributes, .2px, tags.
````
.page {
.content {
width: 870px;
padding: 45px;
}
margin: 0 auto;
font-family: 'Georgia', serif;
font-size: 18px;
line-height: 26px;
padding: 0 60px;
code {
font-size: 16px;
}
pre {
border-width: 1px;
border-style: dashed;
padding: 15px;
margin: 15px 0;
}
h1 {
text-align: left;
font-size: 40px;
margin-top: 15px;
margin-bottom: 35px;
}
p + h1 { margin-top: 60px }
h2, h3 {
margin: 30px 0 15px 0;
}
p + h2, pre + h2, code + h2 {
border-top: 6px solid rgba(255, 255, 255, 0.1);
padding-top: 30px;
}
h3 {
margin: 15px 0;
}
}
```` |
6fd2965
|
|||
|
|
andersonvom + marijnh |
[indent-fold addon] Fix indentation folding
Fix next line after block being incorrectly folded into the block Fix detection of the end of a code block |
98bc784
|
|||
|
|
marijnh |
[indent-fold addon] Fix coding style, use lastLine not lineCount
Issue #1859 |
dad387d
|
|
|
marijnh |
[manual] Fix typo
|
51a4b57
|
|
|
tahajahangir + marijnh |
[lint addon] Wrap long lint messages
e.g. errors on css `input.someLongClassName {}` |
c2189ec
|
|||
|
|
Dominator008 + marijnh |
Add handleEx() to Vim mode's API
Provide an alternative (programmatic) way to run Ex commands. |
5ccebee
|
|||
|
|
marijnh |
Document a few more addons
Issue #1894 |
51a45cc
|
|||
|
|
marijnh |
Improve mode writing docs a little, document line- and line-backgroun…
…d- tokens |
8232c40
|
|||
|
|
marijnh |
Work around poor italic support for webfont
|
72217c5
|
|||
|
|
0b10011 + marijnh |
[continuelist addon] Should continue list even after special chars (s…
…pace, !, etc) |
865bfc8
|
|
|
marijnh |
Mark release 3.19.0
|
231e235
|
- +1 −0 AUTHORS
- +1 −1 addon/edit/closetag.js
- +1 −1 addon/edit/continuelist.js
- +6 −4 addon/fold/foldcode.js
- +21 −0 addon/fold/foldgutter.css
- +2 −0 addon/fold/foldgutter.js
- +21 −7 addon/fold/indent-fold.js
- +3 −19 addon/hint/javascript-hint.js
- +105 −0 addon/hint/sql-hint.js
- +1 −0 addon/hint/xml-hint.js
- +1 −0 addon/lint/lint.css
- +2 −0 addon/search/search.js
- +1 −1 addon/tern/tern.js
- +99 −0 addon/wrap/hardwrap.js
- +0 −1 bower.json
- +4 −24 demo/folding.html
- +69 −0 demo/hardwrap.html
- +2 −0 demo/theme.html
- +5 −0 doc/compress.html
- +4 −0 doc/docs.css
- +184 −72 doc/manual.html
- +7 −0 doc/realworld.html
- +16 −0 doc/releases.html
- +1 −1 index.html
- +55 −17 keymap/vim.js
- +1 −1 lib/codemirror.css
- +42 −19 lib/codemirror.js
- +314 −313 mode/coffeescript/coffeescript.js
- +19 −7 mode/css/css.js
- +5 −1 mode/css/scss_test.js
- +5 −1 mode/css/test.js
- +147 −0 mode/eiffel/eiffel.js
- +430 −0 mode/eiffel/index.html
- +2 −1 mode/gfm/gfm.js
- +168 −0 mode/gherkin/gherkin.js
- +48 −0 mode/gherkin/index.html
- +2 −0 mode/index.html
- +110 −22 mode/less/less.js
- +3 −1 mode/meta.js
- +4 −4 mode/php/php.js
- +1 −1 mode/smartymixed/index.html
- +6 −1 mode/smartymixed/smartymixed.js
- +2 −1 mode/sql/index.html
- +15 −2 mode/sql/sql.js
- +7 −3 mode/xml/xml.js
- +1 −1 package.json
- +0 −1,372 test/lint/parse-js.js
- +16 −8 test/mode_test.js
- +35 −0 test/vim_test.js
- +1 −1 theme/3024-day.css
- +1 −1 theme/3024-night.css
- +1 −1 theme/ambiance.css
- +1 −1 theme/base16-dark.css
- +1 −1 theme/base16-light.css
- +1 −1 theme/blackboard.css
- +1 −1 theme/cobalt.css
- +1 −1 theme/eclipse.css
- +1 −1 theme/elegant.css
- +1 −1 theme/erlang-dark.css
- +1 −1 theme/lesser-dark.css
- +35 −0 theme/mbo.css
- +1 −1 theme/midnight.css
- +1 −1 theme/monokai.css
- +1 −1 theme/night.css
- +1 −1 theme/paraiso-dark.css
- +1 −1 theme/paraiso-light.css
- +1 −1 theme/rubyblue.css
- +7 −7 theme/solarized.css
- +1 −1 theme/the-matrix.css
- +1 −1 theme/tomorrow-night-eighties.css
- +1 −1 theme/twilight.css
- +1 −1 theme/vibrant-ink.css
- +1 −1 theme/xq-dark.css
- +1 −1 theme/xq-light.css
| @@ -84,6 +84,7 @@ Ford_Lawnmower | ||
| Gabriel Nahmias | ||
| galambalazs | ||
| Gautam Mehta | ||
| +Glenn Jorde | ||
| Glenn Ruehle | ||
| Golevka | ||
| Gordon Smith | ||
| @@ -72,7 +72,7 @@ | ||
| function autoCloseSlash(cm) { | ||
| var pos = cm.getCursor(), tok = cm.getTokenAt(pos); | ||
| var inner = CodeMirror.innerMode(cm.getMode(), tok.state), state = inner.state; | ||
| - if (tok.string.charAt(0) != "<" || inner.mode.name != "xml") return CodeMirror.Pass; | ||
| + if (tok.string.charAt(0) != "<" || tok.start != pos.ch - 1 || inner.mode.name != "xml") return CodeMirror.Pass; | ||
| var tagName = state.context && state.context.tagName; | ||
| if (tagName) cm.replaceSelection("/" + tagName + ">", "end"); | ||
| @@ -6,7 +6,7 @@ | ||
| CodeMirror.commands.newlineAndIndentContinueMarkdownList = function(cm) { | ||
| var pos = cm.getCursor(), | ||
| - inList = cm.getStateAfter(pos.line).list, | ||
| + inList = cm.getStateAfter(pos.line).list !== false, | ||
| match; | ||
| if (!inList || !(match = cm.getLine(pos.line).match(listRE))) { | ||
| @@ -1,7 +1,7 @@ | ||
| (function() { | ||
| "use strict"; | ||
| - function doFold(cm, pos, options) { | ||
| + function doFold(cm, pos, options, force) { | ||
| var finder = options && (options.call ? options : options.rangeFinder); | ||
| if (!finder) finder = cm.getHelper(pos, "fold"); | ||
| if (!finder) return; | ||
| @@ -13,7 +13,7 @@ | ||
| if (!range || range.to.line - range.from.line < minSize) return null; | ||
| var marks = cm.findMarksAt(range.from); | ||
| for (var i = 0; i < marks.length; ++i) { | ||
| - if (marks[i].__isFold) { | ||
| + if (marks[i].__isFold && force !== "fold") { | ||
| if (!allowFolded) return null; | ||
| range.cleared = true; | ||
| marks[i].clear(); | ||
| @@ -27,7 +27,7 @@ | ||
| pos = CodeMirror.Pos(pos.line - 1, 0); | ||
| range = getRange(false); | ||
| } | ||
| - if (!range || range.cleared) return; | ||
| + if (!range || range.cleared || force === "unfold") return; | ||
| var myWidget = makeWidget(options); | ||
| CodeMirror.on(myWidget, "mousedown", function() { myRange.clear(); }); | ||
| @@ -59,7 +59,9 @@ | ||
| }; | ||
| // New-style interface | ||
| - CodeMirror.defineExtension("foldCode", function(pos, options) { doFold(this, pos, options); }); | ||
| + CodeMirror.defineExtension("foldCode", function(pos, options, force) { | ||
| + doFold(this, pos, options, force); | ||
| + }); | ||
| CodeMirror.registerHelper("fold", "combine", function() { | ||
| var funcs = Array.prototype.slice.call(arguments, 0); | ||
| @@ -0,0 +1,21 @@ | ||
| +.CodeMirror-foldmarker { | ||
| + color: blue; | ||
| + text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; | ||
| + font-family: arial; | ||
| + line-height: .3; | ||
| + cursor: pointer; | ||
| +} | ||
| +.CodeMirror-foldgutter { | ||
| + width: .7em; | ||
| +} | ||
| +.CodeMirror-foldgutter-open, | ||
| +.CodeMirror-foldgutter-folded { | ||
| + color: #555; | ||
| + cursor: pointer; | ||
| +} | ||
| +.CodeMirror-foldgutter-open:after { | ||
| + content: "\25BE"; | ||
| +} | ||
| +.CodeMirror-foldgutter-folded:after { | ||
| + content: "\25B8"; | ||
| +} |
| @@ -10,6 +10,7 @@ | ||
| cm.off("viewportChange", onViewportChange); | ||
| cm.off("fold", onFold); | ||
| cm.off("unfold", onFold); | ||
| + cm.off("swapDoc", updateInViewport); | ||
| } | ||
| if (val) { | ||
| cm.state.foldGutter = new State(parseOptions(val)); | ||
| @@ -19,6 +20,7 @@ | ||
| cm.on("viewportChange", onViewportChange); | ||
| cm.on("fold", onFold); | ||
| cm.on("unfold", onFold); | ||
| + cm.on("swapDoc", updateInViewport); | ||
| } | ||
| }); | ||
| @@ -1,12 +1,26 @@ | ||
| CodeMirror.registerHelper("fold", "indent", function(cm, start) { | ||
| - var tabSize = cm.getOption("tabSize"), firstLine = cm.getLine(start.line); | ||
| - var myIndent = CodeMirror.countColumn(firstLine, null, tabSize); | ||
| - for (var i = start.line + 1, end = cm.lineCount(); i < end; ++i) { | ||
| - var curLine = cm.getLine(i); | ||
| - if (CodeMirror.countColumn(curLine, null, tabSize) < myIndent && | ||
| - CodeMirror.countColumn(cm.getLine(i-1), null, tabSize) > myIndent) | ||
| + var lastLine = cm.lastLine(), | ||
| + tabSize = cm.getOption("tabSize"), | ||
| + firstLine = cm.getLine(start.line), | ||
| + myIndent = CodeMirror.countColumn(firstLine, null, tabSize); | ||
| + | ||
| + function foldEnded(curColumn, prevColumn) { | ||
| + return curColumn < myIndent || | ||
| + (curColumn == myIndent && prevColumn >= myIndent) || | ||
| + (curColumn > myIndent && i == lastLine); | ||
| + } | ||
| + | ||
| + for (var i = start.line + 1; i <= lastLine; i++) { | ||
| + var curColumn = CodeMirror.countColumn(cm.getLine(i), null, tabSize); | ||
| + var prevColumn = CodeMirror.countColumn(cm.getLine(i-1), null, tabSize); | ||
| + | ||
| + if (foldEnded(curColumn, prevColumn)) { | ||
| + var lastFoldLineNumber = curColumn > myIndent && i == lastLine ? i : i-1; | ||
| + var lastFoldLine = cm.getLine(lastFoldLineNumber); | ||
| return {from: CodeMirror.Pos(start.line, firstLine.length), | ||
| - to: CodeMirror.Pos(i, curLine.length)}; | ||
| + to: CodeMirror.Pos(lastFoldLineNumber, lastFoldLine.length)}; | ||
| + } | ||
| } | ||
| }); | ||
| + | ||
| CodeMirror.indentRangeFinder = CodeMirror.fold.indent; // deprecated |
| @@ -33,21 +33,6 @@ | ||
| tprop = getToken(editor, Pos(cur.line, tprop.start)); | ||
| if (tprop.string != ".") return; | ||
| tprop = getToken(editor, Pos(cur.line, tprop.start)); | ||
| - if (tprop.string == ')') { | ||
| - var level = 1; | ||
| - do { | ||
| - tprop = getToken(editor, Pos(cur.line, tprop.start)); | ||
| - switch (tprop.string) { | ||
| - case ')': level++; break; | ||
| - case '(': level--; break; | ||
| - default: break; | ||
| - } | ||
| - } while (level > 0); | ||
| - tprop = getToken(editor, Pos(cur.line, tprop.start)); | ||
| - if (tprop.type.indexOf("variable") === 0) | ||
| - tprop.type = "function"; | ||
| - else return; // no clue | ||
| - } | ||
| if (!context) var context = []; | ||
| context.push(tprop); | ||
| } | ||
| @@ -110,11 +95,11 @@ | ||
| for (var name in obj) maybeAdd(name); | ||
| } | ||
| - if (context) { | ||
| + if (context && context.length) { | ||
| // If this is a property, see if it belongs to some object we can | ||
| // find in the current environment. | ||
| var obj = context.pop(), base; | ||
| - if (obj.type.indexOf("variable") === 0) { | ||
| + if (obj.type && obj.type.indexOf("variable") === 0) { | ||
| if (options && options.additionalContext) | ||
| base = options.additionalContext[obj.string]; | ||
| base = base || window[obj.string]; | ||
| @@ -132,8 +117,7 @@ | ||
| while (base != null && context.length) | ||
| base = base[context.pop().string]; | ||
| if (base != null) gatherCompletions(base); | ||
| - } | ||
| - else { | ||
| + } else { | ||
| // If not, just look in the window object and any local scope | ||
| // (reading into JS mode internals to get at the local and global variables) | ||
| for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name); | ||
| @@ -0,0 +1,105 @@ | ||
| +(function () { | ||
| + "use strict"; | ||
| + | ||
| + var tables; | ||
| + var keywords; | ||
| + | ||
| + function getKeywords(editor) { | ||
| + var mode = editor.doc.modeOption; | ||
| + if(mode === "sql") mode = "text/x-sql"; | ||
| + return CodeMirror.resolveMode(mode).keywords; | ||
| + } | ||
| + | ||
| + function match(string, word) { | ||
| + var len = string.length; | ||
| + var sub = word.substr(0, len); | ||
| + return string.toUpperCase() === sub.toUpperCase(); | ||
| + } | ||
| + | ||
| + function addMatches(result, search, wordlist, formatter) { | ||
| + for(var word in wordlist) { | ||
| + if(!wordlist.hasOwnProperty(word)) continue; | ||
| + if(Array.isArray(wordlist)) { | ||
| + word = wordlist[word]; | ||
| + } | ||
| + if(match(search, word)) { | ||
| + result.push(formatter(word)); | ||
| + } | ||
| + } | ||
| + } | ||
| + | ||
| + function columnCompletion(result, editor) { | ||
| + var cur = editor.getCursor(); | ||
| + var token = editor.getTokenAt(cur); | ||
| + var string = token.string.substr(1); | ||
| + var prevCur = CodeMirror.Pos(cur.line, token.start); | ||
| + var table = editor.getTokenAt(prevCur).string; | ||
| + var columns = tables[table]; | ||
| + if(!columns) { | ||
| + table = findTableByAlias(table, editor); | ||
| + } | ||
| + columns = tables[table]; | ||
| + if(!columns) { | ||
| + return; | ||
| + } | ||
| + addMatches(result, string, columns, | ||
| + function(w) {return "." + w;}); | ||
| + } | ||
| + | ||
| + function eachWord(line, f) { | ||
| + var words = line.text.split(" "); | ||
| + for(var i = 0; i < words.length; i++) { | ||
| + f(words[i]); | ||
| + } | ||
| + } | ||
| + | ||
| + // Tries to find possible table name from alias. | ||
| + function findTableByAlias(alias, editor) { | ||
| + var aliasUpperCase = alias.toUpperCase(); | ||
| + var previousWord = ""; | ||
| + var table = ""; | ||
| + | ||
| + editor.eachLine(function(line) { | ||
| + eachWord(line, function(word) { | ||
| + var wordUpperCase = word.toUpperCase(); | ||
| + if(wordUpperCase === aliasUpperCase) { | ||
| + if(tables.hasOwnProperty(previousWord)) { | ||
| + table = previousWord; | ||
| + } | ||
| + } | ||
| + if(wordUpperCase !== "AS") { | ||
| + previousWord = word; | ||
| + } | ||
| + }); | ||
| + }); | ||
| + return table; | ||
| + } | ||
| + | ||
| + function sqlHint(editor, options) { | ||
| + tables = (options && options.tables) || {}; | ||
| + keywords = keywords || getKeywords(editor); | ||
| + var cur = editor.getCursor(); | ||
| + var token = editor.getTokenAt(cur); | ||
| + | ||
| + var result = []; | ||
| + | ||
| + var search = token.string.trim(); | ||
| + | ||
| + addMatches(result, search, keywords, | ||
| + function(w) {return w.toUpperCase();}); | ||
| + | ||
| + addMatches(result, search, tables, | ||
| + function(w) {return w;}); | ||
| + | ||
| + if(search.lastIndexOf('.') === 0) { | ||
| + columnCompletion(result, editor); | ||
| + } | ||
| + | ||
| + return { | ||
| + list: result, | ||
| + from: CodeMirror.Pos(cur.line, token.start), | ||
| + to: CodeMirror.Pos(cur.line, token.end) | ||
| + }; | ||
| + } | ||
| + CodeMirror.registerHelper("hint", "sql", sqlHint); | ||
| +})(); |
| @@ -37,6 +37,7 @@ | ||
| Pos(cur.line, token.type == "string" ? token.start : token.end)); | ||
| var atName = before.match(/([^\s\u00a0=<>\"\']+)=$/), atValues; | ||
| if (!atName || !attrs.hasOwnProperty(atName[1]) || !(atValues = attrs[atName[1]])) return; | ||
| + if (typeof atValues == 'function') atValues = atValues.call(this, cm); // Functions can be used to supply values for autocomplete widget | ||
| if (token.type == "string") { | ||
| prefix = token.string; | ||
| if (/['"]/.test(token.string.charAt(0))) { | ||
| @@ -14,6 +14,7 @@ | ||
| padding: 2px 5px; | ||
| position: fixed; | ||
| white-space: pre; | ||
| + white-space: pre-wrap; | ||
| z-index: 100; | ||
| max-width: 600px; | ||
| opacity: 0; | ||
| @@ -70,6 +70,7 @@ | ||
| if (!cursor.find(rev)) return; | ||
| } | ||
| cm.setSelection(cursor.from(), cursor.to()); | ||
| + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); | ||
| state.posFrom = cursor.from(); state.posTo = cursor.to(); | ||
| });} | ||
| function clearSearch(cm) {cm.operation(function() { | ||
| @@ -108,6 +109,7 @@ | ||
| (start && cursor.from().line == start.line && cursor.from().ch == start.ch)) return; | ||
| } | ||
| cm.setSelection(cursor.from(), cursor.to()); | ||
| + cm.scrollIntoView({from: cursor.from(), to: cursor.to()}); | ||
| confirmDialog(cm, doReplaceConfirm, "Replace?", | ||
| [function() {doReplace(match);}, advance]); | ||
| }; | ||
| @@ -439,7 +439,7 @@ | ||
| for (var file in perFile) { | ||
| var known = ts.docs[file], chs = perFile[file];; | ||
| if (!known) continue; | ||
| - chs.sort(function(a, b) { return cmpPos(b, a); }); | ||
| + chs.sort(function(a, b) { return cmpPos(b.start, a.start); }); | ||
| var origin = "*rename" + (++nextChangeOrig); | ||
| for (var i = 0; i < chs.length; ++i) { | ||
| var ch = chs[i]; | ||
Showing you all comments on commits in this comparison.
anstosa
commented on a9ef54c
Oct 18, 2013
|
Instead of removing the block that handles parens, you might change line 45 to |
|
But how would the completer ever know what a function returns? |
anstosa
commented on a9ef54c
Oct 18, 2013
|
We use a modified version of this script to autocomplete for a JS API. If you have an API reference* that says what valid properties an functions are on various objects and instances of objects, this comes in handy. Though you're right, in its raw state I suppose that block isn't of much use. * ours looks something like this: api = {
Type: {...}
Global: {
SomeConstructor: {
'@type': api.Type.Class,
toString: {
'@type': api.Type.InstanceMethod
},
...
}
}
}; |
|
The simple javascript completer doesn't have a way to provide it with an API spec, as far as I know, so it won't be able to use the information this loop was retrieving. The Tern-based completer already does a much better job of finding the expression that's being completed (by using a parser). |
|
This is causing issues with Chrome 34.0.1847.45 beta. Even when the scrollbar width is actually non zero, test.offsetHeight - test.clientHeight is computed as 0. As a result, the scrollbar is visible but does not accept mouse events. |
|
Never mind, just saw marijnh#2326 |