Skip to content

Enable to change the background color of dialogs. - #413

Merged
peterzhu2118 merged 13 commits into
ruby:masterfrom
pocari:support-for-changing-the-background-color-of-dialogs
Jun 27, 2022
Merged

Enable to change the background color of dialogs.#413
peterzhu2118 merged 13 commits into
ruby:masterfrom
pocari:support-for-changing-the-background-color-of-dialogs

Conversation

@pocari

@pocaripocari commented Dec 29, 2021

Copy link
Copy Markdown
Contributor

Reline in its current state also has the ability to change the background color using the bg_color attribute of DialogRenderInfo, but I couldn't seem to use that feature right now.

I changed it so that in addition to the bg_color, the background color of the item being selected for completion can also be set, and then it can be defined in "inputrc" so that the user can choose the color.

default color:
スクリーンショット 2021-12-29 17 12 37

customize sample:
スクリーンショット 2021-12-29 17 13 54

You can try with the following settings

% cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem 'reline', github: 'pocari/reline', branch: 'support-for-changing-the-background-color-of-dialogs'
gem 'irb', github: 'pocari/irb', branch: 'feature/add-config-params-for-reline'
% bundle install
% cat ~/.irbrc
IRB.conf[:DIALOG_DEFAULT_BG_COLOR] = 40
IRB.conf[:DIALOG_POINTER_BG_COLOR] = 47
% bundle exec irb

@pocaripocari changed the title Make it possible to set the background color of the dialog and the ba…Enable to change the background color of dialogs.Dec 29, 2021
@elfham

Copy link
Copy Markdown
Contributor

Readline complains about new unknown keywords in inputrc.

% echo "set dialog-default-bg-color 40" >> ~/.inputrc
% echo "set dialog-pointer-bg-color 47" >> ~/.inputrc
% bash
readline: ~/.inputrc: line 14: dialog-default-bg-color: unknown variable name
readline: ~/.inputrc: line 15: dialog-pointer-bg-color: unknown variable name
$ 

@pocari

Copy link
Copy Markdown
ContributorAuthor

@elfham If Reline is mandatory to be compatible with readline, my implementation this time may not be good.
But we can't customize the background color if we can't pass some value to the reline. If you have a better idea for this, please let me know.

@elfham

Copy link
Copy Markdown
Contributor

Since inputrc is a common configuration file for Readline and Reline, I'm afraid that apps that use Readline will suffer the side effects of adding this keyword.

I'm not an expert on Reline, so I don't know if this is the right way to do it, but how about setting it up in irbrc?

@pocari

Copy link
Copy Markdown
ContributorAuthor

@elfham I did not know that irbrc existed. I'll try to see if I can use it. Thank you.

@pocari

pocari commented Jan 17, 2022

Copy link
Copy Markdown
ContributorAuthor

