From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Yuan Fu <casouri@gmail.com>
Newsgroups: gmane.emacs.devel
Subject: Propose to add setup-wizard.el to ELPA
Date: Sat, 1 Jan 2022 18:07:53 -0800
Message-ID: <897ED591-43BC-4029-912A-917E5E9F6930@gmail.com>
Mime-Version: 1.0 (Mac OS X Mail 15.0 \(3693.40.0.1.81\))
Content-Type: multipart/mixed;
 boundary="Apple-Mail=_E6A7355F-CB2D-4D03-B615-4E647C66FC4C"
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="8368"; mail-complaints-to="usenet@ciao.gmane.io"
To: Emacs developers <emacs-devel@gnu.org>
Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Sun Jan 02 03:09:21 2022
Return-path: <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>
Envelope-to: ged-emacs-devel@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>)
	id 1n3qJF-0001yM-7O
	for ged-emacs-devel@m.gmane-mx.org; Sun, 02 Jan 2022 03:09:21 +0100
Original-Received: from localhost ([::1]:45114 helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>)
	id 1n3qJD-0001Xk-EB
	for ged-emacs-devel@m.gmane-mx.org; Sat, 01 Jan 2022 21:09:19 -0500
Original-Received: from eggs.gnu.org ([209.51.188.92]:59108)
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <casouri@gmail.com>) id 1n3qHw-0000Na-N7
 for emacs-devel@gnu.org; Sat, 01 Jan 2022 21:08:00 -0500
Original-Received: from [2607:f8b0:4864:20::1034] (port=51956
 helo=mail-pj1-x1034.google.com)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <casouri@gmail.com>) id 1n3qHv-00034f-21
 for emacs-devel@gnu.org; Sat, 01 Jan 2022 21:08:00 -0500
Original-Received: by mail-pj1-x1034.google.com with SMTP id v16so26295794pjn.1
 for <emacs-devel@gnu.org>; Sat, 01 Jan 2022 18:07:58 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=from:mime-version:subject:message-id:date:to;
 bh=0qtsHZXTlCXEvBtjeNCvq9OsvBBDLX6cUT3Nryupvds=;
 b=gaTHpPnB8JHt/woMwGxdcTcO4YKzFJ7dPsKEB6E2gmaJQdfyQjJjhXERjFUxbR1UQW
 kBuXKCKCMz+SyzFug4CYTlM50XlsJojbQgxR1/GOLCmXreUAg0bSe53nmfzT+oAX3Ho1
 NhTl0RI9t0bQUjDIP9eItXNwxraYrcPUv6h51OPeevSQMYHDXvq3T2OiEfzg9+vmtxyf
 Nph4Z5GtPLPeFS4AZsl5t0WIem/GsWyOJ/p9fRNx0Z2Jk1fSOwh6e7MLo/ovEM5w2fG5
 B307RYmyQ6kJ6bW5vnsP8QF/SfNYn66KGiyTdECPZEdq96RuSlBxPbCoIFfhJWCYKqhc
 dhrg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:from:mime-version:subject:message-id:date:to;
 bh=0qtsHZXTlCXEvBtjeNCvq9OsvBBDLX6cUT3Nryupvds=;
 b=p6lML3MZ9uWbVooWbxCgYwmus0WQlwaiTESAKlS1mcbm7+Ta82/or1Xb9L6d8fQLwu
 IEYTr5gprKhdApkJbj61j+YCYq+StNU50JetFIZEiv1prgaax7O0wETU7QnXOklwGT95
 aaXLydxMPNIMVgDGnRa0VPaMxhBuMoVj0Eyu4dwMRCxa/luGY5TAHIRSt2EWFtCcTLs5
 K13zilxwj9k+cl7Dk3dhV+SBvl/l8T7p13yMHVuODnsOJWiHBkzd96EDwYoeufd+3AGx
 nzpxh/AI6MkQJc3CVHHB6Sd18Sbos0+KivvBlFJ9KFCNOhOxpOsifRvNctE4DrPC/8hu
 ZfOg==
X-Gm-Message-State: AOAM530eRD8aKkZJ+x4Z5FLyTd04jvTTWeDTWFR5uanwt/LvREl8kNWe
 +F9HPShPpCEleWslxwfnIjllPjpd/GE=
X-Google-Smtp-Source: ABdhPJxdFZYIx1NQdmJPtI0hx9Tx1nafFRIZltJdoGsuYnuBkrKa6UmSvptMA7dJPMiwwI7PMumLgg==
X-Received: by 2002:a17:903:230f:b0:149:36a2:5ea1 with SMTP id
 d15-20020a170903230f00b0014936a25ea1mr40523291plh.50.1641089277221; 
 Sat, 01 Jan 2022 18:07:57 -0800 (PST)
Original-Received: from smtpclient.apple ([2600:1700:2ec7:8c90:a095:5ec2:29e1:ba48])
 by smtp.gmail.com with ESMTPSA id 10sm34107108pfm.56.2022.01.01.18.07.56
 for <emacs-devel@gnu.org>
 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128);
 Sat, 01 Jan 2022 18:07:56 -0800 (PST)
X-Mailer: Apple Mail (2.3693.40.0.1.81)
X-Host-Lookup-Failed: Reverse DNS lookup failed for 2607:f8b0:4864:20::1034
 (failed)
Received-SPF: pass client-ip=2607:f8b0:4864:20::1034;
 envelope-from=casouri@gmail.com; helo=mail-pj1-x1034.google.com
