2014-03-04 67 views
2

如果區域滾動到視線之外,是否有選擇區域功能可保留選區?如何在屏幕移出後保持選定區域

我每天都會使用兩種選定區域。第一種是在各種移動功能中使用交互式代碼"^"的換檔鍵 - 例如左或右。第二種是set-mark-command。在第一種情況下,當我向上或向下滾動時,高亮區域被取消選擇。在第二種情況下,如果選定區域在滾動時觸摸窗口的頂部或底部,則突出顯示的區域會改變/移動。

理想情況下,我想選擇一個區域,然後可以自由地在緩衝區內移動,從點到點到點到點。

+1

這應該是相當容易寫一個存儲po的包在第一個滾動命令之前的點的位置,並且在第一個非滾動命令之前恢復它。然後它可以被精煉,以便在滾動時突出顯示區域反映了「非滾動點」,並且「滾動點」不被繪製爲光標。 – Stefan

回答

1

INITIAL(2014年3月4日):初稿。 lawlist-mwheel-scrollmwheel-scrollmwheel.el的變形例 - 所述一次改性是除去(let ((newpoint (point))) (goto-char opoint) (deactivate-mark) (goto-char newpoint))並立即向上或向下滾動之前,基於region-beginregion-end固定覆蓋替換它。

編輯(2014年3月5日):修訂lawlist-mwheel-scroll表現更像mwheel-scroll原本打算內mwheel.el。由於可以從左至右或從右至左選擇區域,因此original-point可能位於所選區域的任一側。因此,region-beginregion-end不用於計算point是否已移動 - 我們使用original-point並將其與滾動發生後潛在的新(point)進行比較。將先前功能lawlist-select-region的內容合併到功能lawlist-activate-deactivate-mark中,以使前者不再使用。


