How do I hide Emacs' "obsolete variable" warnings? - emacs

I've upgraded to Emacs 23.3 and now the *Compile-Log* buffer opens constantly with errors like:
Warning: `font-lock-beginning-of-syntax-function' is an obsolete variable (as
of Emacs 23.3); use `syntax-begin-function' instead.
I'm assuming the upstream authors will take care of these warnings in the future. Until then, how can I prevent these errors from appearing and opening a new window?

I'm currently back on 23.2 due to another issue, but I hacked a workaround for this issue while I was trying 23.3. It simply prevents the variable from being considered obsolete, but until Mumamo sorts itself out, that seemed preferable!
;; Mumamo is making emacs 23.3 freak out:
(when (and (equal emacs-major-version 23)
(equal emacs-minor-version 3))
(eval-after-load "bytecomp"
'(add-to-list 'byte-compile-not-obsolete-vars
'font-lock-beginning-of-syntax-function))
;; tramp-compat.el clobbers this variable!
(eval-after-load "tramp-compat"
'(add-to-list 'byte-compile-not-obsolete-vars
'font-lock-beginning-of-syntax-function)))

There are four levels of options for the warnings :
warning-minimum-level
warning-minimum-log-level
warning-suppress-types
warning-suppress-log-types
There are more information on the Emacs Manual.

I fixed it by running this on the elisp:
sed -i.bak 's/font-lock-beginning-of-syntax-function/syntax-begin-function/g' `find . -name '*.el' -exec grep -l 'font-lock-beginning-of-syntax-function' {} \;`

Phils's solution didn't work for me for some reason. Here's a more low-level way to do it.
(remprop 'flet 'byte-obsolete-info)
(remprop 'labels 'byte-obsolete-info)

Related

What happened to the ido-imenu in ruby-mode function in Emacs24?

Emacs 23.2 in emacs-starter-kit v1 has C-x C-i (or ido-imenu) (similar to Sublime Text's Cmd+R). Emacs24 in emacs-starter-kit v2 lacks this function. I found this github issue and a fix, which try to recreate the functionality. While this ido-imenu works in elisp-mode, it stopped working in ruby-mode. I get:
imenu--make-index-alist: No items suitable for an index found in this buffer
Has anyone figured out how to get this to work?
Why was this taken out of Emacs24?
Is there a new replacement for this function?
Since the function is part of ESK (as opposed to something budled with Emacs) you'd probably do best to report the bug upstream. On a related note ESK main competitor Emacs Prelude offers the same functionality (bound to C-c i by default) and it seems to be working fine with ruby-mode in Emacs 24. Here you can find more on ido-imenu.
So I finally figured it out, after reading the Defining an Imenu Menu for a Mode section on emacs-wiki again.
Short answer: you need to add this bit to your customization. Feel free to add more types to the list (I am happy with just methods).
(add-hook 'ruby-mode-hook
(lambda ()
(set (make-local-variable imenu-generic-expression)
'(("Methods" "^\\( *\\(def\\) +.+\\)" 1)
))))
Longer answer: I first tried to define a ruby-imenu-generic-expression function and set that to imenu-generic-expression by using the ruby-mode-hook:
(defvar ruby-imenu-generic-expression
'(("Methods" "^\\( *\\(def\\) +.+\\)" 1))
"The imenu regex to parse an outline of the ruby file")
(defun ruby-set-imenu-generic-expression ()
(make-local-variable 'imenu-generic-expression)
(make-local-variable 'imenu-create-index-function)
(setq imenu-create-index-function 'imenu-default-create-index-function)
(setq imenu-generic-expression ruby-imenu-generic-expression))
(add-hook 'ruby-mode-hook 'ruby-set-imenu-generic-expression)
This however did not work (I would get the same error as before). More reading of the Defining an Imenu Menu for a Mode section showed me the way. Now, I'm not an elisp expert, so here's my hypothesis: basically, the above method works for modes where the
major mode supports a buffer local copy of the “real” variable, ‘imenu-generic-expression’. If your mode doesn’t do it, you will have to rely on a hook.
The example for foo-mode made it clear how to do it for ruby-mode. So it appears that ruby-mode does not have a buffer-local copy of the real imenu-generic-expression variable. I still can't explain why it worked in Emacs 23.2 (with ESK v1) but does not on Emacs24, but hey at least I found a working solution.

Emacs ediff error "no newline at end of file"

On Debian Wheezy, Emacs 23.3.1, running ediff-files with a file that is missing a newline at the end results in the error \ No newline at end of file (I hope that's the correct translation; it's German \ Kein Zeilenumbruch am Dateiende. on my computer.)
Is it possible to have just a warning instead, so that I can see the diff and work on it (and fix the missing newline)? It's just a bit tedious to first have ediff fail, then open the file, add the newline, ediff again.
Try changing the value of the variable ediff-diff-ok-lines-regexp to include the German text ("Kein Zeilenumbruch am Dateiende"):
(setq ediff-diff-ok-lines-regexp
(concat
"^\\("
"[0-9,]+[acd][0-9,]+\C-m?$"
"\\|[] "
"\\|---"
"\\|.*Warning *:"
"\\|.*No +newline"
"\\|.*missing +newline"
"\\|.*Kein +Zeilenumbruch +am +Dateiende"
"\\|^\C-m?$"
"\\)"))
Update: Looking at the source code, it does seem that Ediff doesn't make any attempt to deal with the issue of localization of messages from diff. It should also be possible to work around this by wrapping diff in a shell script, e.g:
#!/bin/bash
LANG=C diff $*
..then customising the ediff-diff-program to call the wrapper instead:
(setq ediff-diff-program "~/bin/my-diff.sh")
Other code in the Emacs source directory lisp/vc does seem to handle this, for example vc-hg-state:
(defun vc-hg-state (file)
"Hg-specific version of `vc-state'."
...
(with-output-to-string
(with-current-buffer
standard-output
(setq status
(condition-case nil
;; Ignore all errors.
(let ((process-environment
;; Avoid localization of messages so we
;; can parse the output.
(append (list "TERM=dumb" "LANGUAGE=C")
process-environment)))
...
It seems a bit strange that Ediff doesn't also do this, but perhaps I'm missing something.
Ok, I found out what's wrong, and sadly, it's quite obvious: my environment has LANG=de, therefore when Emacs invokes diff, the warning message is returned in German as well, and Emacs, not recognising this “unkown” message, fails.
Starting emacs with LANG=C emacs works around this problem. However, I consider it a (quite silly) bug of emacs to make assumption on the user's language being English.

How to check which Emacs I am using?

I have two Emacs (Aquamacs and text-based Emacs) on my Mac.
In my .emacs file, I can check if I'm using Aquamacs with ...
(boundp 'aquamacs-version)
How can I check if I'm using text based emacs?
EDIT
Jürgen Hötzel's answer works, but for text based emacs, using
(unless (null window-system) ...)
is better as (window-system) is not defined.
M-x emacs-version
ad some more characters here......
Sorry, from .emacs, just call
(emacs-version)
I know this question was answered a long time ago, but I found another answer by typing emacs --help. This gives a list of options in which you can find emacs --version.
In my case, emacs --version prints: GNU Emacs 24.3.1.
I have only tested this solution on Linux with my current version of Emacs. I do not know if the same solution applies to Windows, or to older versions of Emacs, but in theory it should.
(if (window-system)
"window-based"
"text-based")
Or, you could use this:
(if (or (eq window-system 'ns)
(eq window-system 'mac))
(message "hello, world!"))
It will only print "hello, world!" when you run a graphical Emacs in OS X.
Errr... (not (boundp 'aquamacs-version)), perhaps?

emacs ( recompile -y )

Is it possible to pass a "-yes" flag to the 'recompile' command in emacs?
Excuse my complete lack of (e)lisp know-how. I got sick of going outside Emacs to compile my latex code, so i added the following key binding to my .emacs:
(global-set-key (kbd "<f12>") 'recompile);
Is it possible to automatically answer 'yes' to the following prompt that might appear:
"A compilation process is running; kill it? (yes or no)."
Also, is it possible to make the window that opens and shows the output to scroll to the bottom automatically. The interesting stuff is typically down there. Maybe its possible to chain the following command after recompile: "C-x o, end-of-buffer".
Thanks!
Here's some code to solve your first problem (interrupting the current compilation):
(defun interrupt-and-recompile ()
"Interrupt old compilation, if any, and recompile."
(interactive)
(ignore-errors (kill-compilation))
(recompile))
For your second problem (scrolling the compilation output), just customize the user setting compilation-scroll-output.
This behaviour is governed by the compilation-always-kill global variable. Customize it via customize-variable and set it to t.
Not sure which version of emacs first had this, but 26 and newer certainly does.
I somehow need to put kill-compilation into a ignore-errors with Emacs 23.2 to get it to work when no process is running. Otherwise works great.
(defun interrupt-and-recompile ()
"Interrupt old compilation, if any, and recompile."
(interactive)
(ignore-errors
(kill-compilation))
(recompile)
)
Whenever I tried using kill-compilation with latex/pdflatex it did not work. I assume it is because latex does not respond to SIGINT.
Instead I am using the following hack, which first sets the process-kill-without-query bit of the compilation-buffer and then closes it (which kills the running process).
(defun interrupt-and-recompile ()
"Interrupt old compilation, if any, and recompile."
(interactive)
(ignore-errors
(process-kill-without-query
(get-buffer-process
(get-buffer "*compilation*"))))
(ignore-errors
(kill-buffer "*compilation*"))
(recompile)
)
The other solutions didn't work for me for the same reason as sfeuz, but I didn't like the nuclear option of killing the hardcoded buffer by name.
Here's a short solution that autoanswers yes to that specific question by advising yes-or-no-p:
ftp://download.tuxfamily.org/user42/compilation-always-kill.el
(source: http://www.emacswiki.org/CompilationMode)

How to do use C-x k to kill an Emacs buffer opened in server mode?

I use windows batch file to open files in an already-running instance of Emacs using emacsclientw.exe. However, any file opened that way is opened in server mode, which means that I have to use C-x # to kill it, instead of the usual C-x k. How do I change this behavior?
My solution was to rebind it (well M-w actually) to:
(lambda ()
(interactive)
(if server-buffer-clients
(server-edit)
(kill-this-buffer)))
[edit: having now read the code for server-edit, it might be better to use server-done (depending on what you want). server-edit will switch you to a server-edited buffer (if any still exist) but server-done will simply switch you to the next buffer. You could also use the output of server-done to see if the buffer was actually killed (not the case if the file was open before invoking emacsclient) and then kill it if not. Or use server-kill-buffer as suggested elsewhere.]
Here is what i put in my .emacs to do this :
(add-hook 'server-switch-hook
(lambda ()
(local-set-key (kbd "C-x k") '(lambda ()
(interactive)
(if server-buffer-clients
(server-edit)
(ido-kill-buffer))))))
Like this C-x k work the usual way when i'm not finding a file from emacsclient (which for me is ido-kill-buffer), and if i'm using emacsclient, C-x k does server-edit if the client is waiting, or run ido-kill-buffer otherwise (if i used emacsclient -n).
use:
D:\> emacsclientw -n foo.txt
the -n says "no wait". This is in GNU Emacs 22.2.1 (i386-mingw-nt5.1.2600) of 2008-03-26 on RELEASE (and many prior versions, IIRC).
You know, I hate to suggest workarounds instead of a real solution... but after reading the server code, I am confused as to how emacs even determines that a buffer is a server buffer.
With that in mind, why not open up files like:
emacsclient --eval '(find-file "/path/to/file")'
This way emacs doesn't know that your buffer was opened via emacsclient, which sounds like what you really want.
Edit:
I'm not really happy with this, but it seems to work:
(global-set-key (kbd "C-x k") (lambda () (interactive) (server-kill-buffer (current-buffer))))
Okay, THIS did work for me:
(global-set-key (kbd "C-x k") '(lambda ()
(interactive)
(if server-buffer-clients
(server-done)
(kill-this-buffer))))
(this is the code from IvanAndrus's answer with the explicit changes from edits and comments, and using jrockway's keybinding.)
And, yes -- I am rebinding a standard keybinding. BUT it's a functional replacement NOT something completely different (eg, replacing kill-ring-save with kill-buffer stuff).
BTW, EmacsWiki has a couple of pages on this topic-- KillKey and KillingBuffer -- neither of which shed better light for me than the above (although the first-function on KillKey also used "server-edit"...).
I am not sure if that will work on windows, but on linux, emacs -daemon is just great.
With it, you don't have to run a different program, and your bindings are the same. I guess there are other advantages, but since I could never learn those emacsclient bindings, I never really used it, and can't say.
I don't think -daemon had been released yet, I am using 23.0.60.1 from CVS.