From 2b718b1c0b92b1d9693a982475ad7a0edbef3f84 Mon Sep 17 00:00:00 2001 From: Iwasaki Shuzo Date: Wed, 13 Mar 2019 21:54:15 +0900 Subject: [PATCH 1/3] update: add code character config, modify css, change range to current visible --- .gitignore | 2 +- .vscode/launch.json | 19 +++-- .vscode/tasks.json | 18 ++--- README.md | 4 + package.json | 10 +++ src/extension.ts | 170 +++++++++++++++++++++-------------------- src/jumpy-positions.ts | 11 +-- src/jumpy-vscode.ts | 98 ++++++++++++------------ 8 files changed, 178 insertions(+), 154 deletions(-) diff --git a/.gitignore b/.gitignore index 7e5e08c..2c9c7ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ out node_modules - +.DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json index 4938f32..0a21ddc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,16 +1,20 @@ // A launch configuration that compiles the extension and then opens it inside a new window { - "version": "0.1.0", + "version": "0.2.0", "configurations": [ { "name": "Launch Extension", "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}"], + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}" + ], "stopOnEntry": false, "sourceMaps": true, - "outDir": "${workspaceRoot}/out/src", + "outFiles": [ + "${workspaceRoot}/out/**/*.js" + ], "preLaunchTask": "npm" }, { @@ -18,10 +22,15 @@ "type": "extensionHost", "request": "launch", "runtimeExecutable": "${execPath}", - "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test"], + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}", + "--extensionTestsPath=${workspaceRoot}/out/test" + ], "stopOnEntry": false, "sourceMaps": true, - "outDir": "${workspaceRoot}/out/test", + "outFiles": [ + "${workspaceRoot}/out/**/*.js" + ], "preLaunchTask": "npm" } ] diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 337860a..411891c 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -5,26 +5,24 @@ // ${fileDirname}: the current opened file's dirname // ${fileExtname}: the current opened file's extension // ${cwd}: the current working directory of the spawned process - // A task runner that calls a custom npm script that compiles the extension. { - "version": "0.1.0", - + "version": "2.0.0", // we want to run npm "command": "npm", - // the command is a shell script "isShellCommand": true, - // show the output window only if unrecognized errors occur. "showOutput": "silent", - // we run the custom script "compile" as defined in package.json - "args": ["run", "compile", "--loglevel", "silent"], - + "args": [ + "run", + "compile", + "--loglevel", + "silent" + ], // The tsc compiler is started in watching mode - "isWatching": true, - + "isBackground": true, // use the standard tsc in watch mode problem matcher to find compile problems in the output. "problemMatcher": "$tsc-watch" } diff --git a/README.md b/README.md index 10e263f..ad70215 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ Jumpy settings can be configured by adding entries into your `settings.json` (Fi `"jumpy.lightThemeForeground"`: Text color of Jumpy decoration in light themes +`"jumpy.codeChars"`: Characters used to generate code + +`"jumpy.codeLength"`: Code length, need to greater than 1 + ## Support [Create an issue](https://github.com/wmaurer/vscode-jumpy/issues) diff --git a/package.json b/package.json index 03b70fd..9c754b5 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,16 @@ "type": "string", "default": "white", "description": "Text color of Jumpy decoration in light themes" + }, + "jumpy.codeChars": { + "type": "string", + "default": "abcdefghijklmnopqrstuvwxyz", + "description": "Characters used to generate code" + }, + "jumpy.codeLength": { + "type": "number", + "default": 2, + "description": "Code length, need to greater than 1" } } } diff --git a/src/extension.ts b/src/extension.ts index 8364630..288b785 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,9 +3,10 @@ import * as vscode from 'vscode'; import { Decoration, + createCharArray, createCodeArray, createDataUriCaches, - getCodeIndex, + getCodeIndices, getLines, createTextEditorDecorationType, createDecorationOptions, @@ -13,48 +14,61 @@ import { import { JumpyPosition, JumpyFn, jumpyWord, jumpyLine } from './jumpy-positions'; export function activate(context: vscode.ExtensionContext) { - const codeArray = createCodeArray(); - - // decorations, based on configuration - const editorConfig = vscode.workspace.getConfiguration('editor'); - const configuration = vscode.workspace.getConfiguration('jumpy'); - - let fontFamily = configuration.get('fontFamily'); - fontFamily = fontFamily || editorConfig.get('fontFamily'); - - let fontSize = configuration.get('fontSize'); - fontSize = fontSize || editorConfig.get('fontSize') - 1; - - const colors = { - darkBgColor: configuration.get('darkThemeBackground'), - darkFgColor: configuration.get('darkThemeForeground'), - lightBgColor: configuration.get('lightThemeBackground'), - lightFgColor: configuration.get('lightThemeForeground'), - }; - - const darkDecoration = { - bgColor: colors.darkBgColor, - fgColor: colors.darkFgColor, - fontFamily: fontFamily, - fontSize: fontSize, - }; - const lightDecoration = { - bgColor: colors.lightBgColor, - fgColor: colors.lightFgColor, - fontFamily: fontFamily, - fontSize: fontSize, - }; + // configrations + let fontFamily: string = ""; + let fontSize: number = 1; + let darkDecoration: Decoration = null; + let lightDecoration: Decoration = null; - createDataUriCaches(codeArray, darkDecoration, lightDecoration); + let codeChars: string = ""; + let codeLength: number = 1; - const decorationTypeOffset2 = createTextEditorDecorationType(darkDecoration); - const decorationTypeOffset1 = createTextEditorDecorationType(darkDecoration); + loadConfiguration(); - let positions: JumpyPosition[] = null; - let firstLineNumber = 0; + // property + let positions: JumpyPosition[] = []; let isJumpyMode: boolean = false; + let keysOfCode: string[] = []; + + let charArray: string[] = createCharArray(codeChars); + let codeArray: string[] = createCodeArray(charArray, codeLength); + const decorationType = createTextEditorDecorationType(); + + createDataUriCaches(codeArray, darkDecoration, lightDecoration); setJumpyMode(false); - let firstKeyOfCode: string = null; + + function loadConfiguration() { + const editorConfig = vscode.workspace.getConfiguration('editor'); + const configuration = vscode.workspace.getConfiguration('jumpy'); + + fontFamily = configuration.get('fontFamily'); + fontFamily = fontFamily || editorConfig.get('fontFamily'); + fontSize = configuration.get('fontSize'); + fontSize = fontSize || editorConfig.get('fontSize') - 1; + + const colors = { + darkBgColor: configuration.get('darkThemeBackground'), + darkFgColor: configuration.get('darkThemeForeground'), + lightBgColor: configuration.get('lightThemeBackground'), + lightFgColor: configuration.get('lightThemeForeground'), + }; + + darkDecoration = { + bgColor: colors.darkBgColor, + fgColor: colors.darkFgColor, + fontFamily: fontFamily, + fontSize: fontSize, + }; + lightDecoration = { + bgColor: colors.lightBgColor, + fgColor: colors.lightFgColor, + fontFamily: fontFamily, + fontSize: fontSize, + }; + + codeChars = configuration.get('codeChars'); + codeLength = Math.max(configuration.get('codeLength'), 1); + } function setJumpyMode(value: boolean) { isJumpyMode = value; @@ -67,48 +81,26 @@ export function activate(context: vscode.ExtensionContext) { const getLinesResult = getLines(editor); positions = jumpyFn(codeArray.length, getLinesResult.firstLineNumber, getLinesResult.lines, regexp); - const decorationsOffset2 = positions - .map( - (position, i) => - position.charOffset == 1 - ? null - : createDecorationOptions( - position.line, - position.character, - position.character + 2, - context, - codeArray[i], - ), - ) - .filter(x => !!x); - - const decorationsOffset1 = positions - .map( - (position, i) => - position.charOffset == 2 - ? null - : createDecorationOptions( - position.line, - position.character, - position.character + 2, - context, - codeArray[i], - ), - ) - .filter(x => !!x); - - editor.setDecorations(decorationTypeOffset2, decorationsOffset2); - editor.setDecorations(decorationTypeOffset1, decorationsOffset1); + const decorations = positions + .map((position, i) => + createDecorationOptions( + position.line, + position.character, + codeArray[i] + ) + ); + + editor.setDecorations(decorationType, decorations); setJumpyMode(true); - firstKeyOfCode = null; + keysOfCode = []; } function exitJumpyMode() { const editor = vscode.window.activeTextEditor; setJumpyMode(false); - editor.setDecorations(decorationTypeOffset2, []); - editor.setDecorations(decorationTypeOffset1, []); + + editor.setDecorations(decorationType, []); } const jumpyWordDisposable = vscode.commands.registerCommand('extension.jumpy-word', () => { @@ -136,22 +128,29 @@ export function activate(context: vscode.ExtensionContext) { const editor = vscode.window.activeTextEditor; const text: string = args.text; - if (text.search(/[a-z]/i) === -1) { + let regexp = new RegExp('[' + charArray.join("") + ']', 'i'); + if (text.search(regexp) === -1) { exitJumpyMode(); return; } - if (!firstKeyOfCode) { - firstKeyOfCode = text; + keysOfCode.push(text); + const indices: number[] = getCodeIndices(positions.length, codeArray, keysOfCode.join("").toLowerCase()); + + // invalid char + if (indices.length == 0) { + exitJumpyMode(); return; } - const code = firstKeyOfCode + text; - const position = positions[getCodeIndex(code.toLowerCase())]; + // not unique + if (indices.length != 1) { + return; + } - editor.setDecorations(decorationTypeOffset2, []); - editor.setDecorations(decorationTypeOffset1, []); + editor.setDecorations(decorationType, []); + const position = positions[indices[0]]; vscode.window.activeTextEditor.selection = new vscode.Selection( position.line, position.character, @@ -173,6 +172,15 @@ export function activate(context: vscode.ExtensionContext) { const didChangeActiveTextEditorDisposable = vscode.window.onDidChangeActiveTextEditor(event => exitJumpyMode()); context.subscriptions.push(didChangeActiveTextEditorDisposable); + + const didChangeConfigurationDisposable = vscode.workspace.onDidChangeConfiguration(event => { + loadConfiguration(); + + charArray = createCharArray(codeChars); + codeArray = createCodeArray(charArray, codeLength); + createDataUriCaches(codeArray, darkDecoration, lightDecoration); + }); + context.subscriptions.push(didChangeConfigurationDisposable); } -export function deactivate() {} +export function deactivate() { } diff --git a/src/jumpy-positions.ts b/src/jumpy-positions.ts index 0aa5ada..811f278 100644 --- a/src/jumpy-positions.ts +++ b/src/jumpy-positions.ts @@ -1,7 +1,6 @@ export interface JumpyPosition { line: number; character: number; - charOffset: number; } export interface JumpyFn { @@ -14,16 +13,14 @@ export function jumpyWord( lines: string[], regexp: RegExp, ): JumpyPosition[] { - let positionIndex = 0; const positions: JumpyPosition[] = []; - for (let i = 0; i < lines.length && positionIndex < maxDecorations; i++) { + for (let i = 0; i < lines.length && positions.length < maxDecorations; i++) { let lineText = lines[i]; let word: RegExpExecArray; - while (!!(word = regexp.exec(lineText)) && positionIndex < maxDecorations) { + while (!!(word = regexp.exec(lineText)) && positions.length < maxDecorations) { positions.push({ line: i + firstLineNumber, character: word.index, - charOffset: 2, }); } } @@ -36,14 +33,12 @@ export function jumpyLine( lines: string[], regexp: RegExp, ): JumpyPosition[] { - let positionIndex = 0; const positions: JumpyPosition[] = []; - for (let i = 0; i < lines.length && positionIndex < maxDecorations; i++) { + for (let i = 0; i < lines.length && positions.length < maxDecorations; i++) { if (!lines[i].match(regexp)) { positions.push({ line: i + firstLineNumber, character: 0, - charOffset: lines[i].length == 1 ? 1 : 2, }); } } diff --git a/src/jumpy-vscode.ts b/src/jumpy-vscode.ts index f912443..d2bb0d2 100644 --- a/src/jumpy-vscode.ts +++ b/src/jumpy-vscode.ts @@ -1,22 +1,31 @@ import * as vscode from 'vscode'; -const plusMinusLines = 60; -const numCharCodes = 26; - -export function createCodeArray(): string[] { - const codeArray = new Array(numCharCodes * numCharCodes); - let codeIndex = 0; - for (let i = 0; i < numCharCodes; i++) { - for (let j = 0; j < numCharCodes; j++) { - codeArray[codeIndex++] = String.fromCharCode(97 + i) + String.fromCharCode(97 + j); - } - } - return codeArray; -} - let darkDataUriCache: { [index: string]: vscode.Uri } = {}; let lightDataUriCache: { [index: string]: vscode.Uri } = {}; +export function createCharArray(chars: string): string[] { + return chars.split("").filter(function (x, i, self) { + return self.indexOf(x) === i; + }); +} + +export function createCodeArray(chars: string[], length: number): string[] { + let createArray = function (arr: string[], word: string, d: number) { + d -= 1; + chars.forEach(function (val: string) { + if (d <= 0) { + arr.push(word + val) + } + else { + createArray(arr, word + val, d); + } + }); + return arr; + }; + + return createArray([], '', length);; +}; + export interface Decoration { bgColor: string; fgColor: string; @@ -26,26 +35,30 @@ export interface Decoration { } export function createDataUriCaches(codeArray: string[], darkDecoration: Decoration, lightDecoration: Decoration) { + darkDataUriCache = {} + lightDataUriCache = {} codeArray.forEach(code => (darkDataUriCache[code] = getSvgDataUri(code, darkDecoration))); codeArray.forEach(code => (lightDataUriCache[code] = getSvgDataUri(code, lightDecoration))); } -export function getCodeIndex(code: string): number { - return (code.charCodeAt(0) - 97) * numCharCodes + code.charCodeAt(1) - 97; +export function getCodeIndices(positionCount: number, codeArray: string[], code: string): number[] { + let regexp = new RegExp('^' + code + '.*', 'i'); + return codeArray + .slice(0, positionCount) + .map((val, i) => (val.search(regexp) == -1) ? null : i) + .filter(x => x != null); } export function getLines(editor: vscode.TextEditor): { firstLineNumber: number; lines: string[] } { const document = editor.document; - const activePosition = editor.selection.active; + const range = editor.visibleRanges; - const startLine = activePosition.line < plusMinusLines ? 0 : activePosition.line - plusMinusLines; - const endLine = - document.lineCount - activePosition.line < plusMinusLines - ? document.lineCount - : activePosition.line + plusMinusLines; + // get current visible lines + const startLine = Math.max(range[0].start.line - 1, 0); + const endLine = Math.min(range[0].end.line + 1, document.lineCount - 1); const lines: string[] = []; - for (let i = startLine; i < endLine; i++) { + for (let i = startLine; i <= endLine; i++) { lines.push(document.lineAt(i).text); } @@ -55,36 +68,25 @@ export function getLines(editor: vscode.TextEditor): { firstLineNumber: number; }; } -export function createTextEditorDecorationType(dec: Decoration) { - const width = dec.fontSize + 6; - const left = -width + 2; - +export function createTextEditorDecorationType(): vscode.TextEditorDecorationType { return vscode.window.createTextEditorDecorationType({ - after: { - margin: `0 0 0 ${left}px`, - height: '${dec.fontSize}px', - width: `${width}px`, + before: { + margin: `0 0 0 0px; position: absolute` }, }); } -export function createDecorationOptions( - line: number, - startCharacter: number, - endCharacter: number, - context: vscode.ExtensionContext, - code: string, -): vscode.DecorationOptions { +export function createDecorationOptions(line: number, start: number, code: string): vscode.DecorationOptions { return { - range: new vscode.Range(line, startCharacter, line, endCharacter), + range: new vscode.Range(line, start, line, start + code.length), renderOptions: { dark: { - after: { + before: { contentIconPath: darkDataUriCache[code], }, }, light: { - after: { + before: { contentIconPath: lightDataUriCache[code], }, }, @@ -93,14 +95,12 @@ export function createDecorationOptions( } function getSvgDataUri(code: string, dec: Decoration) { - const width = dec.fontSize + 6; - - // prettier-ignore - let svg = ``; - // prettier-ignore - svg += ``; - // prettier-ignore - svg += ``; + const width = (dec.fontSize / 2.0) * code.length + 4; + const height = dec.fontSize + 2; + + let svg = ``; + svg += ``; + svg += ``; svg += code; svg += ``; From 34426952cfb963082b28f2f378653451f5f25a89 Mon Sep 17 00:00:00 2001 From: Iwasaki Shuzo Date: Thu, 14 Mar 2019 22:43:39 +0900 Subject: [PATCH 2/3] add: incremental code display --- src/extension.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/extension.ts b/src/extension.ts index 288b785..af55f34 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -145,6 +145,16 @@ export function activate(context: vscode.ExtensionContext) { // not unique if (indices.length != 1) { + const decorations = indices + .map((index, i) => + createDecorationOptions( + positions[index].line, + positions[index].character, + codeArray[index] + ) + ) + + editor.setDecorations(decorationType, decorations); return; } From 43d5c9cac23f9c78744179889ae12a366f00dc12 Mon Sep 17 00:00:00 2001 From: Iwasaki Shuzo Date: Fri, 15 Mar 2019 11:25:42 +0900 Subject: [PATCH 3/3] add: varianble code mode --- README.md | 7 ++++++- package.json | 13 +++++++++++-- src/extension.ts | 42 +++++++++++++++++++++++++++++++++--------- src/jumpy-positions.ts | 11 ++++++++--- src/jumpy-vscode.ts | 21 +++++++++++++++++++-- 5 files changed, 77 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ad70215..25e79ed 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,14 @@ Jumpy settings can be configured by adding entries into your `settings.json` (Fi `"jumpy.lightThemeForeground"`: Text color of Jumpy decoration in light themes +`"jumpy.codeCreatingMode"`: Mode of creating code lenght + +* Fixed: Always the same length. And you can set code length. +* Variable: According to the target number, code length is variable. + `"jumpy.codeChars"`: Characters used to generate code -`"jumpy.codeLength"`: Code length, need to greater than 1 +`"jumpy.fixedCodeLength"`: [Fixed mode only] Fixed code length, need to greater than 1 ## Support diff --git a/package.json b/package.json index 9c754b5..867c227 100644 --- a/package.json +++ b/package.json @@ -95,15 +95,24 @@ "default": "white", "description": "Text color of Jumpy decoration in light themes" }, + "jumpy.codeCreatingMode": { + "type": "string", + "default": "Fixed", + "description": "Mode of creating code length (Fixed or Variable)", + "enum": [ + "Fixed", + "Variable" + ] + }, "jumpy.codeChars": { "type": "string", "default": "abcdefghijklmnopqrstuvwxyz", "description": "Characters used to generate code" }, - "jumpy.codeLength": { + "jumpy.fixedCodeLength": { "type": "number", "default": 2, - "description": "Code length, need to greater than 1" + "description": "[Fixed mode only] Fixed code length, need to greater than 1" } } } diff --git a/src/extension.ts b/src/extension.ts index af55f34..63de680 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,7 +4,8 @@ import * as vscode from 'vscode'; import { Decoration, createCharArray, - createCodeArray, + createFixedCodeArray, + createVariableCodeArray, createDataUriCaches, getCodeIndices, getLines, @@ -14,14 +15,20 @@ import { import { JumpyPosition, JumpyFn, jumpyWord, jumpyLine } from './jumpy-positions'; export function activate(context: vscode.ExtensionContext) { + enum CodeType { + Fixed, + Variable + }; + // configrations let fontFamily: string = ""; let fontSize: number = 1; let darkDecoration: Decoration = null; let lightDecoration: Decoration = null; + let codeType: CodeType = CodeType.Fixed; let codeChars: string = ""; - let codeLength: number = 1; + let fixedCodeLength: number = 1; loadConfiguration(); @@ -30,13 +37,20 @@ export function activate(context: vscode.ExtensionContext) { let isJumpyMode: boolean = false; let keysOfCode: string[] = []; - let charArray: string[] = createCharArray(codeChars); - let codeArray: string[] = createCodeArray(charArray, codeLength); + let charArray: string[] = []; + let codeArray: string[] = []; const decorationType = createTextEditorDecorationType(); - createDataUriCaches(codeArray, darkDecoration, lightDecoration); + charArray = createCharArray(codeChars); + if (codeType == CodeType.Fixed) { + codeArray = createFixedCodeArray(charArray, fixedCodeLength); + createDataUriCaches(codeArray, darkDecoration, lightDecoration); + } + setJumpyMode(false); + console.log(fontFamily) + function loadConfiguration() { const editorConfig = vscode.workspace.getConfiguration('editor'); const configuration = vscode.workspace.getConfiguration('jumpy'); @@ -66,8 +80,9 @@ export function activate(context: vscode.ExtensionContext) { fontSize: fontSize, }; + codeType = CodeType[configuration.get('codeCreatingMode')]; codeChars = configuration.get('codeChars'); - codeLength = Math.max(configuration.get('codeLength'), 1); + fixedCodeLength = Math.max(configuration.get('fixedCodeLength'), 1); } function setJumpyMode(value: boolean) { @@ -79,7 +94,13 @@ export function activate(context: vscode.ExtensionContext) { const editor = vscode.window.activeTextEditor; const getLinesResult = getLines(editor); - positions = jumpyFn(codeArray.length, getLinesResult.firstLineNumber, getLinesResult.lines, regexp); + const maxDecorations = (codeType == CodeType.Fixed) ? codeArray.length : -1; + positions = jumpyFn(maxDecorations, getLinesResult.firstLineNumber, getLinesResult.lines, regexp); + + if (codeType == CodeType.Variable) { + codeArray = createVariableCodeArray(charArray, positions.length); + createDataUriCaches(codeArray, darkDecoration, lightDecoration); + } const decorations = positions .map((position, i) => @@ -89,6 +110,7 @@ export function activate(context: vscode.ExtensionContext) { codeArray[i] ) ); + console.log(decorations) editor.setDecorations(decorationType, decorations); @@ -187,8 +209,10 @@ export function activate(context: vscode.ExtensionContext) { loadConfiguration(); charArray = createCharArray(codeChars); - codeArray = createCodeArray(charArray, codeLength); - createDataUriCaches(codeArray, darkDecoration, lightDecoration); + if (codeType == CodeType.Fixed) { + codeArray = createFixedCodeArray(charArray, fixedCodeLength); + createDataUriCaches(codeArray, darkDecoration, lightDecoration); + } }); context.subscriptions.push(didChangeConfigurationDisposable); } diff --git a/src/jumpy-positions.ts b/src/jumpy-positions.ts index 811f278..33dcefe 100644 --- a/src/jumpy-positions.ts +++ b/src/jumpy-positions.ts @@ -14,10 +14,10 @@ export function jumpyWord( regexp: RegExp, ): JumpyPosition[] { const positions: JumpyPosition[] = []; - for (let i = 0; i < lines.length && positions.length < maxDecorations; i++) { + for (let i = 0; i < lines.length && isValidIndex(positions.length, maxDecorations); i++) { let lineText = lines[i]; let word: RegExpExecArray; - while (!!(word = regexp.exec(lineText)) && positions.length < maxDecorations) { + while (!!(word = regexp.exec(lineText)) && isValidIndex(positions.length, maxDecorations)) { positions.push({ line: i + firstLineNumber, character: word.index, @@ -34,7 +34,7 @@ export function jumpyLine( regexp: RegExp, ): JumpyPosition[] { const positions: JumpyPosition[] = []; - for (let i = 0; i < lines.length && positions.length < maxDecorations; i++) { + for (let i = 0; i < lines.length && isValidIndex(positions.length, maxDecorations); i++) { if (!lines[i].match(regexp)) { positions.push({ line: i + firstLineNumber, @@ -44,3 +44,8 @@ export function jumpyLine( } return positions; } + +function isValidIndex(index: number, max: number): boolean { + if (max < 0) return true; + return (index < max); +}; diff --git a/src/jumpy-vscode.ts b/src/jumpy-vscode.ts index d2bb0d2..91c859e 100644 --- a/src/jumpy-vscode.ts +++ b/src/jumpy-vscode.ts @@ -9,7 +9,7 @@ export function createCharArray(chars: string): string[] { }); } -export function createCodeArray(chars: string[], length: number): string[] { +export function createFixedCodeArray(chars: string[], length: number): string[] { let createArray = function (arr: string[], word: string, d: number) { d -= 1; chars.forEach(function (val: string) { @@ -26,6 +26,21 @@ export function createCodeArray(chars: string[], length: number): string[] { return createArray([], '', length);; }; +// Returns a list of hint strings which will uniquely identify the given number of links.The hint strings may be of different lengths. +// https://github.com/philc/vimium +export function createVariableCodeArray(chars: string[], count: number): string[] { + let hints = [""]; + let offset = 0; + while ((hints.length - offset < count) || (hints.length == 1)) { + let hint = hints[offset++]; + chars.forEach(function (val: string) { + hints.push(hint + val); + }); + } + + return hints.slice(offset, offset + count); +} + export interface Decoration { bgColor: string; fgColor: string; @@ -71,7 +86,9 @@ export function getLines(editor: vscode.TextEditor): { firstLineNumber: number; export function createTextEditorDecorationType(): vscode.TextEditorDecorationType { return vscode.window.createTextEditorDecorationType({ before: { - margin: `0 0 0 0px; position: absolute` + // this is very tricky... + margin: `0 0 0 0px; position: relative; z-index: 99`, + width: `0px` }, }); }