├── README.org ├── README_zh.org └── code-library.el /README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: README 2 | #+AUTHOR: lujun9972 3 | #+CATEGORY: code-library 4 | #+DATE: [2015-10-09 五 20:23] 5 | #+OPTIONS: ^:{} 6 | * Usage 7 | 1. set value of `code-library-directory' 8 | 9 | This variable specify the directory where Snippet files are stored. 10 | 11 | Default value is "~/CodeLibrary" 12 | 13 | 2. set value of `code-library-mode-file-alist' 14 | 15 | This variable mapping the correspondence between `major-mode' and the snippet file. 16 | 17 | The element is like '(MAJOR-MODE . ORG-FILENAME) 18 | 19 | 3. mark the snippet which you want to save and then ~M-x code-library-save-code~ 20 | 21 | If the value of `code-library-use-tags-command' is not null, It will automatically run `org-mode' tags prompt when saving a snippet. 22 | 23 | If the value of `code-library-sync-to-gist' is not null, the snippet will also be stored to gist. 24 | 25 | If the whitespace in code snippet should be preserved (such as Makefile snippet), the major-mode should be added into `code-library-keep-indentation' 26 | 27 | If you want to add specified header to every new org-file, you can specify the `code-library-org-file-header' variable. 28 | -------------------------------------------------------------------------------- /README_zh.org: -------------------------------------------------------------------------------- 1 | #+TITLE: README 2 | #+AUTHOR: lujun9972 3 | #+CATEGORY: code-library 4 | #+DATE: [2015-10-09 五 20:23] 5 | #+OPTIONS: ^:{} 6 | * code-library 7 | 这是一个简单的使用org-mode来收集代码片段的工具. 使用步骤为: 8 | 9 | + 设置`code-library-directory' 10 | 11 | 该变量的值为存储代码片段文件的目录. 默认为"~/CodeLibrary" 12 | 13 | + 设置`code-library-mode-file-alist' 14 | 15 | 该变量指定了哪种编程语言存放到哪个org文件中. 16 | 17 | 改变量的元素格式为'(major-mode . org-filename) 18 | 19 | + 使用时,在Emacs中选中要收集的代码块,然后运行M-x code-library-save-code. 然后输入代码说明并为代码设置tag即可 20 | -------------------------------------------------------------------------------- /code-library.el: -------------------------------------------------------------------------------- 1 | ;;; code-library.el --- use org-mode to collect code snippets 2 | 3 | ;; Copyright (C) 2004-2015 DarkSun . 4 | 5 | ;; Author: DarkSun 6 | ;; Created: 2015-11-23 7 | ;; Version: 0.1 8 | ;; Keywords: lisp, code 9 | ;; Package-Requires: ((gist "1.3.1")) 10 | 11 | ;; This file is NOT part of GNU Emacs. 12 | 13 | ;; This program is free software; you can redistribute it and/or modify 14 | ;; it under the terms of the GNU General Public License as published by 15 | ;; the Free Software Foundation, either version 3 of the License, or 16 | ;; (at your option) any later version. 17 | 18 | ;; This program is distributed in the hope that it will be useful, 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | ;; GNU General Public License for more details. 22 | 23 | ;; You should have received a copy of the GNU General Public License 24 | ;; along with this program. If not, see . 25 | 26 | ;;; Source code 27 | ;; 28 | ;; code-library's code can be found here: 29 | ;; http://github.com/lujun9972/code-library 30 | 31 | ;;; Commentary: 32 | 33 | ;; code-library is a tool that use org-mode to collect code snippets. 34 | 35 | ;;; Code: 36 | 37 | (require 'gist) 38 | 39 | (defgroup code-library nil 40 | "code library group" 41 | :prefix "code-library-") 42 | 43 | (defcustom code-library-mode-file-alist '((c++-mode . "cpp.org") 44 | (dos-mode . "bat.org") 45 | (emacs-lisp-mode . "elisp.org") 46 | (perl-mode . "perl.org") 47 | (python-mode . "python.org") 48 | (sh-mode . "bash.org") 49 | (js-jsx-mode . "javascript.org") 50 | (js-mode . "javascript.org") 51 | (js2-jsx-mode . "javascript.org") 52 | (js2-mode . "javascript.org")) 53 | 54 | "Mapping the correspondence between `major-mode' and the snippet file." 55 | :group 'code-library) 56 | 57 | (defcustom code-library-directory "~/CodeLibrary/" 58 | "Snippet files are stored in the directory." 59 | :group 'code-library) 60 | 61 | (defcustom code-library-use-tags-command t 62 | "Automatically run `org-mode' tags prompt when saving a snippet." 63 | :group 'code-library) 64 | 65 | (defcustom code-library-keep-indentation '(makefile-mode 66 | makefile-gmake-mode) 67 | "List of modes which will be keep tabs and indentation as is. 68 | 69 | Normally code-library removed tabs to normalise indentation 70 | because code can come from a range of sources where the 71 | formatting and buffer local tab width can be in use." 72 | :group 'code-library) 73 | 74 | (defcustom code-library-org-file-header "#+PROPERTY: eval no-export" 75 | "Header to be inserted in org-files. 76 | 77 | This is automatically done by code-library before inserting 78 | snippets into empty or new .org files." 79 | :group 'code-library) 80 | 81 | (defcustom code-library-keyword-format-function 'identity 82 | "This function will be used to format the org keyword. 83 | 84 | 'downcase will lower case org mode keywords 85 | 'upcase will upper case org mode keywords" 86 | :group 'code-library) 87 | 88 | (defcustom code-library-sync-to-gist nil 89 | "synchronize to gist or not." 90 | :group 'code-library) 91 | 92 | (defun code-library-trim-left-margin () 93 | "Remove common line whitespace prefix." 94 | (save-excursion 95 | (goto-char (point-min)) 96 | (let ((common-left-margin) ) 97 | (while (not (eobp)) 98 | (unless (save-excursion 99 | (looking-at "[[:space:]]*$")) 100 | (back-to-indentation) 101 | (setq common-left-margin 102 | (min (or common-left-margin (current-column)) (current-column)))) 103 | (forward-line)) 104 | (when (and common-left-margin (> common-left-margin 0)) 105 | (goto-char (point-min)) 106 | (while (not (eobp)) 107 | (delete-region (point) 108 | (+ (point) 109 | (min common-left-margin 110 | (save-excursion 111 | (back-to-indentation) 112 | (current-column))))) 113 | (forward-line)))))) 114 | 115 | (defsubst code-library-buffer-substring (beginning end &optional keep-indent) 116 | "Return the content between BEGINNING and END. 117 | 118 | Tabs are converted to spaces according to mode. 119 | 120 | The first line is whitespace padded if BEGINNING is positioned 121 | after the beginning of that line. 122 | 123 | Common left margin whitespaces are trimmed. 124 | 125 | If KEEP-INDENT is t, tabs and indentation will be kept." 126 | (let ((content (buffer-substring-no-properties beginning end)) 127 | (content-tab-width tab-width) 128 | (content-column-start (save-excursion 129 | (goto-char beginning) 130 | (current-column)))) 131 | (with-temp-buffer 132 | (let ((tab-width content-tab-width)) 133 | (unless keep-indent 134 | (insert (make-string content-column-start ?\s))) 135 | (insert content) 136 | (unless keep-indent 137 | (untabify (point-min) (point-max)) 138 | (code-library-trim-left-margin)) 139 | (buffer-substring-no-properties (point-min) (point-max)))))) 140 | 141 | 142 | (defun code-library-get-thing (&optional keep-indent) 143 | "Return what's supposed to be saved to the conde library as a string." 144 | (let* ((bod (bounds-of-thing-at-point 'defun)) 145 | (r (cond 146 | ((region-active-p) (cons (region-beginning) (region-end))) 147 | (bod bod) 148 | (t (cons (point-min) (point-max)))))) 149 | (code-library-buffer-substring (car r) (cdr r) keep-indent))) 150 | 151 | (defun code-library-create-snippet (head content &optional keep-indent) 152 | "Create and return a new org heading with source block. 153 | 154 | HEAD is the org mode heading" 155 | (let ((code-major-mode (replace-regexp-in-string "-mode$" "" (symbol-name major-mode))) 156 | (tangle-file (if (buffer-file-name) (file-name-nondirectory (buffer-file-name))))) 157 | (with-temp-buffer 158 | (insert content) 159 | (org-escape-code-in-region (point-min) (point-max)) 160 | (unless (bolp) 161 | (insert "\n")) 162 | (insert (format "#+%s\n" (funcall code-library-keyword-format-function "END_SRC"))) 163 | (goto-char (point-min)) 164 | (insert (format "* %s\n" head)) 165 | (insert (format "#+%s %s" (funcall code-library-keyword-format-function "BEGIN_SRC") code-major-mode)) 166 | (when tangle-file 167 | (insert (format " :%s %s" (funcall code-library-keyword-format-function "tangle") tangle-file))) 168 | (insert "\n") 169 | (buffer-string)))) 170 | 171 | (defun code-library--newline-if-non-blankline () 172 | "add newline if point at non-blankline" 173 | (when (and (char-before) 174 | (not (char-equal ?\n (char-before)))) 175 | (newline))) 176 | 177 | (defun code-library-save-code-to-file (library-file head content &optional keep-indent) 178 | "Save the snippet to it's file location." 179 | (let ((snippet (code-library-create-snippet head content keep-indent)) 180 | (new-or-blank (or (not (file-exists-p library-file)) 181 | (= 0 (nth 7 (file-attributes library-file)))))) 182 | (with-current-buffer 183 | (find-file-noselect library-file) ;we can't just use (= 0 (buffer-size)), because find-file-hook or find-file-not-found-functions might change the buffer. 184 | (when new-or-blank 185 | (goto-char (point-max)) 186 | (code-library--newline-if-non-blankline) 187 | (insert code-library-org-file-header) 188 | (code-library--newline-if-non-blankline)) 189 | (when (and keep-indent 190 | (not (buffer-local-value 'org-src-preserve-indentation (current-buffer)))) 191 | (add-file-local-variable-prop-line 'org-src-preserve-indentation t)) 192 | (save-excursion 193 | (goto-char (point-max)) 194 | (beginning-of-line) 195 | (unless (looking-at "[[:space:]]*$") 196 | (newline)) 197 | (insert snippet) 198 | (when code-library-use-tags-command 199 | (org-set-tags-command))) 200 | (save-buffer)))) 201 | 202 | (defun code-library-save-code-to-gist (head content &optional keep-indent) 203 | "Save the snippet to it's file location." 204 | (let* ((file (or (buffer-file-name) (buffer-name))) 205 | (name (file-name-nondirectory file)) 206 | (ext (or (cdr (assoc major-mode gist-supported-modes-alist)) 207 | (file-name-extension file) 208 | "txt")) 209 | (fname (concat (file-name-sans-extension name) "." ext)) 210 | (files (list 211 | (make-instance 'gh-gist-gist-file 212 | :filename fname 213 | :content content)))) 214 | (gist-internal-new files nil head nil))) 215 | 216 | ;;;###autoload 217 | (defun code-library-save-code() 218 | "Save the snippet to it's file location." 219 | (interactive) 220 | (let* ((keep-indent (member major-mode code-library-keep-indentation)) 221 | (head (read-string "Please enter this code description: " nil nil "Untitled")) 222 | (content (code-library-get-thing keep-indent)) 223 | (code-major-mode (replace-regexp-in-string "-mode$" "" (symbol-name major-mode))) 224 | (library-base-file (or (cdr (assoc major-mode code-library-mode-file-alist)) 225 | (concat code-major-mode ".org"))) 226 | (library-file (expand-file-name library-base-file 227 | (file-name-as-directory code-library-directory)))) 228 | (code-library-save-code-to-file library-file head content keep-indent) 229 | (when code-library-sync-to-gist 230 | (code-library-save-code-to-gist head content keep-indent)))) 231 | 232 | (provide 'code-library) 233 | 234 | ;;; code-library.el ends here 235 | --------------------------------------------------------------------------------