diff --git a/configuration.org b/configuration.org index 093ecb1..bfef215 100644 --- a/configuration.org +++ b/configuration.org @@ -49,6 +49,266 @@ I set it up early so I can use it in ~use-package~ calls immediately. user-emacs-directory)) #+END_SRC +* Custom commands and functions + +** Misc text manipulation functions + +*** Delete the current line + +#+BEGIN_SRC emacs-lisp +(defun gpolonkai/delete-current-line () + "Kill the whole line on which point is." + (interactive) + + (beginning-of-line) + (kill-line 1)) +#+END_SRC + +*** Duplicate current line + +#+BEGIN_SRC emacs-lisp +(defun gpolonkai/duplicate-line() + "Duplicate line at point." + + (interactive) + + (save-excursion + (move-beginning-of-line 1) + (kill-line) + (yank) + (open-line 1) + (forward-line 1) + (yank))) +#+END_SRC + +*** Toggle case of character at point + +Based on [[http://ergoemacs.org/emacs/modernization_upcase-word.html][Xah’s toggle letter case defun version 2015-12-22]] + +#+BEGIN_SRC emacs-lisp +(defun toggle-char-case (arg-move-point) + "Toggle the case of the char after point. + +If prefix argument ARG-MOVE-POINT is non-nil, move point after the char." + (interactive "P") + (let ((case-fold-search nil)) + (cond + ((looking-at "[[:lower:]]") (upcase-region (point) (1+ (point)))) + ((looking-at "[[:upper:]]") (downcase-region (point) (1+ (point))))) + (cond + (arg-move-point (right-char))))) +#+END_SRC + +*** Open a new line below + +Copied from http://whattheemacsd.com/editing-defuns.el-01.html + +#+BEGIN_SRC emacs-lisp +(defun open-line-below () + "Open a new line below point." + + (interactive) + + (end-of-line) + (newline) + (indent-for-tab-command)) +#+END_SRC + +*** Open a new line above + +#+BEGIN_SRC emacs-lisp +(defun open-line-above () + "Open a new line above point." + + (interactive) + + (beginning-of-line) + (newline) + (forward-line -1) + (indent-for-tab-command)) +#+END_SRC + +*** TODO Kill or copy the whole line + +Got from Xah’s site (TODO is for adding a link here.) + +#+BEGIN_SRC emacs-lisp +(defun æ-kill-or-copy-whole-line (kill) + "Kill or copy the whole line point is on. + +If KILL is non-nil, the line gets killed. Otherwise, it gets just +copied to the kill ring." + (interactive "P") + + (if kill + (kill-whole-line) + (let ((beginning (progn (beginning-of-line) (point))) + (end (progn (end-of-line) (point)))) + (copy-region-as-kill beginning end)))) +#+END_SRC + +** Navigation + +*** Move to different beginnings of the current line + +Inspired by Bozhidar Batsov's [[http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/][solution]]. + +#+BEGIN_SRC emacs-lisp +(defun gpolonkai/move-to-beginning-of-line () + "Move to different beginnings of the line. + +These are, in order: + +- beginning of the visual line if `visual-line-mode' is active, +- the first non-whitespace (indentation), +- the actual beginning of the line. + +This function will jump between the first character and the +indentation if used multiple times." + (interactive) + (let ((last-pos (point))) + (when visual-line-mode + (beginning-of-visual-line)) + (when (= (point) last-pos) + (back-to-indentation)) + (when (= (point) last-pos) + (beginning-of-line)) + (when (and (eq major-mode 'org-mode) + (= (point) last-pos)) + (org-beginning-of-line)) + (when (= (point) last-pos) + (back-to-indentation)))) +#+END_SRC + +*** Move to the different ends of the current line + +#+BEGIN_SRC emacs-lisp +(defun gpolonkai/move-to-end-of-line () + "Move to the end of the line. + +If `visual-line-mode' is active, jump to the end of the visual +line first. Then jump to the actual end of the line." + (interactive) + (let ((last-pos (point))) + (when visual-line-mode + (end-of-visual-line)) + (when (= (point) last-pos) + (end-of-line)) + (when (and (eq major-mode 'org-mode) + (= (point) last-pos)) + (org-end-of-line)))) +#+END_SRC + +** File manipulation + +*** Rename the current file + +Copied from http://whattheemacsd.com/file-defuns.el-01.html + +#+BEGIN_SRC emacs-lisp +(defun rename-current-buffer-file () + "Renames current buffer and file it is visiting." + (interactive) + + (let ((name (buffer-name)) + (filename (buffer-file-name))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name (read-file-name "New name: " filename))) + (if (get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name) + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + ; TODO: this is suspicious for me… + (set-buffer-modified-p nil) + (message "File '%s' successfully renamed to '%s'" + name (file-name-nondirectory new-name))))))) +#+END_SRC + +*** Delete the current file + +Copied from http://whattheemacsd.com/file-defuns.el-02.html + +#+BEGIN_SRC emacs-lisp +(defun delete-current-buffer-file () + "Remove file connected to current buffer and kill the buffer." + (interactive) + + (let ((filename (buffer-file-name)) + (name (buffer-name)) + (buffer (current-buffer))) + (if (not (and filename (file-exists-p filename))) + (kill-buffer buffer) + (when (yes-or-no-p "Are you sure you want to remove this file? ") + (delete-file filename) + (kill-buffer buffer) + (message "File '%s' successfully removed" filename))))) +#+END_SRC + +*** Allow reopening the previously closed file + +#+BEGIN_SRC emacs-lisp +(defvar gpolonkai/last-killed-buffer-file-name + nil + "The last killed buffer. + +Used by `gpolonkai/kill-this-buffer' and `gpolonkai/undo-buffer-kill'.") + +(defun gpolonkai/kill-this-buffer () + "Kill the current buffer, but save the buffer file name so it can be undone." + (interactive) + (setq gpolonkai/last-killed-buffer-file-name (buffer-file-name)) + (kill-this-buffer)) + +(defun gpolonkai/undo-buffer-kill () + "Undo killing the last buffer. + +Esentially it visits the file again." + (interactive) + (if gpolonkai/last-killed-buffer-file-name + (progn + (find-file gpolonkai/last-killed-buffer-file-name) + (setq gpolonkai/last-killed-buffer-file-name nil)) + (message "The buffer last killed didn’t visit a file."))) +#+END_SRC +** ~c-mode~ related + +*** Copy the prototype of the current function + +#+BEGIN_SRC emacs-lisp +(defun gpolonkai/copy-func-prototype () + "Copy the current function's prototype to the kill ring." + + (interactive) + + (save-excursion + (beginning-of-defun) + (let ((protocopy-begin (point))) + (forward-list) + (let ((protocopy-end (point))) + (kill-ring-save protocopy-begin protocopy-end))))) +#+END_SRC + +** EShell related + +*** Delete a character, or close ~eshell~ if nothing to delet + +Copied from https://ryuslash.org/posts/C-d-to-close-eshell.html + +#+BEGIN_SRC emacs-lisp +(defun eshell-C-d () + "Either call `delete-char' interactively or quit." + (interactive) + + (condition-case err + (call-interactively #'delete-char) + (error (if (and (eq (car err) 'end-of-buffer) + (looking-back eshell-prompt-regexp nil)) + (kill-buffer) + (signal (car err) (cdr err)))))) +#+END_SRC + * UI preferences ** Tweak window chrome diff --git a/init.el b/init.el index 14ab945..89f13cb 100644 --- a/init.el +++ b/init.el @@ -30,7 +30,6 @@ (load "round-number-to-decimals") (load "zim") (load "enclose-string") -(load "buf-manipulation") (load "text-manip") (load "frame-manip") (load "file-manip") @@ -1154,7 +1153,7 @@ INFO plist." ("C-M-r" . isearch-backward) ("C-~" . toggle-char-case) :map ctl-x-map - ("C-y" . duplicate-line) + ("C-y" . gpolonkai/duplicate-line) ("_" . maximize-window) ("C-r" . rename-current-buffer-file) ("C-d" . delete-current-buffer-file) diff --git a/lisp/buf-manipulation.el b/lisp/buf-manipulation.el deleted file mode 100644 index e3ac46b..0000000 --- a/lisp/buf-manipulation.el +++ /dev/null @@ -1,203 +0,0 @@ -;;; buf-manipulation --- Summary -;; Some custom functions for buffer content manipulation -;; -;;; Commentary: - -;;; Code: -(defun delete-current-line () - "Kill the whole line on which point is." - (interactive) - - (beginning-of-line) - (kill-line 1)) - -(defun copy-func-prototype () - "Copy the current function's prototype to the kill ring." - - (interactive) - - (save-excursion - (beginning-of-defun) - (let ((protocopy-begin (point))) - (forward-list) - (let ((protocopy-end (point))) - (kill-ring-save protocopy-begin protocopy-end))))) - -(defun duplicate-line() - "Duplicate line at point." - - (interactive) - - (save-excursion - (move-beginning-of-line 1) - (kill-line) - (yank) - (open-line 1) - (forward-line 1) - (yank))) - -;; Based on Xah's toggle letter case defun version 2015-12-22 -;; -;; URL: http://ergoemacs.org/emacs/modernization_upcase-word.html -(defun toggle-char-case (arg-move-point) - "Toggle the case of the char after point. - -If prefix argument ARG-MOVE-POINT is non-nil, move point after the char." - (interactive "P") - (let ((case-fold-search nil)) - (cond - ((looking-at "[[:lower:]]") (upcase-region (point) (1+ (point)))) - ((looking-at "[[:upper:]]") (downcase-region (point) (1+ (point))))) - (cond - (arg-move-point (right-char))))) - -; Copied from http://whattheemacsd.com/editing-defuns.el-01.html -(defun open-line-below () - "Open a new line below point." - - (interactive) - - (end-of-line) - (newline) - (indent-for-tab-command)) - -(defun open-line-above () - "Open a new line above point." - - (interactive) - - (beginning-of-line) - (newline) - (forward-line -1) - (indent-for-tab-command)) - -; Copied from http://whattheemacsd.com/file-defuns.el-01.html -(defun rename-current-buffer-file () - "Renames current buffer and file it is visiting." - (interactive) - - (let ((name (buffer-name)) - (filename (buffer-file-name))) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (let ((new-name (read-file-name "New name: " filename))) - (if (get-buffer new-name) - (error "A buffer named '%s' already exists!" new-name) - (rename-file filename new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - ; TODO: this is suspicious for me… - (set-buffer-modified-p nil) - (message "File '%s' successfully renamed to '%s'" - name (file-name-nondirectory new-name))))))) - -; Copied from http://whattheemacsd.com/file-defuns.el-02.html -(defun delete-current-buffer-file () - "Remove file connected to current buffer and kill the buffer." - (interactive) - - (let ((filename (buffer-file-name)) - (name (buffer-name)) - (buffer (current-buffer))) - (if (not (and filename (file-exists-p filename))) - (kill-buffer buffer) - (when (yes-or-no-p "Are you sure you want to remove this file? ") - (delete-file filename) - (kill-buffer buffer) - (message "File '%s' successfully removed" filename))))) - -;; delete-char or close eshell -;; Copied from https://ryuslash.org/posts/C-d-to-close-eshell.html -(defun eshell-C-d () - "Either call `delete-char' interactively or quit." - (interactive) - - (condition-case err - (call-interactively #'delete-char) - (error (if (and (eq (car err) 'end-of-buffer) - (looking-back eshell-prompt-regexp nil)) - (kill-buffer) - (signal (car err) (cdr err)))))) - -(defun æ-kill-or-copy-whole-line (kill) - "Kill or copy the whole line point is on. - -If KILL is non-nil, the line gets killed. Otherwise, it gets just -copied to the kill ring." - (interactive "P") - - (if kill - (kill-whole-line) - (let ((beginning (progn (beginning-of-line) (point))) - (end (progn (end-of-line) (point)))) - (copy-region-as-kill beginning end)))) - -;; Inspired by Bozhidar Batsov's solution: -;; -;; http://emacsredux.com/blog/2013/05/22/smarter-navigation-to-the-beginning-of-a-line/ -(defun gpolonkai/move-to-beginning-of-line () - "Move to different beginnings of the line. - -These are, in order: - -- beginning of the visual line if `visual-line-mode' is active, -- the first non-whitespace (indentation), -- the actual beginning of the line. - -This function will jump between the first character and the -indentation if used multiple times." - (interactive) - (let ((last-pos (point))) - (when visual-line-mode - (beginning-of-visual-line)) - (when (= (point) last-pos) - (back-to-indentation)) - (when (= (point) last-pos) - (beginning-of-line)) - (when (and (eq major-mode 'org-mode) - (= (point) last-pos)) - (org-beginning-of-line)) - (when (= (point) last-pos) - (back-to-indentation)))) - -(defun gpolonkai/move-to-end-of-line () - "Move to the end of the line. - -If `visual-line-mode' is active, jump to the end of the visual -line first. Then jump to the actual end of the line." - (interactive) - (let ((last-pos (point))) - (when visual-line-mode - (end-of-visual-line)) - (when (= (point) last-pos) - (end-of-line)) - (when (and (eq major-mode 'org-mode) - (= (point) last-pos)) - (org-end-of-line)))) - -(defvar gpolonkai/last-killed-buffer-file-name - nil - "The last killed buffer. - -Used by `gpolonkai/kill-this-buffer' and `gpolonkai/undo-buffer-kill'.") - -(defun gpolonkai/kill-this-buffer () - "Kill the current buffer, but save the buffer file name so it can be undone." - (interactive) - (setq gpolonkai/last-killed-buffer-file-name (buffer-file-name)) - (kill-this-buffer)) - -(defun gpolonkai/undo-buffer-kill () - "Undo killing the last buffer. - -Esentially it visits the file again." - (interactive) - (if gpolonkai/last-killed-buffer-file-name - (progn - (find-file gpolonkai/last-killed-buffer-file-name) - (setq gpolonkai/last-killed-buffer-file-name nil)) - (message "The buffer last killed didn’t visit a file."))) - -(provide 'buf-manipulation) - -;;; buf-manipulation.el ends here