I have often found myself to know a package name, but fail to remember the casing (some packages are easy, some not as consistent). It is not hard to make a guess and try to tab complete until something works, but I feel like it would be a nice quality of life to be able to just write it in whatever casing and get it completed.
In my head it feels like it should pretty much just be to do a comparison with all items lowercased when finding matches, so just replace all comparisons between partial strings and package names with lowercased versions. Or am I missing something that can go wrong here?
Had a quick look at the code here which seems to be for
pkg> add [tab] if I understand correctly, and it might just be to change the line
if startswith(regpkg.name, partial) to compare with both strings lowercased?
I tried to implement this by just adding
lowercase in the right place in the file of
stdlib/Pkg_xxx for the
xxx in the
stdlib/Pkg.version, but it didn’t make a difference. After recompiling it seems to work though (at least partially, got some strange cases also). Is there any way to not have to recompile all of julia while working on stdlibs?
I also saw something about using
Unicode.normalize(s, casefold=true) instead of
lowercase(s) in this stackoverflow answer, not sure if that applies here since packages does not often have unicode characters?
See Using the development version of Pkg.jl. Note that if you want to develop the Pkg REPL mode you need
using Pkg before
], since otherwise the wrong Pkg is loaded by the trigger key.
lowercase in two spots in Pkg.jl gives me most of what I wanted, though there was still the odd behaviour I mentioned.
The thing that happens is that when I for example write
pkg> add re[tab] it will change to
pkg> add R where the
e has disappeared.
This seems to come from LineEdit.jl in the REPL stdlib. Here the autocomplete looks for the common prefix to all possible completions and if a common prefix exists and it is not the same as the entered string it will replace the entered string. The common prefix for this case is
R since both
Re... as well as
RE... exists (e.g. Revise and REPL) so the
e is not common when case sensitive.
I tried a simple fix to avoid this (could probably be done better since
lowercase are now run multiple times, but to show the idea)
if !isempty(p) && p != partial && length(p) == length(common_prefix(lowercase.(completions)))
and it seems to work. It just checks if the common prefix with lowercased completions is the same length, if not we have the above problem.
This still wasn’t really what I would have optimally wanted though, since for example if there only existed
Repair as completions for
re, then it would not help with the
p even though that was a common letter. One could then instead use the common prefix from lowercase in the case where they return a common prefix of different length, but this might also be strange since it could make uppercase letters to lowercase even if all possible completions have uppercase and you wrote that (writing
Re in previous example would become
Continuing from that, if a user specifically writes a uppercase letter maybe that should take precedence. But that seems like a whole other mess I don’t want to touch.
If either the current version or the one with the lowercase common prefix check is interesting for others I think I prefer both of them to the current version. But since it will give some different results when writing with proper casing it will be possible that it returns different results for people who don’t want this, so maybe that could be problematic. I also realise that they might affect other things using the
complete_line function which I haven’t checked very well. I think it will be fine since other things that use it such as latex completions still have their own
complete_line functions that generate possible completions, so you won’t get a problem writing
\Gamm[tab] and it doesn’t know if it is
\Gamma you want as long as the
complete_line for latex completion only returns the uppercase possibility.
To test it out a bit I put the two affected methods in a package, if anyone want to try you simply need to add it and run using on it. It seems to work for a few cases I tried, but have not yet looked at the other problems I mentioned above so might cause some side effectes.
Have been running with this for a while now, and I find it nice and convenient.
Would this be interesting to add to base julia? It shouldn’t affect the language in any way, just change the behaviour of autocompleting package names in the REPL in a way I find more convenient, but not sure how general of an opinion that is.
If not, is there any nice way to create this as a package. Because right now it is just overriding internal stdlib methods which does not seem very nice. Though looking at OhMyREPL it seems like it also overwrites some julia methods, so maybe it is hard to get around that?