diff --git a/init.el b/init.el index 0fc4cfe..f6d7c2a 100644 --- a/init.el +++ b/init.el @@ -97,7 +97,8 @@ (init-packages/init '(emacs version-control - editing)) + editing + workflow)) ;; *********************************************************************** ;; @@ -117,29 +118,18 @@ ;; -------------------------------------------------------------------------- ;; Load any custom variables. ;; -------------------------------------------------------------------------- - (when (file-exists-p custom-file) - (load custom-file)) + (load custom-file 'noerror) ;; -------------------------------------------------------------------------- - ;; Formatting + ;; Programming style. ;; -------------------------------------------------------------------------- - (setq-default tab-width 8) ;; Tab width - (setq-default indent-tabs-mode nil) ;; No tabs - (setq-default fill-column 79) ;; Line width - (setq-default whitespace-line-column fill-column) ;; For whitespace mode (setq-default c-default-style "linux") ;; Default C style ;; -------------------------------------------------------------------------- ;; Convenience functions. ;; -------------------------------------------------------------------------- - (defun toggle-indent-tabs-mode () - "Toggle a indent-tabs-mode between a defined and undefined state." - (interactive) - (setq indent-tabs-mode (not indent-tabs-mode)) - (setq-default indent-tabs-mode indent-tabs-mode)) - (defun quit-other-window () "Quit the next window in cyclic order" (interactive) @@ -154,12 +144,30 @@ ;; Convenience keyboard shortcuts. ;; -------------------------------------------------------------------------- - (global-set-key (kbd "C-x k") 'kill-default-buffer) ;; Kill current buffer - (global-set-key (kbd "C-x C-q") 'quit-other-window) ;; Kill other window - (global-set-key (kbd "C-c w") 'whitespace-mode) ;; Toggle whitespace mode - (global-set-key (kbd "C-x k") 'kill-default-buffer) ;; Kill current buffer - (global-set-key (kbd "M-o") 'other-window) ;; Change window - (global-set-key (kbd "M-s M-o") 'occur) ;; Occur + ;; Kill current buffer without prompting. + (global-set-key (kbd "C-x k") 'kill-default-buffer) + + ;; Kill other window (cyclic order). + (global-set-key (kbd "C-x C-q") 'quit-other-window) + + ;; Toggle whitespace mode. + (global-set-key (kbd "C-c w") 'whitespace-mode) + + ;; Change active window. More convenient than "C-x o". + (global-set-key (kbd "M-o") 'other-window) + + ;; Occur. More convenient than "M-s o" + (global-set-key (kbd "M-s M-o") 'occur) + + ;; -------------------------------------------------------------------------- + ;; Aliases. + ;; -------------------------------------------------------------------------- + + ;; y or n is enough. + (defalias 'yes-or-no-p 'y-or-n-p) + + ;; Always use ibuffer. + (defalias 'list-buffers 'ibuffer) ;; -------------------------------------------------------------------------- ;; Configure garbage collection. @@ -184,3 +192,4 @@ (setq-default max-lisp-eval-depth 24000) ;; 30x orignal value ) ;; Reset garbage collection settings. +(put 'erase-buffer 'disabled nil) diff --git a/modules/editing.el b/modules/editing.el index 30e03d8..749d3a5 100644 --- a/modules/editing.el +++ b/modules/editing.el @@ -16,12 +16,20 @@ ;;; Required packages: (setq init-packages/editing-packages + '(rainbow-delimiters - highlight-parentheses)) + highlight-parentheses + whole-line-or-region) + + ) ;; Configuration: (defun init-packages/init-editing () + + ;; -------------------------------------------------------------------------- + ;; Parentheses highlighting. + ;; -------------------------------------------------------------------------- (use-package rainbow-delimiters) (add-hook 'prog-mode-hook 'rainbow-delimiters-mode) @@ -31,4 +39,142 @@ (setq hl-paren-colors '("#86DC2F" "IndianRed1" "IndianRed3" - "IndianRed4"))) + "IndianRed4")) + + ;; -------------------------------------------------------------------------- + ;; Use UTF-8. + ;; -------------------------------------------------------------------------- + (set-terminal-coding-system 'utf-8) + (set-keyboard-coding-system 'utf-8) + (set-language-environment "UTF-8") + (prefer-coding-system 'utf-8) + + ;; -------------------------------------------------------------------------- + ;; Convenient editing settings. + ;; -------------------------------------------------------------------------- + + ;; Kill whole line when point at beginning of line. + (setq kill-whole-line t) + + ;; Replace selected rather than inserting text at point. + (delete-selection-mode) + + ;; Kill line when calling kill-region without a selected region. + (whole-line-or-region-global-mode t) + + ;; -------------------------------------------------------------------------- + ;; Formatting + ;; -------------------------------------------------------------------------- + + (setq-default tab-width 8) ;; Tab width + (setq-default indent-tabs-mode nil) ;; No tabs + (setq-default fill-column 79) ;; Line width + (setq-default whitespace-line-column fill-column) ;; For whitespace mode + + ;; -------------------------------------------------------------------------- + ;; Commands. + ;; -------------------------------------------------------------------------- + + (defun toggle-indent-tabs-mode () + "Toggle a indent-tabs-mode between a defined and undefined state." + (interactive) + (setq indent-tabs-mode (not indent-tabs-mode)) + (setq-default indent-tabs-mode indent-tabs-mode)) + + (defun x-move-beginning-of-line (arg) + "Move point back to indentation of beginning of line. + + Move point to the first non-whitespace character on this + line. If point is already there, move to the beginning of + the line. Effectively toggle between the first + non-whitespace character and the beginning of the line. + + If ARG is not nil or 1, move forward ARG - 1 lines first. If + point reaches the beginning or end of the buffer, stop + there." + + (interactive "^p") + (setq arg (or arg 1)) + + ;; Move lines first + (when (/= arg 1) + (let ((line-move-visual nil)) + (forward-line (1- arg)))) + + (let ((orig-point (point))) + (back-to-indentation) + (when (= orig-point (point)) + (move-beginning-of-line 1)))) + + (defun indent-buffer () + "Indent the currently visited buffer." + (interactive) + (indent-region (point-min) (point-max))) + + (defcustom indent-sensitive-modes + '(coffee-mode python-mode slim-mode haml-mode yaml-mode) + "Modes for which auto-indenting is suppressed." + :type 'list) + + (defun indent-region-or-buffer () + "Indent a region if selected, otherwise the whole buffer." + (interactive) + (unless (member major-mode indent-sensitive-modes) + (save-excursion + (if (region-active-p) + (indent-region (region-beginning) (region-end)) + (indent-buffer) + (whitespace-cleanup))))) + + ;; Key-bindings ------------------------------------------------------------- + + ;; Override the beginning of line key-binding. + (global-set-key (kbd "C-a") 'x-move-beginning-of-line) + + ;; Override the indent-region key-binding + (global-set-key (kbd "C-M-\\") 'indent-region-or-buffer) + + ;; -------------------------------------------------------------------------- + ;; Automatically indent yanked text in programming mode. + ;; -------------------------------------------------------------------------- + + (defvar yank-indent-modes + '(LaTeX-mode TeX-mode) + "Modes in which to indent regions that are yanked (or yank-popped). + Only modes that don't derive from `prog-mode' should be + listed here.") + + (defvar yank-indent-blacklisted-modes + '(python-mode slim-mode haml-mode) + "Modes for which auto-indenting is suppressed.") + + (defvar yank-advised-indent-threshold 1000 + "Threshold (# chars) over which indentation does not + automatically occur.") + + (defun yank-advised-indent-function (beg end) + "Do indentation, as long as the region isn't too large." + (if (<= (- end beg) yank-advised-indent-threshold) + (indent-region beg end nil))) + + (defadvice yank (after yank-indent activate) + "If current mode is one of 'yank-indent-modes, + indent yanked text (with prefix arg don't indent)." + (if (and (not (ad-get-arg 0)) + (not (member major-mode yank-indent-blacklisted-modes)) + (or (derived-mode-p 'prog-mode) + (member major-mode yank-indent-modes))) + (let ((transient-mark-mode nil)) + (yank-advised-indent-function (region-beginning) (region-end))))) + + (defadvice yank-pop (after yank-pop-indent activate) + "If current mode is one of `yank-indent-modes', + indent yanked text (with prefix arg don't indent)." + (when (and (not (ad-get-arg 0)) + (not (member major-mode yank-indent-blacklisted-modes)) + (or (derived-mode-p 'prog-mode) + (member major-mode yank-indent-modes))) + (let ((transient-mark-mode nil)) + (yank-advised-indent-function (region-beginning) (region-end))))) + + ) diff --git a/modules/emacs.el b/modules/emacs.el index 439eda7..07f3224 100644 --- a/modules/emacs.el +++ b/modules/emacs.el @@ -16,8 +16,17 @@ ;;; Required packages: (setq init-packages/emacs-packages - '(use-package)) + + '(use-package) + + ) ;;; Configuration: -(defun init-packages/init-emacs ()) +(defun init-packages/init-emacs () + + ;; -------------------------------------------------------------------------- + ;; Empty config. + ;; -------------------------------------------------------------------------- + + ) diff --git a/modules/version-control.el b/modules/version-control.el index 986502c..26364ea 100644 --- a/modules/version-control.el +++ b/modules/version-control.el @@ -17,9 +17,71 @@ ;;; Required packages: (setq init-packages/version-control-packages - '(magit)) + + '(magit) + + ) ;;; Configuration: (defun init-packages/init-version-control () - (use-package magit)) + + ;; -------------------------------------------------------------------------- + ;; Load and configure `magit'. + ;; -------------------------------------------------------------------------- + (use-package magit) + + ;; -------------------------------------------------------------------------- + ;; Diff mode settings. + ;; -------------------------------------------------------------------------- + + ;; Diff mode hook - whitespace mode settings and set read-only mode. + (add-hook 'diff-mode-hook (lambda () + (setq-local whitespace-style + '(face + tabs + tab-mark + spaces + space-mark + trailing + indentation::space + indentation::tab + newline + newline-mark)) + (read-only-mode 1))) + + ;; Extra functions ---------------------------------------------------------- + + ;; Display source in other window whilst keeping point in the diff file. + ;; Based on the code for `diff-goto-source. + (defun x-diff-display-source (&optional other-file event) + "Display the corresponding source line in another window. + `diff-jump-to-old-file' (or its opposite if the OTHER-FILE + prefix arg is given) determines whether to jump to the old or + the new file. If the prefix arg is bigger than 8 (for example + with \\[universal-argument] \\[universal-argument]) then + `diff-jump-to-old-file' is also set, for the next invocations." + (interactive (list current-prefix-arg last-input-event)) + ;; When pointing at a removal line, we probably want to jump to + ;; the old location, and else to the new (i.e. as if reverting). + ;; This is a convenient detail when using smerge-diff. + (if event (posn-set-point (event-end event))) + (let ((rev (not (save-excursion (beginning-of-line) (looking-at "[-<]"))))) + (pcase-let ((`(,buf ,line-offset ,pos ,src ,_dst ,switched) + (diff-find-source-location other-file rev))) + (let ((window (display-buffer buf t))) + (save-selected-window + (select-window window) + (goto-char (+ (car pos) (cdr src))) + (diff-hunk-status-msg line-offset (diff-xor rev switched) t)))))) + + ;; Key-bindings ------------------------------------------------------------- + + ;; This shadows new global key-binding for other-window. + (define-key diff-mode-map (kbd "M-o") nil) + + ;; This copies behaviour from other modes where C-o displays the relevant + ;; source in another window. + (define-key diff-mode-map (kbd "C-o") 'x-diff-display-source) + + ) diff --git a/modules/workflow.el b/modules/workflow.el new file mode 100644 index 0000000..b29ea0f --- /dev/null +++ b/modules/workflow.el @@ -0,0 +1,40 @@ +;;; workflow.el --- Module file for setting up workflows. +;; +;; Copyright (C) 2017 Wojciech Kozlowski +;; +;; Author: Wojciech Kozlowski +;; Created: 25 Aug 2017 +;; +;; This file is not part of GNU Emacs. +;; +;;; Commentary: +;; +;; This module sets up configuration for a workflow and is expected to be +;; loaded last. +;; +;;; License: GPLv3 + +;;; Required packages: + +(setq init-packages/workflow-packages + + '(workgroups2) + + ) + +;;; Configuration: + +(defun init-packages/init-workflow () + + ;; -------------------------------------------------------------------------- + ;; Enable `workgroups'. + ;; -------------------------------------------------------------------------- + + (use-package workgroups2) + (workgroups-mode 1) + + ;; Don't save. Workgroups are transient to the session. + (setq wg-emacs-exit-save-behavior nil) + (setq wg-workgroups-mode-exit-save-behavior nil) + + )