diff --git a/M2/Macaulay2/m2/files.m2 b/M2/Macaulay2/m2/files.m2 index b4076c0373d..d4ca2ed1119 100644 --- a/M2/Macaulay2/m2/files.m2 +++ b/M2/Macaulay2/m2/files.m2 @@ -301,13 +301,13 @@ supplantFileFile = (tmp,filename,backupq) -> ( else "file created for initialization text"; linkFile(tmp,filename); removeFile tmp; - stderr << "--" << msg << ": " << filename << endl; + printerr(msg, ": ", filename); ) supplantStringFile = (text,filename,backupq) -> ( text = replace("/PREFIX/",prefixDirectory,text); if fileExists filename and text === get filename then ( - stderr << "--initialization text already in file: " << filename << endl; + printerr("initialization text already in file: ", filename); return; ); tmp := filename | ".Macaulay2.tmp"; @@ -336,7 +336,7 @@ mungeFile = (filename, headerline, trailerline, text) -> ( ); newcontents := replace(regexp, insert, oldcontents); if oldcontents == newcontents then ( - stderr << "--initialization text already in file, no changes needed: " << filename << endl; + printerr("initialization text already in file, no changes needed: ", filename); return false; ); ) @@ -388,13 +388,18 @@ emacsenvtempl := /// (setenv "VAR" "/PREFIX/DIR:$VAR" t)) /// -dotemacsFix0 = /// -;; this version will give an error if M2-init.el is not found: -(load "M2-init") - -;; this version will not give an error if M2-init.el is not found: -;; (load "M2-init" t) +emacsfallbacktempl := /// +;; Check if setupEmacs() successfully installed the M2 emacs package. If not, +;; then load it manually. +(unless (fboundp 'M2) + (add-to-list 'load-path "/PREFIX/DIR") + ;; this version will give an error if M2-init.el is not found: + (load "M2-init")) + ;; this version will not give an error if M2-init.el is not found: + ;; (load "M2-init" t)) +/// +dotemacsFix0 = /// ;; You may comment out the following line with an initial semicolon if you ;; want to use your f12 key for something else. However, this action ;; will be undone the next time you run setup() or setupEmacs(). @@ -443,11 +448,42 @@ shellfixes := { ("INFOPATH", currentLayout#"info",":"), ("LD_LIBRARY_PATH", currentLayout#"lib","")} emacsfixes := { - ("load-path", currentLayout#"emacs", emacstempl), -- the exec-path fix is not needed, because we exec the shell and ask it to find M2 -- ("exec-path", currentLayout#"bin", emacstempl), ("Info-default-directory-list", currentLayout#"info", emacstempl), - ("PATH", currentLayout#"bin", emacsenvtempl)} + ("PATH", currentLayout#"bin", emacsenvtempl), + ("", currentLayout#"emacs", emacsfallbacktempl)} + +runAndEcho = s -> ( + cmd := demark(" ", s); + printerr("running: ", cmd); + run cmd) + +makeEmacsPackage = emacs -> ( + if run("command -v " | emacs | " > /dev/null") != 0 then ( + printerr "warning: emacs not found; cannot install package"; + return); + rootdir := temporaryFileName() | "/"; + pkgname := "M2-" | version#"VERSION"; + pkgdir := rootdir | pkgname | "/"; + tarfile := pkgname | ".tar.gz"; + makeDirectory pkgdir; + symbolsfile := first select({ + "M2-symbols.el", -- autotools + "M2-symbols.el.gz" -- cmake + }, + file -> fileExists(prefixDirectory | currentLayout#"emacs" | file)); + scan({"M2.el", "M2-mode.el", symbolsfile}, + file -> copyFile( + prefixDirectory | currentLayout#"emacs" | file, + pkgdir | file, Verbose => true)); + pkgfile := openOut(pkgdir | "M2-pkg.el"); + pkgfile << ";; -*- no-byte-compile: t; lexical-binding: nil -*-" << endl; + pkgfile << "(define-package \"M2\" \"" << version#"VERSION"; + pkgfile << "\" \"Macaulay2 major modes\")" << endl << close; + runAndEcho("cd", rootdir, "&&", "tar", "-cf", tarfile, pkgname); + runAndEcho(emacs, "--batch", + "--eval", "'(package-install-file \"" | rootdir | tarfile | "\")'");) stripdir := dir -> if dir === "/" then dir else replace("/$","",dir) fix := (var,dir,rest,templ) -> replace_(":REST",rest) replace_("VAR",var) replace_("DIR",stripdir dir) templ @@ -484,7 +520,13 @@ prelim := () -> ( promptUser = true; if prefixDirectory === null then error "can't determine Macaulay 2 prefix (prefixDirectory not set)"; ) -setupEmacs() := () -> ( prelim(); mungeEmacs(); ) + +setupEmacs String := emacs -> ( + prelim(); + mungeEmacs(); + makeEmacsPackage emacs) +setupEmacs() := () -> setupEmacs "emacs" + setup() := () -> ( prelim(); dotprofileFix = concatenate(shHeader, apply(shellfixes, (var,dir,rest) -> fix(var,dir,rest,bashtempl))); diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/setup-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/setup-doc.m2 index ddd2aa5b3d7..34651a77aa3 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/setup-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/setup-doc.m2 @@ -48,20 +48,33 @@ Node Key setupEmacs 1:setupEmacs + (setupEmacs, String) Usage setupEmacs() + setupEmacs s + Inputs + s:String -- defaults to "emacs" when absent Consequences Item - The initialization file for Emacs (@TT ".emacs"@ in your home directory) will have lines - added to allow the Macaulay2 Emacs mode to operate. The user is prompted before the file - is modified and offered the opportunity to review or reject the change. + The M2 package for Emacs is installed. The initialization file for Emacs (@TT ".emacs"@ in + your home directory) will have lines added to help the Macaulay2 Emacs mode to operate. The + user is prompted before the file is modified and offered the opportunity to review or reject + the change. Description Text - A backup files is made carefully, and if a mangled initialization file is detected, - it will not be modified. The lines added are bracketed by comment lines containing - the phrases @TT "Macaulay 2 start"@ and @TT "Macaulay 2 end"@. + Emacs will be run in batch mode to install the Macaulay2 major mode package. If @CODE "emacs"@ + is not available on the @CODE "PATH"@, then you may specify the path to the Emacs binary using + @VAR "s"@. + + In addition, your @CODE ".emacs"@ file will be modified. A backup file is made carefully, and + if a mangled initialization file is detected, it will not be modified. The lines added are + bracketed by comment lines containing the phrases @TT "Macaulay 2 start"@ and @TT "Macaulay 2 + end"@. These lines load a second file initialization file, @CODE ".emacs-Macaulay2"@, which + checks to see if the M2 Emacs package was successfully installed, and if not, loads it manually. + It also binds @KBD "F12"@ to the function to start a new M2 process. - The function @TO setup@ does all this and more. + The function @TO setup@ also sets up the Emacs initialization files as described above, but + does not attempt to install the M2 Emacs package. SeeAlso setup ///