From: Yuan Fu <casouri@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Po Lu <luangruo@yahoo.com>, Jean Louis <bugs@gnu.support>,
emacs-devel@gnu.org
Subject: Re: Propose to add setup-wizard.el to ELPA
Date: Sun, 9 Jan 2022 14:54:37 -0800 [thread overview]
Message-ID: <64131FC6-A19E-41B5-B636-CD6544140E59@gmail.com> (raw)
In-Reply-To: <83ee5j68z9.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 145 bytes --]
Ok, I retro-fitted setup-wizard.el to use custom. It works, but more black-boxy and IMO not very pretty. I don’t know if I like it.
Yuan
[-- Attachment #2: setup-wizard.el --]
[-- Type: application/octet-stream, Size: 24358 bytes --]
;;; setup-wizard.el --- Setup wizard -*- lexical-binding: t; -*-
;; Copyright (C) 2019-2020 Free Software Foundation, Inc.
;; Author: Yuan Fu <casouri@gmail.com>
;; Maintainer: Yuan Fu <casouri@gmail.com>
;; URL: https://github.com/casouri/setup-wizard
;; Version: 1.0.0
;; Keywords: convenience
;; Package-Requires: ((emacs "26.0"))
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;;
;; This package provides a setup wizard that takes a user through an
;; interactive interface, in which he or she can configure key
;; bindings schemes, UI elements, Fonts, packages, etc.
;;; Code:
(require 'widget)
(require 'wid-edit)
(require 'pcase)
(require 'seq)
(require 'cl-lib)
;;; Widgets
(define-widget 'setup-wizard-number-field 'editable-field
"Editable field but for numbers."
:valid-regexp
(rx (seq (? (or "-" "+"))
(* digit) (? ".") (* digit)
(? (seq "e" (+ digit)))))
:value-to-internal
(lambda (widget val)
(number-to-string val))
:value-get
(lambda (widget)
(string-to-number (widget-field-value-get widget))))
;;; Custom
(defvar setup-wizard-super-copy-paste-mode-map
(make-sparse-keymap)
"Keymap for ‘setup-wizard-super-copy-paste-mode’.")
(define-minor-mode setup-wizard-super-copy-paste-mode
"Use super as the modifier for cut, copy and paste."
:global t
:group 'setup-wizard
(if setup-wizard-super-copy-paste-mode
(progn
(keymap-global-set "s-c" #'kill-ring-save)
(keymap-global-set "s-x" #'kill-region)
(keymap-global-set "s-v" #'yank))
;; Global map doesn’t have a parent, but using REMOVE is
;; semantically correct (see ‘keymap-unset’ for REMOVE).
(keymap-global-unset "s-c" t)
(keymap-global-unset "s-x" t)
(keymap-global-unset "s-v" t)))
(define-minor-mode setup-wizard-linear-undo-mode
"Use linear undo system."
:global t
:group 'setup-wizard
(if setup-wizard-linear-undo-mode
(global-set-key [remap undo] #'undo-only)
(global-unset-key [remap undo])))
(defun setup-wizard--set-magic-variable (symbol value)
"Magically make VALUE of the magic variable SYMBOL take effect.
If VALUE is nil, do nothing."
(when value
(pcase symbol
;; Theme.
('setup-wizard-theme-magic
;; Don’t disable other themes, just load the theme.
(when (not (eq value 'default))
(load-theme value)))
;; Font.
('setup-wizard-font-magic
(set-face-attribute 'default nil :family value))
('setup-wizard-variable-font-magic
(set-face-attribute 'variable-pitch nil :family value))
('setup-wizard-cjk-font
(dolist (charset '(kana han cjk-misc))
(set-fontset-font t charset (font-spec :family value))))
('setup-wizard-font-size-magic
(when (> value 0)
(set-face-attribute
'variable-pitch nil :height (* 10 value)))))))
(defgroup setup-wizard nil
"A wizard that helps you setup Emacs."
:group 'convenience)
(defcustom setup-wizard-theme-magic nil
"A magic variable that sets themes."
:type 'string
:set #'setup-wizard--set-magic-variable)
;; Why not use custom faces? Custom faces requires you to define the
;; whole face, which isn’t what we want to do here.
(defcustom setup-wizard-font-magic nil
"A magic variable that sets the default font."
:type 'string
:set #'setup-wizard--set-magic-variable)
(defcustom setup-wizard-variable-font-magic nil
"A magic variable that sets the variable font."
:type 'string
:set #'setup-wizard--set-magic-variable)
(defcustom setup-wizard-cjk-font-magic nil
"A magic variable that sets the CJK font."
:type 'string
:set #'setup-wizard--set-magic-variable)
(defcustom setup-wizard-font-size-magic nil
"A magic variable that sets the font size."
:type 'integer
:set #'setup-wizard--set-magic-variable)
(defun setup-wizard--save-option
(symbol exp &optional now request comment)
"Save custom option SYMBOL to EXP with NOW, REQUEST and COMMENT.
If EXP is nil, this function is a no-op."
(custom-set-variables `(,symbol ',exp ,now ,request ,comment))
(setup-wizard--set-magic-variable symbol exp))
;;; Pages
(defun setup-wizard--char-displayable-p (char)
"Return non-nil if we can display CHAR."
;; Per manual, ‘char-displayable-p’ may return non-nil even when
;; there is no font available, since it also checks whether the
;; coding system for the text terminal can encode the character.
;;
;; ASCII characters are always displayable.
(cond ((< char 128)
t)
;; Maybe there's a font for it, but we can't put it in the
;; buffer.
((not enable-multibyte-characters)
nil)
(t (when-let ((font-glyph (internal-char-font nil char)))
(if (consp font-glyph)
;; On a window system, a character is displayable
;; if a font for that character is in the default
;; face of the currently selected frame.
(car font-glyph)
;; On a text terminal supporting glyph codes, CHAR is
;; displayable if its glyph code is nonnegative.
(<= 0 font-glyph))))))
(defun setup-wizard--insert (&rest args)
"Insert ARGS and replace emojis if they can’t be displayed."
(widget-insert
(mapconcat (lambda (text)
(if (and (setup-wizard--char-displayable-p ?🧙)
(setup-wizard--char-displayable-p ?🧚))
text
(string-replace
"🧚" "Fairy"
(string-replace
"🧙" "Wizard" text))))
args)))
;;;; Themes
(defvar setup-wizard--c-demo
" #include <stdlib.h>
struct point
{
x: int;
y: int;
};
int main(int arg, int* argv)
{
int x = -1;
int y = 2;
void *buf = malloc(sizeof(uin32_t));
return add(x, y) - 3;
}
"
"Demo C code.")
(defun setup-wizard--theme-page ()
"Theme configuration page."
(setup-wizard--insert
"🧚: Heya! You are here for help setting up your Emacs, right?
Wizard will be here when you read to the next line.
🧙: Emacs comes with a couple of themes built-in, which are shown
below. You can browse for more themes online or in the package
manager.
🧚: Here are the built-in themes!
Theme preview:\n\n")
;; Insert a C demo.
(widget-insert
(with-temp-buffer
(insert setup-wizard--c-demo)
(c-mode)
(font-lock-fontify-region (point-min) (point-max))
(buffer-string)))
(widget-insert "\n")
;; Insert theme selection menu.
(apply #'widget-create 'radio-button-choice
:follow-link t
:value "default"
;; Enable the theme when the user selects it.
:notify (lambda (widget &rest _)
;; First disable other themes.
(dolist (theme custom-enabled-themes)
(disable-theme theme))
;; Enable the theme.
(let* ((theme (intern (widget-value widget))))
(setup-wizard--save-option
'setup-wizard-theme-magic theme)))
(cons '(item "default")
(cl-loop for theme in (custom-available-themes)
collect `(item ,(symbol-name theme)))))
(setup-wizard--insert "\n🧚: Want to ")
(widget-create
'push-button
:notify (lambda (&rest _)
(package-refresh-contents)
(list-packages t)
(goto-char (point-min))
(let ((inhibit-read-only t))
(keep-lines "-theme")))
:value "browse the package manager for themes")
(widget-insert "?\n"))
;;;; Key binding
(defun setup-wizard--keybinding-page ()
"Keybinding page."
(setup-wizard--insert "🧙: This is the notation for modifiers in Emacs:
C (control) Ctrl
M (meta) Alt/Option
s (super) Windows/Command
S (shift) Shift
🧚: Which binding scheme do you like?\n\n")
(widget-create 'radio-button-choice
:follow-link t
:value "Default"
:notify
(lambda (widget &rest _)
(cua-mode -1)
(setup-wizard-super-copy-paste-mode -1)
(pcase (widget-value widget)
("Alternative"
(setup-wizard--save-option
'cua-mode t nil nil
"This enables the Alternative binding scheme"))
("Utilize the super key"
(setup-wizard--save-option
'setup-wizard-super-copy-paste-mode t))))
'(item :value "Default"
:format "%v\n\n%d\n"
:doc " M-w Copy
C-w Cut
C-y Paste")
'(item :value "Alternative"
:format "%v\n\n%d\n"
:doc " C-c Copy
C-x Cut
C-v Paste")
'(item :value "Utilize the super key"
:format "%v\n\n%d\n"
:doc " s-c Copy
s-x Cut
s-v Paste"))
(setup-wizard--insert
"\n🧙: In the alternative binding scheme, the binding for copy
and cut only take effect when some text is selected. So when
nothing is selected, they are still normal prefix keys.\n"))
;;;; UI features
(defun setup-wizard--ui-features-page ()
"UI features page."
(setup-wizard--insert "🧚: What UI elements do you like?\n\n")
;; Line numbers.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'global-display-line-numbers-mode val)))
:value global-display-line-numbers-mode)
(widget-insert " Line numbers.\n")
;; Thin cursor.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'cursor-type (if val 'bar t))))
:value (eq cursor-type 'bar))
(widget-insert " Thin cursor bar.\n")
;; Blink cursor.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'blink-cursor-mode val)))
:value blink-cursor-mode)
(widget-insert " Blink cursor.\n")
;; ‘hl-line’.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'global-hl-line-mode val)))
:value global-hl-line-mode)
(widget-insert " Highlight current line.\n")
;; Tool bar.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'tool-bar-mode val)))
:value tool-bar-mode)
(widget-insert " Tool bar.\n")
;; Menu bar.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'menu-bar-mode val)))
:value menu-bar-mode)
(widget-insert " Menu bar.\n")
;; Scroll bar.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'scroll-bar-mode val)))
:value scroll-bar-mode)
(widget-insert " Scroll bar.\n")
;; Tab width
(let ((width (widget-create 'setup-wizard-number-field
:size 2
:value tab-width
:format "%v Tab width ")))
(widget-create 'push-button
:value "Apply"
:notify (lambda (&rest _)
(let ((val (widget-value width)))
(unless (eq val 0)
(setup-wizard--save-option
'tab-width val)))))
(widget-insert "\n"))
;; Font.
(widget-insert "\n")
(let* (default-font
variable-font
cjk-font
font-size
action
(phrase "The quick brown fox jumps over the lazy dog.\n"))
(widget-insert "Font preview:\n\n")
(widget-insert " " phrase)
(widget-insert " " (propertize phrase 'face 'variable-pitch))
(widget-insert " 大漠孤烟直,长河落日圆。射は正しきを己に求む。\n\n")
(setq default-font
(widget-create 'editable-field
:size 20
:value ""
:format "Default font: %v \n"))
(setq variable-font
(widget-create 'editable-field
:size 20
:value ""
:format "Variable-pitch font: %v \n"))
(setq cjk-font
(widget-create 'editable-field
:size 20
:value ""
:format "CJK font: %v \n"))
(setq font-size
(widget-create 'setup-wizard-number-field
:size 2
:value 0
:format "Font size: %v \n\n"))
(setq action
(lambda (&rest _)
(let* ((default-font (widget-value default-font))
(variable-font (widget-value variable-font))
(cjk-font (widget-value cjk-font))
(font-size (widget-value font-size)))
(unless (equal default-font "")
(setup-wizard--save-option
'setup-wizard-font-magic default-font))
(unless (equal variable-font "")
(setup-wizard--save-option
'setup-wizard-variable-font-magic variable-font))
(unless (equal cjk-font "")
(setup-wizard--save-option
'setup-wizard-cjk-font-magic cjk-font))
(unless (<= font-size 0)
(setup-wizard--save-option
'setup-wizard-font-size-magic font-size)))))
(widget-create 'push-button
:value "Apply font settings"
:notify action)
(widget-insert "\n")))
;;;; Undo
(defun setup-wizard--undo-page ()
"Undo page."
(setup-wizard--insert
"🧙: Emacs has a powerful (but probably unintuitive) undo system,
where undo operations themselves are recorded in the undo
history, and redo is done by undoing an previous undo operation.
🧚: Which undo system do you like?\n\n")
(widget-create 'radio-button-choice
:value "Default"
:follow-lint t
:notify (lambda (widget &rest _)
(let ((val (widget-value widget)))
(pcase val
("Linear"
(setup-wizard--save-option
'setup-wizard-linear-undo-mode t))
("Default"
(setup-wizard--save-option
'setup-wizard-linear-undo-mode nil)))))
'(item :value "Default"
:format "%v\n\n%d\n"
:doc " One undo rules them all")
'(item :value "Linear"
:format "%v\n\n%d\n"
:doc " Undo and redo")))
;;;; Extra package
(defun setup-wizard--package-activate (package)
"Install and activate PACKAGE."
(require 'package)
(unless (package-installed-p package)
(package-install package))
(package-activate package)
(require package))
(defun setup-wizard--package-page ()
"Extra package page."
(setup-wizard--insert
"🧙: Here are some packages that I always install:
(🧚: They will be automatically installed from Internet. That
might take a while!)\n\n")
;; Ivy.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--package-activate 'ivy)
(setup-wizard--package-activate 'counsel)
(custom-set-variables
`(enable-recursive-minibuffers
,val nil nil "Recommended by Wizard for ivy.")
`(ivy-use-selectable-prompt
,val nil nil "Recommended by Wizard for ivy")
`(ivy-use-virtual-buffers
,val nil nil "Recommended by Wizard for ivy"))
(setup-wizard--save-option 'ivy-mode val)
(setup-wizard--save-option
'counsel-mode val nil nil
"Recommended by Wizard for ivy")))
:value (bound-and-true-p ivy-mode))
(widget-insert
" Ivy: A completion package that makes typing file names, buffer
names, commands, etc so much easier.\n")
;; Company
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--package-activate 'company)
(setup-wizard--save-option 'company-mode val)))
:value (bound-and-true-p company-mode))
(widget-insert
" Company: Popup completion menu when writing programs.\n")
(setup-wizard--insert
"🧙: Here are some built-in packages that I always enable:\n\n")
;; Electric-pair.
(widget-create 'checkbox
:notify
(lambda (widget &rest _)
(let ((val (widget-value widget)))
(setup-wizard--save-option
'electric-pair-mode val)))
:value electric-pair-mode)
(widget-insert
" Electric-pair-mode: Automatically closes parenthesis\n")
(setup-wizard--insert "\n🧙: ...\n\n")
(setup-wizard--insert "🧙: I don’t use many packages.\n"))
;;; The wizard framework
(defun setup-wizard--with-boilerplate
(setup-fn &optional page-list finish-fn)
"Call page setup function SETUP-FN with widget boilerplate.
PAGE-LIST is a list of setup function for pages to show in a
series. FINISH-FN is called when user clicks the finish button.
If PAGE-LIST or FINISH-FN are nil, don’t insert navigation
buttons."
(kill-all-local-variables)
(let ((inhibit-read-only t))
(erase-buffer))
(remove-overlays)
(funcall setup-fn)
(widget-insert "\n")
(when (and page-list finish-fn)
(setup-wizard--insert-step-buttons setup-fn page-list finish-fn))
(use-local-map widget-keymap)
(widget-setup)
(goto-char (point-min))
(local-set-key (kbd "q") #'setup-wizard--quit))
(defun setup-wizard--quit (&rest _)
"Quite the wizard."
(interactive)
(kill-buffer)
(message (with-temp-buffer
(setup-wizard--insert "🧚: See ya!")
(buffer-string))))
(defun setup-wizard--insert-step-buttons (page page-list finish-fn)
"Insert buttons that go to previous and next page of PAGE.
PAGE-LIST is a list of setup function for pages to show in a series.
Insert a Button that calls FINISH-FN at the last page."
(let* ((idx (seq-position page-list page))
(previous-page (if (eq idx 0) nil
(nth (1- idx) page-list)))
(next-page (nth (1+ idx) page-list)))
(setup-wizard--insert
(format "🧚: We are at step %s/%s, what’s next? "
(1+ idx) (length page-list)))
(when previous-page
(widget-create
'push-button
:notify (lambda (&rest _)
(setup-wizard--with-boilerplate
previous-page page-list finish-fn))
:value "Back"))
(widget-insert " ")
(if next-page
(widget-create
'push-button
:notify (lambda (&rest _)
(setup-wizard--with-boilerplate
next-page page-list finish-fn))
:value "Next")
(widget-create
'push-button
:notify (lambda (&rest _) (funcall finish-fn))
:value "Finish"))
(widget-insert " ")
(widget-create
'push-button
:value "Quit"
:notify #'setup-wizard--quit)
(widget-insert "\n")))
(defun setup-wizard--finish ()
"The default finish function.
Constructs the config and display them."
(setup-wizard--with-boilerplate
(lambda ()
(custom-save-all)
(setup-wizard--insert
"🧚: All done! Enjoy Emacs!\n"))))
(defvar setup-wizard--pages '(setup-wizard--theme-page
setup-wizard--keybinding-page
setup-wizard--ui-features-page
setup-wizard--undo-page
setup-wizard--package-page)
"A list of page functions.")
(defun setup-wizard ()
"Run the setup wizard."
(interactive)
(switch-to-buffer (get-buffer-create "*mage tower*"))
(let ((page-list setup-wizard--pages))
(setup-wizard--with-boilerplate
(car page-list) page-list
#'setup-wizard--finish)))
;;; Backport
(unless (fboundp 'undo--last-change-was-undo-p)
(defun undo--last-change-was-undo-p (undo-list)
(while (and (consp undo-list) (eq (car undo-list) nil))
(setq undo-list (cdr undo-list)))
(gethash undo-list undo-equiv-table)))
(unless (fboundp 'undo-redo)
(defun undo-redo (&optional arg)
"Undo the last ARG undos."
(interactive "*p")
(cond
((not (undo--last-change-was-undo-p buffer-undo-list))
(user-error "No undo to undo"))
(t
(let* ((ul buffer-undo-list)
(new-ul
(let ((undo-in-progress t))
(while (and (consp ul) (eq (car ul) nil))
(setq ul (cdr ul)))
(primitive-undo arg ul)))
(new-pul (undo--last-change-was-undo-p new-ul)))
(message "Redo%s" (if undo-in-region " in region" ""))
(setq this-command 'undo)
(setq pending-undo-list new-pul)
(setq buffer-undo-list new-ul))))))
(unless (fboundp 'undo-only)
(defun undo-only (&optional arg)
"Undo some previous changes.
Repeat this command to undo more changes.
A numeric ARG serves as a repeat count.
Contrary to `undo', this will not redo a previous undo."
(interactive "*p")
(let ((undo-no-redo t)) (undo arg))))
(provide 'setup-wizard)
;;; setup-wizard.el ends here
;; Local Variables:
;; sentence-end-double-space: t
;; End:
next prev parent reply other threads:[~2022-01-09 22:54 UTC|newest]
Thread overview: 119+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-02 2:07 Propose to add setup-wizard.el to ELPA Yuan Fu
2022-01-02 2:37 ` Po Lu
2022-01-02 3:02 ` Yuan Fu
2022-01-02 3:22 ` Po Lu
2022-01-02 5:51 ` Yuan Fu
2022-01-02 6:30 ` Po Lu
2022-01-02 7:58 ` Yuan Fu
2022-01-02 8:07 ` Po Lu
2022-01-02 9:07 ` Yuan Fu
2022-01-02 9:22 ` xenodasein--- via Emacs development discussions.
2022-01-02 9:45 ` Eduardo Ochs
2022-01-02 9:45 ` Po Lu
2022-01-02 10:09 ` Eduardo Ochs
2022-01-02 10:15 ` Po Lu
2022-01-02 10:25 ` Eduardo Ochs
2022-01-02 10:34 ` xenodasein--- via Emacs development discussions.
2022-01-02 10:52 ` Eli Zaretskii
2022-01-02 10:57 ` xenodasein--- via Emacs development discussions.
2022-01-02 11:14 ` Eli Zaretskii
2022-01-02 11:30 ` xenodasein--- via Emacs development discussions.
2022-01-02 11:38 ` Eli Zaretskii
2022-01-02 12:01 ` Po Lu
2022-01-02 11:31 ` xenodasein--- via Emacs development discussions.
[not found] ` <CADs++6jtFBah1hhsuN6T_-kFyjc_pNmmVKA+16vOWa8OctOZLw@mail.gmail.com>
2022-01-02 11:02 ` xenodasein--- via Emacs development discussions.
2022-01-02 11:17 ` Po Lu
2022-01-02 11:36 ` xenodasein--- via Emacs development discussions.
2022-01-02 12:03 ` Po Lu
2022-01-02 15:27 ` Stefan Kangas
[not found] ` <MsPZqa9--3-2@tutanota.de-MsP_1xO----2>
2022-01-02 11:57 ` xenodasein--- via Emacs development discussions.
2022-01-02 12:05 ` Po Lu
2022-01-02 15:27 ` Stefan Kangas
2022-01-02 15:37 ` Eli Zaretskii
2022-01-02 16:43 ` xenodasein--- via Emacs development discussions.
2022-01-02 17:32 ` Stefan Kangas
2022-01-02 18:51 ` FW: [External] : " Drew Adams
2022-01-02 19:07 ` xenodasein--- via Emacs development discussions.
2022-01-02 21:29 ` Drew Adams
2022-01-02 22:14 ` Stefan Kangas
2022-01-03 6:42 ` Sean Whitton
2022-01-03 7:02 ` Stefan Kangas
2022-01-03 8:19 ` xenodasein--- via Emacs development discussions.
2022-01-03 9:27 ` Po Lu
2022-01-03 9:55 ` xenodasein--- via Emacs development discussions.
2022-01-03 10:10 ` Po Lu
2022-01-03 10:21 ` xenodasein--- via Emacs development discussions.
2022-01-03 10:53 ` Po Lu
2022-01-03 11:07 ` xenodasein--- via Emacs development discussions.
2022-01-03 11:25 ` Po Lu
2022-01-03 11:32 ` xenodasein--- via Emacs development discussions.
2022-01-03 12:13 ` Po Lu
2022-01-03 12:20 ` xenodasein--- via Emacs development discussions.
2022-01-03 12:32 ` Po Lu
2022-01-03 12:44 ` xenodasein--- via Emacs development discussions.
2022-01-03 12:55 ` Po Lu
2022-01-03 13:24 ` xenodasein--- via Emacs development discussions.
2022-01-03 15:15 ` xenodasein--- via Emacs development discussions.
2022-01-03 16:04 ` Drew Adams
2022-01-04 21:19 ` Sean Whitton
2022-01-04 21:28 ` Drew Adams
2022-01-04 22:38 ` Sean Whitton
2022-01-04 22:51 ` Drew Adams
2022-01-05 5:28 ` tomas
2022-01-05 7:43 ` Drew Adams
2022-01-05 8:13 ` tomas
2022-01-07 10:34 ` Jean Louis
2022-01-03 16:03 ` Drew Adams
2022-01-03 16:05 ` Stefan Monnier
2022-01-04 1:50 ` Yuan Fu
2022-01-04 2:53 ` Po Lu
2022-01-04 4:13 ` Stefan Monnier
2022-01-04 4:30 ` Yuan Fu
2022-01-04 6:10 ` Stefan Monnier
2022-01-04 15:04 ` Lars Ingebrigtsen
2022-01-04 21:25 ` Sean Whitton
2022-01-05 0:58 ` Po Lu
2022-01-05 15:35 ` Lars Ingebrigtsen
2022-01-06 6:32 ` Sean Whitton
2022-01-03 0:42 ` Po Lu
2022-01-02 18:47 ` [External] : " Drew Adams
2022-01-02 11:58 ` Philip Kaludercic
2022-01-07 10:09 ` Jean Louis
2022-01-02 18:47 ` [External] : " Drew Adams
2022-01-02 9:41 ` Po Lu
2022-01-02 17:18 ` Yuan Fu
2022-01-02 18:47 ` [External] : " Drew Adams
2022-01-07 10:02 ` Jean Louis
2022-01-07 10:50 ` Po Lu
2022-01-07 12:11 ` Eli Zaretskii
2022-01-09 22:54 ` Yuan Fu [this message]
2022-01-10 4:15 ` Jean Louis
2022-01-10 15:45 ` [External] : " Drew Adams
2022-01-10 17:24 ` Eli Zaretskii
2022-01-11 4:47 ` Jean Louis
2022-01-11 4:51 ` Richard Stallman
2022-01-02 7:55 ` Eli Zaretskii
2022-01-02 8:07 ` Yuan Fu
2022-01-02 15:42 ` Stefan Kangas
2022-01-02 17:26 ` Yuan Fu
2022-01-02 17:36 ` xenodasein--- via Emacs development discussions.
[not found] ` <MsQrOAf--J-2@tutanota.de-MsQrQR2----2>
2022-01-02 17:55 ` xenodasein--- via Emacs development discussions.
2022-01-02 18:50 ` Stefan Kangas
2022-01-02 21:14 ` Yuan Fu
2022-01-03 0:45 ` Po Lu
2022-01-03 0:59 ` Yuan Fu
2022-01-03 1:02 ` Stefan Kangas
2022-01-03 9:12 ` Joost Kremers
2022-01-03 12:49 ` Eli Zaretskii
2022-01-03 13:00 ` Po Lu
2022-01-03 19:30 ` Joost Kremers
2022-01-02 8:07 ` Po Lu
2022-01-02 15:23 ` nanjunjie
2022-01-03 8:28 ` Philip Kaludercic
2022-01-04 16:09 ` Nan JunJie
2022-01-04 19:45 ` Philip Kaludercic
2022-01-02 12:02 ` Philip Kaludercic
2022-01-07 9:58 ` Jean Louis
-- strict thread matches above, loose matches on Subject: below --
2022-01-02 15:46 Simon Pugnet
2022-01-02 17:26 Simon Pugnet
2022-01-02 18:49 ` Stefan Kangas
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=64131FC6-A19E-41B5-B636-CD6544140E59@gmail.com \
--to=casouri@gmail.com \
--cc=bugs@gnu.support \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=luangruo@yahoo.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).