Paste has a huge "Language" selection dropdown, visible here:
The behavior of this field is:
- By default (with no specific forced value, labeled "Detect From Filename in Title" in the dropdown), we'll use the filename to guess the language. For example, a paste named example.php will highlight as PHP.
- With a value set, we'll force the content to highlight with that language.
This control's available values are powered by the pygments.dropdown-choices configuration option. There are several things about this that aren't so great:
- It doesn't show everything. A larger set of languages is supported through pygments, the set is just so gigantic that we opted to only list common options.
- Users keep trying to contribute new defaults upstream, which contradicts the point of having configuration and a limited set of options.
- Users also ask us to add options explicitly, presumably unable to find the configuration option. It isn't obvious that the option exists and the option isn't named something useful.
- Configuration is bad in general (see T8227).
At the time we wrote this (many years ago) we didn't have modern typeahead infrastructure, but we could now reasonably replace this with a typeahead. That should let us resolve pretty much all of these issues, and eventually get rid of the config option.
To do this:
- Create a new typeahead datasource -- this is a class which knows which options are possible, and turns them into selectable tokens. Previously, T10951 interacted with these too.
- Replace the <select /> control with a typeahead.
To develop a new typeahead datasource:
- Subclass PhabricatorTypeaheadDatasource and drop it in src/applications/paste/typeahead/ (new directory).
- You can follow ManiphestTaskStatusDatasource as an example, that's a similar datasource generating results from a hard-coded list of constants.
- For now, just use pygments.dropdown-choices as the underlying data for the typeahead. We can remove this later, but it probably isn't trivial.
- After adding your class, run arc liberate src/ in Phabricator to pick up the new class and add it to the classmap. You should see a change to src/__phutil_library_map.php and a new entry for your new class.
- You can now test the typeahead by navigating to /typeahead/class/, which will let you select options from it. Once it looks like it's working approximately correctly (e.g., similar to the ManiphestStatus datasource), you can put it into Paste.
To integrate it into the UI:
- Paste is a relatively well-modernized application which uses up-to-date code, including EditEngine. You'll only touch it briefly, but some later tasks will work with EditEngine more heavily.
- The field is defined in PhabricatorPasteEditEngine.
- You should be able to replace the SelectEditField with a DatasourceEditField, using setSingleValue() instead of setValue() to make it return single values instead of lists of tokens.
If that works, editing pastes should give you a typeahead instead of a <select /> dropdown, but otherwise work in a similar way to the current behavior.
The behavior of selecting no value (i.e., "detect automatically") may be worth testing explicitly. I suspect it will just work, but there may be some null-vs-empty-string issues or something like that.