;;; shm-yank-kill.el --- Yanking/killing operations ;; Copyright (c) 2014 Chris Done. All rights reserved. ;; This file 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, or (at your option) ;; any later version. ;; This file 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 . ;;; Code: (require 'shm-macros) (require 'shm-layout) (defun shm/mark-node () "Set the active mark to the current node." (interactive) (let ((current (shm-current-node))) (goto-char (shm-node-start current)) (set-mark (shm-node-end current)))) (defun shm/kill-region (beg end) "Kill the region, and save it in the clipboard." (interactive "r") (shm-kill-region nil beg end nil)) (defun shm/copy-region (beg end) "Copy the region, and save it in the clipboard." (interactive "r") (save-excursion (shm-kill-region 'clipboard-kill-ring-save beg end t))) (defun shm/kill-line () "Kill everything possible to kill after point before the end of the line. Successive kills will also work, for example: do |foo bar mu Hitting C-k C-k C-k here will killall three lines, and then C-y will insert them back verbatim." (interactive) (shm-with-fallback kill-line (shm/reparse) (cond ((looking-at "^[ ]+$") (delete-region (point) (line-end-position))) ((= (line-end-position) (line-beginning-position)) (delete-char -1) (forward-char 1)) ((and (shm-in-string) (not (= (point) (shm-node-start (shm-current-node))))) (let ((current (shm-current-node))) (if (and (> (shm-node-end current) (line-end-position)) (save-excursion (goto-char (line-end-position)) (looking-back "\\\\"))) (kill-region (point) (1- (line-end-position))) (kill-region (point) (1- (shm-node-end current)))))) ((and (= (point) (line-end-position)) (not (looking-at "\n[^ ]"))) (let ((column (current-column))) (delete-region (point) (save-excursion (forward-line 1) (goto-char (+ (line-beginning-position) column)))) (shm-kill-to-end-of-line t))) ((shm-current-node) (shm-kill-to-end-of-line)) (t (kill-line))))) (defun shm/kill-node () "Kill the current node." (interactive) (shm-kill-node)) (defun shm/yank () "Yank from the kill ring and insert indented with `shm-insert-indented'." (interactive) (shm-with-fallback yank ;; This avoids merging two identifiers together accidentally. (unless (or (shm-in-comment) (shm-in-string)) (when (looking-back "[a-zA-Z0-9]+_*") (shm-insert-string " ")) (when (looking-at "[a-zA-Z0-9]+_*") (shm-insert-string " ") (forward-char -1))) (shm-insert-indented #'clipboard-yank))) (defun shm/yank-pop () "Yank from the kill ring and insert indented with `shm-insert-indented'." (interactive) (shm-with-fallback yank-pop (if (not (eq last-command 'yank)) (error "Previous command was not a yank (error from shm/yank-pop)")) (shm-insert-indented #'yank-pop))) (defun shm/backward-kill-word () "Kill the word backwards." (interactive) (let ((to-be-deleted (save-excursion (backward-word) (point)))) (save-excursion (shm-adjust-dependents (point) (* -1 (- (point) to-be-deleted)))) (backward-kill-word 1))) (provide 'shm-yank-kill)