#+TITLE: Reading and Writing Configuration #+PROPERTY: header-args :tangle ~/.emacs.d/config.el * Text and Case ** Convert DOuble capitals to single capitals #+begin_src elisp :tangle no (defun my/dcaps-to-scaps () "Convert word in DOuble CApitals to Single Capitals." (interactive) (and (= ?w (char-syntax (char-before))) (save-excursion (and (if (called-interactively-p) (skip-syntax-backward "w") (= -3 (skip-syntax-backward "w")) ) (let (case-fold-search) (looking-at "\\b[[:upper:]]\\{2\\}[[:lower:]]") ) (capitalize-word 1) ) ) ) ) #+end_src Then, let’s define a minor mode for it to be activated. #+begin_src elisp :tangle no (define-minor-mode my-dubcaps-mode "Toggle 'my-dubcaps-mode' and convert words in DOuble CApitals to Single Capitals as you type." :init-value nil :lighter (" DC") (if my-dubcaps-mode (add-hook 'post-self-insert-hook #'my/dcaps-to-scaps nil 'local) (remove-hook 'post-self-insert-hook #'my/dcaps-to-scaps 'local))) #+end_src Finally, let’s add a hook so that it is on for all the text files Emacs opens. #+begin_src elisp :tangle no (add-hook 'text-mode-hook #'my-dubcaps-mode) #+end_src Also, since we add a minor mode string (it might be useful sometimes), currently I prefer to diminish it. #+begin_src elisp :tangle no (defun my/diminish-dubcaps () (interactive) (diminish 'my-dubcaps-mode "")) (add-hook 'my-dubcaps-mode-hook 'my/diminish-dubcaps) #+end_src * Reading and Writing ** Move correctly over camelCased words #+begin_src elisp (subword-mode) #+end_src ** Understand the more common sentence with double space #+begin_src elisp (setq sentence-end-double-space nil) #+end_src ** Join lines into paragraph #+begin_src elisp (defun my/fill-or-unfill-paragraph (&optional unfill region) "Fill paragraph (or REGION). With the prefix argument UNFILL, fill it instead." (interactive (progn (barf-if-buffer-read-only) (list (if current-prefix-arg 'fill) t))) (let ((fill-column (if unfill fill-column (point-max)))) (fill-paragraph nil region))) (bind-key "M-q" 'my/fill-or-unfill-paragraph) #+end_src #+begin_src elisp (defun my/fill-or-unfill-all-paragraphs (&optional unfill) "Fill or unfill all paragraphs in the current buffer. With the prefix argument UNFILL, fill them instead." (interactive (list (if current-prefix-arg 'fill))) (let ((fill-column (if unfill fill-column (point-max)))) (save-excursion (goto-char (point-min)) (while (not (eobp)) (fill-paragraph nil t) (forward-paragraph))))) (bind-key "M-Q" 'my/fill-or-unfill-all-paragraphs) #+end_src #+begin_src elisp (remove-hook 'text-mode-hook #'turn-on-auto-fill) (add-hook 'text-mode-hook 'turn-on-visual-line-mode) #+end_src ** Expand some words with auto-correct #+begin_src elisp :tangle no (setq save-abbrevs 'silently) (setq-default abbrev-mode t) #+end_src ** ediff #+begin_src elisp :tangle no (setq ediff-window-setup-function 'ediff-setup-windows-plain) (setq ediff-split-window-function 'split-window-horizontally) #+end_src ** tramp #+begin_src elisp :tangle no (setq tramp-default-method "ssh" tramp-backup-directory-alist backup-directory-alist tramp-ssh-controlmaster-options "ssh") #+end_src ** Clean up space #+begin_src elisp :tangle no (bind-key "M-SPC" 'cycle-spacing) #+end_src ** Transform links into org links #+begin_src elisp :tangle no (defun my/transform-html-links-to-org () "Transform all HTML links in the current buffer into 'org-mode' links." (interactive) (goto-char (point-min)) (while (re-search-forward "\\(.*?\\)" nil t) (replace-match (org-make-link-string (match-string 1) (match-string 2))))) #+end_src ** Count words per minute #+begin_src elisp :tangle no (require 'org-clock) (defun my/org-entry-wpm () (interactive) (save-restriction (save-excursion (org-narrow-to-subtree) (goto-char (point-min)) (let* ((words (count-words-region (point-min) (point-max))) (minutes (org-clock-sum-current-item)) (wpm (/ words minutes))) (message "WPM: %d (words: %d, minutes: %d)" wpm words minutes) (kill-new (number-to-string wpm)) ) ) ) ) #+end_src ** Enable dict mode #+begin_src elisp :tangle no (setq dictionary-server "automatic") #+end_src ** Pick out passive voice and weasel words #+begin_src elisp :tangle no (use-package writegood-mode :diminish writegood-mode :config (progn (add-hook 'text-mode-hook 'writegood-mode)) ) #+end_src ** Org-babel docker #+begin_src elisp :tangle no (use-package ob-docker-build :straight (ob-docker-build :type git :host github :repo "ifitzpat/ob-docker-build") :defer t :config (add-to-list 'org-babel-load-languages '(docker-build . t)) (org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages) ) #+end_src * Spelling and syntax ** Spell checking This requires installation of hunspell #+begin_src bash :tangle no sudo apt install hunspell #+end_src #+begin_src elisp (use-package flyspell :config (setq ispell-program-name "hunspell" ispell-default-dictionary "en_US" ) :diminish (flyspell-mode . "φ") :hook (text-mode . flyspell-mode) :bind ( ("M-" . flyspell-buffer) ("" . flyspell-word) ("C-;" . flyspell-auto-correct-previous-word) ) ) #+end_src ** Flyspell correct #+begin_src elisp :tangle no (use-package flyspell-correct :after flyspell :bind (:map flyspell-mode-map ("C-;" . flyspell-correct-wrapper)) ) #+end_src ** Flycheck Needs external checkers installed #+begin_src elisp (use-package flycheck :init (global-flycheck-mode) :diminish (flycheck-mode . "") :config (add-hook 'after-init-hook #'global-flycheck-mode) (setq flycheck-emacs-lisp-load-path 'inherit) (setq flycheck-emacs-lisp-load-path (concat user-emacs-directory "straight/build")) ) #+end_src ** Flycheck bash #+begin_src bash :tangle no sudo apt install devscripts #+end_src #+begin_src elisp :tangle no (use-package flycheck-checkbashisms :config (flycheck-checkbashisms-setup) ) #+end_src ** Yaml #+begin_src elisp :tangle no (use-package yaml-mode :config (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode)) (add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-mode)) ) #+end_src ** Docker #+begin_src elisp :tangle no (use-package docker-compose-mode) #+end_src