<commit_before>import * as vscode from 'vscode';
import * as util from './util';
import * as opener from './opener';
import configManager from './config-manager';
import getSupportActions from './support-actions';
import { OpenerItemCategoryList, OpenerItemList, OpenerItemMapping, OpenerEntity, OpenerEntityInPosition } from './types';

/** 显示打开项列表 */
export async function showOpenerList(filters?: OpenerItemCategoryList) {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile(filters);

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);
        return;
    }

    const openerItemList = util.convertOpenerItemMappingToOpenerItemList(openerItemMapping);

    const picked = await showQuickPickForOpenerItemList(openerItemList, {
        placeHolder: 'Please pick an item to open',
    });

    // escaped away
    if (!picked) {
        return;
    }

    const target = picked.detail;

    if (opener.open(target) === false) {
        // remove item from open list
        util.removeOpenerItemFromOpenerItemMapping(target, openerItemMapping);
        configManager.saveOpenerItemMappingToFile(openerItemMapping);

        // show drop message
        vscode.window.showWarningMessage(`Unrecognized item: \`${target}\`, drop it anyway from config file!`);
    }
}

/** 管理打开项列表 */
export async function manageOpenerList() {
    const actions = getSupportActions();
    const result = configManager.hasOpenerItem();

    if (typeof result === 'string') {
        showLoadingFileErrorMessage(result);
        return;
    }

    if (result) {
        for (const action of actions) {
            if (['edit', 'remove'].indexOf(action.type) >= 0) {
                action.active = true;
            }
        }
    }

    const quickPickItems = actions.filter(({ active }) => active).map(({ label }) => label);
    const picked = await vscode.window.showQuickPick(quickPickItems);

    // escaped away
    if (!picked) {
        return;
    }

    const action = actions.find(({ label }) => label === picked);

    switch (action.type) {
    case 'add':
        addItemToOpenerList();
        break;

    case 'edit':
        editItemFromOpenerList();
        break;

    case 'remove':
        removeItemFromOpenerList();
        break;
    }
}

/** 打开配置文件 */
export function openConfigFile() {
    configManager.ensureConfigFileCreated();
    opener.openFile(configManager.configFilePath);
}

/** 添加打开配置项 */
export async function addItemToOpenerList(value = '', openerEntityToBeReplaced?: OpenerEntityInPosition) {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile();

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);
        return;
    }

    const placeHolder = 'Please enter a file, directory or url path, and separated it by `|` with an optional description';
    const input = await showInputBox({ value, placeHolder });

    // escaped away
    if (input === undefined) {
        return;
    }

    const openerEntity = util.parseOpenerEntityFromUserInput(input);

    // input is invalid
    if (!openerEntity) {
        vscode.window.setStatusBarMessage(placeHolder, 1500);
        addItemToOpenerList(input, openerEntityToBeReplaced);
        return;
    }

    const openerEntityInPosition = util.findOpenerEntityFromOpenerItemMapping(openerEntity, openerItemMapping);

    // attempt to add repeating item
    if (openerEntityInPosition) {
        vscode.window.setStatusBarMessage('Same item exists in open list, you can not add it again', 1500);
        addItemToOpenerList(input, openerEntityToBeReplaced);
        return;
    }

    if (openerEntityToBeReplaced) {
        if (openerEntityToBeReplaced.belongTo === openerEntity.belongTo) {
            const index = openerEntityToBeReplaced.index;
            util.replaceOpenerEntityInOpenerItemMapping(index, openerEntity, openerItemMapping);
        } else {
            util.removeOpenerEntityFromOpenerItemMapping(openerEntityToBeReplaced, openerItemMapping);
            util.addOpenerEntityToOpenerItemMapping(openerEntity, openerItemMapping);
        }

    } else {
        util.addOpenerEntityToOpenerItemMapping(openerEntity, openerItemMapping);
    }

    configManager.saveOpenerItemMappingToFile(openerItemMapping);
}

/** 编辑打开配置项 */
export async function editItemFromOpenerList() {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile();

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);<commit_msg>bugfix: attempt to add repeating item<commit_after>import * as vscode from 'vscode';
import * as util from './util';
import * as opener from './opener';
import configManager from './config-manager';
import getSupportActions from './support-actions';
import { OpenerItemCategoryList, OpenerItemList, OpenerItemMapping, OpenerEntity, OpenerEntityInPosition } from './types';

