;;; keybindings.el --- Custom keybindings and functions -*- lexical-binding: t -*-
;;; Commentary:
;; Custom key bindings and utility functions with conflict resolution
;;; Code:
;; Simple aliases
(defalias 'qrr 'query-replace-regexp)
(defalias 'tmm 'tmm-menubar)
(defalias 'qrs 'replace-string)
(defalias 'qfs 'flymake-show-buffer-diagnostics)
;; Utility functions
(defun dws/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)
(set-buffer-modified-p nil)
(message "File '%s' successfully renamed to '%s'"
name (file-name-nondirectory new-name)))))))
(defun dws/kill-other-buffers ()
"Kill all other buffers."
(interactive)
(mapc 'kill-buffer (delq (current-buffer) (buffer-list))))
(defun dws/revert-all-buffers ()
"Refreshes all open buffers from their respective files."
(interactive)
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (and (buffer-file-name)
(file-exists-p (buffer-file-name))
(not (buffer-modified-p)))
(revert-buffer t t t))))
(message "Refreshed open files."))
(defun dws/join-line()
"Join lines at point."
(interactive)
(join-line -1))
(defun dws/set-path ()
"Set up Emacs exec path and PATH environment variable."
(interactive)
(let ((path-from-shell
(replace-regexp-in-string
"[ \t\n]*$" ""
(shell-command-to-string
"$SHELL --login -i -c 'echo $PATH'"))))
(setenv "PATH" path-from-shell)
(setq exec-path (split-string path-from-shell path-separator))))
;; Terminal management
(defun dws/switch-terminal ()
"Switch between eshell and multi-term based on context."
(interactive)
(if (or (eq major-mode 'shell-mode)
(eq major-mode 'term-mode))
;; If we're in a terminal, make a new one
(multi-term)
;; Otherwise switch to most recent terminal or make new
(if (get-buffer "*shell*")
(switch-to-buffer "*shell*")
(shell))))
;; Global keybindings
(bind-keys*
;; Basic editing
("C--" . undo)
("M-j" . dws/join-line)
("DEL" . delete-backward-char) ;; Instead of C-h to preserve help
("C-w" . backward-kill-word)
("C-x ," . dabbrev-expand)
("C-x C-k" . kill-region)
;; Window management (preserved as they're unique)
("M--" . enlarge-window-horizontally)
("M-0" . delete-window)
("M-1" . delete-other-windows)
("M-2" . split-window-below)
("M-3" . split-window-right)
("M-5" . balance-windows)
("M-o" . other-window) ;; Single definition
;; Buffer operations with safer bindings
("M-k" . kill-buffer)
("C-x C-s" . save-buffer) ;; Standard Emacs binding
("M-G" . goto-line) ;; Changed from M-g to preserve goto prefix
;; Terminal management (unified)
;; ("M-/" . dws/switch-terminal) ;; Single smart terminal command
;; setting back to eshell for now
("M-/" . eshell)
;; Custom functions
("C-c r" . dws/revert-all-buffers) ;; Simplified from C-c C-M-r
("C-c d" . delete-frame) ;; Simplified from C-c C-d
("C-c v" . dws/rotate-windows) ;; Simplified from C-c C-v
;; Mac-specific (preserved)
("H-8" . toggle-frame-fullscreen))
;; Mode-specific keybindings
(with-eval-after-load 'term
(bind-keys :map term-mode-map
("M-p" . term-send-up)
("M-n" . term-send-down)
("M-b" . consult-buffer)))
;; Midnight mode for buffer cleanup
(use-package midnight
:defer 600
:custom
(clean-buffer-list-delay-general 3)
:config
(midnight-delay-set 'midnight-delay "9:04am")
(add-to-list 'clean-buffer-list-kill-never-buffer-names "*.org"))
(provide 'keybindings)
;;; keybindings.el ends here