This is a collection of dotfiles and scripts for my bspwm setup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.3 KiB

;;; dot-core-functions.el --- -*- lexical-binding: t; -*-
;;; Commentary:
;; Custom elisp functions and macros.
;;; Code:
;; -----------------------------------------
;; General Functions
;; Functions that only use built-in Emacs functionality.
(defun display-startup-echo-area-message ()
"Hide default startup message."
(message nil))
(defun dot/config-visit ()
"Edit config file."
(interactive)
(find-file (expand-file-name "init.el" dot-emacs-dir)))
(defun dot/config-reload ()
"Reload config file."
(interactive)
(load (expand-file-name "init.el" dot-emacs-dir)))
(defun dot/copy-cpp-function-implementation ()
"Copy C++ function implementation to clipboard."
(interactive)
(save-excursion
(let ((func (save-excursion
(re-search-backward "\\b")
(re-search-forward "\\([^;]+\\);")
(match-string 1)))
(type (progn
(re-search-backward "\\b")
(push-mark)
(back-to-indentation)
(buffer-substring (mark) (point))))
(class (progn
(backward-up-list)
(backward-sexp)
(back-to-indentation)
(forward-to-word 1)
(current-word))))
(kill-new (concat type class "::" func "\n{\n}"))))
(message "Copied function implementation"))
;; Reference: http://turingmachine.org/bl/2013-05-29-recursively-listing-directories-in-elisp.html
(defun dot/directory-files-recursively-depth (dir regexp include-directories maxdepth)
"Depth limited variant of the built-in `directory-files-recursively'."
(let ((result '())
(current-directory-list (directory-files dir t)))
(dolist (path current-directory-list)
(cond
((and (file-regular-p path)
(file-readable-p path)
(string-match regexp path))
(setq result (cons path result)))
((and (file-directory-p path)
(file-readable-p path)
(not (string-equal "/.." (substring path -3)))
(not (string-equal "/." (substring path -2))))
(when (and include-directories
(string-match regexp path))
(setq result (cons path result)))
(when (> maxdepth 1)
(setq result (append (nreverse (dot/directory-files-recursively-depth
path regexp include-directories (- maxdepth 1)))
result))))
(t)))
(reverse result)))
(defun dot/dired-find-file ()
"In Dired, visit the file or directory named on this line."
(interactive)
(if (file-directory-p (dired-file-name-at-point))
(dired-find-alternate-file)
(dired-find-file)))
(defun dot/dired-up-directory ()
"Run Dired on parent directory of current directory."
(interactive)
(find-alternate-file ".."))
(defun dot/find-file-emacsd ()
"Find file under `dot-emacs-dir', recursively."
(interactive)
(let ((files (mapcar 'abbreviate-file-name
(directory-files-recursively dot-emacs-dir ""))))
(find-file (completing-read "Find file (emacs): " files nil t))))
(defun dot/indent-buffer ()
"Indent each nonblank line in the buffer."
(interactive)
(save-excursion
(indent-region (point-min) (point-max) nil)))
(defun dot/insert-spaces-until-column (until-column)
"Insert spaces from point to UNTIL-COLUMN."
(interactive "nInsert spaces until column: ")
(let ((current-column (current-column)))
;; Increment column if the index is 1 based
(when (not column-number-indicator-zero-based)
(setq current-column (+ current-column 1)))
;; Insert spaces
(let ((diff (- until-column current-column)))
(if (> diff 0)
(save-excursion (insert (make-string diff ?\ )))
(user-error "Column should be higher than point")))))
(defun dot/reload-theme ()
"Reload custom theme."
(interactive)
(mapc 'load (file-expand-wildcards
(concat (car custom-theme-load-path) "*.el")))
(load-theme (car custom-enabled-themes) t))
(defun dot/sudo-find-file (filename)
"Edit file FILENAME as root."
(interactive "FOpen file (as root): ")
(find-file (concat "/sudo:root@localhost:" filename)))
(defun dot/sudo-this-file ()
"Edit the current file as root."
(interactive)
(if buffer-file-name
(find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))
(princ "Current buffer isn't a file")))
(defun dot/toggle-fringe (&optional arg)
"Toggle left-only fringe, or set state with ARG."
(interactive)
(if (or (and (eq fringe-mode 0) (eq arg nil))
(eq arg 1))
(set-fringe-mode '(nil . 0))
(set-fringe-mode 0)))
(defun dot/M-x (command)
"Prompt and execute COMMAND."
(interactive "CCommand: ")
(command-execute command))
(defun split-follow-horizontally ()
"Split and follow window."
(interactive)
(split-window-below)
(other-window 1))
(defun split-follow-vertically ()
"Split and follow window."
(interactive)
(split-window-right)
(other-window 1))
;; https://emacsredux.com/blog/2013/05/04/rename-file-and-buffer/
(defun rename-file-and-buffer ()
"Rename the current buffer and file it is visiting."
(interactive)
(let ((filename (buffer-file-name)))
(if (not (and filename (file-exists-p filename)))
(message "Buffer is not visiting a file!")
(let ((new-name (read-file-name "New name: " filename)))
(cond
((vc-backend filename) (vc-rename-file filename new-name))
(t
(rename-file filename new-name t)
(set-visited-file-name new-name t t)))))))
;; -----------------------------------------
;; Hook call functions
(defun dot/hook-disable-line-numbers ()
"Disable the line numbers."
(display-line-numbers-mode 0))
(defun dot/hook-disable-mode-line ()
"Disable the mode line."
(setq-local mode-line-format nil))
(provide 'dot-core-functions)
;; -----------------------------------------
;; Macros
;; Reference: https://github.com/arcticicestudio/nord-emacs/issues/59#issuecomment-414882071
(defmacro dot/run-after-new-frame (func)
"Run FUNC once or after every frame creation.
This is needed for UI initialization when running with the daemon."
`(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame) (with-selected-frame frame ,func)))
,func))
;;; dot-core-functions.el ends here