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

Variable expansion in ipc / command parser #3713

Open
anarazel opened this issue Jun 6, 2019 · 10 comments

Comments

Projects
None yet
4 participants
@anarazel
Copy link

commented Jun 6, 2019

I'm submitting a…

[ ] Bug
[x] Feature Request
[ ] Documentation Request
[ ] Other (Please describe in detail)

Current Behavior

Variables set with set in the config file are not expanded in commands submitted via IPC / i3-msg.

Desired Behavior

Variables set with set in the config file are expanded in commands submitted via IPC / i3-msg.

My personal use-case for this is wanting to access workspace variables in external scripts. When having descriptive names - which I like - it's annoying to have that source of truth in several places.

As far as I can tell there's no strong reason for the current behaviour, it's just historically grown? It doesn't look that hard to change that.

Environment

Output of i3 --moreversion 2>&-:

Binary i3 version:  4.16.1 (2019-01-27) © 2009 Michael Stapelberg and contributors
Running i3 version: 4.16.1 (2019-01-27) (pid 7288)abort…)
Loaded i3 config: /home/andres/.config/i3/config (Last modified: Thu 06 Jun 2019 12:45:24 PM PDT, 2424 seconds ago)

The i3 binary you just called: /usr/bin/i3
The i3 binary you are running: i3

This is on Debian unstable, updated today (2019-06-06).

A quick look in the code suggest that the relevant behaviour hasn't changed since 4.16.1.

@i3bot i3bot added the enhancement label Jun 6, 2019

@Airblader

This comment has been minimized.

Copy link
Member

commented Jun 9, 2019

Variables are directly replaced in the file when parsing. Variables expansion is not recursive so it is not possible to define a variable with a value containing another variable. There is no fancy handling and there are absolutely no plans to change this.

https://i3wm.org/docs/userguide.html#variables

For your specific purpose I can think of two solutions:

  1. Define the workspace names as X resources and use set_from_resource in the config. You can load the same variable from the resource database in your scripts.
  2. Address workspaces by their numbers rather than full names from your script. This depends a bit on your overall setup, but generally should work.

@stapelberg On the other hand, nowadays we do things like keep the config around to allow dumping it, and accessing variables on the IPC would arguably be more intuitive and easy. I wouldn't want to go down a road of querying variables or modifying them, but using them in commands sounds pretty fair to me, even though in the past we didn't want to consider this.

@stapelberg

This comment has been minimized.

Copy link
Member

commented Jun 11, 2019

I haven’t thought too deeply about evaluating variables in commands. I can imagine that tying command evaluation to the config file state will make debugging harder, both for users and for us. Unless it enables compelling use-cases that otherwise aren’t possible, I’m leaning towards not doing that.

One thing that seems like a no-brainer (because it doesn’t change anything in the mental model) is to export variable names and values via the IPC interface. Then, in your script/program, you can substitute the variables yourself.

This is pretty close to the X resources solution which @Airblader suggested, so perhaps that one works as-is for you (without changes to i3).

@Airblader

This comment has been minimized.

Copy link
Member

commented Jun 11, 2019

I don't think there's a shortage of use cases for evaluating variables in commands. For example for mode names, border pixel widths or referencing variables representing the preferred editor etc. Of course all of these can be done using the X resource way, it's just less convenient.

Exposing variables on the IPC is possible, but also much less convenient. I think overall I would argue that evaluating variables in commands follows the principle of least surprise best.

I can imagine that tying command evaluation to the config file state will make debugging harder, both for users and for us.

I don't share that fear because when variables are used it'd pretty easy to see that they are used. Also, cimmands already depend on config state (back and forth and the like).

@stapelberg

This comment has been minimized.

Copy link
Member

commented Jun 11, 2019

I don't think there's a shortage of use cases for evaluating variables in commands. For example for mode names, border pixel widths or referencing variables representing the preferred editor etc. Of course all of these can be done using the X resource way, it's just less convenient.

Sure, there are plenty of use cases for variables. Usually they’re just used within the config file, though, and hence can already be replaced. Do you have some use-case examples where it is necessary (why?) to have a separate process send the command via IPC?

Exposing variables on the IPC is possible, but also much less convenient.

I’d argue the i3 IPC library should make it convenient. I think $i3->cmd("workspace " . $i3->variable("ws1")->recv)->recv (Perl example) is convenient enough, no? :)

