From 653d52352d4ae16178d2236d911c7fca3f9875fa Mon Sep 17 00:00:00 2001 From: lexa Date: Mon, 4 Aug 2014 23:33:05 +0400 Subject: [PATCH 1/3] Added mc-hide-unmatched-lines mode This minor mode when enabled hides all lines where no cursors (and also hum/lines-to-expand below and above) To make use of this mode press "C-'" while multiple-cursor-mode is active. You can still edit lines while you are in mc-hide-unmatched-lines mode. To leave this mode press "" or "C-g" --- mc-hide-unmatched-lines-mode.el | 119 ++++++++++++++++++++++++++++++++ multiple-cursors-core.el | 3 + multiple-cursors.el | 1 + 3 files changed, 123 insertions(+) create mode 100644 mc-hide-unmatched-lines-mode.el diff --git a/mc-hide-unmatched-lines-mode.el b/mc-hide-unmatched-lines-mode.el new file mode 100644 index 0000000..67375bf --- /dev/null +++ b/mc-hide-unmatched-lines-mode.el @@ -0,0 +1,119 @@ +;;; mc-hide-unmatched-lines.el + +;; Copyright (C) 2014 Aleksey Fedotov + +;; Author: Aleksey Fedotov +;; Keywords: editing cursors + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This minor mode when enabled hides all lines where no cursors (and +;; also hum/lines-to-expand below and above) To make use of this mode +;; press "C-'" while multiple-cursor-mode is active. You can still +;; edit lines while you are in mc-hide-unmatched-lines mode. To leave +;; this mode press "" or "C-g" +;; + +;;; Code: + + +(require 'multiple-cursors-core) + +(defvar hum/hide-unmatched-lines-mode-map (make-sparse-keymap) + "Keymap for hide unmatched lines is mainly for rebinding C-g") + +(define-key hum/hide-unmatched-lines-mode-map (kbd "C-g") 'hum/keyboard-quit) +(define-key hum/hide-unmatched-lines-mode-map (kbd "") 'hum/keyboard-quit) + +(defun hum/keyboard-quit () + "Leave hide-unmatched-lines mode" + (interactive) + (mc-hide-unmatched-lines-mode 0)) + +;; used only in in multiple-cursors-mode-disabled-hook +(defun hum/disable-hum-mode () + (mc-hide-unmatched-lines-mode 0) +) + +(define-minor-mode mc-hide-unmatched-lines-mode + "Minor mode when enabled hides all lines where no cursos (and +also hum/lines-to-expand below and above) To make use of this +mode press \"C-'\" while multiple-cursor-mode is active. You can +still edit lines while you are in mc-hide-unmatched-lines +mode. To leave this mode press or \"C-g\"" + nil " hu" + hum/hide-unmatched-lines-mode-map + (if mc-hide-unmatched-lines-mode + ;;just in case if mc mode will be disabled while hide-unmatched-lines is active + (progn + (hum/hide-unmatched-lines) + (add-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode t t)) + (progn + (hum/unhide-unmatched-lines) + (remove-hook 'multiple-cursors-mode-disabled-hook 'hum/disable-hum-mode)) + ) +) + +(defconst hum/invisible-overlay-name 'hum/invisible-overlay-name) + +(defcustom hum/lines-to-expand 2 + "How many lines below and above cursor to show" + :type '(integer) + :group 'multiple-cursors) + +(defcustom hum/placeholder "..." + "Placeholder which will be placed insted of hiden text" + :type '(string) + :group 'multiple-cursors +) + +(defun hum/add-invisible-overlay (begin end) + (let ((overlay (make-overlay begin + end + (current-buffer) + t + nil + ))) + (overlay-put overlay hum/invisible-overlay-name t) + (overlay-put overlay 'invisible t) + (overlay-put overlay 'intangible t) + (overlay-put overlay 'evaporate t) + (overlay-put overlay 'after-string hum/placeholder) + ) + ) + + +(defun hum/hide-unmatched-lines () + (let ((begin (point-min))) + (mc/for-each-cursor-ordered + (save-excursion + (goto-char (mc/cursor-beg cursor)) + (if (< begin (line-beginning-position (- hum/lines-to-expand))) + (hum/add-invisible-overlay begin (line-end-position (- hum/lines-to-expand))) + ) + (setq begin (line-beginning-position (+ 2 hum/lines-to-expand))) + ) + ) + (hum/add-invisible-overlay begin (point-max)) + ) + ) + +(defun hum/unhide-unmatched-lines () + (remove-overlays nil nil hum/invisible-overlay-name t) + ) + +(provide 'mc-hide-unmatched-lines-mode) +(define-key mc/keymap (kbd "C-'") 'mc-hide-unmatched-lines-mode) diff --git a/multiple-cursors-core.el b/multiple-cursors-core.el index 974b1b8..bc8a279 100644 --- a/multiple-cursors-core.el +++ b/multiple-cursors-core.el @@ -596,6 +596,9 @@ for running commands with multiple cursors.") mc/skip-to-next-like-this mc/skip-to-previous-like-this rrm/switch-to-multiple-cursors + mc-hide-unmatched-lines-mode + hum/keyboard-quit + hum/unhide-invisible-overlays save-buffer ido-exit-minibuffer exit-minibuffer diff --git a/multiple-cursors.el b/multiple-cursors.el index 9c847ee..9c44db9 100644 --- a/multiple-cursors.el +++ b/multiple-cursors.el @@ -185,6 +185,7 @@ (require 'mc-mark-pop) (require 'rectangular-region-mode) (require 'mc-separate-operations) +(require 'mc-hide-unmatched-lines-mode) (provide 'multiple-cursors) From bf9e8e95e0f76b6a0014909415bb789804f9a8ef Mon Sep 17 00:00:00 2001 From: lexa Date: Mon, 4 Aug 2014 23:36:01 +0400 Subject: [PATCH 2/3] Added testcase for mc-hide-unmatched-lines-mode --- features/hide-unmatched-lines.feature | 73 +++++++++++++++++++ .../multiple-cursors-steps.el | 27 +++++++ 2 files changed, 100 insertions(+) create mode 100644 features/hide-unmatched-lines.feature diff --git a/features/hide-unmatched-lines.feature b/features/hide-unmatched-lines.feature new file mode 100644 index 0000000..3a4040e --- /dev/null +++ b/features/hide-unmatched-lines.feature @@ -0,0 +1,73 @@ +Feature: Hiding lines without cursor + + Scenario: Hiding lines when three cursor active + Given I have cursors at "line" in : + """ + 0 + line + 2 + 3 + line + 5 + 6 + 7 + 8 + 9 + 10 + 11 + line + 13 + 14 + 15 + """ + And I press "C-'" + Then I should have 3 cursors + Then I should see exactly: + """ + 0 + line + 2 + 3 + line + 5 + 6 + + 10 + 11 + line + 13 + 14 + + """ + + + Scenario: Hiding lines when only two cursor active + When I insert: + """ + 1 + 2 + 3 + 4 + 5 + text + 6 + 7 + 8 + 9 + 10 + """ + And I go to the front of the word "text" + And I press "C->" + And I press "C-'" + Then I should have 2 cursors + Then I should see exactly: + """ + + 4 + 5 + text + 6 + 7 + 8 + + """ diff --git a/features/step-definitions/multiple-cursors-steps.el b/features/step-definitions/multiple-cursors-steps.el index a0052fd..a5590b7 100644 --- a/features/step-definitions/multiple-cursors-steps.el +++ b/features/step-definitions/multiple-cursors-steps.el @@ -79,6 +79,17 @@ (mc/mark-all-like-this) (mc/keyboard-quit))) +(Given "^I have cursors at \"\\(.+\\)\" in \\(?: \"\\(.+\\)\"\\|:\\)$" + (lambda (needle haystack) + (insert haystack) + (goto-char (point-min)) + (search-forward needle) + (set-mark (point)) + (goto-char (match-beginning 0)) + (mc/mark-all-like-this) + (mc/keyboard-quit))) + + (When "^I copy \"\\(.+\\)\" in another program$" (lambda (text) (lexical-let ((text text)) @@ -137,3 +148,19 @@ (split-string rest)) "-")))) (call-interactively func)))) + +(Then "^I should see exactly\\(?: \"\\(.+\\)\"\\|:\\)$" + "Asserts that the current buffer does not include some text with + respect of text hidden by overlays" + (lambda (expected) + (let ((p (point-min)) + (visible-text "") + (message "Expected '%s' to be part of '%s', but was not found in current buffer.") + ) + (while (not (= p (point-max))) + (if (not (invisible-p p)) + (setq visible-text (concat visible-text (buffer-substring p (1+ p)))) + ) + (setq p (1+ p)) + ) + (cl-assert (s-equals? expected visible-text) nil message expected visible-text)))) From 4b0e91239e209886e7281420d7933a61f62e538f Mon Sep 17 00:00:00 2001 From: lexa Date: Mon, 4 Aug 2014 23:37:27 +0400 Subject: [PATCH 3/3] Added description of mc-hide-unmached-mode to Readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f3c98c2..d97345a 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,8 @@ You can [watch an intro to multiple-cursors at Emacs Rocks](http://emacsrocks.co insert a newline in multiple-cursors-mode, use `C-j`. - Sometimes you end up with cursors outside of your view. You can - scroll the screen to center on each cursor with `C-v` and `M-v`. + scroll the screen to center on each cursor with `C-v` and `M-v` or you can + press `C-'` to hide all lines without a cursor, press `C-'` again to unhide. - Try pressing `mc/mark-next-like-this` with no region selected. It will just add a cursor on the next line. @@ -184,6 +185,7 @@ Run the tests with: * [Fuco](https://github.com/Fuco1) added the first version of `mc/mark-all-like-this-dwim` * [Zach Kost-Smith](https://github.com/smithzvk) added `mc/mark-pop` * [Maciej Katafiasz](https://github.com/mathrick) added `mc/mark-all-dwim` +* [Aleksey Fedotov](https://github.com/lexa) added `mc-hide-unmatched-lines-mode` Thanks!