Autoload tuareg-mode for .ml4 files - ocaml

What do I need to change in tuareg.el to get Emacs to automatically load tuareg-mode for .ml4 files?
I can easily change to tuareg-mode manually, but it would be nice not to have to do that.

You don't need to change tuareg.el but your .emacs
(setq auto-mode-alist
(cons '("\\.ml[iylp]?$" . tuareg-mode) auto-mode-alist))
You must have this line in your .emacs so change it with
(setq auto-mode-alist
(cons '("\\.ml[iylp4]?$" . tuareg-mode) auto-mode-alist))
Best :-)

Related

Association list - how set value to the result of a function execution

On high level: I'm trying to create an association list in which value is a result of function execution. What I get instead is an expression which represents that function, and which needs to be wrapped into "eval" to get it to work. I'm trying to understand why, and what makes the behavior different from regular lists.
In more details:
I'm putting together a configuration for org agenda which has a common functionality for all the environments, but then I want to make it possible for a specific environment to add something extra. So, I know that on all the machines org-agenda-files need to include these two dirs: "~/Documents/Org" and "~/Downloads/Org" but I want to let a specific machine to register more dirs in addition to those two and which would only be visible to that machine.
So I build an association list in which machine name is the key, and the value is a list of dirs that need to be handled on that node in addition to those shared by all.
The code looks like this:
;; default-agenda-files are shared by all the environments
(setq default-agenda-files
'("~/Documents/Org" "~/Downloads/Org"))
;; in addition to default, I want to register project-abc
;; dirs for nodeABC and project-xyz dirs for nodeXYZ
(setq per-node-agenda-file-mappings
'(("nodeABC" . (append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
'("nodeXYZ" . (append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))
The code further sets org-agenda-files depending on the machine name.
Here's the problem. If I do
(alist-get "nodeABC" per-node-agenda-file-mappings nil nil 'string-equal)
I get
(append default-agenda-files '("~/Projects/project-abc/doc/" "~/Projects/project-abc/notes"))
rather than
("~/Documents/Org" "~/Downloads/Org" "~/Projects/project-abc/doc/" "~/Projects/project-abc/notes")
I can solve it by doing
(eval (alist-get "nodeABC" per-node-agenda-file-mappings nil nil 'string-equal))
Then everything works.
But I'm trying to understand what's going on there and why same thing doesn't happen with regular lists (with regular lists, evaluation does happen at the time of assignment). Is there a way to make evaluation happen at the time of assignment in this case too? I double-checked, same thing happens if I use hash-table instead of association list.
There's nothing different about using alists from other lists. What you want here is to evaluate some things and not evaluate others. Just do that: quote only the things you don't want evaluated.
You don't need to explicitly invoke eval - Lisp already invokes it implicitly. All you need to do is not evaluate things that you want to treat as data. Here, that means strings (those are constant anyway, so evaluating them makes no difference) and any lists that you want to be just, well, lists - e.g., '("~/Projects/project-abc/doc/" "~/Projects/project-abc/notes").
You want to use backquote instead of quote, and use comma before the (append...) sexp:
(setq per-node-agenda-file-mappings
`(("nodeABC" . ,(append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
("nodeXYZ" . ,(append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))
Or this:
(setq per-node-agenda-file-mappings
`(("nodeABC" ,#(append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
("nodeXYZ" ,#(append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))
Or this:
(setq per-node-agenda-file-mappings
(list (cons "nodeABC" (append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
(cons "nodeXYZ" (append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))
Or just this, since the only thing you need to evaluate is variable default-agenda-files:
(setq per-node-agenda-file-mappings
`(("nodeABC" ,#default-agenda-files
"~/Projects/project-abc/doc/" "~/Projects/project-abc/notes")
("nodeXYZ" ,#default-agenda-files
"~/Projects/project-xyz/doc" "~/Projects/project-xyz/notes")))
See the Elisp manual, node Backquote.

How to remove an item from auto-mode-alist (Emacs)

I thought this would be simple when I tried to do it, however I'm stuck.
When I add octave-mode to my ~/.emacs thus:
(add-to-list 'auto-mode-alist ("\\.m$" . octave-mode))
Opening an Octave file, .m, I instead end up in the OBJC major mode ... this is because auto-mode-alist contains:
(\.m\' . objc-mode)
which comes first in the A-list.
I've tried:
(setq auto-mode-alist (delete '( \.m\' . objc-mode) auto-mode-alist))
and I've even tried:
(setq ama '())
(setq objc '(\.m\' . objc-mode))
(dolist (item auto-mode-alist)
(if (not (eq (cdr (last objc)) (cdr (last item))))
(setq ama (list ama item))))
(setq auto-mode-alist ama)
Any suggestions on either removing the objc-mode from the alist or ensuring that octave-mode supercedes it would be great.
There are essentially two questions here. One is how to remove the element from the list. The other is how to automatically open *.m files in octave-mode. You shouldn't need to remove the element to override it. The provided form
(add-to-list 'auto-mode-alist ("\\.m$" . octave-mode))
causes an error. Instead you should use
(add-to-list 'auto-mode-alist '("\\.m$" . octave-mode))
or better yet:
(add-to-list 'auto-mode-alist '("\\.m\\'" . octave-mode))
These two forms will add the element to the beginning of the association list, meaning filenames will be checked against it first, never making it to the objc-mode element lower down the list.
If you really want to remove the element from the list, here are a couple of ways.
One way that only deletes the exact cons cell '("\\.m\\'" . objc-mode):
(setq auto-mode-alist (delete '("\\.m\\'" . objc-mode) auto-mode-alist))
Another way that will delete anything in the association list associated with "\\.m\\'":
(require 'cl-lib)
(cl-remove "\\.m\\'" auto-mode-alist :test 'equal :key 'car)
There's three obstacles here:
Quoting and regexp syntax at the same time
assq-delete-all (the obvious choice) uses eq to compare the keys, which only succeeds (and thus deletes) it finds the same object - it won't succeed if it sees only an identical string
assq-delete-all does not guarantee to modify the list, so another setq is necessary
The solution is clear: find the car object in the alist. Like:
(setq auto-mode-alist (assq-delete-all (car (rassoc 'objc-mode auto-mode-alist)) auto-mode-alist))
After that, You can
(setq auto-mode-alist (add-to-list 'auto-mode-alist '("\.m\'" . octave-mode)))
To add to what was already said, for completion.
For some modes, the auto-mode-alist contains several different entries associating different file extensions to a mode. For example, the racket-mode uses 3 entries:
...
("\\.rktl\\'" . racket-mode)
("\\.rktd\\'" . racket-mode)
("\\.rkt\\'" . racket-mode)
...
If you want to remove those, the single assq-delete-all on the mode symbol is not sufficient, you must loop with something like this:
(while (rassoc 'racket-mode auto-mode-alist)
(setq auto-mode-alist
(assq-delete-all (car (rassoc 'racket-mode auto-mode-alist))
auto-mode-alist))))
I ran on this issue with racket-mode because the built-in scheme-mode associate the .rtk files with scheme-mode and this association was closer to the head of the auto-mode-alist than the ones to racket-mode. Trying to add a new one failed because it was already present. To be able to have racket-mode used with .rkt files while scheme-mode still available for other scheme files, I had to remove the racket-mode entries first and them add them back, placing them in front of the association with the scheme-mode.

manipulate regexp-search matches using `query-regexp-replace` in a defun

Since version 22 of Emacs, we can use \,(function) for manipualting (parts of) the regex-search result before replacing it. But – this is mentioned often, but nonetheless still the truth – we can use this construct only in the standard interactive way. (Interactive like: By pressing C-M-% or calling query-replace-regexp with M-x.)
As an example:
If we have
[Foo Bar 1900]
and want to get
[Foo Bar \function{foo1900}{1900}]
we can use:
M-x query-replace-regexp <return>
\[\([A-Za-z-]+\)\([^0-9]*\) \([0-9]\{4\}\)\]
[\1\2 \\function{\,(downcase \1)\3}{\3}]
to get it done. So this can be done pretty easy.
In my own defun, I can use query only by replacing without freely modifying the match, or modify the prepared replaced string without any querying. The only way I see, is to serialize it in such a way:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
"[\\1\\2 \\\\function{\\1\\3}{\\3}]" ))
(goto-char (point-min))
(while (search-forward-regexp "\\([a-z0-9]\\)" nil t)
(replace-match (downcase (match-string 1)) t nil)
)
)
For me the query is important, because I can't be sure, what the buffer offers me (= I can't be sure, the author used this kind of string always in the same manner).
I want to use an elisp function, because it is not the only recurring replacement (and also not only one buffer (I know about dired-do-query-replace-regexp but I prefer working buffer-by-buffer with replace-defuns)).
At first I thought I only miss something like a query-replace-match to use instead of replace-match. But I fear, I am also missing the easy and flexible way of rearrange the string the the query-replace-regexp.
So I think, I need a \, for use in an defun. And I really wonder, if I am the only one, who is missing this feature.
If you want your rsearch&replace to prompt the user, that means you want it to be interactive, so it's perfectly OK to call query-replace-regexp (even if the byte-compiler will tell you that this is meant for interactive use only). If the warning bothers you, you can either wrap the call in with-no-warnings or call perform-replace instead.
The docstring of perform-replace sadly doesn't (or rather "didn't" until today) say what is the format of the replacements argument, but you can see it in the function's code:
;; REPLACEMENTS is either a string, a list of strings, or a cons cell
;; containing a function and its first argument. The function is
;; called to generate each replacement like this:
;; (funcall (car replacements) (cdr replacements) replace-count)
;; It must return a string.
The query-replace-function can handle replacement not only as a string, but as a list including the manipulating elements. The use of concat archives building an string from various elements.
So one who wants to manipulate the search match by a function before inserting the replacement can use query-replace-regexp also in a defun.
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(query-replace-regexp
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]")) nil ))
match-string 1 returns the first expression of our regexp-search.
`replace-quote' helps us doublequoting the following expression.
concat forms a string from the following elements.
and
replace-eval-replacement is not documented.
Why it is in use here nevertheless, is because of emacs seems to use it internally, while performing the first »interactive« query-replace-regexp call. At least is it given by asking emacs with repeat-complex-command.
I came across repeat-complex-command (bound to [C-x M-:].) while searching for an answer in the source code of query-replace-regexp.
So an easy to create defun could be archieved by performing the standard search and replace way as told in the question and after first sucess pressing [C-x M-:] results in an already Lisp formed command, which can be copied and pasted in a defun.
Edit (perform-replace)
As Stefan mentioned, one can use perform-replace to avoid using query-replace-regexp.
Such a function could be:
(defun form-to-function ()
(interactive)
(goto-char (point-min))
(while (perform-replace
"\\[\\([A-Za-z-]+\\)\\([^0-9]*\\) \\([0-9]\\{4\\}\\)\\]"
(quote (replace-eval-replacement concat "[\\1\\2 \\\\function{"
(replace-quote (downcase (match-string 1))) "\\3}{\\3}]"))
t t nil)))
The first boolean (t) is a query flag, the second is the regexp switch. So it works also perfectly, but it didn't help finding the replacement expression as easy as in using \,.

How do I beautify lisp source code?

My code is a mess many long lines in this language like the following
(defn check-if-installed[x] (:exit(sh "sh" "-c" (str "command -v " x " >/dev/null 2>&1 || { echo >&2 \"\"; exit 1; }"))))
or
(def Open-Action (action :handler (fn [e] (choose-file :type :open :selection-mode :files-only :dir ListDir :success-fn (fn [fc file](setup-list file)))) :name "Open" :key "menu O" :tip "Open spelling list"))
which is terrible. I would like to format it like so
(if (= a something)
(if (= b otherthing)
(foo)))
How can I beautify the source code in a better way?
The real answer hinges on whether you're willing to insert the newlines yourself. Many systems
can indent the lines for you in an idiomatic way, once you've broken it up into lines.
If you don't want to insert them manually, Racket provides a "pretty-print" that does some of what you want:
#lang racket
(require racket/pretty)
(parameterize ([pretty-print-columns 20])
(pretty-print '(b aosentuh onethunoteh (nte huna) oehnatoe unathoe)))
==>
'(b
aosentuh
onethunoteh
(nte huna)
oehnatoe
unathoe)
... but I'd be the first to admit that inserting newlines in the right places is hard, because
the choice of line breaks has a lot to do with how you want people to read your code.
I use Clojure.pprint often for making generated code more palatable to humans.
it works well for reporting thought it is targeted at producing text. The formatting built into the clojure-mode emacs package produces very nicely formatted Clojure if you put the newlines in your self.
Now you can do it with Srefactor package.
Some demos:
Formatting whole buffer demo in Emacs Lisp (applicable in Common Lisp as well).
Transform between one line <--> Multiline demo
Available Commands:
srefactor-lisp-format-buffer: format whole buffer
srefactor-lisp-format-defun: format current defun cursor is in
srefactor-lisp-format-sexp: format the current sexp cursor is in.
srefactor-lisp-one-line: turn the current sexp of the same level into one line; with prefix argument, recursively turn all inner sexps into one line.
Scheme variants are not as polished as Emacs Lisp and Common Lisp yet but work for simple and small sexp. If there is any problem, please submit an issue report and I will be happy to fix it.

Emacs + C/C++ + Doxygen: Alternative to doxymacs? With yasnippet?

I would like to use doxygen to generate code documentation (of functions) in .c or .cc files with Emacs. I found doxymacs, but it seems not to be maintained anymore (latest version 2007) and I also did not find a way to update the documentation of a function if I change the name of one of the parameters of the function ("unfortunately", I'm used to the great Roxygen for .R scripts which can do all nice things, even inserting a documentation right before a function when the point is somewhere in the function).
I found this, but it seems not very useful. However, there is an example here how to use yasnippets. Has anyone written a yasnippet for doxygen headers? Still, it would not update the parameters if the function name changes. Is there any "better" way to work with doxygen in Emacs? I would assume there are quite a lot of C/C++ programmers that work with Emacs and I would guess that there should be a good tool/approach for code documentation.
Update
I also found this. It's purely based on yasnippet (haven't tried it yet, though).
I use the following:
# -*- mode: snippet -*-
# name: cc-doxygen
# key: dox
# type: command
# contributor: Jonathan Kotta <jpkotta#gmail.com>
# --
(let* ((next-func-alist (doxymacs-find-next-func))
(func-name (cdr (assoc 'func next-func-alist)))
(params-list (cdr (assoc 'args next-func-alist)))
(return-name (cdr (assoc 'return next-func-alist)))
(snippet-text "")
(idx 1))
(setq snippet-text (format "/**\n * ${1:%s}\n * \n" func-name))
(setq idx 2)
(dolist (param params-list)
(unless (string= param "this")
(setq snippet-text (concat snippet-text
(format " * \\param %s ${%d:}\n" param idx)))
(setq idx (+ 1 idx))))
(when (and return-name (not (string= return-name "void")))
(setq snippet-text (concat snippet-text
(format " * \\return ${%d:%s}\n" idx return-name))))
(setq snippet-text (concat snippet-text " */"))
(yas/expand-snippet snippet-text))
1. Generate doxygen from Emacs
Which kind of tool are you using for compiling? CMake? Autotools? Scons?
Once I worked with CMake and we created a target to generate documentation with doxygen.
Something like this.
Then you will have to compile like this:
make doc
But this only covers the first part of your question, the documentation before each function it will be made manually. I will try to integrate this solution with yasnippet.