X-Spam_score_int: 6
X-Spam_score: 0.6
X-Spam_bar: /
X-Spam_report: (0.6 / 5.0 requ) DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 RCVD_IN_DNSWL_NONE=-0.0001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001 autolearn=no autolearn_force=no
X-Spam_action: no action
X-BeenThere: emacs-devel@gnu.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Emacs development discussions." <emacs-devel.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/emacs-devel>,
 <mailto:emacs-devel-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/emacs-devel>
List-Post: <mailto:emacs-devel@gnu.org>
List-Help: <mailto:emacs-devel-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/emacs-devel>,
 <mailto:emacs-devel-request@gnu.org?subject=subscribe>
Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org
Original-Sender: "Emacs-devel"
 <emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org>
Xref: news.gmane.io gmane.emacs.devel:283843
Archived-At: <http://permalink.gmane.org/gmane.emacs.devel/283843>


--Apple-Mail=_E6A7355F-CB2D-4D03-B615-4E647C66FC4C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8

A while ago I wrote a package that helps a new user to configure Emacs: =
it takes a user through some interactive pages, where changes takes =
effect immediately; and in the end it generates some code that can be =
copied to init.el.=20

Demo for the original package: https://youtu.be/0qMskTAR2aw

I made some improvements to that package and renamed it setup-wizard. Do =
you think we could add it to ELPA? Maybe the name is too =E2=80=9Cofficial=
=E2=80=9D, in that case I can rename it to yuan=E2=80=99s-setup-wizard =
or something.

I don=E2=80=99t know how useful could it be, since nowadays every body =
(understandably) starts with some community distribution rather than =
vanilla Emacs, but surely it is better than not having a wizard.

You can try it out with emacs -q -l setup-wizard.el -f setup-wizard

Yuan


--Apple-Mail=_E6A7355F-CB2D-4D03-B615-4E647C66FC4C
Content-Disposition: attachment;
	filename=setup-wizard.el
Content-Type: application/octet-stream;
	x-unix-mode=0644;
	name="setup-wizard.el"
Content-Transfer-Encoding: quoted-printable

