company-mode icon indicating copy to clipboard operation
company-mode copied to clipboard

Incorrect alignment when changing buffer font size

Open cpitclaudel opened this issue 9 years ago • 27 comments

In emacs 24.4.1, using company-mode 20150204.836, changing the font size causes suggestions to be improperly aligned:

screenshot from 2015-02-11 13 40 42

The font size was increased using text-scale-increase after company-mode was loaded. Am I doing anything wrong?

cpitclaudel avatar Feb 11 '15 18:02 cpitclaudel

Thanks for the report, but it's more or less a known issue.

Last discussed here: http://debbugs.gnu.org/18493

I don't have an easy solution for it yet.

dgutov avatar Feb 11 '15 19:02 dgutov

I see, thanks! That's a bit frustrating. Hopefully GUI-based popups will solve this problem!

cpitclaudel avatar Feb 12 '15 04:02 cpitclaudel

Ah I see. I guess Emacs core devs are stubborn enough to have an alternate mechanism to facilitate the fix.

zoom-frm

iTerm2 on OSX has a nifty feature on text zoom in or out. It also resizes the GUI window to adjust the prespective. So I looked that up and found its alternative in Melpa, called zoom-frm. It does exactly what it says, instead of resizing buffer it zooms the whole Emacs frame. There's also face-remap+, which combined with zoom-frm gives you more fine grained control.

For now, it's working really well. I guess, same sort of behavior can be used in company-mode to detect any buffer zooming and replace it with frame zooming. Let the overlays stay. Possibly the best workaround right now but @dgutov would know better :stuck_out_tongue_winking_eye: :beer:

bassu avatar Jun 25 '15 00:06 bassu

Another solution that I've been using:

(defvar original-font-size nil)

