<commit_before>/*
 * COMPLETION HANDLING
 *
 * also responsible for command history, url history and bookmark handling
 */

// array of all our bookmarks
var g_bookmarks = [];
var bookmarks_loaded = false;

// array of all our history items
var g_history = [];
var history_loaded = false;

// variables for the tab completion and command history:
// -1: filled, but no selection made
// >= 0: index of current item in the g_completions array
const COMPLETION_UNINITIALIZED = -2; // if we need to build the completion array first
const COMPLETION_MAXITEMS = 10;
const COMPLETION_CONTEXTLINES = 3;
const COMMAND_LINE_HISTORY_SIZE = 500;

// 2 dimensional: 1st element: what to complete
//                2nd element: help description
var g_completions = new Array(); 

var comp_tab_index = COMPLETION_UNINITIALIZED;  // the index in the internal g_completions array
var comp_tab_list_offset = 0; // how many items is the displayed list shifted from the internal tab index
var comp_tab_startstring = ""; 
var comp_history = new Array();
var comp_history_index = -1;



/* uses the entries in g_completions to fill the listbox
 * starts at index 'startindex', and shows COMPLETION_MAXITEMS
 * returns the number of items */
function completion_fill_list(startindex)/*{{{*/
{
    // remove all old items first
    var items = completion_list.getElementsByTagName("listitem");
    while (items.length > 0) { completion_list.removeChild(items[0]);}

    // find start index
    //var i = index - 3; // 3 lines of context
    if (startindex + COMPLETION_MAXITEMS > g_completions.length)
        startindex = g_completions.length - COMPLETION_MAXITEMS;
    if (startindex < 0)
        startindex = 0;

    for(i=startindex; i<g_completions.length && i < startindex + COMPLETION_MAXITEMS; i++)
    {
        completion_add_to_list(g_completions[i], false);
    }
    //completion_list.hidden = true;
//  completion_list.setAttribute("rows", (i-startindex).toString());
//  showStatusbarMessage ( (i-startindex).toString(), 1);
//  if ( i-startindex > 0) // XXX: respect completetopt setting
//      completion_list.hidden = false;
//  else
//      completion_list.hidden = true;
//  completion_list.setAttribute("rows", (i-startindex).toString());

    return (i-startindex);
}/*}}}*/

function completion_show_list()/*{{{*/
{
    var items = g_completions.length;
    if (items > COMPLETION_MAXITEMS)
        items = COMPLETION_MAXITEMS;
    if (items > 1) // FIXME
    {
        completion_list.setAttribute("rows", items.toString());
        completion_list.hidden = false;
    }
    else
        completion_list.hidden = true;
}/*}}}*/

/* add a single completion item to the list */
function completion_add_to_list(completion_item, at_beginning)/*{{{*/
{
        var item  = document.createElement("listitem");
        var cell1 = document.createElement("listcell");
        var cell2 = document.createElement("listcell");

        cell1.setAttribute("label", completion_item[0]);
        cell1.setAttribute("width", "200");
        cell2.setAttribute("label", completion_item[1]);
        cell2.setAttribute("style", "color:green; font-family: sans");

        item.appendChild(cell1);
        item.appendChild(cell2);
        if (at_beginning == true)
        {
            var items = completion_list.getElementsByTagName("listitem");
            if (items.length > 0)
                completion_list.insertBefore(item, items[0]);
            else
                completion_list.appendChild(item);
        }
        else
            completion_list.appendChild(item);
}/*}}}*/

/* select the next index, refill list if necessary
 *
 * changes 'comp_tab_index' */
function completion_select_next_item()/*{{{*/
{
    comp_tab_index++;
    if (comp_tab_index >= g_completions.length) /* wrap around */
    {
        comp_tab_index = -1;
        completion_list.selectedIndex = -1;
        return;
    }

    if (comp_tab_index == 0) // at the top of the list
    {
        completion_fill_list(0);
        comp_tab_list_offset = 0;
    }

    var listindex = comp_tab_index - comp_tab_list_offset;
    // only move the list, if there are still items we can move
    if (listindex >= COMPLETION_MAXITEMS - COMPLETION_CONTEXTLINES &&
        comp_tab_list_offset < g_completions.length - COMPLETION_MAXITEMS)
    {
        // for speed reason: just remove old item, and add new at the end of the list
        var items = completion_list.getElementsByTagName("listitem");
        completion_list.removeChild(items[0]);
        completion_add_to_list(g_completions[comp_tab_index + COMPLETION_CONTEXTLINES], false);
        comp_tab_list_offset++;
    }

    listindex = comp_tab_index - comp_tab_list_offset;
    completion_list.selectedIndex = listindex;

    showStatusbarMessage(" match " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString() + " ", STATUSFIELD_PROGRESS);
}/*}}}*/

/* select the previous index, refill list if necessary
 *
 * changes 'comp_tab_index' */
