|
Vim has this, and it's almost easter, so clearly we should have it too.
Also it's from Monty Python, which makes it even more fitting.
HEAD KNIGHT: Ni!
KNIGHTS: Ni! Ni! Ni!
ARTHUR: Who are you?
HEAD KNIGHT: We are the Knights Who Say... Ni!
ARTHUR: No! Not the Knights Who Say Ni!
HEAD KNIGHT: The same!
BEDEVERE: Who are they?
HEAD KNIGHT: We are the keepers of the sacred words: Ni, Pen, and Ni-wom!
RANDOM: Ni-wom!
ARTHUR: Those who hear them seldom live to tell the tale!
HEAD KNIGHT: The Knights Who Say Ni demand a sacrifice!
ARTHUR: Knights of Ni, we are but simple travellers who seek the enchanter who lives beyond these woods.
HEAD KNIGHT: Ni! Ni! Ni! Ni!
ARTHUR and PARTY: Oh, ow!
HEAD KNIGHT: We shall say 'nee' again to you if you do not appease us.
ARTHUR: Well, what is it you want?
HEAD KNIGHT: We want... a shrubbery!
[dramatic chord]
ARTHUR: A what?
HEAD KNIGHT: Ni! Ni!
ARTHUR and PARTY: Oh, ow!
ARTHUR: Please, please! No more! We shall find a shrubbery.
HEAD KNIGHT: You must return here with a shrubbery or else you will never pass through this wood alive!
ARTHUR: O Knights of Ni, you are just and fair, and we will return with a shrubbery.
HEAD KNIGHT: One that looks nice.
ARTHUR: Of course.
HEAD KNIGHT: And not too expensive.
ARTHUR: Yes.
HEAD KNIGHTS: Now... go!
ARTHUR: Old crone! Is there anywhere in this town where we could buy a shrubbery!
[dramatic chord]
CRONE: Who sent you?
ARTHUR: The Knights Who Say Nee.
CRONE: Agh! No! Never! We have no shrubberies here.
ARTHUR: If you do not tell us where we can buy a shrubbery, my friend
and I will say... we will say... `nee'.
CRONE: Agh! Do your worst!
ARTHUR: Very well! If you will not assist us voluntarily,... Ni!
CRONE: No! Never! No shrubberies!
ARTHUR: Ni!
BEDEVERE: Noo! Noo!
ARTHUR: No, no, no, no -- it's not that, it's 'Ni'.
BEDEVERE: Noo!
ARTHUR: No, no -- 'Ni'. You're not doing it properly.
BEDEVERE: Noo! Ni!
ARTHUR: That's it, that's it, you've got it.
ARTHUR and BEDEVERE: Ni! Ni!
ROGER: Are you saying 'Ni' to that old woman?
ARTHUR: Um, yes.
ROGER: Oh, what sad times are these when passing ruffians can say `Ni' at will to old ladies. There is a pestilence upon this land, nothing is sacred. Even those who arrange and design shrubberies are under considerable economic stress at this period in history.
ARTHUR: Did you say `shrubberies'?
ROGER: Yes, shrubberies are my trade -- I am a shrubber. My name is Roger the Shrubber. I arrange, design, and sell shrubberies.
BEDEVERE: Ni!
ARTHUR: No! No, no, no! No!
ARTHUR: O, Knights of Ni, we have brought you your shrubbery. May we go now?
HEAD KNIGHT: It is a good shrubbery. I like the laurels particularly. But there is one small problem.
ARTHUR: What is that?
HEAD KNIGHT: We are now... no longer the Knights Who Say Ni.
RANDOM: Ni!
HEAD KNIGHT: Shh shh. We are now the Knights Who Say Ecky-ecky-ecky- ecky-pikang-zoom-boing-mumble-mumble.
RANDOM: Ni!
HEAD KNIGHT: Therefore, we must give you a test.
ARTHUR: What is this test, O Knights of-- Knights Who 'Til Recently Said Ni?
HEAD KNIGHT: Firstly, you must find... another shrubbery!
[dramatic chord]
ARTHUR: Not another shrubbery!
HEAD KNIGHT: Then, when you have found the shrubbery, you must place it here beside this shrubbery, only slightly higher so you get a two-level effect with a little path running down the middle.
RANDOM: A path! A path! Ni!
HEAD KNIGHT: Then, when you have found the shrubbery, you must cut down the mightiest tree in the forest... with... a herring!
[dramatic chord]
ARTHUR: We shall do no such thing!
HEAD KNIGHT: Oh, please!
ARTHUR: Cut down a tree with a herring? It can't be done.
KNIGHTS: Aaaaugh! Aaaugh!
HEAD KNIGHT: Don't say that word.
ARTHUR: What word?
HEAD KNIGHT: I cannot tell, suffice to say is one of the words the Knights of Ni cannot hear.
ARTHUR: How can we not say the word if you don't tell us what it is?
KNIGHTS: Aaaaugh! Aaaugh!
ARTHUR: What, `is'?
HEAD KNIGHT: No, not `is' -- we couldn't get vary far in life not saying `is'.
BEDEVERE: My liege, it's Sir Robin!
MINSTREL (singing): Packing it in and packing it up
And sneaking away and buggering up
And chickening out and pissing about
Yes, bravely he is throwing in the sponge
ARTHUR: Oh, Robin!
ROBIN: My liege! It's good to see you!
KNIGHTS: Aaaaugh!
HEAD KNIGHT: He said the word!
ARTHUR: Surely you've not given up your quest for the Holy Grail?
MINSTREL (singing): He is sneaking away and buggering up--
ROBIN: Shut up! No, no no-- far from it.
HEAD KNIGHT: He said the word again!
ROBIN: I was looking for it.
KNIGHTS: Aaaaugh!
ROBIN: Uh, here, here in this forest.
ARTHUR: No, it is far from--
KNIGHTS: Aaaaugh!
HEAD KNIGHT: Aaaaugh! Stop saying the word!
ARTHUR: Oh, stop it!
KNIGHTS: Aaaaugh!
HEAD KNIGHT: Oh! He said it again!
ARTHUR: Patsy!
HEAD KNIGHT: Aaugh! I said it! I said it! Ooh! I said it again!
KNIGHTS: Aaaaugh!
|
|
This makes CompletionParser.parse simpler and makes ParseResult.cmd and
.args non-Optional. Them being Optional would mean we would've to either
resort to more complex typing with Literal, or to check whether they are
really non-None everywhere.
Since fallback=True is only used at one point, let's just handle this at
the calling site instead.
In theory, this changes the behavior when the cmdstr is empty and
self._partial_match is set, because we now raise early and
self._completion_match isn't called anymore. In practice, I think this
shouldn't make a difference anywhere, and tests seem to agree.
If cmdstr is empty and self._partial_match is False, the behavior should
be the same, because objects.commands[''] will raise KeyError.
|
|
On GitHub Actions, it looks like there's a situation where
os.path.expanduser and pathlib.Path.expanduser disagree.
When in test_filesystem_completion_hypothesis the completion gets '~' as
input, it fails with:
tests/unit/completion/test_models.py:469: in test_filesystem_completion_hypothesis
model.set_pattern(text)
qutebrowser/completion/models/filepathcategory.py:88: in set_pattern
self._paths = sorted(self._contract_user(val, path) for path in paths)
qutebrowser/completion/models/filepathcategory.py:88: in <genexpr>
self._paths = sorted(self._contract_user(val, path) for path in paths)
qutebrowser/completion/models/filepathcategory.py:52: in _contract_user
return str(head / pathlib.Path(path).relative_to(head.expanduser()))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = PosixPath('/home/runneradmin'), other = (PosixPath('/home/runner'),)
parts = ['/', 'home', 'runneradmin'], drv = '', root = '/'
def relative_to(self, *other):
[...]
E ValueError: '/home/runneradmin' does not start with '/home/runner'
Let's use os.path everywhere, so we can be sure the two code paths agree
with each other.
|