(defun adjust-font-size (delta)
  (let* ((old-size (face-attribute 'default :height))
         (new-size (max (max delta (- delta)) (min 200 (+ delta old-size)))))
    (setq original-font-size (or original-font-size old-size))
    (set-face-attribute 'default nil :height new-size)
    (message "Font size set to %d (was %d)" (face-attribute 'default :height) old-size)))

(defun zoom-in ()
  (interactive)
  (adjust-font-size +10))

(defun zoom-out ()
  (interactive)
  (adjust-font-size -10))

(defun zoom-reset ()
  (interactive)
  (when original-font-size
    (set-face-attribute 'default nil :height original-font-size)))

;; Zoom settings
(global-set-key [\C-mouse-4] 'zoom-in)
(global-set-key [\C-mouse-5] 'zoom-out)
(global-set-key [\C-kp-add] 'zoom-in)
(global-set-key [\C-kp-subtract] 'zoom-out)
(global-set-key (kbd "<C-kp-0>") 'zoom-reset)

cpitclaudel avatar Jun 25 '15 01:06 cpitclaudel

@cpitclaudel Nice. I guess that's what zoom-frm is doing to keep the aspect ratio by a factor that it recalculates each time. For ease, I have also remapped the keys

;Zoom-frm
(global-set-key (kbd "C-=") 'zoom-in/out)
(global-set-key (kbd "C--") 'zoom-in/out)
(global-set-key (kbd "<s-triple-wheel-up>")  'zoom-frm-in)
(global-set-key (kbd "<s-triple-wheel-down>") 'zoom-frm-out)

bassu avatar Jun 25 '15 01:06 bassu

That's a good solution, @cpitclaudel maybe you should publish it in a package.

dgutov avatar Jun 25 '15 11:06 dgutov

Hey Dmitry,

Do you have a sense of what problems replacing (car (posn-col-row posn)) by (current-column) in (defun company--posn-col-row (posn) would cause? Extremely minimal testing seems to indicate that it fixes part of this issue.

I can think of the following issues:

  • If the current line has a large font but the following lines have a regular font (eg \section{} lines in AuxTeX), this will break. The current code is already broken in that case, so it's not obvious how bad this is.
  • window-hscroll uses unscaled units, so this will break in an hscrolled window with scaled text. The current code is broken with scaled text in all cases, so this is an improvement. With unscaled text, it should be fine.

Other things that I would have missed?

cpitclaudel avatar Jan 25 '16 00:01 cpitclaudel

Hmm, to answer the question in general, I'm not sure. I thought there was some reason we couldn't use current-column, but I can't think of it now.

On a smaller scale, the issues are:

  • You can't "just" use current-column from a function that takes a posn value as an argument. That position might not be the current point. In particular:
  • company--posn-col-row is called from company--event-col-row, which is used in company-select-mouse. Which means selection of a candidate using the mouse will remain broken.

I'm not sure if the second point justifies not fixing this issue for the keyboard interaction. There is something to be said for handling them both the same, however.

dgutov avatar Jan 25 '16 00:01 dgutov

Indeed, looking at 6468e89 (also see the emacs-devel link there), it was more of a natural change that came together with using posn-col-row to determine the current row.

However, here's another drawback: current-column doesn't take into account the display properties on the current line before point (not sure how often that occurs in practice). It accounts for composition, however, but someone would have to check it in the previous versions of Emacs as well.

dgutov avatar Jan 25 '16 01:01 dgutov

@cpitclaudel would you turn your solution into package? (:

geraldus avatar Jan 25 '16 10:01 geraldus

Ah, the display thing is an issue; mostly because it affects everyone, not only people with text-scale-mode on. I don't know how often this happens in practice, however. If it's not too common, I'd vote for using current-column still.

For the mouse thing, could that work by moving the point to where the mouse event happened, and calling (current-column) there?

The context in which I'm running into this is using company during presentations and demos. Using text-scale-mode is the most intuitive approach to zoom the frame, but it breaks company's display. I've had professors complain that it made company-coq hard to use in front of a class :/

cpitclaudel avatar Jan 25 '16 13:01 cpitclaudel

@geraldus: This doesn't sound like too good an idea to me: I'd much rather help fix the problem for everyone than implement a workaround as a separate package.

cpitclaudel avatar Jan 25 '16 13:01 cpitclaudel

For the mouse thing, could that work by moving the point to where the mouse event happened, and calling (current-column) there?

That position might not exist: it could be inside a display property (not entirely uncommon), or it could be simply after the end of a physical line.

I'd much rather help fix the problem for everyone

IMO, fixing it properly entails implementing a different rendering scheme. Overlay-based rendering will continue to have its drawbacks.

dgutov avatar Jan 25 '16 14:01 dgutov

As a reminder, here are the alternatives for current-column (pick one):

http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18493#77 http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18493#92

dgutov avatar Jan 25 '16 14:01 dgutov

Indeed, I read that thread in detail :)

I'd much rather help fix the problem for everyone IMO, fixing it properly entails implementing a different rendering scheme. Overlay-based rendering will continue to have its drawbacks.

I agree. But if we can fix a common use case without affecting other users, it might be worth doing it, especially if the fix isn't intrusive, don't you think?

cpitclaudel avatar Jan 25 '16 15:01 cpitclaudel

I suppose?

dgutov avatar Jan 25 '16 15:01 dgutov

Another place where current-column fails is with wrapped lines in visual-line-mode.

cpitclaudel avatar Jan 25 '16 20:01 cpitclaudel

Indeed. :( I thought horizontal scrolling could be a problem, but it could be solved by subtracting the window width, assuming the current line does span beyond it.

But visual-line-mode is more of an obstacle.

dgutov avatar Jan 25 '16 21:01 dgutov

Could (- (current-column) (save-excursion (beginning-of-visual-line) (current-column))) be an option?

cpitclaudel avatar Jan 26 '16 00:01 cpitclaudel

I suppose. Even if its results are a bit inconsistent with horizontal scrolling as well.

Eli should be a better person to ask if there are any edge cases we're missing.

dgutov avatar Jan 26 '16 07:01 dgutov

But have you looked into the "taking a copy of posn-col-row into company.el and changing it so that it multiplies" plan? It doesn't sound too difficult, and it'll handle mouse clicks as well.

dgutov avatar Jan 26 '16 07:01 dgutov

Any news?

nico202 avatar Feb 08 '18 15:02 nico202

Ugh, the same problem exists in popup.el / auto-complete. I thought that moving to company-mode would solve this issue, but I guess not. It seems that neither auto-completion solution is superior right now, for this is probably the most outstanding issue for both packages.

ylluminarious avatar Mar 14 '18 06:03 ylluminarious

You can try company-childframe now, but it's fairly experimental.

dgutov avatar Mar 14 '18 07:03 dgutov

I'm trying company-posframe, which, if I understand correctly, supersedes company-childframe, but it's behaving erratically. A proper fix would be fantastic and I think a lot of users would benefit from it. Thanks for your great work on company mode!

tmalsburg avatar Feb 02 '19 13:02 tmalsburg

@tmalsburg I think the best option at this point is report any such bugs to company-posframe's author. He's quite responsive.

dgutov avatar Dec 09 '19 22:12 dgutov

Thanks @dgutov. I ended up not using company because of these issue but will reconsider when I find some spare time.

tmalsburg avatar Dec 10 '19 10:12 tmalsburg