Menu

Tweaking deft: no spaces in file names

Building on my earlierposts on deft, I have another minor improvement I wanted to make. I really like the way deft creates files from the search string, generating the file name from the string. The only problem is that I don’t want spaces in my file names, which I may well have in my deft search string.

My solution was to add the following advice to the function in deft that creates new files, telling it to replace spaces in the search string with hyphens before creating the file.

Maybe someone can help me improve my novice lisp programming here, as I am sure there must be a more direct way to use replace-regexp-in-string here!

I think this is a nice illustration of how the user can relatively easily adjust the behaviour of a function which is quite buried inside a package. You have to be a bit careful when advising functions that you don’t introduce unwanted behaviour if that function is called in a different context, but in this case it should be safe as the function deft-new-file-named is not used elsewhere.

In a comment on my earlier postKaushal Modi linked to his solution to this, which also removes any upper cases.

Update

The wise commenters below pointed out that my function above is a bit dangerous, since the variable name that I use has global scope so could modify another variable called name elsewhere. This can be solved by using (let ...) to give the variable local scope, as Kaushal Modi points out, but I ended up going with the compact version suggested by Noam Postavsky:

;;advise deft-new-file-named to replace spaces in file names with -(defunbjm-deft-strip-spaces(args)"Replace spaces with - in the string contained in the first element of the list args. Used to advise deft's file naming function."(list (replace-regexp-in-string " ""-"(car args))))(advice-add 'deft-new-file-named :filter-args #'bjm-deft-strip-spaces)

Which uses filter-args in the advice function to specify that my bjm-quit-strip-spaces function is applied to the arguments to deft-new-file-named before they are passed to the latter function.

Using the let binding creates and destroys the variable locally. Everything inside the let form will use the local var instead of a global var (if available). In you example, if a name var is used globally, it will update the global value too! (though, no one should have named a global variable called name :))