I was trying to make persistent undo history work in emacs.
I have (setq undo-tree-auto-save history t). The history is indeed saved when I save file. But when I open file, the undo history is not loaded until I use undo.
So if I open a file and make some changes, then run M-x undo-tree-visualize, the previous undo tree is gone, only the recent changes are there. But if I run M-x undo-tree-visualize first, then I can see the old undo tree. Or if I just use undo before making any changes, the old undo history is loaded and the undo works as expected.
Edit: My configuration looks like this: https://gitlab.com/snippets/22693
Edit2: This problem still happens with the most minimal configure file:
;;; init.el --- user init file -*- no-byte-compile: t -*-
(load-file "~/.emacs.d/undo-tree.el")
(global-undo-tree-mode 1)
(setq undo-tree-auto-save-history t)
How come no one has ever noticed this? There's a bug in undo-tree.
The function undo-list-transfer-to-tree failed to append 'undo-tree-canary to buffer-undo-list, which cause it to discard the content of buffer-undo-tree.
I'm still looking into it to see if I can find a solution. Simply append 'undo-tree-canary to buffer-undo-list causing it to discard to content in buffer-undo-list instead
Edit: The solution is indeed to put canary at the end of buffer-undo-list
(when (not (eq (last buffer-undo-list) 'undo-tree-canary))
(setq buffer-undo-list (append buffer-undo-list '(nil undo-tree-canary))))
When undo-tree-auto-save-history is enabled, undo history is loaded from file by the undo-tree-load-history-hook function, which gets added to find-file-hook. So undo history will be loaded automatically when you open a file with undo-tree-mode enabled.
#djangoliv is right: this will only work if global-undo-tree-mode is enabled, because undo-tree-mode needs to be enabled before find-file-hook is called. Perhaps the undo-tree-mode minor-mode function ought to attempt to load history if it detects the buffer hasn't been modified since the last undo history save. But at the moment, it doesn't.
However, your config does enable global-undo-tree-mode, so this can't be the issue.
History loading works just fine for me with global-undo-tree-mode enabled. So unless you give a complete MWE that reproduces your problem -- i.e. step-by-step instructions starting from "emacs -Q" and including Emacs and undo-tree version numbers -- you're unlikely to get much more help here. (Also, note that stackexchange is not a bug tracker. Bug reports should be sent by email to the address listed at the top of the package.)
Have you tinkered with the order you are loading your plugins as well as files you open automatically via init.el or .emacs? That did the trick for me. Evil requires Undo-Tree. So everything having to do with undo-tree should fire before you load Evil. Especially if you use ":e" instead of "find-file" for loading files. A least on my system that solved this issue.
I just want to chime in that I experience a similar thing.
if I emacs file-x from the terminal, earlier undo tree history for file-x is not is not available to me before I undo-tree-load-history. However, when I open emacs and then :edit file-x, the history is loaded just fine.
I'm using spacemacs 0.105.19, with emacs-24.5.1.
My .spacemacs is https://pastebin.com/VNWtB0F1
Reason for this behavior is that when you start up emacs and open up file in buffer even with undo-tree-auto-save-history enabled so that undo-tree-load-history is called as it should be, buffer-undo-list is initially set to nil. If you make an edit before invoking any functionality of undo-tree, buffer-undo-list will have value that doesn't end with an undo-tree-canary.
When undo-list-transfer-to-tree sees buffer-undo-list not ending with undo-tree-canary, it will discard current buffer-undo-tree and construct new one with the value of buffer-undo-list which only have undo history of your initial edit. Consequently, buffer-undo-tree previously built by undo-tree-load-history is deleted, and you are left with fresh, minimal buffer-undo-tree only with single undo history.
So what I did to prevent this from happening was to initialize buffer-undo-list with undo-tree-canary by advising undo-tree-load-history-hook which should call undo-tree-load-history with undo-tree-auto-save-history set to t, and it is also called for opening file as part of find-file-hook.
That is, I added this line of code to my init file:
(advice-add 'undo-tree-load-history-hook :after (lambda () (setq buffer-undo-list '(nil undo-tree-canary))))
Put the (global-undo-tree-mode) in the :init will auto load history if you're using use-package
Example:
(use-package undo-tree
:init
(global-undo-tree-mode)
:custom
(undo-tree-auto-save-history t)
(undo-tree-history-directory-alist '(("." . "~/.config/emacs/undo-tree-history")))
(undo-tree-visualizer-diff t)
(undo-tree-visualizer-timestamps t))
Related
When Emacs is closed with modified buffers present, it creates a file with the format '#file_name#' for recovery purpose in its parent directory for each modified buffer (except for scratch).
When recover-file command is used when Emacs opens the next time, the previously modified buffer of the file is recovered. Even so the file #file_name# is not deleted automatically.
This would not occur if you manually kill all buffers before closing. This is a bit tedious as you would have to use the command kill-some-buffer or kill-matching buffer and say 'yes' to each of the prompts one by one.
Is there a simpler method to overcome this? It would be nice to have solutions for one or more of the following.
Prevent Emacs from creating a recovery file for modified buffer while closing
A simple command to force kill all buffers without prompt to save
Setting to re-route the recovery files to a different location (like ~/.emacs.d/)
(Versions: Emacs-24 on Ubuntu-12.04 / OS-X-10.9)
By adding the following line on your init.el file you'll disable the auto-save feature and no more of these files will be generated
(setq auto-save-default nil)
But you may want those files so you can use the code above which I borrowed from emacswiki
(setq backup-directory-alist
`((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
`((".*" ,temporary-file-directory t)))
This will cause that all backup files will go to the temporary folder on your operating system. Check the emacswiki link to know more about what you can do with this feature
More on this
Emacs manual entry on auto-save
I use a library called dired-details and dired-details+ to simplify dired's display, such that a line like this:
-rw-r--r--# 1 peter staff 22571 Apr 15 16:05 foo.txt
displays like this:
foo.txt
However, I have another function, which places all directories at the top of the list:
(defun mydired-sort ()
"Sort dired listings with directories first."
(save-excursion
(let (buffer-read-only)
(forward-line 2) ;; beyond dir. header
(sort-regexp-fields t "^.*$" "[ ]*." (point) (point-max)))
(set-buffer-modified-p nil)))
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort))
and this second function interferes with dired-details, such that when I C-x d to open a dired buffer, the initial display shows the full extraneous details. Only by pressing g to revert-buffer to refresh the display do the directory details become hidden.
How do I enable hiding of dired details by default in all dired displays?
First, if you use Emacs 24.4 or later (or a developement version past 24.3), then you no longer need either dired-details.el or dired-details+.el. Starting with Emacs 24.4, Dired listing details are hidden by default. dired-hide-details-mode is the relevant mode.
If you use dired+.el (Dired+) then you can more easily take advantage of this new behavior -- it gives you all of the features offered by dired-details+.el. Use ( anytime to toggle this hiding. You can use Dired+ option
diredp-hide-details-initially-flag to change the default/initial state. See also option diredp-hide-details-propagate-flag.
If you use an Emacs version that is prior to Emacs 24.4 (so you need dired-details[+].el) then try loading dired-details+.el (which will load dired-details.el) after you have evaluated your code above. If that does not help, then try also adding this to your defadvice body, just after (mydired-sort): (dired-details-hide). If that does not work then we will need to look a bit further.
If you can upgrade your Emacs version then you will soon be able to use Emacs 24.4 (it is in pretest now), in which case you should be able to just load dired+.el and set option diredp-hide-details-initially-flag to non-nil.
Wrt sorting directories first: Are you on MS Windows? If so, consider using libraries dired-sort-menu.el and dired-sort-menu+.el. It lets you do that and much more.
UPDATE
The problem is that dired-details caches the list of overlays it uses to hide details. It has already done its job (because of dired-after-readin-hook), before your sorting is done, and that changes the buffer without updating the cache info. This will fix the problem (there is probably a more elegant way, but this will do):
(defadvice dired-readin
(after dired-after-updating-hook first () activate)
"Sort dired listings with directories first before adding marks."
(mydired-sort)
(let ((dired-details-internal-overlay-list ())) (dired-details-hide)))
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)
How to open files automatically when starting emacs? does not work either under Windows or under Linux.
After adding the find-file command I received a message
so I disabled the auto-save, but the file does not load anyway.
(add-to-list 'load-path "~/emacs/org-8.0.3")
(setq auto-save-default nil)
(find-file "/home/uwe/Dropbox/orgmode.org")
You probably want to set the initial-buffer-choice variable so that it switches to your org file after running your init.el.
(setq
org-default-notes-file "/home/uwe/Dropbox/orgmode.org"
initial-buffer-choice org-default-notes-file)
The message you see proves that the file is indeed loaded just fine. All it tells you is that there's some auto-save file left over, indicating that some edits were not saved last time. You can ignore the message (which is not an error message), or you can use M-x recover-this-file RET to recover the unsaved changes from the auto-save file.
I strongly recommend you don't disable auto-saving.
IOW what you think doesn't work (automatically loading orgmode.org) actually does work. The only thing that doesn't work the way you want is that this file is not displayed and instead the *scratch* buffer is displayed. The reason for this depends on how you started Emacs. And the fix for it depends on all the different ways you might start Emacs (e.g. if you only ever start Emacs in the exact same way, it's easier).
Don't disable the auto-save, it could save ours files.
Anyway, delete #orgmode.org, if the diff between the two file don't interest you.
I have a strange interaction with tramp and cygwin-mount (I think: Emacs: Tab completion of file name appends an extra i:\cygwin). Because of this, I want to disable tramp. I'm unable to find anything in my .emacs which is loading tramp explicitly. I can see "Loading tramp..." when I hit a tab in the find-file minibuffer. I'd like to figure out what package is causing the loading of tramp and disable that. How do I go about doing this? I tried searching for (require 'tramp) but couldn't find anything interesting. The only other option I can think of is to comment out bits of my .emacs one-by-one and see which one works - but this is so brute-force, I'd like a cleverer (and easier) way.
What a great question! If only because I was not aware of the function (eval-after-load file form) which will enable you to write code like the following and put it in your .emacs file:
(eval-after-load "tramp"
'(debug))
Which will, in brute force form, vomit a backtrace in your window and reveal the offending library.
I think you'll find that tramp is turned on by default. If you do:
M-x customize-apropos
Customize (regexp): tramp
('Customize (regexp):' is the prompt from emacs) you'll see two variables listed (at least I do in emacs 23), something like:
If you set tramp-mode to 'off', save for future sessions, and restart emacs tramp should no longer be loaded. I believe you can just turning it off in the current session should allow you to test this, but this doesn't always work with customize variables, although it should do with something like tramp that is part of the standard emacs distribution.
I don't have emacs 22 installed any more, but something similar should work for that too.
I had a similar problem with tramp, when one day I found
"/C:\...\debuglog.txt" on my system.
Because of that file, auto-complete was invoking tramp each time
I entered "/". And tramp was of course giving an error.
auto-complete was calling
(expand-file-name ...)
which, because of the current file-name-handler-alist, was calling tramp.
My solution was:
(delete-if
(lambda (x)
(or (eq (cdr x) 'tramp-completion-file-name-handler)
(eq (cdr x) 'tramp-file-name-handler)))
file-name-handler-alist)
Instrument find-file for debugging and/or instrument your init file for debugging. Then you can step through the loading and see where the tramp stuff is loaded.