;; A major mode for editing task sheets.  -*- lexical-binding: nil; -*-
;;
;; Usage for your Emacs initialization file:
;;
;;    (require 'task-sheet-mode)
;;    (add-to-list 'auto-mode-alist '("[./]task$" . task-sheet-mode))
;;
;; PUBLIC at `http://reluk.ca/sys/computer/workstation/etc/emacs/` because my Emacs initialization
;; file refers to it there.  http://reluk.ca/.emacs.d/lisp/initialization.el


(define-derived-mode task-sheet-mode fundamental-mode
  "task-sheet"
  "Major mode for editing task sheets"

  (defconst task-sheet-font-lock-keywords-a
    (list
     '("^/.*$"                                   ;  /   · ···     Completed
       . font-lock-comment-face)
     '("^ *\\(/\\) \\(.*\\)$"                    ;    / · ···     Ignored
       (1 font-lock-string-face) (2 font-lock-comment-face))
     '("^ *// .*$"                               ;    // ···      Reason for ignoring
       . font-lock-string-face))
     "High priority rules")
  (defconst task-sheet-font-lock-keywords-filter
    (list
     '("^ *\\([.]\\) \\(.*\\)$"                  ;    . · ···     Filter
       (1 'font-lock-string-face) (2 font-lock-comment-face)))
     "Filter rules")
  (defconst task-sheet-font-lock-keywords-b
    (list
     '("\\(?:[=!?] \\)?\\(.*\\)\\(`\\)$"  ;             ··· `     Section title
       (1 font-lock-keyword-face) (2 'task-sheet-subdued-face))
     '("^\\(?:  [ .] \\)*\\(\\[\\)\\( .*\\)$"    ;      [ ···     Component
       (1 'task-sheet-subdued-face) (2 font-lock-type-face))


     '("^\\(?:  [ .] \\)*\\(-\\) "               ;      - ···     Generic phrase
       1 'task-sheet-subdued-face)
     '("^\\(?:  [ .] \\)*\\(=\\).*? \\(.*\\)$"   ;      = ···     Command
       (1 'task-sheet-subdued-face) (2 font-lock-function-name-face))
     '("^\\(?:  [ .] \\)*\\(\\+\\).*? \\(.*\\)$" ;      + ···     Special
       (1 'task-sheet-subdued-face) (2 font-lock-constant-face))
     '("^\\(?:  [ .] \\)*\\(\\*\\).*? \\(.*\\)$" ;      * ···     Special
       (1 'task-sheet-subdued-face) (2 'task-sheet-special-face))


     '("^\\(?:  [ .] \\)*\\([?!]\\).*? \\(.*\\)$" ;      ? ···     Doubt
       (1 'task-sheet-subdued-face) (2 font-lock-warning-face))


     '("^\\(?:  [ .] \\)*\\((\\) \\(.*\\)$"      ;      ( ···     Aside
       (1 'task-sheet-subdued-face) (2 font-lock-comment-face))
     '("^ *<.*$"                                 ;      <···      Aside, pointed
       . 'task-sheet-subdued-face))
     "All other rules")

  ;; Font lock decoration levels.
  ;; These essentially turn filter decorations off or on (default).
  ;; Use font-lock-decoration-toggle to switch between them.
  (defconst task-sheet-font-lock-keywords-0
    (append
     task-sheet-font-lock-keywords-a
     task-sheet-font-lock-keywords-b
     nil) ; Last item, not copied like those above, so using dummy [better use the *list* function instead]
    "Disables filter decorations")
  (defconst task-sheet-font-lock-keywords-1
    (append
     task-sheet-font-lock-keywords-a
     task-sheet-font-lock-keywords-filter
     task-sheet-font-lock-keywords-b)
    "Normal decorations")

  (make-local-variable 'font-lock-defaults)
  (setq font-lock-defaults
        '(
          (task-sheet-font-lock-keywords-0
           task-sheet-font-lock-keywords-1)
          t)))



;; You will want to customize these faces.  The defaults below are not very good.
;; Working example of customization: http://reluk.ca/.Xresources
(defface task-sheet-special-face
  '((((type tty pc) (class color) (background light)) (:foreground "red"))
    (((type tty pc) (class color) (background dark)) (:foreground "red1"))
    (((class grayscale) (background light)) (:foreground "DimGray" :bold t :italic t))
    (((class grayscale) (background dark)) (:foreground "LightGray" :bold t :italic t))
    (((class color) (background light)) (:foreground "rgb:FF/00/00"))
    (((class color) (background dark)) (:foreground "rgb:FF/00/00"))
    (t (:bold t :italic t)))
  "Task sheet face for special '*' lines."
  :group 'faces)



(defface task-sheet-subdued-face
  `((default . (:inherit init/subdued)))
  "The face for noisy symbolic clutter that needs subduing."
  :group 'faces)



(provide 'task-sheet-mode)