 	  (and (or (null (car elem)) (eq (car elem) major-mode))
 	       (or (null (cadr elem))
 		   (string-match (cadr elem) buffer-file-name))
-	       (setq tab-width (caddr elem)
-		     indent-tabs-mode (cadddr elem)
+	       (setq tab-width (cl-caddr elem)
+		     indent-tabs-mode (cl-cadddr elem)
 		     alist nil))))))
 
+
+;;;===========================================================================
+;;;  CC-mode languages
+;;;===========================================================================
+
+(defvar antlr-c-language-mode-name "C")
+(defvar antlr-cpp-language-mode-name "Cpp")
+(defvar antlr-objc-language-mode-name "ObjC")
+
+(defvar antlr-c-action-mode 'c-mode)
+(defvar antlr-cpp-action-mode 'c++-mode)
+(defvar antlr-objc-action-mode 'objc-mode)
+
+(defvar antlr-c-init-cc-mode 'c-mode)
+(defvar antlr-cpp-init-cc-mode 'c++-mode)
+(defvar antlr-obj-init-cc-mode 'objc-mode)
+
+(defvar antlr-cpp-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    c++-font-lock-keywords-1 c++-font-lock-keywords-2
+    c++-font-lock-keywords-3))
+(defvar antlr-c-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    c-font-lock-keywords-1 c-font-lock-keywords-2
+    c-font-lock-keywords-3))
+(defvar antlr-objc-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    objc-font-lock-keywords-1 objc-font-lock-keywords-2
+    objc-font-lock-keywords-3))
+
+
+;;;===========================================================================
+;;;  JavaScript
+;;;===========================================================================
+
+(defvar antlr-js-language-mode-name "Js")
+
+(defvar antlr-js-action-mode 'js-mode)
+
+(defvar antlr-js-init-submode 'antlr-init-js)
+
+(defvar antlr-js-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    ;; do not use `js--font-lock-keywords-3' !
+    js--font-lock-keywords-1 js--font-lock-keywords-2))
+
+(defvar antlr-js-indent-action-line 'antlr-js-indent-action-line)
+
+(defun antlr-init-js ()
+  (require 'js))
+
+(defun antlr-js-indent-action-line (_bos)
+  (js-indent-line))
+
+
+;;;===========================================================================
+;;;  Delphi (opascal)
+;;;===========================================================================
+
+(defvar antlr-delphi-language-mode-name "Delphi")
+
+(defvar antlr-delphi-action-mode 'opascal-mode)
+
+(defvar antlr-delphi-init-submode 'antlr-init-delphi)
+
+(defvar antlr-delphi-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    opascal-font-lock-keywords))
+
+(defvar antlr-delphi-indent-action-line 'antlr-delphi-indent-action-line)
+
+(defun antlr-init-delphi ()
+  (require 'opascal)
+  (when (integerp c-basic-offset)
+    (when (equal opascal-compound-block-indent opascal-indent-level)
+      (setq-local opascal-compound-block-indent c-basic-offset))
+    (when (equal opascal-case-label-indent opascal-indent-level)
+      (setq-local opascal-case-label-indent c-basic-offset))
+    (setq-local opascal-indent-level c-basic-offset)))
+
+(defun antlr-delphi-indent-action-line (bos)
+  (narrow-to-region (1+ bos) (point-at-eol))
+  ;; make Pascal mode only checks the code fragment after the opening brace,
+  ;; otherwise its indentation gets confused as {...} are block comments
+  (opascal-indent-line)
+  ;; or use low-level `opascal-corrected-indentation' - but that does not have
+  ;; a docstring, i.e. not really official ?
+  (widen)
+  (unless (memq (char-after (point-at-bol)) '(?\ ?\t))
+    ;; no indentation -> considered top-level -> indentation can also be
+    ;; performed by c-cmode
+    (c-indent-line)))
+
+
+;;;===========================================================================
+;;;  Ruby
+;;;===========================================================================
+
+(defvar antlr-ruby-language-mode-name "Ruby")
+
+(defvar antlr-ruby-action-mode 'ruby-mode)
+
+(defvar antlr-ruby-init-submode 'antlr-init-ruby)
+
+(defvar antlr-ruby-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    ruby-font-lock-keywords))
+
+(defvar antlr-ruby-indent-action-line 'antlr-ruby-indent-action-line)
+
+(defun antlr-init-ruby ()
+  (require 'ruby-mode)
+  (setq-local ruby-indent-level c-basic-offset)
+  ;; Disable smie as long as we do not have a function for a part of
+  ;; `ruby-mode-variables'
+  (setq-local ruby-use-smie nil))
+
+(defun antlr-ruby-indent-action-line (bos)
+  (narrow-to-region (1+ bos) (point-at-eol))
+  (ruby-indent-line)
+  (widen)
+  (unless (memq (char-after (point-at-bol)) '(?\ ?\t))
+    ;; no indentation -> considered top-level -> indentation can also be
+    ;; performed by cc-mode
+    (c-indent-line)))
+
+
+;;;===========================================================================
+;;;  Python
+;;;===========================================================================
+
+(defvar antlr-python-language-mode-name "Python")
+
+(defvar antlr-python-action-mode 'python-mode)
+
+(defvar antlr-python-action-font-lock-keywords
+  '(antlr-no-action-keywords
+    python-font-lock-keywords))
+
+(defvar antlr-python-indent-action-line 'antlr-python-indent-action-line)
+
+(defvar antlr-python-init-submode 'antlr-init-python)
+
+(defun antlr-init-python ()
+  (require 'python))
+
+(defun antlr-python-indent-action-line (bos)
+  (let (leftouter)
+    (save-excursion
+      (goto-char bos)
+      (setq leftouter (current-indentation))
+      (forward-char)
+      (skip-chars-forward " \t")
+      (setq bos (and (eq (char-after) ?\n) (point))))
+    ;; a multi-line Python action does not start in its own line: this is a bad
+    ;; idea -> we do not touch those actions
+    (when (and bos
+               (eq antlr-indent-comment t) ; indent-region
+               (boundp 'prog-indentation-context)) ; Emacs 24.5 or later
+      (let ((syntax-ppss-cache nil) ;#dynamic
+            (syntax-ppss-last nil) ;#dynamic
+            ;; TODO: do we also need to call `syntax-propertize'?
+            ;; and/or bind `syntax-propertize-function'?
+            (prog-indentation-context ;#dynamic
+             (list (+ leftouter c-basic-offset) (list (1+ bos)))))
+        (narrow-to-region (1+ bos) (point-max))
+        (python-indent-line (eq this-command 'antlr-indent-command))))))
+
+
 (provide 'antlr-mode)
-
-;;; Local IspellPersDict: .ispell_antlr
-
 ;;; antlr-mode.el ends here


(defvar antlr-font-lock-defaults
  '(antlr-font-lock-keywords
    nil nil ((?_ . "w") (?\( . ".") (?\) . ".")))
  "Font-lock defaults used for ANTLR syntax highlighting.
The SYNTAX-ALIST element is also used to initialize
`antlr-action-syntax-table'.")


;;;===========================================================================

  "Insert Makefile rules in the current buffer at point.
IN-MAKEFILE is non-nil, if the current buffer is the Makefile.  See
command `antlr-show-makefile-rules' for detail."
  (let* ((dirname default-directory)
	 (deps0 (antlr-directory-dependencies dirname))
	 (classes (car deps0))		; CLASS -> (FILE . EVOCAB) ...
	 (deps (cdr deps0))		; FILE -> (c . s) (ev . iv) . LANGUAGE
	 (with-error nil)
	 (gen-sep (or (cl-caddr (cadr antlr-makefile-specification)) " "))
	 (n (and (cdr deps) (cadr antlr-makefile-specification) 0)))
    (or in-makefile (set-buffer standard-output))
    (dolist (dep deps)
      (let ((supers (cl-cdadr dep))
	    (lang (cdr (assoc (cl-cdddr dep) antlr-file-formats-alist))))
	(if n (cl-incf n))
	(antlr-makefile-insert-variable n "" " =")
	(if supers
	    (insert " "
		    (format (cadr antlr-special-file-formats)
			    (file-name-sans-extension (car dep)))))
	(dolist (class-def (cl-caadr dep))
	  (let ((sep gen-sep))
	    (dolist (class-file (cadr lang))
	      (insert sep (format class-file (car class-def)))
	      (setq sep " "))))
	(dolist (evocab (cl-caaddr dep))
	  (let ((sep gen-sep))
	    (dolist (vocab-file (cons (car antlr-special-file-formats)
				      (car lang)))
