4

I am trying to write a little function to get the projectile relative path of a buffer. My idea is to delete the substring projectile-project-root from the string buffer-file-name.

For example:

root-file-path: ~/src/dotfiles
buffer-file-name: ~/src/dotfiles/emacs.d/conf.org
relative-file-name: emacs.d/conf.org

my current code is this:

(setq buffer-file-name (string-remove-prefix projectile-project-root
                                             buffer-file-name))

but I can't get it working. Any ideas?

Basil
  • 12,019
  • 43
  • 69
rafaelleru
  • 381
  • 1
  • 13
  • Could you detail what isn't working? Looking at your code, you have at least two issues: you are quoting your call to `string-remove-prefix`, and `kill-new` should probably be called with only one argument – rpluim Oct 17 '18 at 07:32
  • The step to generate the buffer relative file path, sorry I was trying in the eval buffer and didn't test the function. I will fix the question. – rafaelleru Oct 17 '18 at 07:44
  • `buffer-file-name` must be an absolute, not relative, file name. If you want to change the buffer's user-visible name you should use `rename-buffer` instead. See [`(elisp) Buffer Names`](https://www.gnu.org/software/emacs/manual/html_node/elisp/Buffer-Names.html). If that is not what you're trying to do, then please elaborate on what your ultimate goal is, as it's not very clear from your question. – Basil Oct 17 '18 at 12:28
  • I wnat to get the file path relative to the current project, to put it in the clipboard @Basil it was I said at the beggining of the question. – rafaelleru Oct 17 '18 at 12:30
  • @rafaelleru Your question makes no mention of the kill ring or clipboard, but thanks for clarifying. – Basil Oct 17 '18 at 12:31
  • because my problem is with the file path, I already have other functions similar so I can copy in the clipboard and everithing else but I can't get the correct path. – rafaelleru Oct 17 '18 at 12:32
  • @rafaelleru That is the kind of detail that would help make your question clearer. As things currently stand, the reader does not know what you're trying to achieve, or what you've tried so far, or why or how it isn't working. – Basil Oct 17 '18 at 12:33
  • OK @basil I will update the question with more context. Thanks – rafaelleru Oct 17 '18 at 12:34

2 Answers2

7

I think the reason your code is not working as hoped for is because you are using the buffer-local variable projectile-project-root instead of the eponymous function.

C-hvprojectile-project-rootRET reveals:

projectile-project-root is a variable defined in ‘projectile.el’.
Its value is nil

  Automatically becomes buffer-local when set.

Documentation:
Defines a custom Projectile project root.
This is intended to be used as a file local variable.

In other words, projectile.el never sets this variable itself; it is provided only in case users want to set it buffer- or file-locally (see (emacs) Locals and (emacs) File Variables, respectively).

This explains why

(file-relative-name buffer-file-name projectile-project-root)

(which you mentioned in a comment) returns the non-directory part of buffer-file-name, as opposed to the desired relative path.

Compare this with C-hfprojectile-project-rootRET:

projectile-project-root is a compiled Lisp function in
‘projectile.el’.

(projectile-project-root &optional DIR)

Retrieves the root directory of a project if available.
If DIR is not supplied its set to the current directory by default.

Combining this knowledge with dakra's good suggestion to use file-relative-name instead of manipulating file names as strings (which should and almost always can be avoided), we arrive at the following means of killing the current buffer's absolute file name relative to its projectile root:

(kill-new (file-relative-name buffer-file-name (projectile-project-root)))
Basil
  • 12,019
  • 43
  • 69
2

You want file-relative-name:

(file-relative-name "~/src/dotfiles/emacs.d/conf.org" "~/src/dotfiles")
"emacs.d/conf.org"
dakra
  • 396
  • 3
  • 6
  • when I run as (file-relative-name buffer-file-name projectile-project-root) it returns only the buffer file name `conf.org` and not the relative path. – rafaelleru Oct 17 '18 at 08:47