10

I've configured Emacs to open files named *.cfg in shell-script-mode. These are config files, of course, rather than shell scripts, but 90% of the time it does what I want (mainly, good guesses about faces for comments and variable assignment). I use flycheck-mode, and I like it enough to have global-flycheck-mode enabled. The problem is that, in the case of *.cfg files, flycheck-mode suggests lots of errors that aren't relevant.

Is there a way to disable flycheck-mode automagically based on either file name or the path to the file? The closest I've seen is flycheck-before-syntax-check-hook...I could imagine sticking in a check for path or filename, but it runs before each syntax check (rather than disabling checks entirely).

2 Answers2

11

The good way

Simply do not use Sh Mode for buffers which do not contain shell scripts. Write your own mode instead. This is the canonical way to handle such situations in Emacs.

Write a custom major mode is easy. You can simply inherit from Sh Mode to get all of its features and commands, while still having an independent mode. Just add the following to your init.el for a simple start:

(define-derived-mode my-cfg-mode sh-mode "My CFg Mode"
  "A mode for my CFg files."
  (sh-set-shell "bash"))

(add-to-list 'auto-mode-alist '("\\.cfg\\'" . my-cfg-mode))

Since this new mode is independent from Sh Mode, Flycheck won't try to use syntax checkers for Sh Mode in this new mode.

Using a separate mode also has other advantages: You can setup your own keybindings, independent from Sh Mode, or extend syntax highlighting specifically for this style of configuration files.

The bad way

As a quick hack, you can also simply disable Flycheck again in such files:

(add-hook 'flycheck-mode-hook #'my-keep-flycheck-off)

(defun my-keep-flycheck-off ()
  (when (and (eq major-mode 'sh-mode)
             (buffer-file-name)
             (string= (file-name-extension (buffer-file-name)) "cfg"))
    (flycheck-mode -1)))

Note, though, that speaking as the Flycheck maintainer, I'd recommend against this solution. Be a good Emacs citizen, and write your own mode, really.

9

You can easily disable checkers using

(setq flycheck-disabled-checkers '(sh-shellscript sh-bash sh-zsh))

The Flycheck documentation adds more information here.

You can also disable checkers in a lambda for auto-mode-alist to have it only disable on .cfg files.

(add-to-list 'auto-mode-alist
             '("\\.cfg\\'" . (lambda ()
                               (setq flycheck-disabled-checkers  (append '(sh-shellscript sh-bash sh-zsh) flycheck-disabled-checkers))
                               (shell-script-mode))))
Malabarba
  • 22,878
  • 6
  • 78
  • 163
Gambo
  • 929
  • 5
  • 14
  • 1
    You might want to have the `setq` work off the existing value of `flycheck-disabled-checkers`, as in `(setq flycheck-disabled-checkers (append '(sh-shellscript sh-bash sh-zsh) flycheck-disabled-checkers))`. That way, if the variable gets modified elsewhere, you'll still have the other things in it. – zck Oct 24 '14 at 06:18
  • @zck There is no “existing” value for this variable. It's intended to be set locally, either with `setq` from a hook, or with local variables. –  Oct 24 '14 at 09:59