<commit_before>"use strict";

import * as vscode from "vscode";
import {Position, PositionOptions} from './position';

export enum MotionMode {
    Caret,
    Cursor,
}

export class Motion implements vscode.Disposable {
    /// Certain motions like j, k, and | record data about the desired column within the span.
    /// This value may or may not be a valid point within the line
    private _desiredColumn: number = 0;
    private _motionMode : MotionMode;
    private _position : Position;
    private _disposables = new Array<vscode.Disposable>();

    // Caret Styling
    private _caretDecoration = vscode.window.createTextEditorDecorationType(
    {
        dark: {
            // used for dark colored themes
            backgroundColor: 'rgba(224, 224, 224, 0.4)',
            borderColor: 'rgba(240, 240, 240, 0.8)'
        },
        light: {
            // used for light colored themes
            backgroundColor: 'rgba(32, 32, 32, 0.4)',
            borderColor: 'rgba(16, 16, 16, 0.8)'
        },
        borderStyle: 'solid',
        borderWidth: '1px'
    });

    public get position() : Position {
        return this._position;
    }

    public set position(val: Position) {
        this._position = val;
        this.redraw();
    }

    public constructor(mode: MotionMode) {
        // initialize to current position
        let currentPosition = vscode.window.activeTextEditor.selection.active;
        this._position = new Position(currentPosition.line, currentPosition.character, null);
        this._desiredColumn = this._position.character;

        if (mode !== null) {
            this.changeMode(mode);
        }

        this._disposables.push(vscode.window.onDidChangeTextEditorSelection(e => {
            // handle scenarios where mouse used to change current position
            let selection = e.selections[0];

            if (selection) {
                let line = selection.active.line;
                let char = selection.active.character;

                this.position = new Position(line, char, null);
                this._desiredColumn = this.position.character;
                this.changeMode(this._motionMode);
            }
        }));
    }

    public changeMode(mode : MotionMode) : Motion {
        this._motionMode = mode;
        this.redraw();
        return this;
    }

    public move(): Motion {
        return this.moveTo(null, null);
    }

    public moveTo(line: number, character: number) : Motion {
        if (line !== null && character !== null) {
            this._position = this._position.setLocation(line, character);
            this._desiredColumn = this._position.character;
        }

        if (!this.position.isValid()) {
            throw new RangeError(`Invalid position. Line=${line}, Character=${character}`);
        }

        let selection = new vscode.Selection(this.position, this.position);
        vscode.window.activeTextEditor.selection = selection;

        if (this._motionMode === MotionMode.Caret) {
            this.highlightBlock(this.position);
        }

        return this;
    }

    private redraw() : void {
        switch (this._motionMode) {
            case MotionMode.Caret:
                // Valid Positions for Caret: [0, eol)
                this._position.positionOptions = PositionOptions.CharacterWiseExclusive;

                if (this.position.character > this._position.getLineEnd().character) {
                    this._position = this._position.getLineEnd();
                    this._desiredColumn = this._position.character;
                }

                this.highlightBlock(this.position);
                break;

            case MotionMode.Cursor:
                // Valid Positions for Caret: [0, eol]
                this.position.positionOptions = PositionOptions.CharacterWiseInclusive;
                vscode.window.activeTextEditor.setDecorations(this._caretDecoration, []);
                break;
        }
    }

    /**
     * Allows us to simulate a block cursor by highlighting a 1 character
     * space at the provided position in a lighter color.
     */
    private highlightBlock(start: Position): void {
        this.highlightRange(start, new Position(start.line, start.character + 1, start.positionOptions));
    }

    /**
     * Highlights the range from start to end in the color of a block cursor.
     */
    private highlightRange(start: Position, end: Position): void {
        let range = new vscode.Range(start, end);
        vscode.window.activeTextEditor.revealRange(range, vscode.TextEditorRevealType.InCenterIfOutsideViewport);
        vscode.window.activeTextEditor.setDecorations(this._caretDecoration, [range]);
    }
<commit_msg>Fixes Incorrect Cursor Position after Transition into Normal Mode<commit_after>"use strict";

import * as vscode from "vscode";
import {Position, PositionOptions} from './position';

export enum MotionMode {
    Caret,
    Cursor,
}

export class Motion implements vscode.Disposable {
    /// Certain motions like j, k, and | record data about the desired column within the span.
    /// This value may or may not be a valid point within the line
    private _desiredColumn: number = 0;
    private _motionMode : MotionMode;
    private _position : Position;
    private _disposables = new Array<vscode.Disposable>();