function completion_select_previous_item()/*{{{*/
{
    comp_tab_index--;
    if (comp_tab_index == -1)
    {
        completion_list.selectedIndex = -1;
        return;
    }

    if (comp_tab_index < -1) // go to the end of the list
    {
        comp_tab_index = g_completions.length -1;
        completion_fill_list(g_completions.length - COMPLETION_MAXITEMS);
        comp_tab_list_offset = g_completions.length - COMPLETION_MAXITEMS;//COMPLETION_MAXITEMS - 1;
        if (comp_tab_list_offset < 0)
            comp_tab_list_offset = 0;
    }

    var listindex = comp_tab_index - comp_tab_list_offset;
    // only move the list, if there are still items we can move
    if (listindex < COMPLETION_CONTEXTLINES && comp_tab_list_offset > 0)
    {
        // for speed reason: just remove old item, and add new at the end of the list
        var items = completion_list.getElementsByTagName("listitem");
        completion_list.removeChild(items[items.length-1]);
        completion_add_to_list(g_completions[comp_tab_index - COMPLETION_CONTEXTLINES], true);
        comp_tab_list_offset--;
    }

    listindex = comp_tab_index - comp_tab_list_offset;
    completion_list.selectedIndex = listindex;

    showStatusbarMessage("item " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString(), STATUSFIELD_PROGRESS);
}/*}}}*/


function get_file_completions(filter)/*{{{*/
{
    g_completions = [];

    var match = filter.match(/^(.*[\/\\])(.*?)$/);
    var dir;
    if (!match || !(dir = match[1])) return [];
    var compl = match[2] || '';
    var fd = fopen(dir, "<");
    if (!fd) return [];
    var entries = fd.read();
    var delim = (fd.path.search(/\\/) != -1) ? "\\" : "/";
    var reg = new RegExp("^" + fd.path + delim + compl);
    entries.forEach(function(file) {
        if (file.path.search(reg) != -1)
            g_completions.push([file.path]);
    });

    return g_completions;
}/*}}}*/


/* 
 * filter a list of urls
 *
 * may consist of searchengines, boorkmarks and history,
 * depending on the 'complete' option
 */
