Search code examples
emacstclsyntax-highlighting

modify syntax highlighting for Tcl in Gnu Emacs


I've been using emacs (currently Gnu Emacs 26.3 under Ubuntu) for many years, but I still have to fold when I need to modify or configure emacs.

Can someone please help me with the following problem: I'm using Gnu Emacs to edit Tcl scripts. The highlighting works nicely, with one exception: When I pass a list in curly brackets to a Tcl command, the text in the curly brackets gets highlighted as if it contains Tcl commands. So I get colored if, for, error etc. in normal text.

My first question is, if there's an easy way to deactivate or modify this particular feature while keeping the rest of the syntax highlighting intact? I'm aware that this may be tricky since there's no easy way in Tcl to distinguish between code in curly brackets and other stuff in curly brackets, since code is passed in exactly this way also to commands like while or if.

My second question is: My Tcl files are special since they basically contain another language implemented in Tcl. Can I automatically activate a modified syntax highlighting whenever I open a file e.g. with suffix .mylang.tcl in Emacs? Where do I need to put the modified highlighting style file (actually, where is the original?), how do I tell Emacs to use this highlighting style file for files with the given suffix? How can I guarantee that not the highlighting for .tcl is activated, even if the suffix .mylang.tcl also ends in .tcl, but the new one?

Thanks a lot for your help!


Solution

  • Let me answer from the bottom up.

    If you tap C-h f tcl-mode RET, the help buffer says that it resides in tcl.el, pressing RET on that reveals the actual file (on my system it is /usr/share/emacs/28.1/lisp/progmodes/tcl.el.gz). If you have not installed the sources, maybe you only have its compiled version.

    There is a variable auto-mode-alist that contains associations between file names and modes. You can put something like this in your .emacs file:

    (add-to-list 'auto-mode-alist '("\\.mylang\\.tcl$" . mylang-mode))
    

    Since this puts the new mode at the beginning of the list, it will have precedence over the original tcl-mode.

    As for your main question, differentiating between real text and brace-quoted commands is just not feasible. But if you want to deactivate font-locking of if etc., that is easy enough, just modify the tcl-set-font-lock-keywords function. Deactivating it only when inside braces may be tricky, it depends on what you want. If you want the braces to behave like the double quote, that's a bit more difficult, see the tcl-syntax-propertize-function...

    On another note, you should probably use double-quoted strings for natural language, and then the whole problem disappears :) It is more natural (for those reading your code), and unless there are a lot of characters to escape, I cannot see any motivation behind using braces. (Okay, there may be some efficiency issues, but premature optimization is the root of all evil.)