鼠标点击字符偏右,不能把光标至于字符之后,能否配置解决?

把cursor设成bar来观察效果 (setq cursor-type 'bar)

emacs: image 鼠标移动光标至于“德”字偏右,单击左键,cursor bar出现在“德”字之前

vscode: image 鼠标移动光标至“德”字偏右(过50%即可),单击左键,cursor bar出现在“德”字之后

vscode的响应符合直觉,用着舒服。 感觉emacs这个细节处理不太合理,能否通过配置更改此处的行为?

Emacs 用户估计99%都不会使用鼠标的,用鼠标的话直接用VScode 体验会比较好。除了这个,还有其他地方用鼠标不舒服的地方。

这也是困扰我的一个问题,之前我以为大家都不觉得这是个问题 :grinning:

平时用emacs都是键盘为主,最近用鼠标才发现。

感觉实现应该不难,没有理由不支持啊,有可能是我配置不到位。

期待大神路过,一句lisp解决问题 :grin:

或者有更大的大神,确认不改c源码做不到,让我死心,也就释然了 :upside_down_face:

emacs的光标是按方块的那个来算的。输入的时候是输入到方块的前面,而方块是罩在整个字上,你这么想就直观了。。

1 个赞

Emacs,没有什么不可能👍!

(defun adjust-point-after-click (event &optional _)
  "Adjust point.
Adjust point depending on which portion of the character the
cursor clicked on, if on the right half, move point after.
EVENT is the mouse event."
  (let* ((posn (event-end event))
         (x (car (posn-object-x-y posn)))
         (w (car (posn-object-width-height posn))))
    ;; ‘mouse-set-point’ is called twice when you click mouse, first
    ;; in ‘down-mouse-1’, called by ‘mouse-drag-region’ ->
    ;; ‘mouse-drag-track’ to set point, second in ‘mouse-1’, when
    ;; mouse released and Emacs realized that this is a click event.
    ;; We want to adjust point in both cases.
    (when (and (null (posn-object posn))
               (> x (/ w 2)))
      (forward-char))))

(define-minor-mode accurate-click-mode
  "Accurate point position on click."
  :global t
  :lighter ""
  (if accurate-click-mode
      (advice-add 'mouse-set-point :after #'adjust-point-after-click)
    (advice-remove 'mouse-set-point #'adjust-point-after-click)))
8 个赞

多谢解答,这下舒服了。

有emacs-china众神在,没有什么不可能 :+1:

非常感谢提供解决方案,的确解决了困扰楼主和我的问题。但是有一个新的问题出现了。 2020-08-11_09-02-35

应用了这个模式之后,如果点击图中1的位置,设想中鼠标应该是位于该行末尾,也就是 (event &optional _) 之后。但是实际上确到了下一行的开始。

(defun adjust-point-after-click (event &optional _)
  "Adjust point.
Adjust point depending on which portion of the character the
cursor clicked on, if on the right half, move point after.
EVENT is the mouse event."
  (let* ((posn (event-end event))
         (x (car (posn-object-x-y posn)))
         (w (car (posn-object-width-height posn))))
    ;; ‘mouse-set-point’ is called twice when you click mouse, first
    ;; in ‘down-mouse-1’, called by ‘mouse-drag-region’ ->
    ;; ‘mouse-drag-track’ to set point, second in ‘mouse-1’, when
    ;; mouse released and Emacs realized that this is a click event.
    ;; We want to adjust point in both cases.
    (when (and (null (posn-object posn))
               (> x (/ w 2))
               (not (eq (char-after) ?\n)))
      (forward-char))))

(define-minor-mode delicate-click-mode
  "Accurate point position on click.
That is, if you click on the right half of a character, the point
is set to after it."
  :global t
  :lighter ""
  (if delicate-click-mode
      (advice-add 'mouse-set-point :after #'adjust-point-after-click)
    (advice-remove 'mouse-set-point #'adjust-point-after-click)))
8 个赞

万分感谢。困扰多年问题得以解决 :rofl:

Emacs 30 版本加了个新的全局选项 mouse-prefer-closest-glyph,默认是关闭的, 开启后就可以在鼠标点击字符右半时自动移动光标到字符之后。

详细说明见这2个commit:

  1. etc/NEWS: Announce the new option ‘mouse-prefer-closest-glyph’
  2. Implement new option ‘mouse-prefer-closest-glyph’
  3. emacs-devel: Moving point after character when clicking latter half of it
4 个赞