   :init
   (add-hook 'prog-mode-hook 'rainbow-mode))
 
+;;----------;;
+;; Flycheck ;;
+;;----------;;
+(use-package flycheck
+  :init (global-flycheck-mode))
+
+;;-----------------;;
+;; JS/JSX - TS/TSX ;;
+;;-----------------;;
+(use-package add-node-modules-path)
+(use-package prettier-js)
+
+(use-package js
+  :defines
+  lsp-javascript-format-enable
+  :init
+  (define-derived-mode js/jsx-mode js-mode "js/jsx"
+    "Major mode for JS/JSX"
+    (add-node-modules-path)
+    (add-hook 'before-save-hook 'prettier-js 100 t))
+  :config
+  (add-to-list 'auto-mode-alist '("\\.jsx?\\'" . js/jsx-mode))
+  (setq lsp-javascript-format-enable nil))
+
+(use-package typescript-mode
+  :defines
+  lsp-typescript-format-enable
+  :init
+  (define-derived-mode ts/tsx-mode typescript-mode "ts/tsx"
+    "Major mode for TS/TSX"
+    (add-node-modules-path)
+    (add-hook 'before-save-hook 'prettier-js 100 t))
+  :config
+  (add-to-list 'auto-mode-alist '("\\.tsx?\\'" . ts/tsx-mode))
+  (setq lsp-typescript-format-enable nil))
+
+;;-------------;;
+;; Tree Sitter ;;
+;;-------------;;
+;; TODO: Add other programming languages:
+;;   https://github.com/emacs-tree-sitter/tree-sitter-langs/tree/master/repos
+(use-package tree-sitter
+  :hook ((js/jsx-mode . tree-sitter-hl-mode)
+	 (ts/tsx-mode . tree-sitter-hl-mode)))
+
+(use-package tree-sitter-langs
+  :after tree-sitter
+  :config
+  (tree-sitter-require 'tsx)
+  (add-to-list 'tree-sitter-major-mode-language-alist '(js/jsx-mode . tsx))
+  (add-to-list 'tree-sitter-major-mode-language-alist '(ts/tsx-mode . tsx)))
+
+;;-----;;
+;; LSP ;;
+;;-----;;
+(use-package python
+  :defines
+  lsp-pylsp-plugins-pydocstyle-enabled
+  lsp-pylsp-plugins-pycodestyle-enabled
+  lsp-pylsp-plugins-mccabe-enabled
+  lsp-pylsp-plugins-pyflakes-enabled
+  lsp-pylsp-plugins-pylint-enabled
+  lsp-pylsp-plugins-yapf-enabled
+  :config
+  (setq lsp-pylsp-plugins-pydocstyle-enabled nil)
+  (setq lsp-pylsp-plugins-pycodestyle-enabled nil)
+  (setq lsp-pylsp-plugins-mccabe-enabled nil)
+  (setq lsp-pylsp-plugins-pyflakes-enabled nil)
+  (setq lsp-pylsp-plugins-pylint-enabled nil)
+  (setq lsp-pylsp-plugins-yapf-enabled t)
+  )
+
+(use-package lsp-mode
+  :init
+  (setq lsp-keymap-prefix "C-c l")
+  :commands (lsp lsp-deferred)
+  :config
+  (defun lsp-install-before-save-hooks ()
+    (add-hook 'before-save-hook #'lsp-format-buffer t t)
+    (add-hook 'before-save-hook #'lsp-organize-imports t t))
+  :hook ((lsp-mode . lsp-enable-which-key-integration)
+         (lsp-mode . lsp-install-before-save-hooks)
+         (go-mode . lsp-deferred)
+         (js/jsx-mode . lsp-deferred)
+         (ts/tsx-mode . lsp-deferred)
+         (python-mode . lsp-deferred)))
+
+(use-package lsp-ui
+  :commands lsp-ui-mode)
+
+(use-package which-key
+    :config
+    (which-key-mode))
 
 ;;-------;;
 ;; Theme ;;

(use-package poetry
  :ensure t)

;; Use elpy in python mode
(use-package elpy
  :init
  (add-hook 'python-mode-hook '(lambda ()
                                 (setq python-indent-offset 4)))
  (add-hook 'before-save-hook 'elpy-format-code)
  :config
  (elpy-enable)
  (setq elpy-test-django-with-manage t)
  (setq elpy-modules (delq 'elpy-module-highlight-indentation elpy-modules))
  (setq elpy-rpc-virtualenv-path 'current)
  ;; Permits using pdb.set_trace() when running tests in buffer
  (defun elpy-test-run (working-directory command &rest args)
    (let ((default-directory working-directory))
      (compile (mapconcat #'shell-quote-argument
                          (cons command args)
                          " ")
               t))))

;; Use isort and auto sort imports on save
(use-package py-isort
  :init (add-hook 'before-save-hook 'py-isort-before-save))

;; Use pyenv to activate the correct conda environment
(use-package pyvenv
  :init
  (setenv "WORKON_HOME" "/Users/se7entyse7en/miniconda3/envs")

(use-package terraform-mode)


;;----------;;
;; Web mode ;;
;;----------;;
