Different setup in .emacs for PC/Mac - emacs

I need to have different setup in .emacs depending on my system (Mac or PC).
This post teaches how to know the system that my emacs is running.
How can I check the variable 'system-type' is to set what in emacs?
What code should I have in .emacs to have different setup for PC and Mac?
???
(when (eq system-type 'windows-nt')
)

You can do this:
(if (equal system-type 'windows-nt)
(progn
(... various windows-nt stuff ...)))
(if (equal system-type 'darwin)
(progn
(... various mac stuff ...)))
What I do in my .emacs is set a variable (I call it this-config) based on machine type and name. Then I use the same .emacs everywhere.
Using this code, I can pull the machine name out:
(defvar this-machine "default")
(if (getenv "HOST")
(setq this-machine (getenv "HOST")))
(if (string-match "default" this-machine)
(if (getenv "HOSTNAME")
(setq this-machine (getenv "HOSTNAME"))))
(if (string-match "default" this-machine)
(setq this-machine system-name))
You can then set this-config based on system-type and/or machine name.
Then I use this code:
(cond ((or (equal this-machine "machineX")
(equal this-machine "machineY"))
(do some setup for machineX and machineY))
Edit: system-type returns a symbol, not a string

My emacs says darwin, which is the name for the open OS that OSX is built on. To see the values do a describe-variable on system-type.
Note that the mac also has several possible window types so you might need to make more decisions.

Do this :
(if (eq window-system 'w32)
(progn
... your functions here for Microsoft Windows ...
))
window-system is a function and returns the name of the window system.
system-type is a variable. Do C-h v system-type RET to have the list of supported system-types for your case :
From the help :
`gnu' compiled for a GNU Hurd system.
`gnu/linux' compiled for a GNU/Linux system.
`gnu/kfreebsd' compiled for a GNU system with a FreeBSD kernel.
`darwin' compiled for Darwin (GNU-Darwin, Mac OS X, ...).
`ms-dos' compiled as an MS-DOS application.
`windows-nt' compiled as a native W32 application.
`cygwin' compiled using the Cygwin library.
Anything else (in Emacs 23.1, the possibilities are: aix, berkeley-unix,
hpux, irix, lynxos 3.0.1, usg-unix-v) indicates some sort of
Unix system.

Related

Programmatically distinguishing system-type -- Windos XP v. Windows 7

I'm looking for some assistance, please, to programmatically distinguish between system-type Windows XP versus Windows 7 -- using the same Emacs version.
Emacs Version: GNU Emacs 24.3.94.1 (i686-pc-mingw32) of 2014-10-02 on LEG570
I would like to do something like:
(cond
((eq system-type 'darwin)
. . .)
((and
(eq system-type 'windows-nt)
(eq ... Windows XP)) ;; pseudocode
. . .)
((and
(eq system-type 'windows-nt)
(eq ... Windows 7)) ;; pseudocode
. . .) )
Try M-:x (w32-version) RET on those two systems. The result should be different.
Then use it in something like:
(cond ((equal (w32-version) '...) ...)
I think that the approach here would be the following:
Have sub-conditions when the system-type is 'windows-nt.
Parse the output of some foreign code to get the Windows variant.
Approach 1 : Dummy shell command(output specific to OS locale??)
Use ver to get the os version.
http://www.windows-commandline.com/find-windows-os-version-from-command/
The above approach might produce different string output based on the user locale settings.
Approach 2 : Use some external custom code
Alternatively you could compile some external C++ app and deal with OS semantic versions mappings (http://support2.microsoft.com/kb/307394)
Then things become simple
if system-type is windows-nt
variant = parse (shell-command-to-string "ver")
conditions to run code for interesting variant with a default :else case

"malformed function" warning and require "Cannot open load file:" error

I am getting these two issues :
In toplevel form:
init.el:28:1:Warning: `(add-path (p) (add-to-list (quote load-path) (concat
emacs-root p)))' is a malformed function
init.el:42:1:Error: Cannot open load file: exec-path-from-shell
during compiling the following elisp:
(eval-when-compile (require 'cl))
;; root of all emacs-related stuff
(eval-when-compile
(defvar emacs-root
(if (or (eq system-type 'cygwin)
(eq system-type 'gnu/linux)
(eq system-type 'linux)
(eq system-type 'darwin))
"~/.emacs.d/" "z:/.emacs.d/")
"Path to where EMACS configuration root is."))
(eval-when-compile
(defvar emacs-root "~/.emacs.d"
"Path to where EMACS configuration root is."))
;; path to where plugins are kept
(defvar plugin-path (concat emacs-root "el-get")
"*Path to el-get plugins.")
;; for portability with < 24.3 EMACS
(unless (fboundp 'cl-labels) (fset 'cl-labels 'labels))
;; add paths to various configuration modes
(cl-labels
((add-path (p)
(add-to-list 'load-path
(concat emacs-root p))))
(add-path ".")
(add-path "settings")
(add-path "site-lisp")
(add-path "erlang")
(add-path "exec-path-from-shell"))
;; set PATH, because we don't load .bashrc
(require 'exec-path-from-shell) ;; <- Error: Cannot open load file: exec-path-from-shell
both these issues are very puzzling to me.
I don't see why this fund considered "malformed"
`(add-path (p) (add-to-list (quote load-path) (concat
emacs-root p)))'
and secondly why "require" is not able to load file.
these issues only happen during compilation, not compiled code works ok
would really appreciate any pointers
Regards, Roman
cl-labels is provided by cl-lib, not by cl. So you need (require 'cl-lib) (which you can also wrap in eval-when-compile).
You need to have "cl-lib" loaded at compile time:
(eval-when-compile (require 'cl-lib))
Also, as Stefan explained in his comments in your other question, you should not define variables in eval-when-compile. Just use defvar.

Erlang flymake with nested folders in src cannot find includes folder

Sorry for my poor English.
I'm configuring my emacs with erlang flymake. Source files in src's nested folders report 'can't find include file', but files in src/folder can find the include file.
My emacs settings for erlang:
;; erlang-mode
(setq load-path (cons "/usr/local/Cellar/erlang/R15B02/lib/erlang/lib/tools-2.6.8/emacs" load-path))
(setq erlang-root-dir "/usr/local/Cellar/erlang/R15B02/lib/erlang")
(setq exec-path (cons "/usr/local/Cellar/erlang/R15B02/lib/erlang/bin" exec-path))
(require 'erlang-start)
;; distel
(add-to-list 'load-path "/usr/local/share/distel/elisp/")
(require 'distel)
(distel-setup)
;; erlang-flymake
(require 'erlang-flymake)
(erlang-flymake-only-on-save)
My erlang application folder is like following:
app/src/ (source code)
src/mod
src/lib
app/include/ (hrls)
app/ebin/ (compiled code)
...etc
In erlang-flymake there are 2 variables (erlang-flymake-get-include-dirs-function and erlang-flymake-get-code-path-dirs-function), that specify functions to search include & ebin directories. Right now, they're pointing to the functions erlang-flymake-get-include-dirs and erlang-flymake-get-code-path-dirs that simply return current dir + include and ebin correspondingly. For example, you can use following code to do this:
(defun get-erlang-app-dir ()
(let* ((src-path (file-name-directory (buffer-file-name)))
(pos (string-match "/src/" src-path)))
(if pos
(substring src-path 0 (+ 1 pos))
src-path)))
(setq erlang-flymake-get-code-path-dirs-function
(lambda ()
(concat (get-erlang-app-dir) "ebin")))
(setq erlang-flymake-get-code-include-dirs-function
(lambda ()
(concat (get-erlang-app-dir) "include")))
P.S. Are you using rebar to maintain your project?
If you use erlang-flymake you might want to look at https://github.com/ten0s/syntaxerl. It's a syntax checker for Erlang. It uses erlang-flymake under the hood, but instead of `erlc' it uses a custom syntax checker that can evaluate .erl, .hrl, .config, .rel, .app, .app.src, .escript files. The syntax checker is rebar aware, but also works with standard Erlang/OTP directory structure. Emacs's setup is also there.

How to load module only in linux?

Here is my try:
(if (eq system-type 'gnu/linux)
(load "/usr/share/emacs/site-lisp/site-gentoo")
(require 'site-gentoo))
But anyways I receive error on windows :
/.emacs':
File error: Cannot open load file, site-gentoo
Your problem is in the way you use if: its documentation says it's
(if COND THEN ELSE...)
I.e. your (require 'site-gentoo) gets executed if and only if it's not a GNU/Linux system.
Use when instead, that should do what you intend.
Also, there should actually no need to use both load and require, their usage should have the same result. The differences are mostly that require will search the load-path and don't load something again that was already loaded before.
It should be:
(if (eq system-type 'gnu/linux)
(progn
(load "/usr/share/emacs/site-lisp/site-gentoo")
(require 'site-gentoo)))
or
(when (eq system-type 'gnu/linux)
(load "/usr/share/emacs/site-lisp/site-gentoo")
(require 'site-gentoo))
Instead of (load "/usr/share/emacs/site-lisp/site-gentoo") you should add the folder containing the load file to the load-path:
(add-to-list 'load-path "/usr/share/emacs/site-lisp/")
That should do the trick. require only works for files on the load-path, load on the other hand simply evaluates the lisp file it was given as parameter.
Rörd and Bozhidar Batsov have already provided the answer as to how to resolve it, but just to add in the reason why your original code was failing.
(if COND THEN ELSE...) only accepts a single THEN command. To be able to have it evaluate multiple commands when it returns true you have to wrap the commands in (progn BODY...).
Your code was stating:
If on linux: (load "/usr/share/emacs/site-lisp/site-gentoo")
If not on linux: (require 'site-gentoo)
Using (when ...) or wrapping in (progn ...) will both provide the desired solution.

How to choose system type in Emacs

I'm trying to configure my .emacs file to work in a Windows, Linux, and Mac environment--specifically, I need it to choose the correct font and a certain directory for org-mode.
I have tried the following which loads the correct font, but does not load the path specified for org-mode:
;; On Windows
(if (eq system-type 'windows-nt)
(set-default-font "-outline-Consolas-normal-r-normal-normal-14-97-96-96-c-*-iso8859-1")
(setq load-path (cons "~/elisp/org-6.34c/lisp" load-path))
)
;; On Linux
(if (eq system-type 'gnu/linux)
(set-default-font "Inconsolata-11")
(setq load-path (cons "~/elisp/org-current/lisp" load-path))
)
I have tried the following which on my Windows machine returns the error Font Inconsolata-11 is not defined, and on my Linux machine returns the error Font -outline-Consolas-normal-r-normal-normal-14-97-96-96-c-*-iso8859-1 is not defined. For both, the specified org path is not loaded:
;; On Windows
(if (eq system-type 'windows-nt)
(setq load-path (cons "~/elisp/org-6.34c/lisp" load-path))
(set-default-font "-outline-Consolas-normal-r-normal-normal-14-97-96-96-c-*-iso8859-1")
)
;; On Linux
(if (eq system-type 'gnu/linux)
(setq load-path (cons "~/elisp/org-current/lisp" load-path))
(set-default-font "Inconsolata-11")
)
I evaluated the system-type variable in both environments, and they both evaluate correctly.
Can anyone see what's wrong--also, I'm not very versed in emacs-lisp, can you see what incorrect assumptions I'm making?
Thank you,
Zachary
note that if in lisp is if-then-else. so, in your first case you are doing if windows, set the font, ELSE set the loadpath for windows! then independantly, you are doin if linux setthe font, else set the loadpath for linux!
try
(if (eq system-type 'windows-nt)
(progn
(setq load-path (cons "~/elisp/org-6.34c/lisp" load-path))
(set-default-font "-outline-Consolas-normal-r-normal-normal-14-97-96-96-c-*-iso8859-1")
)
(progn
(setq load-path (cons "~/elisp/org-current/lisp" load-path))
(set-default-font "Inconsolata-11")
)
)
this won't work on mac, or whatever, but if you're only ever using NT or linux, this should work. Otherwise you can stick the other if outside the 2nd progn...