0

For example I have this text in a buffer:

aaa
bbb
ccc

and I want it displayed with some spacing above the bbb line:

aaa

bbb
ccc

Is there a face or something which I could add to the bbb line, so it has some margin above it (without modyfing the buffer contents, so not with a newline like here, which I added only for demonstration purposes).

Tom
  • 1,260
  • 8
  • 16
  • Not an ideal solution, but the first thing that comes to mind is using an overlay or text property with an :overline property and set the thickness to your desire and make the color be the same as the background so that it is basically invisible to the naked eye. If there is a project more specific that you wish to accomplish, then forum participants may have a more comprehensive solution to suggest if you provide some additional details .... – lawlist Jan 15 '20 at 17:18
  • Thanks, overline may work, though in my emacs the docs only says that I can set the color. Is the thickness an emacs 27 feature? – Tom Jan 15 '20 at 17:29
  • Hmmm ... I am having trouble getting :overline to behave like :underline in terms of setting color and thickness and style. If I am able to come up with a working example, I'll post a follow-up comment. – lawlist Jan 15 '20 at 18:12
  • Well, underline can work too, I guess, if it works for the line above. The point is to have some spacing between the two lines, so it doesn't really matter if it's a top margin or a bottom margin for the upper row. – Tom Jan 15 '20 at 18:42
  • Sorry ... according to the accepted answer in the following thread, Emacs does not permit underline thickness adjustment: https://emacs.stackexchange.com/questions/37813/flycheck-change-color-thickness-of-underline – lawlist Jan 15 '20 at 19:04
  • Here is an idea: (add-text-properties (line-beginning-position) (line-end-position) (list 'face '(:box (:line-width 10 :color "yellow"))) The color can be changed to match the background face of the default face so that it can be invisible. Instead of text-properties, an overlay can probably be used instead if so desired. – lawlist Jan 15 '20 at 19:12
  • And here is the same idea with an overlay: (overlay-put (make-overlay (line-beginning-position) (line-end-position) nil t t) 'face (list 'face '(:box (:line-width 10 :color "yellow")))) Another idea would be to insert a thin character and adjust the height of it to force the line height to increase; e.g., there is an ascii character that is zero-width but Emacs treats it as being 1 pixel wide. – lawlist Jan 15 '20 at 19:20
  • Thanks, I found :box, it works, but it sets a bottom and top margin too, and also side margins, so it's not really what I was after, because I only wanted a top margin to separate visually sections of a file with spacing without adding actual new lines. But if there is no other option then it will do. – Tom Jan 15 '20 at 19:29

1 Answers1

1

I found a solution which is bit hackish, but not too much. I find the first space in the line and set it to a larger height. The line in my case always have a space somewhere (and it's generally true usually), the bigger height space forces the line height to be bigger which is effectively a top margin:

(let ((pos (1- (save-excursion (beginning-of-line) (search-forward " ")))))
    (put-text-property pos (1+ pos) 'display '(height 1.5)))

In the comments @rpluim suggested an even simpler alternative: putting the text property on the newline, but note that this method does not work well if the line is long and spans multiple visual lines.

(put-text-property (line-end-position) (1+ (line-end-position)) 'display '(height 1.5))
Tom
  • 1,260
  • 8
  • 16
  • 1
    I think you'd be better off putting the line-spacing or line-height property on the newline for the relevant lines. – rpluim Jan 16 '20 at 10:52
  • Good idea, that works too. – Tom Jan 16 '20 at 12:17
  • 1
    The newline method does not work well in practice, because I use the margin to make some files with long lines more readable (one physical line spans multiple visual lines), and if you put the line-height setting to the newline then the margin appears above the last virtual screen line of the physical line which is not good. If I put the height on the first space in the line then the first visual line always has the margin, even if the line spans multiple visual lines. – Tom Jan 16 '20 at 15:53
  • What if there is no space on the line? Maybe you can use a before-string property? – Lindydancer Feb 05 '22 at 07:38