How to extend Neotree to open a file using hexl? - emacs

I'm trying to extend Neotree to open a file using hexl-mode with the shortcut C-c C-x. How would one do this?
I've tried to evaluate a key definition after the Neotree load where it uses my/neotree-hex to open a file path using neo-buffer--get-filename-current-line.
(defun my/neotree-hex
(hexl-find-file neo-buffer--get-filename-current-line))
(with-eval-after-load 'neotree
(define-key neotree-mode-map (kbd "C-c C-x")
'my/neotree-hex))

At the very least, you are missing the (empty) argument list in the function:
(defun my/neotree-hex ()
(hexl-find-file neo-buffer--get-filename-current-line))
I don't know what neo-buffer--get-filename-current-line is: if it is a function, then you are not calling it correctly - in lisp, you call a function by enclosing the (name of the) function and its arguments in parens: (func arg1 arg2 ...)[1]; so if it is a function and it takes no arguments, then your function should probably look like this:
(defun my/neotree-hex ()
(interactive)
(hexl-find-file (neo-buffer--get-filename-current-line)))
In order to be able to bind it to a key, you have to make your function a command, which means that you need to add the (interactive) form.
Disclaimer: I know nothing about neotree.
[1] You might want to read an introduction to lisp. One (specifically tailored to Emasc Lisp) is included with the emacs documentation, but is also available online. Eventually, you will want to read the Emacs Lisp Reference Manual. Calling a function is covered in the Introduction and is covered in detail in the Reference.

Related

I'm trying to shadow find-file in Emacs, why is this function yelling at me about arguments?

I'm a recent convert to Evil-mode from Vim and I'm trying to make the environment more familiar. One of the things I miss is the find command in Vim. I'm trying to set up something similar in Emacs by wrapping the find-file command in a function. So far I have this:
(defun find nil
"Shadow vim find command, with helm."
(interactive)
(find-file))
When I run the command it yells at me, Wrong number of arguments {doc string} 0 I've tried adding arguments and had no success. The really confusing bit is that I shadowed a helm function the same way and it worked, like this:
(defun buflist nil
"List buffers in helm."
(interactive)
(helm-buffers-list))
What's different? How do I fix this?
find-file takes a file name as argument, you will want to get familiar with C-h f to lookup up function documentation.
interactive can take arguments, for example,
(defun find (filename)
(interactive "F")
(find-file filename))
find-file needs arguments, you can't call it just like
(find-file)
The debugger shows what arguments are needed:
(filename &optional wildcards)
You can also invoke help to see them: C-hf.
Another option is to use call-interactively:
(call-interactively 'find-file)

In emacs how to create a mapping to a function returned by another function?

I'm using emacs with evil-mode, I want to map <leader>tt to the function projectile-dired however if a dired buffer is being shown then it should be mapped to the evil-delete-buffer, so in essence creating a map to a toggle function.
After learning the basics of emacs lisp I came up with this solution:
(defun toggle-projectile-dired ()
"Toggles projectile-dired buffer."
(interactive)
(or
(when (derived-mode-p 'dired-mode)
(evil-delete-buffer (current-buffer)))
(projectile-dired)))
;; This is how the mapping is done
(evil-leader/set-key "tt" 'toggle-projectile-dired)
But what I did with this solution was to create a map to a function that in the end calls to another function.
While my solution works (and I'm fine with it) what I could not do was to return the function to be called (instead of calling it, as I did) how such approach should be written?
Or in other words, how to return a function name and make that mapping call the returning function?.
PD: This question is just for the sake of learn some elisp. Thanks!
EDIT:
Here is some pseudo code (javascript) of what I want to achieve:
function toggleProjectileDired() {
if (derivedModeP == 'dired-mode') {
// We're in dired buffer
return 'evilDeleteBuffer';
} else {
return 'projectileDired';
}
}
evilLeaderSetKey("tt", toggleProjectileDired());
My solution in pseudo code is:
function toggleProjectileDired() {
if (derivedModeP == 'dired-mode') {
// We're in dired buffer
evilDeleteBuffer();
} else {
projectileDired();
}
}
evilLeaderSetKey("tt", toggleProjectileDired);
As you can see, one returns the function name to be called while the other calls the function. How to return a function name to be called in elisp?
(Caveat: I don't use evil, and am not familiar with its custom keybinding functions.)
The canonical approach to making a key do one thing in dired-mode and another thing elsewhere is to define one binding in dired's keymap, and another binding in the global keymap (or whatever is appropriate). I would recommend that you try to follow this approach in most circumstances, because it makes it much simpler to see what's happening.
However, there is a way to do what you're asking for. These pages demonstrate some variations on the approach:
https://stackoverflow.com/a/22863701
http://endlessparentheses.com/define-context-aware-keys-in-emacs.html
http://paste.lisp.org/display/304865
In essence you use the :filter facility of menu items (n.b. menus are actually fancy keymaps in Emacs) to determine the command at run-time. Note that if the filter function returns nil, Emacs treats it as if no binding exists in that keymap, and continues looking for a binding in the remaining keymaps; so this feature facilitates bindings which are only conditionally active.
A non-evil version of your example might look like this:
(define-key global-map (kbd "<f6>")
`(menu-item "" projectile-dired
:filter ,(lambda (default)
(if (derived-mode-p 'dired-mode)
'evil-delete-buffer
default))))
Again, this would be more usual:
(global-set-key (kbd "<f6>") 'projectile-dired)
(eval-after-load "dired"
'(define-key dired-mode-map (kbd "<f6>") 'evil-delete-buffer))
FWIW, I actually think the general approach you started with is probably the best one in this instance. If typing KEY should always toggle dired in that window, then binding it to a toggle-dired command seems like the most self-explanatory implementation.

Function Definition - Don't know how to find

I use SlimeNav to read elisp code. It works good mostly, but for inbuilt functions, at times, it does not work.
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
In this snippet, when i press Alt + . on local-file function, it says,
Don't know how to find 'local-file'
local-file is not a function anywhere in the core. It's used as a let-bound variable 7 times though.
Maybe you confused it.
Also remember that when accessing the documentation on a function (eg with C-h f), you should see a link you can click to get to the source code. Works also with the C sources if they are available in a way Emacs can find.
As an example, the documentation for find-file looks like this:
find-file is an interactive compiled Lisp function in `files.el'.
It is bound to <open>, C-x C-f, <menu-bar> <file> <new-file>.
(find-file FILENAME &optional WILDCARDS)
Edit file FILENAME.
...
You should be able to see that `files.el' comes out in a different colour, this you can click and it will bring you to the definition of that function.

How to find the location, where an an Emacs Lisp function is bound to a key?

I'm trying to figure out where M-m is bound to back-to-indentation function. When I issue C-h k M-m (describe-key), I get the following output
M-m runs the command back-to-indentation, which is an interactive
compiled Lisp function in `simple.el'.
It is bound to M-m.
(back-to-indentation)
Move point to the first non-whitespace character on this line.
When I look at simple.el, I'm seeing only the definition of function back-to-indentation. I searched throughout the file and I didn't see any keybinding done for that function using define-key. I'm assuming that it happens elsewhere.
How can I identify the location where the function is bound to M-m key?
Emacs version: GNU Emacs 24.2.1 (x86_64-apple-darwin12.2.0, NS apple-appkit-1187.34)
I don't know if that's possible in general, but my guess would be that Emacs doesn't remember where the code was that defined a given key.
C-hb will show the current bindings, from which you can establish which keymap you're interested in, and work from there. For most major or minor mode maps, it won't be too difficult to find the code.
Your specific example is a global binding which Emacs configures in bindings.el.
Adding this at the beginning of my .emacs did the trick for me:
(let ((old-func (symbol-function 'define-key))
(bindings-buffer (get-buffer-create "*Bindings*")))
(defun define-key (keymap key def)
(with-current-buffer bindings-buffer
(insert (format "%s -> %s\n" key def))
(mapbacktrace (lambda (evald func args flags)
(insert (format "* %s\n" (cons func args))))))
(funcall old-func keymap key def)))
The idea is that I redefine the define-key function (which is used to bind key within keymap to def) to first log its arguments to a buffer *Bindings*, together with the stacktrace of where it's being called from. After that it calls the old version of the function.
This creates a closure to store the old value of define-key, so it depends of lexical-bindings being t. In retrospect, I think it would have been possible to use function advising instead; but using a closure felt simpler.
Since I had this at the beginning of my .emacs, this recorded all calls to define-key during initialization. So I just had to switch to that buffer once initialization finished, find the call where the particular key was bound, and then inspect the backtrace to find the site from which that happened.

How does the following statement is interpreted by emacs

https://stackoverflow.com/a/663636/391104
(defun my-c++-mode-hook ()
(setq c-basic-offset 4)
(c-set-offset 'substatement-open 0))
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Based on my investigation, I just need to add the above code into my .emacs and then it works magically.
Q1> What does defun my-c++-mode-hook () mean? a function definition in lisp?
Q2> What is the usage of following line? where should I trigger it or it is run automatically by emacs
(add-hook 'c++-mode-hook 'my-c++-mode-hook)
Thank you
Q1: Yes, this is a function definition (hence defun). The second symbol is the name, which has the suffix '-hook' to indicate to humans that it is intended to be used as a hook. It could be given (almost) any arbitrary name without changing its behaviour. The empty () indicates the function takes no arguments. Everything else is the body of the function.
Q2: Basically, this adds a pointer to the previous function to the list of functions that are called when ever c++-mode is started. Whenever you start a mode, the Emacs looks for the mode hook, running all the functions in it. Both the function definition and the add-hook line need to go in your .emacs, and they will be run automatically when you start emacs.
To wrap your head around elisp, the introduction is highly recommended. It ships with emacs, and can be accessed from the info system: C-h i, then look for Elisp Introduction.