From f96daca32c17c91d1b3cfabfe9f4580fb6e352a3 Mon Sep 17 00:00:00 2001 From: Trident Pancake Date: Sat, 7 Jan 2023 13:08:18 -0800 Subject: [PATCH] typeahead: Handle non-pygments data in compare_language_by_popularity. This added functionality will be used to compare pygment_language from Code Playgrounds. There is a choice of how to sort languages with popularity versus without popularity. I chose to sort the Code Playground custom language after other pygment languages based on the reasoning in the comments. --- web/src/typeahead_helper.js | 45 +++++++++++++++++++++++++++++- web/tests/typeahead_helper.test.js | 10 +++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/web/src/typeahead_helper.js b/web/src/typeahead_helper.js index 33a519ac3e..d9036e5458 100644 --- a/web/src/typeahead_helper.js +++ b/web/src/typeahead_helper.js @@ -260,7 +260,50 @@ export function sort_people_for_relevance(objs, current_stream_name, current_top } function compare_language_by_popularity(lang_a, lang_b) { - return pygments_data.langs[lang_b].priority - pygments_data.langs[lang_a].priority; + const lang_a_data = pygments_data.langs[lang_a]; + const lang_b_data = pygments_data.langs[lang_b]; + + // If a "language" doesn't have a popularity score, that "language" is + // probably a custom language created in the Code Playground feature. That + // custom language might not even be an actual programming language. Some + // users simply use the Code Playground feature as a shortcut mechanism. + // Like the report in issue #23935 is suggesting. Also, because Code + // Playground doesn't actually allow custom syntax highlighting, any custom + // languages are probably more likely to be attempts to create a shortcut + // mechanism. In that case, they're more like custom keywords rather than + // languages. + // + // We need to make a choice for the ordering of those custom languages when + // compared with languages available in pygment. It might come down to + // individual usage which one is more valuable. + // + // If most of the time a user uses code block for syntax highlighting, then + // sorting custom language later on makes sense. If most of the time a user + // uses a code block as a shortcut mechanism, then they might want custom + // language earlier on. + // + // At this time, we chose to sort custom languages after pygment languages + // due to the following reasons: + // - Code blocks are originally used to display code with syntax + // highlighting. Users can add Code Playground custom language, without + // having the autocomplete ordering they're used to being affected. + // - Users can design their custom language name to be more unique or using + // characters such that they appear faster in autocomplete. Therefore, + // they have a way to purposely affect the system to suit their + // autocomplete ordering preference. + // + // If in the future we find that many users have a need for a configurable + // setting, then we could create one. But for now, sorting after pygment + // languages seem sensible. + if (!lang_a_data && !lang_b_data) { + return 0; // Neither have popularity, so they tie. + } else if (!lang_a_data) { + return 1; // lang_a doesn't have popularity, so sort a after b. + } else if (!lang_b_data) { + return -1; // lang_b doesn't have popularity, so sort a before b. + } + + return lang_b_data.priority - lang_a_data.priority; } // This function compares two languages first by their popularity, then if diff --git a/web/tests/typeahead_helper.test.js b/web/tests/typeahead_helper.test.js index 3f217c4618..a4fc17116a 100644 --- a/web/tests/typeahead_helper.test.js +++ b/web/tests/typeahead_helper.test.js @@ -825,4 +825,14 @@ test("compare_language", () => { // "abap" and "amdgpu" both have priority = 0 at this time, so there is a tie. // Alphabetical order should be used to break that tie. assert.equal(th.compare_language("abap", "amdgpu"), util.strcmp("abap", "amdgpu")); + + // Test with languages that aren't in the generated pygments data. + assert.equal(actual_pygments_data.langs.custom_a, undefined); + assert.equal(actual_pygments_data.langs.custom_b, undefined); + // Since custom_a has no popularity score, it gets sorted behind python. + assert.equal(th.compare_language("custom_a", "python"), 1); + assert.equal(th.compare_language("python", "custom_a"), -1); + // Whenever there is a tie, even in the case neither have a popularity + // score, then alphabetical order is used to break the tie. + assert.equal(th.compare_language("custom_a", "custom_b"), util.strcmp("custom_a", "custom_b")); });