If you give emacs a filename with a tilde at the front of the name it will open the file if it exists in the current directory.
$ emacs ~abc mg doesn't, mg will give a message "Unkown user abc". If the file doesn't exist and no user exists with the name abc, emacs will create a new buffer called ~abc which will be saved by default in the current directory. mg doesn't, mg will give a message "Unkown user abc". However, if the file doesn't exist but a user does exist, both behave in the same way, they open up the home directory in dired mode (permissions permitting). This diff makes mg behave like emacs regarding the first 2 points. comments/ok? -lum Index: fileio.c =================================================================== RCS file: /cvs/src/usr.bin/mg/fileio.c,v retrieving revision 1.87 diff -u -p -r1.87 fileio.c --- fileio.c 12 Apr 2012 04:47:59 -0000 1.87 +++ fileio.c 21 May 2012 07:30:17 -0000 @@ -270,6 +270,7 @@ fbackupfile(const char *fn) char * adjustname(const char *fn, int slashslash) { + struct stat statbuf; static char fnb[MAXPATHLEN]; const char *cp, *ep = NULL; char user[LOGIN_NAME_MAX], path[MAXPATHLEN]; @@ -291,8 +292,12 @@ adjustname(const char *fn, int slashslas } } - /* first handle tilde expansion */ - if (fn[0] == '~') { + /* + * Handle tilde expansion if: + * 1) ./~fn doesn't exist + * 2) username 'fn' doesn't exist + */ + if (fn[0] == '~' && stat(fn, &statbuf) != 0) { struct passwd *pw; cp = strchr(fn, '/'); @@ -310,20 +315,19 @@ adjustname(const char *fn, int slashslas user[ulen] = '\0'; } pw = getpwnam(user); - if (pw == NULL) { - ewprintf("Unknown user %s", user); - return (NULL); - } - plen = strlcpy(path, pw->pw_dir, sizeof(path)); - if (plen == 0 || path[plen - 1] != '/') { - if (strlcat(path, "/", sizeof(path)) >= sizeof(path)) { - ewprintf("Path too long"); - return (NULL); + if (pw != NULL) { + plen = strlcpy(path, pw->pw_dir, sizeof(path)); + if (plen == 0 || path[plen - 1] != '/') { + if (strlcat(path, "/", sizeof(path)) >= + sizeof(path)) { + ewprintf("Path too long"); + return (NULL); + } } + fn = cp; + if (*fn == '/') + fn++; } - fn = cp; - if (*fn == '/') - fn++; } if (strlcat(path, fn, sizeof(path)) >= sizeof(path)) { ewprintf("Path too long");