(global-set-key (kbd "C-c c") 'lawlist-copy-selected-region) 

(global-set-key (kbd "C-SPC") 'lawlist-activate-deactivate-mark) 

(global-set-key [(wheel)] 'lawlist-mwheel-scroll) 

(global-set-key [(wheel-down)] 'lawlist-mwheel-scroll) 

(global-set-key [(wheel-up)] 'lawlist-mwheel-scroll) 

(defvar region-begin nil 
    "The beginning of the selected region.") 
(make-variable-buffer-local 'region-begin) 

(defvar region-end nil 
    "The ending of the selected region.") 
(make-variable-buffer-local 'region-end) 

(defun lawlist-activate-deactivate-mark() 
(interactive) 
    (cond 
    ;; newly selected region -- no prior overlay 
    ((and 
     (region-active-p) 
     (not region-begin) 
     (not region-end)) 
     (setq region-begin (region-beginning)) 
     (setq region-end (region-end)) 
     (overlay-put (make-overlay region-begin region-end) 'priority 1001) 
     (overlay-put (make-overlay region-begin region-end) 'face isearch-face) 
     (deactivate-mark t)) 
    ;; prior overlay + newly selected region 
    ((and 
     (region-active-p) 
     region-begin 
     region-end) 
     (mapc 'delete-overlay (overlays-in region-begin region-end)) 
     (setq region-begin (region-beginning)) 
     (setq region-end (region-end)) 
     (overlay-put (make-overlay region-begin region-end) 'priority 1001) 
     (overlay-put (make-overlay region-begin region-end) 'face isearch-face) 
     (deactivate-mark t)) 
    ;; prior overlay -- no selected region -- inside of overlay 
    ((and 
     (not (region-active-p)) 
     region-begin 
     region-end 
     (and 
      (>= (point) region-begin) 
      (<= (point) region-end))) 
     (message "[b]egin | [e]nd | [c]urrent | [d]eactivate") 
     (let* ((extend-region (read-char-exclusive))) 
     (cond 
      ((eq extend-region ?b) 
      (set-marker (mark-marker) region-begin (current-buffer)) 
      (setq mark-active t)) 
      ((eq extend-region ?e) 
      (set-marker (mark-marker) region-end (current-buffer)) 
      (setq mark-active t)) 
      ((eq extend-region ?c) 
      (set-marker (mark-marker) (point) (current-buffer)) 
      (setq mark-active t)) 
      ((eq extend-region ?d) 
      (deactivate-mark t)))) 
     (mapc 'delete-overlay (overlays-in region-begin region-end))) 
    ;; prior overlay -- no selected region -- outside of overlay 
    ((and 
     (not (region-active-p)) 
     region-begin 
     region-end 
     (or 
      (< (point) region-begin) 
      (> (point) region-end))) 
     (mapc 'delete-overlay (overlays-in region-begin region-end)) 
     (setq region-begin nil) 
     (setq region-end nil) 
     (deactivate-mark t)) 
    (t 
     (set-mark-command nil)))) 

(defun lawlist-copy-selected-region() 
(interactive) 
    (cond 
    ;; prior overlay + newly selected region 
    ((and 
     (region-active-p) 
     region-begin 
     region-end) 
     (mapc 'delete-overlay (overlays-in region-begin region-end)) 
     (setq region-begin (region-beginning)) 
     (setq region-end (region-end))) 
    ;; prior overlay + no region selected 
    ((and 
     (not (region-active-p)) 
     region-begin 
     region-end) 
     (mapc 'delete-overlay (overlays-in region-begin region-end))) 
    ;; newly selected region -- no prior overlay 
    ((and 
     (region-active-p) 
     (not region-begin) 
     (not region-end)) 
     (setq region-begin (region-beginning)) 
     (setq region-end (region-end)))) 
    (if (and region-begin region-end) 
    (progn 
     (copy-region-as-kill region-begin region-end) 
     (message "copied: %s" 
     (concat 
      (truncate-string-to-width 
      (buffer-substring-no-properties region-begin region-end) 
       40) 
      (if 
      (> 
       (length 
       (buffer-substring-no-properties region-begin region-end)) 
       40) 
      " . . ." 
      ""))) 
     (setq region-begin nil) 
     (setq region-end nil)) 
    (message "To copy, you must first select a region."))) 

(defun lawlist-mwheel-scroll (event) 
    "Scroll up or down according to the EVENT. 
This should only be bound to mouse buttons 4 and 5." 
    (interactive (list last-input-event)) 
    (let* (
     (curwin 
     (if mouse-wheel-follow-mouse 
      (prog1 
      (selected-window) 
      (select-window (mwheel-event-window event))))) 
     (buffer (window-buffer curwin)) 
     (original-point 
     (with-current-buffer buffer 
      (when (eq (car-safe transient-mark-mode) 'only) 
      (point)))) 
     (mods 
     (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) 
     (amt (assoc mods mouse-wheel-scroll-amount))) 
    (with-current-buffer buffer 
     (when (eq (car-safe transient-mark-mode) 'only) 
     (setq region-begin (region-beginning)) 
     (setq region-end (region-end)))) 
    (if amt (setq amt (cdr amt)) 
     (let ((list-elt mouse-wheel-scroll-amount)) 
     (while (consp (setq amt (pop list-elt)))))) 
    (if (floatp amt) (setq amt (1+ (truncate (* amt (window-height)))))) 
    (when (and mouse-wheel-progressive-speed (numberp amt)) 
     (setq amt (* amt (event-click-count event)))) 
    (unwind-protect 
     (let ((button (mwheel-event-button event))) 
     (cond 
      ((eq button mouse-wheel-down-event) 
      (condition-case nil (funcall mwheel-scroll-down-function amt) 
       (beginning-of-buffer 
       (unwind-protect 
        (funcall mwheel-scroll-down-function) 
       (set-window-start (selected-window) (point-min)))))) 
      ((eq button mouse-wheel-up-event) 
      (condition-case nil (funcall mwheel-scroll-up-function amt) 
       (end-of-buffer (while t (funcall mwheel-scroll-up-function))))) 
      (t (error "Bad binding in mwheel-scroll")))) 
     (if curwin (select-window curwin))) 
    (with-current-buffer buffer 
     (when 
      (and 
      original-point 
      (/= (point) original-point)) 
     (overlay-put (make-overlay region-begin region-end) 'priority 1001) 
     (overlay-put (make-overlay region-begin region-end) 'face isearch-face) 
     (deactivate-mark t)))) 
    (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time) 
    (if mwheel-inhibit-click-event-timer 
     (cancel-timer mwheel-inhibit-click-event-timer) 
     (add-hook 'pre-command-hook 'mwheel-filter-click-events)) 
    (setq mwheel-inhibit-click-event-timer 
     (run-with-timer mouse-wheel-inhibit-click-time nil 
     'mwheel-inhibit-click-timeout)))) 

(put 'lawlist-mwheel-scroll 'scroll-command t) 
2

我不認爲有這樣的功能。事情是emacs在滾動時移動點(當點移出窗口時),這就是所選區域改變的原因。請看question

+0

理論上,起點和終點可以設置爲緩衝區局部變量 - 當選定區域的一部分進入視野時,該區域可以被重新突出顯示並激活。也許'post-command-hook'可以用於這個目的。當該區域被用戶停用時,變量將被重新設置爲「nil」,這樣'post-command-hook'不會始終觸發該功能。 – lawlist

+1

@lawlist - 按點定義區域,因此當您在緩衝區中移動時,區域會發生變化。該地區**總是**一端以點爲界。我不認爲有任何方法可以解決這個問題,這對Emacs如何工作至關重要。我認爲你需要找到一種記住不使用該地區的職位的方法。 – Tyler

+0

@泰勒 - 嗯。 。 。我會給它更多的想法 - 像'(isearch-highlight beg end)',但它能夠複製/剪切/粘貼區域。 – lawlist