|
38 | 38 | :prefix "code-library-")
|
39 | 39 |
|
40 | 40 | (defcustom code-library-mode-file-alist '((c++-mode . "cpp.org")
|
41 |
| - (emacs-lisp-mode . "elisp.org") |
42 |
| - (python-mode . "python.org") |
43 |
| - (perl-mode . "perl.org") |
44 |
| - (dos-mode . "bat.org") |
45 |
| - (sh-mode . "bash.org")) |
46 |
| - "Mapping the correspondence between major-mode and the snippet file" |
| 41 | + (dos-mode . "bat.org") |
| 42 | + (emacs-lisp-mode . "elisp.org") |
| 43 | + (perl-mode . "perl.org") |
| 44 | + (python-mode . "python.org") |
| 45 | + (sh-mode . "bash.org") |
| 46 | + (js-jsx-mode . "javascript.org") |
| 47 | + (js-mode . "javascript.org") |
| 48 | + (js2-jsx-mode . "javascript.org") |
| 49 | + (js2-mode . "javascript.org")) |
| 50 | + |
| 51 | + "Mapping the correspondence between `major-mode' and the snippet file." |
47 | 52 | :group 'code-library)
|
48 | 53 |
|
49 | 54 | (defcustom code-library-directory "~/CodeLibrary/"
|
50 |
| - "snippet files are stored in the directory" |
| 55 | + "Snippet files are stored in the directory." |
51 | 56 | :group 'code-library)
|
52 | 57 |
|
| 58 | +(defcustom code-library-use-tags-command t |
| 59 | + "Automatically run `org-mode' tags prompt when saving a snippet." |
| 60 | + :group 'code-library) |
| 61 | + |
| 62 | +(defun code-library-trim-left-margin () |
| 63 | + "Remove common line whitespace prefix." |
| 64 | + (save-excursion |
| 65 | + (goto-char (point-min)) |
| 66 | + (let ((common-left-margin) ) |
| 67 | + (while (not (eobp)) |
| 68 | + (unless (save-excursion |
| 69 | + (looking-at "[[:space:]]*$")) |
| 70 | + (back-to-indentation) |
| 71 | + (setq common-left-margin |
| 72 | + (min (or common-left-margin (current-column) ) (current-column)))) |
| 73 | + (forward-line)) |
| 74 | + (when (and common-left-margin (> common-left-margin 0)) |
| 75 | + (goto-char (point-min)) |
| 76 | + (while (not (eobp)) |
| 77 | + (delete-region (point) |
| 78 | + (+ (point) |
| 79 | + (min common-left-margin |
| 80 | + (save-excursion |
| 81 | + (back-to-indentation) |
| 82 | + (current-column))))) |
| 83 | + (forward-line)))))) |
| 84 | + |
| 85 | +(defsubst code-library-buffer-substring (beginning end) |
| 86 | + "Return the content between BEGINNING and END. |
| 87 | +
|
| 88 | +Tabs are converted to spaces according to mode. |
| 89 | +
|
| 90 | +The first line is whitespace padded if BEGINNING is positioned |
| 91 | +after the beginning of that line. |
| 92 | +
|
| 93 | +Common left margin whitespaces are trimmed." |
| 94 | + (let ((content (buffer-substring-no-properties beginning end)) |
| 95 | + (content-tab-width tab-width) |
| 96 | + (content-column-start (save-excursion |
| 97 | + (goto-char beginning) |
| 98 | + (current-column)))) |
| 99 | + (with-temp-buffer |
| 100 | + (let ((tab-width content-tab-width)) |
| 101 | + (insert (make-string content-column-start ?\s)) |
| 102 | + (insert content) |
| 103 | + (untabify (point-min) (point-max)) |
| 104 | + (code-library-trim-left-margin) |
| 105 | + (buffer-substring-no-properties (point-min) (point-max)))))) |
| 106 | + |
| 107 | + |
| 108 | +(defun code-library-get-thing () |
| 109 | + "Return what's supposed to be saved to the conde library as a string." |
| 110 | + (if (region-active-p) |
| 111 | + (code-library-buffer-substring (region-beginning) (region-end)) |
| 112 | + (let ((bod (bounds-of-thing-at-point 'defun)) ) |
| 113 | + (if bod |
| 114 | + (code-library-buffer-substring (car bod) (cdr bod)))))) |
| 115 | + |
| 116 | +(defun code-library-create-snippet (head) |
| 117 | + "Create and return a new org heading with source block. |
| 118 | +
|
| 119 | +HEAD is the org mode heading" |
| 120 | + (let ((content (code-library-get-thing)) |
| 121 | + (code-major-mode (replace-regexp-in-string "-mode$" "" (symbol-name major-mode))) |
| 122 | + (tangle-file (if (buffer-file-name) (file-name-nondirectory (buffer-file-name))))) |
| 123 | + (with-temp-buffer |
| 124 | + (insert content) |
| 125 | + (org-escape-code-in-region (point-min) (point-max)) |
| 126 | + (unless (bolp) |
| 127 | + (insert "\n")) |
| 128 | + (insert "#+END_SRC\n") |
| 129 | + (goto-char (point-min)) |
| 130 | + (insert (format "* %s\n" head)) |
| 131 | + (insert (format "#+BEGIN_SRC %s" code-major-mode)) |
| 132 | + (when tangle-file |
| 133 | + (insert (format " :tangle %s" tangle-file))) |
| 134 | + (insert "\n") |
| 135 | + (buffer-string)))) |
| 136 | + |
| 137 | + |
53 | 138 | (defun code-library-save-code()
|
54 |
| - "save the snippet." |
| 139 | + "Save the snippet to it's file location." |
55 | 140 | (interactive)
|
56 |
| - (let* ((code (if (region-active-p) |
57 |
| - (buffer-substring-no-properties (region-beginning) (region-end)) |
58 |
| - (thing-at-point 'defun))) |
| 141 | + (let* ((head (read-string "Please enter this code description: " nil nil "Untitled")) |
| 142 | + (snippet (code-library-create-snippet head)) |
59 | 143 | (code-major-mode (replace-regexp-in-string "-mode$" "" (symbol-name major-mode)))
|
60 |
| - (library-base-file (or (cdr (assoc major-mode code-library-mode-file-alist)) |
61 |
| - (concat code-major-mode ".org"))) |
62 |
| - (library-file (concat (file-name-as-directory code-library-directory) library-base-file)) |
63 |
| - (export-file (file-name-nondirectory (buffer-file-name))) |
64 |
| - (head (read-string "Please enter this code description: "))) |
65 |
| - (save-excursion |
66 |
| - (find-file library-file) |
67 |
| - (end-of-buffer) |
68 |
| - (newline) |
69 |
| - (insert (concat "* " head)) |
70 |
| - (newline-and-indent) |
71 |
| - (insert (format "#+BEGIN_SRC %s :tangle %s" code-major-mode export-file)) |
72 |
| - (newline-and-indent) |
73 |
| - (newline-and-indent) |
74 |
| - (insert "#+END_SRC") |
75 |
| - (forward-line -1) ;上一行 |
76 |
| - (org-edit-src-code) |
77 |
| - (insert code) |
78 |
| - (org-edit-src-exit) |
79 |
| - (org-set-tags-command) ;set tags |
80 |
| - (save-buffer)))) |
| 144 | + (library-base-file (or (cdr (assoc major-mode code-library-mode-file-alist)) |
| 145 | + (concat code-major-mode ".org"))) |
| 146 | + (library-file (expand-file-name library-base-file |
| 147 | + (file-name-as-directory code-library-directory)))) |
| 148 | + (with-current-buffer |
| 149 | + (find-file-noselect library-file) |
| 150 | + (save-excursion |
| 151 | + (goto-char (point-max)) |
| 152 | + (beginning-of-line) |
| 153 | + (unless (looking-at "[[:space:]]*$") |
| 154 | + (insert "\n")) |
| 155 | + (insert snippet) |
| 156 | + (when code-library-use-tags-command |
| 157 | + (org-set-tags-command))) |
| 158 | + (save-buffer)))) |
81 | 159 |
|
82 | 160 | (provide 'code-library)
|
83 | 161 |
|
|
0 commit comments