I don't share that fear because when variables are used it'd pretty easy to see that they are used. Also, cimmands already depend on config state (back and forth and the like).

It’s a fair argument that we already have state, but it doesn’t automatically follow that we need to add more state dependencies :).

I think we should pay extra attention to make the log really obvious, though: we should log commands before and after evaluation, and make clear to the user which is which.

@anarazel

This comment has been minimized.

Copy link
Author

commented Jun 11, 2019

I can imagine that tying command evaluation to the config file state will make debugging harder, both for users and for us.
I don't share that fear because when variables are used it'd pretty easy to see that they are used. Also, cimmands already depend on config state (back and forth and the like).

I'd kind of bet that just about every user of i3 has debugged the fact that variables don't work in i3-msg... Especially given that there's no errors or anything. While one possibly can infer that from the docs ("Variables are directly replaced in the file when parsing. "), that can easily also be understood to mean that they're evaluated during parsing, which obviously can be understood to include commands.

To me both X resources and exposing variables via ipc (yes please) just seem like ways to provide variables usable in i3-cmd and other scripts, except in a more convoluted and harder to debug manner.

It's possibly worth noting that variables in sway can be referenced in commands.

@Airblader

This comment has been minimized.

Copy link
Member

commented Jun 11, 2019

It's possibly worth noting that variables in sway can be referenced in commands.

Not really; sway tries to be compatible with i3, the other way around we do not have any such concerns. :-)

Personally I think variables in commands directly would be useful, but exposing them in an IPC, particularly request the value of a specific variable, would also be fine with me.

@anarazel

This comment has been minimized.

Copy link
Author

commented Jun 11, 2019

I think we should pay extra attention to make the log really obvious, though: we should log commands before and after evaluation, and make clear to the user which is which.

Yea, that'd be a good improvement. Probably not just for issues related to this, but also for e.g. quoting related matters. What were you precisely thinking of - dumping something into the debugging log, returning more details as a result to the IPC commands sent, or ...?

Do you have some use-case examples where it is necessary (why?) to have a separate process send the command via IPC?

I have scripts that set up workspaces for specific tasks. E.g. for development work I want to have an editor on both of my "side" monitors and the main one, another workspace to start/monitor postgres on a side monitor, and a bunch of terminals on a separate workspace on the main monitor. That's imo not really doable from within the config file. I can/have worked around the variable limitations, but it'd have been nicer if I didn't have to.

@stapelberg

This comment has been minimized.

Copy link
Member

commented Jun 11, 2019

That's imo not really doable from within the config file.

You could make the desired workspace names command line arguments of your script, then bind that script onto a key within your i3 config (i.e. inject the variable values into your script).

I'd kind of bet that just about every user of i3 has debugged the fact that variables don't work in i3-msg...

There are actually i3 users who don’t ever touch their config file, so I will counter that bet any second :)

What were you precisely thinking of - dumping something into the debugging log, returning more details as a result to the IPC commands sent, or ...?

Yeah, logging for starters, but extending the IPC result status with the expanded command also sounds reasonable. We could make i3-msg print the difference if there is any.

@anarazel

This comment has been minimized.

Copy link
Author

commented Jun 11, 2019

You could make the desired workspace names command line arguments of your script, then bind that script onto a key within your i3 config (i.e. inject the variable values into your script).

Yea, I tried that. But with a significant number of pre-defined workspaces (as in their names + output) that gets kind of cumbersome. I don't think there's a way to move the 'put workspace on this output, and if not present on this output' logic outside of the main config file, so I can't just put that logic outside of i3's main config.

I now simply re-parse the config file :/.

What were you precisely thinking of - dumping something into the debugging log, returning more details as a result to the IPC commands sent, or ...?

Yeah, logging for starters, but extending the IPC result status with the expanded command also sounds reasonable. We could make i3-msg print the difference if there is any.

Ok. I'll take a stab at doing that.

@stapelberg

This comment has been minimized.

Copy link
Member

commented Jun 12, 2019

I don't think there's a way to move the 'put workspace on this output, and if not present on this output' logic outside of the main config file, so I can't just put that logic outside of i3's main config.

I can’t quite parse your sentence, but it sounds like you only need to inject one workspace name and one output name to your script, no?

Ok. I'll take a stab at doing that.

Note that we haven’t said yet whether that feature would be accepted, so please keep that in mind before you sink too much time into it. Of course, having some code might help inform the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.