<commit_before>import { createStore } from 'redux';

import prog from './prog';

const deconstruct = function(root) {
    if (root === null || root === undefined) {
        return null;
    }
    var nodes = [];
    var index = 0;
    var traverse = function (obj, parent = -1) {
        const id = index++;
        const result = { parent };

        Object.keys(obj).forEach(key => {
            const val = obj[key];

            if (val == null) {
                result[key] = val;
            } else if (typeof val === "object") {
                if (Array.isArray(val)) {
                    result[key] = val.map(item => traverse(item, id));
                } else {
                    result[key] = traverse(val, id);
                }
            } else if (typeof val === "function") {
                result[key] = "[function]";
            } else {
                result[key] = val;
            }
        });

        nodes[id] = result;
        return id;
    };

    traverse(root);
    return nodes;
};

const nodes = deconstruct(prog);

const defaultState = {
    nodes: nodes,
    selection: null,
};

const LEFT_KEY = 37;
const RIGHT_KEY = 39;

const getValue = function(node) {
    if (node.type === 'NumberLiteral') {
        return node.value;
    } else if (node.type === 'StringLiteral') {
        return `"${node.value}"`;
    } else if (node.type === 'Identifier') {
        return node.name;
    }
};

const reducer = function(state = defaultState, action) {
    const { selection, nodes } = state;

    switch(action.type) {
        case 'KEY':
            if (selection && selection.pos != null) {
                let pos = selection.pos;
                const node = state.nodes[selection.id];
                const value = getValue(node);

                if (action.keyCode === LEFT_KEY) {
                    pos = Math.max(0, pos - 1);
                } else if (action.keyCode === RIGHT_KEY) {
                    pos = Math.min(value.length, pos + 1);
                }

                return {
                    ...state,
                    selection: {
                        ...selection,
                        pos: pos,
                    },
                };
            }
            return state;
        case 'INSERT':
            if (selection && selection.id) {
                const node = state.nodes[selection.id];
                let pos = selection.pos;

                if (node.type === 'StringLiteral') {
                    if (pos > 0 && pos < node.value.length + 2) {
                        const left = node.value.substring(0, pos - 1);
                        const right = node.value.substring(pos - 1);
                        const value = left + action.char + right;
                        pos += 1;

                        return {
                            ...state,
                            nodes: {
                                ...nodes,
                                [selection.id]: {
                                    ...node,<commit_msg>allow movement between arguments that are literals in a CallExpression<commit_after>import { createStore } from 'redux';

import prog from './prog';

const deconstruct = function(root) {
    if (root === null || root === undefined) {
        return null;
    }
    var nodes = [];
    var index = 0;
    var traverse = function (obj, parent = -1) {
        const id = index++;
        const result = { parent };

        Object.keys(obj).forEach(key => {
            const val = obj[key];

            if (val == null) {
                result[key] = val;
            } else if (typeof val === "object") {
                if (Array.isArray(val)) {
                    result[key] = val.map(item => traverse(item, id));
                } else {
                    result[key] = traverse(val, id);
                }
            } else if (typeof val === "function") {
                result[key] = "[function]";
            } else {
                result[key] = val;
            }
        });

        nodes[id] = result;
        return id;
    };

    traverse(root);
    return nodes;
};

const nodes = deconstruct(prog);

const defaultState = {
    nodes: nodes,
    selection: null,
};

const LEFT_KEY = 37;
const RIGHT_KEY = 39;

const getValue = function(node) {
    if (node.type === 'NumberLiteral') {
        return node.value;
    } else if (node.type === 'StringLiteral') {
        return `"${node.value}"`;
    } else if (node.type === 'Identifier') {
        return node.name;
    }
};

const reducer = function(state = defaultState, action) {
    const { selection, nodes } = state;

    switch(action.type) {
        case 'KEY':
            if (selection && selection.pos != null) {
                let pos = selection.pos;
                let id = selection.id;

                const node = state.nodes[selection.id];
                const value = getValue(node);

                if (action.keyCode === LEFT_KEY) {
                    if (pos === 0) {
                        const parent = state.nodes[node.parent];
                        if (parent.type === 'CallExpression') {
                            let index = parent.arguments.indexOf(id);
                            if (index !== -1) {
                                index = Math.max(0, index - 1);
                                id = parent.arguments[index];
                                pos = getValue(nodes[id]).length;
                            }
                        }
                    } else {
                        pos = pos - 1;
                    }
                } else if (action.keyCode === RIGHT_KEY) {
                    if (pos === value.length) {
                        const parent = state.nodes[node.parent];
                        if (parent.type === 'CallExpression') {
                            let index = parent.arguments.indexOf(id);
                            if (index !== -1) {
                                index = Math.max(0, index + 1);
                                id = parent.arguments[index];
                                pos = 0;
                            }
                        }
                    } else {
                        pos = pos + 1;
                    }
                }

                return {
                    ...state,
                    selection: {
                        id,
                        pos,
                    },
                };
            }
            return state;
        case 'INSERT':
            if (selection && selection.id) {
                const node = state.nodes[selection.id];
                let pos = selection.pos;

                if (node.type === 'StringLiteral') {
                    if (pos > 0 && pos < node.value.length + 2) {
                        const left = node.value.substring(0, pos - 1);
                        const right = node.value.substring(pos - 1);
                        const value = left + action.char + right;
                        pos += 1;

                        return {
                            ...state,
                            nodes: {
                                ...nodes,
                                [selection.id]: {
                                    ...node,
{'fraction_non_alphanumeric': 0.11937835235868519, 'fraction_numerical': 0.005088708568284968, 'mean_word_length': 1.0211228460255697, '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': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2428212', 'n_tokens_mistral': 1905, 'n_tokens_neox': 1750, 'n_words': 458}