From 51fac44a4485f86ec4b1001302c22206daa7d0f8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Pit--Claudel?= Date: Sun, 19 Jun 2016 14:40:08 -0400 Subject: [PATCH] Initial import --- .gitignore | 1 + Cask | 6 +++ Makefile | 6 +++ README.rst | 23 ++++++++++ compact-docstrings.el | 91 +++++++++++++++++++++++++++++++++++++ etc/after.py | 14 ++++++ etc/before.py | 14 ++++++ etc/compact-docstrings.png | Bin 0 -> 25863 bytes etc/screenshot.el | 73 +++++++++++++++++++++++++++++ 9 files changed, 228 insertions(+) create mode 100644 .gitignore create mode 100644 Cask create mode 100644 Makefile create mode 100644 README.rst create mode 100644 compact-docstrings.el create mode 100644 etc/after.py create mode 100644 etc/before.py create mode 100644 etc/compact-docstrings.png create mode 100644 etc/screenshot.el diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..64b10531a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.cask/ diff --git a/Cask b/Cask new file mode 100644 index 000000000..9fd0c8c4f --- /dev/null +++ b/Cask @@ -0,0 +1,6 @@ +(source gnu) +(source melpa) + +(package-file "compact-docstrings.el") + +(development) diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..4677e7f8b --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +EMACS ?= emacs +CASK = env --unset INSIDE_EMACS EMACS=$(EMACS) cask + +screenshot: + $(CASK) exec $(EMACS) --debug-init -Q \ + -L . -l etc/screenshot.el diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..7a56b5a59 --- /dev/null +++ b/README.rst @@ -0,0 +1,23 @@ +============================= + Compact docstrings in Emacs +============================= + +Shrink blank lines in docstrings and doc comments + +.. image:: etc/compact-docstrings.png + +Setup +===== + +Enable locally with ``compact-docstrings-mode``:: + + (add-hook 'some-mode-hook #'compact-docstrings-mode) + +Enable globally (in all programming modes) with ``global-compact-docstrings-mode``:: + + (add-hook 'after-init-hook #'global-compact-docstrings-mode) + +Customization +============= + +Enable compaction of all comments and strings by setting ``compact-docstrings-only-doc-blocks`` to ``nil``. Change the compact line height by customizing ``compact-docstrings-face``. diff --git a/compact-docstrings.el b/compact-docstrings.el new file mode 100644 index 000000000..5780457ec --- /dev/null +++ b/compact-docstrings.el @@ -0,0 +1,91 @@ +;;; compact-docstrings.el --- Shrink blank lines in docstrings and doc comments + +;; Copyright (C) 2016 Clément Pit-Claudel + +;; Author: Clément Pit-Claudel +;; URL: https://github.com/cpitclaudel/compact-docstrings +;; Package-Version: 0.1 +;; Keywords: convenience, faces, lisp, maint, c + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Shrink blank lines in docstrings and doc comments +;; +;; Enable locally with `compact-docstrings-mode': +;; (add-hook 'some-mode-hook #'compact-docstrings-mode) +;; +;; Enable globally (in all programming modes) with +;; (add-hook 'after-init-hook #'global-compact-docstrings--mode) + +;;; Code: + +(defgroup compact-docstrings nil + "Shrink empty lines in docstrings and doc comments." + :group 'faces) + +(defface compact-docstrings-face + '((t :height 0.5)) + "Face applied to blank lines in docstrings." + :group 'compact-docstrings) + +(defcustom compact-docstrings-only-doc-blocks t + "When nil, also shrink blank lines in regular strings and comments." + :group 'compact-docstrings + :type 'boolean) + +(defun compact-docstrings--matcher (bound) + "Find blank line in docstring, looking in point .. BOUND." + (let ((found nil)) + (while (and (not found) (re-search-forward "^\\s-*\n" bound t)) + (let ((syntax (syntax-ppss))) + (when (and (or (nth 3 syntax) ;; In string + (nth 4 syntax)) ;; In comment + (or (not compact-docstrings-only-doc-blocks) + (let ((face (get-text-property (point) 'face))) + (or (eq face 'font-lock-doc-face) + (and (listp face) (memq 'font-lock-doc-face face)))))) + (setq found t)))) + found)) + +(defconst compact-docstrings--keywords + '((compact-docstrings--matcher 0 'compact-docstrings-face prepend)) 'append) + +;;;###autoload +(define-minor-mode compact-docstrings-mode + "Shrink empty lines in docstrings and doc comments." + :lighter " compact" + (if compact-docstrings-mode + (font-lock-add-keywords nil compact-docstrings--keywords 'append) + (font-lock-remove-keywords nil compact-docstrings--keywords)) + (if (fboundp #'font-lock-flush) + (font-lock-flush) + (with-no-warnings (font-lock-fontify-buffer)))) + +(defun compact-docstrings--mode-on () + "Turn on `compact-docstrings-mode', if appropriate." + (when (derived-mode-p major-mode #'prog-mode) + (compact-docstrings-mode))) + +;;;###autoload +(defalias 'shrink-docstrings #'compact-docstrings--mode-on) + +;;;###autoload +(define-globalized-minor-mode global-compact-docstrings-mode compact-docstrings-mode + compact-docstrings--mode-on + :init-value nil) + +(provide 'compact-docstrings) +;;; compact-docstrings.el ends here diff --git a/etc/after.py b/etc/after.py new file mode 100644 index 000000000..26a7ae2d6 --- /dev/null +++ b/etc/after.py @@ -0,0 +1,14 @@ +# With compact docstrings +def complex(real=0.0, imag=0.0): + """Form a complex number. + + Keyword arguments: + real -- the real part (default 0.0) + imag -- the imaginary part (default 0.0) + + Some more description text, artificially + lengthened to make it span two lines. + + Another paragraph. + """ + pass diff --git a/etc/before.py b/etc/before.py new file mode 100644 index 000000000..66bebaa5d --- /dev/null +++ b/etc/before.py @@ -0,0 +1,14 @@ +# With regular docstrings +def complex(real=0.0, imag=0.0): + """Form a complex number. + + Keyword arguments: + real -- the real part (default 0.0) + imag -- the imaginary part (default 0.0) + + Some more description text, artificially + lengthened to make it span two lines. + + Another paragraph. + """ + pass diff --git a/etc/compact-docstrings.png b/etc/compact-docstrings.png new file mode 100644 index 0000000000000000000000000000000000000000..fd86dd3d6e96777daa3443a8e9da234a2843acf1 GIT binary patch literal 25863 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%0A(d>#aNr`9T9@ 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 literal 0 HcmV?d00001 diff --git a/etc/screenshot.el b/etc/screenshot.el new file mode 100644 index 000000000..98a34043d --- /dev/null +++ b/etc/screenshot.el @@ -0,0 +1,73 @@ +(defvar my/fringe-width 6) + +(defconst my/script-dir + (file-name-directory (or load-file-name + buffer-file-name))) + +(defun my/cleanup () + (dolist (buffer (buffer-list)) + (kill-buffer buffer))) + +(defun my/prepare-UI () + "Prepare UI for taking a screenshot." + (ido-mode) + (tool-bar-mode -1) + (menu-bar-mode -1) + (scroll-bar-mode -1) + (column-number-mode) + (fringe-mode (cons my/fringe-width my/fringe-width)) + (blink-cursor-mode -1) + (setq-default cursor-type 'bar + split-width-threshold 80 + truncate-partial-width-windows t + frame-title-format (format "Compact docstrings @ Emacs %s" emacs-version) + x-gtk-use-system-tooltips nil) + (load-theme 'tango t) + ;; (set-face-attribute 'tooltip nil :height 60) + (set-face-attribute 'match nil :background "yellow1") + (set-face-attribute 'default nil :family "Ubuntu Mono" :height 110) + (set-face-attribute 'mode-line nil :foreground "gray60" :background "black") + (set-face-attribute 'mode-line-inactive nil :foreground "gray60" :background "#404045") + (set-face-attribute 'mode-line-buffer-id nil :foreground "#eab700") + (set-fontset-font t 'unicode "Ubuntu Mono") + (set-frame-size nil 100 13) + (redisplay t)) + +(defun my/load-package () + "Load package." + (package-initialize) + (load-library "compact-docstrings")) + +(defun my/load-example () + "Prepare files and layout windows." + (find-file "etc/before.py") + (setq buffer-name "Regular docstrings") + (find-file-other-window "after.py") + (setq buffer-name "Compact docstrings") + (compact-docstrings-mode)) + +(defun my/prepare-screenshot-1 () + "Prepare for taking a screenshot." + (my/prepare-UI) + (my/load-package) + (my/load-example) + (message nil)) + +(defun my/save-screenshot () + "Save screenshot of current frame." + (let ((fname (expand-file-name "compact-docstrings.png" my/script-dir))) + (process-lines "import" "-window" (frame-parameter nil 'outer-window-id) + fname) + (process-lines "mogrify" "-strip" "-matte" + "-bordercolor" (face-attribute 'fringe :background) + "-border" (format "0x%d" my/fringe-width) fname) + (process-lines "optipng" "-o3" fname)) + (kill-emacs)) + +(defun my/take-screenshot () + (my/prepare-screenshot-1) + (redisplay t) + (run-with-idle-timer 1 nil #'my/save-screenshot)) + +(print default-directory) +(run-with-idle-timer 0 nil #'my/take-screenshot) -- 2.39.2