@elfham I modified irbrc so that it can pass configuration items. (ruby/irb#337)

You can try this fix with a Gemfile like the one below.

% cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem 'reline', github: 'pocari/reline', branch: 'support-for-changing-the-background-color-of-dialogs'
gem 'irb', github: 'pocari/irb', branch: 'feature/add-config-params-for-reline'
% bundle install
% cat ~/.irbrc
IRB.conf[:DIALOG_DEFAULT_BG_COLOR] = 40
IRB.conf[:DIALOG_POINTER_BG_COLOR] = 47
% bundle exec irb

スクリーンショット 2022-01-17 23 00 08

@elfham

Copy link
Copy Markdown
Contributor

I have tried this fix and it seems to be working well.
Thanks for the fix.

@joeyparis

Copy link
Copy Markdown

@pocari also confirmed working with no problems

@pocari

Copy link
Copy Markdown
ContributorAuthor

I have also made the foreground color changeable.
ruby/irb#337 (comment)

@sshock

Copy link
Copy Markdown
Contributor

Would love to see this feature! Is there any reason it hasn't been approved and merged yet?

@elfham

Copy link
Copy Markdown
Contributor

I too see no problem with this feature.

BTW, the main developer, @aycabta, does not seem to be very active since the end of last year.
He tweeted that he suffered a mild stroke and I am concerned ......

Comment threadlib/reline/line_editor.rb Outdated
fg_color = 37
if i == pointer
bg_color = '45'
if dialog_render_info.pointer_fg_color

@st0012st0012May 16, 2022

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about setting the default values when initializing the reline like other configs?

reline/lib/reline.rb

Lines 546 to 551 in 5b3fc02

core.basic_word_break_characters=" \t\n`><=;|&{("
core.completer_word_break_characters=" \t\n`><=;|&{("
core.basic_quote_characters='"\''
core.completer_quote_characters='"\''
core.filename_quote_characters=""
core.special_prefixes=""

Then we don't need these if statements because the dialog_render_info should always have values from the config default. It will also help users getting the default by just calling Reline.dialog_default_fg_color.

If we really worry about the values being nil by accident, we should validate them at the setter.

@pocari

pocari commented May 22, 2022

Copy link
Copy Markdown
ContributorAuthor

@st0012 Thanks for the comments. Those points seemed right to me. However, the properties I added this time were defined in the below section, so I wasn't sure if I should treat them the same way.

DialogRenderInfo=Struct.new(:pos,:contents,:bg_color,:width,:height,:scrollbar,keyword_init: true)

@st0012

Copy link
Copy Markdown
Member

Since we want them to be exposed externally, I think it doesn't matter where they'll be used. The point is to make the values more easily accessible.

@pocari

Copy link
Copy Markdown
ContributorAuthor

@st0012 Thank you. I have added the code as you mentioned. 9bf4979

Comment threadlib/reline.rb Outdated
core.add_dialog_proc(:autocomplete, Reline::DEFAULT_DIALOG_PROC_AUTOCOMPLETE, Reline::DEFAULT_DIALOG_CONTEXT)
core.dialog_default_bg_color = 46 # Cyan
core.dialog_default_fg_color = 37 # White
core.dialog_pointer_bg_color = 45 # Maggenta

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maggenta => Magenta

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Maumagnaguagno Thanks. I have fixed it.

@st0012

Copy link
Copy Markdown
Member

@pocari Thanks for the update. It looks good to me 👍
Do you think you can update the description example to a version that doesn't require the irb patch? I think directly setting reline's color with the exposed APIs should work too? Something like:

# .irbrcReline.dialog_default_bg_color=40Reline.dialog_pointer_bg_color=47

@hsbt Would you mind giving this a look? I know @aycabta is the maintainer but he seems to have been away for a while.

I think being able to change the background color of the dialog is essential for good user-experience. And as shown in ruby/irb#328, the default color doesn't look good with some themes (for example, mine). And many users decided to turn off the autocomplete feature altogether because of the color.

Of course, to completely fix the irb's issue will require some more work (releasing this change in a minor release + bump irb's dependency requirement + cut another irb minor release). But having this merged will already allow some users to workaround the issue themselves.

@pocari

pocari commented May 30, 2022

Copy link
Copy Markdown
ContributorAuthor

@st0012As for irbrc, I was advised by another person and made the following changes.
ruby/irb#337 (comment)

Do you think you can update the description example to a version that doesn't require the irb patch?

That may be possible.

@pocari

pocari commented May 30, 2022

Copy link
Copy Markdown
ContributorAuthor

@st0012 As you said it was possible. Thanks! You can try it with the following

% cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem 'reline', github: 'pocari/reline', branch: 'support-for-changing-the-background-color-of-dialogs'
% bundle install
% cat ~/.irbrc
if Reline
Reline.dialog_default_bg_color = 40
Reline.dialog_pointer_bg_color = 47
Reline.dialog_pointer_fg_color = 30
Reline.dialog_pointer_bg_color = 45
end
% bundle exec irb

I have added a condition because there must be some environments where Reline is not installed.

@st0012

st0012 commented May 30, 2022

Copy link
Copy Markdown
Member

@pocari To be clear, I know the irb change is necessary. But having reline-only example will make this change easier to understand and test 🙂

@st0012

Copy link
Copy Markdown
Member

@pocari Can you rebase your branch to see if the CI passes?

pocariand others added 3 commits June 25, 2022 23:56
Co-authored-by: Peter Zhu <peter@peterzhu.ca>
…f github.com:pocari/reline into support-for-changing-the-background-color-of-dialogs
@pocari
pocariforce-pushed the support-for-changing-the-background-color-of-dialogs branch from d0559f8 to 2302293CompareJune 26, 2022 05:56

@peterzhu2118peterzhu2118 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution!

@st0012

Copy link
Copy Markdown
Member

@hsbt@peterzhu2118 Do you think we can cut a 0.4.0 release for this change? Here are the changes since v0.3.1

There are a few reasons:

  1. We can test these new APIs early.
  2. irb can start requiring reline >= 0.4.0, which can make the implementation cleaner and also make users adopting it easier.
    • Instead of installing both irb and reline on GH source, the user will only need to install the latest irb.

Or do you have any concerns/thoughts?

@nobu

nobu commented Jun 27, 2022

Copy link
Copy Markdown
Member

46, 37 and so on are not “colors”, but attributes including where they are applied to, foreground or background.
That means you can set “background” to a foreground attribute 37, for instance.
So I think “attribute” string would be more proper here.

@pocari

Copy link
Copy Markdown
ContributorAuthor

@nobu
Just to confirm, are you saying that dialog_default_bg_attribute is better than dialog_default_bg_color, for example?

