I have been having issues with recentf for quite a while: even I close emacs gracefully very oftern used files would not be in recent files next time.
My recentf config looks like
(use-package recentf
:config
(setq
recentf-save-file "~/.cache/emacs/recentf"
recentf-max-saved-items 10000
recentf-max-menu-items 5000
)
(recentf-mode 1)
(run-at-time nil (* 5 60) 'recentf-save-list)
)
Recently I have noticed this
Saving file /home/yuki/.cache/emacs/recentf...
Wrote /home/yuki/.cache/emacs/recentf
Saving file /home/yuki/.cache/emacs/recentf...
Wrote /home/yuki/.cache/emacs/recentf
Error: (file-missing "Doing chmod" "No such file or directory" "/home/yuki/.cache/emacs/recentf")
Saving file /home/yuki/.cache/emacs/recentf...
Wrote /home/yuki/.cache/emacs/recentf
Saving file /home/yuki/.cache/emacs/recentf...
Seems like at some point file disappears or something. Did anyone have similar problems? Any ideas what can go wrong (may be multiple instances)?
I suspect something is loading recentf earlier than you expect (for me it was triggered by a require in consult.el, which mean that it loads the recentf list from the wrong place because you haven't yet set it to your location. Later, when the (run-at-time ...) fires, you store only those files that have been loaded since startup and the cycle continues...
TL;DR - You need to move your setup from :config to :init.
(use-package recentf
:init
(setq
recentf-save-file "~/.cache/emacs/recentf"
recentf-max-saved-items 10000
recentf-max-menu-items 5000
)
(recentf-mode 1)
(run-at-time nil (* 5 60) 'recentf-save-list)
)
Related
I usually have 3-4 different projects that I work on at once. So I am trying to figure out how to get emacs to load the desktop from the folder that I open emacs from and also save to that file when I exit from that emacs instance.
All of the docs I have seen either describe how to get emacs to automatically open and save from a default location (which makes multiple desktops impossible), or to manually load and save the desktop to a specific directory (which I am doing now).
Thanks!
Put this to your .emacs:
(setq your-own-path default-directory)
(if (file-exists-p
(concat your-own-path ".emacs.desktop"))
(desktop-read your-own-path))
(add-hook 'kill-emacs-hook
`(lambda ()
(desktop-save ,your-own-path t)))
Upd.: v. 2, ignore on demand.
(setq your-own-path default-directory)
(if (file-exists-p
(concat your-own-path ".emacs.desktop"))
(if (y-or-n-p "Read .emacs.desktop and add hook?")
(progn
(desktop-read your-own-path)
(add-hook 'kill-emacs-hook
`(lambda ()
(desktop-save ,your-own-path t))))))
I have developed a small set of functions to manage multiple desktops: desktop+
You might want to check it out. My workflow is not exactly the same as yours, though:
I always run emacs from the same directory (I run it from a key binding in my window manager), meaning that I can not rely on the starting directory to know which desktop I want to work with
the first time I work on a new project, I call M-xdesktop-create and provide a name. The desktop is then saved to a central location (under "~/.emacs.d/desktops" by default)
each subsequent time I want to work with a saved desktop, I run M-xdesktop-load, and am provided with a list of saved sessions in which I can quickly retrieve the name of the desired session.
Sessions are always saved when emacs exits or you load another session.
For a really simple answer I put this at the end of my .emacs file. It works fine if you save the desktop in the project folder and start emacs from the project folder.
(desktop-change-dir default-directory)
Basically, I have a which-function-mode that crashes on large files. Is it possible to only set it if the file is less than 1,000 lines?
EDIT: I just noticed that I had forgotten that what you want is already provided by which-function-mode. Just customize which-func-maxout.
You can try something like the following:
(add-hook 'find-file-hook
(lambda ()
(if (> (buffer-size) 100000) ;; More than 100K characters.
(set (make-local-variable 'which-func-mode) nil))))
which-function-mode is a global minor mode, but each buffer can enable/disable it individually by setting which-func-mode. Sadly, I think the above will fail because which-function-mode doesn't expect other code to set which-func-mode so its own find-file-hook will override your setting.
This said, 1000 lines is not large, so there's no excuse for which-function-mode failing on such files: you might want to M-x report-emacs-bug.
Is there an emacs extension that takes periodic snapshots (once a minute, once every x keystrokes, whatever) of a file while it is being edited similar to the change history in Eclipse or the edit history in Google Docs and other programs?
I'm hoping for something that'll let me easy navigate through the changes I've made from day to day - Is there anything like this already written?
Edit
I should be more specific - I'm not looking for a VCS. I'm looking for a minor-mode or something similar I can just switch on and have hard copies of the revisions on disk.
There's a built-in feature called autosave that saves after N keystrokes (and maybe after M seconds, I'm not sure). I generally use this if Emacs crashes, not for looking at what edits I've made; undo is better for that. Here's my config:
(setq autosave-dir (concat user-emacs-directory "autosaves/")
auto-save-list-file-prefix (concat emacs-persistence-directory
"autosave-list"))
(if (not (file-exists-p autosave-dir))
(make-directory autosave-dir t))
(add-to-list 'auto-save-file-name-transforms
`("\\`/?\\([^/]*/\\)*\\([^/]*\\)\\'" ,(concat autosave-dir "\\2") t))
;; tramp autosaves
(setq tramp-auto-save-directory (concat user-emacs-directory "tramp-autosaves/"))
(if (not (file-exists-p tramp-auto-save-directory))
(make-directory tramp-auto-save-directory))
There's also a backup system that creates a copy after every save (not autosave). I use this for what I think you're asking for - looking at history since my last VCS commit. Here's my config:
(setq make-backup-files t
vc-make-backup-files t
version-control t
kept-new-versions 256
kept-old-versions 0
delete-old-versions t
backup-by-copying t)
(setq backup-dir (concat user-emacs-directory "backup/"))
(if (not (file-exists-p backup-dir))
(make-directory backup-dir))
(add-to-list 'backup-directory-alist
`(".*" . ,backup-dir))
(defun force-backup-of-buffer ()
(setq buffer-backed-up nil))
(add-hook 'before-save-hook 'force-backup-of-buffer)
;; this is what tramp uses
(setq tramp-backup-directory-alist backup-directory-alist)
(add-to-path "backup-walker")
(autoload 'backup-walker-start "backup-walker"
"start walking with the latest backup" t)
I use the excellent backup-walker to navigate through the backups.
The best solution I have found for this is undo-tree, which is the Emacs equivalent to gundo for vim: it lets you visualise the tree of undo/redo, navigate through the changes and go back and forth between different versions.
undo-tree can be installed using ELPA; once it is installed, add the following to .emacs:
(require 'undo-tree)
(global-undo-tree-mode)
The undo tree can then be visualised using Ctrl-x u (undo-tree-visualize). The different “versions” can be navigated in a very intuitive manner, using arrow keys.
The history can also be made persistent using undo-tree-save-history.
If you really value keeping your changes, I would highly recommend starting to use git. It will work for your windows and linux coding environments. I use it to port changes from code back and forth. It does a great job of fixing all the little line endings and merging changes.
If you really just want it to keep old versions, then emacs can create a new backup every time that you save. It just creates another file right next to your current one. That way you can control how often it makes a new backup (every time you save).
Here's a good page that talks about the options:
ftp://ftp.gnu.org/pub/old-gnu/Manuals/emacs-20.7/html_chapter/emacs_18.html#SEC109
Try http://www.emacswiki.org/emacs/BackupEachSave
It has saved me a number of times allowing me to backtrack.
From time to time I delete files that I shouldn't and worst is files that I've been writing myself. Therefore I have many times been saved by the backup feature of Emacs.
But my problem is that Emacs only makes a backup the very first time you save a buffer. Is there a way to make Emacs do it every time I press C-x C-s?
This is what my .emacs look like currently (only the part that deals with backups):
* snip *
;; ===== Backups =====
;; Enable backup files.
(setq make-backup-files t)
;; Save all backup file in this directory.
(setq backup-directory-alist (quote ((".*" . "~/.emacs_backups/"))))
;; Always backup by copying (safest, but slowest)
(setq backup-by-copying t)
;; Append .~1~ (and increasing numbers) to end of file when saving backup
(setq version-control t)
;; Defining how many old versions of a file to keep (starting from the
;; most recent and counting backward
(setq kept-new-versions 100)
* snip *
After reading this: EmacsWiki: Force Backups
I added these lines to my .emacs:
(defun force-backup-of-buffer ()
(setq buffer-backed-up nil))
(add-hook 'before-save-hook 'force-backup-of-buffer)
It utilizes the standard back up/version control but resets the flag that indicates wether or not the buffer has been backed up this session before a save.
First two rows define a function that resets the flag that indicates wether the buffer was backed up during this session.
Last row adds an event hook that executes the function before a save.
This does exactly what I wanted.
If you want to do it on your own, here's a start:
(defun backup-and-save ()
(interactive)
(setq filename (buffer-file-name))
(write-file (concat filename (format-time-string "_" "%Y%m%d%H%M%S")))
(write-file filename)
)
It saves a copy as originalfilename_timestamp in connection with a timestamp.
You might of course adjust it to store it in a separate backup folder or add other "tweaks".
Here is what I use. It puts backups in a subdirectory of the directory
the file is in. It also saves a backup each time the file is saved.
(setq make-backup-files t ; backup of a file the first time it is saved.
backup-by-copying t ; don't clobber symlinks
version-control t ; version numbers for backup files
delete-old-versions t ; delete excess backup files silently
delete-by-moving-to-trash t
kept-old-versions 6 ; oldest versions to keep when a new numbered
; backup is made (default: 2)
kept-new-versions 9 ; newest versions to keep when a new numbered
; backup is made (default: 2)
auto-save-default t ; auto-save every buffer that visits a file
auto-save-timeout 20 ; number of seconds idle time before auto-save
; (default: 30)
auto-save-interval 200 ; number of keystrokes between auto-saves
; (default: 300)
)
;; make backup to a designated dir, mirroring the full path
;; backup to dir hung on source dir...
(add-hook 'write-file-hooks 'setBackUp)
(defun setBackUp ()
"Called by before-save-hook to set up backup location"
(defvar backupdirname "BackUps~") ; you can chose the sub dir name here
(if (not (file-exists-p backupdirname))
(make-directory backupdirname t))
(setq backup-directory-alist `(("." . ,backupdirname)))
(setq buffer-backed-up nil) ; force backup every save
nil
)
I am upgrading to emacs23. I find that my emacs.el loads much more slowly.
It's my own fault really... I have a lot of stuff in there.
So I am also trying to autoload everything possible that is currently "required" by my emacs.el.
I have a module that exposes 12 entry points - interactive functions I can call.
Is the correct approach to have 12 calls to autoload in order to insure that the module is loaded regardless of which function I call? Are there any problems with this approach? Will it present performance issues?
If not that approach, then what?
What you really want is to get the autoloads generated for you automatically, so that your .emacs file remains pristine. Most packages have the ;;;###autoload lines in them already, and if not, you can easily add them.
To manage this, you can put all the packages in a directory, say ~/emacs/lisp, and in there have a file named update-auto-loads.el which contains:
;; put this path into the load-path automatically
;;;###autoload
(progn
(setq load-path (cons (file-name-directory load-file-name) load-path)))
;;;###autoload
(defun update-autoloads-in-package-area (&optional file)
"Update autoloads for files in the diretory containing this file."
(interactive)
(let ((base (file-truename
(file-name-directory
(symbol-file 'update-autoloads-in-package-area 'defun)))))
(require 'autoload) ;ironic, i know
(let ((generated-autoload-file (concat base "loaddefs.el")))
(when (not (file-exists-p generated-autoload-file))
(with-current-buffer (find-file-noselect generated-autoload-file)
(insert ";;") ;; create the file with non-zero size to appease autoload
(save-buffer)))
(cd base)
(if file
(update-file-autoloads file)
(update-autoloads-from-directories base)))))
;;;###autoload
(defun update-autoloads-for-file-in-package-area (file)
(interactive "f")
(update-autoloads-in-package-area file))
If you add 'update-autoloads-in-package-area to your kill-emacs-hook, then the loaddefs.el will automatically be updated every time you exit Emacs.
And, to tie it all together, add this to your .emacs:
(load-file "~/emacs/lisp/loaddefs.el")
Now, when you download a new package, just save it in the ~/emacs/lisp directory, update the loaddefs via M-x update-autoloads-in-package-area (or exit emacs), and it'll be available the next time you run Emacs. No more changes to your .emacs to load things.
See this question for other alternatives to speeding up Emacs startup: How can I make Emacs start-up faster?
Well, who cares how slowly it starts?
Fire it up via emacs --daemon & and then connect using either one of
emacsclient -c /some/file.ext, or
emacsclient -nw
I created aliases for both these as emx and emt, respectively. Continuing once editing session is so much saner...
Ideally you shouldn't have any load or require in your .emacs file.
You should be using autoload instead...
e.g.
(autoload 'slime-selector "slime" t)
You will need to use eval-after-load to do any library specific config, but the upshot is that you won't need to wait for all this to load up front, or cause errors on versions of Emacs that don't have the same functionality. (e.g. Terminal based, or a different platform etc.)
While this may not affect you right now, chances are, in future you will want to use the same config on all machines / environments where you use Emacs, so it's a very good thing to have your config ready to fly.
Also use (start-server) and open external files into Emacs using emacsclient - So you avoid restarting Emacs.