When I follow a link in org-mode the attach directory is not found initially; I always have to execute org-attach-sync first. How can I solve this? - emacs

Consider the org-mode section:
Section
:PROPERTIES:
:DIR: directory
:END
[[attachment:file]]
When I follow this last link for the first time (i.e, I try to open "directory/file"), I get a Yes/No dialog stating "No match - Create this as a new heading?". Then I always have to answer "No" and then execute org-attach-sync for activating the link. How can I solve this problem?, i.e, how can I get org-mode to automatically sync the attach directory and follow the link from the start?

org-attach is not loaded once you load org.
If you don't mind the startup time, you can just
(with-eval-after-load 'org
(require 'org-attach))
Or If you want to defer org-attach, here is an use-package example:
(use-package org-attach
:defer t
:commands (org-attach-follow org-attach-complete-link)
:init
(org-link-set-parameters "attachment"
:follow #'org-attach-follow
:complete #'org-attach-complete-link))

Related

emacs > org mode > agenda - always use current buffer

I am using many different org mode files for various projects, and I rev them by adding the date to the filename eg filename-2020-09-17.org. I realize I could use version control but in this case that is not possible, due to needing to share the file with others who are not using VC.
I would like the Agenda to always show just the items for the current file/buffer.
When I save eg the file with filename-2020-09-16.org to filename-2020-09-17.org, then the agenda still shows the old file name unless I remove it from the agenda file list and add the new file.
I realize that I can use C-c a < a but I am lazy and would rather not have to type S-, each time to get the <.
I looked at
Agenda view of the current buffer
And the OP says the solution was simple but he/she/they did not provide the solution - at least I don't see it and I tried the posted code but it no works.
I also found https://www.reddit.com/r/orgmode/comments/bxwovd/agenda_for_current_buffer/ but that did not seem to meet my need.
Specifically I would like to put something in .emacs so that this would apply to all files all the time.
I also looked into a keystroke macro programs but this does not seem ideal.
Any help is appreciated.
Thanks ahead of time.
Here's a simple function to do what you want, but there is no error checking to make sure e.g. that you are invoking it from a buffer that is visiting an Org mode file. The idea is that you set the org-agenda-files list to contain just the file which the buffer is visiting and then you call the regular org-agenda function. Binding the modified function to the C-c a key may or may not be what you want to do, but you can try and decide for yourself:
(defun org-agenda-current-buffer ()
(interactive)
(let ((org-agenda-files (list (buffer-file-name (current-buffer)))))
(org-agenda)))
(define-key global-map (kbd "C-c a") #'org-agenda-current-buffer)

Emacs: Update git-gutter annotations when staging or unstaging changes in magit-status buffer

I use git-gutter for visualizing changes I make to version-controlled files, and magit for staging/committing/diffing etc.
When working on a project I usually keep a magit-status window open at all times. The problem I have is that when I stage or unstage changes in the magit-status buffer and then switch back to the window showing the file whose status I just updated, the fringe annotations produced by git-gutter are not adjusted automatically. (My current workaround to trigger an update is to hit SPC Backspace followed by C-x C-s to save the file, but that's not very efficient.)
I looked at git-gutter.el, and sure enough it provides a customizable variable called git-gutter:update-hooks which is set to
(after-save-hook after-revert-hook window-configuration-change-hook)
by default. So all I really need to do is add the correct hook to this list and I should be good to go. What's the name of the hook that is run when switching windows? I've looked at various sections of the Elisp manual and haven't been able to find what I am looking for. Alternatively, does magit provide a hook that is run when staging or unstaging changes?
EDIT:
If you are reading this because you're facing a similar problem: Both of the answers I got below are working solutions! For newer versions of magit, #lunaryorn's solution is short and sweet. #Jordon Biondo's solution requires adding a bit more custom code, but comes with generalizable (!) advice for creating custom hooks and injecting them into existing functionality. So, since I can only accept one answer: Boost your SO karma by rewarding both posters with an upvote :)
Edit: with the latest versions of magit and git-gutter, this no longer requires so much configuration, see lunaryorns answer for a more up to date and simple solution.
Original Answer:
The switching window method might be a bit overkill since you'll be refreshing more than you need to be.
Magit does not offer before/after stage/unstage hooks, however we can make our own hooks using advice!
You can define two variables for your stage and unstage hooks.
(defvar my-magit-after-stage-hooks nil
"Hooks to be run after staging one item in magit.")
(defvar my-magit-after-unstage-hooks nil
"Hooks to be run after unstaging one item in magit.")
There is a nice wrapper function for running hooks: run-hooks we will use function advice to run our custom hooks after magit-stage-item and magit-unstage-item
(defadvice magit-stage-item (after run-my-after-stage-hooks activate)
"Run `my-magit-after-stage-hooks` after staging an item in magit."
(when (called-interactively-p 'interactive)
(run-hooks 'my-magit-after-stage-hooks)))
(defadvice magit-unstage-item (after run-my-after-unstage-hooks activate)
"Run `my-magit-after-unstage-hooks` after unstaging an item in magit."
(when (called-interactively-p 'interactive)
(run-hooks 'my-magit-after-unstage-hooks)))
For our hook we can just iterate over all the buffers, and refresh git-gutter when applicable because we don't know what is staged or unstaged. So We will just refresh the git-gutter display on all visible buffers that are running git-gutter-mode. (If you'd like to do all git-gutter buffers, just remove the get-buffer-window call.)
(defun my-refresh-visible-git-gutter-buffers ()
"Refresh git-gutter-mode on all visible git-gutter-mode buffers."
(dolist (buff (buffer-list))
(with-current-buffer buff
(when (and git-gutter-mode (get-buffer-window buff))
(git-gutter-mode t)))))
Finally, just add your hook function to your custom hook!
(add-hook 'my-magit-after-unstage-hooks
'my-refresh-visible-git-gutter-buffers)
(add-hook 'my-magit-after-stage-hooks
'my-refresh-visible-git-gutter-buffers)
Ideally we would know what file(s) got staged/unstaged and only refresh those buffers, if you could use around advice on a deeper magit function and get the name of the magit status buffer item you are acting on and refresh only that. But this is a good start!
This is what I needed to do with current magit:
(add-hook 'magit-post-refresh-hook
#'git-gutter:update-all-windows)
Please note that current version of magit does not use `magit-revert-buffer-hook'. So, lunaryorn's solution may not work.
You can add git-gutter update hooks function of magit-after-revert-hook and magit-not-reverted-hook that are called when magit refreshes all visited buffers from current repository (e.g after commit or "g" command):
(add-hook 'git-gutter:update-hooks 'magit-after-revert-hook)
(add-hook 'git-gutter:update-hooks 'magit-not-reverted-hook)

Org-mode: embed links to info files

I maintain a diary (internal blog containing thoughts to remember) in org-mode, and sometimes, as i study Emacs, i store learned skills and tricks with references to info files.
Currently i do the following. I open the needed info file, press c to copy current node name, press < s TAB - that is an easy template which unwraps into a src-block. Then i add lisp expression and paste node name and finally the link looks like this:
#+begin_src emacs-lisp
(info "(org) Properties and Columns")
#+end_src
When i need to view the info file, i put cursor after lisp sexp and press C-x C-e (eval-last-sexp).
This process is tedious and inelegant. What is the best way to embed links to info files in org-mode?
Edit: I've found how one can add links to info nodes. Org-mode manual on External links describes these equivalent methods using links:
[[info:org#Tags]]
[[elisp:(info "(org) Tags")]]
With the first variant i'm not sure how to automatically transform (org) Tags in org#Tags. How can i further simplify this process?
You do it as in any of the supported link types (see the "Handling
links" section in the manual). In the info file, you say M-x org-store-link,
(bind it to C-c l as suggested in the manual) and then in your org
file, you insert the link with C-c C-l. There you just have to
select the link to your info file from the list of stored links.
org-store-link says "Cannot link to a buffer which is not visiting a file" when visiting an Info page because Info sets the buffer-name to *info* and the buffer-file-name to nil. To work around this, the community contributed example of how to add linking to man pages (http://orgmode.org/manual/Adding-hyperlink-types.html) can be modified slightly:
;; Modified version of contrib/lisp/org-man.el; see
;; (http://orgmode.org/manual/Adding-hyperlink-types.html#Adding-hyperlink-types)
(require 'org)
(org-add-link-type "info" 'org-info-open)
(add-hook 'org-store-link-functions 'org-info-store-link)
(defcustom org-info-command 'info
"The Emacs command to be used to display an info page."
:group 'org-link
:type '(choice (const info)))
(defun org-info-open (path)
"Visit the infopage on PATH.
PATH should be a topic that can be thrown at the info command."
(funcall org-info-command path))
(defun org-info-store-link ()
"Store a link to an info page."
(when (memq major-mode '(Info-mode))
;; This is a info page, we do make this link
(let* ((page (org-info-get-page-name))
(link (concat "info:" page))
(description (format "Infopage for %s" page)))
(org-store-link-props
:type "info"
:link link
:description description))))
(defun org-info-get-page-name ()
"Extract the page name from Info in a hackish way."
;; This works for `Info-mode'.
;; Hackity-hack: copy the node name into the kill ring.
(Info-copy-current-node-name)
;; Just return the kill.
(current-kill 0))
(provide 'org-info)
The important bit is near the end: since the info node name is not directly accessible (not that I could easily find), we can work around it by calling Info-copy-current-node-name to put it in the kill-ring, then return the first entry in the kill-ring (which should be the just inserted node name).
The step that should work
- go to info node you need then press just 'c' (node-name will be
entry to kill ring)
- on your org source-file go to point you need to insert the link
press C-c,C-l
- press Tab then select elisp: from prompted buffer shown (or any kind
of link you need).Now your prompt in mini-buffer say elisp:
- entry this context after that ':' (info "^") ,let ^ be your
node-name yank back by C-y
- press Ret ,then you'll be ask for some description just fill it with
your own. Now you are done with it ,but still don't know what happen
really.
- M-x,visibility-mode,And there how to write that content manually and
we are now came to conclusion that "%20" must be replace every
occurence of space in the context.
eg.==> do it yourself ,see it yourself
- switch back your visibility-mode
GoodLuck

Emacs Org-mode - Export to another directory?

I know this is kind of minor, but it's been bugging me. I'm using Org-mode for a project and I tend to export to either PDF or HTML rather frequently and it leaves my directory littered with PDF, Tex, and HTML files. Is there a way to have Org-mode export to another location, perhaps a subdirectory called ./exports?
In addition to the use of publishing by modifying your org-publish-project-alist variable as #user1248256 suggested, you can directly specify the org-export-publishing-directory variable within your file:
#+bind: org-export-publishing-directory "./exports"
* This is a test headline
Some text here. This should be exported to the "./exports" directory.
Upon export it will be placed in the "exports" directory, but only if that directory exists. If it does not exist, you will get an error message in the console.
The original question referred to exporting of org-files, while most answers above actually have to do with publishing, which is a different concept.
I believe the best way to solve the problem posed by the OP is to add the following to your emacs initialization file (.emacs):
(defadvice org-export-output-file-name (before org-add-export-dir activate)
"Modifies org-export to place exported files in a different directory"
(when (not pub-dir)
(setq pub-dir "exported-org-files")
(when (not (file-directory-p pub-dir))
(make-directory pub-dir))))
PS:
I realize a 5 year old question might no longer be relevant to the OP, but hopefully people searching for similar stuff will benefit from this answer.
This is a slight modification of a code snippet found in http://rwx.io/posts/org-export-configurations/
The original solution found in the above blog allows for setting up different directories for each exported format. However, if the goal is to avoid having
one's directory "littered with PDF, Tex, and HTML files", I think it is best to have only one directory containing exported files of all formats, which is the essence of the modification I offered above.
Edit: The emacs manual (https://www.gnu.org/software/emacs/manual/html_node/elisp/Porting-old-advice.html#Porting-old-advice) states that the defadvice mechanism was made obsolete by the new advice-add. So here is a code snipet with the same effect, using the recommended advice-add:
(defun org-export-output-file-name-modified (orig-fun extension &optional subtreep pub-dir)
(unless pub-dir
(setq pub-dir "exported-org-files")
(unless (file-directory-p pub-dir)
(make-directory pub-dir)))
(apply orig-fun extension subtreep pub-dir nil))
(advice-add 'org-export-output-file-name :around #'org-export-output-file-name-modified)
As before, this should be placed in your .emacs file.
This probably wasn't possible when the question was first asked, but the simplest solution would be to add the directory to the :EXPORT_FILE_NAME: property:
:PROPERTIES:
:EXPORT_FILE_NAME: exports/<filename>
:END:
Just as in the accepted answer, the directory must exist in order for this to work.
You have to put the following line at the beginning of your org file :
#+EXPORT_FILE_NAME: PATH/filename
Where PATH is the path to the folder where you want your file to be exported (e.g. ~/exports) and filename the name you want to give to your exported file (e.g. tutorial.html).
I believe you can get that with org-publish.
Add to you emacs configuration file something like that:
(setq org-publish-project-alist
'(("html"
:base-directory "~/org/"
:base-extension "org"
:publishing-directory "~/org/exports"
:publishing-function org-publish-org-to-html)
("pdf"
:base-directory "~/org/"
:base-extension "org"
:publishing-directory "~/org/exports"
:publishing-function org-publish-org-to-pdf)
("all" :components ("html" "pdf"))))
Eval this expression (or restart emacs), press C-c C-e X at org-mode, then choose a project from a list.
You can see more information at http://orgmode.org/worg/org-tutorials/org-publish-html-tutorial.html and http://orgmode.org/manual/Publishing.html#Publishing
As stated in the section "Export settings", we can use the EXPORT_FILE_NAME within a file in order to set the output directory. The quote shown below is the relevant part of the documentation
‘EXPORT_FILE_NAME’
The name of the output file to be generated. Otherwise, Org generates the file name based on the buffer name and the extension based on the back-end format.

Setup for emacs org-mode outside .emacs file

I would like to set up a project to be published as HTML using org-mode.
I don't want to litter my .emacs with project definitions, and I was wondering where I could put the (setq org-publish-project-alist) variable.
Can I somehow put it in the same dir?
Ryan McGeary describes what I think is a good way to organize emacs startup files.
Update:
The domain emacsblog.org expired :(
You can look at the cached copy of the originally linked page.
You could just add a new file in your .emacs.d (or whereever) and do a load-file in your .emacs file.
-- EDIT --
For example, you could have the following in your .emacs
(load (expand-file-name "~/.emacs.d/lisp/personal-org-mode-stuff.el"))
and then put all of your customization stuff in ~/.emacs.d/lisp/personal-org-mode-stuff.el and it will load that file and import all of your .emacs
Another poster also posted a link to a description of how to add your lisp files to the load path and require them.
If you don't set it manually at all, but rather use Emacs' customize mechanism to control the value of this variable, your .emacs file will not be cluttered if you add the following two lines to your .emacs:
(setq custom-file "~/.emacs-custom.el")
(load custom-file 'noerror)
Although some might claim that it's kind of ironic that you have to add two lines two your .emacs file to declutter it that way...