-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add case-insensitive autocomplete #928
Add case-insensitive autocomplete #928
Conversation
Note: This patch is only for readline, I should add a comment that says that. |
Current coverage is 54.45% (diff: 0.00%)@@ master #928 diff @@
==========================================
Files 430 430
Lines 224650 224706 +56
Methods 3431 3431
Messages 0 0
Branches 0 0
==========================================
- Hits 122383 122361 -22
- Misses 102267 102345 +78
Partials 0 0
|
@ChrisJefferson - thank you. If this is does not change the default behaviour, and may be useful in some situations, then let's have it.
you can of course edit github comments, so you may update the description of changes for the release notes.
First, define
Now, if you type
and this is what I expect. However, if you type |
Oo, that second one is interesting. I'm going to have to think about the best way to do a partial completion. There may not be a best thing to do, but I agree that changing the case is a bit weird. For example, if I had |
Sounds to me like it should only change the case of a prefix if the capitalization is the same across all matching names. Otherwise it should stay lowercase / not change the case. E.g.
|
ssiccha: That sounds reasonable. One more bad case, when a tab-completion produces a complete word, which can still be extended to a longer name. For example in gap we have If I type In general pressing when you have a finished GAP name will case-correct it. |
I think so too.
Maybe nothing, and then when the user press Tab second time, it displays both names. Perhaps with readline one could also implement scrolling across all available completions, and also "backwards" completion (e.g. type "classes" and see all names that end with this string) - don't know how practically useful this is though. A real life use case is also |
That sounds reasonable. Although I would like the following more:
Typing |
For my taste all the behaviours discussed here are more confusing than helpful. The mentioned problems/questions are the reason why I decided against a case-insensitive completion when I wrote the current function. (Nevertheless, as long as the user has a choice I have no objections to experimenting with alternative Completion functions.) |
@frankluebeck : I agree that this is quite painful. For the specific use case of blind GAP users however it is very useful, as screen readers often don't give the case of characters when they are reading out, so case-insensitive completion makes GAP much easier to use. |
e2b416c
to
b7aae2a
Compare
I believe this is now ready to be merged -- I am using it day-to-day. |
@@ -751,10 +751,108 @@ GAPInfo.CommandLineEditFunctions.Functions.(INT_CHAR(' ')) := | |||
GAPInfo.CommandLineEditFunctions.Functions.SpaceDeletePrompt; | |||
BindKeysToGAPHandler(" "); | |||
|
|||
|
|||
BindGlobal("STANDARD_EXTENDERS", rec( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name tells me nothing about the purpose of this record. Coud you add a comment before it that briefly states what is is used for?
@@ -751,10 +751,108 @@ GAPInfo.CommandLineEditFunctions.Functions.(INT_CHAR(' ')) := | |||
GAPInfo.CommandLineEditFunctions.Functions.SpaceDeletePrompt; | |||
BindKeysToGAPHandler(" "); | |||
|
|||
|
|||
BindGlobal("STANDARD_EXTENDERS", rec( | |||
caseSensitive := function(cand, word) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is cand, what is word, what is this function supposed to do? Again, I can of course reverse engineer it, by grepping for places this is used, but a brief comment would help a lot. Since there seem to be multiple such functions in this record, this could also be explained once in a comment before STANDARD_EXTENDERS
c := cand[1][i+1]; | ||
for j in [2..Length(cand)] do | ||
if Length(cand[j]) > i and cand[j][i+1] = c then | ||
j := j+1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code confuses me. You increment j
, but that's the loop variable, this has basically no effect, except perhaps for the last iteration, when j=Length(cand)
, yes? So, while I think I see why you are doing this, that seems like an needlessly "clever" way to do this loop, which obscures what goes on.
Why not instead drop this, negate the if-condition, and the replace the break;
by something like commonPrefixFound := false
. So the loop would be roughly this (untested, just typed it into my browser):
commonPrefixFound := true
while commonPrefixFound and i < Length(cand[1])) do
i := i + 1; # try finding a common prefix with one more character
c := cand[1][i];
for j in [2..Length(cand)] do
if Length(cand[j]) < i or cand[j][i] <> c then
commonPrefixFound := false;
i := i - 1;
break;
fi;
od;
od;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah OK, I see now that this was the original code, and you simply copied and then edited it.
I still think that it was / is needlessly arcane :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it's weird, I'll be honest I hadn't looked at it carefully!
# If there are several equal words, just pick the first one... | ||
if Length(filtequal) > 0 then | ||
return filtequal[1]; | ||
fi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just do this:
filtequal := First(cand, a -> LowercaseString(a) = lowword);
if filtequal <> fail then
return filtequal;
fi;
else | ||
return fail; | ||
fi; | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps add a comma after this, so that if more functions are added to the list in the future, no diff for that line shows up?
description := [ | ||
"Set how names are filtered during tab-autocomplete, \ | ||
this can be: \"default\": case-sensitive matching. \"case-insensitive\": \ | ||
case-insensitive matching, or a record of two functions, each of which take \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
take -> takes
"Set how names are filtered during tab-autocomplete, \ | ||
this can be: \"default\": case-sensitive matching. \"case-insensitive\": \ | ||
case-insensitive matching, or a record of two functions, each of which take \ | ||
two arguments. 'filter' takes a list of names and a partial identifier and returns \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe clarify what filter
is, namely the name of a record component? So:
or a record with two components named 'filter' and 'completer' which both must be set to functions: 'filter' takes...
b7aae2a
to
7fe2d8d
Compare
7fe2d8d
to
89865c3
Compare
Ping everyone - sounds like we shall merge this? |
Personally I am not very keen on this change. But that's just a subjective thing, I guess... and it can be turned off (or is even off by default). So I am not actively objecting, but I am also not going to be the one who merges it ;-). |
Please make sure that this pull request:
Tick all what applies to this pull request
Write below the description of changes (for the release notes)
Adds a new configuration option
Autocompleter
, which chooses how GAP filters when tab-completing words. Adds an optioncase-insensitive
which does case-insensitive matching, and also allows an arbitrary function to be used.(this option works only when GAP is compiled with readline support).