<commit_before>/// <reference path="../../typings/ace/ace.d.ts" />
/// <reference path="fuse.d.ts" />

import * as React from "react";
import * as pkg from "./package";
import * as core from "./core";
import * as srceditor from "./srceditor"
import * as compiler from "./compiler"
import * as sui from "./sui";
import * as data from "./data";
import * as codecard from "./codecard";

declare let require: any;
const ace: AceAjax.Ace = require("brace");

const SK = ts.pxt.SymbolKind;

import Util = pxt.Util;
const lf = Util.lf

require('brace/mode/typescript');
require('brace/mode/javascript');
require('brace/mode/json');
require('brace/mode/c_cpp');
require('brace/mode/text');
require('brace/mode/xml');
require('brace/mode/markdown');
require('brace/mode/assembly_armthumb');

require('brace/theme/textmate');
require('brace/theme/tomorrow_night_bright');

require("brace/ext/language_tools");
require("brace/ext/keybinding_menu");
require("brace/ext/searchbox");



let acequire = (ace as any).acequire;
let Range = acequire("ace/range").Range;
let HashHandler = acequire("ace/keyboard/hash_handler").HashHandler;

export const cursorMarker = "\uE108"
let maxCompleteItems = 20;

export interface CompletionEntry {
    name: string;
    symbolInfo: ts.pxt.SymbolInfo;
    lastScore: number;
    searchName: string;
    searchDesc: string;
    desc: string;
    block?: string;
    snippet?: string;
    matches?: Util.Map<number[][]>;
}

export interface CompletionCache {
    apisInfo: ts.pxt.ApisInfo;
    completionInfo: ts.pxt.CompletionInfo;
    entries: CompletionEntry[];
    fuseEntries: Fuse;
    posTxt: string;
}

function fixupSearch(e: CompletionEntry) {
    e.searchName = (e.searchName || "").replace(/\s+/g, "").toLowerCase() + " ";
    e.searchDesc = " " + (e.searchDesc || "").toLowerCase().replace(/[^a-z0-9]+/g, " ") + " ";
    e.block = e.block ? e.block.replace(/\s/g, '').toLowerCase() : '';
    return e
}

function mkSyntheticEntry(name: string, desc: string) {
    return fixupSearch({
        name: name,
        symbolInfo: {
            attributes: {
                jsDoc: desc,
                paramDefl: {},
                callingConvention: ts.pxt.ir.CallingConvention.Plain
            },
            name: name,
            namespace: "",
            kind: SK.None,
            parameters: null,
            retType: "",
        },
        lastScore: 0,
        searchName: name,
        searchDesc: desc,
        desc: desc
    })
}

function mkSnippet(name: string, desc: string, code: string) {
    let e = mkSyntheticEntry(name, desc)
    e.snippet = code
    return e
}

let block = `{\n ${cursorMarker}\n}`
// TODO auto-rename of locals
let snippets = [
    mkSnippet("if", "Do something depending on condition", `if (${cursorMarker}) ${block}`),
    mkSnippet("if else", "Do something or something else depending on condition", `if (${cursorMarker}) ${block} else ${block}`),
    mkSnippet("else", "What to do if the condition is not satisfied", `else ${block}`),
    mkSnippet("else if", "Check the alternative condition", `else if (${cursorMarker}) ${block}`),
    mkSnippet("while", "Loop while condition is true", `while (true) {\n ${cursorMarker}\nbasic.pause(20)\n}`),
    mkSnippet("for", "Repeat a given number of times", `for (let i = 0; i < 5; i++) ${block}`),
    mkSnippet("function", "Define a new procedure", `function doSomething() ${block}`),
    mkSnippet("class", "Define a new object type", `class Thing ${block}`),
    mkSnippet("let", "Define a new variable", `let x = ${cursorMarker}`),
    // TODO proper text formatting for switch missing
    mkSnippet("switch", "Branch on a number or enum", `switch (${cursorMarker}) {\ncase 0:\nbreak\n}`),
    mkSnippet("true", "True boolean value", `true`),
    mkSnippet("false", "False boolean value", `false`),
    // for each not supported at the moment in the compiler
    //mkSnippet("for each", "Do something for all elements of an array", `for (let e of ${placeholderChar}) ${block}`),
]

