huijunchen9260 / dmenufm

A simple file manager using dmenu
GNU General Public License v3.0
227 stars 15 forks source link

[WIP] Allow separate programs to be used in place of fzf/dmenufm #35

Closed camnw closed 4 years ago

camnw commented 4 years ago

Hello, making this a draft pull request to be worked on until it fits well and functionality is extended a bit.

With my changes, there is a new function, makePromptOpts. This functions job is to take input and parse them into the proper options for the respective program being used, and then passing them on to said program. In the main fzffm script there is now a case statement for new variable $FM_PROG. Based on what this variable is, it will set up other variables starting with $FM_OPT_* to align with that programs corresponding flags. For example, in fzf the flag to put the prompt at the top is --reverse. However, in the case of bemenu, there is no such option thus bemenu would complain about an invalid option. So, with $FM_PROG="bemenu", this case statement sets this variable to be blank, and so when it is ultimately passed to bemenu there will be no adverse effects.

You will have a better understanding after you read through and test it yourself. Do let me know if you would like to take a different approach, though I do think this will work well when we add in more options and more programs to the mix.

huijunchen9260 commented 4 years ago

Finally...sorry @VebbNix that I did exactly nothing during qualifier preparation. Today the first round of qualifier ended, and I decided to rest for two days from qualifier and try to research on this function (and maybe optimize my original code)

huijunchen9260 commented 4 years ago

@VebbNix I slightly test it. I installed bemenu-x11 on my arch, and I also add FM_PROG=bemenu to the .config/fzffm/fzffm.conf. But somehow I cannot use bemenu with it. It still opened with fzf.

camnw commented 4 years ago

Haha, do not worry, as you can see I too haven't done much. Anyways, for me bemenu seems to work fine... any useful terminal output running it with bemenu?

Edit: Oops, I seem to have slightly misread that you say it still opens with fzf regardless of the setting. If you run FM_PROG=bemenu /path/to/fzffm does that successfully launch with bemenu?

huijunchen9260 commented 4 years ago

Haha, do not worry, as you can see I too haven't done much. Anyways, for me bemenu seems to work fine... any useful terminal output running it with bemenu?

Edit: Oops, I seem to have slightly misread that you say it still opens with fzf regardless of the setting. If you run FM_PROG=bemenu /path/to/fzffm does that successfully launch with bemenu?

Here is some relevent error message:

sed /^$/ d
+ yprompt dmenufm-fzffm/dmenufm-fzffm
+ fzf --reverse --preview --no-sort --prompt dmenufm-fzffm/dmenufm-fzffm
inappropriate ioctl for device                                          
+ CHOICE=                     
+ [  = ./ ]
+ [  = ../ ]
+ [  = Actions ]
+ [  = Terminal ]
+ [ -d  ]
+ [ -f  ]
+ break
+ printf %s /home/shelby/dmenufm-fzffm/dmenufm-fzffm

It seems that the $FM_PROG, $FM_OPTS and $FM_OPT_PROMPT has been correctly set, but just yprompt do not want to execute these commands, and have inappropriate ioctl for device error.

huijunchen9260 commented 4 years ago

Haha, do not worry, as you can see I too haven't done much. Anyways, for me bemenu seems to work fine... any useful terminal output running it with bemenu?

Edit: Oops, I seem to have slightly misread that you say it still opens with fzf regardless of the setting. If you run FM_PROG=bemenu /path/to/fzffm does that successfully launch with bemenu?

I realize that it is purely my mistake LOL. I didn't realize that my fzffm-menu is linked to the same file in other place... My bad LOL, your implementation works flawlessly!

camnw commented 4 years ago

Ah alright! Happens to the best of us. I still do want to make it a bit more complete before we think about merging. I'll take some time over the next couple days to see what I can do.

huijunchen9260 commented 4 years ago

Ah alright! Happens to the best of us. I still do want to make it a bit more complete before we think about merging. I'll take some time over the next couple days to see what I can do.

Thank you so much!

Do you think I should try my best to use as few if statements as possible? I saw the following post on stackoverflow, and I am surprised how efficient case statement is:

https://stackoverflow.com/a/20020764

huijunchen9260 commented 4 years ago

@VebbNix

I also tried peco with only --prompt option, and the following error occurs.

+ yprompt dmenufm-fzffm/dmenufm-fzffm 
+ peco --prompt dmenufm-fzffm/dmenufm-fzffm
panic: runtime error: index out of range [2] with length 0