function get_url_completions(filter)/*{{{*/
{
    g_completions = [];

    var cpt = get_pref("complete");
    // join all completion arrays together
    for (var i = 0; i < cpt.length; i++)
    {<commit_msg>file completion now works for the path '/' also<commit_after>/*
 * COMPLETION HANDLING
 *
 * also responsible for command history, url history and bookmark handling
 */

// array of all our bookmarks
var g_bookmarks = [];
var bookmarks_loaded = false;

// array of all our history items
var g_history = [];
var history_loaded = false;

// variables for the tab completion and command history:
// -1: filled, but no selection made
// >= 0: index of current item in the g_completions array
const COMPLETION_UNINITIALIZED = -2; // if we need to build the completion array first
const COMPLETION_MAXITEMS = 10;
const COMPLETION_CONTEXTLINES = 3;
const COMMAND_LINE_HISTORY_SIZE = 500;

// 2 dimensional: 1st element: what to complete
//                2nd element: help description
var g_completions = new Array(); 

var comp_tab_index = COMPLETION_UNINITIALIZED;  // the index in the internal g_completions array
var comp_tab_list_offset = 0; // how many items is the displayed list shifted from the internal tab index
var comp_tab_startstring = ""; 
var comp_history = new Array();
var comp_history_index = -1;



/* uses the entries in g_completions to fill the listbox
 * starts at index 'startindex', and shows COMPLETION_MAXITEMS
 * returns the number of items */
function completion_fill_list(startindex)/*{{{*/
{
    // remove all old items first
    var items = completion_list.getElementsByTagName("listitem");
    while (items.length > 0) { completion_list.removeChild(items[0]);}

    // find start index
    //var i = index - 3; // 3 lines of context
    if (startindex + COMPLETION_MAXITEMS > g_completions.length)
        startindex = g_completions.length - COMPLETION_MAXITEMS;
    if (startindex < 0)
        startindex = 0;

    for(i=startindex; i<g_completions.length && i < startindex + COMPLETION_MAXITEMS; i++)
    {
        completion_add_to_list(g_completions[i], false);
    }
    //completion_list.hidden = true;
//  completion_list.setAttribute("rows", (i-startindex).toString());
//  showStatusbarMessage ( (i-startindex).toString(), 1);
//  if ( i-startindex > 0) // XXX: respect completetopt setting
//      completion_list.hidden = false;
//  else
//      completion_list.hidden = true;
//  completion_list.setAttribute("rows", (i-startindex).toString());

    return (i-startindex);
}/*}}}*/

function completion_show_list()/*{{{*/
{
    var items = g_completions.length;
    if (items > COMPLETION_MAXITEMS)
        items = COMPLETION_MAXITEMS;
    if (items > 1) // FIXME
    {
        completion_list.setAttribute("rows", items.toString());
        completion_list.hidden = false;
    }
    else
        completion_list.hidden = true;
}/*}}}*/

/* add a single completion item to the list */
function completion_add_to_list(completion_item, at_beginning)/*{{{*/
{
        var item  = document.createElement("listitem");
        var cell1 = document.createElement("listcell");
        var cell2 = document.createElement("listcell");

        cell1.setAttribute("label", completion_item[0]);
        cell1.setAttribute("width", "200");
        cell2.setAttribute("label", completion_item[1]);
        cell2.setAttribute("style", "color:green; font-family: sans");

        item.appendChild(cell1);
        item.appendChild(cell2);
        if (at_beginning == true)
        {
            var items = completion_list.getElementsByTagName("listitem");
            if (items.length > 0)
                completion_list.insertBefore(item, items[0]);
            else
                completion_list.appendChild(item);
        }
        else
            completion_list.appendChild(item);
}/*}}}*/

/* select the next index, refill list if necessary
 *
 * changes 'comp_tab_index' */
function completion_select_next_item()/*{{{*/
{
    comp_tab_index++;
    if (comp_tab_index >= g_completions.length) /* wrap around */
    {
        comp_tab_index = -1;
        completion_list.selectedIndex = -1;
        return;
    }

    if (comp_tab_index == 0) // at the top of the list
    {
        completion_fill_list(0);
        comp_tab_list_offset = 0;
    }

    var listindex = comp_tab_index - comp_tab_list_offset;
    // only move the list, if there are still items we can move
    if (listindex >= COMPLETION_MAXITEMS - COMPLETION_CONTEXTLINES &&
        comp_tab_list_offset < g_completions.length - COMPLETION_MAXITEMS)
    {
        // for speed reason: just remove old item, and add new at the end of the list
        var items = completion_list.getElementsByTagName("listitem");
        completion_list.removeChild(items[0]);
        completion_add_to_list(g_completions[comp_tab_index + COMPLETION_CONTEXTLINES], false);
        comp_tab_list_offset++;
    }

    listindex = comp_tab_index - comp_tab_list_offset;
    completion_list.selectedIndex = listindex;

    showStatusbarMessage(" match " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString() + " ", STATUSFIELD_PROGRESS);
}/*}}}*/

/* select the previous index, refill list if necessary
 *
 * changes 'comp_tab_index' */
function completion_select_previous_item()/*{{{*/
{
    comp_tab_index--;
    if (comp_tab_index == -1)
    {
        completion_list.selectedIndex = -1;
        return;
    }

    if (comp_tab_index < -1) // go to the end of the list
    {
        comp_tab_index = g_completions.length -1;
        completion_fill_list(g_completions.length - COMPLETION_MAXITEMS);
        comp_tab_list_offset = g_completions.length - COMPLETION_MAXITEMS;//COMPLETION_MAXITEMS - 1;
        if (comp_tab_list_offset < 0)
            comp_tab_list_offset = 0;
    }

    var listindex = comp_tab_index - comp_tab_list_offset;
    // only move the list, if there are still items we can move
    if (listindex < COMPLETION_CONTEXTLINES && comp_tab_list_offset > 0)
    {
        // for speed reason: just remove old item, and add new at the end of the list
        var items = completion_list.getElementsByTagName("listitem");
        completion_list.removeChild(items[items.length-1]);
        completion_add_to_list(g_completions[comp_tab_index - COMPLETION_CONTEXTLINES], true);
        comp_tab_list_offset--;
    }

    listindex = comp_tab_index - comp_tab_list_offset;
    completion_list.selectedIndex = listindex;

    showStatusbarMessage("item " + (comp_tab_index+1).toString() + " of " + g_completions.length.toString(), STATUSFIELD_PROGRESS);
}/*}}}*/


function get_file_completions(filter)/*{{{*/
{
    g_completions = [];

    var match = filter.match(/^(.*[\/\\])(.*?)$/);
    var dir;
    if (!match || !(dir = match[1])) return [];
    var compl = match[2] || '';
    var fd = fopen(dir, "<");
    if (!fd) return [];
    var entries = fd.read();
    var delim = fd.path.length == 1 ? '' : (fd.path.search(/\\/) != -1) ? "\\" : "/";
    var reg = new RegExp("^" + fd.path + delim + compl);
    entries.forEach(function(file) {
        if (file.path.search(reg) != -1)
            g_completions.push([file.path, '']);
    });

    return g_completions;
}/*}}}*/


/* 
 * filter a list of urls
 *
 * may consist of searchengines, boorkmarks and history,
 * depending on the 'complete' option
 */
function get_url_completions(filter)/*{{{*/
{
    g_completions = [];

    var cpt = get_pref("complete");
    // join all completion arrays together
    for (var i = 0; i < cpt.length; i++)
    {
{'fraction_non_alphanumeric': 0.12288280874991428, 'fraction_numerical': 0.008297332510457382, 'mean_word_length': 3.0657931419013105, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 23, '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': '6705290', 'n_tokens_mistral': 4639, 'n_tokens_neox': 4533, 'n_words': 1117}