{"action":"created","issue":{"url":"https://api.github.com/repos/jwiegley/use-package/issues/813","repository_url":"https://api.github.com/repos/jwiegley/use-package","labels_url":"https://api.github.com/repos/jwiegley/use-package/issues/813/labels{/name}","comments_url":"https://api.github.com/repos/jwiegley/use-package/issues/813/comments","events_url":"https://api.github.com/repos/jwiegley/use-package/issues/813/events","html_url":"https://github.com/jwiegley/use-package/issues/813","id":537232996,"node_id":"MDU6SXNzdWU1MzcyMzI5OTY=","number":813,"title":"Implementing :validate-custom using validate.el (feedback please)","user":{"login":"xenodium","id":8107219,"node_id":"MDQ6VXNlcjgxMDcyMTk=","avatar_url":"https://avatars0.githubusercontent.com/u/8107219?v=4","gravatar_id":"","url":"https://api.github.com/users/xenodium","html_url":"https://github.com/xenodium","followers_url":"https://api.github.com/users/xenodium/followers","following_url":"https://api.github.com/users/xenodium/following{/other_user}","gists_url":"https://api.github.com/users/xenodium/gists{/gist_id}","starred_url":"https://api.github.com/users/xenodium/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xenodium/subscriptions","organizations_url":"https://api.github.com/users/xenodium/orgs","repos_url":"https://api.github.com/users/xenodium/repos","events_url":"https://api.github.com/users/xenodium/events{/privacy}","received_events_url":"https://api.github.com/users/xenodium/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2019-12-12T21:51:22Z","updated_at":"2019-12-18T13:09:29Z","closed_at":null,"author_association":"NONE","body":"### Goal\r\n\r\nTo implement **:validate-custom** keyword (same as **:custom**, but backed by [validate.el](https://github.com/Malabarba/validate.el) validation).\r\n\r\nI seem to have an initial implementation. I could really use some feedback/guidance. Spot flaws? Potential improvements? \r\n\r\n### Background\r\n\r\nI'm a fan of [validate.el](https://github.com/Malabarba/validate.el). It enforces schema validation when setting custom variables, automatically surfacing incompatibilities (often overlooked), specially when upgrading packages.\r\n\r\nGreat posts about validate.el by @manuel-uberti and @Malabarba \r\n\r\nhttps://manuel-uberti.github.io/emacs/2016/09/17/validate\r\nhttps://endlessparentheses.com/validate-el-schema-validation-for-emacs-lisp.html\r\n\r\nI'm also a fan of use-package's **:custom** keyword, enabling declarative package configurations.\r\n\r\nI'd like to combine **:custom**-style configuration with [validate.el](https://github.com/Malabarba/validate.el) validation. Read on for potential implementation.\r\n\r\n### Usage\r\n\r\n```\r\n(use-package magit\r\n  :ensure t\r\n  :validate-custom\r\n  (magit-diff-refine-hunk 'all)\r\n  (magit-status-margin '(t \"%Y-%m-%d %H:%M \" magit-log-margin-width t 18)))\r\n```\r\n\r\n### Potential implementation\r\n\r\n```\r\n(use-package validate\r\n  :ensure t\r\n  :config\r\n  (defmacro validate-customize-set-variable (variable value &optional comment)\r\n    \"Like `customize-set-variable', but throw an error if validation fails.\r\nVALUE is validated against SYMBOL's custom type.\r\n\r\n\\(fn [SYM VAL] ...)\"\r\n    `(if (boundp ,variable)\r\n         (customize-set-variable ,variable (validate-value ,value (custom-variable-type ,variable)) ,comment)\r\n       (user-error \"Trying to validate a variable that's not defined yet: `%s'.\\nYou need to require the package before validating\" ,variable)))\r\n\r\n  (setq use-package-keywords\r\n        (use-package-list-insert :validate-custom\r\n                                 use-package-keywords\r\n                                 :load t))\r\n\r\n  (defun use-package-normalize/:validate-custom (_name keyword args)\r\n    \"Normalize use-package validate-custom keyword.\"\r\n    (use-package-as-one (symbol-name keyword) args\r\n      #'(lambda (label arg)\r\n          (unless (listp arg)\r\n            (use-package-error\r\n             (concat label \" a (<symbol> <value> [comment])\"\r\n                     \" or list of these\")))\r\n          (if (use-package-non-nil-symbolp (car arg))\r\n              (list arg)\r\n            arg))))\r\n\r\n  (defun use-package-handler/:validate-custom (name _keyword args rest state)\r\n    \"Generate use-package validate-custom keyword code.\"\r\n    (use-package-concat\r\n     (mapcar\r\n      #'(lambda (def)\r\n          (let ((variable (nth 0 def))\r\n                (value (nth 1 def))\r\n                (comment (nth 2 def)))\r\n            (unless (and comment (stringp comment))\r\n              (setq comment (format \"Customized with use-package %s\" name)))\r\n            `(validate-customize-set-variable (quote ,variable) ,value ,comment)))\r\n      args)\r\n     (use-package-process-keywords name rest state))))\r\n```"},"comment":{"url":"https://api.github.com/repos/jwiegley/use-package/issues/comments/567024424","html_url":"https://github.com/jwiegley/use-package/issues/813#issuecomment-567024424","issue_url":"https://api.github.com/repos/jwiegley/use-package/issues/813","id":567024424,"node_id":"MDEyOklzc3VlQ29tbWVudDU2NzAyNDQyNA==","user":{"login":"a13","id":251267,"node_id":"MDQ6VXNlcjI1MTI2Nw==","avatar_url":"https://avatars3.githubusercontent.com/u/251267?v=4","gravatar_id":"","url":"https://api.github.com/users/a13","html_url":"https://github.com/a13","followers_url":"https://api.github.com/users/a13/followers","following_url":"https://api.github.com/users/a13/following{/other_user}","gists_url":"https://api.github.com/users/a13/gists{/gist_id}","starred_url":"https://api.github.com/users/a13/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/a13/subscriptions","organizations_url":"https://api.github.com/users/a13/orgs","repos_url":"https://api.github.com/users/a13/repos","events_url":"https://api.github.com/users/a13/events{/privacy}","received_events_url":"https://api.github.com/users/a13/received_events","type":"User","site_admin":false},"created_at":"2019-12-18T13:09:29Z","updated_at":"2019-12-18T13:09:29Z","author_association":"NONE","body":"What a nice idea!\r\n\r\nIMO it is not necessary to add an additional keyword here, all we need is a defcustom with a name like `use-package-custom-use-validate` or smth like that, to let people choose "}}
{"actor":{"display_login":"a13"}}