Create a new mode in Emacs - emacs

I know nothing about Emacs Lisp (or any Lisp, for that matter). I want to do something that seems very simple, yet I have had no luck with online guides. I want to create "packet-mode.el" for .packet files. I want to do the following:
Enable C++ mode
Make packet a keyword, while leaving the rest of C++ mode unchanged
(define-derived-mode packet-mode fundamental-mode
(font-lock-add-keywords 'c++-mode `(("packet" . font-lock-keyword-face)))
(c++-mode))
(add-to-list 'auto-mode-alist '("\\.packet\\'" . packet-mode)
(provide 'packet-mode)
I've also tried switching the order of the statements in packet mode, but then the C++ highlighting breaks.
I would like packet to behave like struct in the sense that
packet foo {
int bar;
}
is highlighted the same way it would be if struct were used in place of packet.

Here is what you need to put into packet-mode.el:
(defvar packet-mode-font-lock-keywords
'(("\\<packet\\>" . font-lock-keyword-face)))
(define-derived-mode packet-mode c++-mode "Packet"
"A major mode to edit GNU ld script files."
(font-lock-add-keywords nil packet-mode-font-lock-keywords))
(add-to-list 'auto-mode-alist '("\\.packet\\'" . packet-mode))
(provide 'packet-mode)
Place packet-mode.el into a directory in your load-path and
(optionally) byte compile it.
Now, add (require 'packet-mode) into your .emacs.el.

Related

"Symbol's value as variable is void" when adding a path to coqtop when opening emacs

I am trying to run emacs with proof generale to open Coq files. However, when I open emacs I get the following error message:
Symbol's value as variable is void: “/Users/myusername/.opam/default/bin/coqtop”
My emacs file is as follows:
(setq coq-prog-name “/Users/username/.opam/default/bin/coqtop”)
(require 'package) ;; (setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3") ; see remark below (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t) (package-initialize)
(custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(package-selected-packages '(proof-general))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. )
Any advice on how to make my emacs work with coqtop?
Emacs treats “/Users/myusername/.opam/default/bin/coqtop” as a symbol because it's a sequence of ordinary characters. It does not start with an (ASCII) double quote, it starts with the character “ and ends with the character ”. They non-ASCII left and right double quotes. Use the ASCII quote ", which is the string delimiter in Emacs Lisp (and many other programming languages).
(setq coq-prog-name "/Users/username/.opam/default/bin/coqtop")
Don't edit source code with word processors that insert “smart quotes” and other features meant for text read by humans. The best place to edit your Emacs configuration is Emacs itself. Emacs knows what type of file you're editing and won't do such substitutions in programming modes (unless you've gone out of your way to configure it to do so, in which case, don't).

Indent code in org-babel src blocks

In an org-mode file, with code like the following:
#+begin_src emacs-lisp
(add-to-list 'org-tab-before-tab-emulation-hook
(lambda ()
(when (within-the-body-of-a-begin-src-block)
(indent-for-tab-command--as-if-in-lisp-mode))))
#+end_src
I would like the TAB key to indent the code as it would if it were in a buffer in lisp mode.
What I need is:
A way to figure out whether the cursor is within a src block. It needs to not trigger when on the header line itself, as in that case the default org folding should take place.
A way to indent the code according to the mode (emacs-lisp in this case) specified in the header.
Org can already syntax highlight src blocks according to mode, and the TAB hooks are there. This looks do-able.
Since Emacs 24.1 you can now set the following option:
(setq org-src-tab-acts-natively t)
...and that should handle all src blocks.
Just move point into the code block and press C-c '
This will pop up a buffer in elisp-mode, syntax higlighting ad all...
Here's a rough solution:
(defun indent-org-src-block-line ()
"Indent the current line of emacs lisp code."
(interactive)
(let ((info (org-babel-get-src-block-info 'light)))
(when info
(let ((lang (nth 0 info)))
(when (string= lang "emacs-lisp")
(let ((indent-line-function 'lisp-indent-line))
(indent-for-tab-command)))))))
(add-to-list 'org-tab-before-tab-emulation-hook
'indent-org-src-block-line)
It only handles emacs-lisp blocks. I've only tested with the src block un-indented (not the org default).
It is tough in general to make one mode work inside another - many keyboard commands will conflict. But some of the more basic strokes, like tab for indent, newline, commenting (org will comment the lisp code with #, which is wrong) seem like they could be made to work and would have the largest impact.
(defun my/org-cleanup ()
(interactive)
(org-edit-special)
(indent-buffer)
(org-edit-src-exit))
should do it, where `indent-buffer' is defined as:
(defun indent-buffer ()
(interactive)
(indent-region (point-min) (point-max)))

Emacs change file extension - mode association

My Emacs opens .m files in ObjC mode. However I want to open them in Octave mode. I have already added to the .emacs file:
(autoload 'octave-mode "octave-mod" nil t)
(setq auto-mode-alist (cons '("\\.m$" . octave-mode) auto-mode-alist))
What else should I do? I do have Octave mode installed.
Fortunately everything is working now and unfortunately I don't remember how I fixed it :) Maybe there was an error in my .emacs earlier. This is the more correct code:
(add-to-list 'auto-mode-alist '("\\.m$" . octave-mode))
Autoloading is unneeded in recent versions; if you do need to enable it, note that "octave-mode" is not a typo.
(autoload 'octave-mode "octave-mod" nil t)
Use this.
;; octave-mode
(autoload 'octave-mode "octave-mode" "Loding octave-mode" t)
(add-to-list 'auto-mode-alist '("\\.m\\'" . octave-mode))
Just ran into this exact problem.
Your statement is correct, but your .emacs file probably isn't loading up correctly. Emacs searches the "HOME" variable to load up preferences, lisp code etc.
To see what your HOME variable is:
Open scratch buffer (this is a "play place" to try things out):
C-x C-b *scratch* <RET>
Evaluate this expression by typing it, then putting the cursor to the right, then hitting C-x C-e
insert (getenv "HOME")
Emacs will display your home path at the bottom (mine defaulted to ...Documents and Settings\UserName)
I haven't worked out a good way to change it, but you're supposed to be able to simply add HOME as an environment variable (that didn't work for me).
It's also talked about a bit more over here:
http://www.gnu.org/software/emacs/manual/html_node/emacs/Windows-HOME.html
Also remember that the file has to be ".emacs" and not myConfig.emacs or something of the like. Use bash command ren to rename the file (windows explorer won't let you have nameless files)

Auto-complete mode doesn't turn on automatically in ObjC buffers

I load auto-complete mode like this:
(let ((ac-path "path/to/auto-complete"))
(add-to-list 'load-path ac-path)
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories (concat ac-path "ac-dict"))
(ac-config-default))
It works fine with C major mode, but doesn't turn on automatically when I open ObjC files. I can still turn it on manually and it will work fine along with the ObjC major mode.
Here's a snippet from the docs regarding ObjC major mode:
The hook `c-mode-common-hook' is run with no args
at mode initialization, then `objc-mode-hook'.
If I understand correctly, auto-complete adds a hook to the c-mode-common-hook, but objc-mode-hook somehow overrides it. Is there a way to fix this?
Thanks.
While looking through the source code of auto-complete.el, I've stumbled upon this definition
(defcustom ac-modes
'(emacs-lisp-mode
lisp-interaction-mode
c-mode cc-mode c++-mode
java-mode clojure-mode scala-mode
scheme-mode
ocaml-mode tuareg-mode
perl-mode cperl-mode python-mode ruby-mode
ecmascript-mode javascript-mode js-mode js2-mode php-mode css-mode
makefile-mode sh-mode fortran-mode f90-mode ada-mode
xml-mode sgml-mode)
"Major modes `auto-complete-mode' can run on."
:type '(repeat symbol)
:group 'auto-complete)
It turns out that auto-complete doesn't have a true global mode. It is enabled only with those major modes that are included in the ac-modes variable.
So, adding the following line to the .emacs file has solved the issue for me.
; add this line after the auto-complete mode has been loaded
(add-to-list 'ac-modes 'objc-mode)
Use the following:
(defun my-objc-mode-hook ()
(auto-complete-mode 1))
(add-hook 'objc-mode-hook 'my-objc-mode-hook)
Note 1: The function auto-complete-mode is a toggle function, when called with no arguments.
Note 2: It's possible to add an anonymous function using lambda, but this have several drawbacks. The most important ones are: modifying the function and reevaluating the expression will add the modified function in addition to the earlier version and C-h v xxx will print the full unformatted lambda function, which typically is hopeless to read and understand.
(add-hook 'objc-mode-hook 'auto-complete-mode)
That should do it if you're using auto-complete-mode. You can add more complex things to mode hooks by doing:
(add-hook 'objc-mode-hook '(lambda ()
(something-with arguments)))
Note that both arguments to add-hook are quoted, this is necessary and if you add unquoted functions they will probably not work.

How to tell emacs to open .h file in C++ mode?

What lines should I add to my _emacs (on Windows) file to have it open .h files in C++ mode? The default is C mode.
Try this:
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
Whenever you open .h files, C++-mode will be used.
Another approach for using both c-mode and c++-mode as appropriate, is to use directory local variables to set the mode.
Directory variables are evaluated after the mode has been set1, so you can actually write a .dir-locals.el file for your C++ project containing this:
((c-mode . ((mode . c++))))
And Emacs will change the mode to c++-mode whenever it had initially set it to c-mode.
If you work with a mix of C and C++ projects, this makes for a pretty trivial solution on a per-project basis.
Of course, if the majority of your projects are C++, you might set c++-mode as the default2, and you could then use this approach in reverse to switch to c-mode where appropriate.
1 normal-mode calls (set-auto-mode) and (hack-local-variables) in that order. See also: How can I access directory-local variables in my major mode hooks?
2 To do so, add
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
to your .emacs file which open .h files in C++ mode by default.
If you don't want this to apply to every .h file, you can add the following to the bottom of your C++ header files.
// Local Variables:
// mode: c++
// End:
This will work for any Emacs variables that you want to set on a per file basis. Emacs ignores the leading characters, so use whatever comment characters are appropriate for the file type.
Apparently you can also put this at the top of the file:
// -*-c++-*-
to tell Emacs it's a C++ file.
I use this since I quite frequently end up on a vanilla Emacs and it works without configuring Emacs in any way.
Since I use both C and C++ regularly, I wrote this function to try and "guess" whether a .h file is meant to be C or C++
;; function decides whether .h file is C or C++ header, sets C++ by
;; default because there's more chance of there being a .h without a
;; .cc than a .h without a .c (ie. for C++ template files)
(defun c-c++-header ()
"sets either c-mode or c++-mode, whichever is appropriate for
header"
(interactive)
(let ((c-file (concat (substring (buffer-file-name) 0 -1) "c")))
(if (file-exists-p c-file)
(c-mode)
(c++-mode))))
(add-to-list 'auto-mode-alist '("\\.h\\'" . c-c++-header))
And if that doesn't work I set a key to toggle between C and C++ modes
;; and if that doesn't work, a function to toggle between c-mode and
;; c++-mode
(defun c-c++-toggle ()
"toggles between c-mode and c++-mode"
(interactive)
(cond ((string= major-mode "c-mode")
(c++-mode))
((string= major-mode "c++-mode")
(c-mode))))
It's not perfect, there might be a better heuristic for deciding whether a header is C or C++ but it works for me.
I could swear I saw this question answered appropriately already? Weird.
You want this:
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))