emacs-vs / auto-rename-tag

Automatically rename paired HTML/XML tag.
GNU General Public License v3.0
37 stars 10 forks source link

lsp-mode with flycheck doesn't work. #9

Open jcs090218 opened 4 years ago

jcs090218 commented 4 years ago

Refer to https://github.com/jcs-elpa/auto-rename-tag/issues/3#issuecomment-630584742

aaronjensen commented 4 years ago

Thanks, I added a repro and reported upstream: https://github.com/emacs-lsp/lsp-mode/issues/1704

aaronjensen commented 4 years ago

@jcs090218 looks like they closed it, see: https://github.com/emacs-lsp/lsp-mode/issues/1704#issuecomment-630904219

I just played around with firing what's in the after-change in a timer, which works, but it makes more sense to do it as a post-command hook, I think.

aaronjensen commented 4 years ago

Here's what I got working, I had to disable the before change hook while the timer is running:

(defvar auto-rename-tag--after-change-active nil)

(defun auto-rename-tag--before-change-functions (_begin _end)
  "Do stuff before buffer is changed.
BEGIN : beginning of the changes.
END : end of the changes."
  (unless auto-rename-tag--after-change-active

    ;; Reset record.
    (setq auto-rename-tag--record-prev-word "")
    ;; Reset flag.
    (setq auto-rename-tag--pre-command-actived nil)

    (when (and (not undo-in-progress)
               (auto-rename-tag--inside-tag-p)
               (not (auto-rename-tag--self-tag-p)))
      (save-excursion
        ;; Set active flag.
        (setq auto-rename-tag--pre-command-actived t)

        (setq auto-rename-tag--record-prev-word (auto-rename-tag--get-tag-name-at-point))

        (when (string= auto-rename-tag--record-prev-word "/")
          (setq auto-rename-tag--record-prev-word ""))

        ;; Ensure `auto-rename-tag--record-prev-word' is something other than nil.
        (unless auto-rename-tag--record-prev-word
          (setq auto-rename-tag--record-prev-word ""))))))

(defun auto-rename-tag--after-change-function (_begin _end _length)
  "Do stuff after buffer is changed.
BEGIN : beginning of the changes.
END : end of the changes.
LENGTH : deletion length."
  (when auto-rename-tag--pre-command-actived
    (run-at-time 0 nil (lambda () 
                         (save-excursion
                           (let ((is-end-tag nil)
                                 (current-word "") (pair-tag-word "")
                                 (auto-rename-tag--after-change-active nil))
                             ;; Goto the first character inside the tag.
                             (auto-rename-tag--goto-the-start-of-tag-name)

                             (setq is-end-tag (auto-rename-tag--is-closing-tag-p))

                             (setq current-word (auto-rename-tag--get-tag-name-at-point))

                             (unless (string= current-word auto-rename-tag--record-prev-word)
                               ;; NOTE: Is closing tag.
                               (when is-end-tag
                                 (auto-rename-tag--resolve-nested 'backward)

                                 ;; Get the tag name and ready to be compare.
                                 (setq pair-tag-word (auto-rename-tag--get-tag-name-at-point))

                                 ;; Ensure `pair-tag-word' is something other than nil.
                                 (unless pair-tag-word (setq pair-tag-word ""))

                                 (when (string= auto-rename-tag--record-prev-word pair-tag-word)
                                   ;; Delete the pair word.
                                   (unless (string= pair-tag-word "")
                                     (auto-rename-tag--delete-tag-name))
                                   ;; Insert new word.
                                   (insert current-word)))

                               ;; NOTE: Is opening tag.
                               (unless is-end-tag
                                 (auto-rename-tag--resolve-nested 'forward)

                                 (setq is-end-tag (auto-rename-tag--is-closing-tag-p))

                                 ;; Get the tag name and ready to be compare.
                                 (setq pair-tag-word (auto-rename-tag--get-tag-name-at-point))

                                 ;; Ensure `pair-tag-word' is something other than nil.
                                 (unless pair-tag-word (setq pair-tag-word ""))

                                 (when (string= auto-rename-tag--record-prev-word pair-tag-word)
                                   ;; Delete the pair word.
                                   (unless (string= pair-tag-word "")
                                     (auto-rename-tag--delete-tag-name))
                                   ;; Insert new word.
                                   (insert current-word))))))))))
jcs090218 commented 4 years ago

Interesting, not sure if there is more elegant way to solve this. Would you mind to make a PR? Cuz I can't really tell what changes and what doesn't. 😕

In my understanding, we have a auto-rename-tag--after-change-active flag to check weather to active the timer you put in after hook? Would that causes any side effect? Thanks! :)

jcs090218 commented 4 years ago

Refer to #10.

jcs090218 commented 4 years ago

Okay, so post-command-hook doesn't gives me the same result hence I have this patch here 4fd9de4dc7939b4a0c4c35cd7035fe88f57e9a32. I just have function runs twice, the performance might went down but this is the best solution for now. 😕 See if this works for you! (Running twice might still cause the LSP display error)

aaronjensen commented 4 years ago

Yeah, unfortunately this has the same problem.

What was the issue you had with post-command-hook alone?

jcs090218 commented 4 years ago

What was the issue you had with post-command-hook alone?

I think the tag wasn't update properly. If I tried delete the whole word, then it seems to be not working. But it will work when I modified by adding/deleting the character one by one. I haven't figure out the solution yet. 😕