├── .gitignore ├── projectile-codesearch.el ├── README.md ├── listing-codesearch.el └── codesearch.el /.gitignore: -------------------------------------------------------------------------------- 1 | .csearchindex -------------------------------------------------------------------------------- /projectile-codesearch.el: -------------------------------------------------------------------------------- 1 | ;;; projectile-codesearch.el --- Integration of codesearch into projectile 2 | ;; 3 | ;; Author: Austin Bingham 4 | ;; Version: 2 5 | ;; URL: https://github.com/abingham/emacs-codesearch 6 | ;; Keywords: tools, development, search 7 | ;; Package-Requires: ((codesearch "20171122.431") (projectile "20150405.126")) 8 | ;; 9 | ;; This file is not part of GNU Emacs. 10 | ;; 11 | ;; Copyright (c) 2014-2017 Austin Bingham 12 | ;; 13 | ;;; Commentary: 14 | ;; 15 | ;; Description: 16 | ;; 17 | ;; This extension makes it convenient to use codesearch with 18 | ;; projectile projects. 19 | ;; 20 | ;; For more details, see the project page at 21 | ;; https://github.com/abingham/emacs-codesearch. 22 | ;; 23 | ;; For more details on projectile, see its project page at 24 | ;; http://github.com/bbatsov/projectile 25 | ;; 26 | ;; Installation: 27 | ;; 28 | ;; The simple way is to use package.el: 29 | ;; 30 | ;; M-x package-install projectile-codesearch 31 | ;; 32 | ;; Or, copy projectile-codesearch.el to some location in your emacs 33 | ;; load path. Then add "(require 'projectile-codesearch)" to your 34 | ;; emacs initialization (.emacs, init.el, or something). 35 | ;; 36 | ;; Example config: 37 | ;; 38 | ;; (require 'projectile-codesearch) 39 | ;; 40 | ;;; License: 41 | ;; 42 | ;; Permission is hereby granted, free of charge, to any person 43 | ;; obtaining a copy of this software and associated documentation 44 | ;; files (the "Software"), to deal in the Software without 45 | ;; restriction, including without limitation the rights to use, copy, 46 | ;; modify, merge, publish, distribute, sublicense, and/or sell copies 47 | ;; of the Software, and to permit persons to whom the Software is 48 | ;; furnished to do so, subject to the following conditions: 49 | ;; 50 | ;; The above copyright notice and this permission notice shall be 51 | ;; included in all copies or substantial portions of the Software. 52 | ;; 53 | ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 54 | ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 55 | ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 56 | ;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 57 | ;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 58 | ;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 59 | ;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 60 | ;; SOFTWARE. 61 | 62 | ;;; Code: 63 | 64 | (require 'listing-codesearch) 65 | 66 | (defun projectile-codesearch-search (pattern file-pattern) 67 | (interactive 68 | (list 69 | (read-string "Pattern: " (thing-at-point 'symbol)) 70 | (read-string "File pattern: " ".*"))) 71 | (unless (projectile-project-root) (error "Not in a projectile project.")) 72 | (let ((fpatt (concat (projectile-project-root) file-pattern))) 73 | (listing-codesearch-search pattern fpatt))) 74 | 75 | (provide 'projectile-codesearch) 76 | 77 | ;;; projectile-codesearch.el ends here 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

emacs-codesearch: Tools for using codesearch from Emacs

