如何使用与浏览器中相同的条形光标进行选择

How to make selection with bar cursor the same as in browser

我是 emacs 的新手,正在尝试从现有的 browser/vscode-like 文本操作工作流程开始逐步学习它。

起初,用鼠标选择文本似乎让我很沮丧。为了修复它,我通过将 (setq-default cursor-type 'bar) 放在 ~/.emacs.

中切换到经典浏览器“条形”光标样式

但是,它并没有解决选择问题,它只是在视觉上改变了光标。在浏览器中,如果我点击可编辑文本区域中的一个字符,我的光标会被放置

在 emacs 中,如果我单击一个字符,光标总是位于字符之前。 我该如何解决?

您可以尝试 emacs.stackexchange.com 来获取常规 Emacs 帮助。 Mouse pointer between characters and the text cursor misplacement 看起来有人和你有基本相同的问题,并且有一些信息丰富的讨论以及一个代码片段,你可能会觉得有帮助,但我没有试过。

我将 posn-point 函数(subr.el 中的 defined)的实现替换为我自己的 advice-add。因此,在初始化文件 (~/.emacs.d/init.el) 中插入以下代码后,一切都按预期进行。它在 emacs 27.2 中工作,但如果 posn-point 的原始实现或调用它发生变化,可能会中断。

(setq-default cursor-type 'bar) ;; thin cursor

(defun my-point-bol (point)
  "check if point location at the beginning of line"
  (save-excursion
    (goto-char point)
    (equal (point-at-bol) point)))

(defun my-point-eol (point)
  "check if point location at the end of line"
  (save-excursion
    (goto-char point)
    (equal (point-at-eol) point)))

(defun my-posn-point (orig-posn-point position)
  "Redefenition of standard emacs function that fixes character clicks"
  (let ((point (nth 5 position))
        (dx (car-safe (posn-object-x-y position)))
        (sx (car-safe (posn-object-width-height position)))
        (non-text-pos (posn-object position)))
    (if (and point dx sx (not non-text-pos)
             (>= dx 0) ;; fix clicks at line nubmers
             (not (my-point-eol point))) ;; fix clicks after end of line
        (let ((offset (round (/ (float dx) sx))))
          (+ point offset))
      (funcall orig-posn-point position)))) ;; for some reason doesn't work (reliably) without funcall

(advice-add 'posn-point :around #'my-posn-point)

;; enable firing mouse-movement events on pixel change instead of glyph change
;; it fixes lagging selection during dragging
(setq mouse-fine-grained-tracking t)

这段代码的思路来源于问题https://emacs.stackexchange.com/questions/20279/mouse-pointer-between-characters-and-the-text-cursor-misplacement的答案。在这里,我试图解决我在那里发现的所有错误:行首、行尾的不正确处理,当调用转到原始函数而不是重载函数时的奇怪情况,以及拖动鼠标选择。