emacs-eaf / eaf-browser

A modern, customizable and extensible browser in Emacs
GNU General Public License v3.0
132 stars 26 forks source link

Support word deleting and cursor moving by C-backspace, C-delete, C-left, C-right in textbox? #8

Closed taquangtrung closed 3 years ago

taquangtrung commented 3 years ago

Hi,

Is your feature request related to a problem? Please describe.

No

Describe the solution you'd like

Open google.com, type the string "foo1 foo2 bar1 bar2" in the search book.

I'd like to be able to use Ctrl + left/right arrow to quickly move the cursor among words, and use Ctrl + Backspace, Ctrl + Delete to delete words.

Describe alternatives you've considered

I tried these key bindings from Emacs but it doesn't work:

  (define-key eaf-mode-map* (kbd "C-<backspace>") 'eaf-send-key)
  (define-key eaf-mode-map* (kbd "M-<backspace>") 'eaf-send-key)
manateelazycat commented 3 years ago

You need eaf-create-send-sequence-function create key sequence first.

I have fix this issue by https://github.com/emacs-eaf/emacs-application-framework/commit/eba8b68652fb87178d91288ada1c459e1e38038c and https://github.com/emacs-eaf/eaf-browser/commit/b7470a50f0ea7a3dcbc2514dff22ecdc298106ff

taquangtrung commented 3 years ago

@manateelazycat Thanks for the update!

I put the following code in my Emacs configuration:

  (define-key eaf-mode-map* (kbd "C-<left>") 'eaf-send-key-sequence)
  (define-key eaf-mode-map* (kbd "C-<right>") 'eaf-send-key-sequence)
  (define-key eaf-mode-map* (kbd "C-<backspace>") 'eaf-send-key-sequence)
  (define-key eaf-mode-map* (kbd "C-<delete>") 'eaf-send-key-sequence)

But when typing C-left, C-right, C-backspace, C-delete in the textbox of EAF browser, I am still not able to move the cursor by words, or delete words.

Here is the result of C-h k on C-left:

<C-left> runs the command eaf-send-key-sequence (found in eaf-mode-map), which
is an interactive Lisp closure in ‘eaf.el’.

It is bound to <C-delete>, <C-backspace>, <C-right>, <C-left>.

(eaf-send-key-sequence)

Directly send key sequence to EAF Python side.

I notice in buffer.py there is the function def fake_key_sequence(self, event_string).

Do I need to update it to handle those key sequences?

taquangtrung commented 3 years ago

I think that at the beginning of fake_key_sequence, we need to remove the < and > symbols from the event_string by event_string = event_string[1:-1].

    def fake_key_sequence(self, event_string):
        ''' Fake key sequence.'''
        event_string = event_string[1:-1]
        event_list = event_string.split("-")

Now the command QApplication.sendEvent(widget, QKeyEvent(QEvent.KeyPress, qt_key_dict[last_key], modifiers, last_key)) is able to send the correct key and modifier.

But somehow the cursor moving by C-left still doesn't work.

Do you think it's the limitation of the Qt app?

manateelazycat commented 3 years ago

You need eaf-create-send-sequence-function create key sequence first.

I have fix this issue by emacs-eaf/emacs-application-framework@eba8b68 and b7470a5

Please use install-eaf.py update EAF to newest version, new version has fixed this issue.

And please check patch above, EAF can send any key or key sequence to Python side.

taquangtrung commented 3 years ago

Yes, I updated and tested with the newest code containing your patch, and when press Ctrl + Left, the cursor still doesn't move.

I found out that the key sequence sent to fake_key_sequence in buffer.py has a slightly different format from what is expected by the processing inside the body of fake_key_sequence.

For example, when pressing Ctrl + Left, the event_string sent to fake_key_sequence is <C-left>.

While I believe that the body of fake_key_sequence expects the string C-<left>.

When I updated the code to below, then it's working:

    def fake_key_sequence(self, event_string):
        ''' Fake key sequence.'''
        # TRUNG: new code
        if event_string.startswith("<") and event_string.endswith(">"):
            event_string = event_string[1:-1]

        event_list = event_string.split("-")

        if len(event_list) > 1:
            for widget in [self.buffer_widget.focusProxy()]:
                last_char = event_list[-1]
                last_key = last_char
                if len(last_char) == 1:
                    last_key = last_char.lower()
                else:
                    # TRUNG: new code
                    last_key = "<" + last_key + ">"

Here is the related commit in my forked version: https://github.com/taquangtrung/emacs-application-framework/commit/53ef1ce945c7a0b9f7bb06ac8e5ad53c025ccf4a

Could you advise if my patch is correct or I misunderstood your patch?

manateelazycat commented 3 years ago

Yes, I updated and tested with the newest code containing your patch, and when press Ctrl + Left, the cursor still doesn't move.

I found out that the key sequence sent to fake_key_sequence in buffer.py has a slightly different format from what is expected by the processing inside the body of fake_key_sequence.

For example, when pressing Ctrl + Left, the event_string sent to fake_key_sequence is <C-left>.

While I believe that the body of fake_key_sequence expects the string C-<left>.

When I updated the code to below, then it's working:

    def fake_key_sequence(self, event_string):
        ''' Fake key sequence.'''
        # TRUNG: new code
        if event_string.startswith("<") and event_string.endswith(">"):
            event_string = event_string[1:-1]

        event_list = event_string.split("-")

        if len(event_list) > 1:
            for widget in [self.buffer_widget.focusProxy()]:
                last_char = event_list[-1]
                last_key = last_char
                if len(last_char) == 1:
                    last_key = last_char.lower()
                else:
                    # TRUNG: new code
                    last_key = "<" + last_key + ">"

Here is the related commit in my forked version: taquangtrung/emacs-application-framework@53ef1ce

Could you advise if my patch is correct or I misunderstood your patch?

Upgrade to newest version EAF, and remove your Ctrl + Left config from your .emacs !!! Because Your wrong config overwrite my newest patch

Please looks my patch, it have code (eaf-create-send-sequence-function "ctrl-left" "C-<left>"), I use eaf-create-send-sequence-function macro to tell EAF send C-<left> to Python side.

Your patch above is not right, it's a hacking way.

taquangtrung commented 3 years ago

Sorry for the confusion. But I did update your newest code 3 times but by default Ctrl+Left still doesn't work for me.

I'm using Spacemacs, hence, the way I update new code is to remove the eaf package, and run Spacemacs again so that it always installs the newest code: the lastest package it downloaded is eaf-20210824.120.

I found out that my problem might be due to the default configuration of Spacemacs: it binds Ctrl + Left, Right to left-word, right-word in the global-key-map by default (from the bindings.el library).

These bindings somehow override the below keybinding setting of EAF browser buffer.

(eaf-create-send-sequence-function "ctrl-left" "C-<left>")
(eaf-create-send-sequence-function "ctrl-right" "C-<right>")

Do you have any idea how to make EAF keybinding override the global-key-map?

manateelazycat commented 3 years ago

Sorry for the confusion. But I did update your newest code 3 times but by default Ctrl+Left still doesn't work for me.

I'm using Spacemacs, hence, the way I update new code is to remove the eaf package, and run Spacemacs again so that it always installs the newest code: the lastest package it downloaded is eaf-20210824.120.

I found out that my problem might be due to the default configuration of Spacemacs: it binds Ctrl + Left, Right to left-word, right-word in the global-key-map by default (from the bindings.el library).

These bindings somehow override the below keybinding setting of EAF browser buffer.

(eaf-create-send-sequence-function "ctrl-left" "C-<left>")
(eaf-create-send-sequence-function "ctrl-right" "C-<right>")

Do you have any idea how to make EAF keybinding override the global-key-map?

Did you remove (define-key eaf-mode-map* (kbd "C-<left>") 'eaf-send-key-sequence) from your .emacs ?

taquangtrung commented 3 years ago

Yes, I removed all of them, then C-h k and C-<left> shows the binding to left-word

<C-left> runs the command left-word (found in global-map), which is an
interactive compiled Lisp function in ‘bindings.el’.

It is bound to <C-left>, <M-left>.

(left-word &optional N)
manateelazycat commented 3 years ago

Yes, I removed all of them, then C-h k and C-<left> shows the binding to left-word

<C-left> runs the command left-word (found in global-map), which is an
interactive compiled Lisp function in ‘bindings.el’.

It is bound to <C-left>, <M-left>.

(left-word &optional N)

I don't know why you can't work, I have test newest version 5 times, works well.

Please use emacs -Q for test.

taquangtrung commented 3 years ago

Ok, I figured out the reason why Spacemacs overrides your setting.

In the layer eaf, the initialized keybindings for EAF browser is still the old one:

https://github.com/syl20bnr/spacemacs/blob/develop/layers/%2Btools/eaf/packages.el#L161

After I added your code from https://github.com/emacs-eaf/eaf-browser/commit/b7470a50f0ea7a3dcbc2514dff22ecdc298106ff

              ("C-<left>" . "eaf-send-ctrl-left-sequence")
              ("C-<right>" . "eaf-send-ctrl-right-sequence")
              ("C-<delete>" . "eaf-send-ctrl-delete-sequence")
              ("C-<backspace>" . "eaf-send-ctrl-backspace-sequence")

Then it works fine!

Sorry for the trouble.

And thank you so much for the great efforts on building EAF! :+1: