375 lines
13 KiB
EmacsLisp
375 lines
13 KiB
EmacsLisp
|
|
(require 'eieio)
|
|||
|
|
(require 'polymode-core)
|
|||
|
|
|
|||
|
|
;;; ROOT CLASS
|
|||
|
|
(if (fboundp 'eieio-named)
|
|||
|
|
(progn
|
|||
|
|
(defclass pm-root (eieio-instance-inheritor eieio-named)
|
|||
|
|
((-props
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation "Internal. Used to store various user
|
|||
|
|
history values. Use `pm--prop-get' and `pm--prop-put' to
|
|||
|
|
place key value pairs into this list."))
|
|||
|
|
"Root polymode class.")
|
|||
|
|
|
|||
|
|
;; bug #22840
|
|||
|
|
(defmethod clone ((obj eieio-named) &rest params)
|
|||
|
|
"Clone OBJ, initializing `:parent' to OBJ.
|
|||
|
|
All slots are unbound, except those initialized with
|
|||
|
|
PARAMS."
|
|||
|
|
(let* ((newname (and (stringp (car params)) (pop params)))
|
|||
|
|
(nobj (apply #'call-next-method obj params))
|
|||
|
|
(nm (slot-value obj 'object-name)))
|
|||
|
|
(eieio-oset nobj 'object-name
|
|||
|
|
(or newname
|
|||
|
|
(save-match-data
|
|||
|
|
(if (and nm (string-match "-\\([0-9]+\\)" nm))
|
|||
|
|
(let ((num (1+ (string-to-number
|
|||
|
|
(match-string 1 nm)))))
|
|||
|
|
(concat (substring nm 0 (match-beginning 0))
|
|||
|
|
"-" (int-to-string num)))
|
|||
|
|
(concat nm "-1")))))
|
|||
|
|
nobj)))
|
|||
|
|
|
|||
|
|
(defclass pm-root (eieio-instance-inheritor)
|
|||
|
|
((-props
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation "Internal. Plist used to store various extra
|
|||
|
|
metadata such as user history. Use `pm--prop-get' and
|
|||
|
|
`pm--prop-put' to place key value pairs into this list."))
|
|||
|
|
"Root polymode class."))
|
|||
|
|
|
|||
|
|
;;; CONFIG
|
|||
|
|
(defclass pm-polymode (pm-root)
|
|||
|
|
((hostmode
|
|||
|
|
:initarg :hostmode
|
|||
|
|
:initform 'pm-host/blank
|
|||
|
|
:type symbol
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Symbol pointing to an object of class pm-chunkmode
|
|||
|
|
representing the host chunkmode.")
|
|||
|
|
(minor-mode
|
|||
|
|
:initarg :minor-mode
|
|||
|
|
:initform 'polymode-minor-mode
|
|||
|
|
:type symbol
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Symbol pointing to minor-mode function that should be
|
|||
|
|
activated in all buffers (base and indirect). This is a
|
|||
|
|
\"glue\" mode and is `polymode-minor-mode' by default. You
|
|||
|
|
will rarely need to change this.")
|
|||
|
|
(lighter
|
|||
|
|
:initarg :lighter
|
|||
|
|
:initform " PM"
|
|||
|
|
:type string
|
|||
|
|
:custom string
|
|||
|
|
:documentation "Modline lighter.")
|
|||
|
|
(exporters
|
|||
|
|
:initarg :exporters
|
|||
|
|
:initform '(pm-exporter/pandoc)
|
|||
|
|
:type list
|
|||
|
|
:custom list
|
|||
|
|
:documentation
|
|||
|
|
"List of names of polymode exporters available for this polymode.")
|
|||
|
|
(exporter
|
|||
|
|
:initarg :exporter
|
|||
|
|
:initform nil
|
|||
|
|
:type (or null symbol)
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Current exporter name. If non-nil should be the name of the
|
|||
|
|
default exporter for this polymode. Can be set with
|
|||
|
|
`polymode-set-exporter' command.")
|
|||
|
|
(weavers
|
|||
|
|
:initarg :weavers
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:custom list
|
|||
|
|
:documentation
|
|||
|
|
"List of names of polymode weavers available for this polymode.")
|
|||
|
|
(weaver
|
|||
|
|
:initarg :weaver
|
|||
|
|
:initform nil
|
|||
|
|
:type (or null symbol)
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Current weaver name. If non-nil this is the default weaver
|
|||
|
|
for this polymode. Can be dynamically set with
|
|||
|
|
`polymode-set-weaver'")
|
|||
|
|
(map
|
|||
|
|
:initarg :map
|
|||
|
|
:initform 'polymode-mode-map
|
|||
|
|
:type (or symbol list)
|
|||
|
|
:documentation
|
|||
|
|
"Has a similar role as the :keymap argument in
|
|||
|
|
`define-polymode' with the difference that this argument is
|
|||
|
|
inherited through cloning, but :keymap argument is not. That
|
|||
|
|
is, child objects derived through clone will inherit
|
|||
|
|
the :map argument of its parents through the following
|
|||
|
|
scheme: if :map is nil or an alist of keys, the parent is
|
|||
|
|
inspected for :map argument and the keys are merged
|
|||
|
|
recursively from parent to parent till a symbol :map slot is
|
|||
|
|
met. If :map is a symbol, it must be a keymap, in which case
|
|||
|
|
this keymap is used and no parents are further inspected
|
|||
|
|
for :map slot. If :map is an alist it must be suitable for
|
|||
|
|
`easy-mmode-define-keymap'.")
|
|||
|
|
(init-functions
|
|||
|
|
:initarg :init-functions
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation
|
|||
|
|
"List of functions to run at the initialization time.
|
|||
|
|
All init-functions in the inheritance chain are called. Parents
|
|||
|
|
hooks first. So, if current config object C inherits from object
|
|||
|
|
B, which in turn inherits from object A. Then A's init-functions
|
|||
|
|
are called first, then B's and then C's.
|
|||
|
|
Either customize this slot or use `object-add-to-list' function.")
|
|||
|
|
(switch-buffer-functions
|
|||
|
|
:initarg :switch-buffer-functions
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation
|
|||
|
|
"List of functions to run at polymode buffer switch.
|
|||
|
|
Each function is run with two arguments, OLD-BUFFER and
|
|||
|
|
NEW-BUFFER.")
|
|||
|
|
|
|||
|
|
(-hostmode
|
|||
|
|
:type (or null pm-chunkmode)
|
|||
|
|
:documentation
|
|||
|
|
"Dynamically populated `pm-chunkmode' object.")
|
|||
|
|
(-innermodes
|
|||
|
|
:type list
|
|||
|
|
:initform '()
|
|||
|
|
:documentation
|
|||
|
|
"Dynamically populated list of chunkmodes objects that
|
|||
|
|
inherit from `pm-hbtchunkmode'.")
|
|||
|
|
(-buffers
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation
|
|||
|
|
"Holds all buffers associated with current buffer. Dynamically populated."))
|
|||
|
|
|
|||
|
|
"Configuration for a polymode. Each polymode buffer contains a local
|
|||
|
|
variable `pm/polymode' instantiated from this class or a subclass
|
|||
|
|
of this class.")
|
|||
|
|
|
|||
|
|
(defclass pm-polymode-one (pm-polymode)
|
|||
|
|
((innermode
|
|||
|
|
:initarg :innermode
|
|||
|
|
:type symbol
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Symbol of the chunkmode. At run time this object is cloned
|
|||
|
|
and placed in -innermodes slot."))
|
|||
|
|
|
|||
|
|
"Configuration for a simple polymode that allows only one
|
|||
|
|
innermode. For example noweb.")
|
|||
|
|
|
|||
|
|
(defclass pm-polymode-multi (pm-polymode)
|
|||
|
|
((innermodes
|
|||
|
|
:initarg :innermodes
|
|||
|
|
:type list
|
|||
|
|
:custom list
|
|||
|
|
:initform nil
|
|||
|
|
:documentation
|
|||
|
|
"List of names of the chunkmode objects that are associated
|
|||
|
|
with this configuration. At initialization time, all of
|
|||
|
|
these are cloned and plased in -innermodes slot."))
|
|||
|
|
|
|||
|
|
"Configuration for a polymode that allows multiple (known in
|
|||
|
|
advance) innermodes.")
|
|||
|
|
|
|||
|
|
(defclass pm-polymode-multi-auto (pm-polymode-multi)
|
|||
|
|
((auto-innermode
|
|||
|
|
:initarg :auto-innermode
|
|||
|
|
:type symbol
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Name of pm-hbtchunkmode-auto object (a symbol). At run time
|
|||
|
|
this object is cloned and placed in -auto-innermodes with
|
|||
|
|
coresponding :mode slot initialized at run time.")
|
|||
|
|
(-auto-innermodes
|
|||
|
|
:type list
|
|||
|
|
:initform '()
|
|||
|
|
:documentation
|
|||
|
|
"List of chunkmode objects that are auto-generated in
|
|||
|
|
`pm-get-span' method for this class."))
|
|||
|
|
|
|||
|
|
"Configuration for a polymode that allows multiple innermodes
|
|||
|
|
that are not known in advance. Examples are org-mode and markdown.")
|
|||
|
|
|
|||
|
|
|
|||
|
|
;;; CHUNKMODE CLASSES
|
|||
|
|
(defclass pm-chunkmode (pm-root)
|
|||
|
|
((mode :initarg :mode
|
|||
|
|
:type symbol
|
|||
|
|
:initform nil
|
|||
|
|
:custom symbol)
|
|||
|
|
(protect-indent-line :initarg :protect-indent-line
|
|||
|
|
:type boolean
|
|||
|
|
:initform t
|
|||
|
|
:custom boolean
|
|||
|
|
:documentation
|
|||
|
|
"Whether to modify local `indent-line-function' by narrowing
|
|||
|
|
to current span first")
|
|||
|
|
(indent-offset :initarg :indent-offset
|
|||
|
|
:type integer
|
|||
|
|
:initform 0
|
|||
|
|
:documentation
|
|||
|
|
"Offset to add when indenting chunk's line. Takes effect only
|
|||
|
|
when :protect-indent-line is non-nil.")
|
|||
|
|
(font-lock-narrow :initarg :font-lock-narrow
|
|||
|
|
:type boolean
|
|||
|
|
:initform t
|
|||
|
|
:documentation
|
|||
|
|
"Whether to narrow to span during font lock")
|
|||
|
|
(adjust-face :initarg :adjust-face
|
|||
|
|
:type (or number face list)
|
|||
|
|
:custom (or number face list)
|
|||
|
|
:initform nil
|
|||
|
|
:documentation
|
|||
|
|
"Fontification adjustments chunk face. It should be either,
|
|||
|
|
nil, number, face or a list of text properties as in
|
|||
|
|
`put-text-property' specification. If nil no highlighting
|
|||
|
|
occurs. If a face, use that face. If a number, it is a
|
|||
|
|
percentage by which to lighten/darken the default chunk
|
|||
|
|
background. If positive - lighten the background on dark
|
|||
|
|
themes and darken on light thems. If negative - darken in
|
|||
|
|
dark thems and lighten in light thems.")
|
|||
|
|
(init-functions
|
|||
|
|
:initarg :init-functions
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation
|
|||
|
|
"List of functions to called after the initialization of chunkmode has finished.
|
|||
|
|
Functions are called the buffer associated with this
|
|||
|
|
chunkmode. All init-functions in the inheritance chain are
|
|||
|
|
called. Parents hooks first. So, if current config object C
|
|||
|
|
inherits from object B, which in turn inherits from object
|
|||
|
|
A. Then A's init-functions are called first, then B's and
|
|||
|
|
then C's. Either customize this slot or use
|
|||
|
|
`object-add-to-list' function.")
|
|||
|
|
(switch-buffer-functions
|
|||
|
|
:initarg :switch-buffer-functions
|
|||
|
|
:initform '()
|
|||
|
|
:type list
|
|||
|
|
:documentation
|
|||
|
|
"List of functions to run at polymode buffer switch.
|
|||
|
|
Each function is run with two arguments, OLD-BUFFER and
|
|||
|
|
NEW-BUFFER. In contrast to identically named slot in
|
|||
|
|
`pm-polymode' class, these functions are run only when
|
|||
|
|
NEW-BUFFER is associated with this chunkmode.")
|
|||
|
|
|
|||
|
|
(-buffer
|
|||
|
|
:type (or null buffer)
|
|||
|
|
:initform nil))
|
|||
|
|
|
|||
|
|
"Representatioin of a generic chunkmode object.")
|
|||
|
|
|
|||
|
|
(defclass pm-bchunkmode (pm-chunkmode)
|
|||
|
|
()
|
|||
|
|
"Representation of the body-only chunkmodes. Body-only
|
|||
|
|
chunkmodes are commonly used as host modes. For example for a
|
|||
|
|
the web-mdoe the hostmode is `html-mode', for nowweb mode the
|
|||
|
|
host mode is usually `latex-mode', etc.")
|
|||
|
|
|
|||
|
|
(defclass pm-hbtchunkmode (pm-chunkmode)
|
|||
|
|
((head-mode
|
|||
|
|
:initarg :head-mode
|
|||
|
|
:type symbol
|
|||
|
|
:initform 'poly-head-tail-mode
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Chunk's header mode. If set to 'body, the head is considered
|
|||
|
|
part of the chunk body. If set to 'host, head is considered
|
|||
|
|
part of the surrounding host mode.")
|
|||
|
|
(tail-mode
|
|||
|
|
:initarg :tail-mode
|
|||
|
|
:type symbol
|
|||
|
|
:initform nil
|
|||
|
|
:custom symbol
|
|||
|
|
:documentation
|
|||
|
|
"Chunk's tail mode. If nil, or 'head, the mode is picked
|
|||
|
|
from :HEAD-MODE slot. If set to 'body, the tail's mode is the
|
|||
|
|
same as chunk's body mode. If set to 'host, the mode will be
|
|||
|
|
of the parent host.")
|
|||
|
|
|
|||
|
|
(head-reg
|
|||
|
|
:initarg :head-reg
|
|||
|
|
:initform ""
|
|||
|
|
:type (or string symbol)
|
|||
|
|
:custom (or string symbol)
|
|||
|
|
:documentation "Regexp for the chunk start (aka head), or a
|
|||
|
|
function returning the start and end positions of the head.
|
|||
|
|
See `pm--default-matcher' for an example function.")
|
|||
|
|
(tail-reg
|
|||
|
|
:initarg :tail-reg
|
|||
|
|
:initform ""
|
|||
|
|
:type (or string symbol)
|
|||
|
|
:custom (or string symbol)
|
|||
|
|
:documentation "Regexp for chunk end (aka tail), or a
|
|||
|
|
function returning the start and end positions of the tail.
|
|||
|
|
See `pm--default-matcher' for an example function.")
|
|||
|
|
|
|||
|
|
(adjust-face
|
|||
|
|
:initform 2)
|
|||
|
|
(head-adjust-face
|
|||
|
|
:initarg :head-adjust-face
|
|||
|
|
:initform font-lock-type-face
|
|||
|
|
:type (or null number face list)
|
|||
|
|
:custom (or null number face list)
|
|||
|
|
:documentation
|
|||
|
|
"Can be a number, list or face.")
|
|||
|
|
(tail-adjust-face
|
|||
|
|
:initarg :tail-adjust-face
|
|||
|
|
:initform nil
|
|||
|
|
:type (or null number face list)
|
|||
|
|
:custom (or null number face list)
|
|||
|
|
:documentation
|
|||
|
|
"Can be a number, list or face. If nil, take the
|
|||
|
|
configuration from :head-adjust-face.")
|
|||
|
|
|
|||
|
|
(-head-buffer
|
|||
|
|
:type (or null buffer)
|
|||
|
|
:initform nil
|
|||
|
|
:documentation
|
|||
|
|
"This buffer is set automatically to -buffer if :head-mode is
|
|||
|
|
'body, and to base-buffer if :head-mode is 'host")
|
|||
|
|
(-tail-buffer
|
|||
|
|
:initform nil
|
|||
|
|
:type (or null buffer)))
|
|||
|
|
|
|||
|
|
"Representation of an inner Head-Body-Tail chunkmode.")
|
|||
|
|
|
|||
|
|
(defclass pm-hbtchunkmode-auto (pm-hbtchunkmode)
|
|||
|
|
((retriever-regexp :initarg :retriever-regexp
|
|||
|
|
:type (or null string)
|
|||
|
|
:custom string
|
|||
|
|
:initform nil
|
|||
|
|
:documentation
|
|||
|
|
"Regexp that is used to retrive the modes symbol from the
|
|||
|
|
head of the chunkmode chunk. fixme: elaborate")
|
|||
|
|
(retriever-num :initarg :retriever-num
|
|||
|
|
:type integer
|
|||
|
|
:custom integer
|
|||
|
|
:initform 1
|
|||
|
|
:documentation
|
|||
|
|
"Subexpression to be matched by :retriver-regexp")
|
|||
|
|
(retriever-function :initarg :retriever-function
|
|||
|
|
:type symbol
|
|||
|
|
:custom symbol
|
|||
|
|
:initform nil
|
|||
|
|
:documentation
|
|||
|
|
"Function symbol used to retrive the modes symbol from the
|
|||
|
|
head of the chunkmode chunk. It is called with no arguments
|
|||
|
|
with the point positioned at the beginning of the chunk
|
|||
|
|
header. It must return the mode name string or symbol (need
|
|||
|
|
not include '-mode' postfix).)"))
|
|||
|
|
|
|||
|
|
"Representation of an inner chunkmode")
|
|||
|
|
|
|||
|
|
(provide 'polymode-classes)
|