    // Caret Styling
    private _caretDecoration = vscode.window.createTextEditorDecorationType(
    {
        dark: {
            // used for dark colored themes
            backgroundColor: 'rgba(224, 224, 224, 0.4)',
            borderColor: 'rgba(240, 240, 240, 0.8)'
        },
        light: {
            // used for light colored themes
            backgroundColor: 'rgba(32, 32, 32, 0.4)',
            borderColor: 'rgba(16, 16, 16, 0.8)'
        },
        borderStyle: 'solid',
        borderWidth: '1px'
    });

    public get position() : Position {
        return this._position;
    }

    public set position(val: Position) {
        this._position = val;
        this.redraw();
    }

    public constructor(mode: MotionMode) {
        // initialize to current position
        let currentPosition = vscode.window.activeTextEditor.selection.active;
        this._position = new Position(currentPosition.line, currentPosition.character, null);
        this._desiredColumn = this._position.character;

        if (mode !== null) {
            this.changeMode(mode);
        }

        this._disposables.push(vscode.window.onDidChangeTextEditorSelection(e => {
            // handle scenarios where mouse used to change current position
            let selection = e.selections[0];

            if (selection) {
                let line = selection.active.line;
                let char = selection.active.character;

                var newPosition = new Position(line, char, this._position.positionOptions);

                if (char > newPosition.getLineEnd().character) {
                   newPosition = new Position(newPosition.line, newPosition.getLineEnd().character, null);
                }

                this.position = newPosition;
                this._desiredColumn = this.position.character;
                this.changeMode(this._motionMode);
            }
        }));
    }

    public changeMode(mode : MotionMode) : Motion {
        this._motionMode = mode;
        this.redraw();
        return this;
    }

    public move(): Motion {
        return this.moveTo(null, null);
    }

    public moveTo(line: number, character: number) : Motion {
        if (line !== null && character !== null) {
            this._position = this._position.setLocation(line, character);
            this._desiredColumn = this._position.character;
        }

        if (!this.position.isValid()) {
            throw new RangeError(`Invalid position. Line=${line}, Character=${character}`);
        }

        let selection = new vscode.Selection(this.position, this.position);
        vscode.window.activeTextEditor.selection = selection;

        if (this._motionMode === MotionMode.Caret) {
            this.highlightBlock(this.position);
        }

        return this;
    }

    private redraw() : void {
        switch (this._motionMode) {
            case MotionMode.Caret:
                // Valid Positions for Caret: [0, eol)
                this._position.positionOptions = PositionOptions.CharacterWiseExclusive;

                this.highlightBlock(this.position);
                break;

            case MotionMode.Cursor:
                // Valid Positions for Caret: [0, eol]
                this.position.positionOptions = PositionOptions.CharacterWiseInclusive;
                vscode.window.activeTextEditor.setDecorations(this._caretDecoration, []);
                break;
        }
    }

    /**
     * Allows us to simulate a block cursor by highlighting a 1 character
     * space at the provided position in a lighter color.
     */
    private highlightBlock(start: Position): void {
        this.highlightRange(start, new Position(start.line, start.character + 1, start.positionOptions));
    }

    /**
     * Highlights the range from start to end in the color of a block cursor.
     */
    private highlightRange(start: Position, end: Position): void {
        let range = new vscode.Range(start, end);
        vscode.window.activeTextEditor.revealRange(range, vscode.TextEditorRevealType.InCenterIfOutsideViewport);
        vscode.window.activeTextEditor.setDecorations(this._caretDecoration, [range]);
    }

{'fraction_non_alphanumeric': 0.09990515333544103, 'fraction_numerical': 0.0094846664558963, 'mean_word_length': 2.1749749079959853, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4399894', 'n_tokens_mistral': 2665, 'n_tokens_neox': 2471, 'n_words': 644}