0

So I've recently come back to working with emacs again I mostly write JavaScript in particular React these days and I'm noticing some strange behaviour when trying to indent my code.

it seems the indentation will only work for the first couple of times and then everything after a certain point has to be on the same indent. For example:

import React from 'react';


const About = () => {
  return (
    <div className="about">
    <div className="header">

    </div>
    </div>
  );
}

export default About;

You will notice that the react component above that the header div is indented to the same level as the about container. but all other indentation is fine. If I try to add any further elements in the header or anywhere else in the container the indentation remains the same too.

Here is my .emacs (apologies for the mess):


;; Include MELPA packages
(when (>= emacs-major-version 24)
  (require 'package)
  (package-initialize)
  (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
  )

;; KEY MODIFIERS
(global-set-key (kbd "M-3") '(lambda () (interactive) (insert "#")))
(defalias 'yes-or-no-p 'y-or-n-p)

;; YASNIPPET
(require 'yasnippet)
(yas-global-mode 1)

;; IDO MODE
(ido-mode 1)
(setq ido-file-extensions-order '(".js" ".json" ".scss" ".html" ".css"  ".yml"  ".rb"))
(setq ido-create-new-buffer 'always)
(setq ido-enable-flex-matching t)
(setq ido-everywhere t)

;; THEME
;; (load-theme 'tsdh-dark)

;; WEB MODE
(setq-default indent-tabs-mode nil)
(defun my-web-mode-hook ()
  "Hooks for Web mode."
  (setq web-mode-markup-indent-offset 2)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-code-indent-offset 2)
)

(add-hook 'web-mode-hook  'my-web-mode-hook)
(add-to-list 'auto-mode-alist '("\\.js\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.scss\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.css\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.jsx\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-mode))


;; No more backup files
(setq make-backup-files nil)

;; FLYCHECK
(require 'flycheck)

;; turn on flychecking globally
(add-hook 'after-init-hook #'global-flycheck-mode)

;; disable jshint since we prefer eslint checking
(setq-default flycheck-disabled-checkers
  (append flycheck-disabled-checkers
    '(javascript-jshint)))

;; use eslint with web-mode for jsx files
(flycheck-add-mode 'javascript-eslint 'web-mode)

;; customize flycheck temp file prefix
(setq-default flycheck-temp-prefix ".flycheck")

;; disable json-jsonlist checking for json files
(setq-default flycheck-disabled-checkers
  (append flycheck-disabled-checkers
    '(json-jsonlist)))

;; https://github.com/purcell/exec-path-from-shell
;; only need exec-path-from-shell on OSX
;; this hopefully sets up path and other vars better
(when (memq window-system '(mac ns))
  (exec-path-from-shell-initialize))

(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-selected-packages
   '(yasnippet exec-path-from-shell web-mode flycheck darkmine-theme json-mode js3-mode)))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )

I've been banging my head agasint this problem for most of the morning, so I thought it was time to ask on here. Any help towards getting my indentation working correctly would be a huge help!

TIA

2

2 Answers 2

3

With web-mode, make sure your treating your code as React, not JavaScript.

Using your init file, and saving your example code to a file with a .js extension, I get the behavior you describe. Saving your example code to a .jsx file, the html is syntax highlighted and indented properly.

To specify ReactJS vs JavaScript you could mess with web-mode-content-type and/or web-mode-set-content-type a la this emacs.SE answer no html/jsx indentation in jsx-mode or expand what files get what content type a la this emacs.SE answer Formatting jsx in js files with web-mode. You can also settings on a per-project basis with directory local variables.

3
  • So the only way to get web-mode to respect React code is to use the .jsx file extension? It’s a small change I guess, but could cause problems on projects where most of the codebase has already been written like this. Commented Mar 20, 2020 at 22:21
  • No, its just the test I did. See my update.
    – nega
    Commented Mar 20, 2020 at 23:32
  • Interesting, I never thought to try swapping out the file extension, I guess I’ve got so used to using .js instead or .jsx. At least that gives me something more to go on, thanks Commented Mar 21, 2020 at 22:08
2

Solved: After some digging it turns out the solution is actually really simple you just need to tell web mode to act the same for.js and .jsx files by adding this line into your emacs config:

(setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'")))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.