;;;=20setup-wizard.el=20---=20Setup=20wizard=20=20-*-=20lexical-binding:=20=
t;=20-*-=0A=0A;;=20Copyright=20(C)=202019-2020=20Free=20Software=20=
Foundation,=20Inc.=0A=0A;;=20Author:=20Yuan=20Fu=20<casouri@gmail.com>=0A=
;;=20Maintainer:=20Yuan=20Fu=20<casouri@gmail.com>=0A;;=20URL:=20=
https://github.com/casouri/setup-wizard=0A;;=20Version:=201.0.0=0A;;=20=
Keywords:=20convenience=0A;;=20Package-Requires:=20((emacs=20"26.0"))=0A=0A=
;;=20This=20file=20is=20part=20of=20GNU=20Emacs.=0A=0A;;=20GNU=20Emacs=20=
is=20free=20software:=20you=20can=20redistribute=20it=20and/or=20modify=0A=
;;=20it=20under=20the=20terms=20of=20the=20GNU=20General=20Public=20=
License=20as=20published=20by=0A;;=20the=20Free=20Software=20Foundation,=20=
either=20version=203=20of=20the=20License,=20or=0A;;=20(at=20your=20=
option)=20any=20later=20version.=0A=0A;;=20GNU=20Emacs=20is=20=
distributed=20in=20the=20hope=20that=20it=20will=20be=20useful,=0A;;=20=
but=20WITHOUT=20ANY=20WARRANTY;=20without=20even=20the=20implied=20=
warranty=20of=0A;;=20MERCHANTABILITY=20or=20FITNESS=20FOR=20A=20=
PARTICULAR=20PURPOSE.=20=20See=20the=0A;;=20GNU=20General=20Public=20=
License=20for=20more=20details.=0A=0A;;=20You=20should=20have=20received=20=
a=20copy=20of=20the=20GNU=20General=20Public=20License=0A;;=20along=20=
with=20GNU=20Emacs.=20=20If=20not,=20see=20=
<https://www.gnu.org/licenses/>.=0A=0A;;;=20Commentary:=0A;;=0A;;=20This=20=
package=20provides=20a=20setup=20wizard=20that=20takes=20a=20user=20=
through=20an=0A;;=20interactive=20interface,=20in=20which=20he=20or=20=
she=20can=20configure=20key=0A;;=20bindings=20schemes,=20UI=20elements,=20=
Fonts,=20packages,=20etc.=0A=0A;;;=20Code:=0A=0A(require=20'widget)=0A=
(require=20'wid-edit)=0A(require=20'pcase)=0A(require=20'seq)=0A(require=20=
'cl-lib)=0A=0A;;;=20Configs=0A=0A(defvar=20setup-wizard--config=20nil=0A=20=
=20"An=20alist=20(OPTION=20.=20(FORM=20COMMENT))=20of=20configurations.=0A=
We=20use=20FORM=20and=20COMMENT=20to=20produce=20the=20final=20config.")=0A=
=0A(defun=20setup-wizard--save-option-and-eval=0A=20=20=20=20(option=20=
form=20comment=20&optional=20additional)=0A=20=20"Save=20OPTION=20FORM=20=
and=20COMMENT,=20and=20evaluate=20FORM.=0AIf=20ADDITIONAL=20is=20=
non-nil,=20eval=20that=20too."=0A=20=20(when=20form=0A=20=20=20=20(setf=20=
(alist-get=20option=20setup-wizard--config)=0A=20=20=20=20=20=20=20=20=20=
=20(list=20form=20comment))=0A=20=20=20=20(eval=20form))=0A=20=20(when=20=
additional=20(eval=20additional)))=0A=0A;;;=20Pages=0A=0A(defun=20=
setup-wizard--insert=20(&rest=20args)=0A=20=20"Insert=20ARGS=20and=20=
replace=20emojis=20if=20they=20can=E2=80=99t=20be=20displayed."=0A=20=20=
(widget-insert=0A=20=20=20(mapconcat=20(lambda=20(text)=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(if=20(and=20(char-displayable-p=20=
?=F0=9F=A7=99)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(char-displayable-p=20?=F0=9F=A7=9A))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20text=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(string-replace=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20"=F0=9F=A7=9A"=20"Fairy"=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(string-replace=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"=F0=9F=A7=99"=20"Wizard"=20=
text))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20args)))=0A=0A;;;;=20=
Themes=0A=0A(defvar=20setup-wizard--c-demo=0A=20=20"=20=20=20=20#include=20=
<stdlib.h>=0A=0A=20=20=20=20struct=20point=0A=20=20=20=20{=0A=20=20=20=20=
=20=20x:=20int;=0A=20=20=20=20=20=20y:=20int;=0A=20=20=20=20};=0A=0A=20=20=
=20=20int=20main(int=20arg,=20int*=20argv)=0A=20=20=20=20{=0A=20=20=20=20=
=20=20int=20x=20=3D=20-1;=0A=20=20=20=20=20=20int=20y=20=3D=202;=0A=20=20=
=20=20=20=20void=20*buf=20=3D=20malloc(sizeof(uin32_t));=0A=20=20=20=20=20=
=20return=20add(x,=20y)=20-=203;=0A=20=20=20=20}=0A"=0A=20=20"Demo=20C=20=
code.")=0A=0A(defun=20setup-wizard--theme-page=20()=0A=20=20"Theme=20=
configuration=20page."=0A=20=20(setup-wizard--insert=0A=20=20=20"=F0=9F=A7=
=9A:=20Heya!=20You=20are=20here=20for=20help=20setting=20up=20your=20=
Emacs,=20right?=0AWizard=20will=20be=20here=20when=20you=20read=20to=20=
the=20next=20line.=0A=0A=F0=9F=A7=99:=20Emacs=20comes=20with=20a=20=
couple=20of=20themes=20built-in,=20which=20are=20shown=0Abelow.=20You=20=
can=20browse=20for=20more=20themes=20online=20or=20in=20the=20package=0A=
manager.=0A=0A=F0=9F=A7=9A:=20Here=20are=20the=20built-in=20themes!=0A=0A=
Theme=20preview:\n\n")=0A=20=20;;=20Insert=20a=20C=20demo.=0A=20=20=
(widget-insert=0A=20=20=20(with-temp-buffer=0A=20=20=20=20=20(insert=20=
setup-wizard--c-demo)=0A=20=20=20=20=20(c-mode)=0A=20=20=20=20=20=
(font-lock-fontify-region=20(point-min)=20(point-max))=0A=20=20=20=20=20=
(buffer-string)))=0A=20=20(widget-insert=20"\n")=0A=20=20;;=20Insert=20=
theme=20selection=20menu.=0A=20=20(apply=20#'widget-create=20=
'radio-button-choice=0A=20=20=20=20=20=20=20=20=20:follow-link=20t=0A=20=20=
=20=20=20=20=20=20=20:value=20"default"=0A=20=20=20=20=20=20=20=20=20;;=20=
Enable=20the=20theme=20when=20the=20user=20selects=20it.=0A=20=20=20=20=20=
=20=20=20=20:notify=20(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(mapc=20#'disable-theme=20=
custom-enabled-themes)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(let*=20((theme=20(intern=20(widget-value=20widget)))=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(form=20(if=20(eq=20theme=20'default)=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
nil=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20`(load-theme=20',theme))))=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'theme=20form=20(format=20"Load=20%s=20=
theme"=20theme))))=0A=20=20=20=20=20=20=20=20=20(cons=20'(item=20=
"default")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cl-loop=20for=20=
theme=20in=20(custom-available-themes)=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20collect=20`(item=20,(symbol-name=20=
theme)))))=0A=20=20(setup-wizard--insert=20"\n=F0=9F=A7=9A:=20Want=20to=20=
")=0A=20=20(widget-create=0A=20=20=20'push-button=0A=20=20=20:notify=20=
(lambda=20(&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
(package-refresh-contents)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
(list-packages=20t)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(goto-char=20=
(point-min))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20=
((inhibit-read-only=20t))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(keep-lines=20"-theme")))=0A=20=20=20:value=20"browse=20the=20package=20=
manager=20for=20themes")=0A=20=20(widget-insert=20"?\n"))=0A=0A;;;;=20=
Keybinding=0A=0A(defun=20setup-wizard--keybinding-page=20()=0A=20=20=
"Keybinding=20page."=0A=20=20(setup-wizard--insert=20"=F0=9F=A7=99:=20=
This=20is=20the=20notation=20for=20modifiers=20in=20Emacs:=0A=0A=20=20=20=
=20C=20(control)=20=20=20Ctrl=0A=20=20=20=20M=20(meta)=20=20=20=20=20=20=
Alt/Option=0A=20=20=20=20s=20(super)=20=20=20=20=20Windows/Command=0A=20=20=
=20=20S=20(shift)=20=20=20=20=20Shift=0A=0A=F0=9F=A7=9A:=20Which=20=
binding=20scheme=20do=20you=20like?\n\n")=0A=20=20(widget-create=20=
'radio-button-choice=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:follow-link=20t=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20"default"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20=
(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'keybinding=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(cond=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20((equal=20(widget-value=20widget)=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
"Alternative")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20'(cua-mode))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20((equal=20(widget-value=20widget)=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20"Wizard=E2=80=99=
s=20choice")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20`(progn=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(global-set-key=20(kbd=20"s-c")=20#'kill-ring-save)=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(global-set-key=20(kbd=20"s-x")=20#'kill-region)=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(global-set-key=20=
(kbd=20"s-v")=20#'yank))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20"Set=20bindings=20for=20copy/cut/paste."))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20'(item=20:value=20"Default"=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20=
"%v\n\n%d\n"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20:doc=20"=20=20=20=20M-w=20=20=20=20=20=20=20=20=20=20=20Copy=0A=
=20=20=20=20C-w=20=20=20=20=20=20=20=20=20=20=20Cut=0A=20=20=20=20C-y=20=20=
=20=20=20=20=20=20=20=20=20Paste")=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20'(item=20:value=20"Alternative"=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"%v\n\n%d\n"=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:doc=20"=20=20=20=20C-c=20=20=20=20=20=20=20=20=20=20=20Copy=0A=20=20=20=20=
C-x=20=20=20=20=20=20=20=20=20=20=20Cut=0A=20=20=20=20C-v=20=20=20=20=20=20=
=20=20=20=20=20Paste")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20'(item=20:value=20"Wizard=E2=80=99s=20choice"=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"%v\n\n%d\n"=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:doc=20"=20=20=20=20s-c=20=20=20=20=20=20=20=20=20=20=20Copy=0A=20=20=20=20=
s-x=20=20=20=20=20=20=20=20=20=20=20Cut=0A=20=20=20=20s-v=20=20=20=20=20=20=
=20=20=20=20=20Paste"))=0A=20=20(setup-wizard--insert=0A=20=20=20=
"\n=F0=9F=A7=99:=20In=20the=20alternative=20binding=20scheme,=20the=20=
binding=20for=20copy=0Aand=20cut=20only=20take=20effect=20when=20some=20=
text=20is=20selected.=20So=20when=0Anothing=20is=20selected,=20they=20=
are=20still=20normal=20prefix=20keys.\n"))=0A=0A;;;;=20UI=20features=0A=0A=
(defun=20setup-wizard--ui-features-page=20()=0A=20=20"UI=20features=20=
page."=0A=20=20(setup-wizard--insert=20"=F0=9F=A7=9A:=20What=20UI=20=
elements=20do=20you=20like?\n\n")=0A=20=20;;=20Line=20numbers.=0A=20=20=
(widget-create=20'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((val=20(widget-value=20widget)))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'line-number=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20`(global-display-line-numbers-mode=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
,(if=20val=201=20-1))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(format=20"%s=20line=20number."=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20=
val=20"Display"=20"Don=E2=80=99t=20display")))))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20:value=20nil)=0A=20=20(widget-insert=20"=20=
Line=20numbers.\n")=0A=20=20;;=20Thin=20cursor.=0A=20=20(widget-create=20=
'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:notify=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20(widget=20=
&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(let=20((val=20(widget-value=20widget)))=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
'thin-cursor=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20`(setq-default=20cursor-type=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
',(if=20val=20'bar=20t))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(format=20"Use=20%s=20cursor"=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20=
val=20"thin"=20"default")))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20:value=20nil)=0A=20=20(widget-insert=20"=20Thin=20cursor=20=
bar.\n")=0A=20=20;;=20Blink=20cursor.=0A=20=20(widget-create=20'checkbox=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:notify=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20(widget=20&rest=20_)=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((val=20=
(widget-value=20widget)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'blink-cursor=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
`(blink-cursor-mode=20,(if=20val=201=20-1))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(format=20"%s=20cursor"=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(if=20val=20"Blink"=20"Do=20not=20blink")))))=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20:value=20blink-cursor-mode)=0A=20=20=
(widget-insert=20"=20Blink=20cursor.\n")=0A=20=20;;=20Tool=20bar.=0A=20=20=
(widget-create=20'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((val=20(widget-value=20widget)))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'tool-bar=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20`(tool-bar-mode=20,(if=20val=201=20-1))=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(format=20"%s=20tool=20bar."=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20val=20"Enable"=20=
"Disable")))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20tool-bar-mode)=0A=20=20(widget-insert=20"=20Tool=20bar.\n")=0A=20=
=20;;=20Menu=20bar.=0A=20=20(widget-create=20'checkbox=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((val=20(widget-value=20=
widget)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'menu-bar=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20`(menu-bar-mode=20,(if=20val=201=20-1))=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(format=20"%s=20menu=20bar."=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20val=20"Enable"=20=
"Disable")))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20menu-bar-mode)=0A=20=20(widget-insert=20"=20Menu=20bar.\n")=0A=20=
=20;;=20Scroll=20bar.=0A=20=20(widget-create=20'checkbox=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20:notify=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((val=20(widget-value=20=
widget)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'scroll-bar=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20`(scroll-bar-mode=20,(if=20val=201=20=
-1))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(format=20"%s=20scroll=20bar"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(if=20val=20"Enable"=20=
"Disable")))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20scroll-bar-mode)=0A=20=20(widget-insert=20"=20Scroll=20bar.\n")=0A=
=20=20;;=20Font.=0A=20=20(widget-insert=20"\n")=0A=20=20(let*=20=
(default-font-field=0A=20=20=20=20=20=20=20=20=20variable-font-field=0A=20=
=20=20=20=20=20=20=20=20cjk-font-field=0A=20=20=20=20=20=20=20=20=20=
size-field=0A=20=20=20=20=20=20=20=20=20action=0A=20=20=20=20=20=20=20=20=
=20(phrase=20"The=20quick=20brown=20fox=20jumps=20over=20the=20lazy=20=
dog.\n"))=0A=20=20=20=20(widget-insert=20"Font=20preview:\n\n")=0A=20=20=20=
=20(widget-insert=20"=20=20=20=20"=20phrase)=0A=20=20=20=20=
(widget-insert=20"=20=20=20=20"=20(propertize=20phrase=20'face=20=
'variable-pitch))=0A=20=20=20=20(widget-insert=20"=20=20=20=20=
=E5=A4=A7=E6=BC=A0=E5=AD=A4=E7=83=9F=E7=9B=B4=EF=BC=8C=E9=95=BF=E6=B2=B3=E8=
=90=BD=E6=97=A5=E5=9C=86=E3=80=82\n")=0A=20=20=20=20(widget-insert=20"=20=
=20=20=20=E5=B0=84=E3=81=AF=E4=BB=81=E3=81=AE=E9=81=93=E3=81=AA=E3=82=8A=E3=
=80=82=E5=B0=84=E3=81=AF=E6=AD=A3=E3=81=97=E3=81=8D=E3=82=92=E5=B7=B1=E3=81=
=AB=E6=B1=82=E3=82=80=E3=80=82\n\n")=0A=20=20=20=20(setq=20=
default-font-field=0A=20=20=20=20=20=20=20=20=20=20(widget-create=20=
'editable-field=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20:size=2020=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20:value=20""=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"Default=20=
font:=20%v=20\n"))=0A=20=20=20=20(setq=20variable-font-field=0A=20=20=20=20=
=20=20=20=20=20=20(widget-create=20'editable-field=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:size=2020=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20""=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20:format=20"Variable-pitch=20font:=20%v=20\n"))=0A=20=20=20=
=20(setq=20cjk-font-field=0A=20=20=20=20=20=20=20=20=20=20(widget-create=20=
'editable-field=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20:size=2020=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20:value=20""=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"CJK=20font:=20=
%v=20\n"))=0A=20=20=20=20(setq=20size-field=0A=20=20=20=20=20=20=20=20=20=
=20(widget-create=20'editable-field=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20:size=202=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:value=20""=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:format=20"Font=20size:=20%v=20\n\n"))=0A=20=20=20=20(setq=20action=0A=20=
=20=20=20=20=20=20=20=20=20(lambda=20(&rest=20_)=0A=20=20=20=20=20=20=20=20=
=20=20=20=20(let*=20((default-font=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(string-trim=20(widget-value=20=
default-font-field)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(variable-font=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(string-trim=20(widget-value=20variable-font-field)))=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(cjk-font=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(string-trim=20=
(widget-value=20cjk-font-field)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(size=20(string-to-number=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(string-trim=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(widget-value=20size-field)))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20(unless=20(equal=20default-font=20"")=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20'font=20`(set-face-attribute=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
'default=20nil=20:family=20,default-font)=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20"Set=20default=20font."))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(unless=20(equal=20variable-font=20"")=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'variable-font=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(set-face-attribute=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'variable-pitch=20nil=20=
:family=20,variable-font)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20"Set=20variable-pitch=20font."))=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(unless=20(equal=20cjk-font=20"")=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20'cjk-font=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20`(dolist=20(charset=20'(kana=20han=20cjk-misc))=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(set-fontset-font=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20t=20charset=20(font-spec=20:family=20,cjk-font)))=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20"Set=20CJK=20font."))=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(unless=20(eq=20size=200)=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setup-wizard--save-option-and-eval=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'font-size=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20`(set-face-attribute=20'default=20=
nil=20:height=20,(*=20size=2010))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20"Set=20font=20size.")))))=0A=20=20=20=20(widget-create=20=
'push-button=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:value=20"Apply=20font=20settings"=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20:notify=20action)=0A=20=20=20=20(widget-insert=20=
"\n")))=0A=0A(defun=20setup-wizard--undo-page=20()=0A=20=20"Undo=20=
page."=0A=20=20(setup-wizard--insert=0A=20=20=20"=F0=9F=A7=99:=20Emacs=20=
has=20a=20powerful=20(but=20probably=20unintuitive)=20undo=20system,=0A=
where=20undo=20operations=20themselves=20are=20recorded=20in=20the=20=
undo=0Ahistory,=20and=20redo=20is=20done=20by=20undoing=20an=20previous=20=
undo=20operation.=0A=0A=F0=9F=A7=9A:=20Which=20undo=20system=20do=20you=20=
like?\n\n")=0A=20=20(widget-create=20'radio-button-choice=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20:value=20"default"=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20:follow-lint=20t=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20:notify=20(lambda=20(widget=20&rest=20_)=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(when=20(equal=20(widget-value=20widget)=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20"Linear")=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'undo=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20`(global-set-key=20[remap=20undo]=20#'undo-only)=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
"Use=20linear=20undo=20style.")))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20'(item=20:value=20"Default"=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"%v\n\n%d\n"=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:doc=20"=20=
=20=20=20One=20undo=20rules=20them=20all")=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20'(item=20:value=20"Linear"=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"%v\n\n%d\n"=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
:doc=20"=20=20=20=20Undo=20and=20redo"))=0A=20=20(let=20(undo-key=20=
redo-key)=0A=20=20=20=20(widget-insert=20"\n")=0A=20=20=20=20(setq=20=
undo-key=0A=20=20=20=20=20=20=20=20=20=20(widget-create=20=
'editable-field=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20:size=205=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20:value=20"C-/"=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:format=20"Bind=20undo=20=
to:=20%v=20"))=0A=20=20=20=20(widget-create=20'push-button=0A=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:value=20"Apply"=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:notify=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20(&rest=20_)=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(let=20((key=20=
(string-trim=20(widget-value=20undo-key))))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20'undo-key=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(global-set-key=20(kbd=20=
,key)=20#'undo)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20"Set=20binding=20for=20=E2=80=98undo=E2=80=99."))))=0A=20=20=
=20=20(widget-insert=20"\n")=0A=20=20=20=20(setq=20redo-key=0A=20=20=20=20=
=20=20=20=20=20=20(widget-create=20'editable-field=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:size=205=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:value=20=
"C-?"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20:format=20"Bind=20redo=20to:=20%v=20"))=0A=20=20=20=20=
(widget-create=20'push-button=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20:value=20"Apply"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(lambda=20(&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20(let=20((key=20(string-trim=20(widget-value=20=
redo-key))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'undo-key=0A=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(global-set-key=20=
(kbd=20,key)=20#'undo-redo)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20"Set=20binding=20for=20=E2=80=98undo-redo=E2=80=
=99."))))=0A=20=20=20=20(setup-wizard--insert=20"\n\n=F0=9F=A7=99:=20I=20=
bind=20redo=20to=20C-.\n")))=0A=0A;;;;=20Extra=20package=0A=0A(defun=20=
setup-wizard--package-activate=20(package=20mode)=0A=20=20"Return=20a=20=
form=20that=20activates=20PACKAGE=20and=20enable=20MODE."=0A=20=20=
`(progn=0A=20=20=20=20=20(require=20'package)=0A=20=20=20=20=20(unless=20=
(package-installed-p=20',package)=0A=20=20=20=20=20=20=20=
(package-install=20',package))=0A=20=20=20=20=20(package-activate=20=
'ivy)=0A=20=20=20=20=20(require=20',package)=0A=20=20=20=20=20(,mode)))=0A=
=0A(defun=20setup-wizard--package-page=20()=0A=20=20"Extra=20package=20=
page."=0A=20=20(setup-wizard--insert=0A=20=20=20"=F0=9F=A7=99:=20Here=20=
are=20some=20packages=20that=20I=20always=20install:\n\n")=0A=20=20;;=20=
Ivy.=0A=20=20(widget-create=20'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20(let=20((val=20(widget-value=20widget)))=0A=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'ivy=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20(when=20val=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(progn=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
,(setup-wizard--package-activate=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'ivy=20'ivy-mode)=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setq=20enable-recursive-minibuffers=20t=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
ivy-use-selectable-prompt=20t=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
ivy-use-virtual-buffers=20t)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20,(setup-wizard--package-activate=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20'counsel=20'counsel-mode)))=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20"Install=20and=20enable=20=
=E2=80=98ivy-mode=E2=80=99=20and=20=E2=80=98counsel-mode=E2=80=99."=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20`(progn=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(ivy-mode=20,(if=20val=201=20-1))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(counsel-mode=20,(if=20val=201=20=
-1))))))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:value=20=
nil)=0A=20=20(widget-insert=0A=20=20=20"=20Ivy:=20A=20completion=20=
package=20that=20makes=20typing=20file=20names,=20buffer=0Anames,=20=
commands,=20etc=20so=20much=20easier.\n")=0A=20=20;;=20Company=0A=20=20=
(widget-create=20'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((val=20(widget-value=20widget)))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'company=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(setup-wizard--package-activate=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20'company=20=
'company-mode)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20"Install=20and=20enable=20=E2=80=98company-mode=E2=80=99."=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
`(company-mode=20,(if=20val=201=20-1)))))=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20:value=20nil)=0A=20=20(widget-insert=0A=20=20=20"=20=
Company:=20Popup=20completion=20menu=20when=20writing=20programs.\n")=0A=20=
=20(widget-create=20'checkbox=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20:notify=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(lambda=20(widget=20&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(let=20((val=20(widget-value=20widget)))=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--save-option-and-eval=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20'electric-pair-mode=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(when=20val=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
`(electric-pair-mode))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20"Enable=20=E2=80=98electric-pair-mode=E2=80=99."=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
`(electric-pair-mode=20,(if=20val=201=20-1)))))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20:value=20nil)=0A=20=20(widget-insert=0A=20=20=20=
"=20Electric-pair-mode=20(built-in):=20Automatically=20closes=20=
parenthesis\n")=0A=20=20(setup-wizard--insert=20"\n=F0=9F=A7=99:=20=
...\n\n")=0A=20=20(setup-wizard--insert=20"=F0=9F=A7=99:=20I=20don=E2=80=99=
t=20use=20many=20packages.\n"))=0A=0A;;;=20Guide=0A=0A(defun=20=
setup-wizard--with-boilerplate=0A=20=20=20=20(setup-fn=20&optional=20=
page-list=20finish-fn)=0A=20=20"Call=20page=20setup=20function=20=
SETUP-FN=20with=20widget=20boilerplate.=0APAGE-LIST=20is=20a=20list=20of=20=
setup=20function=20for=20pages=20to=20show=20in=20a=0Aseries.=20=
FINISH-FN=20is=20called=20when=20user=20clicks=20the=20finish=20button.=0A=
If=20PAGE-LIST=20or=20FINISH-FN=20are=20nil,=20don=E2=80=99t=20insert=20=
navigation=0Abuttons."=0A=20=20(kill-all-local-variables)=0A=20=20(let=20=
((inhibit-read-only=20t))=0A=20=20=20=20(erase-buffer))=0A=20=20=
(remove-overlays)=0A=20=20(funcall=20setup-fn)=0A=20=20(widget-insert=20=
"\n")=0A=20=20(when=20(and=20page-list=20finish-fn)=0A=20=20=20=20=
(setup-wizard--insert-step-buttons=20setup-fn=20page-list=20finish-fn))=0A=
=20=20(use-local-map=20widget-keymap)=0A=20=20(widget-setup)=0A=20=20=
(goto-char=20(point-min))=0A=20=20(local-set-key=20(kbd=20"q")=20=
#'setup-wizard--quit))=0A=0A(defun=20setup-wizard--quit=20(&rest=20_)=0A=20=
=20"Quite=20the=20wizard."=0A=20=20(interactive)=0A=20=20(kill-buffer)=0A=
=20=20(message=20(with-temp-buffer=0A=20=20=20=20=20=20=20=20=20=20=20=20=
=20(setup-wizard--insert=20"=F0=9F=A7=9A:=20See=20ya!")=0A=20=20=20=20=20=
=20=20=20=20=20=20=20=20(buffer-string))))=0A=0A(defun=20=
setup-wizard--insert-step-buttons=20(page=20page-list=20finish-fn)=0A=20=20=
"Insert=20buttons=20that=20go=20to=20previous=20and=20next=20page=20of=20=
PAGE.=0APAGE-LIST=20is=20a=20list=20of=20setup=20function=20for=20pages=20=
to=20show=20in=20a=20series.=0AInsert=20a=20Button=20that=20calls=20=
FINISH-FN=20at=20the=20last=20page."=0A=20=20(let*=20((idx=20=
(seq-position=20page-list=20page))=0A=20=20=20=20=20=20=20=20=20=
(previous-page=20(if=20(eq=20idx=200)=20nil=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(nth=20(1-=20idx)=20=
page-list)))=0A=20=20=20=20=20=20=20=20=20(next-page=20(nth=20(1+=20idx)=20=
page-list)))=0A=20=20=20=20(setup-wizard--insert=0A=20=20=20=20=20=
(format=20"=F0=9F=A7=9A:=20We=20are=20at=20step=20%s/%s,=20what=E2=80=99s=20=
next?=20"=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(1+=20idx)=20(length=20=
page-list)))=0A=20=20=20=20(when=20previous-page=0A=20=20=20=20=20=20=
(widget-create=0A=20=20=20=20=20=20=20'push-button=0A=20=20=20=20=20=20=20=
:notify=20(lambda=20(&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(setup-wizard--with-boilerplate=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20previous-page=20page-list=20finish-fn))=0A=20=20=
=20=20=20=20=20:value=20"Back"))=0A=20=20=20=20(widget-insert=20"=20")=0A=
=20=20=20=20(if=20next-page=0A=20=20=20=20=20=20=20=20(widget-create=0A=20=
=20=20=20=20=20=20=20=20'push-button=0A=20=20=20=20=20=20=20=20=20=
:notify=20(lambda=20(&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(setup-wizard--with-boilerplate=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20next-page=20page-list=20=
finish-fn))=0A=20=20=20=20=20=20=20=20=20:value=20"Next")=0A=20=20=20=20=20=
=20(widget-create=0A=20=20=20=20=20=20=20'push-button=0A=20=20=20=20=20=20=
=20:notify=20(lambda=20(&rest=20_)=20(funcall=20finish-fn))=0A=20=20=20=20=
=20=20=20:value=20"Finish"))=0A=20=20=20=20(widget-insert=20"=20")=0A=20=20=
=20=20(widget-create=0A=20=20=20=20=20'push-button=0A=20=20=20=20=20=
:value=20"Quit"=0A=20=20=20=20=20:notify=20#'setup-wizard--quit)=0A=20=20=
=20=20(widget-insert=20"\n")))=0A=0A(defun=20setup-wizard--insert-config=20=
()=0A=20=20"Insert=20configuration=20in=20=E2=80=98setup-wizard--config=E2=
=80=99=20line-by-line."=0A=20=20(dolist=20(config=20(reverse=20=
setup-wizard--config))=0A=20=20=20=20(insert=20";;=20"=20(nth=202=20=
config)=20"\n")=0A=20=20=20=20(dolist=20(conf=20(if=20(eq=20(car=20(nth=20=
1=20config))=20'progn)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20(cdr=20(nth=201=20config))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20(list=20(nth=201=20config))))=0A=20=20=20=
=20=20=20(insert=20(prin1-to-string=20conf)=20"\n"))))=0A=0A(defun=20=
setup-wizard--finish=20()=0A=20=20"The=20default=20finish=20function.=0A=
Constructs=20the=20config=20and=20display=20them."=0A=20=20=
(setup-wizard--with-boilerplate=0A=20=20=20(lambda=20()=0A=20=20=20=20=20=
(setup-wizard--insert=0A=20=20=20=20=20=20"=F0=9F=A7=9A:=20Here=20is=20=
your=20configuration!=20Do=20you=20want=20me=20to=20append=20it=20to=0A=
init.el=20for=20you?=20")=0A=20=20=20=20=20(widget-create=20'push-button=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20:notify=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(lambda=20=
(&rest=20_)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20(let=20((init-file=20(locate-user-emacs-file=0A=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20"init.el"=20".emacs")))=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(find-file=20init-file)=0A=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(goto-char=20(point-max))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20(insert=20"\n")=0A=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
(setup-wizard--insert-config)))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20:value=20"Append=20to=20init.el")=0A=20=20=20=20=20=
(widget-insert=20"\n\n")=0A=20=20=20=20=20(widget-insert=0A=20=20=20=20=20=
=20(with-temp-buffer=0A=20=20=20=20=20=20=20=20=
(setup-wizard--insert-config)=0A=20=20=20=20=20=20=20=20=
(emacs-lisp-mode)=0A=20=20=20=20=20=20=20=20(font-lock-fontify-region=20=
(point-min)=20(point-max))=0A=20=20=20=20=20=20=20=20=
(buffer-string))))))=0A=0A(defun=20setup-wizard=20()=0A=20=20"Run=20the=20=
setup=20wizard."=0A=20=20(interactive)=0A=20=20(switch-to-buffer=20=
(get-buffer-create=20"*mage=20tower*"))=0A=20=20(setq=20=
setup-wizard--config=20nil)=0A=20=20(let=20((page-list=20=
'(setup-wizard--theme-page=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20setup-wizard--keybinding-page=0A=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20setup-wizard--ui-features-page=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
setup-wizard--undo-page=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20setup-wizard--package-page)))=0A=20=20=20=20=
(setup-wizard--with-boilerplate=0A=20=20=20=20=20(car=20page-list)=20=
page-list=0A=20=20=20=20=20#'setup-wizard--finish)))=0A=0A;;;=20Backport=0A=
=0A(unless=20(fboundp=20'undo--last-change-was-undo-p)=0A=20=20(defun=20=
undo--last-change-was-undo-p=20(undo-list)=0A=20=20=20=20(while=20(and=20=
(consp=20undo-list)=20(eq=20(car=20undo-list)=20nil))=0A=20=20=20=20=20=20=
(setq=20undo-list=20(cdr=20undo-list)))=0A=20=20=20=20(gethash=20=
undo-list=20undo-equiv-table)))=0A=0A(unless=20(fboundp=20'undo-redo)=0A=20=
=20(defun=20undo-redo=20(&optional=20arg)=0A=20=20=20=20"Undo=20the=20=
last=20ARG=20undos."=0A=20=20=20=20(interactive=20"*p")=0A=20=20=20=20=
(cond=0A=20=20=20=20=20((not=20(undo--last-change-was-undo-p=20=
buffer-undo-list))=0A=20=20=20=20=20=20(user-error=20"No=20undo=20to=20=
undo"))=0A=20=20=20=20=20(t=0A=20=20=20=20=20=20(let*=20((ul=20=
buffer-undo-list)=0A=20=20=20=20=20=20=20=20=20=20=20=20=20(new-ul=0A=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20(let=20((undo-in-progress=20t))=0A=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20(while=20(and=20(consp=20=
ul)=20(eq=20(car=20ul)=20nil))=0A=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20(setq=20ul=20(cdr=20ul)))=0A=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20(primitive-undo=20arg=20ul)))=0A=20=20=20=20=20=20=20=20=20=
=20=20=20=20(new-pul=20(undo--last-change-was-undo-p=20new-ul)))=0A=20=20=
=20=20=20=20=20=20(message=20"Redo%s"=20(if=20undo-in-region=20"=20in=20=
region"=20""))=0A=20=20=20=20=20=20=20=20(setq=20this-command=20'undo)=0A=
=20=20=20=20=20=20=20=20(setq=20pending-undo-list=20new-pul)=0A=20=20=20=20=
=20=20=20=20(setq=20buffer-undo-list=20new-ul))))))=0A=0A(unless=20=
(fboundp=20'undo-only)=0A=20=20(defun=20undo-only=20(&optional=20arg)=0A=20=
=20=20=20"Undo=20some=20previous=20changes.=0ARepeat=20this=20command=20=
to=20undo=20more=20changes.=0AA=20numeric=20ARG=20serves=20as=20a=20=
repeat=20count.=0AContrary=20to=20`undo',=20this=20will=20not=20redo=20a=20=
previous=20undo."=0A=20=20=20=20(interactive=20"*p")=0A=20=20=20=20(let=20=
((undo-no-redo=20t))=20(undo=20arg))))=0A=0A(provide=20'setup-wizard)=0A=0A=
;;;=20setup-wizard.el=20ends=20here=0A=

--Apple-Mail=_E6A7355F-CB2D-4D03-B615-4E647C66FC4C--