This document describes usage of the uim-custom API and facility for
developers.


* Abstract

* Design basics and decisions

* How to define your own customs

* How to reflect defined customs into your IM code

  To acquire a defined custom in your IM, describe as following in the
  your IM file.

    (require-custom "your-custom.scm")

  Don't use ordinary 'require' to load a custom file. The
  require-custom performs per-user configuration loading and reload
  management, but ordinary 'require' does not.

  "-custom" suffix of the filename is only a convention and not
  required. But we recommend the naming convention to manage the files
  easily.


* Invoke an arbitrary procedure when a custom variable has been set

  The feature is usable via the hook named 'custom-set-hooks'. See
  following example.

  (custom-add-hook 'anthy-input-mode-actions
                   'custom-set-hooks
                   (lambda ()
                     (puts "anthy-input-mode-actions has been set\n")
                     (anthy-configure-widgets)))

  Any procedure that takes no argument can be placed into the third
  argument to custom-add-hook. The procedure will be invoked when the
  custom variable anthy-input-mode-actions has been set. Interprocess
  custom variable update via uim-helper-server also triggers this
  hook. So some variables edited on uim-pref will be propagated to any
  processes and invokes the hook on the fly.

  For example, dynamic file switching can be triggered by uim-pref
  using following hook.

  (custom-add-hook 'skk-dic-file-name
                   'custom-set-hooks
                   skk-reload-dic)

  There are some limitations for the set-hook feature.

  - Runtime version of the custom facility (custom-rt.scm) only
    accepts at most one hook per custom variable (full-featured
    version can handle multiple hooks)

  - Custom API enabled only in full-featured version (custom.scm)
    cannot be invoked in the hook procedure.

    Enclose such code into conditional block as follows. This ensures
    that custom-rt.scm ignores the hook.

    (if custom-full-featured?
        (custom-add-hook 'anthy-kana-input-method-actions
                         'custom-set-hooks
                         (lambda ()
                           (custom-choice-range-reflect-olist-val
                            'default-widget_anthy_kana_input_method
                            'anthy-kana-input-method-actions
                            anthy-kana-input-method-indication-alist))))


* Control activity of a custom variable

  Any custom variables has a state named 'activity'. This state
  indicates whether the value set in the custom variable makes sense
  or not. The state should be reflected to value editability of the
  corresponding widget on preference tools. i.e. Use
  gtk_widget_set_sensitive() for the corresponding widget to reflect
  the state.

  To control activity of a custom variable, configure the hook for the
  custom variable. Otherwise all custom variables are always active.


  Example1: Simple activity

  Following example shows that the custom variable
  my-frequently-used-string1 is active only when username is
  "yamaken". The third argument of custom-add-hook can be any
  predicate to indicate whether the custom variable is active or
  inactive.

  The activity is tested by the predicate when:

  - The custom variable has been acquired by uim_custom_get().

  - Invoking custom-active? explicitly

  - Any custom variable has been set. See next example for further
    information

  (define-custom 'my-frequently-used-string1 "I'm hungry! Give me some sweets."
    '(my-private)
    '(string)
    (_ "My frequently used string 1")
    (_ "long description will be here."))

  (custom-add-hook 'my-frequently-used-string1
                   'custom-activity-hooks
                   (lambda ()
                     (string=? (getenv "USER")
                               "yamaken")))


  Example2: Dynamic activity update reflecting other custom variable

  The activity alters when other custom variables have been set.

  In following example, segment-separator will be active only when
  show-segment-separator? is true. The activity will be changed
  automatically and noticed to client of uim-custom via callback for
  the segment-separator previously set immediately after new value of
  show-segment-separator? has been set.

  The predicate will be evaluated when any of custom variables have
  been set (changing to different value is not required). So you can
  place any flexible predicate as the third argument for the
  custom-add-hook.

  All activity predicates will be evaluated and noticed via
  corresponding callback when any of custom variables has been set.

  No group relationships including subgrouping is not required to set
  variable relationships.

  (define-custom 'show-segment-separator? #f
    '(foo)
    '(boolean)
    (_ "Show segment separator")
    (_ "long description will be here."))

  (define-custom 'segment-separator "|"
    '(bar)
    '(string ".*")
    (_ "Segment separator")
    (_ "long description will be here."))

  (custom-add-hook 'segment-separator
                   'custom-activity-hooks
                   (lambda ()
                     show-segment-separator?))
