Copy links from image-dired to org-mode - emacs

I'm working with directories full of images, which are photographs of documents in an archive. I'm writing org files with notes on the content of these, and I would like to make it quicker and easier to browse the images (e.g. with image-dired) and copy links into the org-mode file alongside my notes.
My working setup looks like this:
My questions are:
How can I automatically copy a link for the currently displayed image into org?
Is there any easy way to control the image-dired picture (browsing backwards and forwards, rotating) from within the org windows?
Are there any other modes or tools that I should be looking at?

Here is a little code to make working with images easier. Just copy it into your *scratch* buffer and run M-x eval-buffer.
(defun my-next-image ()
(interactive)
(save-excursion
(with-current-buffer "*image-dired*"
(image-dired-forward-image)
(image-dired-display-thumbnail-original-image))))
(defun my-prev-image ()
(interactive)
(save-excursion
(with-current-buffer "*image-dired*"
(image-dired-backward-image)
(image-dired-display-thumbnail-original-image))))
(defun my-insert-current-image-path ()
(interactive)
(insert
(concat
"[["
(save-excursion
(with-current-buffer "*image-dired*"
(image-dired-original-file-name)))
"]]")))
(define-key org-mode-map (kbd "<f9> n") 'my-next-image)
(define-key org-mode-map (kbd "<f9> p") 'my-prev-image)
(define-key org-mode-map (kbd "<f9> i") 'my-insert-current-image-path)
Press F9 n to switch to the next image while in org mode, press F9 i to insert a link to the current image. Rebind keys to your liking.

Related

Display Flycheck buffer (with errors) when saving

In Emacs, what would be the way to display the Flycheck buffer automatically when saving, only if there are errors?
A bit like https://github.com/steelbrain/linter.
I've searched on https://stackoverflow.com/questions/tagged/flycheck?sort=votes&pageSize=50 but did not find anything approaching.
Add the following to ~/.emacs, this will bind it to C-x C-s:
(defun save-buffer-maybe-show-errors ()
"Save buffer and show errors if any."
(interactive)
(save-buffer)
(when (not flycheck-current-errors)
(flycheck-list-errors)))
;; Bind it to some key:
(global-set-key (kbd "C-x C-s") 'save-buffer-maybe-show-errors)

How to customize Emacs key bindings for going to specific line / end of buffer

I want to customize Emacs so that pressing
ESC : n RET
takes me to line number n
and
ESC : $ RET
takes me to the last line. (That's how the vi editor works.)
How can I achieve this inside my Emacs configuration file? Currently I have this in my .emacs:
(global-set-key (kbd "M-9") 'prev-window)
(global-set-key (kbd "M-0") 'other-window)
I don't want to use any of the off-the-shelf solutions (eg. evil) because they are bloated and mess with my existing shortcuts.
Put this in a file and load it (load means execute):
(defun vi-goto-line (arg)
(interactive "sLine:")
(message arg)
(if (string= "$" arg)
(end-of-buffer)
(goto-line (string-to-int arg))
)
)
(global-set-key (kbd "M-:") 'vi-goto-line)
To load it you can use M-xload-file and then enter interactively the path to the file.
Keep in mind that the key combo M-: (which is the same as ESC:) already has a meaning in Emacs, so this now gets cloaked.
Of course you also can load the file from your .emacs by putting (load-file "/path/to/my/file") into the .emacs or put these lines directly into your .emacs file (or any other configuration file which gets loaded)

How can one quickly browse through lots of files in Emacs?

is there a way to quickly browse through lots of files in Emacs (24.3)? More specifically:
Let's assume an Emacs frame is split into two windows. Suppose focus is in the left window that has an open 'dired' buffer with lots of text files (or code). I would like to go up and down the list of files (e.g. with cursor keys), while at the same time the current file is shown in the right window. Even better the file is only viewed and closed once I move in the dired buffer to the next file. This would be very useful especially together with some 'omit' mode.
Can this be done in 'dired'? I also coudn't find this functionality in dired-x or in sunrise-commander. Is it possible?
The best candidates I tried already (and why they not solve the problem):
'v' which shows the current file, but also moves the attention
'C-o' which shows the current file, but after moving up or down, I have to press C-o again, also it generates lots of buffers
Thanks a lot for your help!
A simple and generic (while not optimum) solution could be via the C-x () mechanism.
First open the two panes in Emacs, with - say - top one being dired.
Press o to open the first file in the 2nd pane.
Then you can start the repetition mechanism:
do C-x ( to start recording a macro
do C-x k and return to close the buffer
do o again to go back to dired
do down key to go to next file
do o to open next file in bottom pane
do C-x ) to end the macro
From that point (being in bottom pane, dired in top pane), doing a mere
C-x e (and then only e if there is no other operation in between)
will automatically
close bottom pane file, go to top pane, down to next file, open it in bottom pane
There is maybe a more specific way to do that, but knowing the macro mechanism is anyway very helpful in Emacs.
Here's how I do this with view-mode:
(add-hook 'view-mode-hook
(lambda()
(define-key view-mode-map (kbd "n") 'dired-view-next)
(define-key view-mode-map (kbd "p") 'dired-view-prev)))
(defun dired-view-next ()
"Move to next dired line and view ."
(interactive)
(quit-window)
(dired-next-line 1)
(dired-view-file))
(defun dired-view-prev ()
"Move to next dired line and view ."
(interactive)
(quit-window)
(dired-next-line -1)
(dired-view-file))
UPD:
This one has two panes:
(defun dired-view-next-pane ()
(interactive)
(other-window 1)
(if view-mode
(kill-buffer))
(other-window -1)
(dired-next-line 1)
(view-file-other-window
(dired-get-file-for-visit))
(other-window -1))
Thanks a lot for all those answers. Summarizing I created the following solution (extending the answer of "abo-abo"):
;; little modification to dired-mode that let's you browse through lots of files
(add-hook 'dired-mode-hook
(lambda()
(define-key dired-mode-map (kbd "C-o") 'dired-view-current) ; was dired-display-file
(define-key dired-mode-map (kbd "n") 'dired-view-next) ; was dired-next-line
(define-key dired-mode-map (kbd "p") 'dired-view-previous))) ; was dired-previous-line
(defun dired-view-next ()
"Move down one line and view the current file in another window."
(interactive)
(dired-next-line)
(dired-view-current))
(defun dired-view-previous ()
"Move up one line and view the current file in another window."
(interactive)
(dired-previous-line)
(dired-view-current))
(defun dired-view-current ()
"View the current file in another window (possibly newly created)."
(interactive)
(if (not (window-parent))
(split-window)) ; create a new window if necessary
(let ((file (dired-get-file-for-visit))
(dbuffer (current-buffer)))
(other-window 1) ; switch to the other window
(unless (equal dbuffer (current-buffer)) ; don't kill the dired buffer
(if (or view-mode (equal major-mode 'dired-mode)) ; only if in view- or dired-mode
(kill-buffer))) ; ... kill it
(let ((filebuffer (get-file-buffer file)))
(if filebuffer ; does a buffer already look at the file
(switch-to-buffer filebuffer) ; simply switch
(view-file file)) ; ... view it
(other-window -1)))) ; give the attention back to the dired buffer
Three keys are changed:
C-o to view the current item in another window (possibly create one).
n to view the next item in another window.
p to view the previous item in another window.
This can be used in a dired buffer. Note that only dired-mode buffers and view-mode buffers get killed while moving up and down. If a file is shown that another buffer is already visiting (not in view-mode), that buffer is shown as well, but not killed when moving to the next. Another subtlety is the case when the passively shown buffer is the dired buffer used for going through the list (this can easily happen, when going inside a folder with RET). To handle this case, we first check whether we are trying to kill the initial dired buffer.
Load Icicles.
Define this command:
(defun my-find-file ()
"Like `icicle-find-file', but alt action views file temporarily.
Alternate action keys such as `C-S-down' visit the candidate file in
`view-mode' and kill the buffer of the last such viewed candidate."
(interactive)
(let ((icicle-candidate-alt-action-fn
(lambda (file)
(when (and my-last-viewed
(get-file-buffer my-last-viewed))
(kill-buffer (get-file-buffer my-last-viewed)))
(setq my-last-viewed (abbreviate-file-name file))
(view-file file)
(select-frame-set-input-focus
(window-frame (active-minibuffer-window))))))
(icicle-find-file-of-content)))
(defvar my-last-viewed nil
"Last file viewed by alternate action of `my-find-file'.")
Then you can:
Use M-x my-find-file (or bind it to a key - e.g., C-x C-f).
Optionally type part of a file name, to limit the matching names.
Optionally use down or up to cycle among file names.
Use C-S-down to visit the next file in order.
Repeat #4 to see other files in order.
Repeat #2 or #3 to see other sets of files.
End with RET to choose a file to visit or C-g to cancel.
Each file buffer you visited with C-S-down was killed when you
viewed the next one. You can also mix in C-down or C-RET to
also visit files whose buffers you do not want to kill
automatically. (Change view-file to find-file if you don't
want to visit in view-mode, which is read-only.)
[By default, the alternate action for icicle-find-file is
icicle-alt-act-fn-for-type, which prompts you for a file-
appropriate action to use on the particular candidate chosen for
the action. Command my-find-file just substitutes a different
alternate action function (for all candidates you choose).]
See also this thread from help-gnu-emacs#gnu.org. It is pretty much the same question as yours, I think. My replies there were pretty much the same as my reply here, but there are also replies from others that might help you as well.
Try
M-x speedbar
That might appeal to you
Another view-mode solution on top of ag-mode lists. I couldn't find a question for ag-mode, maybe this helps someone generalize a ffap-preview for any mode.
(defun directory-ag-results ()
(save-excursion
(goto-char (point-min))
(search-forward "\"")
(setq a (point))
(search-forward "\"")
(setq b (- (point) 1))
(buffer-substring-no-properties a b)))
(defun search-item-path ()
(let ((dir (directory-ag-results))
(file-parts (split-string (substring-no-properties (thing-at-point 'filename)) ":")))
(concat dir (nth 0 file-parts))))
(defun search-item-line ()
(let ((file-parts (split-string (substring-no-properties (thing-at-point 'filename)) ":")))
(- (string-to-number (nth 1 file-parts)) 1)))
(defun view-current ()
"Quickly view the current file in another window."
(if (not (window-parent))
(split-window)) ; create a new window if necessary
(let ((file (search-item-path))
(line (search-item-line))
(dbuffer (current-buffer)))
(other-window 1) ; switch to the other window
(unless (equal dbuffer (current-buffer)) ; don't kill the dired buffer
(if (or view-mode (equal major-mode 'dired-mode)) ; only if in view- or dired-mode
(kill-buffer))) ; ... kill it
(let ((filebuffer (get-file-buffer file)))
(if filebuffer ; does a buffer already look at the file
(switch-to-buffer filebuffer) ; simply switch
(progn
(view-file file) ; ... view it
(goto-char (point-min))
(next-line line)))
(other-window -1))))
(defun next-view-current ()
(interactive)
(next-line)
(view-current))
(defun previous-view-current ()
(interactive)
(previous-line)
(view-current))
(define-key ag-mode-map (kbd "M-p") 'previous-view-current)
(define-key ag-mode-map (kbd "M-n") 'next-view-current)
This is the one thing I think Sublime does better than Emacs. Blasphemy, I know! I like the "q to exit" feel of view-mode, rather than timer-based solutions, and like scrolling around a previewed file. This snippet navigates to the line number found in the search results, optimizing for browsing speed.
Note about the code: I tried polyfilling vc-root-dir from Emacs 25, but it doesn't really make sense for ag-mode since ag-mode's buffer is outside the repo you're searching in. I ended up pulling the root dir from the top of the "ag search" buffer.
Early stages. Improvements welcome.
Demo
Edit: It works for ag-mode, not dired. Demo gif.
Credits: abo-abo, user2979331
In the interest of keeping StackOverflow up to date, the package peep-dired does everything posted in the other answers, and I’m sure there are other packages as well. You don’t have to maintain copypasted or home-rolled lisp for this job.

Show all open buffers in Emacs

In emacs, is there an M-x command or key combo to render all current open buffers into different windows?
For clarity, let's suppose I have four open buffers, and I am only seeing one currently being displayed, and I would like in one step to show each buffer in one quadrant.
I recommend ibuffer. M-x ibuffer is probably what you want. Here's my ibuffer configuration:
;; *Messages* is so annoying. Also, I really like ibuffer
(require 'ibuf-ext)
(add-to-list 'ibuffer-never-show-predicates "^\\*Messages")
(add-to-list 'ibuffer-never-show-predicates "^\\*Completions")
(global-set-key (kbd "C-b") 'ibuffer)
(kill-buffer "*scratch*")
('ibuffer)
(switch-to-buffer "*Ibuffer*")
You will be able to start with the following code if there is not an already-known way to do it:
(defun buffer-in-window-list ()
(let (buffers)
(walk-windows (lambda (window) (push (window-buffer window) buffers)) t t)
buffers))
(defun display-all-buffers ()
(interactive)
(let (buffers-in-window (buffer-in-window-list))
(dolist (buffer (buffer-list))
(when (and (not (string-match "\\`[[:space:]]*\\*" (buffer-name buffer)))
(not (memq buffer buffers-in-window)))
(set-window-buffer (split-window (get-largest-window)) buffer)))
(balance-windows)))
The display-all-buffers command opens a new window for each buffer that is not currently displayed anywhere (including other frames). For usability, it ignores buffers whose names start with * (optionally, prefixed with whitespace characters) because they are usually for internal use only.
Note that Emacs does not allow a user to make too small a window. So, when there are too many buffers to display, the command will display as many buffers as possible in order of most recent display or selection and signal an error.

Automatically jump to tag in Emacs

I'd like to have find-tag automatically accept the default option (i.e. the word at point) and jump to the tag postion without prompting.
Is this possible?
I'm also using the advised version of find-tag from Emacswiki, that in case of match re-runs ctags. So I'd like something like this:
is current word a known tag?
-> yes: jump to it without further confirmation
-> no: rerun ctags
is it known now?
-> yes: jump to it without further confirmation
-> no: prompt user for input
Thank you!
This is one of the top hits on Google for "find tags emacs no prompt." For the simple version of that - without the ctag-regeneration logic the poster mentioned - it seems the key is:
(find-tag (find-tag-default))
So, for me, this works:
(defun find-tag-no-prompt ()
"Jump to the tag at point without prompting"
(interactive)
(find-tag (find-tag-default)))
;; don't prompt when finding a tag
(global-set-key (kbd "M-.") 'find-tag-no-prompt)
Here is my settings for ctags, works awesome for me. I borrow it from here.
(require 'eproject)
(require 'etags-select)
(defun build-ctags ()
(interactive)
(message "building project tags")
(let ((root (eproject-root)))
(shell-command
(concat "ctags-exuberant -e -R --extra=+fq --exclude=db --exclude=test --exclude=.git --exclude=public -f " root "TAGS " root)))
(visit-project-tags)
(message "tags built successfully"))
(defun visit-project-tags ()
(interactive)
(let ((tags-file (concat (eproject-root) "TAGS")))
(visit-tags-table tags-file)
(message (concat "Loaded " tags-file))))
(defun hbin-find-tag ()
"Borrow from http://mattbriggs.net/blog/2012/03/18/awesome-emacs-plugins-ctags/"
(interactive)
(if (file-exists-p (concat (eproject-root) "TAGS"))
(visit-project-tags)
(build-ctags))
(etags-select-find-tag-at-point))
(global-set-key (kbd "M-.") 'hbin-find-tag)
PS: you may be need these:
git://github.com/jrockway/eproject.git
git://github.com/emacsmirror/etags-select.git
Well, I found a hack-y solution:
;; auto jump
(global-set-key (kbd "C-x C-M->") 'find-tag) ; bind to some unused placeholder
(global-set-key (kbd "M-.") (kbd "C-x C-M-> <return>"))
First bind find-tag to some dummy binding that you'll never use anyway (this step is necessary to avoid infinite loops). Then bind M-. to this new binding + <return>.
Ugly, but works... I'll leave the question open if somebody has a better answer (including handling of failed search as described in the original question).
here's a slightly modified version that loads dependent gems (useful in ruby on rails)
(defun build-ctags ()
(interactive)
(message "building project tags")
(let ((default-directory (eproject-root)))
(shell-command (concat "exctags -e -R --extra=+fq --exclude=db --exclude=test --exclude=.git --exclude=public -f TAGS * " (trim-string (shell-command-to-string "rvm gemdir")) "/gems/*"))
(visit-project-tags)
(message "tags built successfully")))
Emacs 25 does this by default. M-. (xref-find-definitions) jumps to the definition and M-, (xref-pop-marker-stack) pops back.