/** 显示打开项列表 */
export async function showOpenerList(filters?: OpenerItemCategoryList) {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile(filters);

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);
        return;
    }

    const openerItemList = util.convertOpenerItemMappingToOpenerItemList(openerItemMapping);

    const picked = await showQuickPickForOpenerItemList(openerItemList, {
        placeHolder: 'Please pick an item to open',
    });

    // escaped away
    if (!picked) {
        return;
    }

    const target = picked.detail;

    if (opener.open(target) === false) {
        // remove item from open list
        util.removeOpenerItemFromOpenerItemMapping(target, openerItemMapping);
        configManager.saveOpenerItemMappingToFile(openerItemMapping);

        // show drop message
        vscode.window.showWarningMessage(`Unrecognized item: \`${target}\`, drop it anyway from config file!`);
    }
}

/** 管理打开项列表 */
export async function manageOpenerList() {
    const actions = getSupportActions();
    const result = configManager.hasOpenerItem();

    if (typeof result === 'string') {
        showLoadingFileErrorMessage(result);
        return;
    }

    if (result) {
        for (const action of actions) {
            if (['edit', 'remove'].indexOf(action.type) >= 0) {
                action.active = true;
            }
        }
    }

    const quickPickItems = actions.filter(({ active }) => active).map(({ label }) => label);
    const picked = await vscode.window.showQuickPick(quickPickItems);

    // escaped away
    if (!picked) {
        return;
    }

    const action = actions.find(({ label }) => label === picked);

    switch (action.type) {
    case 'add':
        addItemToOpenerList();
        break;

    case 'edit':
        editItemFromOpenerList();
        break;

    case 'remove':
        removeItemFromOpenerList();
        break;
    }
}

/** 打开配置文件 */
export function openConfigFile() {
    configManager.ensureConfigFileCreated();
    opener.openFile(configManager.configFilePath);
}

/** 添加打开配置项 */
export async function addItemToOpenerList(value = '', openerEntityToBeReplaced?: OpenerEntityInPosition) {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile();

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);
        return;
    }

    const placeHolder = 'Please enter a file, directory or url path, and separated it by `|` with an optional description';
    const input = await showInputBox({ value, placeHolder });

    // escaped away
    if (input === undefined) {
        return;
    }

    const openerEntity = util.parseOpenerEntityFromUserInput(input);

    // input is invalid
    if (!openerEntity) {
        vscode.window.setStatusBarMessage(placeHolder, 1500);
        addItemToOpenerList(input, openerEntityToBeReplaced);
        return;
    }

    const openerEntityInPosition = util.findOpenerEntityFromOpenerItemMapping(openerEntity, openerItemMapping);

    // attempt to add repeating item
    if (openerEntityInPosition && (!openerEntityToBeReplaced || openerEntityInPosition.value[1] !== openerEntityToBeReplaced.value[1])) {
        vscode.window.setStatusBarMessage('Same item exists in open list, you can not add it again', 1500);
        addItemToOpenerList(input, openerEntityToBeReplaced);
        return;
    }

    if (openerEntityToBeReplaced) {
        if (openerEntityToBeReplaced.belongTo === openerEntity.belongTo) {
            const index = openerEntityToBeReplaced.index;
            util.replaceOpenerEntityInOpenerItemMapping(index, openerEntity, openerItemMapping);
        } else {
            util.removeOpenerEntityFromOpenerItemMapping(openerEntityToBeReplaced, openerItemMapping);
            util.addOpenerEntityToOpenerItemMapping(openerEntity, openerItemMapping);
        }

    } else {
        util.addOpenerEntityToOpenerItemMapping(openerEntity, openerItemMapping);
    }

    configManager.saveOpenerItemMappingToFile(openerItemMapping);
}

/** 编辑打开配置项 */
export async function editItemFromOpenerList() {
    const openerItemMapping = configManager.loadOpenerItemMappingFromFile();

    if (typeof openerItemMapping === 'string') {
        showLoadingFileErrorMessage(openerItemMapping);
{'fraction_non_alphanumeric': 0.10147562018819505, 'fraction_numerical': 0.00213857998289136, 'mean_word_length': 3.3705607476635513, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '2801598', 'n_tokens_mistral': 2733, 'n_tokens_neox': 2611, 'n_words': 571}