goroutine 31 [running]:
github.com/nsf/termbox-go.SetCursor(0x1c, 0x0)
    /Users/lestrrat/dev/pkg/mod/github.com/nsf/termbox-go@v0.0.0-20190817171036-93860e161317/api.go:214 +0x1b2
github.com/peco/peco.(*Termbox).SetCursor(0xc000096200, 0x1c, 0x0)
    /Users/lestrrat/dev/src/github.com/peco/peco/screen.go:38 +0x35
github.com/peco/peco.UserPrompt.Draw(0xc000097000, 0x7ffebdcb7c34, 0x1b, 0x1b, 0xc000069bc2, 0xc000069880)
    /Users/lestrrat/dev/src/github.com/peco/peco/layout.go:189 +0x3ce
github.com/peco/peco.(*BasicLayout).DrawPrompt(...)
    /Users/lestrrat/dev/src/github.com/peco/peco/layout.go:672
github.com/peco/peco.(*BasicLayout).DrawScreen(0xc000097040, 0xc000069880, 0x0)
    /Users/lestrrat/dev/src/github.com/peco/peco/layout.go:688 +0xb4
github.com/peco/peco.(*View).drawScreen(0xc000097060, 0x6298a0, 0xc000096f20, 0x0)
    /Users/lestrrat/dev/src/github.com/peco/peco/view.go:86 +0x7e
github.com/peco/peco.(*View).Loop(0xc000097060, 0x62a2e0, 0xc0000a6c40, 0xc000096e00, 0x0, 0x0)
    /Users/lestrrat/dev/src/github.com/peco/peco/view.go:66 +0x3e8
created by github.com/peco/peco.(*Peco).Run.func4
    /Users/lestrrat/dev/src/github.com/peco/peco/peco.go:365 +0x1c0
+ CHOICE=
+ [  = ./ ]
+ [  = ../ ]
+ [  = Actions ]
+ [  = Terminal ]
+ [ -d  ]
+ [ -f  ]
+ break

It seems like peco has some internal error, but if I just run

