emacs-citar / citar

Emacs package to quickly find and act on bibliographic references, and edit org, markdown, and latex academic documents.
GNU General Public License v3.0
498 stars 54 forks source link

Support embark multitarget actions #486

Closed bdarcus closed 2 years ago

bdarcus commented 2 years ago

Omar just merged support for this, discussed in #477:

https://github.com/oantolin/embark/commit/b17af024d92e5c8532ed94f157e65aa7f4cda334

So we need to test this and get him feedback, but also make sure citar works with it. Once we get it working as expected, we can also add the pdf-search function, which would rely on this.

I'm not sure why, but this is the result I get.

Debugger entered--Lisp error: (wrong-type-argument listp "huck1975a")
  #f(compiled-function (x) #<bytecode -0x1433a9947753cda6>)("huck1975a")
  mapcar(#f(compiled-function (x) #<bytecode -0x1433a9947753cda6>) ("huck1975a" "huck1975b" "huck1975c" "huck1975d" "huck1975e" "huck1975f" "huck1975" "huck1975g"))
  citar-citeproc-format-reference(("huck1975a" "huck1975b" "huck1975c" "huck1975d" "huck1975e" "huck1975f" "huck1975" "huck1975g"))
  citar-copy-reference(("huck1975a" "huck1975b" "huck1975c" "huck1975d" "huck1975e" "huck1975f" "huck1975" "huck1975g"))
  #f(compiled-function () #<bytecode -0x1bcb76d099fa68a4>)()
  apply(#f(compiled-function () #<bytecode -0x1bcb76d099fa68a4>) nil)
  #f(compiled-function () #<bytecode -0x1ebf6128d325eb1a>)()
  #f(compiled-function () #<bytecode -0x14e4eee3a110c9d2>)()

Any ideas @localauthor @roshanshariff?

See https://github.com/oantolin/embark/issues/433

roshanshariff commented 2 years ago

It looks like with this change, Embark will call the function non-interactively with a list of keys. So citar-select-refs is skipped entirely, and the function needs to lookup entries on its own. I can add a function to do this and change the Citar commands to use it, so they can be used as multi-actions.

minad commented 2 years ago

Hmm, I see. Your function is not taking a list of keys but alist of already looked-up key entries. If you change your functions accordingly such that they takes keys as argument it will work.

But maybe we can come up with an even better crm injection protocol in Embark. Embark could also temporarily advise completing-read-multiple and return the "injected" candidates directly. The advice would only be active once and then be removed. @oantolin I wonder why did you chose a minibuffer injection mechanism in the first place. Why not advise read-from-minibuffer for embark-act? This way one could also perform auto detection in embark-act-all, if CRM is called we are done, if read-from-mb is used continue with the tail of the list in a loop.

minad commented 2 years ago

@bdarcus I suggest you don't apply changes to citar just yet. Maybe it is worth to rethink the target injection mechanism in Embark.

oantolin commented 2 years ago

I think advising read-from-minibuffer never occurred to me. I had just learned about the minibuffer-setup-hook and it worked, so I never looked for other solutions.

The minibuffer injection solution is pretty flexible, though. It allows embark-allow-edit-actions which is great for, say M-!(to write which command you want run on the file) or even M-: (to add arguments to functions). Other action setup hooks like minibuffer-force-complete for package-delete, come in handy too. I guess all those things could be done by advising read-from-minibuffer but they sound a little awkward to do. I'll think about it.

minad commented 2 years ago

Okay I think the edit actions are a good argument to keep the minibuffer injection as is. Thanks for reminding me. While it is more heavy than an advice based mechanism the injection mechanism is relatively robust from experience since it simulates user input.

oantolin commented 2 years ago

Maybe we could use the advise method only for embark-act-all, where we don't need the bells and whistles of the injection method?

minad commented 2 years ago

I am not sure. I am out of ideas here. Maybe citar should indeed be rewritten to conform to the string list argument protocol.

The only thing I'd like to make sure is that multi actions don't require the action author to write "unnatural" code. Ideally the CRM actions look like normal interactive crm commands.

minad commented 2 years ago

Maybe we could use the advise method only for embark-act-all, where we don't need the bells and whistles of the injection method?

I think it is not a good idea to use either the advice method and the injection method depending on act-all/act. This will just lead to inconsistencies.

But we could use the CRM advice mechanism only for actions registered in the embark-crm-action list.

minad commented 2 years ago

Hmm, I kind of hate it for it's complexity but what about the nuclear option of adding an embark-action-injection-mechanism-alist. Default is 'minibuffer. Other alternatives 'list-argument, 'string-argument, 'crm-advice...

oantolin commented 2 years ago

That seems excessive. 😄

oantolin commented 2 years ago

Ah! How about this? We could leave both embark and these citar functions as they are and just do the reference lookup in an embark pre-action hook! Those hooks recieve a plist with a key :candidates that would contain all the keys, a pre-action hook could modify it to contains the looked up references.

roshanshariff commented 2 years ago

Regardless of the ultimate choice of Embark injection protocol, I like the idea of allowing the keys-entries function arguments to be lists of keys. I wrote a simple citar--ensure-entries function that looks up any missing entries, to be used if you really need a list of (KEY . ENTRY) pairs.

On the other hand, some functions just need keys and not entries, and they already use citar--extract-keys; this now guarantees that the elements of the list are just keys.

These two functions can be used to normalize the keys-entries list depending on the situation. The main benefit is that all the functions become easier to use from outside Citar, since you don't have to do the entry lookup yourself.

oantolin commented 2 years ago

Although I might argue that it would be nice if the citar functions could be called from Lisp code either with a list of looked up references or, for convenience, with a list of keys. Just like the Emacs buffer functions which can take either a buffer object or a string naming a buffer.

oantolin commented 2 years ago

Ah, I see @roshanshariff beat me to the punchline. I really do think it's a nice bit of convenience for possible Emacs Lisp users of citar to allow lists of keys.

minad commented 2 years ago

We could leave both embark and these citar functions as they are and just do the reference lookup in an embark pre-action hook! Those hooks recieve a plist with a key :candidates that would contain all the keys, a pre-action hook could modify it to contains the looked up references.

@oantolin I am not sure if this would work. Can the pre action hook lookup the candidates/transform them? I thought these hooks can transform the minibuffer content. Also it introduces a weird splitting of the responsibilities.

oantolin commented 2 years ago

The hooks that are meant to transform the minibuffer content are the setup hooks, the pre-action hooks get called before the action is called, and thus before there even is a minibuffer. No currently known use of the pre-action hook mutates the target plist, but it should definitely work. However I do agree it's not the best place for the lookup to happen. As I said above, I think the best thing would be to add the convenience feature to citar functions of looking things up for you if presented with bare keys.

minad commented 2 years ago

@roshanshariff Thanks! If you say that a list of strings is anyways more natural and flexible or if you perform normalization of a keys-or-entry-list then it is best to keep the simple mechanism we have right now! This is all I wanted to make sure - the action author should end up with commands which look natural.

oantolin commented 2 years ago

This is all I wanted to make sure - the action author should end up with commands which look natural.

Yes, that's the main thing! And I do think that @roshanshariff's suggestion here is not an unnatural contortion that you'd never think to do if it weren't for Embark, but a reasonable convenience features to be added to the citar calling convention. I mentioned Emacs allowing buffer objects or string name and doing the lookup for you, but I'm pretty sure there are other examples in Emacs.

oantolin commented 2 years ago

I guess you could say that completing-read accepting alists and hashtables is another example, it really just extracts the list of keys for you,really saving you only one function call.

roshanshariff commented 2 years ago

There is one (small) remaining consideration: writing multi-action functions that work with both older and newer versions of Embark. This is not a problem for interactive commands, since the old embark-act always calls them interactively and the new one never does. But for non-interactive functions, old Embark calls it with a single string argument, whereas the new version calls it with a list of strings.

So, in practice, the calling convention will need to handle both strings and lists. Maybe this isn't really worth considering? It's a relatively minor issue in Citar anyway, since we only have one non-interactive Embark action and that probably needs a rethink anyway.

oantolin commented 2 years ago

Oh, interesting point. As a work around, I guess embark-act could call the multitarget action first with a singleton list, and if there is an error, print a warning and try again with a string. Or does that sound too horrible?

oantolin commented 2 years ago

It would be temporary, like other obsolescence warnings. I think I've actually done something like that in the past when I changed the number of arguments a user supplied function is called with. 😬 😄

minad commented 2 years ago

I would not implement special support for old Embark versions. Embark just acquired multi action support in particular for Citar. It seems okay to ask users to update Citar and Embark to the newest version.

roshanshariff commented 2 years ago

In the one instance we do this in Embark (citar-run-default-action) it's easy enough to just handle strings and lists, so perhaps you could leave it as it is and consider the more complicated approach if somebody complains?

oantolin commented 2 years ago

Sounds good, @roshanshariff, let's do it that way. Thanks.

roshanshariff commented 2 years ago

Another design question: now that Embark knows how to run multi-actions, should target finders be allowed to return lists of strings rather than just one string?

In Embark, we have a target finder for multi-key citations that returns strings like "key1 & key2 & key3", relying on CRM with an appropriate separator to split the strings. I'm not entirely sure, but maybe it's easier if it can just return a list of strings?

oantolin commented 2 years ago

Oh! Good question. Right now there are two types of contexts for targets: embark-act is singular and wants just one target; embark-collect-*, embark-export and embark-act-all are plural and look for lists of candidates. They don't even use the same mechanism to procure targets: embark-act calls the functions on embark-target-finders, while all the "plural commands" call the functions on embark-candidate-collectors instead.

But maybe a radical reorganization is in order? If we did allow target finders to return lists of targets, we could merge target finders and candidate collectors, and merge embark-act and embark-act-all.

oantolin commented 2 years ago

I guess that target finder for multi-key citations could instead become a candidate collector, to be used with embark-act-all instead of with embark-act. A nice advantage of that change would be that you could directly call embark-collect-snapshot with point on a multi-key citation and get a nice little buffer showing the keys where you could act on the individually.

roshanshariff commented 2 years ago

The current design is that we actually have two target finders (with different target types, alas, since currently Embark only keeps one target of a particular type). One just returns the single key at point (with its bounds) and the other returns all the keys in the citation (with the bounds of the whole citation).

So the current UX is that embark-act will highlight a single key, and you can embark-cycle if you want to act on all the keys. I kind of like this, to be honest.

minad commented 2 years ago

@roshanshariff Honestly I think it is too late now for this change. See my comment https://github.com/bdarcus/citar/issues/477#issuecomment-990370575 where I ha mentioned the possibility of modifying target finders such that they return a list of candidates. After this comment it was more or less agreed on that we don't go with multi targets per target finder.

We decided on the solution with embark-act-all. I kind of see your point but I am not happy with how this is going. Why come up with this now that we have the new mechanism in Embark? Moving to target finders which return a list of candidates will give yet another aspect to the current design. It does not make sense to end up with ten different approaches in Embark to do the same thing.

oantolin commented 2 years ago

Well, @roshanshariff, if instead of the two target finders you made it one target finder and one candidate collector, you could run embark-act to act on the single key at point and then press A to act on all of the keys!

minad commented 2 years ago

@roshanshariff To be fair, maybe not all the implications have been clear in the discussion. My feeling is this - either we have embark-act-all acting on collected candidates (this is what we have now) or we use a target finder approach, where multiple targets can be returned by a finder. But the second design is much harder to reconcile with how Embark works now. And we would still have to keep the collectors. Or we really go with the big overhaul where everything is moved over to target finders. I am not a fan of this. Embark is in principle focused on single candidates and I don't think we should change this or only change it in moderate ways. While I like Citar - I don't agree with changing Embark to move to multi targets as its main unit of operation. This misses the point since most of Emacs is in fact not centered around crm, not centered around multi targets and the primary goal as I see it is to integrate well with existing infrastructure, which is primarily based on completing-read/single strings/single targets.

oantolin commented 2 years ago

@minad I wouldn't want just add to list-valued target finder keeping all the other stuff we have going on; but if instead of that it were a redesign that somehow unified target finders with candidate collectors and that just also unified embark-act with embark-act-all, and which made the exporters into multitarget actions... That I might like, depending on whether the design really comes together well or not, but it would certainly be a huge change, an Embark 2.0. And, as you said, Emacs isn't really full of multitarget actions, so it might feel overenginereed.

roshanshariff commented 2 years ago

@minad, yeah, I was thinking of this as a long-term change/design study, to keep in mind for Embark 2.0.

@oantolin: the problem with that approach is that (unless I'm mistaken) the region-based actions won't be available for the full citation. So you can't just embark-act embark-cycle and kill the entire citation easily. Is there a way to get this without two target finders?

minad commented 2 years ago

@oantolin

I wouldn't want just add to list-valued target finder keeping all the other stuff we have going on; but if instead of that it were a redesign that somehow unified target finders with candidate collectors and that just also unified embark-act with embark-act-all, and which made the exporters into multitarget actions...

Okay. I agree with this. I should say that I don't consider @roshanshariff's idea a bad idea per se. We already considered this and discussed it, so it was an option on the table. And we discussed many times at length, so I am also not against long discussions. But I really don't like if there seems to be some agreement on a solution and then as soon as it has somehow materialized we should overthrow it again.

And, as you said, Emacs isn't really full or multitarget actions, so it might feel overenginereed.

Exactly. I would not want this due to its overengineering. I think it misses the goal. Why not use Helm then, @roshanshariff ?

oantolin commented 2 years ago

@roshanshariff Good point about killing the entire citation. There's no support for anything like a candidate collector reporting bounds, so you do need a second target finder for this.

minad commented 2 years ago

@roshanshariff

yeah, I was thinking of this as a long-term change/design study, to keep in mind for Embark 2.0.

Due to the arguments being made I consider this a wrong outlook and development direction. Of course I cannot foresee if this will turn out to be a good concept, maybe it will be. Helm already has multi targets as its main unit of operation.

the problem with that approach is that (unless I'm mistaken) the region-based actions won't be available for the full citation. So you can't just embark-act embark-cycle and kill the entire citation easily. Is there a way to get this without two target finders?

There is actually a way - why not introduce an additional special target finder citar-multi-citations which returns a string which is a list of citations (comma separated, semicolon separated). And then you transform it within the context of Citar.

oantolin commented 2 years ago

why not introduce an additional special target finder citar-multi-citations which returns a string which is a list of citations

I'm a little confused, isn't that basically equivalent to the second target finder @roshanshariff said they already had?

minad commented 2 years ago

I'm a little confused, isn't that basically equivalent to the second target finder @roshanshariff said they already had.

No, the difference is that Embark does not handle multiple targets then. But I am not sure if it is a satisfactory solution.

My main problem here is that if we allow target finders with multiple candidates (a list of strings, not a single string) we have to change how embark-act works, basically adding the multi candidate capability to embark-act. And since we already have embark-act-all, it is getting out of hand at that point.

oantolin commented 2 years ago

No, the difference is that Embark does not handle multiple targets then

Their current "big target" finder returns a single string of the form key1 & key2 & ..., so it does sound very similar to what you are suggesting, no @minad? Maybe I misunderstood you.

My main problem here is that if we allow target finders with multiple candidates (a list of strings, not a single string) we have to change how embark-act works

Oh, I agree. I'd only do something like it if it unified things as I said above. It would not be a quick change but a big redesign and I'd think a lot about feasability and benefits before doing it. Right now I'm inclined to say it would most likely be overenginereed: it would be a system that used singleton lists 99% of the time!

minad commented 2 years ago

@oantolin

Their current "big target" finder returns a single string of the form key1 & key2 & ..., so it does sound very similar to what you are suggesting, no @minad?

Okay, if their target finder already returns such a "big string candidate" then this is exactly what I suggested. I am just not fond of changing target finders to return multiple candidates at once due to the conflict with collectors, the required multi candidate adjustment to embark-act and the conflict between embark-act/embark-act-all.

Oh, I agree. I'd only do something like if it unified things as I said above. It would not be a quick change but a big redesign and I'd think a lot about feasability and benefits before doing it. Right now I'm inclined to say it would most likely be overenginereed: it would be a system that used singleton lists 99% of the time!

Exactly. If you consider the Embark target cycler it would be very confusing to cycle between targets of different arity. So I am strongly in favor of pursuing the current route where multi candidates (collectors) and single candidates (target finders) are kept distinct. Of course @roshanshariff may still implement a prototype. But really the value of Embark and related packages is that they keep things simple and close to existing facilities. I see some value in not going with the fully generalized over-engineered solution even if the non-general solution has limitations. As you said, 99% are single candidates.

My proposal for Citar is to work with the existing design, trying to push it to its limit but in a way which does not require to overthrow the entire existing Embark design. So far we managed this and still got a pretty good interface with consult-completing-read-multiple etc.

roshanshariff commented 2 years ago

@minad, I certainly didn't think my suggestion required a big redesign of Embark, and I saw it as natural consequence of the design that @oantolin already implemented. I like Embark's design (more than Helm :slightly_smiling_face:) and I don't think there's any need to re-orient it around multi-targets. The simplest implementation is: if a target finder returns a list instead of a string, embark-act uses its existing calling convention for non-interactive functions (which happens to match the new embark-act-all calling convention). If I'm not mistaken, this is at most a couple of lines to change in embark-act and is completely backward-compatible.

Then @oantolin pointed out that this opens the door to more radical simplification in the future. But of course, I'll defer to the two of you on that front; this is not the best place to discuss that anyway. And I'm not strongly advocating for the simple change above either, so please don't read so much into it.

minad commented 2 years ago

@roshanshariff

I certainly didn't think my suggestion required a big redesign of Embark I don't think there's any need to re-orient it around multi-targets.

Okay.

The simplest implementation is: if a target finder returns a list instead of a string, embark-act uses its existing calling convention for non-interactive functions (which happens to match the new embark-act-all calling convention). If I'm not mistaken, this is at most a couple of lines to change in embark-act and is completely backward-compatible.

And what should it do for interactive functions? At this point embark-act will behave like embark-act-all. I consider this a conflict. Note that the multi list target should also work well for the general actions not only Citar actions. I would not like if acting on certain targets will then implicitly behave like embark-act-all. By mixing up these two concepts I argue that we lose some clarity of the design and behavior. You can still achieve your goals in Citar with the existing design by defining a "big target string" as proposed above.

Then @oantolin pointed out that this opens the door to more radical simplification in the future.

Look, this is why I disagree with you here. It may open the door for a radical simplification. But then we are back at the big overhaul that I am not fond of. I really see some good things in the current design, even if it is limited in comparison to a generalized design ("radical simplification"). As I wrote above such a generalized design will have flaws - I don't think it is feasible to unify target finders and candidate collectors, without worsening the UI experience. Or if one tries to preserve the current UI experience as is one would still have to add special casing and wouldn't win anything on the technical side - no simplification!

But of course, I'll defer to the two of you on that front; this is not the best place to discuss that anyway. And I'm not strongly advocating for the simple change above either, so please don't read so much into it.

In the end it is Omar's decision. I am only expressing that I like the current design which distinguishes single candidates and multiple candidates and which keeps clear boundaries between the two concepts instead of mixing them up as you are proposing.

minad commented 2 years ago

I wonder why it is not possible for Citar to treat multiple citation keys as point as a single target. This seems like a perfectly simple solution to me within the bounds of the current Embark design. See https://github.com/bdarcus/citar/issues/486#issuecomment-993238389 and https://github.com/bdarcus/citar/issues/486#issuecomment-993243153.

One should also look at it like this: Since Citar is the only package which asked for such a multi target feature, it does not seem justified to change Embark to support this single use case, in particular since it is possible to implement all of this within Citar directly. This adds complications to the Embark injection mechanism and the target finder API.

In contrast, the functionality added by @oantolin with embark-act-all (and also the consult-completing-read-multiple target collector) are general features, which work in any context for any Emacs command, so they are definitely a good and justified addition. Of course it is even better that Citar profits from it!

roshanshariff commented 2 years ago

@minad,

You can still achieve your goals in Citar

Yes, on that I agree (and perhaps why this is a bad place to discuss this). Citar will get by anyway with or without these changes, modulo some minor annoyances. I was mostly concerned with simplifying Embark for its own sake.

And what should it do for interactive functions?

Do the same thing as embark-act-all, i.e. call the function non-interactively if it's in embark-multitarget-actions, or call it in a loop otherwise. By putting that code in embark--act, the acting side of embark-act and embark-act-all can be unified. Indeed, embark--act already has the non-interactive calling convention. All I'm saying is that if it's calling a function non-interactively (just forwarding the target as the function argument) it shouldn't care what the type of the target is, whether list or string.

I consider this a conflict.

The main difference is that embark-act-all gets its targets using collectors, whereas embark-act gets them using target finders. This is an important difference on the target-collection side, but that doesn't imply they have to have different action-execution semantics.

Look, this is why I disagree with you here.

This disagreement feels misdirected; @oantolin proposed the radical simplification of unifying target finders and collectors, not me :stuck_out_tongue: (only kidding, since I believe @oantolin was also just brainstorming future ideas). Not that my opinion is important here, but I actually agree with you that target finders and candidate collectors seem semantically distinct (the former finds something at or near point, whereas the latter scans the entire buffer; in the minibuffer the target finder returns the current selection, whereas the collector returns all candidates).

All that said, I can think of some pain points that I've actually encountered that also get solved with this small change, and that have nothing to do with multi-target actions (rather, they rely on being able to force an interactive command to be called non-interactively by embark-act, which is one effect of embark-multitarget-actions). But since this thread is getting way too long and off-topic already, I should probably get around to opening a discussion on the embark project to discuss it further.

minad commented 2 years ago

@roshanshariff

Yes, on that I agree (and perhaps why this is a bad place to discuss this). Citar will get by anyway with or without these changes, modulo some minor annoyances. I was mostly concerned with simplifying Embark for its own sake.

Good, then let's proceed like this. I would like to emphasize once more that using a single target has advantages. I argue that the general actions work better on the single target string. By introducing multi targets on the target finder level all these actions won't work well anymore. For example the mark action, should this mark the closure of all targets then? In comparison, what about the action which add the target to the kill ring, should this action add each of the subtargets one by one? It will get quite incoherent I think. These are all complications on the level of Embark which you didn't consider.

The problem here also comes from the side of Citar. You neglect the general actions and you even have (or had) them removed from the actions menu in order to clean up the which-key indicator. While I understand the motivation it works a bit against the design and the spirit of Embark and it leads you to making proposals which do not generalize well.

The main difference is that embark-act-all gets its targets using collectors, whereas embark-act gets them using target finders. This is an important difference on the target-collection side, but that doesn't imply they have to have different action-execution semantics.

Of course nothing is implied. We can design it as we like. I argue that we should keep the distinction. embark-act is single target from the target finders and embark-act-all is for multiple targets from the collectors and we should not mix these up.

This disagreement feels misdirected

Maybe, but you used it as an argument in favor of making this change. I disagree with using a potential "radical simplification" as argument. It is baseless anyways since we don't have a coherent design for this.

All that said, I can think of some pain points that I've actually encountered that also get solved with this small change, and that have nothing to do with multi-target actions (rather, they rely on being able to force an interactive command to be called non-interactively by embark-act, which is one effect of embark-multitarget-actions).

I disagree. The change is not a small change and it has implications you are not foreseeing. I don't understand why you keep on trying and insisting so hard. Why not try to solve this in Citar now? Of course you don't have to take me as any kind of authority here and it is good to check the design from all sides. But you still seem to ignore my arguments and my concerns. If you say that it is only a minor inconvenience/annoyance on the side of Citar while at the same time I argue that for Embark the change would be more impactful, why are you pushing so hard? If you show me the code for Citar with the annoyance (probably only a small amount of normalization code is needed) in comparison to the cleaner or better code without the annoyance then we can judge the impact. But I am convinced that the outcome will probably be that the Citar code will be a small change in comparison to the changes which would be needed on the side of Embark.

bdarcus commented 2 years ago

Wow; quite the thread!

So we should look into changing all the citar interactive functions to operate on keys?

I think, as @roshanshariff says, that should be easy enough.

We just want to confirm, as that would mean reverting to what was there from the beginning. And I know there was a good reason for that at the time (that may no longer be relevant given subsequent changes).

And am I correct these embark changes also impact embark-act, so that code like this would no longer be needed here?

https://github.com/bdarcus/citar/blob/51b30f2e4091a41243ae62cfbac53e7a579f3168/citar.el#L785-L787

roshanshariff commented 2 years ago

For example the mark action, should this mark the closure of all targets then? These are all complications on the level of Embark which you didn't consider.

Ow, I wonder if this is the root of all the misunderstanding. I didn't mean that the target finders would return multiple targets (which would mean multiple bounds, multiple target types, etc.) I just meant that the target need not be a string, i.e. the second element of the target finder's return value. But there's still only one target type and one set of bounds. embark--mark-target would not be affected (nor any of the embark-region-map commands), since it ignores the target and cares only about its bounds. And kill-new adding all the target items to the kill ring actually seems like really nice behaviour. If you're concerned, remember that we'd still confirm before running the action on multiple targets.

In fact, of all the actions in embark-general-map, the only one that it doesn't make sense to call in a loop is embark-isearch. But that is a wrapper around isearch anyway, which can easily do something useful if it's given a list-valued target (run isearch to match any element of the list, for example). Remember that most target finders will only return string-valued targets. And my opinion (different from yours, obviously) is that it's unnecessarily restrictive to disallow list-valued targets, especially since doing so results in unnecessary inconsistency and code duplication.

But you still seem to ignore my arguments and my concerns.

I've tried to address the complications you've actually brought up. But it could also be that you overestimated the magnitude of the change I'm proposing.

it leads you to making proposals which do not generalize well.

Now this is really off-topic, but I fear you misunderstood my position on that issue. I didn't decide to remove the general actions or even advocate for that. I just wanted a way for all actions to be available but not displayed in the indicators. But please, I'd appreciate a fair consideration of what I'm trying to say without being prejudiced by half-remembered unrelated discussions (understanding, of course, that some back-and-forth might be needed for us to understand each other, and you have no obligation to engage).

I don't understand why you keep on trying and insisting so hard.

Because I like Embark and would like to see it achieve its goals with a minimum of unnecessary complexity. But you're right, I don't think this discussion is moving in a productive direction. When I have the time and energy, maybe I'll write up a better design proposal. (Might have to create a pseudonym to get a fair shake though :stuck_out_tongue:.)

roshanshariff commented 2 years ago

So we should look into changing all the citar interactive functions to operate on keys?

I mostly have this implemented already. PR incoming soon.

And I correct these embark changes also impact embark-act, so that code like this would no longer be needed here?

They don't; embark-act still only works with string-valued targets, which it injects into the minibuffer for interactive commands, and passes as an argument for non-interactive functions. That's one of the reasons I was proposing the change, to try to bring embark-act more in line with embark-act-all.

bdarcus commented 2 years ago

They don't; embark-act still only works with string-valued targets, which it injects into the minibuffer for interactive commands, and passes as an argument for non-interactive functions.

So did @oantolin implement his plan here to have non-interactive functions (I guess) work more like embark-act-all (" if it is non-interactive it would pass it a singleton list")?

https://github.com/oantolin/embark/issues/433#issuecomment-992718311