jacobslusser / ScintillaNET

A Windows Forms control, wrapper, and bindings for the Scintilla text editor.
MIT License
967 stars 245 forks source link

AutoComplete not working with capitals #167

Open seraphx2 opened 8 years ago

seraphx2 commented 8 years ago

I've noticed some oddities while trying to get the AutoComplete to show:

Scenario 1: lowercase string-set; lowercase typing; IgnoreCase: false - SUCCESS (Expected) Scenario 2: lowercase string-set; uppercase typing; IgnoreCase: false - FAIL (Expected) Scenario 3: lowercase string-set; any typing; IgnoreCase: true - FAIL (Unexpected) Scenario 4: uppercase string-set: uppercase typing: IgnoreCase: false - FAIL (Unexpected) Scenario 5: uppercase string-set: uppercase typing: IgnoreCase: true - FAIL (Unexpected)

/* Keywords */
private const string keywords = "abort alter authorization begin by call case checkpoint collect comment commit constraint create delete drop dump echo end execute explain from function give glop grant group hash help index initiate inner insert join left locking macro merge method modify new order ordering outer partition primary procedure profile qualify rename replace replication restart revoke role rollback select set show transaction transform trigger type union update user using where";
/* "Sub" Keywords */
private const string keywords2 = "all and as between database distinct else in on or over table then view when analysis capture demographics dml flush logging logon query ruleset session statistics";
/* Functions */
private const string functions = "abs add_months acos acosh ascii asin asinh atan atanh atan2 average begin bytes cast case_n char_length char2hexint characters chr coalesce contains cos cosh count corr covar_pop covar_samp csum current_date decode editdistance empty_blob empty_clob end exp extract floor format from_bytes greatest index initcap instr interval hashamp hashbakamp hashbucket hashrow kurtosis length ln log lower last last_day least lpad ltrim mavg max maximum mcharacters mdiff meets mindex minimum mlinreg months_between msubstr msum named next next_day ngram nullifzero numtodsinterval numtoyminterval nvl nvl2 nvp oadd_months octet_length oreplace otranslate p_intersect p_normalize percent_rank position power precedes prior quantile random range_n rank rdiff regexp_instr regexp_replace regexp_similar regexp_substr regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy regr_syy round row_number rpad rtrim sign sin sinh skew soundex sqrt stddev_pop stddev_samp strtok substr substring succeeds sum tan tanh title to_bytes to_char to_date to_dsinterval to_number to_timestamp to_timestamp_tz to_yminterval truncate translate translate_chk trim trunc type upper var_pop var_samp width_bucket xmlagg xmlcomment xmlconcat xmldocument xmlelement xmlforest xmlparse xmlpi xmlquery xmlserialize xmltable xmltext xmlvalidate";
/* Data Types */
private const string datatypes = "bigint byte byteint char clob date decimal double graphic integer long number period smallint time timestamp varbyte varchar vargraphic";
/* Special NULL value styling */
private const string sp_null = "null";
/* Special NULL Operator styling */
private const string sp_operator = "is not";

/// <summary>
/// 
/// </summary>
/// <returns></returns>
private static List<string> BuildAutoShowList()
{
    List<string> list = new List<string>();

    list.AddRange(keywords.Split(' '));
    list.AddRange(keywords2.Split(' '));
    list.AddRange(functions.Split(' '));
    list.AddRange(datatypes.Split(' '));

    return list.OrderBy(m => m).ToList();
}

/// <summary>
/// 
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
static void scintilla_CharAdded(object sender, CharAddedEventArgs e)
{
    Scintilla scintilla = (Scintilla)sender;

    // Find the word start
    var currentPos = scintilla.CurrentPosition;
    var wordStartPos = scintilla.WordStartPosition(currentPos, true);
    var lenEntered = currentPos - wordStartPos;

    // Display the autocompletion list
    List<string> autoShowList = BuildAutoShowList();

    if (lenEntered > 2)
        scintilla.AutoCShow(lenEntered, string.Join(" ", autoShowList.ToArray()));

    // Capitalize known keywords automatically
    scintilla.TargetStart = wordStartPos;
    scintilla.TargetEnd = currentPos;
    if (autoShowList.Contains(scintilla.TargetText))
    {
        scintilla.ReplaceTarget(scintilla.TargetText.ToUpper());
        scintilla.AnchorPosition = scintilla.WordEndPosition(currentPos, true);
        scintilla.CurrentPosition = scintilla.WordEndPosition(currentPos, true);
    }

    // AutoIndent of New Lines
    if (e.Char == 125)
    {
        int curLine = scintilla.LineFromPosition(scintilla.CurrentPosition);

        if (scintilla.Lines[curLine].Text.Trim() == "}")
            SetIndent(scintilla, curLine, GetIndent(scintilla, curLine) - 4);
    }
}
jacobslusser commented 8 years ago

I'm trying to follow, but having a hard time understanding. Can you simplify your explanation of the issue?

seraphx2 commented 8 years ago

Basically, if you provide a certain upper or lowercase set of keywords, type in upper or lowercase, and set scintilla.IgnoreCase equal to true or false, in most combinations of those three things, the AC popup won't actually popup. Only the ones marked success do I actually get the popup to work.

Joostul commented 8 years ago

I have encountered this issue too. Some words wouldn't induce a popup for auto completion. It looked like the popup did show, but then immediately got removed again.

After further investigation it seemed that if there is a list with capitalized and non-capitalized words not sorted by capitalization, some words cannot be found. For example in "String string Take" nothing can be found if you press t. While with "String string take" if you press t take is selected. To fix the issue further testing may be required.

We solved it in our application by sorting the list ordinarily before this code fragment is executed:

if (lenEntered > 2)
        scintilla.AutoCShow(lenEntered, string.Join(" ", autoShowList.ToArray()));