oantolin / embark

Emacs Mini-Buffer Actions Rooted in Keymaps
GNU General Public License v3.0
944 stars 56 forks source link

embark-target-file-at-point not properly recognizing filenames? #390

Closed slayer152 closed 3 years ago

slayer152 commented 3 years ago

embark-act on, say, abcd.txt, in a regular buffer does not recognize file as a target. It looks like embark-target-file-at-point relies first on ffap-file-at-point (which returns nil in the example) and uses (thing-at-point 'filename) only if ffap-file-at-point is non-nil.

I also don't understand the reference to ffap-el-mode in this function but should embark-target-file-at-point also be looking at (thing-at-point 'filename) if ffap-file-at-point returns nil ?

oantolin commented 3 years ago

Let's start with the basics: in your example, are you sure there exists a file called abcd.txt in the current directory? Does the command M-x ffap find it?

slayer152 commented 3 years ago

Sorry, I should have described the case better.

abcd.txt doesn't exist in the current directory. My use-case is actually detecting a file at point in a regular buffer even if the file is in a different directory, e.g. files in pre-processor directives like #include <filename>.

On second thought, I guess this detection wouldn't make much sense as most of the actions on files in the embark-file-map won't work if the full file location is not known when embark-act is called. I think it may be better if I detect this as a new target in my config.

Sorry for the trouble - please close this if you agree or I can close this too.

oantolin commented 3 years ago

If ffap can figure out what file is meant, then Embark will target that. I just tried #include <stdio.h> and Embark correctly targeted /usr/include/stdio.h (I actually used Embark to copy that path to the clipboard) despite the default-directory for my file being something under $HOME.

So, I'm guessing that in your situation that M-x ffap isn't finding the file either, is it? How do you use that C file? Do you compile it specifying an include path? Instead of adding your own Embark target you might want to configure ffap to find the correct file instead: just add the directories to user option ffap-c-path.

oantolin commented 3 years ago

Also, let me briefly explain the logic of the file target finder:

The reason Embark uses (ffap-file-at-point) rather than (thing-at-point 'filename) is that the latter is really just syntactical so whenever point is on a letter, for example, it returns something. The vast majority of the time those "filenames" don't correspond to any file.

slayer152 commented 3 years ago

So, I'm guessing that in your situation that M-x ffap isn't finding the file either, is it? How do you use that C file? Do you compile it specifying an include path? Instead of adding your own Embark target you might want to configure ffap to find the correct file instead: just add the directories to user option ffap-c-path.

Yes, M-x ffap doesn't find it. Not C files; the files are in an in-house language and are generated by various flows that can put them in one of ten/hundred directories inside a project. Something like files x, y... generate <filename> which is #include'd in file z. The build flow puts the path of <filename> in another file a1 and a1 is passed to the compiler to compile z.

I'm not sure if I want to look at configuring ffap-c-path because there can be hundreds of #include <filename> in each file and the files are distributed over several directories (even the a1-like files containing filepaths are put in several directories).

So, I'm thinking one of these two:

Option 1 is easier/supported out-of-the-box but I'm training my muscle memory to instinctively use embark-act as the front/initial command AMAP. I didn't get the hang of Embark initially but @karthink's post with the gifs was the 'Aha!' moment for me (I'm more of a visual learner). Thank you for this package!

oantolin commented 3 years ago

Oh, I see. Then making your own target that searches for the file sounds like a good option.

And since these aren't C files as I thought then modifying ffap-c-path wouldn't be appropriate, but you could still configure ffap to work for the in-house language, you just need to add an entry to ffap-alist associating the in-house language files with a function that given the base filename figures out the full path. Configuring ffap this way would be an alternative to making an embark target. I think it should be about the same amount of work either way.