Automatically Update to Dynamic Grammar


Part of the package I am developing [] requires that the user can change part of the grammar by editing their settings. I’ve got it mostly working by loading in the CSON grammar file by hand and passing it to an instance of a new Grammar. This way, whenever the user changes a setting by using config.observe, I can remove the current grammar and add a brand new one. Problem is that if the user already has a todo file open, the grammar of that specific file isn’t re-run.

Is there a way to force re-activation of a grammar via code? Or a better way to add/remove a changing grammar?

Semantic highlighting
Dynamic Grammers
Defining a language grammar via code
Syntax highlighting using existing tokenizer
ShadowDom breaks dynamic grammar
Getting an abstract syntax tree of a Java code
Tokenizing process
Marker decorations that add style classes to the actual text nodes?

If your package does what I think it does, i.e. highlights TODO comments inside code of various languages, you should take a look at the Language Hyperlink package which highlights hyperlinks inside comments of source code, or when encountered in text files. Perhaps you could just do this with a simple grammar?


It actually does a bit more than that package. It handles special syntax hightlighting for .todo and .taskpaper files, which are plain text todo lists! The idea is that each line is marked as a task or a list and they can be completed, cancelled, and archived to make it easier to keep track of what’s going on. Since the actual way that each line is marked (either with a ☐, :heavy_check_mark:, or ✘ by default) can be changed in the settings, I want to be able to refresh the actual grammar on the fly. I’ve got that part working, but I can’t get it to refresh for the actively open files. You have to re-choose the syntax as tasks in order to update the highlighting.


Ok, was able to get the result I needed! After removing the old grammar, updating to the new one, I can run:

atom.workspaceView.eachEditorView (editorView) ->
  path = editorView.getEditor().getPath()
  if path.indexOf('.todo')>-1 or path.indexOf('.taskpaper')>-1

Which will loop through all open files and if they are of the given types, reload their grammar.