Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: Special Symbol for File Description #65

Closed
huettenhain opened this issue Aug 24, 2018 · 5 comments
Closed

Enhancement: Special Symbol for File Description #65

huettenhain opened this issue Aug 24, 2018 · 5 comments
Assignees

Comments

@huettenhain
Copy link

I would often like to have a special symbol for the description of a file, like !.! gives the long file name with extension, it might be possible to have !* translate to the description of the current file. It can be just the empty string when there is none.

The following was the only position in the code which looks like it is performing these substitutions:

However, I did not find any reference to the MakePatternStr function elsewhere, so I am not sure. Either way, it seems like the request can be easily implemented and if someone points me to the exact spot where the substitution is done, I'll gladly prepare a PR for this - but of course only if this change is welcome.

@alabuzhev
Copy link
Contributor

alabuzhev commented Sep 1, 2018

misc/fexcept is definitely not the right place for that.
You need far/fnparce.cpp

May I ask how do you plan to use it?
It should be already possible to get a file description with something like
lua:print(Panel.Item(0, 2, 11)).

@huettenhain
Copy link
Author

I would like to use it in a variety of cases, let me list just a few to give you an idea:

  1. Sometimes I need to unpack a number of archives which are password protected. I would very much like to store the password in the description, and then be able to Ctrl+G and type 7z x -p:!* -o!.0 !.! to extract all selected archives. (I beg you, please let us not start a deep dive into why or why not or in which cases this might be a good or a bad idea ;-). I have my reasons.)
  2. Sometimes I store a URL associated to some file in a description. Again, I would like to call wget on all of these URLs and update the file contents with the response. This would also be a single line from Ctrl+G if a description placeholder existed.
  3. I have a script which generates certain PDF reports from Markdown files, but the script requires an additional parameter (an identifier) which I store in the description. It would be nice if I could create a custom menu item to compile such items, but right now there is no way to access the file description.

Of course, these are all individual cases and all of them can be solved on a case by case basis with Lua macros or by means of other workarounds. Trust me, I have done so.

However, the same type of issue just keeps coming up, having the placeholder for descriptions would be a universal solution to all of them and, I believe, to many others that have not come up yet.

Granted, though, I will absolutely survive without this feature. If you think it's a bad idea, just ignore it.

@alabuzhev
Copy link
Contributor

I'm not saying it's a bad idea. Perhaps a little controversial - every other special symbol there is for some part of file name, while description is more like 'metadata'. However, it looks useful in your examples.

@huettenhain
Copy link
Author

The following code would implement this (as long as a reasonable token description = L"!*"sv is defined):

	if (const auto Tail = tokens::skip(CurStr, tokens::description))
	{
		FarGetPluginPanelItem CurrentItem = { sizeof(FarGetPluginPanelItem) };
		const auto Panel = ( SubstData.PassivePanel ? SubstData.Another.Panel : SubstData.This.Panel );
		const auto ItemSize = Panel->SetPluginCommand(FCTL_GETSELECTEDPANELITEM, 0, NULL);
		CurrentItem.Item = static_cast<struct PluginPanelItem*>(malloc(ItemSize));
		if (CurrentItem.Item) {
			CurrentItem.Size = ItemSize;
			if (Panel->SetPluginCommand(FCTL_GETSELECTEDPANELITEM, 0, static_cast<void*>(&CurrentItem))
				&& CurrentItem.Item->Description) 
			{
				Out += CurrentItem.Item->Description;
			}
			free(CurrentItem.Item);
		}
		return Tail;
	}

This works because Ctrl+G is always operating on the first item which is currently selected, and if no item is selected, FCTL_GETSELECTEDPANELITEM returns the item under the cursor which also works as intended.

However, the rest of the code is designed to pass all relevant substitution information (file names) to SubstFileName separately rather than have ProcessMetasymbols query the API for results, so this seems a little inconsistent, and I am a little worried that the above is not the way it's supposed to be.

Comments, thoughts? Would you accept this PR? I am gladly willing to invest more time into this if you would wish for a different solution.

@alabuzhev
Copy link
Contributor

Far's internals shouldn't query the Plugin API at all. FCTL_GETSELECTEDPANELITEM is designed for plugins, allocating and throwing away a PluginPanelItem only to access Description is overkill.
It should already be possible to assess FileList -> FileListItem -> DizText directly, if not - the code can be reorganised to do so. For example, enum_selected() could be moved from Panel to FileList (it belongs there anyway) and yield FileListItem instead of find_data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants