9

The documentation of Face Attributes suggests that adding a line-width of -n to the box attribute will

draw a line of width n whose top and bottom parts occupy the space of the underlying text, thus avoiding any increase in the character height.

So I've added the following line to my personal theme file for isearch candidates (lazy-highlight):

`(lazy-highlight ((,class (:box (:line-width -1 :color ,search) :background ,bg1 :foreground ,fg1))))

This works fine considering the height, however, the text width changes as seen in the gif below:

enter image description here

Is there any way to make left and the right part of the box also occupy the underlying text so that there is no change in the text width?

Pouya
  • 203
  • 1
  • 10

1 Answers1

4

My use case for this SE is to have a box around region face, so the highlighted region in transient-mark-mode is visible even when the region overlaps with some other overlays:

(set-face-attribute 'region nil
                    :box '(:line-width -1
                           :color "gtk_selection_bg_color"
                           :style nil))

For example, with iedit-mode:

boxed region overlay overlapping with iedit overlay

Every time the text is highlighted with "boxed region" I can see the described text width flickering.

The dirty hack I could find to eliminate this flickering is to add a box with background colour to the default face. Unfortunately, such hack would introduce a number of issues in other places, such as an additional gap between lines or incorrect rendering of button widgets (e.g. in customization buffers).

The ultimate solution is given in the following bug report (see attached patch at the end of the thread):

Text flickering moving cursor with box around text enabled

This solution affects Emacs internals and requires Emacs custom build after applying the patch.

I am going to try the later solution soon. The problem however is that my init.el would then become incompatible with stock Emacs builds and will have to use some additional logic to find if the above patch is applied.

Hopefully, after some testing this patch would get accepted into Emacs source...

2019-01-21 follow-up:

It seems that the above referenced patch is not compatible with the latest Emacs source code. I had to make some changes in order to make it work with the current Emacs git master branch. Instead of creating another patch, I made a fork at github and created a branch from upstream with face box patch:

face-box-patch

Building Emacs from this branch is the same as stock Emacs builds.

The following is the init.el code which should be compatible with both patched and vanilla Emacs versions:

(unwind-protect
    (condition-case ex
        (set-face-attribute
         'region nil
         :box '(:line-width (-1 . -1)
                            :color "gtk_selection_bg_color"
                            :style nil))
      ('error
       (set-face-attribute
        'region nil
        :box '(:line-width -1
                           :color "gtk_selection_bg_color"
                           :style nil)))))

It is only tested on Linux with GTK+

  • Nice find! Looks like patch was a year ago so I'm not hopeful that it will be accepted. – amitp Jan 18 '19 at 02:53
  • I applied the patch and am happily using negative box-width now :-) Thank you! – amitp Jan 18 '19 at 02:58
  • @amitp Thank for confirming that Alexandre's patch has worked for you! What Emacs version, OS and GUI are you using? – Victor Rybynok Jan 21 '19 at 22:26
  • I'm using the GUI version of the ["Mac Port"](https://bitbucket.org/mituharu/emacs-mac/). Emacs 26.1.91. After applying the patch I had to change a Mac-specific file (macterm.c) to make the same changes as in the rest of the code. I think the patch does far more than I really want though. I think (but haven't tested) that I should be able to change `eabs (s->face->box_line_width)` to `max (s->face->box_line_width, 0)` and no other changes. – amitp Jan 22 '19 at 23:27
  • After using it for a day, I'm seeing little glitches. I don't know if these are because of the patch or because of my changes to macterm.c. In any case, I ended up reverting. – amitp Jan 30 '19 at 00:40
  • I am using Alexandre's patch with my changes on Linux at home and at work for the last 10 days. The box face with negative line width works as expected. Unfortunately, this patch is designed with no backwards compatibility. I.e. if the patch is not applied to certain terminals (such as macterm) or emacs original code changes, it would not compile or would not work correctly. Ideally, this patch needs to be refactored to a common patch and a patch for each terminal type. The common patch should be back-compatible with un-patched terminal types and fall-back to conventional behaviour... – Victor Rybynok Jan 31 '19 at 00:54