rjsx-mode icon indicating copy to clipboard operation
rjsx-mode copied to clipboard

rjsx-electric-lt and rjsx-delete-creates-full-tag misbehaves

Open shackra opened this issue 6 years ago • 21 comments

Sometimes I will push the < key on my keyboard and the tag woun't auto-complete per rjsx-electric-lt behavior as I expect, instead the error missing ‘>’ after ‘/’ in self-closing tag will be registered on *Messages*.

Also, if the tag is automatically close by rjsx-electric-lt, and then I press C-d (rjsx-delete-creates-full-tag) the / gets deleted but I see no closing tags, I need to insert the / again and the delete it with C-d in order to get the function working as expected.

You can see this misbehavior from both functions in action on the following video:

https://streamable.com/6izlx

This is my full JavaScript, ReactJS and JSX configuration:

(setq-default js-indent-level 2)

(use-package ng2-mode)

;; TODO: Eliminar cuando el soporte para lsp-mode sea activado
(use-package tide
  :init
  (defun setup-tide-mode ()
    (interactive)
    (tide-setup)
    (tide-hl-identifier-mode +1))
  (setf tide-format-options
        '(:insertSpaceAfterFunctionKeywordForAnonymousFunctions t :placeOpenBraceOnNewLineForFunctions nil))
  (setf tide-tsserver-process-environment '("TSS_LOG=-level verbose -file /tmp/tss.log"))
  (add-hook 'before-save-hook 'tide-format-before-save)
  ;; Añade company-tide como fuente de auto-completado para varios modos
  ;; mayores que lidian con JavaScript/Typescript
  (dolist (hook '(js2-mode-hook
                  rjsx-mode-hook
                  inferior-js-mode-hook
                  typescript-mode-hook
                  ng2-ts-mode-hook))
    (add-hook hook #'setup-tide-mode)
    (add-hook hook (lambda ()
                     (add-to-list (make-local-variable 'company-backends)
                                  '(company-tide :with company-yasnippet)))))
  :config
  (with-eval-after-load flycheck-mode
    (flycheck-add-next-checker 'javascript-eslint 'jsx-tide 'append)))

(use-package js2-refactor
  :after (js2-mode)
  :config
  (add-hook 'js2-mode-hook #'js2-refactor-mode)
  (js2r-add-keybindings-with-prefix "C-c C-m"))

(use-package xref-js2
  :after (js2-mode)
  :init
  (add-hook 'js2-mode-hook (lambda () (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t))))

(use-package js2-mode
  :mode "\\.js\\'"
  :init
  (add-hook 'js2-mode-hook #'js2-imenu-extras-mode))

;; Indium se conecta con una pestaña del navegador web o un proceso de NodeJS
;; y provee varias características para el desarrollo en JavaScript
(use-package indium ;; https://indium.readthedocs.io/en/latest/setup.html
  :config
  (add-hook 'js-mode-hook #'indium-interaction-mode))

;; Modo mayor para trabajar con Reactive.JS
(use-package rjsx-mode
  :init
  (add-to-list 'auto-mode-alist '("components?\\/.*\\.js\\'" . rjsx-mode))
  (add-to-list 'auto-mode-alist '("containers?\\/.*\\.js\\'" . rjsx-mode))
  :config
  ;; tomado de https://emacs.stackexchange.com/a/33544/690 mejora el sangrado
  ;; de lineas
  (defadvice js-jsx-indent-line (after js-jsx-indent-line-after-hack activate)
    "Workaround sgml-mode and follow airbnb component style."
    (save-excursion
      (beginning-of-line)
      (if (looking-at-p "^ +\/?> *$")
          (delete-char sgml-basic-offset)))))

(with-eval-after-load flycheck-mode
  ;; tomado de https://jamiecollinson.com/blog/my-emacs-config/ hace que
  ;; flycheck utilice eslint instalado en el proyecto en lugar del habilitado
  ;; globalmente en el sistema
  (defun jc/use-eslint-from-node-modules ()
    "Set local eslint if available."
    (let* ((root (locate-dominating-file
                  (or (buffer-file-name) default-directory)
                  "node_modules"))
           (eslint (and root
                        (expand-file-name "node_modules/eslint/bin/eslint.js"
                                          root))))
      (when (and eslint (file-executable-p eslint))
        (setq-local flycheck-javascript-eslint-executable eslint))))

  (add-hook 'flycheck-mode-hook #'jc/use-eslint-from-node-module))

shackra avatar Apr 18 '18 01:04 shackra

What version of rjsx are you using? I can reproduce the first problem (working on a fix), but not the second one

felipeochoa avatar Apr 18 '18 13:04 felipeochoa

According to package.el is the version 20180409.902 from Melpa inestable.

Is weird you cannot reproduce the issue of rjsx-delete-creates-full-tag.

Felipe [email protected] writes:

What version of rjsx are you using? I can reproduce the first problem (working on a fix), but not the second one

shackra avatar Apr 18 '18 17:04 shackra

I have this problem with https://github.com/hlissner/doom-emacs too

ar1a avatar Apr 21 '18 14:04 ar1a

Is this issue still happening with the latest version of rjsx? Based on the syntax highlighting it looks like the parse is choking on your file, but when I manually write it into a test buffer it works fine. Would you mind pasting the file that is causing issues for you?

felipeochoa avatar Apr 28 '18 02:04 felipeochoa

I'm not getting the close tag when deleting the / with C-d

shackra avatar Apr 28 '18 04:04 shackra

Can you paste the whole buffer content that causes the issue?

felipeochoa avatar Apr 28 '18 04:04 felipeochoa

Sure:

import React, { Component } from 'react';
import './App.css';

class App extends Component {
  constructor() {
    super();
    this.state = { inputValue: "hola mundo" };
    this.onChange = this.onChange.bind(this);
  }
  onChange(event) {
    this.setState({ inputValue: event.target.value });
  }
  render() {
    return (
      <div>
        <input type="text" id="input1" value={this.state.inputValue} onChange={this.onChange} />
      </div>
    );
  }
}

export default App;

shackra avatar Apr 28 '18 04:04 shackra

Where are you trying to add the </div>?

felipeochoa avatar Apr 28 '18 04:04 felipeochoa

I write < which becomes </> then I write div which leaves me with <div/> and the I press C-d which leaves me with <div> when I was expecting <div></div>. I need to write the / and then press C-d again to trigger the close tag auto-completion.

shackra avatar Apr 28 '18 04:04 shackra

I understand the issue, but still cannot reproduce. Where in the buffer are you writing this?

felipeochoa avatar Apr 28 '18 04:04 felipeochoa

At the upper line from <input type="text" id="input1" value={this.state.inputValue} onChange={this.onChange} /> but inside the div tag.

shackra avatar Apr 28 '18 04:04 shackra

Sorry still nothing. Can you reproduce the issue in an emacs -Q session? Have you updated to the latest version of rjsx?

felipeochoa avatar Apr 28 '18 04:04 felipeochoa

Here is a demo https://streamable.com/shkt3

Yes, I just updated all my packages 5 minutes ago

shackra avatar Apr 28 '18 04:04 shackra

And can you reproduce in an emacs -Q session? I understand the issue you're describing, but unless I can reproduce on my machine it's very hard to debug.

Can you do the following and let me know what you get?

  1. Type <div (so you end up with <div/>). Leave point on the /
  2. Run M-x eval-expression and then (get-char-property (point) 'rjsx-class)
  3. Run M-x eval-expression and then (js2-node-short-name (rjsx--tag-at-point))

felipeochoa avatar Apr 28 '18 04:04 felipeochoa

These are the results, with emacs -Q:

self-closing-slash
"rjsx-node"

shackra avatar Apr 28 '18 05:04 shackra

And does it work with emacs -Q? What are the results in your normal session?

felipeochoa avatar Apr 28 '18 05:04 felipeochoa

yeah, it actually works fine with emacs -Q

When running emacs normally the behavior shown on the last video is what happens

shackra avatar Apr 28 '18 05:04 shackra

Ok. At this point you should try bisecting your config to see what causes the issue. I personally use js2-refactor, and tide, so I it's probably not one of those. If you can narrow it down to a single package interacting badly with rjsx I can investigate from there

felipeochoa avatar Apr 28 '18 05:04 felipeochoa

Done, using Bug hunter it tells me the error comes from this part of my configuration:

Initial tests done. Hunting for the cause...
"/home/jorge/.emacs.d/tmp-init.el", line 1332 pos 0:
  The assertion returned the following value here:
    t
  Caused by the following expression:
    (use-package prog-mode :ensure nil :init
      (defun shackra-prog-mode nil
        (set
         (make-local-variable 'fill-column)
         79)
        (set
         (make-local-variable 'comment-auto-fill-only-comments)
         t)
        (auto-fill-mode t)
        (highlight-numbers-mode)
        (hes-mode)
        (electric-pair-mode)
        (rainbow-turn-on)
        (when
            (or
             (executable-find "ispell")
             (executable-find "hunspell"))
          (flyspell-prog-mode))
        (prettify-symbols-mode))
      (bind-key* "C-M-," 'comment-dwim)
      (add-hook 'prog-mode-hook #'shackra-prog-mode))

But I don't know if you see anything meaningful in that snippet of code

shackra avatar Apr 28 '18 05:04 shackra

I think I may have found it... Can you try disabling flyspell-prog-mode and seeing if you can reproduce the issue? Can you then re-enable flyspell and after typing <div wait for ~10s and then try deleting the slash?

felipeochoa avatar Apr 28 '18 05:04 felipeochoa

I was narrowing my code too and the issue is indeed flyspell-prog-mode, ha!

Disabling it functions as a workaround.

shackra avatar Apr 28 '18 05:04 shackra