2 | 3 | These extensions allow you to use 4 | [codesearch](https://github.com/google/codesearch) from Emacs. 5 | 6 | This project comprises two main parts. First, `codesearch.el` contains 7 | low-level functionality for interacting with the codesearch tools `cindex` and 8 | `csearch`. These functions execute the tools, help manage your index files, and 9 | provide access to tool output, but they don't provide any sort of user 10 | interface. 11 | 12 | The second main part is a collection packages that provide user interfaces for 13 | the codesearch tools. Currently we have: 14 | 15 | * `listing-codesearch.el` provides a very simple, listing-oriented display of 16 | results 17 | 18 | 19 | **Table of Contents** 20 | 21 | - [Core functionality from `codesearch.el`](#core-functionality-from-codesearchel) 22 | - [Installation](#installation) 23 | - [Configuring your index files(s)](#configuring-your-index-filess) 24 | - [Further configuration](#further-configuration) 25 | - [Low-level codsearch commands](#low-level-codsearch-commands) 26 | - [List-oriented UI with `listing-codesearch.el`](#list-oriented-ui-with-listing-codesearchel) 27 | - [Installation](#installation) 28 | - [Configuration](#configuration) 29 | - [Commands](#commands) 30 | 31 | 32 | 33 | 34 | # Core functionality from `codesearch.el` 35 | 36 | `codesearch.el` is needed for any interaction with the codesearch tools. 37 | 38 | ## Installation 39 | 40 | It can be installed from [melpa](https://melpa.org): 41 | ``` 42 | M-x package-install codesearch 43 | ``` 44 | 45 | Then just `require` it somewhere in your Emacs configuration: 46 | ``` 47 | (require 'codesearch) 48 | ``` 49 | 50 | (Note that the various UI packages will also `require` codesearch, so this step 51 | may not be strictly necessary). 52 | 53 | ## Configuring your index files(s) 54 | 55 | The codesearch tools use an index file for storing information about the symbols 56 | found in your source code. `codesearch.el` provides two modes for specifying the 57 | locations of these index files. 58 | 59 | The first mode is *global index mode* wherein you specify a single, global index 60 | file that is used for all codesearch operations. To use global index mode, set 61 | the variable `codesearch-global-csearchindex` to the path for you index file. 62 | When set, the specified file will be used for every search and indexing 63 | operation that you perform. 64 | 65 | The second indexing mode is *project index mode* where you will use different 66 | index files for different directories. To use this mode, first make sure that 67 | `codesearch-global-csearchindex` is set to `nil`. Then, set the variable 68 | `codesearch-csearchindex` to the *filename* that you use for your indexes. Now 69 | when `codesearch.el` performs operations it will look for the file 70 | `codesearch-csearchindex` in the current directory and its ancestors until one 71 | is found. If none is found, an error is raised. 72 | 73 | **NB:** At the time of writing there is no way to *create* new project-specific 74 | indices using `codesearch.el`. You'll need to create those outside of Emacs 75 | until 76 | [the issue is addressed](https://github.com/abingham/emacs-codesearch/issues/4). 77 | 78 | ## Further configuration 79 | 80 | You can also configure other aspects of `codesearch.el`, though that's not 81 | generally necessary. See the configuration group `codesearch` for full details. 82 | 83 | ## Low-level codsearch commands 84 | 85 | The core codesearch package provides a number of commands that you need to use 86 | in order to manage your indices. 87 | 88 | * `codesearch-build-index` - This command adds a directory tree to the 89 | configured index. 90 | * `codeseearch-update-index` - This command updates the currently configured 91 | index by rescanning all of the directories that it already contains. 92 | * `codesearch-reset` - This removes the currently configured index completely. 93 | 94 | # List-oriented UI with `listing-codesearch.el` 95 | 96 | `listing-codesearch` provides a simple, list-oriented UI for displaying and 97 | interacting with codesearch results. 98 | 99 | ## Installation 100 | 101 | It can be installed from [melpa](https://melpa.org): 102 | ``` 103 | M-x package-install listing-codesearch 104 | ``` 105 | 106 | Then just `require` it somewhere in your Emacs configuration: 107 | ``` 108 | (require 'listing-codesearch) 109 | ``` 110 | 111 | ## Configuration 112 | 113 | `listing-codesearch` doesn't typically require any configuration, but check the 114 | `listing-codesearch` configuration group for full details. 115 | 116 | ## Commands 117 | 118 | `listing-codesearch` provides two functions for displaying information. 119 | 120 | * `listing-codesearch-search` - Perform a query on the currently configured 121 | index and lists the results in a buffer. Clicking on individual results in 122 | the output buffer will take you to those locations in the source code. 123 | 124 | * `listing-codesearch-list-directories` - List the directories currently index 125 | in the currently configured index. 126 | -------------------------------------------------------------------------------- /listing-codesearch.el: -------------------------------------------------------------------------------- 1 | ;;; listing-codesearch.el --- Simple, list-based UI for codesearch 2 | ;; 3 | ;; Author: Austin Bingham 4 | ;; Version: 1 5 | ;; URL: https://github.com/abingham/emacs-codesearch 6 | ;; Keywords: tools, development, search 7 | ;; 8 | ;; This file is not part of GNU Emacs. 9 | ;; 10 | ;; Copyright (c) 2016-2017 Austin Bingham 11 | ;; 12 | ;;; Commentary: 13 | ;; 14 | ;; Description: 15 | ;; 16 | ;; Provides a simple, list-oriented UI for results from codesearch. 17 | ;; 18 | ;; For more details, see the project page at 19 | ;; https://github.com/abingham/emacs-codesearch 20 | ;; 21 | ;; For more details on codesearch, see its project page at 22 | ;; https://github.com/google/codesearch 23 | ;; 24 | ;; Installation: 25 | ;; 26 | ;; The simple way is to use package.el: 27 | ;; 28 | ;; M-x package-install listing-codesearch 29 | ;; 30 | ;; Or, copy codesearch.el to some location in your emacs load 31 | ;; path. Then add "(require 'listing-codesearch)" to your emacs initialization 32 | ;; (.emacs, init.el, or something). 33 | ;; 34 | ;; Example config: 35 | ;; 36 | ;; (require 'listing-codesearch) 37 | ;; 38 | ;;; License: 39 | ;; 40 | ;; Permission is hereby granted, free of charge, to any person 41 | ;; obtaining a copy of this software and associated documentation 42 | ;; files (the "Software"), to deal in the Software without 43 | ;; restriction, including without limitation the rights to use, copy, 44 | ;; modify, merge, publish, distribute, sublicense, and/or sell copies 45 | ;; of the Software, and to permit persons to whom the Software is 46 | ;; furnished to do so, subject to the following conditions: 47 | ;; 48 | ;; The above copyright notice and this permission notice shall be 49 | ;; included in all copies or substantial portions of the Software. 50 | ;; 51 | ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 52 | ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 53 | ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 54 | ;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 55 | ;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 56 | ;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 57 | ;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 58 | ;; SOFTWARE. 59 | 60 | ;;; Code: 61 | 62 | (require 'codesearch) 63 | 64 | (defgroup listing-codesearch nil 65 | "Variables related to listing-codesearch." 66 | :prefix "listing-codesearch-" 67 | :group 'tools) 68 | 69 | (defface listing-codesearch-filename 70 | '((t :inherit font-lock-constant-face)) 71 | "Face used to highlight filenames in matches." 72 | :group 'listing-codesearch) 73 | 74 | (defface listing-codesearch-line-number 75 | '((t :inherit font-lock-keyword-face)) 76 | "Face used to highlight line numbers in matches." 77 | :group 'listing-codesearch) 78 | 79 | (defconst listing-codesearch--match-regex "^\\(.*\\):\\([0-9]+\\):" 80 | "The regular expression used to find matches in the codesearch output.") 81 | 82 | (define-button-type 'listing-codesearch--filename-match-button 83 | 'face 'listing-codesearch-filename 84 | 'follow-link 't 85 | 'button 't) 86 | 87 | (define-button-type 'listing-codesearch--line-number-match-button 88 | 'face 'listing-codesearch-line-number 89 | 'follow-link 't 90 | 'button 't) 91 | 92 | (defun listing-codesearch--make-filenames-clickable (buff) 93 | "Finds all codesearch matches in `buff', turning them into 94 | clickable buttons that link to the matched file/line-number. 95 | 96 | `buff' is assumed to contain the output from running csearch. 97 | " 98 | (with-current-buffer buff 99 | (beginning-of-buffer) 100 | (while (re-search-forward listing-codesearch--match-regex nil t) 101 | (lexical-let* ((filename (match-string 1)) 102 | (line-number (string-to-number (match-string 2))) 103 | (visit-match (lambda (b) 104 | (find-file-other-window filename) 105 | (goto-line line-number)))) 106 | (make-text-button 107 | (match-beginning 1) 108 | (match-end 1) 109 | 'type 'listing-codesearch--filename-match-button 110 | 'action visit-match) 111 | 112 | (make-text-button 113 | (match-beginning 2) 114 | (match-end 2) 115 | 'type 'listing-codesearch--line-number-match-button 116 | 'action visit-match))))) 117 | 118 | (defvar listing-codesearch-pattern-history nil) 119 | 120 | (defvar listing-codesearch-file-pattern-history nil) 121 | 122 | ;;;###autoload 123 | (defun listing-codesearch-search (pattern file-pattern) 124 | "Search files matching `file-pattern'in the index for `pattern'." 125 | (interactive 126 | (list 127 | (read-string "Pattern: " (thing-at-point 'symbol) 128 | 'listing-codesearch-pattern-history (car listing-codesearch-pattern-history)) 129 | (read-string "File pattern: " ".*" 130 | 'listing-codesearch-file-pattern-history (car listing-codesearch-file-pattern-history)))) 131 | (lexical-let ((file-pattern (if (memq system-type '(windows-nt ms-dos)) 132 | (replace-regexp-in-string "/" "\\\\\\\\" file-pattern) 133 | file-pattern)) 134 | (buff (get-buffer-create "*codesearch-results*")) 135 | (proc (codesearch-run-csearch 136 | default-directory 137 | (list "-f" file-pattern 138 | "-n" pattern)))) 139 | 140 | (with-current-buffer buff 141 | (read-only-mode 0) 142 | (erase-buffer)) 143 | 144 | (set-process-sentinel 145 | proc 146 | #'(lambda (process event) 147 | (when (string-equal event "finished\n") 148 | (listing-codesearch--make-filenames-clickable buff) 149 | (pop-to-buffer buff) 150 | (read-only-mode 1)))) 151 | 152 | (set-process-filter 153 | proc 154 | #'(lambda (process output) 155 | (let ((switch-to-visible-buffer t)) 156 | (with-current-buffer buff 157 | (insert output))))))) 158 | 159 | ;;;###autoload 160 | (defun listing-codesearch-list-directories () 161 | "List the directories currently being indexed." 162 | (interactive) 163 | (lexical-let ((buff (get-buffer-create "*codesearch-directories*")) 164 | (proc (codesearch-run-cindex 165 | nil nil 166 | "-list"))) 167 | (with-current-buffer buff 168 | (read-only-mode 0) 169 | (erase-buffer) 170 | (insert "[codesearch: currently indexed directories]\n\n") 171 | (pop-to-buffer buff)) 172 | 173 | (set-process-filter 174 | proc 175 | #'(lambda (process output) 176 | (with-current-buffer buff 177 | (insert output)))))) 178 | 179 | (provide 'listing-codesearch) 180 | 181 | ;;; listing-codesearch.el ends here 182 | -------------------------------------------------------------------------------- /codesearch.el: -------------------------------------------------------------------------------- 1 | ;;; codesearch.el --- Core support for managing codesearch tools 2 | ;; 3 | ;; Author: Austin Bingham 4 | ;; Youngjoo Lee 5 | ;; Version: 1 6 | ;; URL: https://github.com/abingham/emacs-codesearch 7 | ;; Keywords: tools, development, search 8 | ;; Package-Requires: ((log4e "0.3.1")) 9 | ;; 10 | ;; This file is not part of GNU Emacs. 11 | ;; 12 | ;; Copyright (c) 2016-2017 Austin Bingham, Youngjoo Lee 13 | ;; 14 | ;;; Commentary: 15 | ;; 16 | ;; Description: 17 | ;; 18 | ;; This extension provides basic support for executing the codesearch tools and 19 | ;; for managing codesearch indices. 20 | ;; 21 | ;; For more details, see the project page at 22 | ;; https://github.com/abingham/emacs-codesearch 23 | ;; 24 | ;; For more details on codesearch, see its project page at 25 | ;; https://github.com/google/codesearch 26 | ;; 27 | ;; Installation: 28 | ;; 29 | ;; The simple way is to use package.el: 30 | ;; 31 | ;; M-x package-install codesearch 32 | ;; 33 | ;; Or, copy codesearch.el to some location in your emacs load 34 | ;; path. Then add "(require 'codesearch)" to your emacs initialization 35 | ;; (.emacs, init.el, or something). 36 | ;; 37 | ;; Example config: 38 | ;; 39 | ;; (require 'codesearch) 40 | ;; 41 | ;; This elisp extension assumes you've got the codesearch tools - 42 | ;; csearch and cindex - installed. See the codesearch-csearch and 43 | ;; codesearch-cindex variables for more information. 44 | ;; 45 | ;;; License: 46 | ;; 47 | ;; Permission is hereby granted, free of charge, to any person 48 | ;; obtaining a copy of this software and associated documentation 49 | ;; files (the "Software"), to deal in the Software without 50 | ;; restriction, including without limitation the rights to use, copy, 51 | ;; modify, merge, publish, distribute, sublicense, and/or sell copies 52 | ;; of the Software, and to permit persons to whom the Software is 53 | ;; furnished to do so, subject to the following conditions: 54 | ;; 55 | ;; The above copyright notice and this permission notice shall be 56 | ;; included in all copies or substantial portions of the Software. 57 | ;; 58 | ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 59 | ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 60 | ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 61 | ;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 62 | ;; BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 63 | ;; ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 64 | ;; CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 65 | ;; SOFTWARE. 66 | 67 | ;;; Code: 68 | 69 | (eval-when-compile 70 | (require 'cl)) 71 | 72 | (require 'log4e) 73 | 74 | (log4e:deflogger "codesearch" "%t [%l] %m" "%H:%M:%S") 75 | 76 | (defgroup codesearch nil 77 | "Variables related to codesearch." 78 | :prefix "codesearch-" 79 | :group 'tools) 80 | 81 | (defcustom codesearch-csearch "csearch" 82 | "The csearch executable to use." 83 | :type '(string) 84 | :group 'codesearch) 85 | 86 | (defcustom codesearch-cindex "cindex" 87 | "The cindex executable to use." 88 | :type '(string) 89 | :group 'codesearch) 90 | 91 | (defcustom codesearch-global-csearchindex nil 92 | "The global index file. 93 | 94 | If defined, this will be used for all codesearch operations for 95 | which a more specific index is not available." 96 | :type '(string) 97 | :group 'codesearch) 98 | 99 | (defcustom codesearch-csearchindex ".csearchindex" 100 | "The directory-specific index file name. 101 | 102 | When determining the index file to use for a codesearch 103 | operation, we initially search up the directory tree for 104 | the value of this option. If a match is found, it is used." 105 | :type '(string) 106 | :group 'codesearch) 107 | 108 | (defcustom codesearch-output-buffer "*codesearch*" 109 | "Buffer where miscellaneous tool output gets written." 110 | :type '(string) 111 | :group 'codesearch) 112 | 113 | (defun codesearch--find-dominant-csearchindex (dir) 114 | "Search `dir' and its ancestors for `codesearch-csearchindex', 115 | returning the path if found." 116 | (when codesearch-csearchindex 117 | (let* ((start-dir (expand-file-name dir)) 118 | (index-dir (locate-dominating-file start-dir codesearch-csearchindex))) 119 | (if index-dir 120 | (concat index-dir codesearch-csearchindex))))) 121 | 122 | (defun codesearch--csearchindex (dir) 123 | "Get the full path to the index to use for searches that start 124 | in `dir'." 125 | (expand-file-name (or (codesearch--find-dominant-csearchindex dir) 126 | codesearch-global-csearchindex 127 | (error "Can't find csearchindex")))) 128 | 129 | (defun codesearch--handle-output (process output) 130 | "Append process output to standard buffer." 131 | (with-current-buffer (get-buffer-create codesearch-output-buffer) 132 | (goto-char (point-max)) 133 | (insert "\n") 134 | (insert output))) 135 | 136 | (defun codesearch--run-tool (dir command args &optional index-file) 137 | "Run `command' with CSEARCHINDEX variable set correctly. 138 | 139 | `dir' is the directory from which any index-file searches will 140 | start. Returns the process object." 141 | (let* ((search-dir (or dir default-directory)) 142 | (index-file (or index-file (codesearch--csearchindex search-dir))) 143 | (process-environment (copy-alist process-environment))) 144 | (codesearch--log-info 145 | "Running %s %s from %s with index-file %s" 146 | command args dir index-file) 147 | 148 | (setenv "CSEARCHINDEX" (expand-file-name index-file)) 149 | (apply 150 | 'start-process 151 | "codesearch" 152 | nil 153 | command 154 | args))) 155 | 156 | (defun codesearch-run-cindex (&optional dir index-file &rest args) 157 | "Run the cindex command passing `args' arguments." 158 | (codesearch--run-tool 159 | dir codesearch-cindex args index-file)) 160 | 161 | (defun codesearch-run-csearch (&optional dir args) 162 | "Run the csearch command passing `args' arguments." 163 | (codesearch--run-tool 164 | dir codesearch-csearch args)) 165 | 166 | ;;;###autoload 167 | (defun codesearch-build-index (dir index-file) 168 | "Add the contents of `dir' to `index-file'." 169 | (interactive 170 | (let* ((dir (read-directory-name "Directory: ")) 171 | (proj-index (codesearch--find-dominant-csearchindex dir)) 172 | (use-proj-index (if proj-index 173 | (y-or-n-p (format "Use existing project index (%s)?" proj-index)))) 174 | (use-global (if (and (not use-proj-index) 175 | codesearch-global-csearchindex) 176 | (y-or-n-p (format "Use global index (%s)?" codesearch-global-csearchindex)))) 177 | (index (cond (use-proj-index proj-index) 178 | (use-global codesearch-global-csearchindex) 179 | (t (concat (read-directory-name "Index directory:" dir) 180 | codesearch-csearchindex))))) 181 | (list dir index))) 182 | (lexical-let ((dir dir) 183 | (proc (codesearch-run-cindex nil index-file dir))) 184 | (set-process-sentinel 185 | proc 186 | (lambda (proc event) 187 | (codesearch--log-info "Build of %s complete" dir))) 188 | (set-process-filter proc 'codesearch--handle-output))) 189 | 190 | 191 | ;;;###autoload 192 | (defun codesearch-update-index () 193 | "Rescan all of the directories currently in the index, updating 194 | the index with the new contents." 195 | (interactive) 196 | (let ((proc (codesearch-run-cindex))) 197 | (set-process-sentinel 198 | proc 199 | (lambda (proc event) 200 | (codesearch--log-info "Update complete"))) 201 | (set-process-filter proc 'codesearch--handle-output))) 202 | 203 | ;;;###autoload 204 | (defun codesearch-reset () 205 | "Reset (delete) the codesearch index." 206 | (interactive) 207 | (set-process-filter 208 | (codesearch-run-cindex nil nil "-reset") 209 | 'codesearch--handle-output)) 210 | 211 | (provide 'codesearch) 212 | 213 | ;;; codesearch.el ends here 214 | --------------------------------------------------------------------------------