How can I create an empty file from emacs, ideally from within a dired buffer?
For example, I've just opened a Python module in dired mode, created a new directory, opened that in dired, and now need to add an empty __init__.py file in the directory.
If I use C-x C-f __init__.py RET C-x C-s then emacs doesn't create the file because no changes have been made to it. I would have to type in the file, save it, delete my typing and then save it again for that to work.
Thanks
You can use the touch command:
M-! touch __init__.py RET
The following works: C-x b __init__.py RET C-x C-w RET
If you're in a dired buffer the file will be saved in the directory show here.
The trick is to first create an empty buffer by switching to a name that doesn't exist. Then write out the file.
If you want Emacs to treat all new files as modified, you can automate the solution like this:
(add-hook 'find-file-hooks 'assume-new-is-modified)
(defun assume-new-is-modified ()
(when (not (file-exists-p (buffer-file-name)))
(set-buffer-modified-p t)))
Programatically and without any dependency on touch, it's quite easy:
(with-temp-buffer (write-file "path/to/empty/file/"))
After this thread, Emacs has added two new commands:
make-empty-file
dired-create-empty-file
These commands will be available in the emacs 27.1 release.
Here's an adaptation of dired-create-directory. It works the same way, so as well as a plain filename, you can also specify new parent directories (to be created under the current directory) for the file (e.g. foo/bar/filename).
(eval-after-load 'dired
'(progn
(define-key dired-mode-map (kbd "C-c n") 'my-dired-create-file)
(defun my-dired-create-file (file)
"Create a file called FILE.
If FILE already exists, signal an error."
(interactive
(list (read-file-name "Create file: " (dired-current-directory))))
(let* ((expanded (expand-file-name file))
(try expanded)
(dir (directory-file-name (file-name-directory expanded)))
new)
(if (file-exists-p expanded)
(error "Cannot create file %s: file exists" expanded))
;; Find the topmost nonexistent parent dir (variable `new')
(while (and try (not (file-exists-p try)) (not (equal new try)))
(setq new try
try (directory-file-name (file-name-directory try))))
(when (not (file-exists-p dir))
(make-directory dir t))
(write-region "" nil expanded t)
(when new
(dired-add-file new)
(dired-move-to-filename))))))
Emacs won't allow you to save a buffer unless it thinks the contents have changed. The quickest, though possibly not cleanest is to open the file using C-x C-f, then press (say) space and backspace, then you should be able to save a file with no contents.
There are other ways of changing the "buffer has been modified" flag, but I don't think there's any easier.
Use touch command.
M-! touch __init__.py RET
The shortest way
Creates an empty file via a shell operation (but does not open it):
M-! > __init__.py RET
Open the new file:
C-x C-f RET
(Note: we don't have to type in the name again, because the new file is automatically the first choice)
(shell-command (concat "touch " (buffer-file-name))) will do what you want, if you've already opened the empty file.
In addition to other answers on the page, you can use f.el's function f-touch:
M-:(f-touch "__init__.py")RET
You can mark an empty buffer as modified by running set-buffer-modified-p. Then when you save it, Emacs will write the file.
M-; ; Eval
(set-buffer-modified-p t) ; Mark modified
C-x C-s ; Save buffer
I use the following bound to t in dired.
(defun my-dired-touch (filename)
(interactive (list (read-string "Filename: " ".gitkeep")))
(with-temp-buffer
(write-file filename)))
;; optionally bind it in dired
(with-eval-after-load 'dired
(define-key dired-mode-map "t" 'my-dired-touch))
I've modified answer from MrBones and created custom function with keybinding:
; create empty __init__.py at the place
(defun create-empty-init-py()
(interactive)
(shell-command "touch __init__.py")
)
(global-set-key (kbd "C-c p i") 'create-empty-init-py)
This is very useful to not spend time on recurring action of creating init.py everywhere in new Python project folder.
The best option would be:
(with-temp-file "filename"
(insert ""))
Related
I am using the code from the answer on this problem for asynchronous copy-directory for a few months now, but sometimes I need one or more subdirectories to be ignored. Is there an easy way by slightly modifying the code to do that?
I have tried to use Selective Directory Copying: SDC package from here, but it brakes when file or folder already exists.
This is the code I am using right now:
(async-start
`(lambda()
(copy-directory ,"~/Documents/data/" ,"~/Dropbox/data_backup/" t t t)
,"~/Documents/data/")
(lambda(return-path)
(message "Upload '%s' finished" return-path)))
There is a subdirectory in ~/Documents/data that sometimes I want it to be ignored because it is larger than a threshold.
copy-directory calls itself recursively. You can use cl-flet to redefine it locally, while keeping the original definition. You can also do this with advice (and actually this cl-flet technique seems to break advice), but then it's effectively globally redefining the function and you need to control it with e.g. variables.
(defun jpk/copy-directory (directory newname &optional keep-time parents copy-contents)
(cl-letf (((symbol-function 'orig/copy-directory) (symbol-function 'copy-directory))
((symbol-function 'copy-directory)
(lambda (directory newname &optional keep-time parents copy-contents)
(if (string= directory "/path/to/foo")
(message "skipping: %s" directory)
(orig/copy-directory directory newname keep-time parents copy-contents)))))
(copy-directory directory newname keep-time parents copy-contents)))
In more detail: store the original function to orig/copy-directory, replace the function copy-directory with a lambda that calls orig/copy-directory only if the directory name doesn't match some string, then call the new definition of copy-directory. The recursive call to copy-directory also uses the new definition. All of this is wrapped up in jpk/copy-directory. To make it more flexible, you could add a predicate argument to jpk/copy-directory so the test isn't hard coded.
In emacs, when im typing the begining of a file name, and then press tab for autocompletion, here's what i get :
Possible completions are:
dummy.cmi dummy.cmx
dummy.ml dummy.o
I want emacs to ignore object files (.o, .cmx, .cmi) and directly complete with dummy.ml
Is there a way to specify that behaviour in emacs ? some sort .emacsignore mechanism like in git?
The variable that controls ignored file extensions for completion is completion-ignored-extensions. It should already have a couple of extensions in it, but you can add your own.
If you do M-x customize-variable RET (i.e. Meta+x, type customize-variable and hit Enter)
Then type in: completion-ignored-extensions Enter
You will now get a list of what's already in it. You can also delete entries and add new ones.
You can also add this to your init.el/.emacs:
(add-to-list 'completion-ignored-extensions ".blah")
To add multiple elements, instead of duplicating that line:
(setq completion-ignored-extensions
(append completion-ignored-extensions
(quote
(".ext1" ".ext2" ".ext3"))))
I want to launch an arbitrary program that takes selected filename argument from a buffer that lists files in a directory.
I tried to use F3 key to insert the filename but the following records a new macro instead which is rather confusing.
(define-key minibuffer-local-map [f3] (lambda () (interactive (find-file-at-point))))
You're problem is not completely clear to me, but maybe this helps.
Please see the following screenshot of my Emacs in the scratch buffer. It contains a function and the keybinding, the echo area at the bottom is showing the results from the call to message
For your convenience, here is the function and the keybinding repeated for better copying:
(defun command-on-file-at-point ()
(interactive)
(let ((f (ffap-file-at-point)))
(message "File is %s" f)))
(global-set-key [f3] 'command-on-file-at-point)
Hope, that helps.
Please note first of all that this is a homework question so I'm not looking for straight code or anything like that, just for someone to maybe help me with my logic.
The assignment is in DrRacket. The question asks:
Given a FileSystem, which we've defined as a structure with two fields, name and contents, where contents is a list of either directories or files; write a function that will create a ".bak" filename for every file in the directory and place it immediately after the file.
I am totally lost. My logic is as follows: If the first thing in the content list is a file, simply remake the directory with that file and a new file with ".bak" appended. This is as far as I can get - I can't see how to work things out if there's a subdirectory, OR how to go about moving further down the list.
Here's my atrocious code:
(define (backup my-fs)
(cond
[(empty? (dir-contents my-fs)) empty]
[(file? (first (dir-contents my-fs))) (make-dir (dir-name my-fs) (append (backup-list (first (dir-contents my-fs)))(rest (dir-contents my-fs))))]
[(dir? (first (dir-contents my-fs))) (backup (first (dir-contents my-fs)))]))
Can anyone help me reason this out?
The contents part of your FileSystem is a list containing files or directories (which are lists containing ....).
This is a basic tree-traversal problem where you have three cases, as you noted:
list is empty
first element in list is a file
first element in list is a directory
Then you need an action for each case:
done
keep that filename, create a new filename, and continue processing the rest of the list
keep that directory, recursing over it, and continue processing the rest of the list
For example:
(define (traverse contents)
(cond
[(empty? contents) ... nothing to do ...]
[(file? (first contents)) ;; if the first element's a file:
(cons (first contents) ;; keep the file
(cons (... make backup filename ... (first contents)) ;; make the backup
(traverse (rest contents))))] ;; and recurse on the rest
[(dir? (first contents) ;; if the first element's a directory:
(cons (traverse (first contents)) ;; recurse on the first
(traverse (rest contents)))])) ;; and also recurse on the rest
You need to clarify your data definition. You write:
"Given a FileSystem, which we've defined as a structure with two fields, name and contents, where contents is a list of either directories or files; write a function that will create a ".bak" filename for every file in the directory and place it immediately after the file. "
This makes it clear what a FileSystem is... if you know what "directories" and "files" are. You need to clarify this by writing data definitions for "directory" and "file". Each of these should be a separate sentence. They might be really simple, e.g. "A file is represented as a string".
After doing this, write some examples of FileSystems.
I want to do the following in Emacs: Save the current buffer to a new file, but also keep the current file open.
When I do C-x C-w then current buffer gets replaced, but I want to keep open both buffer. Is this possible without reopening the original file?
I don't think there's anything built in, but it's easy enough to write:
(defun my-clone-and-open-file (filename)
"Clone the current buffer writing it into FILENAME and open it"
(interactive "FClone to file: ")
(save-restriction
(widen)
(write-region (point-min) (point-max) filename nil nil nil 'confirm))
(find-file-noselect filename))
Here's a snippet I've had for a while to do just this
;;;======================================================================
;;; provide save-as functionality without renaming the current buffer
(defun save-as (new-filename)
(interactive "FFilename:")
(write-region (point-min) (point-max) new-filename)
(find-file-noselect new-filename))
I found it helpful to combine Scott's and Chris's answers above. The user can call save-as and then answer "y" or "n" when prompted whether to switch to the new file. (Alternatively, the user can select the desired functionality via the function name save-as-and-switch or save-as-but-do-not-switch, but this requires more keystrokes. Those names are still available for being called by other functions in the future, however.)
;; based on scottfrazer's code
(defun save-as-and-switch (filename)
"Clone the current buffer and switch to the clone"
(interactive "FCopy and switch to file: ")
(save-restriction
(widen)
(write-region (point-min) (point-max) filename nil nil nil 'confirm))
(find-file filename))
;; based on Chris McMahan's code
(defun save-as-but-do-not-switch (filename)
"Clone the current buffer but don't switch to the clone"
(interactive "FCopy (without switching) to file:")
(write-region (point-min) (point-max) filename)
(find-file-noselect filename))
;; My own function for combining the two above.
(defun save-as (filename)
"Prompt user whether to switch to the clone."
(interactive "FCopy to file: ")
(if (y-or-n-p "Switch to new file?")
(save-as-and-switch filename)
(save-as-but-do-not-switch filename)))
C-x h
selects all the buffer, then
M-x write-region
writes the region (whole buffer in this example) to another file.
Edit: this function does what you need
(defun write-and-open ( filename )
(interactive "GClone to file:")
(progn
(write-region (point-min) (point-max) filename )
(find-file filename ))
)
It's a bit crude, but modify to your will.
The interactive code 'G' prompts for a filename which goes into the 'filename' argument.
Drop this into your .emacs and call with M-x write-and-open (or define a key sequence).