@st0012

Copy link
Copy Markdown
Member

I feel "color" is still a better name because that's what we want them to be used for.
But the APIs can indeed do more to prevent misuse.

How about this

Reline.dialog_default_bg_color=:blackReline.dialog_pointer_bg_color=:whiteReline.dialog_pointer_fg_color=:blackReline.dialog_pointer_bg_color=:white

And the color assignment logic can do:

# lib/reline/config.rbdefdialog_default_bg_color=(color)@dialog_default_bg_color=select_color_code(:bg,color)enddefselect_color_code(type,color)if:bgcasecolorwhen:black40when:white47# ...... the restelseraiseColorNotFoundendelsecasecolorwhen:black30when:white37# ...... the restelseraiseColorNotFoundendendend

@nobu

nobu commented Jun 28, 2022

Copy link
Copy Markdown
Member

To set colors only, dialog_default_bg_color etc make sense, and passing color names would be better.
However attributes are not only colors, but highlight, reverse video, underline, etc too.

Another concern is "\e[#{bg_color}m\e[#{fg_color}m#{str}" will reset bg_color if fg_color is set to 0.
The setters don't check the arguments.

BTW, your select_color_code can be:

defselect_color_code(type,color)casetypewhen:bg;40when:fg;30elseraiseColorNotFoundend +
casecolorwhen:black;30when:white;37# ...... the restelseraiseColorNotFoundend

or even Hash#fetch may be useful.

@st0012

Copy link
Copy Markdown
Member

However attributes are not only colors, but highlight, reverse video, underline, etc too.

That's true. But from what I've seen so far, the only request is on color and not other text effects. I'm sure some users would want that but perhaps we can design better APIs for those cases when we get more feedback?

Another concern is "\e[#{bg_color}m\e[#{fg_color}m#{str}" will reset bg_color if fg_color is set to 0.

The reason I want to pass color symbol instead of integer is to prevent cases like this, as we won't have 0 available in the case statement.

BTW, your select_color_code can be:

That's a great suggestion 👍 I'll open a PR shortly.

@james-caresnap

Copy link
Copy Markdown

46, 37 and so on are not “colors”, but attributes including where they are applied to, foreground or background.
That means you can set “background” to a foreground attribute 37, for instance.
So I think “attribute” string would be more proper here.

The linux man page calls them "color sequences".

However, the ANSI escape code standard calls them "control sequences".

st0012 added a commit to st0012/reline that referenced this pull request Jun 28, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_code APIs to access the raw code.
@st0012st0012 mentioned this pull request Jun 28, 2022
st0012 added a commit to st0012/reline that referenced this pull request Jun 28, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
st0012 added a commit to st0012/reline that referenced this pull request Jun 28, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
@nobunobu added the enhancement New feature or request label Jun 29, 2022
str_width = dialog.width - (dialog.scrollbar_pos.nil? ? 0 : @block_elem_width)
str = padding_space_with_escape_sequences(Reline::Unicode.take_range(item, 0, str_width), str_width)
@output.write "\e[#{bg_color}m#{str}"
@output.write "\e[#{bg_color}m\e[#{fg_color}m#{str}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be "\e[#{bg_color};#{fg_color}m#{str}".

@output.write "\e[#{bg_color}m#{str}"
@output.write "\e[#{bg_color}m\e[#{fg_color}m#{str}"
if dialog.scrollbar_pos and (dialog.scrollbar_pos != old_dialog.scrollbar_pos or dialog.column != old_dialog.column)
@output.write "\e[37m"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe scrollbar color too?

st0012 added a commit to st0012/reline that referenced this pull request Jun 30, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
st0012 added a commit to st0012/reline that referenced this pull request Jul 11, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
st0012 added a commit to st0012/reline that referenced this pull request Jul 11, 2022
As pointed out in the
[comment](ruby#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
matzbot pushed a commit to ruby/ruby that referenced this pull request Jul 15, 2022
…r APIs
As pointed out in the
[comment](ruby/reline#413 (comment)),
the code is actually a control sequence and not only for colors.
To make the dialog color APIs safer to use, we should restrict its
usages and extract away the bg/fg concept from the input.
So in this commit, I made these changes:
1. The dialog_*_bg/fg_color APIs only takes and returns color names (symbol):
- :black
- :red
- :green
- :yellow
- :blue
- :magenta
- :cyan
- :white
2. Add additional dialog_*_bg/fg_color_sequence APIs to access the raw code.
ruby/reline@b32a977766
@st0012st0012 mentioned this pull request Jul 27, 2022
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancementNew feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants

@pocari@elfham@joeyparis@sshock@st0012@arianf@nobu@james-caresnap@Maumagnaguagno@peterzhu2118