From af430aca2220618b7945456d36e727c448d3e273 Mon Sep 17 00:00:00 2001 From: Sietse Brouwer Date: Mon, 20 Jan 2020 16:23:11 +0100 Subject: [PATCH 1/2] Fix for parameter hints not showing when using tabs instead of spaces Parameter hints were not showing when using the tab character for indents. In case of spaces a column number equals the character position in the line string, but in case of tabs that trick doesn't work. This fix converts a column number to a character position, taking tabs into account. --- src/JSUtils/Session.js | 51 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/JSUtils/Session.js b/src/JSUtils/Session.js index a102edb0cee..0a6c94203d1 100644 --- a/src/JSUtils/Session.js +++ b/src/JSUtils/Session.js @@ -394,6 +394,43 @@ define(function (require, exports, module) { lex.prev.info === "call"))); } + /** + * Convert a column number based on a line with spaces + * to a character position in a string with (possibly) tabs. + * For example: + * In the line `function ()` with tab size 4 and col = 8, + * col 8 is referring to the `f` of `function`, because it is based on a line with spaces. + * The character position this function will output, is 2, referring to the same `f`. + * + * @param {Number} col - column number in a line with spaces + * @param {String} lineText - a line of text in the editor + * @param {Number} tabSize - tab size in the editor + * @return {Number} character position in the line of text + */ + function columnToCharPos(col, lineText, tabSize) { + var spaces, + addedChars = 0, + posInLineWithSpaces = 0, + tabPos = 0; + + // Check for tabs in the text part before `col` + while (lineText.indexOf("\t") > -1 && posInLineWithSpaces < col) { + // Calculate number of spaces to the next tab stop + tabPos = lineText.indexOf("\t"); + posInLineWithSpaces += tabPos; + spaces = tabSize - posInLineWithSpaces % tabSize; + posInLineWithSpaces += spaces; + + // The tab itself is 1 character, + // so when for eaxample the tab was 4 spaces, we added 4 - 1 = 3 characters + addedChars += spaces - 1; + + // Process rest of the line + lineText = lineText.substring(tabPos + 1); + } + return col - addedChars; + } + if (token) { // if this token is part of a function call, then the tokens lexical info // will be annotated with "call". @@ -427,9 +464,17 @@ define(function (require, exports, module) { var col = lexical.info === "call" ? lexical.column : lexical.prev.column, line, e, - found; + found, + lineText, + charPos, + tabSize = this.editor._codeMirror.options.tabSize; + for (line = this.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { - if (this.getLine(line).charAt(col) === "(") { + // Column is based on a line with spaces. + // We have to convert it to a character position when tabs are used, otherwise our check will fail. + lineText = this.getLine(line); + charPos = columnToCharPos(col, lineText, tabSize); + if (lineText.charAt(charPos) === "(") { found = true; break; } @@ -437,7 +482,7 @@ define(function (require, exports, module) { if (found) { inFunctionCall = true; - functionCallPos = {line: line, ch: col}; + functionCallPos = {line: line, ch: charPos}; } } } From 748b41f5a2a9f53fa8155a96cb1db7f62f589d3f Mon Sep 17 00:00:00 2001 From: Sietse Brouwer Date: Tue, 11 Feb 2020 16:04:31 +0100 Subject: [PATCH 2/2] Code clean-up: using Editor method to convert column number to char pos Using the build-in method Editor.getCharIndexForColumn results in much shorter and cleaner code. --- src/JSUtils/Session.js | 46 +++--------------------------------------- 1 file changed, 3 insertions(+), 43 deletions(-) diff --git a/src/JSUtils/Session.js b/src/JSUtils/Session.js index 0a6c94203d1..b15825664d3 100644 --- a/src/JSUtils/Session.js +++ b/src/JSUtils/Session.js @@ -394,43 +394,6 @@ define(function (require, exports, module) { lex.prev.info === "call"))); } - /** - * Convert a column number based on a line with spaces - * to a character position in a string with (possibly) tabs. - * For example: - * In the line `function ()` with tab size 4 and col = 8, - * col 8 is referring to the `f` of `function`, because it is based on a line with spaces. - * The character position this function will output, is 2, referring to the same `f`. - * - * @param {Number} col - column number in a line with spaces - * @param {String} lineText - a line of text in the editor - * @param {Number} tabSize - tab size in the editor - * @return {Number} character position in the line of text - */ - function columnToCharPos(col, lineText, tabSize) { - var spaces, - addedChars = 0, - posInLineWithSpaces = 0, - tabPos = 0; - - // Check for tabs in the text part before `col` - while (lineText.indexOf("\t") > -1 && posInLineWithSpaces < col) { - // Calculate number of spaces to the next tab stop - tabPos = lineText.indexOf("\t"); - posInLineWithSpaces += tabPos; - spaces = tabSize - posInLineWithSpaces % tabSize; - posInLineWithSpaces += spaces; - - // The tab itself is 1 character, - // so when for eaxample the tab was 4 spaces, we added 4 - 1 = 3 characters - addedChars += spaces - 1; - - // Process rest of the line - lineText = lineText.substring(tabPos + 1); - } - return col - addedChars; - } - if (token) { // if this token is part of a function call, then the tokens lexical info // will be annotated with "call". @@ -465,16 +428,13 @@ define(function (require, exports, module) { line, e, found, - lineText, - charPos, - tabSize = this.editor._codeMirror.options.tabSize; + charPos; for (line = this.getCursor().line, e = Math.max(0, line - 9), found = false; line >= e; --line) { // Column is based on a line with spaces. // We have to convert it to a character position when tabs are used, otherwise our check will fail. - lineText = this.getLine(line); - charPos = columnToCharPos(col, lineText, tabSize); - if (lineText.charAt(charPos) === "(") { + charPos = this.editor.getCharIndexForColumn(line, col); + if (this.getLine(line).charAt(charPos) === "(") { found = true; break; }