8

When opening a vector icon text file for editing, Emacs first tries to display it as an image. That is wrong ; If the file has errors, Emacs (25.3.2 - x86_64-pc-linux-gnu, GTK+ Version 3.18.9) crashes miserably. Well, I know it has errors, that why I opened it in a text editor in the first place :/

And furthermore, Emacs will hang even if the file doesn't have errors, but just because it cannot render it (like it's just several paths with ids inside a svg grouping tag) which is frustrating to say the least.

How can I make Emacs load text files as text files and not try to render it (because it can't) unless I explicitly told him to?

PS - Yes, I know that I can switch to text-mode by pressing C-c C-c.

What I tried

(add-to-list `auto-mode-alist
             '("\\.svg\\'" . xml-mode))

But no, Emacs still crashes on me upon opening my icons.svg file because it tries to render it as an image (and it's actually several images) when actually it's not its job.

Annex: The SVG code

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="cross" viewBox="0 0 20 20">
    <path d="M17.1 5.2l-2.6-2.6-4.6 4.7-4.7-4.7-2.5 2.6 4.7 4.7-4.7 4.7 2.5 2.5 4.7-4.7 4.6 4.7 2.6-2.5-4.7-4.7"/>
  </symbol>
  <symbol id="play" viewBox="0 0 15 15">
    <path d="M690 60H40l330 570L700 60z" />
  </symbol>
</svg>
  • 4
    You can open you file with M-x find-file-literaly and then M-x xml-mode – djangoliv Dec 1 '17 at 8:59
  • Cannot reproduce that problem with emacs 25.3.1 GTK+ on cygwin. What version of emacs do you use? – Tobias Dec 1 '17 at 13:24
  • 1
    FWIW, both on emacs-24 and a reasonably recent emacs-26.0.90 (add-to-list `auto-mode-alist '("\\.svg\\'" . xml-mode)) is sufficient to cause the svg file to be opened as xml (tested with emacs -Q). Interestingly, on emacs-24, opening your svg file as an image (i.e. the default) does not cause a crash, while on emacs-26.0.90, it does. – aplaice Dec 1 '17 at 15:16
  • 1
    @aplaice You are right, not only about add-to-list working in a emacs -Q session, but also, in this session my image displays, too!! Well, it's broken, but at least Emacs didn't crash. Curiouser and curiouser. – yPhil Dec 2 '17 at 8:43
  • 1
    I've reported the bug of the svg causing emacs to crash, in the form that I observed it, here. – aplaice Dec 5 '17 at 23:19
3

You'll probably like to either disable auto-image-file-mode or tweak image-file-name-extensions.

BTW, if Emacs crashes or hangs for a particular SVG file, I suggest you M-x report-emacs-bug about it. Maybe there's not much Emacs's code can do about it (e.g. the problem is in the SVG rendering livbrary), but it might be a good reason to change the default so that image-mode is not used by default on SVG files (hell, it might even be a security hole).

  • Thanks, but it does not work. Here is the description of the auto-image-file-mode var: "auto-image-file-mode’s value is nil Documentation: Non-nil if Auto-Image-File mode is enabled. See the ‘auto-image-file-mode’ command for a description of this minor mode. Setting this variable directly does not take effect; either customize it (see the info node ‘Easy Customization’) or call the function ‘auto-image-file-mode’." but even customizing it (? I don't get this "Setting this variable directly does not take effect" weirdness) doesn't change anything: Emacs crashes :[ – yPhil Dec 2 '17 at 8:37
  • I might add that eval (auto-image-file-mode -1) doesn't do anything either. – yPhil Dec 2 '17 at 8:40
1

I have a solution that does 2 things:

  1. Attempt to open any XML file in nXML mode, and this obviously needs to include SVG files.
  2. If such a file is an SVG file, then define C-c C-c to image-mode.

For the first item, I use magic-mode-alist to select nxml-mode on some sequences at the beginning of the buffer: <?xml, some DOCTYPE line with XHTML, and <svg followed by a newline character, a space, or >. This will work with SVG files that use an XML prolog or not (I assume no initial spaces, but this could be changed). Here's the code:

(when (boundp 'magic-mode-alist)
  (push '("\\`<\\(\\?xml\\|!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML\\|svg[\n >]\\)"
          . nxml-mode)
        magic-mode-alist)
)

For the second item, I use code for a find-file hook:

(defun my-find-file-hook ()
  (when (and (string= major-mode "nxml-mode")
             (save-excursion
               (and (re-search-forward "<[a-z]" 1024 t)
                    (progn (backward-char)
                           (looking-at "svg[\n >]")))))
    (global-set-key "\C-c\C-c" 'image-mode)))
(add-hook 'find-file-hook 'my-find-file-hook)

If the buffer is in nXML mode, it searches for the root element and if it is svg, then it defines C-c C-c. Note that this is just a heuristic. In particular, a <svg sequence in an initial XML comment could yield a false positive, but I think that this never occurs in practice.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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