From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] for review - Allow expansion of "~" (as opposed to "~user") Date: Tue, 03 Mar 2015 18:48:24 +0100 Organization: http://mina86.com/ Message-ID: References: <83r3ta4fwk.fsf@gnu.org> <837fuzse3n.fsf@gnu.org> <83fv9mqeh9.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1425404934 29768 80.91.229.3 (3 Mar 2015 17:48:54 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 3 Mar 2015 17:48:54 +0000 (UTC) Cc: petewil@google.com, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Mar 03 18:48:53 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YSqw5-0005DS-38 for ged-emacs-devel@m.gmane.org; Tue, 03 Mar 2015 18:48:49 +0100 Original-Received: from localhost ([::1]:40168 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YSqw4-0005oe-6T for ged-emacs-devel@m.gmane.org; Tue, 03 Mar 2015 12:48:48 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39259) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YSqvx-0005kW-W9 for emacs-devel@gnu.org; Tue, 03 Mar 2015 12:48:44 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YSqvm-0006wc-8U for emacs-devel@gnu.org; Tue, 03 Mar 2015 12:48:41 -0500 Original-Received: from mail-wg0-x231.google.com ([2a00:1450:400c:c00::231]:42950) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YSqvl-0006vq-Qp for emacs-devel@gnu.org; Tue, 03 Mar 2015 12:48:30 -0500 Original-Received: by wggz12 with SMTP id z12so4418540wgg.9 for ; Tue, 03 Mar 2015 09:48:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:in-reply-to:organization:references :user-agent:face:date:message-id:mime-version:content-type :content-transfer-encoding; bh=srZ6ypuqUblE3PZOkJuXWXmNHaPW5itO1sr9DPK4NQs=; b=UsHgpPMMunXI0qwIp8VoaEFYmjHRe5i3w+R4bHP4itzw+mY1IYW8FjFYO3GfM99vtd yjMzpbiWtH8XNgiukdSyIrJjeMOJMH7EzDFrnDbqIRKR6rKifsCnFTb/e7TZ65Y1SOzs jNdkB9wlJwAAfV6mk48dEOhmQui7FVBnH8LJE3QXoKCijZuxeBGJBsFBPR+Z+h9ERGKI bClBnEv+Dq5EZuuGs4rx+SOwzMLv5fxRKMbEMhzAvU00B9r4p+sXkQ2757SHg32Z3xNy 4u85fTo7fe9UfezEKiQFTrwK91o+5hxVqZ2zKaKGhHWi61Z74REYuQi6SAUjvMU3sLWe P1DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:in-reply-to :organization:references:user-agent:face:date:message-id :mime-version:content-type:content-transfer-encoding; bh=srZ6ypuqUblE3PZOkJuXWXmNHaPW5itO1sr9DPK4NQs=; b=eVnzpRmZnHzRE5qgc9on1ZAXGsPcfjvyBuIwqW3HU5JhJTFdoJffQHjLL1nWZik+cN 1sxPoAqIZYLVko8oGlDPoapn+QwwjmWU2f2DpqH0D87sJskSZIZlDWj5TuAJgHJbBi0D pML/O757Ht6gNnl3zNu5o3hpj0+632FPPm/cx+dTSU8I55TewEUswoQceYiVn1MYy395 nn21CFoSCuN21keMCGN5mr57+TDmTPErKQ1qycR1OMWUbEMZmuBE2j1MMaoniSz5RUEO yxRhn9b7FdxrWiACS6j3Tl5zdbtUn6EczrCQcXliClOG5s5Ff7vS/f9z3MQkrMODjgbl hDCQ== X-Gm-Message-State: ALoCoQlUD79jEw3LXlz49aqQ2H4iqhVbbT/fDtuRqwYtMsRFCaanH5AEMwEzkZSZWNRdVsBVavxX X-Received: by 10.180.10.131 with SMTP id i3mr5243370wib.54.1425404908509; Tue, 03 Mar 2015 09:48:28 -0800 (PST) Original-Received: from mpn-glaptop ([2620:0:105f:310:b559:5160:d8d7:6f39]) by mx.google.com with ESMTPSA id ga8sm3432417wib.6.2015.03.03.09.48.25 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 03 Mar 2015 09:48:26 -0800 (PST) In-Reply-To: <83fv9mqeh9.fsf@gnu.org> User-Agent: Notmuch/0.19+53~g2e63a09 (http://notmuchmail.org) Emacs/25.0.50.1 (x86_64-unknown-linux-gnu) X-Face: PbkBB1w#)bOqd`iCe"Ds{e+!C7`pkC9a|f)Qo^BMQvy\q5x3?vDQJeN(DS?|-^$uMti[3D*#^_Ts"pU$jBQLq~Ud6iNwAw_r_o_4]|JO?]}P_}Nc&"p#D(ZgUb4uCNPe7~a[DbPG0T~!&c.y$Ur,=N4RT>]dNpd; KFrfMCylc}gc??'U2j,!8%xdD Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAJFBMVEWbfGlUPDDHgE57V0jUupKjgIObY0PLrom9mH4dFRK4gmjPs41MxjOgAAACQElEQVQ4jW3TMWvbQBQHcBk1xE6WyALX1069oZBMlq+ouUwpEQQ6uRjttkWP4CmBgGM0BQLBdPFZYPsyFUo6uEtKDQ7oy/U96XR2Ux8ehH/89Z6enqxBcS7Lg81jmSuujrfCZcLI/TYYvbGj+jbgFpHJ/bqQAUISj8iLyu4LuFHJTosxsucO4jSDNE0Hq3hwK/ceQ5sx97b8LcUDsILfk+ovHkOIsMbBfg43VuQ5Ln9YAGCkUdKJoXR9EclFBhixy3EGVz1K6eEkhxCAkeMMnqoAhAKwhoUJkDrCqvbecaYINlFKSRS1i12VKH1XpUd4qxL876EkMcDvHj3s5RBajHHMlA5iK32e0C7VgG0RlzFPvoYHZLRmAC0BmNcBruhkE0KsMsbEc62ZwUJDxWUdMsMhVqovoT96i/DnX/ASvz/6hbCabELLk/6FF/8PNpPCGqcZTGFcBhhAaZZDbQPaAB3+KrWWy2XgbYDNIinkdWAFcCpraDE/knwe5DBqGmgzESl1p2E4MWAz0VUPgYYzmfWb9yS4vCvgsxJriNTHoIBz5YteBvg+VGISQWUqhMiByPIPpygeDBE6elD973xWwKkEiHZAHKjhuPsFnBuArrzxtakRcISv+XMIPl4aGBUJm8Emk7qBYU8IlgNEIpiJhk/No24jHwkKTFHDWfPniR 4iw5vJaw2nzSjfq2zffcE/GDjRC2dn0J0XwPAbDL84TvaFCJEU4Oml9pRyEUhR3Cl2t01AoEjRbs0sYugp14/4X5n4pU4EHHnMAAAAAElFTkSuQmCC X-PGP: 50751FF4 X-PGP-FP: AC1F 5F5C D418 88F8 CC84 5858 2060 4012 5075 1FF4 X-Hashcash: 1:20:150303:eliz@gnu.org::629Oq6TFn62eZovt:0000021Li X-Hashcash: 1:20:150303:petewil@google.com::HjksOGEVTT+CLsPo:00000000000000000000000000000000000000000003WaP X-Hashcash: 1:20:150303:emacs-devel@gnu.org::UTTltHUN2aH4Lg3/:0000000000000000000000000000000000000000006FOb X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c00::231 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:183605 Archived-At: On Tue, Mar 03 2015, Eli Zaretskii wrote: >> From: Michal Nazarewicz >> Cc: petewil@google.com, emacs-devel@gnu.org >> Date: Mon, 02 Mar 2015 21:37:56 +0100 >>=20 >> >> Looking at that code, it appears it=E2=80=99s inconsistent on Windows= when it >> >> comes to handling ~/.emacs.d/init.el. If I understand it correctly, >> >> here=E2=80=99s how Emacs behave on Windows: >> >>=20 >> >> * emacs -> load ~/.emacs, ~/_emacs or ~/.emacs.d/init.el >> >> * emacs -u foo -> load ~/.emacs or ~/_emacs >> > >> > I'm not bothered about the inconsistency, since the "-u foo" >> > "handling" is a kludge for a situation that shouldn't happen. I >> > wouldn't object to emitting an error in that case. >>=20 >> Doesn=E2=80=99t this basically mean doing this: >>=20 >> - (if (file-directory-p (expand-file-name >> - ;; We don't support ~USER on MS-Windows >> - ;; and MS-DOS except for the current >> - ;; user, and always load .emacs from >> - ;; the current user's home directory >> - ;; (see below). So always check "~", >> - ;; even if invoked with "-u USER", or >> - ;; if $USER or $LOGNAME are set to >> - ;; something different. >> - (if (memq system-type '(windows-nt ms-dos= )) >> - "~" >> - (concat "~" init-file-user)))) >> - nil >> - (display-warning 'initialization >> + (unless (file-directory-p (expand-file-name >> + (concat "~" init-file-user))) >> + (display-warning 'initialization >>=20 >> and then using ~user/=E2=80=A6 for every system including windows-nt? > > Not exactly. First, we had what you suggest before 1df1e49eb, so > going back to that code means re-introducing the problem it solved. 1df1e49eb actually makes sense to me (since windows-nt ignores `init-file-user' when looking for .emacs) but 5463218ce doesn=E2=80=99t sin= ce ms-dos uses `init-file-user' when looking for _emacs. > Second, it's not really nice to have init-file-user have the value of, > say, "~bob/.emacs", when Emacs was invoked with "-u bob", whereas in > fact we loaded "C:/fred's-home/.emacs". That does not happen. If an init file has been loaded, `user-itni-file' variable *will* point to it. However, if =E2=80=98bob=E2=80=99 is not a valid user, and fred runs Emacs = with =E2=80=98-u bob=E2=80=99, `init-file-user' will be "bob" while `user-init-file' will be: * on Windows: "C:/fred's-home/.emacs" (if that file exists) or "~/.emacs" (if it does not); * on DOS: "D:/current/dir/~bob/_emacs" (if that file exists) or "~bob/_emacs" (if it does not); and * on POSIX: "/current/dir/~bob/.emacs" (if that file exists) or=20 "~bob/.emacs" (if it does not). If =E2=80=98bob=E2=80=99 is a valid user with a home directory though, `use= r-init-file' will be: * on Windows: "C:/fred's-home/.emacs" (if that file exists) or "~/.emacs" (if it does not); * on DOS: "C:/bob's-home/_emacs" (if that file exists) or "~bob/_emacs" (if it does not); and * on POSIX: "/home/bob/.emacs" (if that file exists) or=20 "~bob/.emacs" (if it does not). Furthermore: * DOS port will check "C:/fred's-home" directory even though it will try to load "C:/fred's-home/~bob/_emacs" or "C:/bob's-home/_emacs" file; and * Windows port will load "C:/fred's-home/.emacs" even if "C:/bob's-home/.emacs" or "C:/fred's-home/~bob/.emacs" exists. > It's a lie, and one that's tricky to untangle: you need to know that > to get a _real_ file name, you need to run it through > expand-file-name. If you don't, things will subtly fail, e.g., if you > compare this with some other file name. This is already a problem on *all* systems and it happens if user init file is not found. If you run =E2=80=98emacs -u foo=E2=80=99 on GNU/Linux,= you=E2=80=99ll end up with `user-init-file" equal to "~foo/.emacs". > So I'd rather we either errored out with such invocation, or fixed the > value to not lie, as we do now. > >> If I understand correctly, ~user/=E2=80=A6 expansion depends on getpwnam= and a) >> on MS-DOS DJGPP provides it (by having a single pw entry for user =3D=3D >> current user), b) on W32 src/w32.c provides it (with the same >> implementation) and on POSIX we have it properly implemented. > Another important piece of the puzzle is that if USER is not > recognized as a valid user by the getpwnam emulation on > MS-Windows/MS-DOS, you get this: > > (expand-file-name "~USER") =3D> /current/directory/~USER > > And it is possible to have a literal "~USER" directory, in which case > the warning will be incorrectly skipped. This also happens on UNIX-like systems. Like I=E2=80=99ve said above, if y= ou run =E2=80=98emacs -u foo=E2=80=99 on GNU/Linux, you end up with "~foo/.ema= cs" `user-init-file'. You also end up with =E2=80=98User foo has no home direc= tory=E2=80=99 warning. Based on all that, I think the most consistent option is to: 1) always check if ~USER/ directory exists for the =E2=80=98User foo has no= home directory=E2=80=99 warning; 2) user ~USER/.emacs and ~USER/_emacs on MS-Windows; and 3) use `expand-file-name' when setting `user-init-file' if init file has not been loaded. The below untested patch does that plus stops Emacs from attempting to load init file if `init-file-user' is =E2=80=98invalid=E2=80=99, i.e. conta= ins ~, /, : or \n. >From d96e4d6e4f9ed3919351f81bdb50412f9a1ea178 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Tue, 3 Mar 2015 18:44:27 +0100 Subject: [PATCH] startup.el: Harmonise initialisation file loading across systems MIME-Version: 1.0 Content-Type: text/plain; charset=3DUTF-8 Content-Transfer-Encoding: 8bit * lisp/startup.el (command-line): Change how initialisation file is loaded on various systems in the effort to harmonise it and get rid of various inconsistencies. 1. If init file has not been loaded, the `user-file-user' will now be an absolute path rather than "~/.emacs" (or "~/_emacs" on DOS). 2. With =E2=80=98-u=E2=80=99 argument, MS-Windows version of Emacs will n= ow try to load ~USER/.emacs, ~USER/_emacs and finally ~USER/.emacs.d/init files (in that order) rather than ~/.emacs, ~/_emacs and ~USER/.emacs.d/init. NB: If `-u=E2=80=99 argument specifies an unknown user, expansion of "~USER/=E2=80=A6" yields "/current/working/directory/~USER/=E2=80=A6" Th= is is nothing new and it=E2=80=99s how *NIX and DOS ports behaved already. 3. With =E2=80=98-u=E2=80=99 argument, MS-DOS and MS-Windows versions wil= l check if "~USER/" directory exists before issuing a =E2=80=98user has no home=E2= =80=99 warning. This is consistent with the fact that both those ports will attempt to read files inside of "~USER/". (For MS-DOS port, the latter has already been the case, but it checked "~/" nonetheless). --- lisp/startup.el | 159 ++++++++++++++++++++++------------------------------= ---- 1 file changed, 63 insertions(+), 96 deletions(-) diff --git a/lisp/startup.el b/lisp/startup.el index 999e53e..0bfb5f0 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -1043,108 +1043,75 @@ (defun command-line () (setq inhibit-startup-screen nil) =20 ;; Warn for invalid user name. - (when init-file-user - (if (string-match "[~/:\n]" init-file-user) - (display-warning 'initialization - (format "Invalid user name %s" - init-file-user) - :error) - (if (file-directory-p (expand-file-name - ;; We don't support ~USER on MS-Windows - ;; and MS-DOS except for the current - ;; user, and always load .emacs from - ;; the current user's home directory - ;; (see below). So always check "~", - ;; even if invoked with "-u USER", or - ;; if $USER or $LOGNAME are set to - ;; something different. - (if (memq system-type '(windows-nt ms-dos)) - "~" - (concat "~" init-file-user)))) - nil - (display-warning 'initialization - (format "User %s has no home directory" - (if (equal init-file-user "") - (user-real-login-name) - init-file-user)) - :error)))) - ;; Load that user's init file, or the default one, or none. (let (debug-on-error-from-init-file debug-on-error-should-be-set (debug-on-error-initial (if (eq init-file-debug t) 'startup init-file-debug)) - (orig-enable-multibyte (default-value 'enable-multibyte-characters))) + (orig-enable-multibyte (default-value 'enable-multibyte-characters)) + home-dir) + + (when init-file-user + (if (string-match "[~/:\n]" init-file-user) + (display-warning 'initialization + (format "Invalid user name %s" init-file-user) + :error) + (setq home-dir (file-name-as-directory + (expand-file-name (concat "~" init-file-user)))) + (unless (file-directory-p home-dir) + (display-warning 'initialization + (format "User %s has no home directory" + (if (equal init-file-user "") + (user-real-login-name) + init-file-user)) + :error)))) + (let ((debug-on-error debug-on-error-initial) - ;; This function actually reads the init files. - (inner - (function - (lambda () - (if init-file-user - (let ((user-init-file-1 - (cond - ((eq system-type 'ms-dos) - (concat "~" init-file-user "/_emacs")) - ((not (eq system-type 'windows-nt)) - (concat "~" init-file-user "/.emacs")) - ;; Else deal with the Windows situation - ((directory-files "~" nil "^\\.emacs\\(\\.elc?\\)?$") - ;; Prefer .emacs on Windows. - "~/.emacs") - ((directory-files "~" nil "^_emacs\\(\\.elc?\\)?$") - ;; Also support _emacs for compatibility, but warn about it. - (push '(initialization - "`_emacs' init file is deprecated, please use `.emacs'") - delayed-warnings-list) - "~/_emacs") - (t ;; But default to .emacs if _emacs does not exist. - "~/.emacs")))) - ;; This tells `load' to store the file name found - ;; into user-init-file. - (setq user-init-file t) - (load user-init-file-1 t t) - - (when (eq user-init-file t) - ;; If we did not find ~/.emacs, try - ;; ~/.emacs.d/init.el. - (let ((otherfile - (expand-file-name - "init" - (file-name-as-directory - (concat "~" init-file-user "/.emacs.d"))))) - (load otherfile t t) - - ;; If we did not find the user's init file, - ;; set user-init-file conclusively. - ;; Don't let it be set from default.el. - (when (eq user-init-file t) - (setq user-init-file user-init-file-1)))) - - ;; If we loaded a compiled file, set - ;; `user-init-file' to the source version if that - ;; exists. - (when (and user-init-file - (equal (file-name-extension user-init-file) - "elc")) - (let* ((source (file-name-sans-extension user-init-file)) - (alt (concat source ".el"))) - (setq source (cond ((file-exists-p alt) alt) - ((file-exists-p source) source) - (t nil))) - (when source - (when (file-newer-than-file-p source user-init-file) - (message "Warning: %s is newer than %s" - source user-init-file) - (sit-for 1)) - (setq user-init-file source)))) - - (unless inhibit-default-init - (let ((inhibit-startup-screen nil)) - ;; Users are supposed to be told their rights. - ;; (Plus how to get help and how to undo.) - ;; Don't you dare turn this off for anyone - ;; except yourself. - (load "default" t t))))))))) + ;; This function actually reads the init files. + (inner + (function + (lambda () + (when home-dir + ;; This tells `load' to store the file name found + ;; into user-init-file. + (setq user-init-file t) + ;; On MS-DOS, try ~USER/_emacs. On MS-Windows try + ;; ~USER/.emacs, ~USER/_emacs and ~/emacs.d/init. On all + ;; other systems, try ~USER/.emacs and ~/emacs.d/init. + (if (or (and (not (eq system-type 'ms-dos)) + (load (concat home-dir ".emacs") t t)) + (and (memq system-type '(ms-dos windows-nt)) + (load (concat home-dir "_emacs") t t)) + (and (not (eq system-type 'ms-dos)) + (load (concat home-dir ".emacs.d/init") t t= ))) + ;; If we loaded a compiled file, set `user-init-file= ' to + ;; the source version if that exists. + (when (equal (file-name-extension user-init-file) "e= lc") + (let* ((src (file-name-sans-extension user-init-fi= le)) + (alt (concat src ".el"))) + (setq src (cond ((file-exists-p alt) alt) + ((file-exists-p src) src) + (t nil))) + (when source + (when (file-newer-than-file-p src user-init-fi= le) + (message "Warning: %s is newer than %s" + src user-init-file) + (sit-for 1)) + (setq user-init-file src)))) + ;; If we failed to load the init file, set `user-init-= file' + ;; to the default location for it. On MS-DOS that=E2= =80=99s + ;; ~USER/_emacs and on all other systems it=E2=80=99s = ~USER/.emacs + (setq user-init-file (if (eq system-type 'ms-dos) + (concat home-dir "_emacs") + (concat home-dir ".emacs"))) + + (unless inhibit-default-init + (let ((inhibit-startup-screen nil)) + ;; Users are supposed to be told their rights. (P= lus + ;; how to get help and how to undo.) Don't you da= re + ;; turn this off for anyone except yourself. + (load "default" t t))))))))) + (if init-file-debug ;; Do this without a condition-case if the user wants to debug. (funcall inner) --=20 Best regards, _ _ .o. | Liege of Serenely Enlightened Majesty of o' \,=3D./ `o ..o | Computer Science, Micha=C5=82 =E2=80=9Cmina86=E2=80=9D Nazarewicz = (o o) ooo +------ooO--(_)--Ooo--