Fork me on GitHub
#emacs
<
2019-12-02
>
Lucas Barbosa02:12:10

Anybody had issues with font lock on big clojure files before? My emacs is hanging when I open a 6k lines cljs file (an edn i18n dictionary). I profiled it and looks like font-lock is the culprit :thinking_face:

āœ‹ 4
codeasone16:12:28

Lucas, I recently introduced the following into my config for large files, whilst it won't address the initial loading issue, it may help for general navigation with any large file (not just Clojure code)

(use-package fast-scroll
  :ensure t
  :init
  (add-hook 'fast-scroll-start (lambda () (flycheck-mode -1)))
  (add-hook 'fast-scroll-end   (lambda () (flycheck-mode 1)))
  :config
  (fast-scroll-config)
  (fast-scroll-mode 1))

Lucas Barbosa14:12:36

I'll give it a try! Thanks

royalaid02:12:44

I think is a general emacs issue unfortunately

royalaid02:12:15

You can see it happen with any large file and font-lock, or if the file is large enough emacs just grinds to a halt

royalaid02:12:22

but I also would be interested in a solution

sogaiu02:12:11

waiting for tree sitter support šŸ™‚

sogaiu02:12:47

turning off the highlighting at least allows one to get things done, iirc

bozhidar08:12:21

Yep. The current font-locking engine is based on regular expressions, which results in pretty poor performance in certain cases.

bozhidar08:12:44

Iā€™m pretty sure we can improve the existing regular expressions, but I never found the time to profile and tweak them.

Lucas Barbosa11:12:43

Yeah, if I open the file literally, it is very fast @royalaid

Lucas Barbosa12:12:59

Well, it actually opens the file and I am able to navigate (slowly, but doable)

Lucas Barbosa12:12:22

But it hangs for a while when I ask it to open the file :thinking_face: not a deal breaker, definitely

yuhan12:12:35

I noticed major slowdowns too when the file is basically a single huge sexp, in the case of edn data

yuhan12:12:58

made a lightweight edn-mode based on text-mode to get around this - not sure if that would be something generally useful to people?

(defvar edn-font-lock-keywords
  `((,(rx (group (repeat 1 2 ":"))
          (group (+ (or (syntax word) (syntax symbol))))
          (group "/")
          (group (+ (or (syntax word) (syntax symbol)))))
     (1 'clojure-keyword-face)
     (2 font-lock-type-face)
     (3 'default)
     (4 'clojure-keyword-face))
    (,(rx (group (repeat 1 2 ":"))
          (group (+ (or (syntax word) (syntax symbol)))))
     (1 'clojure-keyword-face)
     (2 'clojure-keyword-face))))

(define-derived-mode edn-mode text-mode "EDN"
  "Major mode for editing Extensible Data Notation files"
  (set-syntax-table clojure-mode-syntax-table)
  (setq-local tab-width 2)
  (setq-local comment-start ";")
  (setq-local comment-start-skip ";+ *")
  (setq-local comment-add 1)
  (setq-local font-lock-defaults '(edn-font-lock-keywords nil)))

(add-hook 'edn-mode-hook 'rainbow-delimiters-mode)

(with-eval-after-load 'clojure-mode
  (add-to-list 'auto-mode-alist '("\\.edn\\'" . edn-mode))
  (add-to-list 'auto-mode-alist '("deps.edn\\'" . clojure-mode))
  (add-to-list 'auto-mode-alist '("shadow-cljs.edn\\'" . clojure-mode))
  (add-to-list 'auto-mode-alist '("config.edn" . clojure-mode)))

yuhan12:12:48

the last part is basically a whitelist of edn config files like "deps.edn" where you still want prog-mode commands like structural editing

sogaiu14:12:38

i use the joe editor for huge edn :)

sogaiu14:12:36

still cumbersome, but can at least search without terrible responsiveness

borkdude22:12:19

What is the emacs command for indenting the contents of a string like:

(deftest redefine-var-test
  (eval* "(def ^:redef x 10)
        (defn foo [] x)
     (def x 11)
   (println (foo))
"))

borkdude22:12:31

I found indent-relative works, but not for multiple lines at once

sogaiu22:12:03

i select the region and use indent-region

borkdude22:12:23

that doesn't work for a string

sogaiu22:12:42

ah, just the string part...

sogaiu22:12:51

no idea -- though you could indent the string when it's a form first and then paste?

sogaiu22:12:24

may be narrow-to-region first?

borkdude22:12:31

that also doesn't work very well

sogaiu22:12:50

i guess ending the line with the eval on it at the double quote and then starting the form on the next line is not to your taste?

borkdude22:12:33

yeah, that works šŸ™‚