CHOICE=$(printf '%s\n' ./* | sed "/^$/ d" | peco --prompt "Test")

(Individually run that part which arise error)

which works perfect LOL. Totally don't understand why.

huijunchen9260 commented 4 years ago
FM_PROG=rofi
FM_OPTS="-dmenu"
FM_OPT_PROMPT="-p"

works flawlessly.

camnw commented 4 years ago

I’ll see if I can figure out peco when I get on

huijunchen9260 commented 4 years ago

I think it is very close to merge/combine to master branch. It just that still one stuff is bothering me.

When I want to change the default software to dmenu, I encounter some problems:

The code:

case $FM_PROG in
    "fzf")
        [ -z "$FM_OPTS" ] && FM_OPTS="--reverse"
        FM_OPT_PROMPT="--prompt"
        ;;
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS="-l 10"
        FM_OPT_PROMPT="-p"
        ;;
    "rofi")
        [ -z "$FM_OPTS" ] && FM_OPTS="-dmenu -l 10"
        FM_OPT_PROMPT="-p"
        ;;
    "")
        echo "No program selected, falling back to dmenu."
        [ -z "$FM_OPTS" ] && FM_OPTS="-f -fn "$FM_GENERIC_FONT" -sb $2 -i -l 10"
        FM_PROG="dmenu"
        FM_OPT_PROMPT="-p"
        ;;
    *)
        [ -z "$FM_OPTS" ] && FM_OPTS=""
        [ -z "$FM_OPT_PROMPT" ] && FM_OPT_PROMPT="--prompt" && echo "Program \`$FM_PROG\` not recognized, trying to run with prompt option '--prompt'. If this does not work, please use the FM_OPT_PROMPT variable to set it!"
        ;;
esac

and it seems that it cannot read $2 as an argument of -sb, and result in the error like this:

+ yprompt dmenufm-fzffm/dmenufm-fzffm #005577
+ dmenu -f -fn Monospace-15 -sb -i -l 10 -p dmenufm-fzffm/dmenufm-fzffm 
error, cannot allocate color '-i'
d

the argument $2 is not read, and thus -sb take -i as an argument and fail.

Is it possible to maintain the general statement like now but allow user to specify color as a second arguments?

huijunchen9260 commented 4 years ago

I realize that if I modify the prompt function using default value, then it will fall back to dmenufm:

## PROMPT FUNCTIONS
yprompt () { # Usage yprompt [MSG] [BG_COLOR]
    ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10} ${FM_OPT_PROMPT:--p} "$1 "
}

xprompt () { # Usage xprompt [MSG] [BG_COLOR]
    printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10} ${FM_OPT_PROMPT:--p} "$1 "
}

NotiPrompt () { # Usage NotiPrompt [MSG]
    printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_NOTIF_FONT" -sb "#d79921" -sf "#1d2021" -nf "#000000" -nb "#000000"} ${FM_OPT_PROMPT:--p} "$1 "

}

DangerPrompt () { # Usage: DangerPrompt [MSG] && ...
    [ "$(printf "No\\nYes" | ${FM_PROG:-dmenu } ${FM_OPTS:--f -fn "$FM_DANGER_FONT" -i -nb darkred -sb red -sf white -nf gray } ${FM_OPT_PROMPT:--p} "$1")" = "Yes" ]
}

Everything is complete! DangerPrompt somehow not working LOL

I tested more, somehow the DangerPrompt (which is further wrapped into DangerMenu) works in the Empty Trash function in FM_TRH, but not FM_DEL function.

Totally don't understand why LOL

camnw commented 4 years ago

On the color point, I guess the most complete approach would be to make a set of generic options (like FM_BG_OPT or something of the like) and then also have user defined variables to change these colors. The problem is this would create a lot of extra variables that would probably make it messier. Maybe we could do something like this:

FM_COLOR_OPTS=“-sf -sb -nf -nb”
FM_COLORS=“#ffffff #111111 #aaaaaa #000000”

In this example, we would create the FM_COLOR_OPTS variable per program, and then the user would customize their list of colors in a predefined order we have set up. The trade off would just be you need a simple statement towards the beginning that assembles the color options to be appened. (For example would turn the above into something like FM_COLOR_THING=“-sf #ffffff -sb #111111 ” etc.)

The reason this approach could be done as opposed to separate variables for each color type is that there would be the same amount of variables no matter how many colors the program needs, because you just net to make a list of all the color options and the list of all the colors in order to be “merged” into the final set of options to be passed. Let me know what you think about this approach and if you’d like me to elaborate further.

huijunchen9260 commented 4 years ago

I try to set the variable as:

case $FM_PROG in
    ...
    "")
        echo "No program selected, falling back to dmenu."
        FM_NOTIF_COLOR_OPTS="-sb -sf -nf -nb"
        FM_NOTIF_COLOR="#d79921 #1d2021 #000000 #000000"
        FM_DANGER_COLOR_OPTS="-nb -sb -sf -nf"
        FM_DANGER_COLOR="darkred red white gray"

as well as define both prompts in fzffm-menu:

NotiPrompt () { # Usage NotiPrompt [MSG]
    FM_NOTIF_OPT="$(
        awk 'BEGIN{
        split(ARGV[1],lp, " ")
        split(ARGV[2],rp, " ")
        for (i=1; i in lp; i++) {
        print lp[i], rp[i]
        }
    }' "$FM_NOTIF_COLOR_OPTS" "$FM_NOTIF_COLOR"
    )"
    printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_NOTIF_FONT"} ${FM_NOTIF_OPT} ${FM_OPT_PROMPT:--p} "$1 "
    # printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_NOTIF_FONT" -sb "#d79921" -sf "#1d2021" -nf "#000000" -nb "#000000"} ${FM_OPT_PROMPT:--p} "$1 "

}

DangerPrompt () { # Usage: DangerPrompt [MSG] && ...
    FM_DANGER_OPT="$(
        awk 'BEGIN{
        split(ARGV[1],lp, " ")
        split(ARGV[2],rp, " ")
        for (i=1; i in lp; i++) {
        print lp[i], rp[i]
        }
    }' "$FM_DANGER_COLOR_OPTS" "$FM_DANGER_COLOR"
    )"
    [ "$(printf "No\\nYes" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn $FM_DANGER_FONT} ${FM_DANGER_OPT} ${FM_OPT_PROMPT:--p} "$1")" = "Yes" ]
}

and still, the NotiPrompt works, but DangerPrompt in FM_DEL function does not work. Surprisingly, FM_TRH works only when Empty the Trash. Then I realize that it is a wrapping function DangerMenu that is bothering, and if I decompose this back to some like the following, FM_DEL works again:

FM_DEL () { # Usage: FM_DEL
    ...
        case "$actCHOICE" in
    *)
        case "$bulkselection" in
            ....
        *)
            # Single-selection mode
            allowbulk="NotAllowed"
            # Check the chosen on is directory or not
            [ -n "$HERE" ] && [ -d "$HERE" ] && result=$?
            [ -n "$HERE" ] && SELECTED="$HERE" &&
            DangerPrompt "Remove all the files / directories in $name?" &&
            IFS="$nl" &&
            for selection in $(printf '%s' "$SELECTED"); do
                unset IFS
                rm -rf "$selection"
            done && NotiPrompt "Selected removed."
                        ....
            ;;
        esac
}

So I think the real problem is actually in this wrapper function, the original FM_OPTS approach is actually good!

huijunchen9260 commented 4 years ago

OK, I totally understand what's going on here. Let me list all the problems and reasons.

Problem: DangerMenu not working

Conclusion:

It is totally fine to just set up default value!

## PROMPT FUNCTIONS
yprompt () { # Usage yprompt [MSG] [BG_COLOR]
    ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10} ${FM_OPT_PROMPT:--p} "$1 "
}

xprompt () { # Usage xprompt [MSG] [BG_COLOR]
    printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10} ${FM_OPT_PROMPT:--p} "$1 "
}

NotiPrompt () { # Usage NotiPrompt [MSG]
    printf '%s' "" | ${FM_PROG:-dmenu} ${FM_OPTS:--f -fn "$FM_NOTIF_FONT" -sb "#d79921" -sf "#1d2021" -nf "#000000" -nb "#000000"} ${FM_OPT_PROMPT:--p} "$1 "

}

DangerPrompt () { # Usage: DangerPrompt [MSG] && ...
    [ "$(printf "No\\nYes" | ${FM_PROG:-dmenu } ${FM_OPTS:--f -fn "$FM_DANGER_FONT" -i -nb darkred -sb red -sf white -nf gray } ${FM_OPT_PROMPT:--p} "$1")" = "Yes" ]
}

Solution: change DangerMenu to the following:

DangerMenu () { # Usage: DangerMenu [CMD] [MSG] (OPT: [Dest])
    if DangerPrompt "$2"; then
    IFS="$nl"
    for selection in $(printf '%s' "$SELECTED"); do
        unset IFS
        [ -z "$destination" ] &&
        $1 "$selection" ||
        $1 "$selection" "$3"
    done && NotiPrompt "Selected removed."
    fi
}

Reason: Previous, I put IFS=$nl before DangerPrompt, and thus DangerPrompt does not take each options in ${FM_OPTS:-...} as options. This is because the IFS now does not include space, and thus it does not recognize the following individual field.

camnw commented 4 years ago

Ah. Thank you for looking into this, will get these changes in and working, I do believe that edits are open to maintainers on my fork so you could add this how you wanted if you so please.

huijunchen9260 commented 4 years ago

I've combined all of the above discussion with master branch:

https://github.com/huijunchen9260/dmenufm/commit/98e7075d9811303a5bb912923f8175a09ba4d482

I added the support of FM_NOTIF_OPTS and FM_DANGER_OPTS if anyone wants to configure NotiPrompt and DangerPrompt individually.

I think next step is to find a way to "fully" support other menu system, which means allow add arguments to the FM_OPTS. That is to say, for now, I cannot make this work

FM_PROG=bemenu
...
case $FM_PROG in
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS='-l 10 --sb=$2'
        FM_OPT_PROMPT="-p"
        ;;

I cannot make FM_OPTS with $2 argument to work in yprompt. What do you think about this?

huijunchen9260 commented 4 years ago

Newest Update

@VebbNix Do you think it is possible to make positional parameters to work in FM_OPTS and FM_OPT_PROMPT? I've tried very hard to think this possibility, but still most of my works is in vain.

Or at least should the user just directly assign the $FM_GENERIC_COLOR in $FM_OPTS, something like

FM_PROG=bemenu
...
case $FM_PROG in
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS='-l 10 --sb=$FM_GENERIC_COLOR'
        FM_OPT_PROMPT="-p"
        ;;

What do you think about this?

camnw commented 4 years ago

I'm sorry if I am being ignorant, but could you explain what you mean in more detail? I don't know exactly to what you are referring to having the user put.

huijunchen9260 commented 4 years ago

I'm sorry if I am being ignorant, but could you explain what you mean in more detail? I don't know exactly to what you are referring to having the user put.

Ah, my bad. I would explain it thoroughly.

In original dmenu setting, our prompt will change its color based on the setting of $FM_GENERIC_COLOR, $FM_ACTION_COLOR_LV1, $FM_ACTION_COLOR_LV2, and $FM_ACTION_COLOR_BULK. This change relies on different input to the $2 argument in the function yprompt and xprompt. To my best expectation, I would like to give user this ability if they can also include $2 in their $FM_OPTS, i.e.,

FM_PROG=bemenu
...
case $FM_PROG in
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS='-l 10 --sb=$2'
        FM_OPT_PROMPT="-p"
        ;;

However, I always encounter two types of error:

  1. If let FM_OPTS="-l 10 --sb=$2", then $2 will be executed here, which is actually nothing. And thus no argument is given to --sb option, resulting an error.
  2. If let FM_OPTS='-l 10 --sb=$2', then when inside the yprompt and xprompt function, this $2 will just be interpreted as a string of $2 rather than a positional parameter $2.

The second option is to let user directly define FM_OPTS like this:

FM_PROG=bemenu
...
case $FM_PROG in
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS='-l 10 --sb=$FM_GENERIC_COLOR'
        FM_OPT_PROMPT="-p"
        ;;

but by doing so, we will lose the flexibility of inserting different input into yprompt and xprompt function.

camnw commented 4 years ago

Thank you for writing this as I now see what the core issue is.

Sorry I have been slow to respond at times, I have had limited time actually at my computer to work on this recently.

For this issue I would say that if we want to keep the flexibility, I would say we have the user decide on colors ahead of time, I guess we would have to settle and just have a separate variable containing the 'colors', as I feel all possible scenarios of parsing any number of unique settings for $FM_OPTS to choose what to replace with particular colors will be way more inefficient than simply making a separate variable for the different cases.

So my initial thought is maybe just settle for running something like bemenu ${FM_OPTS} ${FM_COLORS_GENERIC} However, the interesting note arises where we could in theory have ${FM_COLORS_GENERIC} contain some option that has nothing to do with color, as we are not parsing any of this and just sending it along. Because of this, maybe the best option which I know we have had the idea for before is to have ${FM_OPTS} and then ${FM_OPTS_GENERIC} and the likes. Simply having the user decide (If they so choose) what options will be used anywhere. Since we already have the initial case statement for setting variables related to the program being used, we can easily add in defaults for supported programs like so:

case $FM_PROG in
    "bemenu")
        [ -z "$FM_OPTS" ] && FM_OPTS='-l 10'
        [ -z "$FM_OPTS_GENERIC" ] && FM_OPTS_GENERIC='-l 10 --sb=ffffff'
        [ -z "$FM_OPTS_BULK" ] && FM_OPTS_BULK='--sb=ababab'
        FM_OPT_PROMPT="-p"
        ;;

This way we could have the user decide from the start (Or not decide) and still have it work. The only adverse effect is of course there have to be multiple more variables thrown into the mix but it is my belief that it will be far more effective than trying to cram it all into one variable and have the script parse it every single time we want to add a simple color. We'd simply remove that second argument from yprompt() and the others and just in the function itself have it run bemenu ${FM_OPTS} ${FM_OPTS_GENERIC} (Or maybe even have completely separate for each and do bemenu ${FM_OPTS_GENERIC}?).

Do let me know what you think, apologies again for being less active as of late.

huijunchen9260 commented 4 years ago

Thank you for writing this as I now see what the core issue is.

Sorry I have been slow to respond at times, I have had limited time actually at my computer to work on this recently.

For this issue I would say that if we want to keep the flexibility, I would say we have the user decide on colors ahead of time, I guess we would have to settle and just have a separate variable containing the 'colors', as I feel all possible scenarios of parsing any number of unique settings for $FM_OPTS to choose what to replace with particular colors will be way more inefficient than simply making a separate variable for the different cases.

So my initial thought is maybe just settle for running something like bemenu ${FM_OPTS} ${FM_COLORS_GENERIC} However, the interesting note arises where we could in theory have ${FM_COLORS_GENERIC} contain some option that has nothing to do with color, as we are not parsing any of this and just sending it along. Because of this, maybe the best option which I know we have had the idea for before is to have ${FM_OPTS} and then ${FM_OPTS_GENERIC} and the likes. Simply having the user decide (If they so choose) what options will be used anywhere. Since we already have the initial case statement for setting variables related to the program being used, we can easily add in defaults for supported programs like so:

case $FM_PROG in
  "bemenu")
      [ -z "$FM_OPTS" ] && FM_OPTS='-l 10'
      [ -z "$FM_OPTS_GENERIC" ] && FM_OPTS_GENERIC='-l 10 --sb=ffffff'
      [ -z "$FM_OPTS_BULK" ] && FM_OPTS_BULK='--sb=ababab'
      FM_OPT_PROMPT="-p"
      ;;

This way we could have the user decide from the start (Or not decide) and still have it work. The only adverse effect is of course there have to be multiple more variables thrown into the mix but it is my belief that it will be far more effective than trying to cram it all into one variable and have the script parse it every single time we want to add a simple color. We'd simply remove that second argument from yprompt() and the others and just in the function itself have it run bemenu ${FM_OPTS} ${FM_OPTS_GENERIC} (Or maybe even have completely separate for each and do bemenu ${FM_OPTS_GENERIC}?).

Do let me know what you think, apologies again for being less active as of late.

Sorry that I am also working on my own stuff, since I want to switch from polybar to lemonbar.

I'll think about it today and maybe give you reply tomorrow.

huijunchen9260 commented 4 years ago

@VebbNix I think I got a good way to integrate your thought into original code with least modification (since I am lazy lol)

Rewrite the yprompt and xprompt like this:

yprompt () { # Usage yprompt [MSG] [BG_COLOR]
    case "$2" in
        "$FM_GENERIC_COLOR") ${FM_PROG:-dmenu} ${FM_OPTS_GENERIC:-${FM_OPTS--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10}} ${FM_OPT_PROMPT--p} "$1 " ;;
    "$FM_ACTION_COLOR_LV1") ${FM_PROG:-dmenu} ${FM_OPTS_ACTION_LV1:-${FM_OPTS--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10}} ${FM_OPT_PROMPT--p} "$1 " ;;
    "$FM_ACTION_COLOR_LV2") ${FM_PROG:-dmenu} ${FM_OPTS_ACTION_LV2:-${FM_OPTS--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10}} ${FM_OPT_PROMPT--p} "$1 " ;;
    "$FM_ACTION_COLOR_BULK") ${FM_PROG:-dmenu} ${FM_OPTS_ACTION_BULK:-${FM_OPTS--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10}} ${FM_OPT_PROMPT--p} "$1 " ;;
    *) ${FM_PROG:-dmenu} ${FM_OPTS--f -fn "$FM_GENERIC_FONT" -sb "$2" -i -l 10} ${FM_OPT_PROMPT--p} "$1 " ;;
    esac
    }

In this case, if FM_OPTS_GENERIC, FM_OPTS_ACTION_LV1, FM_OPTS_ACTION_LV2, FM_OPTS_ACTION_BULK is unset or empty, then it will fallback to FM_OPTS. If they are set and nonempty, then those OPTS will be adopted.

Also, in this way, you can just set OPTS in dmenufm.conf directly, no need to bother the source code.

camnw commented 4 years ago

I have implemented my idea for when you have the time to look. I will note I am not on my machine right now, so I could not fully test it. Obviously my fork isn't critical like the master branch so if it is slightly broken ill fix it later and that'll be fine. It should still convey my idea well.

I'd prefer not to do what you stated before because I feel it is not needed to have a case statement every time we run yprompt, and instead just have these defined beforehand.

Simply put, instead of supplying yprompt with ${FM_GENERIC_COLOR} you give it ${FM_OPTS_GENERIC}. To be honest, this is mostly changing the name of the variable, but by doing this we open up more doors to what you can do. With the current dmenufm I suppose you could just use the different colors as full sets of options that could be passed. For example you could do FM_GENERIC_COLOR="#983298 -l 10 --someOtherOptions". Now, you can still do the same thing (albeit more clearly) but it is intended to be changed as such, thus the name change from COLOR to just OPTS.

huijunchen9260 commented 4 years ago

I'd prefer not to do what you stated before because I feel it is not needed to have a case statement every time we run yprompt, and instead just have these defined beforehand.

This is a lovely idea. I will think about it and try to implement it and upload to master branch.

huijunchen9260 commented 4 years ago

Achieved by https://github.com/huijunchen9260/dmenufm/commit/f9e3804ba73ecd47be0e97c3f55c967826174241