.emacs.d/init.d/text/misc.el

267 lines
11 KiB
EmacsLisp

;;; misc.el --- Miscellaneous file formats. -*- lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(require 'basics/package-management)
(require 'basics/buffers)
(require 'misc/completion)
(require 'text/common)
(use-package conf-mode
:straight (:type built-in)
:mode (("^/etc/conf\\.d/" . conf-mode) ; openrc config.
("^/etc/portage/package\\.use/" . conf-space-mode) ; Portage config.
("^/etc/portage/package\\.accept_keywords/" . conf-space-mode)
("^/etc/portage/package\\.mask/" . conf-space-mode)
("^/etc/portage/package\\.unmask/" . conf-space-mode)
("^/etc/portage/package\\.license" . conf-space-mode)
("package\\.mask$" . conf-space-mode) ; In ebuild repos.
("\\.pc\\(\\.in\\)?$" . conf-mode)
("conanfile\\.txt$" . conf-mode)))
(use-package crontab-mode
;; Shrink minutes to normal size.
:custom-face (outline-1 ((t (:inherit outline-1 :height 1.0))))
:mode (("/cron\\.d/" . crontab-mode)
("^'/etc/crontab$" . crontab-mode))
:hook (crontab-mode . turn-off-auto-fill)) ; No word-wrapping.
(use-package nginx-mode)
(use-package company-nginx
:after (nginx-mode company)
:hook (nginx-mode . company-nginx-keywords))
(use-package yaml-mode
:mode ("\\.yml$" . yaml-mode)
:hook (yaml-mode . my/truncate-lines))
(use-package mediawiki
:commands (mediawiki-mode))
(use-package csv-mode
:mode ("\\.[Cc][Ss][Vv]$" . csv-mode))
(use-package adoc-mode
:after (hl-todo)
:custom-face
;; Style headers.
(markup-title-0-face ((t (:inherit markup-gen-face :height 1.4
:weight bold))))
(markup-title-1-face ((t (:inherit markup-gen-face :height 1.3
:weight bold))))
(markup-title-2-face ((t (:inherit markup-gen-face :height 1.2
:weight bold))))
(markup-title-3-face ((t (:inherit markup-gen-face :height 1.1
:weight bold))))
(markup-title-4-face ((t (:inherit markup-gen-face :height 1.0
:weight bold
:underline t))))
(markup-title-5-face ((t (:inherit markup-gen-face :height 1.0
:weight bold))))
;; Enlarge meta-data to the same size as the other text.
(markup-meta-face ((t (:inherit font-lock-comment-face))))
(markup-secondary-text-face ((t (:inherit markup-gen-face :height 1.0))))
(markup-hide-delimiter-face ((t (:inherit markup-meta-face))))
(markup-meta-hide-face ((t (:inherit markup-meta-face))))
:config (set-face-background 'markup-verbatim-face ; Inline code.
(face-background 'hl-line))
:mode ("\\.adoc$" . adoc-mode)
:hook ((adoc-mode . auto-fill-mode) ; Wrap at fill-column.
(adoc-mode . (lambda () ; Automatically update date.
(setq-local time-stamp-pattern
"8/:[dD][aA][tT][eE]: +%Y-%02m-%02d\n")))
(adoc-mode . yas-minor-mode)
(adoc-mode . hl-todo-mode)))
(use-package markdown-mode
:after (hl-line)
:custom (markdown-command "cmark")
:custom-face
;; Style headers.
(markdown-header-face-1 ((t (:inherit markdown-header-face :height 1.4
:weight bold))))
(markdown-header-face-2 ((t (:inherit markdown-header-face :height 1.3
:weight bold))))
(markdown-header-face-3 ((t (:inherit markdown-header-face :height 1.2
:weight bold))))
(markdown-header-face-4 ((t (:inherit markdown-header-face :height 1.1
:weight bold))))
(markdown-header-face-5 ((t (:inherit markdown-header-face :height 1.0
:weight bold :underline t))))
(markdown-header-face-6 ((t (:inherit markdown-header-face :height 1.0
:weight bold))))
(markdown-header-face-7 ((t (:inherit markdown-header-face :height 1.0
:weight bold))))
:config (set-face-background 'markdown-code-face ; Won't work in :custom-face.
(face-background 'hl-line))
:mode (("README\\.md$" . gfm-mode)
("\\.md$" . gfm-mode)
("\\.markdown$" . gfm-mode))
:hook (markdown-mode . auto-fill-mode)) ; Wrap at fill-column.
;; Document editing, formatting, and organizing mode.
(use-package org
:straight (:type built-in)
:defer 4
:defines (org-default-notes-file)
:commands (org-mode org-agenda)
:custom ((org-default-notes-file "~/notes.org")
(org-startup-folded nil)
(org-latex-compiler "xelatex")
(org-agenda-files '("~/notes.org"
"~/Dokumente/Videoserien.org"
"~/.calendars/org/tastytea_calendar.org"))
(org-blank-before-new-entry
'((heading . nil) (plain-list-item . auto)))
(org-agenda-show-all-dates nil)
(org-agenda-span (* 30.5 6)))
:config (progn (set-face-attribute 'org-level-1 nil :height 1.4)
(set-face-attribute 'org-level-2 nil :height 1.2)
(org-babel-do-load-languages 'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(C .t)))
(add-to-list 'org-modules 'org-tempo) ; Templates (<s).
(put 'org-confirm-babel-evaluate
'safe-local-variable #'booleanp)
(require 'ox-md))
:hook (org-mode . (lambda () ; Automatically update date.
(setq-local
time-stamp-pattern
"8/#\\+[dD][aA][tT][eE]: <+%Y-%02m-%02d %H:%M>")))
:bind (("C-c o" . (lambda () (interactive) ; Open notes.
(find-file org-default-notes-file)))
("C-c a" . org-agenda)
(:map org-mode-map ; Remove some annoying keybindings.
("M-<left>" . nil)
("C-c M-<left>" . org-metaleft)
("M-<right>" . nil)
("C-c M-<right>" . org-metaright)
("M-<up>" . nil)
("C-c M-<up>" . org-metaup)
("M-<down>" . nil)
("C-c M-<down>" . org-metadown)
("M-S-<left>" . nil)
("C-c M-S-<left>" . org-shiftmetaleft)
("M-S-<right>" . nil)
("C-c M-S-<right>" . org-shiftmetaright)
("M-S-<up>" . nil)
("C-c M-S-<up>" . org-shiftmetaup)
("M-S-<down>" . nil)
("C-c M-S-<down>" . org-shiftmetadown)
("S-<left>" . nil)
("C-c S-<left>" . org-shiftleft)
("S-<right>" . nil)
("C-c S-<right>" . org-shiftright)
("S-<up>" . nil)
("C-c S-<up>" . org-shiftup)
("S-<down>" . nil)
("C-c S-<down>" . org-shiftdown)
("C-S-<left>" . nil)
("C-c C-S-<left>" . org-shiftcontrolleft)
("C-S-<right>" . nil)
("C-c C-S-<right>" . org-shiftcontrolright)
("C-S-<up>" . nil)
("C-c C-S-<up>" . org-shiftcontrolup)
("C-S-<down>" . nil)
("C-c C-S-<down>" . org-shiftcontroldown))))
(use-package org-bullets
:after org
:hook (org-mode . org-bullets-mode))
(use-package ox-asciidoc
:after org
:hook (org-mode . (lambda () (require 'ox-asciidoc))))
(use-package sendmail
:straight (:type built-in)
:mode ("/.claws-mail/tmp/tmpmsg\\." . mail-mode) ; claws-mail messages.
:hook (mail-mode . (lambda () (set-fill-column 72))))
;; Open more file extensions in nxml-mode.
(use-package nxml
:straight (:type built-in)
:init (progn
;; mark variables as safe.
(put 'nxml-child-indent 'safe-local-variable #'integerp)
(put 'nxml-outline-child-indent 'safe-local-variable #'integerp))
:mode ("\\.qrc" . nxml-mode))
;; Syntax highlighting for docker files.
(use-package dockerfile-mode
:mode ("Dockerfile$" . dockerfile-mode))
(use-package ebuild-mode
:straight nil ; Only install if not installed by OS.
:init (unless (fboundp 'ebuild-mode)
(straight-use-package
'(ebuild-mode
:host nil
:repo "https://anongit.gentoo.org/git/proj/ebuild-mode.git")))
:hook (ebuild-mode . (lambda () (set-fill-column 80))))
;; Syntax-highlighting mode for text/gemini.
(use-package gemini-mode
:hook (gemini-mode . turn-off-auto-fill))
;; udev rule files.
(use-package udev-mode)
;; i3 configuration files.
(use-package i3wm-config-mode)
(use-package json-mode)
;; Sync with CalDAV
(use-package org-caldav
:defer t
:custom ((org-caldav-url "https://buzuk.tastytea.de/caldav.php/tastytea")
(org-caldav-calendar-id "calendar")
(org-caldav-inbox "~/.calendars/org/tastytea_calendar.org")
(org-icalendar-timezone "Europe/Berlin")
(org-caldav-files nil))
;; <https://github.com/dengste/org-caldav/issues/231>
:config (defun org-caldav-url-dav-get-properties (url property)
"Retrieve PROPERTY from URL.
Output is the same as `url-dav-get-properties'. This switches to
OAuth2 if necessary."
(let ((request-data (concat "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" "<propfind xmlns='DAV:'>\n<prop>" "<" property "/></prop></propfind>\n"))
(extra '(("Depth" . "1") ("Content-type" . "text/xml"))))
(let ((resultbuf (org-caldav-url-retrieve-synchronously
url "PROPFIND" request-data extra)))
(with-current-buffer resultbuf
(goto-char (point-min))
(when (not (re-search-forward "^HTTP[^ ]* \\([0-9]+ .*\\)$"
(point-at-eol) t))
(switch-to-buffer buffer)
(error "No valid HTTP response from URL %s." url))
(let ((response (match-string 1)))
(when (not (string-match "2[0-9][0-9].*" response))
(switch-to-buffer resultbuf)
(error "Error while doing PROPFIND for '%s' at URL %s: %s" property url response))))
(org-caldav-namespace-bug-workaround resultbuf)
;; HACK: remove DAV:responses with empty properties
(with-current-buffer resultbuf
(save-excursion
(while (re-search-forward "<response>" nil t)
(let ((begin (point))
(end (progn (re-search-forward "<response>" nil t) (+ (point) 0))))
(when (and begin end)
(goto-char begin)
(if (and (re-search-forward "<prop/>" nil t) (< (point) end))
(progn
(goto-char end)
(delete-region begin end))
(goto-char end)))))))
(url-dav-process-response resultbuf url)))))
(provide 'text/misc)
;;; misc.el ends here