extract marker generation method

This commit is contained in:
Maxfield Walker 2017-09-03 14:35:27 +09:00 committed by Horace He
parent 20ffa2fcb0
commit 4a308bc37f
3 changed files with 63 additions and 49 deletions

View File

@ -28,10 +28,11 @@ abstract class BaseEasyMotionCommand extends BaseCommand {
vimState.easyMotion.clearMarkers();
let index = 0;
const markerGenerator = EasyMotion.createMarkerGenerator(matches.length);
for (const match of matches) {
// Skip if the match position equals to cursor position
if (!match.position.isEqual(cursorPosition)) {
const marker = EasyMotion.generateMarker(index++, matches.length, match.position);
const marker = markerGenerator.generateMarker(index++, match.position);
if (marker) {
vimState.easyMotion.addMarker(marker);
}

View File

@ -3,6 +3,7 @@ import { Position } from './../../../common/motion/position';
import { Configuration } from './../../../configuration/configuration';
import { TextEditor } from './../../../textEditor';
import { EasyMotionSearchAction } from './easymotion.cmd';
import { MarkerGenerator } from './markerGenerator';
export class EasyMotion {
/**
@ -39,17 +40,6 @@ export class EasyMotion {
return this._markers;
}
/**
* The key sequence for marker name generation
*/
public static getKeyTable(): string[] {
if (Configuration.easymotionKeys) {
return Configuration.easymotionKeys.split('');
} else {
return 'hklyuiopnm,qwertzxcvbasdgjf;'.split('');
}
}
/**
* Mode to return to after attempting easymotion
*/
@ -61,40 +51,8 @@ export class EasyMotion {
this.decorations = [];
}
/**
* Generate a marker following a sequence for the name and depth levels
*/
public static generateMarker(
index: number,
matchesCount: number,
markerPosition: Position
): EasyMotion.Marker | null {
const keyTable = EasyMotion.getKeyTable();
const prefixKeyTable: string[] = [];
const totalRemainder = Math.max(matchesCount - keyTable.length, 0);
const totalSteps = Math.floor(totalRemainder / keyTable.length) + 1;
// Make prefix key table if needed
if (matchesCount >= keyTable.length) {
const reversed = keyTable.slice().reverse();
const count = Math.min(totalSteps, reversed.length);
prefixKeyTable.push(...reversed.slice(0, count));
}
if (index >= keyTable.length - prefixKeyTable.length) {
const remainder = index - (keyTable.length - prefixKeyTable.length);
const currentStep = Math.floor(remainder / keyTable.length) + 1;
if (currentStep > prefixKeyTable.length) {
return null;
} else {
const prefix = prefixKeyTable[currentStep - 1];
const label = keyTable[remainder % keyTable.length];
return new EasyMotion.Marker(prefix + label, markerPosition);
}
} else {
const label = keyTable[index];
return new EasyMotion.Marker(label, markerPosition);
}
public static createMarkerGenerator(matchesCount: number): MarkerGenerator {
return new MarkerGenerator(matchesCount);
}
/**
@ -163,9 +121,9 @@ export class EasyMotion {
} else {
const uri = vscode.Uri.parse(
`data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ` +
`${height}" height="${height}" width="${width}"><rect width="${width}" height="${height}" rx="2" ry="2" ` +
`style="fill: ${backgroundColor}"></rect><text font-family="${fontFamily}" font-size="${fontSize}" ` +
`font-weight="${fontWeight}" fill="${fontColor}" x="1" y="${Configuration.easymotionMarkerYOffset}">${code}</text></svg>`
`${height}" height="${height}" width="${width}"><rect width="${width}" height="${height}" rx="2" ry="2" ` +
`style="fill: ${backgroundColor}"></rect><text font-family="${fontFamily}" font-size="${fontSize}" ` +
`font-weight="${fontWeight}" fill="${fontColor}" x="1" y="${Configuration.easymotionMarkerYOffset}">${code}</text></svg>`
);
this.svgCache[code] = uri;

View File

@ -0,0 +1,55 @@
import { EasyMotion } from "./easymotion";
import { Position } from './../../../common/motion/position';
import { Configuration } from './../../../configuration/configuration';
export class MarkerGenerator {
private matchesCount: number;
private keyTable: string[];
private prefixKeyTable: string[];
constructor(matchesCount: number) {
this.matchesCount = matchesCount;
this.keyTable = this.getKeyTable();
this.prefixKeyTable = this.createPrefixKeyTable();
}
public generateMarker(index: number, markerPosition: Position): EasyMotion.Marker | null {
const keyTable = this.keyTable;
const prefixKeyTable = this.prefixKeyTable;
if (index >= keyTable.length - prefixKeyTable.length) {
const remainder = index - (keyTable.length - prefixKeyTable.length);
const currentStep = Math.floor(remainder / keyTable.length) + 1;
if (currentStep > prefixKeyTable.length) {
return null;
} else {
const prefix = prefixKeyTable[currentStep - 1];
const label = keyTable[remainder % keyTable.length];
return new EasyMotion.Marker(prefix + label, markerPosition);
}
} else {
const label = keyTable[index];
return new EasyMotion.Marker(label, markerPosition);
}
}
private createPrefixKeyTable(): string[] {
const keyTable = this.keyTable;
const totalRemainder = Math.max(this.matchesCount - keyTable.length, 0);
const totalSteps = Math.floor(totalRemainder / keyTable.length) + 1;
const reversed = this.keyTable.slice().reverse();
const count = Math.min(totalSteps, reversed.length);
return reversed.slice(0, count);
}
/**
* The key sequence for marker name generation
*/
private getKeyTable(): string[] {
if (Configuration.easymotionKeys) {
return Configuration.easymotionKeys.split('');
} else {
return 'hklyuiopnm,qwertzxcvbasdgjf;'.split('');
}
}
}