Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: more multiple-cursor commands #1517

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ lint:
.qlot/bin/sblint extensions/lua-mode/lem-lua-mode.asd
.qlot/bin/sblint extensions/makefile-mode/lem-makefile-mode.asd
.qlot/bin/sblint extensions/markdown-mode/lem-markdown-mode.asd
.qlot/bin/sblint extensions/multiple-cursors/lem-multiple-cursors.asd
.qlot/bin/sblint extensions/nim-mode/lem-nim-mode.asd
.qlot/bin/sblint extensions/ocaml-mode/lem-ocaml-mode.asd
.qlot/bin/sblint extensions/paredit-mode/lem-paredit-mode.asd
Expand Down
4 changes: 4 additions & 0 deletions extensions/multiple-cursors/lem-multiple-cursors.asd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(defsystem "lem-multiple-cursors"
:depends-on (:lem)
:serial t
:components ((:file "multiple-cursors")))
98 changes: 98 additions & 0 deletions extensions/multiple-cursors/multiple-cursors.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
(defpackage :lem-multiple-cursors
(:use :cl :lem)
(:import-from :lem/isearch
:isearch-start
:search-next-matched
:isearch-abort
:make-add-char-callback)
(:import-from :lem/buffer/internal
:point-linum
:point-line
:point-change-line)
(:import-from :lem/buffer/line
:line-previous
:line-next)
(:export :add-cursors-to-next-line
:add-cursors-to-previous-line
:mark-next-like-this)
#+sbcl
(:lock t))
(in-package :lem-multiple-cursors)

(define-key *global-keymap* "M-C" 'add-cursors-to-next-line)

(define-command add-cursors-to-next-line () ()
"Duplicates the cursor under the currently existing cursors."
(add-cursor-to-line-with-offset 1))

(define-command add-cursors-to-previous-line () ()
"Duplicates the cursor above the currently existing cursors."
(add-cursor-to-line-with-offset -1))

(define-command mark-next-like-this () ()
""
(if (buffer-mark-p (current-buffer))
(mark-like-this-direction (buffer-mark (current-buffer)) (buffer-point (current-buffer))
#'search-forward)
(add-cursors-to-next-line)))

(define-command mark-previous-like-this () ()
""
(if (buffer-mark-p (current-buffer))
(mark-like-this-direction (buffer-mark (current-buffer)) (buffer-point (current-buffer))
#'search-backward)
(add-cursors-to-previous-line)))

(defun add-cursor-to-line-with-offset (offset)
(let ((cursors (buffer-cursors (current-buffer))))
(loop :for (cursor next-cursor) :on cursors
:do (with-point ((p cursor))
(when (and (line-offset p offset (point-charpos p))
(or (null next-cursor)
(not (same-line-p p next-cursor))))
(make-fake-cursor p))))))

(defun clear-duplicate-cursors (buffer)
(loop :for (cursor next-cursor) :on (buffer-cursors buffer)
:when (and next-cursor (and (same-line-p cursor next-cursor) (eq (point-charpos cursor) (point-charpos next-cursor))))
:do (delete-fake-cursor
(if (eq cursor (buffer-point buffer))
next-cursor
cursor))))

(defun mark-like-this-direction (start end direction)
(isearch-start ""
(make-add-char-callback direction)
direction
(if (equal direction #'search-forward)
#'search-backward
#'search-forward)
(points-to-string start end))
(dolist (point (buffer-cursors (current-buffer)))
(with-point ((point point))
(if (search-next-matched point 1)
(progn
(setf (point-charpos point) (point-charpos end))
(setf cursor (make-fake-cursor point))
(dotimes (_ (- (point-linum end) (point-linum start)))
(if (equal direction #'search-forward)
(point-change-line point (- (point-linum point) 1) (line-previous (point-line point)))
(point-change-line point (+ (point-linum point) 1) (line-next (point-line point)))))
(setf (point-charpos point) (- (point-charpos point) (- (point-charpos end) (point-charpos start))))
(set-cursor-mark cursor point))
(message "No more matches"))))
(isearch-abort))

(defun garbage-collection-cursors ()
;; TODO: find a less janky method of preventing multiple cursors from overlapping and typing the same letter twice
(clear-duplicate-cursors (current-buffer))
(clear-duplicate-cursors (current-buffer)))

(add-hook *pre-command-hook* 'garbage-collection-cursors)

(defun clear-cursors-when-aborted ()
(let ((string (merge-cursor-killrings (current-buffer))))
(clear-cursors (current-buffer))
(copy-to-clipboard-with-killring string)))

(add-hook *editor-abort-hook* 'clear-cursors-when-aborted)
4 changes: 2 additions & 2 deletions lem.asd
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@
(:file "project" :depends-on ("file"))
(:file "buffer")
(:file "window" :depends-on ("move"))
(:file "multiple-cursors")
(:file "process")
(:file "help")
(:file "font")
Expand Down Expand Up @@ -263,7 +262,8 @@
"lem-terminal"
"lem-legit"
"lem-dashboard"
"lem-copilot"))
"lem-copilot"
"lem-multiple-cursors"))

(defsystem "lem/executable"
:build-operation program-op
Expand Down
38 changes: 0 additions & 38 deletions src/commands/multiple-cursors.lisp

This file was deleted.

1 change: 0 additions & 1 deletion src/external-packages.lisp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
(uiop:define-package :lem
(:use :cl)
(:use-reexport :lem-core)
(:use-reexport :lem-core/commands/multiple-cursors)
(:use-reexport :lem-core/commands/move)
(:use-reexport :lem-core/commands/edit)
(:use-reexport :lem-core/commands/mark)
Expand Down