Skip to content
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

Provide custom implementation of apply_completion #1912

Open
contificate opened this issue Sep 6, 2024 · 6 comments
Open

Provide custom implementation of apply_completion #1912

contificate opened this issue Sep 6, 2024 · 6 comments

Comments

@contificate
Copy link

Is there an idiomatic way of overriding the behaviour of apply_completion in Buffer?

I see that the default semantics, which is suitable for most applications, is:

self.delete_before_cursor(-completion.start_position)
self.insert_text(completion.text)

However, I have a kind of niche use-case which would be catered for better if there was an idiomatic way to reliably change this behaviour. For example, the most general interface I can imagine is effectively a function that rewrites the line and cursor position arbitrarily.

I apologise if there's a simple Python trick that I'm unaware of that would permit me to override this (I've tried various modifications to the example autocomplete-with-control-space.py to no avail) or if permitting this could have unintended interactions with other parts of the completer infrastructure that I haven't considered.

@nitanmarcel
Copy link

You can use inheriting to modify the behavior of a class method

https://docs.python.org/3/tutorial/classes.html#inheritance

@contificate
Copy link
Author

contificate commented Sep 26, 2024

You can use inheriting to modify the behavior of a class method

https://docs.python.org/3/tutorial/classes.html#inheritance

Yes, but I am not sure if there is an idiomatic way to actually thread this through. Suppose I overloaded apply_completion in a sub-class, how do I create a regular prompt that will use my custom buffer instance? Looks like most code samples query for the default buffer and never subclass Buffer itself. I tried some trickery to overload apply_completion in-place but it is neither effectual nor persistent.

@nitanmarcel
Copy link

You can use inheriting to modify the behavior of a class method
https://docs.python.org/3/tutorial/classes.html#inheritance

Yes, but I am not sure if there is an idiomatic way to actually thread this through. Suppose I overloaded apply_completion in a sub-class, how do I create a regular prompt that will use my custom buffer instance? Looks like most code samples query for the default buffer and never subclass Buffer itself. I tried some trickery to overload apply_completion in-place but it is neither effectual nor persistent.

Uh? Just use your custom inherited class and use it instead of buffer. Unless you mean something else

class MyBuffer(Buffer):
    def __init__(self, use the same args as the original Buffer):
        super().__init__(self, the same args as above)
    def apply_completion(self, same args as the original function:
        #modify the function here

And instead of using Buffer() you use MyBuffer().

For example here's me modifying the initialization function of KeyBinds class to create my bindings by default when initialized

https://github.com/nitanmarcel/Sno-py/blob/9cc3d366aa28e300893ddef5925e2c12b7bb0d0f/src/sno_py/bindings.py#L7

And here instead of using KeyBinds() I'm using the modified class

https://github.com/nitanmarcel/Sno-py/blob/main/src/sno_py/snoedit.py#L67

@nitanmarcel
Copy link

.

You can use inheriting to modify the behavior of a class method
https://docs.python.org/3/tutorial/classes.html#inheritance

Yes, but I am not sure if there is an idiomatic way to actually thread this through. Suppose I overloaded apply_completion in a sub-class, how do I create a regular prompt that will use my custom buffer instance? Looks like most code samples query for the default buffer and never subclass Buffer itself. I tried some trickery to overload apply_completion in-place but it is neither effectual nor persistent.

And if you want promt() call to use your buffer, override this to initialize your buffer

def _create_default_buffer(self) -> Buffer:

@nitanmarcel
Copy link

And you probably have to provide your own promt function that initializes your new class

session: PromptSession[str] = PromptSession(history=history)

@contificate
Copy link
Author

Alas, I have tried all levels of monkey patching to no avail.

This issue isn't really about whether or not there is a conceivable way to hack in what I want (there probably is, but I've been unable to get it to work) - it's a feature request to avoid having to hack it in. If you can supply a completer, why not also be allowed to specify how it completes?

The use-case I had in mind is being able to do auto-completion as a form of correction. If your cursor is within an erroneous portion of line input, a completer that is context-aware should effectively replace the erroneous segment (or keep the prefix) up to a synchronising token.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants