diff --git a/modules/app/present/autoload.el b/modules/app/present/autoload.el index b14744238..992c434eb 100644 --- a/modules/app/present/autoload.el +++ b/modules/app/present/autoload.el @@ -1,25 +1,90 @@ ;;; app/present/autoload.el +;; --- impatient-mode ------------------------------------------------------------- + ;;;###autoload -(defun +present/buffer () +(defun +present/impatient-mode () (interactive) (require 'simple-httpd) (unless (process-status "httpd") (httpd-start)) - (unless impatient-mode - (impatient-mode +1))) + (impatient-mode) + (if impatient-mode + (add-hook 'kill-buffer-hook '+present--cleanup-impatient-mode) + (+present--cleanup-impatient-mode))) + +(defun +present--cleanup-impatient-mode () + (unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'impatient-mode buf)) + (doom-buffer-list)) + (httpd-stop) + (remove-hook 'kill-buffer-hook '+present--cleanup-impatient-mode))) + + +;; --- org tree slides ------------------------------------------------------------ + +(defvar +present--overlays-list nil) + +;;;###autoload +(defun +present/org-tree-slides () + (interactive) + (unless (derived-mode-p 'org-mode) + (error "Not in an org buffer")) + (call-interactively 'org-tree-slide-mode) + (add-hook 'kill-buffer-hook '+present--cleanup-org-tree-slides-mode)) + +;;;###autoload +(defun +present|add-overlays () + (add-to-invisibility-spec '(+present)) + (save-excursion + ;; hide org-mode options starting with #+ + (goto-char (point-min)) + (while (re-search-forward "^[[:space:]]*\\(#\\+\\)\\(\\(?:BEGIN\\|END\\|ATTR\\)[^[:space:]]+\\).*" nil t) + (+present--make-invisible + (match-beginning 1) + (match-end 0))) + ;; hide stars in headings + (goto-char (point-min)) + (while (re-search-forward "^\\(\\*+\\s-\\)" nil t) + (+present--make-invisible (match-beginning 1) (match-end 1))))) + +;;;###autoload +(defun +present|remove-overlays () + (mapc 'delete-overlay +present--overlays-list) + (remove-from-invisibility-spec '(+present))) + +(defun +present--cleanup-org-tree-slides-mode () + (unless (cl-remove-if-not (lambda (buf) (buffer-local-value 'org-tree-slide-mode buf)) + (doom-buffers-in-mode 'org-mode)) + (org-tree-slide-mode -1) + (remove-hook 'kill-buffer-hook '+present--cleanup-org-tree-slides-mode))) + +(defun +present--make-invisible (beg end) + (let ((overlay (make-overlay beg end))) + (push overlay +present--overlays-list) + (overlay-put overlay 'invisible '+present))) + +(defun +present--detect-slide () + (outline-show-all) + (if (member "title" (org-get-tags-at)) + (text-scale-set 10) + (text-scale-set +present-scale))) + + +;; --- misc ----------------------------------------------------------------------- + +(defvar +present--original-font +doom-font) ;;;###autoload (define-minor-mode +present/big-mode :init-value nil :lighter " BIG" :global t - (if +present-big-mode + (if +present/big-mode (set-frame-font +present-big-font t t) - (set-frame-font +present-original-font t t))) + (set-frame-font +present--original-font t t))) ;;;###autoload -(defun +present/stream () +(defun +present/resize-frame-for-stream () "Resize the frame pixelwise, so that it fits directly into my livecoding.tv streaming layout." (interactive) diff --git a/modules/app/present/config.el b/modules/app/present/config.el index 17b482b0c..dc74b1160 100644 --- a/modules/app/present/config.el +++ b/modules/app/present/config.el @@ -1,17 +1,25 @@ ;;; app/present/config.el -;; Sometimes you just get that powerful urge to show off. I don't have a fancy -;; car, so Emacs will have to do. +;; Sometimes you just get that urge to show off. I don't have a fancy car, so +;; my code or Emacs will have to do. +;; +;; Sometimes I stream my work on liveedu.tv, or record it on youtube, or peer +;; program over skype/teamviewer, or present at talks -- for all of this, Emacs +;; is my solution. ;; ;; + `impatient-mode' lets me show off code, as I write it, in real-time over ;; HTTP (see `+present/buffer') ;; + `ox-reveal' adds a reveal.js exporter to org-mode +;; + `org-tree-slide' for presenting org buffers as slides, plus some hacks to +;; unclutter them. ;; + and `+present/big-mode' lets me toggle big fonts for streams or ;; screen-sharing -;; Fonts for `+present/big-mode' -(defvar +present-original-font +doom-font) -(defvar +present-big-font (font-spec :family "Fira Mono" :size 16)) +(defvar +present-big-font (font-spec :family "Fira Mono" :size 18) + "Font to use when `+present/big-mode' is enabled.") + +(defvar +present-scale 7 + "The `text-scale-amount' for `org-tree-slide-mode'.") ;; @@ -21,12 +29,80 @@ (def-package! impatient-mode :commands impatient-mode) -;; reveal.js -(when (featurep! :lang org) + +(def-package! centered-window-mode + :commands centered-window-mode + :config + (setq cwm-use-vertical-padding t + cwm-frame-internal-border 110 + cwm-left-fringe-ratio -10 + cwm-centered-window-width 240)) + + +(when (featurep! :lang org) ;; reveal.js (if (bound-and-true-p org-modules-loaded) (require 'ox-reveal) (add-hook! 'org-load (require 'ox-reveal))) (setq org-reveal-root "http://cdn.jsdelivr.net/reveal.js/3.0.0/" - org-reveal-mathjax t)) + org-reveal-mathjax t) + + (def-package! org-tree-slide + :commands org-tree-slide-mode + :init + (after! org + (map! :map org-mode-map + "" '+present/org-tree-slides + "" '+present/next)) + :config + (setq org-tree-slide-skip-outline-level 2 + org-tree-slide-activate-message " " + org-tree-slide-deactivate-message " " + org-tree-slide-modeline-display nil) + (org-tree-slide-simple-profile) + + (map! :map org-tree-slide-mode-map + [right] 'org-tree-slide-move-next-tree + [left] 'org-tree-slide-move-previous-tree) + + (add-hook! 'org-tree-slide-mode-after-narrow-hook + '(+present|detect-slide +present|add-overlays org-display-inline-images)) + + (add-hook! 'org-tree-slide-mode-hook + (doom/window-zoom) + (let ((arg (if org-tree-slide-mode +1 -1))) + (when (featurep 'doom-themes) + (doom-buffer-mode (* arg -1))) + (centered-window-mode arg) + (window-divider-mode (* arg -1)) + (doom-hide-modeline-mode arg) + (cond (org-tree-slide-mode + (org-indent-mode -1) + (text-scale-set +present-scale) + (ignore-errors (org-preview-latex-fragment '(4))) + (set-face-attribute 'org-level-2 nil :height 1.4)) + (t + (org-indent-mode +1) + (text-scale-set 0) + (org-remove-latex-fragment-image-overlays) + (set-face-attribute 'org-level-2 nil :height 1.0) + (+present|remove-overlays) + (org-remove-inline-images))))) + + (defun +present*org-tree-slide-narrow-exclude-header (orig-fn &rest args) + (cl-letf (((symbol-function 'org-narrow-to-subtree) + (lambda () (save-excursion + (save-match-data + (org-with-limited-levels + (narrow-to-region + (progn (org-back-to-heading t) + (forward-line 1) + (point)) + (progn (org-end-of-subtree t t) + (when (and (org-at-heading-p) (not (eobp))) (backward-char 1)) + (point))))))))) + (apply orig-fn args))) + (advice-add 'org-tree-slide--display-tree-with-narrow + :around '+present*org-tree-slide-narrow-exclude-header))) + diff --git a/modules/app/present/packages.el b/modules/app/present/packages.el index e4102020b..c3fe6c3f2 100644 --- a/modules/app/present/packages.el +++ b/modules/app/present/packages.el @@ -1,6 +1,8 @@ ;; -*- no-byte-compile: t; -*- ;;; app/present/packages.el +(package! centered-window-mode) (package! htmlize) (package! impatient-mode) +(package! org-tree-slide) (package! ox-reveal) diff --git a/modules/private/hlissner/+bindings.el b/modules/private/hlissner/+bindings.el index 075abe5e3..b7f1c1aa8 100644 --- a/modules/private/hlissner/+bindings.el +++ b/modules/private/hlissner/+bindings.el @@ -126,7 +126,7 @@ :desc "Fullscreen" :n "f" 'doom/toggle-fullscreen :desc "Indent guides" :n "i" 'highlight-indentation-mode :desc "Indent guides (column)" :n "I" 'highlight-indentation-current-column-mode - :desc "Impatient-mode" :n "h" '+present/buffer + :desc "Impatient mode" :n "h" '+present/impatient-mode :desc "Big mode" :n "b" '+present/big-mode) (:desc "Tmux/Terminal"