so-long.el
(Emacs Wiki, GNU ELPA) will help in many situations. It is included by default in Emacs 27+ and available in GNU ELPA for older versions of Emacs (24.4 and later).
This library enables you to configure some simple thresholds to check when visiting a file, beyond which a more performant mode will be used in place of the normal mode, including disabling certain buffer-local minor modes with performance implications, and tuning buffer-local variables to maximise responsiveness. By default this will happen for programming modes only, but the behaviour is all highly configurable.
Use M-x global-so-long-mode
to enable/toggle the functionality. To enable
the functionality by default, either customize the global-so-long-mode
user
option, or add the following to your init file:
;; Avoid performance issues in files with very long lines.
(global-so-long-mode 1)
The comprehensive documentation can be read on its GNU ELPA page in plain text, but is nicer to read inside Emacs itself using the command:
M-x so-long-commentary
Using the 18MiB one_line.json
from the question as an example, the time until Emacs is responsive (on my system) after visiting that file:
Without so-long
, Emacs hangs for nearly 3.5 minutes.
$ time emacs -Q --eval "(setq large-file-warning-threshold nil)" --eval "(run-with-idle-timer 0.1 nil #'kill-emacs)" -- one_line.json
real 3m25.785s
user 3m25.058s
sys 0m0.365s
With so-long
, Emacs is responsive in under a second.
$ time emacs -Q -f global-so-long-mode --eval "(setq large-file-warning-threshold nil)" --eval "(run-with-idle-timer 0.1 nil #'kill-emacs)" -- one_line.json
real 0m0.890s
user 0m0.538s
sys 0m0.047s
Note that despite that very dramatic improvement, if you actually need to navigate to a position very far into a line of such magnitude, then performance will again become very bad -- still better than it would have been, but the performance issues that so-long can't address will rapidly overshadow the ones it can address, the further into the line you get.
Visiting and moving around near the start of the file should present no problems at all, however -- and for long lines which are not on the scale of this example, the improvements may well be sufficient to make editing practical throughout the buffer.
This library may be noticeably more effective in Emacs 27.1 than in earlier versions, because one of the variables that it sets, bidi-inhibit-bpa
, was introduced in 27.1, and that has a significant effect on performance for lines with vast numbers of deeply-nested 'paired bracket' characters (as are abundant in JSON); so the combination of Emacs 27.1 and global-so-long-mode
is the best pairing at present.
(If editing files like this one is a regular requirement, however, then Emacs probably isn't the best tool for the job. For JSON specifically, the jq
command-line tool may serve you well.)
View Large Files
(vlf) is a minor mode that is aimed to help with editing large files by loading them in batches. Disclaimer: I've never used it and I don't know whether it handles long lines in batches too.$ tail -f /some/file | fold -s
in a shell buffer. This isn't good for editing, obviously, but helps a lot with reading.