export class AceCompleter extends data.Component<{ parent: Editor; }, {
    visible?: boolean;
    cache?: CompletionCache;
    selectedEntry?: string;
}> {
    queryingFor: string;
    firstTime = true;
    completionRange: AceAjax.Range;
    keyHandler: any;
    entries: CompletionEntry[] = [];<commit_msg>localize snippets<commit_after>/// <reference path="../../typings/ace/ace.d.ts" />
/// <reference path="fuse.d.ts" />

import * as React from "react";
import * as pkg from "./package";
import * as core from "./core";
import * as srceditor from "./srceditor"
import * as compiler from "./compiler"
import * as sui from "./sui";
import * as data from "./data";
import * as codecard from "./codecard";

declare let require: any;
const ace: AceAjax.Ace = require("brace");

const SK = ts.pxt.SymbolKind;

import Util = pxt.Util;
const lf = Util.lf

require('brace/mode/typescript');
require('brace/mode/javascript');
require('brace/mode/json');
require('brace/mode/c_cpp');
require('brace/mode/text');
require('brace/mode/xml');
require('brace/mode/markdown');
require('brace/mode/assembly_armthumb');

require('brace/theme/textmate');
require('brace/theme/tomorrow_night_bright');

require("brace/ext/language_tools");
require("brace/ext/keybinding_menu");
require("brace/ext/searchbox");



let acequire = (ace as any).acequire;
let Range = acequire("ace/range").Range;
let HashHandler = acequire("ace/keyboard/hash_handler").HashHandler;

export const cursorMarker = "\uE108"
let maxCompleteItems = 20;

export interface CompletionEntry {
    name: string;
    symbolInfo: ts.pxt.SymbolInfo;
    lastScore: number;
    searchName: string;
    searchDesc: string;
    desc: string;
    block?: string;
    snippet?: string;
    matches?: Util.Map<number[][]>;
}

export interface CompletionCache {
    apisInfo: ts.pxt.ApisInfo;
    completionInfo: ts.pxt.CompletionInfo;
    entries: CompletionEntry[];
    fuseEntries: Fuse;
    posTxt: string;
}

function fixupSearch(e: CompletionEntry) {
    e.searchName = (e.searchName || "").replace(/\s+/g, "").toLowerCase() + " ";
    e.searchDesc = " " + (e.searchDesc || "").toLowerCase().replace(/[^a-z0-9]+/g, " ") + " ";
    e.block = e.block ? e.block.replace(/\s/g, '').toLowerCase() : '';
    return e
}

function mkSyntheticEntry(name: string, desc: string) {
    return fixupSearch({
        name: name,
        symbolInfo: {
            attributes: {
                jsDoc: desc,
                paramDefl: {},
                callingConvention: ts.pxt.ir.CallingConvention.Plain
            },
            name: name,
            namespace: "",
            kind: SK.None,
            parameters: null,
            retType: "",
        },
        lastScore: 0,
        searchName: name,
        searchDesc: desc,
        desc: desc
    })
}

function mkSnippet(name: string, desc: string, code: string) {
    let e = mkSyntheticEntry(name, desc)
    e.snippet = code
    return e
}

let block = `{\n ${cursorMarker}\n}`
// TODO auto-rename of locals
let snippets = [
    mkSnippet("if", lf("Do something depending on condition"), `if (${cursorMarker}) ${block}`),
    mkSnippet("if else", lf("Do something or something else depending on condition"), `if (${cursorMarker}) ${block} else ${block}`),
    mkSnippet("else", lf("What to do if the condition is not satisfied"), `else ${block}`),
    mkSnippet("else if", lf("Check the alternative condition"), `else if (${cursorMarker}) ${block}`),
    mkSnippet("while", lf("Repeat while condition is true"), `while (true) {\n ${cursorMarker}\nbasic.pause(20)\n}`),
    mkSnippet("for", lf("Repeat a given number of times"), `for (let i = 0; i < 5; i++) ${block}`),
    mkSnippet("function", lf("Define a new function"), `function doSomething() ${block}`),
    mkSnippet("class", lf("Define a new object type"), `class Thing ${block}`),
    mkSnippet("let", lf("Define a new variable"), `let x = ${cursorMarker}`),
    mkSnippet("const", lf("Define a new constant variable"), `const x = ${cursorMarker}`),
    // TODO proper text formatting for switch missing
    mkSnippet("switch", lf("Branch on a number or enum"), `switch (${cursorMarker}) {\ncase 0:\nbreak\n}`),
    mkSnippet("true", lf("True boolean value"), `true`),
    mkSnippet("false", lf("False boolean value"), `false`),
    // for each not supported at the moment in the compiler
    //mkSnippet("for each", "Do something for all elements of an array", `for (let e of ${placeholderChar}) ${block}`),
]

export class AceCompleter extends data.Component<{ parent: Editor; }, {
    visible?: boolean;
    cache?: CompletionCache;
    selectedEntry?: string;
}> {
    queryingFor: string;
    firstTime = true;
    completionRange: AceAjax.Range;
    keyHandler: any;
    entries: CompletionEntry[] = [];
{'fraction_non_alphanumeric': 0.16526195899772209, 'fraction_numerical': 0.00296127562642369, 'mean_word_length': 3.507700205338809, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '1260213', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2739, 'n_words': 756}