├── .gitignore ├── CHANGES ├── ChangeLog ├── LICENSE ├── README ├── bundles ├── rails-apidock-bundle.el ├── rails-apidock-bundle │ ├── rails.js │ ├── rspec.js │ └── search.rb ├── rails-basic-bundle.el ├── rails-database-bundle.el ├── rails-generator-bundle.el ├── rails-rake-bundle.el ├── rails-rspec-bundle.el ├── rails-test-unit-bundle.el └── rails-webserver-bundle.el ├── core-ext.el ├── files-ext.el ├── inflections.el ├── list-ext.el ├── rails-anything.el ├── rails-autoload.el ├── rails-bundles.el ├── rails-compile.el ├── rails-lib.el ├── rails-project.el ├── rails-proxy.el ├── rails-reloaded.el ├── rails-resources.el ├── rails-ruby.el ├── rails-runner.el ├── snippets └── ruby-mode │ ├── controller.restful.basic │ ├── controller.restful.nested │ ├── controller_spec.restful.basic │ ├── controller_spec.restful.nested │ ├── migration.ac │ ├── migration.ai │ ├── migration.aiu │ ├── migration.cc │ ├── migration.ccd │ ├── migration.cht │ ├── migration.cre │ ├── migration.dt │ ├── migration.rc │ ├── migration.renc │ ├── migration.rent │ ├── migration.ri │ ├── migration.tb │ ├── migration.tbin │ ├── migration.tbt │ ├── migration.td │ ├── migration.tdt │ ├── migration.tf │ ├── migration.ti │ ├── migration.tim │ ├── migration.tin │ ├── migration.tref │ ├── migration.ts │ ├── migration.tt │ ├── migration.ttim │ ├── model.bt │ ├── model.btp │ ├── model.hm │ ├── model.hma │ ├── model.hmt │ ├── model.ho │ ├── model.hoa │ ├── model.hot │ ├── model.ns │ ├── model.nsl │ ├── model.vf │ ├── model.vl │ ├── model.vn │ ├── model.vp │ ├── model.vu │ ├── resources.cpath │ ├── resources.curl │ ├── resources.ncpath │ ├── resources.ncurl │ ├── resources.npath │ ├── resources.nurl │ ├── resources.path │ ├── resources.pcpath │ ├── resources.pcurl │ ├── resources.pncpath │ ├── resources.pncurl │ ├── resources.pnpath │ ├── resources.pnurl │ ├── resources.ppath │ ├── resources.purl │ ├── resources.rc │ ├── resources.rk │ ├── resources.ro │ └── resources.url ├── string-ext.el ├── tests.rails ├── all.el ├── rails-lib.test.el └── test-helper.el ├── tests ├── all.el ├── app │ ├── README │ ├── app │ │ ├── controllers │ │ │ ├── application.rb │ │ │ └── posts_controller.rb │ │ ├── helpers │ │ │ └── posts_helper.rb │ │ ├── models │ │ │ └── post.rb │ │ └── views │ │ │ └── posts │ │ │ ├── _form.html.erb │ │ │ ├── edit.html.erb │ │ │ ├── index.html.erb │ │ │ ├── index.xml.builder │ │ │ ├── new.html.erb │ │ │ └── show.html.erb │ └── config │ │ └── environment.rb ├── el-expectations.el ├── el-mock.el ├── elk-test.el ├── ext │ ├── core-ext.elk │ ├── files-ext.elk │ ├── inflections.elk │ ├── list-ext.elk │ ├── string-ext.elk │ └── test-helper.el ├── fringe-helper.el └── test-helper.el └── vendor └── anything.el /.gitignore: -------------------------------------------------------------------------------- 1 | *.elc 2 | /TAGS 3 | *.js.data 4 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | == HEAD 2 | *) Feature: added the snippets for yasnippets. 3 | *) Bugfix: compilation warnnings. 4 | 5 | == 0.99 Changes (5 Mar 2009) 6 | First release. 7 | *) Bugfix: 8 | *) Feature: 9 | *) Change: 10 | *) Workaround: 11 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/ChangeLog -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | It is the minor mode for editing Ruby On Rails code with Emacs. This 2 | minor mode makes your work much easier and user friendly. 3 | 4 | 5 | == Requirements 6 | 7 | The emacs-rails-reloaded is requiring a 22.x or 23 (CVS) version of 8 | Emacs, and can’t be running on old versions (less 22.0). To install 9 | Emacs: 10 | 11 | * For UNIX: use your package manager (typically name of package emacs, 12 | emacs-cvs or emacs22) or compile it from source. 13 | 14 | * For OSX: use the "Aquameacs":http://aquamacs.org or nightly builds 15 | of "CVS version with Cocoa":http://atomized.org/wp-content/cocoa-emacs-nightly/ 16 | or install using macports (name of package: emacs or emacs-app) 17 | 18 | * For Windows: download and install "EmacsW32":http://ourcomments.org/Emacs/EmacsW32.html 19 | 20 | 21 | == Instalation 22 | 23 | Download last release from "github project page":http://github.com/dima-exe/emacs-rails-reloaded/downloads 24 | and unpack it to directory containing libraries of Emacs, by default it’s 25 | $HOME/.emacs.d/ 26 | 27 | After that add bellow code in your the .emacs file: 28 | 29 | (setq load-path (cons (expand-file-name "~/.emacs.d/rails-reloaded") load-path)) 30 | (require 'rails-autoload) 31 | 32 | Next bytecompile, press [M-x] and type rails/bytecompile. 33 | 34 | 35 | == First Acquaintance 36 | 37 | Go to directory with your rails application and open any file in Emacs: 38 | 39 | cd $HOME/project/simple_rails_application 40 | emacs app/controllers/application.rb 41 | 42 | There must be “RoR” sign in the list of active minor-modes in status 43 | bar. Thi means, that emacs-rails is enabled and ready to help you in 44 | your not so easy work. 45 | 46 | Almoust all actions are in the “RoR” menu. You can check it 47 | out and try some of them. Don’t forget, that menu will help you only 48 | first time. After that you better use hot keys for effective work, you 49 | can find them in the brackets. 50 | 51 | 52 | == Features 53 | 54 | * Integration with script/generate, script/destroy and rake, press 55 | [C-c '] or [C-c ;] and type 'rake', 'gen', 'des' to display 56 | available tasks. 57 | 58 | * Navigation around rails files, 59 | press [C-c '] or [C-c ;] to display available files. 60 | [C-c up] to toggle (controller|mailer) <> view. 61 | [C-c t] to toggle test <> implementation. 62 | 63 | * Support test frameworks Test::Unit and RSpec, press [C-c C-c .] or 64 | [C-c C-c ,] to run current test. 65 | 66 | * Management of WEBrick/Mongrel/Thing 67 | 68 | * Per project configuration, you can setup the default port for server, 69 | the environment or etc. 70 | 71 | * Apidock.com integration, press [C-c '] or [C-c ;] and type who you 72 | wish find. 73 | 74 | * Textmate like snippets. 75 | 76 | 77 | == Links 78 | 79 | For bugs, patches and other requests: 80 | http://dima.lighthouseapp.com/projects/1882-emacs-rails 81 | 82 | Google group about rails development on Emacs: 83 | http://groups.google.com/group/emacs-on-rails -------------------------------------------------------------------------------- /bundles/rails-apidock-bundle.el: -------------------------------------------------------------------------------- 1 | (defconst rails/apidock-bundle/buffer-name "*rails-apidock-bundle*") 2 | (defconst rails/apidock-bundle/script-file-name "bundles/rails-apidock-bundle/search.rb") 3 | 4 | (defun rails/apidock-bundle/get-proc () 5 | (let ((proc (get-buffer-process rails/apidock-bundle/buffer-name))) 6 | (unless proc 7 | (setq 8 | proc 9 | (start-process rails/apidock-bundle/buffer-name 10 | rails/apidock-bundle/buffer-name 11 | rails/ruby/command 12 | (rails/apidock-bundle/locate-script))) 13 | (set-process-query-on-exit-flag proc nil)) 14 | proc)) 15 | 16 | (defun rails/apidock-bundle/get-result (mod query) 17 | (let ((proc (rails/apidock-bundle/get-proc))) 18 | (with-current-buffer rails/apidock-bundle/buffer-name 19 | (kill-region (point-min) (point-max)) 20 | (process-send-string proc (format "%s %s\n" mod query)) 21 | (while 22 | (progn 23 | (sleep-for 0 100) 24 | (goto-char (point-max)) 25 | (goto-char (point-at-bol 0)) 26 | (not (string= "APIDOCK_EOF" 27 | (buffer-substring (line-beginning-position) 28 | (line-end-position)))))) 29 | (read (buffer-substring-no-properties (point-min) 30 | (point)))))) 31 | 32 | (defun rails/apidock-bundle/locate-script () 33 | (let* ((path (file-name-directory (locate-library "rails-reloaded"))) 34 | (script (concat path rails/apidock-bundle/script-file-name))) 35 | (when (file-exists-p script) 36 | script))) 37 | 38 | (defun rails/apidock-bundle/search (query &optional mod) 39 | (let ((mod (or mod "rails"))) 40 | (rails/apidock-bundle/get-result mod query))) 41 | 42 | (rails/defbundle "Apidock" 43 | (:triggers 44 | (("apidock-rails" "Search on apidock.com/rails" 45 | (candidates 46 | . 47 | (lambda () 48 | (let ((rs (rails/apidock-bundle/search anything-pattern "rails"))) 49 | rs))) 50 | (action ("Browse Url" . browse-url)) 51 | (requires-pattern . 3) 52 | (candidate-number-limit . 10) 53 | (volatile) 54 | (delayed)) 55 | ("apidock-rspec" "Search on apidock.com/rspec" 56 | (candidates 57 | . 58 | (lambda () 59 | (let ((rs (rails/apidock-bundle/search anything-pattern "rspec"))) 60 | rs))) 61 | (action ("Browse Url" . browse-url)) 62 | (requires-pattern . 3) 63 | (candidate-number-limit . 10) 64 | (volatile) 65 | (delayed))))) 66 | -------------------------------------------------------------------------------- /bundles/rails-apidock-bundle/search.rb: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'activesupport' 5 | 6 | LIMIT = 12 7 | 8 | def create_data(data_file, file) 9 | result = [] 10 | File.open(file, "rb") do |f| 11 | str = f.read 12 | keywords,data = str.split(";") 13 | data.gsub!(/^[^=]+= /, "") 14 | decoded = ActiveSupport::JSON.decode(data) 15 | for it in decoded 16 | i = { 17 | :score => it["score"], 18 | :name => it["name"], 19 | :path => it["path"] == "-" ? nil : it["path"], 20 | :type => it["type"], 21 | :method_type => it["method_type"] 22 | } 23 | result << i 24 | end 25 | end 26 | File.open(data_file, "wb") do |f| 27 | f.write Marshal.dump(result) 28 | end 29 | end 30 | 31 | def get_data(file) 32 | data_file = "#{file}.data" 33 | unless File.exists?(data_file) 34 | create_data(data_file, file) 35 | end 36 | Marshal.load(File.open(data_file)) 37 | end 38 | 39 | def search(mod, str) 40 | file = File.dirname(__FILE__) + "/#{mod}.js" 41 | data = get_data(file) 42 | q = Regexp.new(Regexp.quote(str), Regexp::IGNORECASE) 43 | result = [] 44 | for it in data 45 | next unless q.match(it[:name]) 46 | it[:score] = it[:score].to_f 47 | result << it 48 | end 49 | return if result.empty? 50 | 51 | result = result.sort_by{ |a| a[:score] }.reverse 52 | to_lisp(mod, result[0..LIMIT]) 53 | end 54 | 55 | def to_lisp(mod, data) 56 | result = [] 57 | for it in data 58 | url_prefix = if it[:path] 59 | "#{it[:path].gsub(/\:\:/, "/")}/" 60 | else 61 | "" 62 | end 63 | url_prefix = "http://apidock.com/#{mod}/#{url_prefix}" 64 | title = it[:name].dup 65 | title << " (#{it[:path]})" if it[:path] 66 | line = case it[:type] 67 | when "method" 68 | if it[:method_type] == "instance" 69 | [title, "#{url_prefix}#{it[:name]}"] 70 | else 71 | [title, "#{url_prefix}#{it[:name]}/class"] 72 | end 73 | when "class", "module" 74 | [title, "#{url_prefix}#{it[:name]}"] 75 | end 76 | result << line 77 | end 78 | result.map! do |i| 79 | '("' + i.first + '" . "' + i.last + '")' 80 | end 81 | "(" + result.join("\n") + ")" 82 | end 83 | 84 | STDOUT.flush 85 | loop do 86 | line = STDIN.gets 87 | mod, q = /(\w+)(.*)$/.match(line)[1..2] 88 | q.strip! 89 | puts search(mod, q) unless q.blank? 90 | puts "APIDOCK_EOF" 91 | STDOUT.flush 92 | end 93 | -------------------------------------------------------------------------------- /bundles/rails-basic-bundle.el: -------------------------------------------------------------------------------- 1 | (defun rails/basic-bundle/toggle-from-view (root rails-buffer) 2 | (when (eq 'view (rails/resource-buffer-type rails-buffer)) 3 | (let ((controllers 4 | (rails/resources/get-associated-items-by-resource 5 | root 6 | rails-buffer 7 | (rails/resources/find 'controller))) 8 | (mailers 9 | (rails/resources/get-associated-items-by-resource 10 | root 11 | rails-buffer 12 | (rails/resources/find 'controller))) 13 | (method (file-name-sans-extension 14 | (file-name-sans-extension 15 | (file-name-nondirectory 16 | (rails/resource-buffer-file rails-buffer))))) 17 | item) 18 | (setq item 19 | (or (car controllers) 20 | (car mailers))) 21 | (when item 22 | (rails/resources/find-file-by-item root item) 23 | (rails/ruby/goto-method-in-current-buffer method) 24 | (rails/resources/notify-item item) 25 | t)))) 26 | 27 | (defun rails/basic-bundle/toggle-to-view (root rails-buffer) 28 | (when (memq (rails/resource-buffer-type rails-buffer) 29 | '(controller mailer)) 30 | (let* ((method (rails/ruby/current-method)) 31 | (res-name (rails/resource-buffer-title rails-buffer)) 32 | (view (rails/resources/find 'view)) 33 | (dir (concat root (rails/resource-dir view) res-name "/")) 34 | (regexp (if method 35 | (concat "^" method "\..*") 36 | ".*")) 37 | items 38 | file) 39 | (setq items 40 | (files-ext/directory-files-recursive dir regexp)) 41 | (if (= 1 (length items)) 42 | (setq file (car items)) 43 | (setq file 44 | (ido-completing-read "Select view: " 45 | items))) 46 | (find-file (concat dir file)) 47 | (rails/resources/notify-item 48 | nil 49 | "View" 50 | (concat res-name "/" file))) 51 | t)) 52 | 53 | (rails/defbundle "Basic" 54 | () 55 | 56 | (rails/defresource 'controller "Controller" 57 | :dir "app/controllers" 58 | :file-ext "rb" 59 | :file-suffix "_controller") 60 | 61 | (rails/defresource 'mailer "Mailer" 62 | :dir "app/models" 63 | :file-ext "rb" 64 | :skip-file-suffix "_mailer" 65 | :weight 2) 66 | 67 | (rails/defresource 'helper "Helper" 68 | :dir "app/helpers" 69 | :file-suffix "_helper" 70 | :file-ext "rb") 71 | 72 | (rails/defresource 'view "View" 73 | :dir "app/views" 74 | :file-pattern "{name}/.*" 75 | :toggle '(rails/basic-bundle/toggle-to-view . rails/basic-bundle/toggle-from-view) 76 | :group 'viewa 77 | :options 'expand-in-menu 78 | :weight 2) 79 | 80 | (rails/defresource 'migration "Migration" 81 | :dir "db/migrate" 82 | :file-ext "rb" 83 | :file-pattern "[0-9]+_create_{name}") 84 | 85 | (rails/defresource 'model "Model" 86 | :dir "app/models" 87 | :file-ext "rb" 88 | :options 'pluralize) 89 | 90 | (rails/defresource 'observer "Observer" 91 | :dir "app/models" 92 | :file-ext "rb" 93 | :file-suffix "_observer" 94 | :weight 2 95 | :options 'pluralize) 96 | 97 | (rails/defresource 'stylesheet "Stylesheet" 98 | :dir "public/stylesheets" 99 | :file-ext "css") 100 | 101 | (rails/defresource 'javascript "Javascript" 102 | :dir "public/javascripts" 103 | :file-ext "js") 104 | ) 105 | -------------------------------------------------------------------------------- /bundles/rails-database-bundle.el: -------------------------------------------------------------------------------- 1 | (require 'cl) 2 | 3 | (autoload 'rails/rake-bundle/task-run "bundles/rails-database-bundle") 4 | 5 | ;;; --------------------------------------------------------- 6 | ;;; - Variables 7 | ;;; 8 | (defvar rails/database-bundle/keywords 9 | '(("^[=]+\s\\(.*\\)\s[=]+" 10 | (0 font-lock-string-face)) 11 | ("^[-]+\s\\(.*\\)(" 12 | (1 font-lock-function-name-face)) 13 | ("\\(:[^ ,)]+\\)" 14 | (1 font-lock-constant-face)) 15 | ("^\s+\\(->.*\\)" 16 | (1 font-lock-comment-face)))) 17 | 18 | ;;; --------------------------------------------------------- 19 | ;;; - Functions 20 | ;;; 21 | 22 | (defun rails/database-bundle/versions (root) 23 | (reverse 24 | (delete-if nil 25 | (mapcar 26 | #'(lambda (file) 27 | (string-ext/string=~ "^\\([0-9]+\\)\\(.*\\)\\.rb" 28 | file 29 | (format "%s %s" $1 (string-ext/decamelize $2)))) 30 | (directory-files 31 | (concat root "db/migrate/") 32 | nil rails/ruby/file-suffix))))) 33 | 34 | (defmacro rails/database-bundle/retmsg (success failed) 35 | `(lambda (retval) 36 | (rails/notify 37 | (if (zerop retval) ,success ,failed)))) 38 | 39 | (defun rails/database-bundle/run-task (root task &optional args funcs) 40 | "Run a Database task in RAILS_ROOT with MAJOR-MODE." 41 | (when (and task root) 42 | (unless funcs 43 | (setq funcs '(rails/runner/popup-buffer-if-failed))) 44 | (rails/rake-bundle/task-run 45 | root (concat "db:" task) args rails/database-bundle/keywords funcs))) 46 | 47 | ;;; --------------------------------------------------------- 48 | ;;; - Interactives 49 | ;;; 50 | 51 | (defun rails/database-bundle/migrate () 52 | (interactive) 53 | (when-bind (root (rails/root)) 54 | (rails/database-bundle/run-task root "migrate"))) 55 | 56 | (defun rails/database-bundle/migrate-to-version () 57 | (interactive) 58 | (when-bind (root (rails/root)) 59 | (let ((version 60 | (ido-completing-read "Version: " 61 | (rails/database-bundle/versions root) 62 | nil 63 | t))) 64 | (when (not (string-ext/empty-p version)) 65 | (rails/database-bundle/run-task 66 | root 67 | "migrate" 68 | (format "VERSION=%s" (car (split-string version " ")))))))) 69 | 70 | (defun rails/database-bundle/migrate-rollback () 71 | (interactive) 72 | (when-bind (root (rails/root)) 73 | (let* ((steps 74 | (rails/completing-read "Steps to rollback")) 75 | (steps (string-to-number steps))) 76 | (if (zerop steps) 77 | (rails/notify "Invalid step, muste be digits.") 78 | (rails/database-bundle/run-task root 79 | "rollback" 80 | (format "STEP=%s" steps)))))) 81 | 82 | (defun rails/database-bundle/migrate-redo () 83 | (interactive) 84 | (when-bind (root (rails/root)) 85 | (rails/database-bundle/run-task root "migrate:redo"))) 86 | 87 | (defun rails/database-bundle/clone () 88 | (interactive) 89 | (when-bind (root (rails/root)) 90 | (rails/database-bundle/run-task root "test:clone"))) 91 | 92 | ;;; --------------------------------------------------------- 93 | ;;; - Bundle 94 | ;;; 95 | 96 | (rails/defbundle "Database" 97 | (:menu 98 | (([clone] (cons "Clone Development DB to Test DB" 'rails/database-bundle/clone)) 99 | ([redo] (cons "Redo Last Migration" 'rails/database-bundle/migrate-redo)) 100 | ([rollback] (cons "Migrate to Previous Version" 'rails/database-bundle/migrate-rollback)) 101 | ([version] (cons "Migrate to Version" 'rails/database-bundle/migrate-to-version)) 102 | ([migrate] (cons "Migrate" 'rails/database-bundle/migrate))) 103 | :keys 104 | (("d m" 'rails/database-bundle/migrate) 105 | ("d v" 'rails/database-bundle/migrate-to-version) 106 | ("d r" 'rails/database-bundle/migrate-rollback) 107 | ("d R" 'rails/database-bundle/migrate-redo) 108 | ("d c" 'rails/database-bundle/clone)) 109 | :triggers 110 | (("db" "Database Tasks" 111 | (candidates 112 | . 113 | (lambda () 114 | (when (string-match "^db" anything-pattern) 115 | (list 116 | (cons 117 | (format "db migrate %s" (propertize "# Migrate" 'face 'font-lock-comment-face)) 118 | 'rails/database-bundle/migrate) 119 | (cons 120 | (format "db clone %s" (propertize "# Clone Development DB to Test DB" 'face 'font-lock-comment-face)) 121 | 'rails/database-bundle/clone) 122 | (cons 123 | (format "db version %s" (propertize "# Migrate to Version" 'face 'font-lock-comment-face)) 124 | 'rails/database-bundle/migrate-to-version) 125 | (cons 126 | (format "db redo %s" (propertize "# Redo Last Migration" 'face 'font-lock-comment-face)) 127 | 'rails/database-bundle/migrate-redo) 128 | (cons 129 | (format "db rollback %s" (propertize "# Migrate to Previous Version" 'face 'font-lock-comment-face)) 130 | 'rails/database-bundle/migrate-rollback))))) 131 | (action ("Run" . (lambda (i) (funcall i)))) 132 | (requires-pattern . 2))))) 133 | -------------------------------------------------------------------------------- /bundles/rails-generator-bundle.el: -------------------------------------------------------------------------------- 1 | (require 'cl) 2 | 3 | ;;; --------------------------------------------------------- 4 | ;;; - Variables 5 | ;;; 6 | 7 | (defconst rails/generator-bundle/tasks-cache-file "tmp/.generate-cache") 8 | 9 | (defvar rails/generator-bundle/options "-s") 10 | (defvar rails/generator-bundle/history nil) 11 | (defvar rails/generator-bundle/tasks-regexp "^\s+\\(Plugins ([^)]+)\\|Builtin\\|Rubygems\\):\s+\\(.*\\)$" 12 | "Regexp to match tasks list in `rake --tasks` output.") 13 | 14 | (defvar rails/generator-bundle/button-regexp "^\s+create\s+\\(.*\\)$") 15 | 16 | (defvar rails/generator-bundle/font-lock-keywords 17 | '(("^\s+\\(exists\\|notempty\\)\s+\\(.*\\)$" 18 | (1 font-lock-function-name-face) 19 | (2 font-lock-comment-delimiter-face)) 20 | ("^\s+\\(create\\|rm\\|rmdir\\)\s+\\(.*\\)$" 21 | (1 font-lock-function-name-face) 22 | (2 font-lock-string-face)))) 23 | 24 | ;;; --------------------------------------------------------- 25 | ;;; - Functions 26 | ;;; 27 | 28 | (defun rails/generator-bundle/make-buttons (&rest args) 29 | (save-excursion 30 | (while (re-search-forward rails/generator-bundle/button-regexp nil t) 31 | (let ((root rails/runner/buffer-rails-root) 32 | (file (match-string 1))) 33 | (when (and (rails/file-exist-p root file) 34 | (not (rails/file-directory-p root file))) 35 | (make-button (match-beginning 1) (match-end 1) 36 | :type 'rails/button 37 | :file-name (concat root file)))))) 38 | (rails/button-action (next-button (point-min)))) 39 | 40 | (defun rails/generator-bundle/create-cache (root) 41 | "Create a cache file from script/generate output." 42 | (in-directory root 43 | (let ((string (rails/proxy/shell-command-to-string 44 | root 45 | (format 46 | "%s script/generate --help" 47 | rails/ruby/command))) 48 | (pos 0) 49 | tasks) 50 | (while (string-match rails/generator-bundle/tasks-regexp string pos) 51 | (setq pos (match-end 2)) 52 | (setq tasks 53 | (merge 'list 54 | tasks 55 | (split-string (match-string 2 string) ", ") 56 | 'string-lessp))) 57 | (files-ext/write-string-to-file 58 | (concat root rails/generator-bundle/tasks-cache-file) 59 | (prin1-to-string tasks)) 60 | tasks))) 61 | 62 | (defun rails/generator-bundle/list-of-tasks (root) 63 | "Return all available tasks and create tasks cache file." 64 | (let ((cache-file (concat root rails/generator-bundle/tasks-cache-file))) 65 | (if (file-exists-p cache-file) 66 | (files-ext/read-from-file cache-file) 67 | (rails/generator-bundle/create-cache root)))) 68 | 69 | (defun rails/generator-bundle/run (root what task options &optional script-options) 70 | "Run a Rake task in RAILS_ROOT with MAJOR-MODE." 71 | (when (and task root) 72 | (unless script-options 73 | (setq script-options "")) 74 | (rails/runner/run root 75 | rails/ruby/command (format "script/%s %s %s %s" 76 | what 77 | task 78 | options 79 | script-options) 80 | :keywords rails/generator-bundle/font-lock-keywords) 81 | 82 | (setq rails/runner/after-stop-func-list 83 | '(rails/runner/popup-buffer rails/generator-bundle/make-buttons)))) 84 | 85 | ;;; --------------------------------------------------------- 86 | ;;; - Interactives 87 | ;;; 88 | 89 | (defun rails/generator-bundle/generate (&optional task) 90 | "Run a Generator task." 91 | (interactive) 92 | (rails/with-root nil 93 | (if task 94 | (let (options) 95 | (unless (string-ext/empty-p task) 96 | (setq options (read-string (format "script/generate %s " task))) 97 | (unless (string-ext/empty-p options) 98 | (rails/generator-bundle/run (rails/root) 99 | "generate" 100 | task 101 | options 102 | rails/generator-bundle/options)))) 103 | (rails/anything/run-with-pattern "gen ")))) 104 | 105 | (defun rails/generator-bundle/destroy (&optional task) 106 | "Run a Destroy task." 107 | (interactive) 108 | (rails/with-root nil 109 | (if task 110 | (let (options) 111 | (unless (string-ext/empty-p task) 112 | (setq options (read-string (format "script/destroy %s " task))) 113 | (unless (string-ext/empty-p options) 114 | (rails/generator-bundle/run (rails/root) "destroy" task options)))) 115 | (rails/anything/run-with-pattern "des ")))) 116 | 117 | (defun rails/generator-bundle/reset-cache () 118 | (interactive) 119 | (when-bind (root (rails/root)) 120 | (rails/generator-bundle/create-cache root))) 121 | 122 | ;;; --------------------------------------------------------- 123 | ;;; - Bundle 124 | ;;; 125 | 126 | (rails/defbundle "Generator" 127 | (:menu 128 | (([reset] (cons "Reset Cache" 'rails/generator-bundle/reset-cache)) 129 | ([destroy] (cons "Destroy" 'rails/generator-bundle/destroy)) 130 | ([create] (cons "Generate" 'rails/generator-bundle/generate))) 131 | :keys 132 | (("e" 'rails/generator-bundle/generate) 133 | ("E" 'rails/generator-bundle/destroy)) 134 | :triggers 135 | (("gen" "Generate" 136 | (candidates 137 | . 138 | (lambda () 139 | (when (string-match "^gen" anything-pattern) 140 | (mapcar 141 | (lambda (i) 142 | (cons (format "gen %s" i) i)) 143 | (rails/generator-bundle/list-of-tasks anything-rails-current-root))))) 144 | (action ("Run" . rails/generator-bundle/generate)) 145 | (requires-pattern . 3)) 146 | ("des" "Destroy" 147 | (candidates 148 | . 149 | (lambda () 150 | (when (string-match "^des" anything-pattern) 151 | (mapcar 152 | (lambda (i) 153 | (cons (format "des %s" i) i)) 154 | (rails/generator-bundle/list-of-tasks anything-rails-current-root))))) 155 | (action ("Run" . rails/generator-bundle/destroy)) 156 | (requires-pattern . 3))))) 157 | -------------------------------------------------------------------------------- /bundles/rails-rake-bundle.el: -------------------------------------------------------------------------------- 1 | (require 'cl) 2 | 3 | ;;; --------------------------------------------------------- 4 | ;;; - Variables 5 | ;;; 6 | 7 | (defconst rails/rake-bundle/command "rake") 8 | (defconst rails/rake-bundle/tasks-cache-file "tmp/.rake-tasks-cache") 9 | (defvar rails/rake-bundle/history nil) 10 | (defvar rails/rake-bundle/tasks-regexp "^rake\s+\\([^ ]+\\)\s+\\(.*\\)$" 11 | "Regexp to match tasks list in `rake --tasks` output.") 12 | (defvar rails/rake-bundle/tasks-runners-alist nil) 13 | 14 | (defvar rails/rake-bundle/task-keywords-alist 15 | '(("^notes.*$" . (("^\\([^ ]+\\):" 16 | (0 font-lock-string-face)) 17 | ("^ +\\(\\*\\) \\(\\[[ 0-9]+\\]\\( \\[\\w+\\]\\)?\\) \\(.*\\)$" 18 | (1 font-lock-function-name-face) 19 | (2 font-lock-constant-face) 20 | (4 font-lock-comment-face)))))) 21 | 22 | (defvar rails/rake-bundle/task-after-stop-alist 23 | '(("^notes.*$" . rails/rake-bundle/after-stop-notes))) 24 | 25 | (defvar rails/rake-bundle/task-name nil) 26 | 27 | ;;; --------------------------------------------------------- 28 | ;;; - Functions 29 | ;;; 30 | 31 | (defun rails/rake-bundle/create-tasks-cache (root) 32 | "Create a cache file from rake --tasks output." 33 | (in-directory root 34 | (let ((tasks (loop for str in (split-string (rails/proxy/shell-command-to-string 35 | root "rake --tasks") 36 | "[\r\n]+") 37 | for task = (unless (string-ext/empty-p str) 38 | (string-ext/string=~ rails/rake-bundle/tasks-regexp 39 | str 40 | (when $1 (cons $1 $2)))) 41 | when task collect task))) 42 | (files-ext/write-string-to-file 43 | (concat root rails/rake-bundle/tasks-cache-file) 44 | (prin1-to-string tasks)) 45 | (mapcar 'car tasks)))) 46 | 47 | (defun rails/rake-bundle/list-of-tasks (root) 48 | "Return all available tasks and create tasks cache file." 49 | (let* ((cache-file (concat root rails/rake-bundle/tasks-cache-file))) 50 | (if (file-exists-p cache-file) 51 | (mapcar 'car 52 | (files-ext/read-from-file cache-file)) 53 | (rails/rake-bundle/create-tasks-cache root)))) 54 | 55 | (defun rails/rake-bundle/alist-of-tasks (root) 56 | "Return all available tasks and descriptions and create tasks cache file." 57 | (let* ((cache-file (concat root rails/rake-bundle/tasks-cache-file))) 58 | (unless (file-exists-p cache-file) 59 | (rails/rake-bundle/create-tasks-cache root)) 60 | (files-ext/read-from-file cache-file))) 61 | 62 | (defun rails/rake-bundle/task-run-with-rake (root task &optional args keywords after-stop-funcs) 63 | "Run a Rake task in RAILS_ROOT with MAJOR-MODE." 64 | (when (and task root) 65 | (unless keywords 66 | (setq keywords 67 | (cdr (find task rails/rake-bundle/task-keywords-alist 68 | :key 'car 69 | :test '(lambda(i j) (string-match j i)))))) 70 | (rails/runner/run root 71 | rails/rake-bundle/command 72 | (if args 73 | (format "RAILS_ENV=%s %s %s" rails/default-environment task args ) 74 | (format "RAILS_ENV=%s %s" rails/default-environment task)) 75 | :keywords keywords) 76 | (with-current-buffer rails/runner/buffer-name 77 | (set (make-local-variable 'rails/rake-bundle/task-name) task)) 78 | (rails/notify (format "Run task %s in %s" task rails/default-environment) :notice) 79 | (if after-stop-funcs 80 | (progn 81 | (setq rails/runner/after-stop-func-list after-stop-funcs)) 82 | (progn 83 | (setq rails/runner/after-stop-func-list '(rails/runner/popup-buffer)) 84 | (setq after-stop-funcs 85 | (cdr (find task rails/rake-bundle/task-after-stop-alist 86 | :key 'car 87 | :test '(lambda(i j) (string-match j i))))) 88 | (when after-stop-funcs 89 | (add-to-list 'rails/runner/after-stop-func-list after-stop-funcs t)))) 90 | (add-to-list 'rails/runner/after-stop-func-list 'rails/rake-bundle/after-stop-notify t))) 91 | 92 | (defun rails/rake-bundle/task-run (root task &optional args keywords after-stop-funcs) 93 | (let (runner) 94 | (setq 95 | runner 96 | (loop for it in rails/rake-bundle/tasks-runners-alist 97 | for found = (string-ext/string=~ (car it) task it) 98 | when found 99 | return found)) 100 | (if runner 101 | (funcall (cdr runner) root task args) 102 | (rails/rake-bundle/task-run-with-rake root task args keywords after-stop-funcs)))) 103 | 104 | 105 | ;;; --------------------------------------------------------- 106 | ;;; - After stop functions 107 | ;;; 108 | 109 | (defun rails/rake-bundle/after-stop-notify (ret-val) 110 | (if (zerop ret-val) 111 | (rails/notify (format "Task %s was successfuly stopped" rails/rake-bundle/task-name) :notice) 112 | (rails/notify (format "Failed to run task %s" rails/rake-bundle/task-name) :notice))) 113 | 114 | (defun rails/rake-bundle/after-stop-notes (&rest args) 115 | (save-excursion 116 | (while (re-search-forward "^\\(\\w.*\\):$" nil t) 117 | (let ((root rails/runner/buffer-rails-root) 118 | (file (match-string 1)) 119 | line) 120 | (make-button (match-beginning 1) (match-end 1) 121 | :type 'rails/button 122 | :file-name (concat root file)) 123 | (setq line (buffer-substring-no-properties 124 | (line-beginning-position) 125 | (line-end-position))) 126 | (while (not (string-ext/empty-p line)) 127 | (when (string-match "^\s+\\*\s+\\[\\([ 0-9]+\\)\\]" line) 128 | (make-button (+ (line-beginning-position) (match-beginning 1)) 129 | (+ (line-beginning-position) (match-end 1)) 130 | :type 'rails/button 131 | :file-name (concat root file) 132 | :line (string-to-number (match-string 1 line)))) 133 | (goto-char (+ (line-end-position) 1)) 134 | (setq line (buffer-substring-no-properties 135 | (line-beginning-position) 136 | (line-end-position)))))))) 137 | 138 | ;;; --------------------------------------------------------- 139 | ;;; - Interactives 140 | ;;; 141 | 142 | (defun rails/rake-bundle/run (&optional task) 143 | "Run a Rake task." 144 | (interactive) 145 | (rails/with-root nil 146 | (if task 147 | (when (not (string-ext/empty-p task)) 148 | (rails/rake-bundle/task-run (rails/root) task)) 149 | (rails/rake-bundle/list-tasks)))) 150 | 151 | (defun rails/rake-bundle/run-with-args (&optional task) 152 | "Run a Rake task with arguments ARGS." 153 | (interactive) 154 | (rails/with-root nil 155 | (if task 156 | (when (not (string-ext/empty-p task)) 157 | (let ((args (read-string (format "Arguments fo %s: " task)))) 158 | (rails/rake-bundle/task-run (rails/root) task args))) 159 | (rails/rake-bundle/list-tasks)))) 160 | 161 | (defun rails/rake-bundle/reset-cache () 162 | "Reset tasks cache." 163 | (interactive) 164 | (rails/with-root nil 165 | (rails/rake-bundle/create-tasks-cache (rails/root)))) 166 | 167 | (defun rails/rake-bundle/list-tasks () 168 | "List of availabled Rake tasks." 169 | (interactive) 170 | (rails/with-root nil 171 | (rails/anything/run-with-pattern "rake "))) 172 | 173 | ;;; --------------------------------------------------------- 174 | ;;; - Bundle 175 | ;;; 176 | 177 | (rails/defbundle "Rake" 178 | (:menu 179 | (([reset] (cons "Reset Tasks Cache" 'rails/rake-bundle/reset-cache)) 180 | ([task] (cons "Run Rake Task" 'rails/rake-bundle/list-tasks))) 181 | :keys 182 | (("r" 'rails/rake-bundle/list-tasks)) 183 | :triggers 184 | (("rake" "Rake Task" 185 | (candidates 186 | . 187 | (lambda () 188 | (when (string-match "^rake" anything-pattern) 189 | (mapcar 190 | (lambda (i) (cons (format "rake %s %s" 191 | (car i) 192 | (propertize (cdr i) 'face font-lock-comment-face)) 193 | (car i))) 194 | (rails/rake-bundle/alist-of-tasks anything-rails-current-root))))) 195 | (action ("Run" . (lambda (i) (rails/rake-bundle/run i))) 196 | ("Run with Arguments" . (lambda (i) (rails/rake-bundle/run-with-args i)))) 197 | (requires-pattern . 4)))) 198 | 199 | (setq rails/rake-bundle/tasks-runners-alist nil)) 200 | -------------------------------------------------------------------------------- /bundles/rails-rspec-bundle.el: -------------------------------------------------------------------------------- 1 | ;;; --------------------------------------------------------- 2 | ;;; - Variables 3 | ;;; 4 | 5 | (defvar rails/rspec-bundle/command rails/ruby/command) 6 | (defvar rails/rspec-bundle/spec-options "-O spec/spec.opts") 7 | 8 | ;;; --------------------------------------------------------- 9 | ;;; - Functions 10 | ;;; 11 | 12 | (defun rails/rspec-bundle/single-file (root rails-buffer) 13 | (rails/compile/run-file 14 | root 15 | rails-buffer 16 | rails/rspec-bundle/command 17 | (concat "script/spec %s" (format " %s" rails/rspec-bundle/spec-options)) 18 | "_spec\\.rb$")) 19 | 20 | (defun rails/rspec-bundle/current-method (root rails-buffer) 21 | (when-bind (line (line-number-at-pos)) 22 | (rails/compile/run-file 23 | root 24 | rails-buffer 25 | rails/rspec-bundle/command 26 | (concat "script/spec %s" (format " %s -l %s" rails/rspec-bundle/spec-options line)) 27 | "_spec\\.rb$"))) 28 | 29 | (defun rails/rspec-bundle/run-spec-task (root task args) 30 | (rails/compile/run root 31 | (if (boundp 'rails/rake-bundle/command) 32 | rails/rake-bundle/command 33 | "rake") 34 | (format "%s %s" task (if args args "")))) 35 | 36 | (defun rails/rspec-bundle/after-load () 37 | (when (boundp 'rails/rake-bundle/tasks-runners-alist) 38 | (add-to-list 'rails/rake-bundle/tasks-runners-alist 39 | '("^spec" . rails/rspec-bundle/run-spec-task))) 40 | (setq rails/compile/single-file-list 41 | (cons 'rails/rspec-bundle/single-file 42 | rails/compile/single-file-list)) 43 | (setq rails/compile/current-method-list 44 | (cons 'rails/rspec-bundle/current-method 45 | rails/compile/current-method-list))) 46 | 47 | ;;; --------------------------------------------------------- 48 | ;;; - Bundle 49 | ;;; 50 | (rails/defbundle "RSpec" 51 | (:menu 52 | (([method] (cons "Run Current Mehtod" 'rails/compile/current-method)) 53 | ([file] (cons "Run Single File" 'rails/compile/single-file))) 54 | :after-load-bundles 55 | 'rails/rspec-bundle/after-load) 56 | 57 | ;;; --------------------------------------------------------- 58 | ;;; - Resources 59 | ;;; 60 | 61 | (rails/defresource 'model-spec "RSpec Model" 62 | :group 'spec 63 | :dir "spec/models" 64 | :file-suffix "_spec" 65 | :file-ext "rb" 66 | :options 'pluralize 67 | :test-to 'model) 68 | 69 | (rails/defresource 'controller-spec "RSpec Controller" 70 | :group 'spec 71 | :dir "spec/controllers" 72 | :file-suffix "_controller_spec" 73 | :file-ext "rb" 74 | :test-to 'controller) 75 | 76 | (rails/defresource 'helper-spec "RSpec Helper" 77 | :group 'spec 78 | :dir "spec/helpers" 79 | :file-suffix "_helper_spec" 80 | :file-ext "rb" 81 | :test-to 'helper) 82 | 83 | (rails/defresource 'fixture-spec "RSpec Fixture" 84 | :group 'spec 85 | :dir "spec/fixtures" 86 | :file-ext "yml") 87 | 88 | (rails/defresource 'factory-spec "RSpec Factory" 89 | :dir "spec/factories" 90 | :file-ext "rb" 91 | :options 'pluralize) 92 | 93 | (rails/defresource 'view-spec "RSpec View" 94 | :group 'views 95 | :dir "spec/views" 96 | :file-suffix "_spec" 97 | :file-pattern "{name}/.*" 98 | :file-ext "rb" 99 | :options 'expand-in-menu 100 | :test-to 'view )) -------------------------------------------------------------------------------- /bundles/rails-test-unit-bundle.el: -------------------------------------------------------------------------------- 1 | ;;; --------------------------------------------------------- 2 | ;;; - Functions 3 | ;;; 4 | 5 | (defun rails/test-unit-bundle/single-file (root rails-buffer) 6 | (rails/compile/run-file 7 | root 8 | rails-buffer 9 | rails/ruby/command 10 | "%s" 11 | "_test\\.rb$")) 12 | 13 | (defun rails/test-unit-bundle/current-method (root rails-buffer) 14 | (when-bind (method (rails/ruby/current-method)) 15 | (rails/compile/run-file 16 | root 17 | rails-buffer 18 | rails/ruby/command 19 | (concat "%s --name=" method) 20 | "_test\\.rb$"))) 21 | 22 | (defun rails/test-unit-bundle/run-test-task (root task args) 23 | (rails/compile/run root 24 | (if (boundp 'rails/rake-bundle/command) 25 | rails/rake-bundle/command 26 | "rake") 27 | (format "%s %s" task (if args args "")))) 28 | 29 | (defun rails/test-unit-bundle/after-load () 30 | (setq rails/compile/single-file-list 31 | (cons 'rails/test-unit-bundle/single-file 32 | rails/compile/single-file-list)) 33 | (setq rails/compile/current-method-list 34 | (cons 'rails/test-unit-bundle/current-method 35 | rails/compile/current-method-list)) 36 | 37 | (when (boundp 'rails/rake-bundle/tasks-runners-alist) 38 | (add-to-list 'rails/rake-bundle/tasks-runners-alist 39 | '("^test" . rails/test-unit-bundle/run-test-task)))) 40 | 41 | ;;; --------------------------------------------------------- 42 | ;;; - Bundle 43 | ;;; 44 | 45 | (rails/defbundle "Test::Unit" 46 | (:menu 47 | (([method] (cons "Run Current Mehtod" 'rails/compile/current-method)) 48 | ([file] (cons "Run Single File" 'rails/compile/single-file))) 49 | :after-load-bundles 50 | 'rails/test-unit-bundle/after-load) 51 | 52 | ;;; --------------------------------------------------------- 53 | ;;; - Resources 54 | ;;; 55 | 56 | (rails/defresource 'unit-test "Unit Test" 57 | :group 'unit-test 58 | :dir "test/unit" 59 | :file-suffix "_test" 60 | :file-ext "rb" 61 | :options 'pluralize 62 | :test-to 'model) 63 | 64 | (rails/defresource 'unit-test-mailer "Unit Test Mailer" 65 | :group 'unit-test 66 | :dir "test/unit" 67 | :file-suffix "_test" 68 | :skip-file-suffix "_mailer" 69 | :file-ext "rb" 70 | :weight 2 71 | :test-to 'mailer) 72 | 73 | (rails/defresource 'fixture "Fixture" 74 | :group 'unit-test 75 | :dir "test/fixtures" 76 | :file-ext "yml") 77 | 78 | (rails/defresource 'functional-test "Functional Test" 79 | :group 'unit-test 80 | :dir "test/functional" 81 | :file-suffix "_controller_test" 82 | :file-ext "rb" 83 | :test-to 'controller)) 84 | -------------------------------------------------------------------------------- /bundles/rails-webserver-bundle.el: -------------------------------------------------------------------------------- 1 | ;;; --------------------------------------------------------- 2 | ;;; - Variables 3 | ;;; 4 | 5 | (defconst rails/webserver-bundle/buffer-name "*RServer*") 6 | (defconst rails/webserver-bundle/types '("mongrel" "webrick" "lighttpd" "thin")) 7 | 8 | (defcustom rails/webserver-bundle/default-type "mongrel" 9 | "Webserver default server type." 10 | :type 'string 11 | :group 'rails) 12 | 13 | (defcustom rails/webserver-bundle/port 3000 14 | "Webserver defaut port." 15 | :type 'integer 16 | :group 'rails) 17 | 18 | (defcustom rails/webserver-bundle/addr "127.0.0.1" 19 | "Webserver defaut bind address." 20 | :type 'string 21 | :group 'rails) 22 | 23 | (defvar rails/webserver-bundle/process-type nil) 24 | (defvar rails/webserver-bundle/process-env nil) 25 | (defvar rails/webserver-bundle/process-port nil) 26 | (defvar rails/webserver-bundle/process-addr nil) 27 | 28 | ;;; --------------------------------------------------------- 29 | ;;; - Functions 30 | ;;; 31 | 32 | (defun rails/webserver-bundle/started-p () 33 | (get-buffer-process (get-buffer rails/webserver-bundle/buffer-name))) 34 | 35 | (defun rails/webserver-bundle/type-p (type) 36 | (when (stringp type) 37 | (string= rails/webserver-bundle/default-type type))) 38 | 39 | (defun rails/webserver-bundle/set-default-type (type) 40 | (setq rails/webserver-bundle/default-type type)) 41 | 42 | (defun rails/webserver-bundle/make-server-command (type port env addr) 43 | (cond 44 | ((string= "thin" type) 45 | (cons type 46 | (format "-p %s -e %s start" 47 | port 48 | env))) 49 | (t 50 | (cons rails/ruby/command 51 | (format "script/server %s -b %s -p %s -e %s" 52 | type 53 | addr 54 | port 55 | env))))) 56 | 57 | (defun rails/webserver-bundle/sentinel-proc (proc msg) 58 | (let ((env rails/webserver-bundle/process-env) 59 | (port rails/webserver-bundle/process-port) 60 | (type rails/webserver-bundle/process-type) 61 | (addr rails/webserver-bundle/process-addr)) 62 | (when (memq (process-status proc) '(exit signal)) 63 | (rails/proxy/down-tunnel-if-need port) 64 | (setq rails/webserver-bundle/process-env nil) 65 | (setq rails/webserver-bundle/process-port nil) 66 | (setq rails/webserver-bundle/process-type nil) 67 | (setq rails/webserver-bundle/process-addr nil) 68 | (setq msg (format "stopped (%s)" msg))) 69 | (rails/notify 70 | (replace-regexp-in-string 71 | "\n" "" 72 | (format "%s (%s) %s:%s %s" 73 | (capitalize type) 74 | env 75 | addr 76 | port 77 | msg)) 78 | :notice))) 79 | 80 | (defun rails/webserver-bundle/start (root type env port addr) 81 | (let ((proc (get-buffer-process rails/webserver-bundle/buffer-name))) 82 | (if proc 83 | (rails/notify "Only one instance of rails/webserver allowed.") 84 | (in-directory root 85 | (let* ((cmd-alist (rails/webserver-bundle/make-server-command type port env addr)) 86 | (proc (rails/proxy/shell-command root 87 | (car cmd-alist) 88 | rails/webserver-bundle/buffer-name 89 | (car cmd-alist) 90 | (cdr cmd-alist)))) 91 | (when (processp proc) 92 | (rails/runner/prepare-buffer proc) 93 | (rails/proxy/up-tinnel-if-need root port) 94 | (set-process-sentinel proc 'rails/webserver-bundle/sentinel-proc) 95 | (setq rails/webserver-bundle/process-env env) 96 | (setq rails/webserver-bundle/process-type type) 97 | (setq rails/webserver-bundle/process-port port) 98 | (setq rails/webserver-bundle/process-addr addr) 99 | (rails/notify (format "%s (%s) starting at %s:%s" 100 | (capitalize type) 101 | env 102 | addr 103 | port) 104 | :notice))))))) 105 | 106 | (defun rails/webserver-bundle/stop (root) 107 | "Stop the WebServer process." 108 | (let ((proc (get-buffer-process rails/webserver-bundle/buffer-name))) 109 | (when proc (kill-process proc t)))) 110 | 111 | ;;; --------------------------------------------------------- 112 | ;;; - Interactives 113 | ;;; 114 | 115 | (defun rails/webserver-bundle/toggle () 116 | (interactive) 117 | (when-bind (root (rails/root)) 118 | (if (rails/webserver-bundle/started-p) 119 | (rails/webserver-bundle/stop root) 120 | (rails/webserver-bundle/start root 121 | rails/webserver-bundle/default-type 122 | rails/default-environment 123 | rails/webserver-bundle/port 124 | rails/webserver-bundle/addr)))) 125 | 126 | (defun rails/webserver-bundle/run-with-env (&optional env port) 127 | (interactive) 128 | (unless (rails/webserver-bundle/started-p) 129 | (when-bind (root (rails/root)) 130 | (unless env 131 | (setq env (rails/completing-read "Run with environment" 132 | (rails/environments root) 133 | t 134 | rails/default-environment))) 135 | (unless port 136 | (setq port (rails/completing-read "and port" 137 | nil 138 | nil 139 | (format "%s" rails/webserver-bundle/port))) 140 | (when (zerop (string-to-number port)) 141 | (setq port rails/webserver-bundle/port))) 142 | (rails/webserver-bundle/start root 143 | rails/webserver-bundle/default-type 144 | env 145 | port 146 | rails/webserver-bundle/addr)))) 147 | 148 | ;;; --------------------------------------------------------- 149 | ;;; - Bundle 150 | ;;; 151 | 152 | (rails/defbundle "Webserver" 153 | (:keys 154 | (("w s" 'rails/webserver-bundle/toggle) 155 | ("w S" 'rails/webserver-bundle/run-with-env))) 156 | 157 | ;;; --------------------------------------------------------- 158 | ;;; - Menu 159 | ;;; 160 | 161 | (let ((map (make-sparse-keymap))) 162 | (dolist (type rails/webserver-bundle/types) 163 | (define-key map 164 | (vector (string-ext/safe-symbol type)) 165 | (list 'menu-item 166 | (capitalize type) 167 | `(lambda () (interactive) (rails/webserver-bundle/set-default-type ,type)) 168 | :button (cons :radio `(rails/webserver-bundle/type-p ,type))))) 169 | (define-keys map 170 | ([separator] (cons "--" "--")) 171 | ([run] (list 'menu-item 172 | "Run with Environment and Port" 173 | 'rails/webserver-bundle/run-with-env 174 | :enable '(not (rails/webserver-bundle/started-p)))) 175 | ([toggle] (cons "Toggle Start/Stop" 'rails/webserver-bundle/toggle))) 176 | (rails/bundles/add-to-bundles-menu "WebServer" map))) 177 | 178 | -------------------------------------------------------------------------------- /core-ext.el: -------------------------------------------------------------------------------- 1 | ;;; core-ext.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (defmacro* when-bind ((var expr) &rest body) 26 | "Binds VAR to the result of EXPR. 27 | If EXPR is not nil exeutes BODY. 28 | 29 | (when-bind (var (func foo)) 30 | (do-somth (with var)))." 31 | `(let ((,var ,expr)) 32 | (when ,var 33 | ,@body))) 34 | 35 | (defmacro define-keys (key-map &rest key-funcs) 36 | "Define key bindings for KEY-MAP (create KEY-MAP, if it does 37 | not exist." 38 | `(progn 39 | (unless (boundp ',key-map) 40 | (setf ,key-map (make-keymap))) 41 | ,@(mapcar 42 | #'(lambda (key-func) 43 | `(define-key ,key-map ,(first key-func) ,(second key-func))) 44 | key-funcs) 45 | ,key-map)) 46 | 47 | (defmacro funcs-chain (&rest list-of-funcs) 48 | `(lambda(it) 49 | (dolist (l (quote ,list-of-funcs)) 50 | (setq it (funcall l it))) 51 | it)) 52 | 53 | (defmacro in-directory (dir &rest body) 54 | `(let ((default-directory ,dir)) 55 | ,@body)) 56 | 57 | (provide 'core-ext) -------------------------------------------------------------------------------- /files-ext.el: -------------------------------------------------------------------------------- 1 | ;;; files-ext.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | (require 'string-ext) 27 | 28 | 29 | (defun files-ext/file-special-p (file) 30 | (let ((file (file-name-nondirectory file))) 31 | (or (string-match "^[.#~]" file) 32 | (string-match "[#~]$" file)))) 33 | 34 | (defun files-ext/file-in-directory-p (dir file) 35 | (string-ext/start-p (expand-file-name file) 36 | (expand-file-name dir))) 37 | 38 | (defun files-ext/file-in-directories-p (dir-list file) 39 | (loop for dir in dir-list 40 | when (files-ext/file-in-directory-p dir file) 41 | return dir)) 42 | 43 | (defun files-ext/write-string-to-file (file string) 44 | "Write a string to a file (erasing the previous content)." 45 | (write-region string nil file)) 46 | 47 | (defun files-ext/read-from-file (file-name) 48 | "Read sexpr from a file named FILE-NAME." 49 | (with-temp-buffer 50 | (insert-file-contents file-name) 51 | (goto-char (point-min)) 52 | (unless (string-ext/empty-p (buffer-substring-no-properties (point-min) (point-max))) 53 | (read (current-buffer))))) 54 | 55 | (defun files-ext/directory-files-recursive (dir regexp) 56 | (let ((dir-stack '()) 57 | (files-stack '()) 58 | (res '()) 59 | (dir (if (string-ext/end-p dir "/") 60 | dir 61 | (concat dir "/"))) 62 | cur-dir 63 | fst 64 | it 65 | done 66 | filter-list) 67 | (push "" dir-stack) 68 | (while (car dir-stack) 69 | (setq done t) 70 | (setq cur-dir (car dir-stack)) 71 | (setq filter-list (directory-files (concat dir cur-dir) nil)) 72 | 73 | (setq filter-list (remove-if '(lambda(i) 74 | (and 75 | (not (file-directory-p (concat dir cur-dir i))) 76 | (not (string-match regexp i)))) 77 | filter-list)) 78 | ;; (message-box "%S" filter-list) 79 | ;; (push (directory-files (concat dir cur-dir) nil regexp) files-stack) 80 | (push filter-list files-stack) 81 | (while (and (> (length files-stack) 0) 82 | done) 83 | (setq fst (pop files-stack)) 84 | (while (and (car fst) 85 | done) 86 | (setq it (car fst)) 87 | (setq fst (cdr fst)) 88 | (unless (files-ext/file-special-p it) 89 | (if (file-directory-p (concat dir cur-dir it)) 90 | (progn 91 | (push fst files-stack) 92 | (push (concat cur-dir it "/") dir-stack) 93 | (setq done nil)) 94 | (progn 95 | (setq res (append res (list (concat cur-dir it)))))))) 96 | (when done 97 | (pop dir-stack) 98 | (setq cur-dir (car dir-stack))))) 99 | res)) 100 | 101 | (provide 'files-ext) 102 | -------------------------------------------------------------------------------- /inflections.el: -------------------------------------------------------------------------------- 1 | ;;; inflections.el --- inflection support. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Howard Yeh 7 | 8 | ;; Keywords: ruby rails languages oop 9 | ;; $URL: svn+ssh://rubyforge.org/var/svn/emacs-rails/trunk/inflections.el $ 10 | ;; $Id: inflections.el 216 2007-11-02 20:48:22Z dimaexe $ 11 | 12 | ;;; License 13 | 14 | ;; This program is free software; you can redistribute it and/or 15 | ;; modify it under the terms of the GNU General Public License 16 | ;; as published by the Free Software Foundation; either version 2 17 | ;; of the License, or (at your option) any later version. 18 | 19 | ;; This program is distributed in the hope that it will be useful, 20 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | ;; GNU General Public License for more details. 23 | 24 | ;; You should have received a copy of the GNU General Public License 25 | ;; along with this program; if not, write to the Free Software 26 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 | 28 | ;;; Code: 29 | 30 | (require 'cl) 31 | 32 | (require 'string-ext) 33 | 34 | (defvar inflection-singulars nil) 35 | (defvar inflection-plurals nil) 36 | (defvar inflection-irregulars nil) 37 | (defvar inflection-uncountables nil) 38 | 39 | (defmacro define-inflectors (&rest specs) 40 | `(progn 41 | ,@(loop for (type . rest) in specs collect 42 | (case type 43 | (:singular `(push ',rest inflection-singulars)) 44 | (:plural `(push ',rest inflection-plurals)) 45 | (:irregular `(push ',rest inflection-irregulars)) 46 | (:uncountable `(setf inflection-uncountables 47 | (append ',rest inflection-uncountables))))))) 48 | 49 | (define-inflectors 50 | (:plural "$" "s") 51 | (:plural "s$" "s") 52 | (:plural "\\(ax\\|test\\)is$" "\\1es") 53 | (:plural "\\(octop\\|vir\\)us$" "\\1i") 54 | (:plural "\\(alias\\|status\\)$" "\\1es") 55 | (:plural "\\(bu\\)s$" "\\1ses") 56 | (:plural "\\(buffal\\|tomat\\)o$" "\\1oes") 57 | (:plural "\\([ti]\\)um$" "\\1a") 58 | (:plural "sis$" "ses") 59 | (:plural "\\(?:\\([^f]\\)fe\\|\\([lr]\\)f\\)$" "\\1\\2ves") 60 | (:plural "\\(hive\\)$" "\\1s") 61 | (:plural "\\([^aeiouy]\\|qu\\)y$" "\\1ies") 62 | (:plural "\\(x\\|ch\\|ss\\|sh\\)$" "\\1es") 63 | (:plural "\\(matr\\|vert\\|ind\\)ix\\|ex$" "\\1ices") 64 | (:plural "\\([m\\|l]\\)ouse$" "\\1ice") 65 | (:plural "^\\(ox\\)$" "\\1en") 66 | (:plural "\\(quiz\\)$" "\\1zes") 67 | 68 | (:singular "s$" "") 69 | (:singular "\\(n\\)ews$" "\\1ews") 70 | (:singular "\\([ti]\\)a$" "\\1um") 71 | (:singular "\\(\\(a\\)naly\\|\\(b\\)a\\|\\(d\\)iagno\\|\\(p\\)arenthe\\|\\(p\\)rogno\\|\\(s\\)ynop\\|\\(t\\)he\\)ses$" "\\1\\2sis") 72 | (:singular "\\(^analy\\)ses$" "\\1sis") 73 | (:singular "\\([^f]\\)ves$" "\\1fe") 74 | (:singular "\\(hive\\)s$" "\\1") 75 | (:singular "\\(tive\\)s$" "\\1") 76 | (:singular "\\([lr]\\)ves$" "\\1f") 77 | (:singular "\\([^aeiouy]\\|qu\\)ies$" "\\1y") 78 | (:singular "\\(s\\)eries$" "\\1eries") 79 | (:singular "\\(m\\)ovies$" "\\1ovie") 80 | (:singular "\\(x\\|ch\\|ss\\|sh\\)es$" "\\1") 81 | (:singular "\\([m\\|l]\\)ice$" "\\1ouse") 82 | (:singular "\\(bus\\)es$" "\\1") 83 | (:singular "\\(o\\)es$" "\\1") 84 | (:singular "\\(shoe\\)s$" "\\1") 85 | (:singular "\\(cris\\|ax\\|test\\)es$" "\\1is") 86 | (:singular "\\(octop\\|vir\\)i$" "\\1us") 87 | (:singular "\\(alias\\|status\\)es$" "\\1") 88 | (:singular "^\\(ox\\)en" "\\1") 89 | (:singular "\\(vert\\|ind\\)ices$" "\\1ex") 90 | (:singular "\\(matr\\)ices$" "\\1ix") 91 | (:singular "\\(quiz\\)zes$" "\\1") 92 | 93 | (:irregular "stratum" "strate") 94 | (:irregular "syllabus" "syllabi") 95 | (:irregular "radius" "radii") 96 | (:irregular "addendum" "addenda") 97 | (:irregular "cactus" "cacti") 98 | (:irregular "child" "children") 99 | (:irregular "corpus" "corpora") 100 | (:irregular "criterion" "criteria") 101 | (:irregular "datum" "data") 102 | (:irregular "genus" "genera") 103 | (:irregular "man" "men") 104 | (:irregular "medium" "media") 105 | (:irregular "move" "moves") 106 | (:irregular "person" "people") 107 | (:irregular "man" "men") 108 | (:irregular "child" "children") 109 | (:irregular "sex" "sexes") 110 | (:irregular "move" "moves") 111 | 112 | (:uncountable "dashboard" "equipment" "information" "rice" "money" "species" "series" "fish" "sheep" "news")) 113 | 114 | (defun singularize-string (str) 115 | (when (stringp str) 116 | (or (car (member str inflection-uncountables)) 117 | (caar (member* (downcase str) inflection-irregulars :key 'cadr :test 'equal)) 118 | (loop for (from to) in inflection-singulars 119 | for singular = (string-ext/string=~ from str (sub to)) 120 | when singular do (return singular)) 121 | str))) 122 | 123 | (defun pluralize-string (str) 124 | (when (stringp str) 125 | (or (car (member str inflection-uncountables)) 126 | (cadar (member* (downcase str) inflection-irregulars :key 'car :test 'equal)) 127 | (loop for (from to) in inflection-plurals 128 | for plurals = (string-ext/string=~ from str (sub to)) 129 | when plurals do (return plurals)) 130 | str))) 131 | 132 | (provide 'inflections) 133 | -------------------------------------------------------------------------------- /list-ext.el: -------------------------------------------------------------------------------- 1 | ;;; list-ext.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | 27 | (defun list-ext/uniq (list) 28 | "Return a list of unique elements." 29 | (let ((result '())) 30 | (dolist (elem list) 31 | (when (not (member elem result)) 32 | (push elem result))) 33 | (nreverse result))) 34 | 35 | (defun list-ext/group-by (list func &optional sort) 36 | (let ((res '())) 37 | (dolist (it list) 38 | (let* ((key (funcall func it)) 39 | (res-key (assoc key res))) 40 | (if res-key 41 | (push it (cadr res-key)) 42 | (add-to-list 'res (list key (list it)))))) 43 | (setq res 44 | (mapcar 45 | #'(lambda(it) 46 | (list (car it) (nreverse (cadr it)))) 47 | (nreverse res))) 48 | (when sort 49 | (setq res (sort* res sort :key 'car))) 50 | res)) 51 | 52 | (defun list-ext/options-value (key list) 53 | (cadr (memq key list))) 54 | 55 | (defalias 'opt-val 'list-ext/options-value) 56 | 57 | (defun list-ext/swap-tail (key list) 58 | (let* ((list-len (length list)) 59 | (tail (member key list)) 60 | (beg (- list-len (length tail))) 61 | (i 0)) 62 | (when tail 63 | (while (not (zerop (+ beg 1))) 64 | (add-to-list 'tail (nth i list) t) 65 | (decf beg) 66 | (incf i)) 67 | tail))) 68 | 69 | (provide 'list-ext) 70 | -------------------------------------------------------------------------------- /rails-anything.el: -------------------------------------------------------------------------------- 1 | ;;; rails-anything.el --- anything integration 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | 27 | ;; load anything from rails-reloaded/vendor directory unless they loaded. 28 | (unless (featurep 'anything) 29 | (load (locate-library "vendor/anything"))) 30 | 31 | (defvar anything-rails-current-buffer nil) 32 | (defvar anything-rails-current-root nil) 33 | 34 | (defvar anything-c-source-rails-associated 35 | '((name . "Goto from current to") 36 | (init . rails/anything/init-func) 37 | (candidates . rails/anything/associated-func) 38 | (candidate-number-limit . 100) 39 | (type . file))) 40 | 41 | (defun rails/anything/load-triggers () 42 | (loop for triggers in rails/bundles/trigger-list 43 | collect 44 | (let ((name (cadr triggers)) 45 | (its (cddr triggers)) 46 | result) 47 | (add-to-list 'result (cons 'name name)) 48 | (add-to-list 'result (cons 'init 'rails/anything/init-func)) 49 | (unless (find 'candidate-number-limit its :key 'car) 50 | (add-to-list 'result (cons 'candidate-number-limit 100))) 51 | (dolist (tr its) 52 | (add-to-list 'result tr)) 53 | result))) 54 | 55 | (defun rails/anything/hightlight-current (current) 56 | (setq current (concat ">" current "<")) 57 | (setq current (propertize current 'face 'font-lock-keyword-face))) 58 | 59 | (defun rails/anything/init-func () 60 | (setq anything-rails-current-buffer 61 | (current-buffer)) 62 | (setq anything-rails-current-root 63 | (rails/root))) 64 | 65 | (defun rails/anything/make-filename (root item) 66 | (concat root (rails/resource-item-file item))) 67 | 68 | (defun rails/anything/find-file-by-item (item) 69 | (with-current-buffer anything-rails-current-buffer 70 | (rails/resources/find-file-by-item (rails/root) item))) 71 | 72 | (defun rails/anything/associated-func () 73 | (let ((buf anything-rails-current-buffer)) 74 | (with-current-buffer buf 75 | (let ((root (rails/root)) 76 | items result) 77 | (setq items (rails/resources/get-associated-items root rails/current-buffer)) 78 | (setq items 79 | (list-ext/group-by 80 | items 81 | '(lambda(i) (rails/resource-item-resource-group (car i))) 82 | 'string<)) 83 | (dolist (i items) 84 | (dolist (ii (cadr i)) 85 | (if (and (= 1 (length ii)) 86 | (not (rails/resource-options-p 87 | (rails/resources/find (rails/resource-item-resource-type (car ii))) 88 | 'expand-in-menu))) 89 | (progn 90 | (add-to-list 'result (cons (rails/resource-item-resource-title (car ii)) 91 | (car ii)) t)) 92 | (progn 93 | (dolist (it ii) 94 | (add-to-list 'result (cons 95 | (concat (rails/resource-item-resource-title it) 96 | " " 97 | (rails/resource-item-title it)) 98 | it) t)))))) 99 | (setq result 100 | (mapcar 101 | '(lambda (i) 102 | (let ((title (car i))) 103 | (when (string= (rails/resource-item-file (cdr i)) 104 | (rails/resource-buffer-file rails/current-buffer)) 105 | (setq title (rails/anything/hightlight-current title))) 106 | (cons title 107 | (rails/anything/make-filename root (cdr i))))) 108 | result)) 109 | result)))) 110 | 111 | (defun rails/anything/associated () 112 | (interactive) 113 | (rails/with-current-buffer 114 | (let ((root (rails/root))) 115 | (anything (list anything-c-source-rails-associated))))) 116 | 117 | (defun rails/anything/goto-resource-items-alist (root buffer resource) 118 | (let ((dir (rails/resource-dir resource)) 119 | (type (rails/resource-type resource)) 120 | (comp-alist (rails/resources/get-compared-resources-alist resource)) 121 | file-mask files item) 122 | (setq file-mask 123 | (cdr (find resource comp-alist :key 'car))) 124 | (setq files (rails/directory-files-recursive root dir file-mask)) 125 | (setq files 126 | (loop for file in files 127 | for alist = (rails/resources/compare-file-by-compared-alist (concat dir file) 128 | comp-alist) 129 | for res = (car alist) 130 | for res-name = (cdr alist) 131 | when (eq (rails/resource-type res) type) 132 | collect 133 | (make-rails/resource-item 134 | :file (concat dir file) 135 | :title res-name 136 | :resource-type (rails/resource-type resource) 137 | :resource-group (rails/resource-group resource) 138 | :resource-title res-name))) 139 | (let ((suffix (rails/resource-file-suffix resource)) 140 | (ext (rails/resource-file-ext resource))) 141 | (mapcar 142 | (lambda (i) 143 | (let ((title (concat (rails/resource-item-title i) suffix ext)) 144 | (file (rails/anything/make-filename root i))) 145 | (when (string= file (buffer-file-name buffer)) 146 | (setq title (rails/anything/hightlight-current title))) 147 | (cons title file))) 148 | files)))) 149 | 150 | (defun rails/anything/goto (&optional resource-type) 151 | (interactive) 152 | (rails/with-root (buffer-file-name) 153 | (let ((root (rails/root)) 154 | (resources (if resource-type 155 | (list (rails/resources/find resource-type)) 156 | rails/resources/list-defined)) 157 | result) 158 | (loop for res in resources 159 | for cand = (rails/anything/goto-resource-items-alist 160 | root 161 | (current-buffer) 162 | res) 163 | do 164 | (add-to-list 'result 165 | (list (cons 'name (rails/resource-title res)) 166 | (cons 'init 'rails/anything/init-func) 167 | (cons 'candidates cand) 168 | (cons 'candidate-number-limit 100) 169 | (cons 'type 'file)) 170 | t)) 171 | (anything result)))) 172 | 173 | (defun rails/anything/run-with-pattern (pattern) 174 | (anything (rails/anything/load-triggers) pattern)) 175 | 176 | ;;; --------------------------------------------------------- 177 | ;;; - advice anything sources 178 | ;;; 179 | (defadvice anything-normalize-sources (around rails-anything activate) 180 | (let ((sources ad-do-it)) 181 | (when (rails/root) 182 | (let ((result (rails/anything/load-triggers))) 183 | (dolist (it sources) 184 | (add-to-list 'result it t)) 185 | (setq ad-return-value result))))) 186 | 187 | (provide 'rails-anything) 188 | -------------------------------------------------------------------------------- /rails-autoload.el: -------------------------------------------------------------------------------- 1 | ;;; rails-autoload.el --- minor mode for editing RubyOnRails code. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;; Keywords: ruby rails languages 9 | 10 | ;;; License 11 | 12 | ;; This program is free software; you can redistribute it and/or 13 | ;; modify it under the terms of the GNU General Public License 14 | ;; as published by the Free Software Foundation; either version 2 15 | ;; of the License, or (at your option) any later version. 16 | 17 | ;; This program is distributed in the hope that it will be useful, 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;; GNU General Public License for more details. 21 | 22 | ;; You should have received a copy of the GNU General Public License 23 | ;; along with this program; if not, write to the Free Software 24 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | ;;; Code: 27 | 28 | (require 'cl) 29 | 30 | (defun rails/bytecompile () 31 | "Byte compile rails-reloaded library." 32 | (interactive) 33 | (require 'rails-reloaded) 34 | (let* ((rails/disabled-bundles-group-list nil) 35 | (func '(lambda (file) 36 | (unless (string= (file-name-nondirectory file) 37 | "rails-bytecompile.el") 38 | (byte-compile-file file)))) 39 | (path (file-name-directory (locate-library "rails-reloaded")))) 40 | (mapc func (directory-files path t "\\.el\\'")) 41 | (mapc func (directory-files (concat path "bundles/") t "\\.el\\'")) 42 | (mapc func (directory-files (concat path "vendor/") t "\\.el\\'")))) 43 | 44 | (defun rails/selftest () 45 | "Run unit tests for rails-reloaded library." 46 | (interactive) 47 | (load-file 48 | (concat 49 | (file-name-directory 50 | (locate-library "rails-reloaded")) 51 | "tests/all.el")) 52 | (message (format "rails/selftest: done"))) 53 | 54 | (defun rails/tags-create () 55 | (interactive) 56 | (let ((path (file-name-directory (locate-library "rails-reloaded")))) 57 | (let ((default-directory path)) 58 | (shell-command (concat "etags " path "*.el")) 59 | (shell-command (concat "etags -a " path "bundles/*.el")) 60 | (visit-tags-table (format "%s/TAGS" path))))) 61 | 62 | (defun rails/load-verdor-lib (lib file) 63 | (unless (featurep (intern file)) 64 | (let ((path (file-name-directory (locate-library "rails-reloaded")))) 65 | (load-library (concat path "vendor/" lib "/" file)))) 66 | t) 67 | 68 | ;;; --------------------------------------------------------- 69 | ;;; - Setup autoload 70 | ;;; 71 | (defun rails/find-file-hook () 72 | "Activate `rails-minor-mode' if opened file inside RAILS_ROOT." 73 | (when (rails/root (buffer-file-name)) 74 | (rails/initialize-for-current-buffer))) 75 | 76 | (autoload 'rails/initialize-for-current-buffer "rails-reloaded" nil t) 77 | (autoload 'rails/root "rails-lib" nil t) 78 | (add-hook 'find-file-hooks 'rails/find-file-hook) 79 | 80 | ;;; --------------------------------------------------------- 81 | ;;; - Setup modes and encoding 82 | ;;; 83 | (defun rails/setup-auto-modes-alist () 84 | "Added default ruby/rails filetypes to `auto-mode-alist' if not defined." 85 | (let ((modes 86 | '((ruby-mode "\\.rb\\'" "\\.rake\\'" "Rakefile\\'" "\\.rjs\\'" "\\.rxml\\'" "\\.builder\\'") 87 | (eruby-html-mumamo "\\.erb\\'" "\\.rhtml\\'")))) 88 | (dolist (mode modes) 89 | (loop for regexp in (cdr mode) 90 | for allow = (and (not (find regexp auto-mode-alist :key 'car :test 'string=)) 91 | (fboundp (car mode))) 92 | when allow 93 | do 94 | (setq auto-mode-alist (cons (cons regexp (car mode)) auto-mode-alist)))))) 95 | 96 | (defun rails/setup-auto-coding-alist () 97 | (when (eq system-type 'windows-nt) 98 | (dolist (re '("\\.[e]?rb\\'" "\\.rake\\'" "Rakefile\\'" "\\.rjs\\'" "\\.rxml\\'" "\\.builder\\'" "\\.rhtml\\'" "\\.yml\\'")) 99 | (setq auto-coding-alist (cons (cons re 'utf-8) auto-coding-alist))))) 100 | 101 | (rails/setup-auto-modes-alist) 102 | (rails/setup-auto-coding-alist) 103 | 104 | ;;; --------------------------------------------------------- 105 | ;;; - Mumamo fixes 106 | ;;; 107 | (eval-after-load 'mumamo 108 | '(progn 109 | (add-to-list 'mumamo-survive 'rails-minor-mode) 110 | (put 'rails/current-buffer 'permanent-local t))) 111 | 112 | ;;; --------------------------------------------------------- 113 | ;;; - snippets 114 | ;;; 115 | (when (fboundp 'yas/minor-mode) 116 | (let ((dir 117 | (concat 118 | (file-name-directory (locate-library "rails-reloaded")) 119 | "snippets"))) 120 | (yas/load-directory dir))) 121 | 122 | (provide 'rails-autoload) 123 | -------------------------------------------------------------------------------- /rails-bundles.el: -------------------------------------------------------------------------------- 1 | ;;; rails-bundles.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | (require 'rails-resources) 27 | 28 | (defvar rails/bundles/disabled-list nil) 29 | (defvar rails/bundles/loaded-list nil) 30 | (defvar rails/bundles/loaded-p nil) 31 | (defvar rails/bundles/trigger-list nil) 32 | (defvar rails/bundles/after-load-list nil) 33 | 34 | (defconst rails/bundles/file-regexp "^rails-\\(.*\\)-bundle\.el$") 35 | (defconst rails/bundles/name-fmt "rails/%s-bundle/name") 36 | 37 | (defun rails/bundles/enabled-p (title) 38 | (not (memq (string-ext/safe-symbol title) rails/bundles/disabled-list))) 39 | 40 | (defun rails/bundles/toggle-enabled (title) 41 | (let ((sym (string-ext/safe-symbol title))) 42 | (if (rails/bundles/enabled-p title) 43 | (progn 44 | (add-to-list 'rails/bundles/disabled-list sym nil 'eq) 45 | nil) 46 | (setq rails/bundles/disabled-list (delete sym rails/bundles/disabled-list)) 47 | t))) 48 | 49 | (defun rails/bundles/load () 50 | (unless rails/bundles/loaded-p 51 | (let* ((bdir (concat 52 | (file-name-directory (locate-library "rails-reloaded")) 53 | "bundles")) 54 | (files (directory-files bdir nil rails/bundles/file-regexp))) 55 | (dolist (file files) 56 | (load (concat bdir "/" (file-name-sans-extension file))) 57 | (let* ((sym (intern 58 | (string-ext/string=~ rails/bundles/file-regexp file $1))) 59 | (title (symbol-value 60 | (intern (format rails/bundles/name-fmt sym))))) 61 | (add-to-list 'rails/bundles/loaded-list (cons sym title)) 62 | (rails/bundles/add-to-loaded-menu title)))) 63 | (mapc 'funcall rails/bundles/after-load-list) 64 | (setq rails/bundles/loaded-p t))) 65 | 66 | (defun rails/bundles/reload () 67 | (interactive) 68 | (setq rails/bundles/loaded-list nil) 69 | (setq rails/bundles/loaded-p nil) 70 | (setq rails/bundles/trigger-list nil) 71 | (setq rails/bundles/after-load-list nil) 72 | (rails/resources/clear) 73 | (rails/bundles/load)) 74 | 75 | (defun rails/bundles/add-to-loaded-menu (title) 76 | (unless (lookup-key rails-minor-mode-map 77 | [menu-bar rails bundles-loaded]) 78 | (define-key-after rails-minor-mode-map 79 | [menu-bar rails bundles-loaded] 80 | (cons "Loaded Bundles" (make-sparse-keymap)) 81 | 'env)) 82 | (define-key rails-minor-mode-map 83 | (merge 'vector [menu-bar rails bundles-loaded] 84 | (list (string-ext/safe-symbol title)) 85 | 'eq) 86 | (list 'menu-item title 87 | `(lambda() 88 | (interactive) 89 | (rails/bundles/toggle-enabled ,title) 90 | (rails/reload-all)) 91 | :button (cons :toggle (rails/bundles/enabled-p title))))) 92 | 93 | (defun rails/bundles/add-to-bundles-menu (title menumap) 94 | (define-key-after rails-minor-mode-map 95 | (merge 'vector [menu-bar rails] (list (string-ext/safe-symbol title)) 'eq) 96 | (cons (concat title " Bundle") menumap) 97 | 'bundles-title)) 98 | 99 | (defmacro* rails/defbundle (name (&key menu keys triggers after-load-bundles) &body body) 100 | `(progn 101 | (defconst 102 | ,(intern (format rails/bundles/name-fmt (string-ext/safe-symbol name))) 103 | ,name) 104 | (when (rails/bundles/enabled-p ,name) 105 | (when ,(not (not menu)) 106 | (rails/bundles/add-to-bundles-menu 107 | ,name 108 | (let ((map (make-sparse-keymap))) 109 | (define-keys map 110 | ,@menu)))) 111 | (when ,(not (not triggers)) 112 | ,@(loop for tr in triggers 113 | collect 114 | `(add-to-list 'rails/bundles/trigger-list ',tr))) 115 | (when ,(not (not after-load-bundles)) 116 | (setq rails/bundles/after-load-list 117 | (cons ,after-load-bundles rails/bundles/after-load-list))) 118 | (when ,(not (not keys)) 119 | ,@(loop for (key func) in keys collect 120 | `(rails/define-key ,key ,func))) 121 | ,@body))) 122 | 123 | (provide 'rails-bundles) -------------------------------------------------------------------------------- /rails-compile.el: -------------------------------------------------------------------------------- 1 | ;;; rails-compile.el --- run compilation process for rails application. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;;; License 9 | 10 | ;; This program is free software; you can redistribute it and/or 11 | ;; modify it under the terms of the GNU General Public License 12 | ;; as published by the Free Software Foundation; either version 2 13 | ;; of the License, or (at your option) any later version. 14 | 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with this program; if not, write to the Free Software 22 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | 24 | ;;; Code: 25 | 26 | (require 'rails-resources) 27 | 28 | (defvar rails/compile/single-file-list '()) 29 | (defvar rails/compile/current-method-list '()) 30 | 31 | (defvar rails/compile/font-lock-keywords 32 | '(("\\([[:digit:]]+ tests\\), \\([[:digit:]]+ assertions\\), \\([[:digit:]]+ failures\\), \\([[:digit:]]+ errors\\)" 33 | (1 compilation-info-face) 34 | (2 compilation-info-face) 35 | (3 compilation-error-face) 36 | (4 compilation-error-face)) 37 | ("^\s+\\([0-9]+)\s+\\(Error\\|Failure\\):\\)" 38 | 1 compilation-error-face) 39 | ("^[.EF]+$" . compilation-info-face) 40 | ("^\\([a-z0-9_]+\\)(\\(.*\\))\\(:$\\|\n\s+\\[\\|\s+\\[\\)" 41 | (1 font-lock-function-name-face) 42 | (2 font-lock-type-face)) 43 | ("^<\\(.*\\)> \\(expected but was\\)\n<\\(.*\\)>.$" 44 | (1 font-lock-constant-face) 45 | (2 font-lock-string-face) 46 | (3 font-lock-constant-face)) 47 | ("`\\(.+\\)'" 48 | (1 font-lock-function-name-face)))) 49 | 50 | (defun rails/compile/match-error (limit) 51 | (catch 'found 52 | (while (re-search-forward "\\(?:\\[\\|^\\|\\s+\\|(\\)?\\([^ :\n\]+\\):\\([0-9]+\\)+\\b" limit t) 53 | (let ((file (match-string 1)) 54 | (root (rails/root default-directory))) 55 | (when root 56 | (unless (file-name-absolute-p file) 57 | (setq file (concat root file))) 58 | (setq file (expand-file-name file)) 59 | (when (and (file-exists-p file) 60 | (not (files-ext/file-in-directory-p (concat root "vendor/") file))) 61 | (throw 'found t))))))) 62 | 63 | (defun rails/compile/error-regexp-alist () 64 | (list 65 | (list 'rails/compile/error 'rails/compile/match-error 1 2 nil 2 1))) 66 | 67 | 68 | (define-derived-mode rails/compilation-mode compilation-mode "RCompile" 69 | "Major mode for RoR tests." 70 | (set (make-local-variable 'font-lock-keywords-only) t) 71 | (set (make-local-variable 'font-lock-keywords) nil) 72 | ;; (set (make-local-variable 'font-lock-defaults) nil) ; to enable fontify by ansi-color 73 | ;; (set (make-local-variable 'font-lock-defaults) 74 | ;; '(rails/compile/font-lock-keywords t)) 75 | (set (make-local-variable 'compilation-mode-font-lock-keywords) 76 | rails/compile/font-lock-keywords) 77 | (set (make-local-variable 'compilation-error-regexp-alist-alist) 78 | (rails/compile/error-regexp-alist)) 79 | (set (make-local-variable 'compilation-error-regexp-alist) 80 | '(rails/compile/error))) 81 | 82 | (defun rails/compile/run (root command args) 83 | (rails/runner/run root command args :mode 'rails/compilation-mode) 84 | (setq rails/runner/after-stop-func-list 85 | '(rails/runner/popup-buffer-if-failed))) 86 | 87 | (defun rails/compile/run-file (root rails-buffer command args-pattern &optional file-pattern) 88 | (let* ((item 89 | (when rails-buffer 90 | (rails/resources/get-associated-test-item-for-buffer 91 | root 92 | rails-buffer))) 93 | (match (when file-pattern 94 | (string-ext/string=~ file-pattern 95 | (or 96 | (when item (rails/resource-item-file item)) 97 | (rails/resource-buffer-file rails-buffer)) 98 | t))) 99 | file) 100 | (cond 101 | ((and item (if file-pattern match t)) 102 | (setq file (rails/resource-item-file item)) 103 | (rails/compile/run root 104 | command 105 | (format args-pattern 106 | file))) 107 | ((and file-pattern 108 | match) 109 | (rails/compile/run root 110 | command 111 | (format args-pattern 112 | (rails/cut-root (buffer-file-name))))) 113 | (t 114 | (rails/notify "Can't run current file as a test." :error))))) 115 | 116 | (defun rails/compile/single-file () 117 | (interactive) 118 | (when-bind (root (rails/root)) 119 | (loop for func in rails/compile/single-file-list 120 | for res = (funcall func root rails/current-buffer) 121 | when res 122 | do (return res)))) 123 | 124 | (defun rails/compile/current-method () 125 | (interactive) 126 | (when-bind (root (rails/root)) 127 | (loop for func in rails/compile/current-method-list 128 | for res = (funcall func root rails/current-buffer) 129 | when res 130 | do (return res)))) 131 | 132 | (provide 'rails-compile) 133 | -------------------------------------------------------------------------------- /rails-lib.el: -------------------------------------------------------------------------------- 1 | ;;; rails-lib.el --- library functions used in rails. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;;; License 9 | 10 | ;; This program is free software; you can redistribute it and/or 11 | ;; modify it under the terms of the GNU General Public License 12 | ;; as published by the Free Software Foundation; either version 2 13 | ;; of the License, or (at your option) any later version. 14 | 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with this program; if not, write to the Free Software 22 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | 24 | ;;; Code: 25 | 26 | (require 'cl) 27 | 28 | (require 'files-ext) 29 | (require 'string-ext) 30 | (require 'list-ext) 31 | 32 | ;;; --------------------------------------------------------- 33 | ;;; - Variables 34 | ;;; 35 | 36 | (defvar rails/projects '()) 37 | 38 | 39 | (defcustom rails/search-files-in-dirs nil 40 | "Set this variable to search rails files only in them." 41 | :group 'rails 42 | :type '(repeat (directory :tag "Directory"))) 43 | 44 | 45 | ;;; --------------------------------------------------------- 46 | ;;; - rails/root functions 47 | ;;; 48 | 49 | (defun rails/root (&optional file) 50 | "Return RAILS_ROOT for FILE, if FILE not set using `buffer-file-name' or `default-directory' instead it. 51 | If RAILS_ROOT not found, return nil." 52 | (let ((file (or file 53 | (buffer-file-name) 54 | default-directory))) 55 | (unless (and rails/search-files-in-dirs 56 | (files-ext/file-in-directories-p rails/search-files-in-dirs 57 | file)) 58 | (or 59 | (rails/find-existing-root-for file) 60 | (rails/find-root-for file))))) 61 | 62 | (defmacro* rails/with-root (&optional file &body body) 63 | "If you use `rails-project:root' or functions related on it 64 | several times in a block of code, you can optimize your code by 65 | using this macro. Also, blocks of code will be executed only if 66 | rails-root exist. 67 | (rails/with-root (root) 68 | (foo root) 69 | (bar (rails-core:file \"some/path\"))) 70 | " 71 | (let ((root (gensym))) 72 | `(let ((,root (rails/root ,file))) 73 | (when ,root 74 | (flet ((rails/root (&optional file) ,root)) 75 | ,@body))))) 76 | 77 | (defmacro rails/when-root (file &rest body) 78 | `(when (rails/root ,file) 79 | ,@body)) 80 | 81 | (defun rails/cut-root (file) 82 | (if (file-name-absolute-p file) 83 | (string-ext/cut file (rails/root file) :begin) 84 | file)) 85 | 86 | (defun rails/find-existing-root-for(file) 87 | "Search RAILS_ROOT for FILE in `rails/projects' and return, 88 | else return nil" 89 | (let ((file (expand-file-name file)) 90 | (project (car rails/projects)) 91 | (projects (cdr rails/projects)) 92 | (root)) 93 | (while (and (not root) 94 | project) 95 | (if (string-ext/start-p file project) 96 | (setq root project) 97 | (progn 98 | (setq project (car projects)) 99 | (setq projects (cdr projects))))) 100 | root)) 101 | 102 | (defun rails/find-root-for (file) 103 | "Return RAILS_ROOT if FILE is a part of a Rails application, 104 | else return nil" 105 | (when file 106 | (let ((curdir (file-name-directory (expand-file-name file))) 107 | (max 10) 108 | (found nil)) 109 | (while (and (not found) (> max 0)) 110 | (progn 111 | (if (file-exists-p (concat curdir "config/environment.rb")) 112 | (progn 113 | (setq found t)) 114 | (progn 115 | (setq curdir (concat curdir "../")) 116 | (setq max (- max 1)))))) 117 | (when found 118 | (let ((root (expand-file-name curdir))) 119 | (setq rails/projects (list-ext/uniq (add-to-list 'rails/projects root))) 120 | root))))) 121 | 122 | (defmacro rails/with-current-buffer (&rest body) 123 | `(if (and (rails/resource-buffer-p rails/current-buffer) 124 | (rails/resource-buffer-title rails/current-buffer)) 125 | (rails/with-root (buffer-file-name) 126 | ,@body) 127 | (rails/notify "Curent buffer it's not a rails resource." :error))) 128 | 129 | ;;; --------------------------------------------------------- 130 | ;;; - Rails files functions 131 | ;;; 132 | 133 | (defun rails/file-exist-p (root file) 134 | (file-exists-p (concat root file))) 135 | 136 | (defun rails/file-directory-p (root dir) 137 | (file-directory-p (concat root dir))) 138 | 139 | (defun rails/find-file (root file) 140 | (find-file (concat root file))) 141 | 142 | (defun rails/directory-files (root directory &optional full match nosort) 143 | (let ((fullname (concat root "/" directory))) 144 | (when (file-directory-p fullname) 145 | (loop for file in (directory-files fullname full match nosort) 146 | for allow = (not (files-ext/file-special-p file)) 147 | when allow 148 | collect file)))) 149 | 150 | (defun rails/directory-files-recursive (root directory &optional regexp) 151 | (let ((fullname (concat root "/" directory))) 152 | (when (file-directory-p fullname) 153 | (loop for file in (files-ext/directory-files-recursive 154 | fullname regexp) 155 | for allow = (not (files-ext/file-special-p file)) 156 | when allow 157 | collect file)))) 158 | 159 | ;;; --------------------------------------------------------- 160 | ;;; - Menu functions 161 | ;;; 162 | 163 | (defun rails/display-menu (title menu &optional force-ido) 164 | (let ((func 165 | (cond 166 | ((and window-system 167 | (not force-ido) 168 | (eq rails/display-menu-method 'popup)) 169 | 'rails/display-menu-using-popup) 170 | (t 171 | 'rails/display-menu-using-ido)))) 172 | (funcall func title menu))) 173 | 174 | (defun rails/display-menu-using-popup (title menu) 175 | (add-to-list 'menu title) 176 | (x-popup-menu (list '(300 50) (get-buffer-window (current-buffer))) 177 | (list title 178 | menu))) 179 | 180 | (defun rails/display-menu-using-ido (title menu &optional dont-require-match) 181 | (let (choices value) 182 | (dolist (item menu) ; filter 183 | (let ((name (car item)) 184 | (goto (cdr item))) 185 | (unless (and (stringp goto) 186 | (string= "--" goto)) 187 | (add-to-list 'choices (cons name goto) t)))) 188 | (when-bind (value 189 | (ido-completing-read (format "%s: " title) 190 | (mapcar 'car choices) 191 | nil 192 | (not dont-require-match))) 193 | (cdr (find value choices :test 'string= :key 'car))))) 194 | 195 | (defun rails/completing-read (title &optional list require default history) 196 | (let ((title (if default 197 | (format "%s [%s]: " title default) 198 | (format "%s: " title)))) 199 | (completing-read title list nil require nil history default))) 200 | 201 | (defun rails/button-action (ov) 202 | (when (overlayp ov) 203 | (let ((file-name (overlay-get ov :file-name)) 204 | (func (overlay-get ov :func)) 205 | (line (overlay-get ov :line))) 206 | (cond 207 | (func 208 | (funcall func ov)) 209 | ((and file-name (file-exists-p file-name)) 210 | (other-window 1) 211 | (find-file file-name) 212 | (when line 213 | (goto-line line))))))) 214 | 215 | ;;; --------------------------------------------------------- 216 | ;;; - Key functions 217 | ;;; 218 | 219 | (defmacro rails/key (key) 220 | `(kbd ,(concat rails-minor-mode-prefix-key " " rails-minor-mode-prefix2-key " " key))) 221 | 222 | (defmacro rails/define-key (key func) 223 | `(define-key rails-minor-mode-map (rails/key ,key) ,func)) 224 | 225 | (defmacro rails/short-key (key) 226 | `(kbd ,(concat rails-minor-mode-prefix-key " " key))) 227 | 228 | (defmacro rails/define-goto-key (goto-key goto-func) 229 | `(define-key rails-minor-mode-map (rails/key ,(concat "g " goto-key)) ,goto-func)) 230 | 231 | (defun rails/define-goto-menu (title func) 232 | (define-key rails-minor-mode-map 233 | (merge 'vector [menu-bar rails goto] (list (string-ext/safe-symbol title)) 'eq) 234 | (cons (concat "Go to " (pluralize-string title)) func))) 235 | 236 | (defmacro rails/define-toggle-key (key func) 237 | `(define-key rails-minor-mode-map (rails/short-key ,key) ,func)) 238 | 239 | (defun rails/define-toggle-menu (title func) 240 | (define-key-after 241 | rails-minor-mode-map 242 | (merge 'vector '[menu-bar rails toggle] (list (string-ext/safe-symbol title)) 'eq) 243 | (list 'menu-item (concat "Go to current " title) func :enable t) 'separator)) 244 | 245 | ;;; --------------------------------------------------------- 246 | ;;; - Misc functions 247 | ;;; 248 | 249 | (defun rails/environments (root) 250 | (mapcar 251 | 'file-name-sans-extension 252 | (directory-files 253 | (concat root "config/environments/") 254 | nil 255 | rails/ruby/file-suffix))) 256 | 257 | (defun rails/default-environment-p (env) 258 | (string= env rails/default-environment)) 259 | 260 | (defmacro rails/toggle-environment-menu-func (env) 261 | `'(lambda() (interactive) (rails/set-default-environment ,(symbol-value env)))) 262 | 263 | ;;; --------------------------------------------------------- 264 | ;;; - Snippet support functions 265 | ;;; 266 | 267 | (defun rails/controller? () 268 | (when (rails/resource-buffer-p rails/current-buffer) 269 | (eq 'controller (rails/resource-buffer-type rails/current-buffer)))) 270 | 271 | (defun rails/controller-spec? () 272 | (when (rails/resource-buffer-p rails/current-buffer) 273 | (eq 'controller-spec (rails/resource-buffer-type rails/current-buffer)))) 274 | 275 | (defun rails/model? () 276 | (when (rails/resource-buffer-p rails/current-buffer) 277 | (eq 'model (rails/resource-buffer-type rails/current-buffer)))) 278 | 279 | (defun rails/migration? () 280 | (when (rails/resource-buffer-p rails/current-buffer) 281 | (eq 'migration (rails/resource-buffer-type rails/current-buffer)))) 282 | 283 | (defun rails/cur-res-title () 284 | (when rails/current-buffer 285 | (rails/resource-buffer-title rails/current-buffer))) 286 | 287 | (provide 'rails-lib) 288 | -------------------------------------------------------------------------------- /rails-project.el: -------------------------------------------------------------------------------- 1 | ;;; rails-project.el --- support per rails project settings 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | (require 'rails-lib) 27 | 28 | (defcustom rails/project/config "config/config.el" 29 | "The file name to store per project settings." 30 | :group 'rails 31 | :type 'string) 32 | 33 | (defvar rails/project/template 34 | "((rails/webserver-bundle/port . 3000)\n (rails/default-environment . \"development\")\n (rails/bundles/disabled-list . (test-unit)))\n") 35 | 36 | (defun rails/project/apply (root buffer config) 37 | (with-current-buffer buffer 38 | (when-bind (root (rails/root)) 39 | (mapc 40 | '(lambda(i) 41 | (set (make-local-variable (car i)) (cdr i)) 42 | (rails/project/apply-mumamo (car i) buffer)) 43 | config)))) 44 | 45 | (defun rails/project/apply-mumamo (var buffer) 46 | (unless (get var 'permanent-local) 47 | (put var 'permanent-local t))) 48 | 49 | (defun rails/project/edit (&optional root) 50 | (interactive) 51 | (unless root 52 | (setq root (rails/root))) 53 | (when root 54 | (rails/find-file root rails/project/config) 55 | (when (string-ext/empty-p (buffer-substring-no-properties (point-min) (point-max))) 56 | (insert rails/project/template)) 57 | (add-hook 'after-save-hook 'rails/project/update t t))) 58 | 59 | (defun rails/project/update (&optional root) 60 | (interactive) 61 | (unless root 62 | (setq root (rails/root))) 63 | (when root 64 | (when-bind (config (rails/project/read-config root)) 65 | (mapc 66 | '(lambda (buf) 67 | (rails/project/apply root buf config)) 68 | (buffer-list)) 69 | (rails/reload-all)))) 70 | 71 | (defun rails/project/read-config (root) 72 | (when (rails/file-exist-p root rails/project/config) 73 | (let ((config (files-ext/read-from-file 74 | (concat root rails/project/config)))) 75 | (when (listp config) 76 | config)))) 77 | 78 | (provide 'rails-project) 79 | -------------------------------------------------------------------------------- /rails-proxy.el: -------------------------------------------------------------------------------- 1 | ;;; rails-proxy.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | 27 | (defvar rails/proxy/ssh "ssh") 28 | (defvar rails/proxy/ssh-args "-t -t -q") 29 | (defvar rails/proxy/tunnel-local-port "80") 30 | (defvar rails/proxy/tunnel-args "-t -t -q -L %s:127.0.0.1:%s %s") 31 | (defvar rails/proxy/tunnel-buffer "*tunnel %s*") 32 | 33 | (defvar rails/proxy/dir-list 34 | '(("z:/apps/" "dima-exe@d2.undev.ru" "/home/dima-exe/apps/"))) 35 | 36 | (defvar rails/proxy/local-root nil) 37 | (defvar rails/proxy/remote-root nil) 38 | 39 | (defun rails/proxy/remote-p (dir) 40 | (files-ext/file-in-directories-p 41 | (mapcar 'car rails/proxy/dir-list) dir)) 42 | 43 | (defun rails/proxy/remote-list (dir) 44 | (find (rails/proxy/remote-p dir) 45 | rails/proxy/dir-list 46 | :key 'car :test 'string=)) 47 | 48 | (defun rails/proxy/make-command (root command &optional args) 49 | (if (rails/proxy/remote-p root) 50 | (let* ((plist (rails/proxy/remote-list root)) 51 | (dir (car plist)) 52 | (rdir (concat (caddr plist) (string-ext/cut root dir :begin))) 53 | (host (cadr plist))) 54 | (list rails/proxy/ssh 55 | (format (concat "%s %s \"(cd %s && %s " args ")\"") 56 | rails/proxy/ssh-args 57 | host 58 | rdir 59 | command) 60 | host)) 61 | (list command args))) 62 | 63 | (defun rails/proxy/shell-command (root name buffer command &optional args) 64 | (let* ((cmd (rails/proxy/make-command root command args)) 65 | (proc (start-process-shell-command name 66 | buffer 67 | (car cmd) 68 | (cadr cmd)))) 69 | (if (rails/proxy/remote-p root) 70 | (rails/proxy/setup-remote root proc) 71 | proc))) 72 | 73 | (defun rails/proxy/setup-remote (root proc) 74 | (with-current-buffer (process-buffer proc) 75 | (let ((plist (rails/proxy/remote-list root))) 76 | (set (make-local-variable 'rails/proxy/local-root) (car plist)) 77 | (set (make-local-variable 'rails/proxy/remote-root) (caddr plist))) 78 | proc)) 79 | 80 | (defun rails/proxy/shell-command-to-string (root command) 81 | (let ((cmd (rails/proxy/make-command root command))) 82 | (shell-command-to-string 83 | (if (cadr cmd) 84 | (format "%s %s" (car cmd) (cadr cmd)) 85 | (car cmd))))) 86 | 87 | (defun rails/proxy/up-tinnel-if-need (root remote-port) 88 | (when-bind (plist (rails/proxy/remote-list root)) 89 | (let ((args (format rails/proxy/tunnel-args 90 | rails/proxy/tunnel-local-port 91 | remote-port 92 | (cadr plist))) 93 | (name (format rails/proxy/tunnel-buffer remote-port))) 94 | (unless (get-buffer-process name) 95 | (start-process-shell-command name 96 | name 97 | rails/proxy/ssh 98 | args))))) 99 | 100 | (defun rails/proxy/down-tunnel-if-need (remote-port) 101 | (let ((name (format rails/proxy/tunnel-buffer remote-port))) 102 | (when-bind (proc (get-buffer-process name)) 103 | (kill-process proc)))) 104 | 105 | (provide 'rails-proxy) -------------------------------------------------------------------------------- /rails-reloaded.el: -------------------------------------------------------------------------------- 1 | ;;; rails-reloaded.el --- minor mode for editing RubyOnRails code. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;; Keywords: ruby rails languages 9 | 10 | ;;; License 11 | 12 | ;; This program is free software; you can redistribute it and/or 13 | ;; modify it under the terms of the GNU General Public License 14 | ;; as published by the Free Software Foundation; either version 2 15 | ;; of the License, or (at your option) any later version. 16 | 17 | ;; This program is distributed in the hope that it will be useful, 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;; GNU General Public License for more details. 21 | 22 | ;; You should have received a copy of the GNU General Public License 23 | ;; along with this program; if not, write to the Free Software 24 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | ;;; Commentary: 27 | 28 | ;; Basic steps to setup: 29 | ;; 1. Setup `load-path': 30 | ;; (setq load-path (cons (expand-file-name "~/.emacs.d/rails-reloaded") load-path)) 31 | ;; 2. Put in your .emacs file: 32 | ;; (require 'rails-autoload) 33 | ;; 3. To bytecompile after emacs restarted, type: 34 | ;; [M-x] rails/bytecompile 35 | ;; 4. Optional: run unit tests for rails-reloaded: 36 | ;; [M-x] rails/selftest 37 | 38 | ;;; Code: 39 | 40 | (require 'cl) 41 | 42 | (require 'core-ext) 43 | (require 'string-ext) 44 | (require 'files-ext) 45 | (require 'list-ext) 46 | (require 'inflections) 47 | 48 | (require 'rails-ruby) 49 | (require 'rails-lib) 50 | (require 'rails-runner) 51 | (require 'rails-compile) 52 | (require 'rails-project) 53 | (require 'rails-resources) 54 | (require 'rails-bundles) 55 | (require 'rails-anything) 56 | 57 | ;;; --------------------------------------------------------- 58 | ;;; - Variables 59 | ;;; 60 | 61 | (defconst rails/version "0.99" 62 | "emacs-rails version string") 63 | 64 | (defvar rails/notify-func-list '(rails/notify-growl)) 65 | 66 | ;;; --------------------------------------------------------- 67 | ;;; - Customized variables 68 | ;;; 69 | 70 | (defgroup rails nil 71 | "Edit Rails projects with Emacs." 72 | :group 'programming 73 | :prefix "rails/") 74 | 75 | (defcustom rails/display-menu-method 'popup 76 | "Display menu method." 77 | :group 'rails 78 | :type '(choice (const :tag "Default" nil) 79 | (const :tag "Using Popup Menu" popup) 80 | (const :tag "Using ido-completion" ido))) 81 | 82 | (defcustom rails-minor-mode-hook nil 83 | "Hook run when entering Rails minor mode." 84 | :type 'hook 85 | :group 'rails) 86 | 87 | (defcustom rails/default-environment "development" 88 | "Default Railt environment." 89 | :type 'string 90 | :group 'rails) 91 | 92 | ;;; --------------------------------------------------------- 93 | ;;; - Buttons 94 | ;;; 95 | 96 | (define-button-type 'rails/button 97 | 'follow-link t 98 | 'action #'rails/button-action) 99 | 100 | ;;; --------------------------------------------------------- 101 | ;;; - Notify 102 | ;;; 103 | 104 | (defun rails/notify (string &optional level) 105 | (message string) 106 | (when level 107 | (dolist (i rails/notify-func-list) 108 | (funcall i string level)))) 109 | 110 | (defun rails/notify-growl (string level) 111 | (when (fboundp 'growl) 112 | (growl "Emacs rails" string))) 113 | 114 | ;;; --------------------------------------------------------- 115 | ;;; - Interactives 116 | ;;; 117 | 118 | (defun rails/reload-all () 119 | (interactive) 120 | (setq rails/compile/single-file-list nil) 121 | (setq rails/compile/current-method-list nil) 122 | (rails-minor-mode-reset-keymap) 123 | (rails-minor-mode-reset-keymap) 124 | (rails/bundles/reload)) 125 | 126 | (defun rails/initialize-for-current-buffer () 127 | (interactive) 128 | (rails/with-root (buffer-file-name) 129 | (when-bind (file (rails/cut-root (buffer-file-name))) 130 | (rails/project/apply (rails/root) 131 | (current-buffer) 132 | (rails/project/read-config (rails/root))) 133 | (rails/bundles/load) 134 | (set (make-local-variable 'rails/current-buffer) 135 | (rails/resources/get-buffer-for-file (rails/root) file)) 136 | (rails-minor-mode t)))) 137 | 138 | (defun rails/set-default-environment (&optional env) 139 | (interactive) 140 | (when-bind (root (rails/root)) 141 | (unless env 142 | (setq env (rails/completing-read "Default environment" 143 | (rails/environments root) 144 | t 145 | rails/default-environment))) 146 | (when (not (string-ext/empty-p env)) 147 | (setq rails/default-environment env)))) 148 | 149 | (defun rails/goto (&optional resource-type) 150 | (interactive) 151 | (rails/anything/goto resource-type)) 152 | 153 | (defun rails/goto-associated () 154 | (interactive) 155 | (rails/anything/associated)) 156 | 157 | ;;; --------------------------------------------------------- 158 | ;;; - Rails minor mode 159 | ;;; 160 | 161 | (defcustom rails-minor-mode-prefix-key "\C-c" 162 | "Key prefix for Rails minor mode." 163 | :group 'rails 164 | :type 'string) 165 | 166 | (defcustom rails-minor-mode-prefix2-key "\C-c" 167 | "Additional key prefix for Rails minor mode." 168 | :group 'rails 169 | :type 'string) 170 | 171 | (defun rails-minor-mode-reset-keymap () 172 | (setf rails-minor-mode-map (rails-minor-mode-default-keymap)) 173 | (setf (cdr (assoc 'rails-minor-mode minor-mode-map-alist)) 174 | rails-minor-mode-map)) 175 | 176 | (defun rails-minor-mode-menu-bar-map () 177 | (let ((map (make-sparse-keymap))) 178 | (define-keys map 179 | ([rails] (cons "RoR" (make-sparse-keymap "RubyOnRails"))) 180 | ([rails version] '(menu-item (concat "Version: " rails/version) 'foo :enable nil)) 181 | ([rails bundles-separator] (cons "--" "--")) 182 | ([rails bundles-title] '(menu-item "Bundles:" "--" :enable nil)) 183 | ([rails separator] (cons "--" "--")) 184 | ([rails env] '(menu-item "Environments" (make-sparse-keymap) 185 | :filter rails-minor-mode-environments-menu)) 186 | ([rails project] (cons "Project" (make-sparse-keymap))) 187 | ([rails project update] (cons "Apply Project Settings" 'rails/project/update)) 188 | ([rails project edit] (cons "Edit Project Settings" 'rails/project/edit)) 189 | ([rails env-separator] (cons "--" "--")) 190 | ([rails toggle] (cons "Go To From Current File" (make-sparse-keymap))) 191 | ([rails toggle toggle-test] (cons "Toggle Test/Implementation" 'rails/resources/toggle-test)) 192 | ([rails toggle toggle] (cons "Toggle" 'rails/resources/toggle)) 193 | ([rails toggle goto] (cons "Go to..." 'rails/goto-associated)) 194 | ([rails goto] (cons "Go To" (make-sparse-keymap))) 195 | ([rails find] (cons "Find file" 'rails/goto))) 196 | map)) 197 | 198 | (defun rails-minor-mode-environments-menu (&optional args) 199 | (let ((map (make-sparse-keymap)) 200 | (envs (rails/environments (rails/root)))) 201 | (dolist (e envs) 202 | (define-key map 203 | (vector (string-ext/safe-symbol e)) 204 | (list 'menu-item 205 | (capitalize e) 206 | `(lambda()(interactive)(rails/set-default-environment ,e)) 207 | :button (cons :radio (rails/default-environment-p e))))) 208 | (define-key map [separator] (cons "--" "--")) 209 | (define-key map [toggle] (cons "Set Default Environment" 'rails/set-default-environment)) 210 | map)) 211 | 212 | (defun rails-minor-mode-default-keymap () 213 | (let ((map (make-keymap))) 214 | (define-keys map 215 | ([menu-bar] (rails-minor-mode-menu-bar-map)) 216 | ((rails/short-key "") 'rails/resources/toggle) 217 | ((rails/short-key "t") 'rails/resources/toggle-test) 218 | ((rails/short-key "'") 'rails/goto-associated) 219 | ((rails/short-key ";") 'rails/goto) 220 | ((rails/short-key "/") 'rails/runner/toggle-output-window) 221 | ((kbd "\e\e e") 'rails/set-default-environment) 222 | ((rails/key ".") 'rails/compile/single-file) 223 | ((rails/key ",") 'rails/compile/current-method)) 224 | map)) 225 | 226 | (defvar rails-minor-mode-map (rails-minor-mode-default-keymap)) 227 | 228 | (define-minor-mode rails-minor-mode 229 | "RubyOnRails" 230 | nil 231 | " RoR" 232 | rails-minor-mode-map) 233 | 234 | (provide 'rails-reloaded) -------------------------------------------------------------------------------- /rails-ruby.el: -------------------------------------------------------------------------------- 1 | ;;; rails-ruby.el --- ruby-mode functions and variables used in rails. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;; Keywords: ruby languages 9 | 10 | ;;; License 11 | 12 | ;; This program is free software; you can redistribute it and/or 13 | ;; modify it under the terms of the GNU General Public License 14 | ;; as published by the Free Software Foundation; either version 2 15 | ;; of the License, or (at your option) any later version. 16 | 17 | ;; This program is distributed in the hope that it will be useful, 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | ;; GNU General Public License for more details. 21 | 22 | ;; You should have received a copy of the GNU General Public License 23 | ;; along with this program; if not, write to the Free Software 24 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | (require 'inf-ruby) 27 | 28 | (defvar rails/ruby/file-suffix ".rb") 29 | (defvar rails/ruby/command "ruby") 30 | 31 | (defun rails/ruby/current-method () 32 | (let (action 33 | (re "^ *def +\\([^ (\n]+\\)")) 34 | (save-excursion 35 | (end-of-line) 36 | (when (re-search-backward re nil t) 37 | (setq action (buffer-substring-no-properties (match-beginning 1) (match-end 1))))) 38 | action)) 39 | 40 | (defun rails/ruby/goto-method-in-current-buffer (action) 41 | (let* (pos 42 | (cur-pos (point)) 43 | (re (format "^ *def +\\<\\(%s\\)\\>" (regexp-quote action)))) 44 | (save-excursion 45 | (goto-char (point-min)) 46 | (when-bind (start-pos (re-search-forward re nil t)) 47 | (setq pos start-pos) 48 | (when (fboundp 'ruby-end-of-defun) 49 | (ruby-end-of-defun) 50 | (when (and (< cur-pos (point)) 51 | (> cur-pos start-pos)) 52 | (setq pos nil))))) 53 | (when pos 54 | (goto-char pos) 55 | (beginning-of-line)))) 56 | 57 | (defun rails/ruby/run-in-buffer (buf script &optional params) 58 | "Run CMD as a ruby process in BUF if BUF does not exist." 59 | (let ((abuf (concat "*" buf "*"))) 60 | (when (not (comint-check-proc abuf)) 61 | (set-buffer (make-comint buf rails/ruby/command nil script params))) 62 | (inferior-ruby-mode) 63 | (make-local-variable 'inferior-ruby-first-prompt-pattern) 64 | (make-local-variable 'inferior-ruby-prompt-pattern) 65 | (setq inferior-ruby-first-prompt-pattern "^>> " 66 | inferior-ruby-prompt-pattern "^>> ") 67 | (setq ruby-buffer abuf) 68 | (rails-minor-mode t) 69 | (pop-to-buffer abuf))) 70 | 71 | (defun rails/console () 72 | (interactive) 73 | (when-bind (root (rails/root)) 74 | (in-directory root 75 | (rails/ruby/run-in-buffer "ruby" "script/console" rails/default-environment)))) 76 | 77 | (provide 'rails-ruby) -------------------------------------------------------------------------------- /rails-runner.el: -------------------------------------------------------------------------------- 1 | ;;; rails-runner.el --- run external process. 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | ;; Rezikov Peter 7 | 8 | ;;; License 9 | 10 | ;; This program is free software; you can redistribute it and/or 11 | ;; modify it under the terms of the GNU General Public License 12 | ;; as published by the Free Software Foundation; either version 2 13 | ;; of the License, or (at your option) any later version. 14 | 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with this program; if not, write to the Free Software 22 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | 24 | ;;; Code: 25 | 26 | (require 'font-lock) 27 | (require 'ansi-color) 28 | (require 'rails-proxy) 29 | 30 | (defvar rails/runner/buffer-name "*ROutput*") 31 | (defvar rails/runner/buffer-rails-root nil) 32 | (defvar rails/runner/output-mode-hook nil) 33 | (defvar rails/runner/show-buffer-hook nil) 34 | (defvar rails/runner/after-stop-func-list nil) 35 | (defvar rails/runner/script-name nil) 36 | 37 | (defun rails/runner/running-p () 38 | (get-buffer-process rails/runner/buffer-name)) 39 | 40 | (defun rails/runner/setup-output-buffer () 41 | "Setup default variables and values for the output buffer." 42 | (set (make-local-variable 'scroll-margin) 0) 43 | ;; (set (make-local-variable 'scroll-preserve-screen-position) nil) 44 | (make-local-variable 'after-change-functions) 45 | (rails-minor-mode t)) 46 | 47 | (defun rails/runner/scroll-up () 48 | (with-current-buffer (get-buffer rails/runner/buffer-name) 49 | (goto-char (point-min)) 50 | (vertical-motion (- next-screen-context-lines)) 51 | (when-bind (win (get-buffer-window rails/runner/buffer-name)) 52 | (set-window-start win (point-min))))) 53 | 54 | (defun rails/runner/popup-buffer (&rest args) 55 | ;; args not used, added to compatibility of rails/runner/after-stop-func-list 56 | (unless (get-buffer-window rails/runner/buffer-name) 57 | (pop-to-buffer rails/runner/buffer-name t t) 58 | (shrink-window-if-larger-than-buffer 59 | (get-buffer-window rails/runner/buffer-name)) 60 | (run-hooks 'rails/runner/show-buffer-hook) 61 | (other-window 1))) 62 | 63 | (defun rails/runner/popup-buffer-if-failed (retval) 64 | (unless (zerop retval) 65 | (rails/runner/popup-buffer))) 66 | 67 | (defun rails/runner/toggle-output-window () 68 | (interactive) 69 | (let ((buf (get-buffer rails/runner/buffer-name))) 70 | (if buf 71 | (if (get-buffer-window rails/runner/buffer-name 'visible) 72 | (delete-windows-on buf) 73 | (rails/runner/popup-buffer)) 74 | (rails/notify "No output window found. Try running a script or a rake task before.")))) 75 | 76 | (defun rails/runner/setup-font-lock (&optional keywords) 77 | (font-lock-add-keywords nil keywords nil) 78 | (font-lock-mode t)) 79 | 80 | (define-derived-mode rails/runner/output-mode fundamental-mode "ROutput" 81 | "Major mode to Rails Script Output." 82 | (rails/runner/setup-output-buffer) 83 | (set (make-local-variable 'font-lock-keywords-only) t) 84 | (set (make-local-variable 'font-lock-keywords) nil) 85 | (buffer-disable-undo) 86 | (setq buffer-read-only t)) 87 | 88 | (defun rails/runner/sentinel-proc (proc msg) 89 | (let* ((name rails/runner/script-name) 90 | (ret-val (process-exit-status proc)) 91 | (buf (get-buffer rails/runner/buffer-name)) 92 | (ret-message (if (zerop ret-val) "successful" "failure")) 93 | msg) 94 | (when (memq (process-status proc) '(exit signal)) 95 | (rails/runner/scroll-up) 96 | (setq rails/runner/script-name nil 97 | msg (format "%s was stopped (%s)." name ret-message))) 98 | (message (replace-regexp-in-string "\n" "" msg)) 99 | (when rails/runner/after-stop-func-list 100 | (dolist (func rails/runner/after-stop-func-list) 101 | (with-selected-window (or (get-buffer-window buf) 102 | (get-buffer-window (current-buffer))) 103 | (with-current-buffer buf 104 | (goto-char (point-min)) 105 | (funcall func ret-val)))) 106 | ret-val))) 107 | 108 | (defun rails/runner/prepare-buffer (proc) 109 | (set-process-filter proc 'ansi-color-insertion-filter) 110 | (set-process-coding-system proc 'utf-8 'utf-8)) 111 | 112 | (defun rails/runner/run (root command parameters &rest options) 113 | "Run a Rails script COMMAND with PARAMETERS in ROOT with 114 | BUFFER-MAJOR-MODE." 115 | (save-some-buffers) 116 | (if (rails/runner/running-p) 117 | (message "Only one instance rails-script allowed") 118 | 119 | (setq rails/runner/after-stop-func-list nil) 120 | (setq rails/runner/buffer-rails-root root) 121 | (when (get-buffer rails/runner/buffer-name) 122 | (with-current-buffer (get-buffer rails/runner/buffer-name) 123 | (let ((buffer-read-only nil)) 124 | (delete-region (point-min) (point-max))))) 125 | (in-directory (if (string-ext/end-p root "/") 126 | root (concat root "/")) 127 | (let ((proc (rails/proxy/shell-command root 128 | rails/runner/buffer-name 129 | rails/runner/buffer-name 130 | command 131 | parameters))) 132 | (rails/runner/prepare-buffer proc) 133 | (with-current-buffer (process-buffer proc) 134 | (setq default-directory (if (string-ext/end-p root "/") 135 | root (concat root "/"))) 136 | (if (opt-val :mode options) 137 | (funcall (opt-val :mode options)) 138 | (rails/runner/output-mode)) 139 | (when (opt-val :keywords options) 140 | (rails/runner/setup-font-lock (opt-val :keywords options))) 141 | (set-process-sentinel proc 'rails/runner/sentinel-proc) 142 | (set (make-local-variable 'font-lock-unfontify-region-function) 143 | 'ansi-color-unfontify-region) ; fixed conflict ansi-color and compilation-mode 144 | (setq rails/runner/script-name (format "%s %s" command parameters)) 145 | (message "Starting %s." rails/runner/script-name)))))) 146 | 147 | (defun ansi-color-insertion-filter (proc string) 148 | (with-current-buffer (process-buffer proc) 149 | (let ((moving (= (point) (process-mark proc))) 150 | (buffer-read-only nil)) 151 | (save-excursion 152 | ;; Insert the text, advancing the process marker. 153 | (goto-char (process-mark proc)) 154 | ;; decode ansi color sequences 155 | (insert (ansi-color-apply string)) 156 | (set-marker (process-mark proc) (point))) 157 | (if moving (goto-char (process-mark proc)))))) 158 | 159 | (provide 'rails-runner) 160 | -------------------------------------------------------------------------------- /snippets/ruby-mode/controller.restful.basic: -------------------------------------------------------------------------------- 1 | #name : generating a RESTful controller 2 | #key : restful 3 | #group : rails.controller 4 | #condition : (rails/controller?) 5 | # -- 6 | before_filter :capture_${1:`(singularize-string (rails/cur-res-title))`} 7 | $0 8 | def index 9 | @${1:$(pluralize-string text)} = ${2:`(decamelize-string (singularize-string (rails/cur-res-title)))`}.all 10 | respond_to do |format| 11 | format.html # index.html.erb 12 | format.xml { render :xml => @${1:$(pluralize-string text)} } 13 | end 14 | end 15 | 16 | def show 17 | respond_to do |format| 18 | format.html # show.html.erb 19 | format.xml { render :xml => @$1 } 20 | end 21 | end 22 | 23 | def new 24 | respond_to do |format| 25 | format.html # new.html.erb 26 | format.xml { render :xml => @$1 } 27 | end 28 | end 29 | 30 | def edit 31 | end 32 | 33 | def create 34 | @$1.update_attributes!(params[:$1]) 35 | flash[:notice] = t('.flash') 36 | respond_to do |format| 37 | format.html { redirect_to($1_path(@$1)) } 38 | format.xml { render :xml => @$1, :status => :created, :location => $1_url(@$1) } 39 | end 40 | rescue ActiveRecord::RecordInvalid 41 | respond_to do |format| 42 | format.html { render :action => "new" } 43 | format.xml { render :xml => @$1.errors, :status => :unprocessable_entity } 44 | end 45 | end 46 | 47 | def update 48 | @$1.update_attributes!(params[:$1]) 49 | flash[:notice] = t('.flash') 50 | respond_to do |format| 51 | format.html { redirect_to($1_path(@$1)) } 52 | format.xml { head :ok } 53 | end 54 | rescue ActiveRecord::RecordInvalid 55 | respond_to do |format| 56 | format.html { render :action => "edit" } 57 | format.xml { render :xml => @$1.errors, :status => :unprocessable_entity } 58 | end 59 | end 60 | 61 | def destroy 62 | @$1.destroy 63 | flash[:notice] = t('.flash') 64 | respond_to do |format| 65 | format.html { redirect_to(${1:$(pluralize-string text)}_path) } 66 | format.xml { head :ok } 67 | end 68 | end 69 | 70 | private 71 | 72 | def capture_$1 73 | @$1 = $2.find(params[:id]) if params[:id] 74 | @$1 ||= $2.new 75 | end -------------------------------------------------------------------------------- /snippets/ruby-mode/controller.restful.nested: -------------------------------------------------------------------------------- 1 | #name : generating a nested RESTful controller 2 | #key : restful.nested 3 | #group : rails.controller 4 | #condition : (rails/controller?) 5 | # -- 6 | before_filter :capture_${1:owner}_and_${2:`(singularize-string (rails/cur-res-title))`} 7 | $0 8 | def index 9 | @${2:$(pluralize-string text)} = @$1.${2:$(pluralize-string text)} 10 | respond_to do |format| 11 | format.html # index.html.erb 12 | format.xml { render :xml => @${2:$(pluralize-string text)} } 13 | end 14 | end 15 | 16 | def show 17 | respond_to do |format| 18 | format.html # show.html.erb 19 | format.xml { render :xml => @$2 } 20 | end 21 | end 22 | 23 | def new 24 | respond_to do |format| 25 | format.html # new.html.erb 26 | format.xml { render :xml => @$2 } 27 | end 28 | end 29 | 30 | def edit 31 | end 32 | 33 | def create 34 | @$2.update_attributes!(params[:$2]) 35 | flash[:notice] = t('.flash') 36 | respond_to do |format| 37 | format.html { redirect_to($1_$2_path(@$1, @$2)) } 38 | format.xml { render :xml => @$2, :status => :created, :location => $1_$2_url(@$1, @$2) } 39 | end 40 | rescue ActiveRecord::RecordInvalid 41 | respond_to do |format| 42 | format.html { render :action => "new" } 43 | format.xml { render :xml => @$2.errors, :status => :unprocessable_entity } 44 | end 45 | end 46 | 47 | def update 48 | @$2.update_attributes!(params[:$2]) 49 | flash[:notice] = t('.flash') 50 | respond_to do |format| 51 | format.html { redirect_to($1_$2_path(@$1, @$2)) } 52 | format.xml { head :ok } 53 | end 54 | rescue ActiveRecord::RecordInvalid 55 | respond_to do |format| 56 | format.html { render :action => "edit" } 57 | format.xml { render :xml => @$2.errors, :status => :unprocessable_entity } 58 | end 59 | end 60 | 61 | def destroy 62 | @$2.destroy 63 | flash[:notice] = t('.flash') 64 | respond_to do |format| 65 | format.html { redirect_to($1_${2:$(pluralize-string text)}_path(@$1)) } 66 | format.xml { head :ok } 67 | end 68 | end 69 | 70 | private 71 | 72 | def capture_$1_and_$2 73 | @$1 = ${1:$(decamelize-string text)}.find(params[:$1_id]) 74 | @$2 = @$1.${2:$(pluralize-string text)}.find(params[:id]) if params[:id] 75 | @$2 ||= ${2:$(decamelize-string text)}.new(:$1 => @$1) 76 | end -------------------------------------------------------------------------------- /snippets/ruby-mode/controller_spec.restful.basic: -------------------------------------------------------------------------------- 1 | #name : generating a RESTful controller spec 2 | #key : restful.basic_spec 3 | #group : rails.controller_spec 4 | #condition : (rails/controller-spec?) 5 | # -- 6 | $0 7 | before(:each) do 8 | @${1:`(singularize-string (rails/cur-res-title))`} = mock_model(${2:`(decamelize-string (singularize-string (rails/cur-res-title)))`}) 9 | @${1:$(pluralize-string text)} = [@$1] 10 | @attrs = { "name" => "name" } 11 | end 12 | 13 | it "should use ${2:$(pluralize-string text)}Controller" do 14 | controller.should be_an_instance_of(${2:$(pluralize-string text)}Controller) 15 | end 16 | 17 | describe "GET 'index'" do 18 | before(:each) do 19 | $2.should_receive(:all).and_return(@${1:$(pluralize-string text)}) 20 | end 21 | 22 | describe "with :format => :html" do 23 | before(:each) do 24 | get :index 25 | end 26 | it_should_be_successful 27 | it_should_render "${1:$(pluralize-string text)}/index" 28 | it_should_be_assign :$1 29 | it_should_return_content_type :html 30 | end 31 | 32 | describe "with :format => :xml" do 33 | before(:each) do 34 | @${1:$(pluralize-string text)}.should_receive(:to_xml).and_return("XML") 35 | get :index, :format => "xml" 36 | end 37 | it_should_be_successful 38 | it_should_be_assign :$1 39 | it_should_return_content_type :xml 40 | it_should_response_body "XML" 41 | end 42 | end 43 | 44 | describe "GET 'show'" do 45 | before(:each) do 46 | $2.should_receive(:find).with("1").and_return(@$1) 47 | end 48 | 49 | describe "with :format => :html" do 50 | before(:each) do 51 | get :show, :id => "1" 52 | end 53 | it_should_be_successful 54 | it_should_render "${1:$(pluralize-string text)}/show" 55 | it_should_be_assign :$1 56 | end 57 | 58 | describe "with :format => :xml" do 59 | before(:each) do 60 | @$1.should_receive(:to_xml).and_return("XML") 61 | get :show, :id => "1", :format => "xml" 62 | end 63 | it_should_be_successful 64 | it_should_return_content_type :xml 65 | it_should_be_assign :$1 66 | it_should_response_body "XML" 67 | end 68 | end 69 | 70 | describe "GET 'new'" do 71 | before(:each) do 72 | $2.should_receive(:new).and_return(@$1) 73 | @$1.stub!(:new_record? => true) 74 | get :new 75 | end 76 | it_should_be_successful 77 | it_should_render '${1:$(pluralize-string text)}/new' 78 | it_should_be_assign :$1 79 | end 80 | 81 | describe "GET 'edit'" do 82 | before(:each) do 83 | $2.should_receive(:find).with("1").and_return(@$1) 84 | get :edit, :id => "1" 85 | end 86 | it_should_be_successful 87 | it_should_be_assign :$1 88 | it_should_render '${1:$(pluralize-string text)}/edit' 89 | end 90 | 91 | describe "POST 'create'" do 92 | before(:each) do 93 | $2.should_receive(:new).and_return(@$1) 94 | @$1.stub!(:new_record? => true) 95 | end 96 | 97 | describe "successfuly" do 98 | before(:each) do 99 | @$1.should_receive(:update_attributes!).with(@attrs) 100 | end 101 | 102 | describe "with :format => :html" do 103 | before(:each) do 104 | post :create, :$1 => @attrs 105 | end 106 | it_should_be_redirect { $1_url(@$1) } 107 | it_should_be_assign :$1 108 | it_should_flash_notice_have I18n.translate('${1:$(pluralize-string text)}.create.flash') 109 | end 110 | 111 | describe "with :format => :xml" do 112 | before(:each) do 113 | @$1.should_receive(:to_xml).and_return("XML") 114 | post :create, :$1 => @attrs, :format => "xml" 115 | end 116 | it_should_be_successful 117 | it_should_return_content_type :xml 118 | it_should_be_assign :$1 119 | it_should_response_body "XML" 120 | it_should_response_status "201 Created" 121 | it_should_response_location { $1_url(@$1) } 122 | end 123 | end 124 | 125 | describe "failed" do 126 | before(:each) do 127 | raise_record_invalid_on @$1, :update_attributes!, @attrs 128 | end 129 | 130 | describe "with :format => :html" do 131 | before(:each) do 132 | post :create, :$1 => @attrs 133 | end 134 | it_should_be_successful 135 | it_should_be_assign :$1 136 | it_should_render '${1:$(pluralize-string text)}/new' 137 | end 138 | 139 | describe "with :format => :xml" do 140 | before(:each) do 141 | @$1.errors.should_receive(:to_xml).and_return("errors") 142 | post :create, :$1 => @attrs, :format => "xml" 143 | end 144 | it_should_return_content_type :xml 145 | it_should_be_assign :$1 146 | it_should_response_status "422 Unprocessable Entity" 147 | it_should_response_body "errors" 148 | end 149 | end 150 | end 151 | 152 | describe "PUT 'update'" do 153 | before(:each) do 154 | $2.should_receive(:find).with("1").and_return(@$1) 155 | end 156 | 157 | describe "successfuly" do 158 | before(:each) do 159 | @$1.should_receive(:update_attributes!).with(@attrs) 160 | end 161 | 162 | describe "with :format => :html" do 163 | before(:each) do 164 | put :update, :id => "1", :$1 => @attrs 165 | end 166 | it_should_be_redirect { $1_url(@$1) } 167 | it_should_be_assign :$1 168 | it_should_flash_notice_have I18n.translate("${1:$(pluralize-string text)}.update.flash") 169 | end 170 | 171 | describe "with :format => :xml" do 172 | before(:each) do 173 | put :update, :id => "1", :$1 => @attrs, :format => "xml" 174 | end 175 | it_should_be_successful 176 | it_should_return_content_type :xml 177 | it_should_be_assign :$1 178 | it_should_response_be_blank 179 | end 180 | end 181 | 182 | describe "failed" do 183 | before(:each) do 184 | raise_record_invalid_on @$1, :update_attributes!, @attrs 185 | end 186 | 187 | describe "with :format => :html" do 188 | before(:each) do 189 | put :update, :id => "1", :$1 => @attrs 190 | end 191 | it_should_be_successful 192 | it_should_be_assign :$1 193 | it_should_render '${1:$(pluralize-string text)}/edit' 194 | end 195 | 196 | describe "with :format => :xml" do 197 | before(:each) do 198 | @$1.errors.should_receive(:to_xml).and_return("errors") 199 | put :update, :id => "1", :$1 => @attrs, :format => "xml" 200 | end 201 | it_should_return_content_type :xml 202 | it_should_be_assign :$1 203 | it_should_response_status "422 Unprocessable Entity" 204 | it_should_response_body "errors" 205 | end 206 | end 207 | end 208 | 209 | describe "DELETE 'destroy'" do 210 | before(:each) do 211 | $2.should_receive(:find).with("1").and_return(@$1) 212 | @$1.should_receive(:destroy) 213 | end 214 | 215 | describe "with :format => :html" do 216 | before(:each) do 217 | delete :destroy, :id => "1" 218 | end 219 | it_should_be_redirect { ${1:$(pluralize-string text)}_url } 220 | it_should_be_assign :$1 221 | it_should_flash_notice_have I18n.translate("${1:$(pluralize-string text)}.destroy.flash") 222 | end 223 | 224 | describe "with :format => :xml" do 225 | before(:each) do 226 | delete :destroy, :id => "1", :format => "xml" 227 | end 228 | it_should_be_successful 229 | it_should_return_content_type :xml 230 | it_should_be_assign :$1 231 | it_should_response_be_blank 232 | end 233 | end 234 | 235 | describe_routes_for :controller => "${1:$(pluralize-string text)}" do 236 | it_should_have_route_for_resources "${1:$(pluralize-string text)}" 237 | end 238 | -------------------------------------------------------------------------------- /snippets/ruby-mode/controller_spec.restful.nested: -------------------------------------------------------------------------------- 1 | #name : generating a nested RESTful controller spec 2 | #key : restful.nested_spec 3 | #group : rails.controller_spec 4 | #condition : (rails/controller-spec?) 5 | # -- 6 | $0 7 | before(:each) do 8 | @${1:owner} = mock_model(${2:Owner}) 9 | @${3:`(singularize-string (rails/cur-res-title))`} = mock_model(${4:`(decamelize-string (singularize-string (rails/cur-res-title)))`}, :$1 => @$1) 10 | @${3:$(pluralize-string text)} = [@$3] 11 | @attrs = { "name" => "name" } 12 | end 13 | 14 | it "should use ${4:$(pluralize-string text)}Controller" do 15 | controller.should be_an_instance_of(${4:$(pluralize-string text)}Controller) 16 | end 17 | 18 | describe "GET 'index'" do 19 | before(:each) do 20 | $2.should_receive(:find).with("1").and_return(@$1) 21 | @$1.should_receive(:${3:$(pluralize-string text)}).and_return(@${3:$(pluralize-string text)}) 22 | end 23 | 24 | describe "with :format => :html" do 25 | before(:each) do 26 | get :index, :$1_id => "1" 27 | end 28 | it_should_be_successful 29 | it_should_render "${3:$(pluralize-string text)}/index" 30 | it_should_be_assign :$1, :$3 31 | it_should_return_content_type :html 32 | end 33 | 34 | describe "with :format => :xml" do 35 | before(:each) do 36 | @${3:$(pluralize-string text)}.should_receive(:to_xml).and_return("XML") 37 | get :index, :$1_id => "1", :format => "xml" 38 | end 39 | it_should_be_successful 40 | it_should_be_assign :$1, :$3 41 | it_should_return_content_type :xml 42 | it_should_response_body "XML" 43 | end 44 | end 45 | 46 | describe "GET 'show'" do 47 | before(:each) do 48 | $2.should_receive(:find).with("1").and_return(@$1) 49 | @$1.should_receive(:${3:$(pluralize-string text)}).and_return(@${3:$(pluralize-string text)}) 50 | @${3:$(pluralize-string text)}.should_receive(:find).with("1").and_return(@$3) 51 | end 52 | 53 | describe "with :format => :html" do 54 | before(:each) do 55 | get :show, :$1_id => "1", :id => "1" 56 | end 57 | it_should_be_successful 58 | it_should_render "${3:$(pluralize-string text)}/show" 59 | it_should_be_assign :$1, :$3 60 | end 61 | 62 | describe "with :format => :xml" do 63 | before(:each) do 64 | @$3.should_receive(:to_xml).and_return("XML") 65 | get :show, :$1_id => "1", :id => "1", :format => "xml" 66 | end 67 | it_should_be_successful 68 | it_should_return_content_type :xml 69 | it_should_be_assign :$1, :$3 70 | it_should_response_body "XML" 71 | end 72 | end 73 | 74 | describe "GET 'new'" do 75 | before(:each) do 76 | $2.should_receive(:find).with("1").and_return(@$1) 77 | $4.should_receive(:new).with(:$1 => @$1).and_return(@$3) 78 | @$3.stub!(:new_record? => true) 79 | get :new, :$1_id => "1" 80 | end 81 | it_should_be_successful 82 | it_should_render '${3:$(pluralize-string text)}/new' 83 | it_should_be_assign :$1, :$3 84 | end 85 | 86 | describe "GET 'edit'" do 87 | before(:each) do 88 | $2.should_receive(:find).with("1").and_return(@$1) 89 | @$1.should_receive(:${3:$(pluralize-string text)}).and_return(@${3:$(pluralize-string text)}) 90 | @${3:$(pluralize-string text)}.should_receive(:find).with("1").and_return(@$3) 91 | get :edit, :$1_id => "1", :id => "1" 92 | end 93 | it_should_be_successful 94 | it_should_be_assign :$1, :$3 95 | it_should_render '${3:$(pluralize-string text)}/edit' 96 | end 97 | 98 | describe "POST 'create'" do 99 | before(:each) do 100 | $2.should_receive(:find).with("1").and_return(@$1) 101 | $4.should_receive(:new).with(:$1 => @$1).and_return(@$3) 102 | @$3.stub!(:new_record? => true) 103 | end 104 | 105 | describe "successfuly" do 106 | before(:each) do 107 | @$3.should_receive(:update_attributes!).with(@attrs) 108 | end 109 | 110 | describe "with :format => :html" do 111 | before(:each) do 112 | post :create, :$1_id => "1", :$3 => @attrs 113 | end 114 | it_should_be_redirect { $1_$3_url(@$1, @$3) } 115 | it_should_be_assign :$1, :$3 116 | it_should_flash_notice_have I18n.translate('${3:$(pluralize-string text)}.create.flash') 117 | end 118 | 119 | describe "with :format => :xml" do 120 | before(:each) do 121 | @$3.should_receive(:to_xml).and_return("XML") 122 | post :create, :$1_id => "1", :$3 => @attrs, :format => "xml" 123 | end 124 | it_should_be_successful 125 | it_should_return_content_type :xml 126 | it_should_be_assign :$1, :$3 127 | it_should_response_body "XML" 128 | it_should_response_status "201 Created" 129 | it_should_response_location { $1_$3_url(@$1, @$3) } 130 | end 131 | end 132 | 133 | describe "failed" do 134 | before(:each) do 135 | raise_record_invalid_on @$3, :update_attributes!, @attrs 136 | end 137 | 138 | describe "with :format => :html" do 139 | before(:each) do 140 | post :create, :$1_id => "1", :$3 => @attrs 141 | end 142 | it_should_be_successful 143 | it_should_be_assign :$1, :$3 144 | it_should_render '${3:$(pluralize-string text)}/new' 145 | end 146 | 147 | describe "with :format => :xml" do 148 | before(:each) do 149 | @$3.errors.should_receive(:to_xml).and_return("errors") 150 | post :create, :$1_id => "1", :$3 => @attrs, :format => "xml" 151 | end 152 | it_should_return_content_type :xml 153 | it_should_be_assign :$1, :$3 154 | it_should_response_status "422 Unprocessable Entity" 155 | it_should_response_body "errors" 156 | end 157 | end 158 | end 159 | 160 | describe "PUT 'update'" do 161 | before(:each) do 162 | $2.should_receive(:find).with("1").and_return(@$1) 163 | @$1.should_receive(:${3:$(pluralize-string text)}).and_return(@${3:$(pluralize-string text)}) 164 | @${3:$(pluralize-string text)}.should_receive(:find).with("1").and_return(@$3) 165 | end 166 | 167 | describe "successfuly" do 168 | before(:each) do 169 | @$3.should_receive(:update_attributes!).with(@attrs) 170 | end 171 | 172 | describe "with :format => :html" do 173 | before(:each) do 174 | put :update, :$1_id => "1", :id => "1", :$3 => @attrs 175 | end 176 | it_should_be_redirect { $1_$3_url(@$1, @$3) } 177 | it_should_be_assign :$1, :$3 178 | it_should_flash_notice_have I18n.translate("${3:$(pluralize-string text)}.update.flash") 179 | end 180 | 181 | describe "with :format => :xml" do 182 | before(:each) do 183 | put :update, :$1_id => "1", :id => "1", :$3 => @attrs, :format => "xml" 184 | end 185 | it_should_be_successful 186 | it_should_return_content_type :xml 187 | it_should_be_assign :$1, :$3 188 | it_should_response_be_blank 189 | end 190 | end 191 | 192 | describe "failed" do 193 | before(:each) do 194 | raise_record_invalid_on @$3, :update_attributes!, @attrs 195 | end 196 | 197 | describe "with :format => :html" do 198 | before(:each) do 199 | put :update, :$1_id => "1", :id => "1", :$3 => @attrs 200 | end 201 | it_should_be_successful 202 | it_should_be_assign :$1, :$3 203 | it_should_render '${3:$(pluralize-string text)}/edit' 204 | end 205 | 206 | describe "with :format => :xml" do 207 | before(:each) do 208 | @$3.errors.should_receive(:to_xml).and_return("errors") 209 | put :update, :$1_id => "1", :id => "1", :$3 => @attrs, :format => "xml" 210 | end 211 | it_should_return_content_type :xml 212 | it_should_be_assign :$1, :$3 213 | it_should_response_status "422 Unprocessable Entity" 214 | it_should_response_body "errors" 215 | end 216 | end 217 | end 218 | 219 | describe "DELETE 'destroy'" do 220 | before(:each) do 221 | $2.should_receive(:find).with("1").and_return(@$1) 222 | @$1.should_receive(:${3:$(pluralize-string text)}).and_return(@${3:$(pluralize-string text)}) 223 | @${3:$(pluralize-string text)}.should_receive(:find).with("1").and_return(@$3) 224 | @$3.should_receive(:destroy) 225 | end 226 | 227 | describe "with :format => :html" do 228 | before(:each) do 229 | delete :destroy, :$1_id => "1", :id => "1" 230 | end 231 | it_should_be_redirect { $1_${3:$(pluralize-string text)}_url(@$1) } 232 | it_should_be_assign :$1, :$3 233 | it_should_flash_notice_have I18n.translate("${3:$(pluralize-string text)}.destroy.flash") 234 | end 235 | 236 | describe "with :format => :xml" do 237 | before(:each) do 238 | delete :destroy, :$1_id => "1", :id => "1", :format => "xml" 239 | end 240 | it_should_be_successful 241 | it_should_return_content_type :xml 242 | it_should_be_assign :$1, :$3 243 | it_should_response_be_blank 244 | end 245 | end 246 | 247 | describe_routes_for :controller => "${3:$(pluralize-string text)}", :$1_id => "1" do 248 | it_should_have_route_for_resources "${1:$(pluralize-string text)}/1/${3:$(pluralize-string text)}" 249 | end 250 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ac: -------------------------------------------------------------------------------- 1 | #name : add_column 2 | #key : ac 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | add_column :${1:`(or (rails/cur-res-title) "table")`}, :${2:column}, :${3:integer} -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ai: -------------------------------------------------------------------------------- 1 | #name : add_index 2 | #key : ai 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | add_index :${1:`(or (rails/cur-res-title) "table")`}, [:${2:column}] -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.aiu: -------------------------------------------------------------------------------- 1 | #name : add_index :unique => true 2 | #key : aiu 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | add_index :${1:`(or (rails/cur-res-title) "table")`}, [:${2:column}], :unique => true -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.cc: -------------------------------------------------------------------------------- 1 | #name : change_column 2 | #key : cc 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | change_column :${1:`(or (rails/cur-res-title) "table")`}, :${2:column}, :${3:type} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ccd: -------------------------------------------------------------------------------- 1 | #name : change_column_default 2 | #key : ccd 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | change_column_default :${1:`(or (rails/cur-res-title) "table")`}, :${2:column}, :${3:default_value} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.cht: -------------------------------------------------------------------------------- 1 | #name : change_table 2 | #key : cht 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | change_table :${1:`(or (rails/cur-res-title) "table")`} do |t| 7 | $0 8 | end 9 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.cre: -------------------------------------------------------------------------------- 1 | #name : create_table 2 | #key : cre 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | create_table :${1:`(or (rails/cur-res-title) "table")`} do |t| 7 | $0 8 | end 9 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.dt: -------------------------------------------------------------------------------- 1 | #name : drop_table 2 | #key : dt 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | drop_table :${1:`(or (rails/cur-res-title) "table")`} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.rc: -------------------------------------------------------------------------------- 1 | #name : remove_columns 2 | #key : rcs 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | remove_columns :${1:`(or (rails/cur-res-title) "table")`}, :${2:column}, :${3:column} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.renc: -------------------------------------------------------------------------------- 1 | #name : rename_column 2 | #key : renc 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | rename_column :${1:`(or (rails/cur-res-title) "table")`}, :${2:old_name}, :${3:new_name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.rent: -------------------------------------------------------------------------------- 1 | #name : rename_table 2 | #key : rent 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | rename_table :${1:old_name}, :${2:new_name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ri: -------------------------------------------------------------------------------- 1 | #name : remove_index 2 | #key : ri 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | remove_index :${1:`(or (rails/cur-res-title) "table")`}, :${2:column} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tb: -------------------------------------------------------------------------------- 1 | #name : t.boolean 2 | #key : tb 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.boolean :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tbin: -------------------------------------------------------------------------------- 1 | #name : t.binary 2 | #key : tbin 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.binary :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tbt: -------------------------------------------------------------------------------- 1 | #name : t.belongs_to 2 | #key : tbt 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.belongs_to :${1:owner}${2:, :polymorphic => true} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.td: -------------------------------------------------------------------------------- 1 | #name : t.date 2 | #key : td 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.date :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tdt: -------------------------------------------------------------------------------- 1 | #name : t.datetime 2 | #key : tdt 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.datetime :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tf: -------------------------------------------------------------------------------- 1 | #name : t.float 2 | #key : tf 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.float :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ti: -------------------------------------------------------------------------------- 1 | #name : t.integer 2 | #key : ti 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.integer :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tim: -------------------------------------------------------------------------------- 1 | #name : t.timestamps 2 | #key : tim 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.timestamps 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tin: -------------------------------------------------------------------------------- 1 | #name : t.index 2 | #key : tin 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.index [:${name}$0] 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tref: -------------------------------------------------------------------------------- 1 | #name : t.references 2 | #key : tref 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.references :${1:owner} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ts: -------------------------------------------------------------------------------- 1 | #name : t.string 2 | #key : ts 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.string :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.tt: -------------------------------------------------------------------------------- 1 | #name : t.text 2 | #key : tt 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.text :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/migration.ttim: -------------------------------------------------------------------------------- 1 | #name : t.time 2 | #key : ttim 3 | #group : rails.migration 4 | #condition : (rails/migration?) 5 | # -- 6 | t.time :${1:name} 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/model.bt: -------------------------------------------------------------------------------- 1 | #name : belongs_to 2 | #key : bt 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | belongs_to :${1:model} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.btp: -------------------------------------------------------------------------------- 1 | #name : belongs_to :polymorphic 2 | #key : btp 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | belongs_to :${1:ownable}, :polymorphic => true -------------------------------------------------------------------------------- /snippets/ruby-mode/model.hm: -------------------------------------------------------------------------------- 1 | #name : has_many 2 | #key : hm 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_many :${1:model}${2:, :dependent => :destroy} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.hma: -------------------------------------------------------------------------------- 1 | #name : has_many :as 2 | #key : hma 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_many :${1:model}, :as => :${2:ownable} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.hmt: -------------------------------------------------------------------------------- 1 | #name : has_many :through 2 | #key : hmt 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_many :${1:model}, :through => :${2:through} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.ho: -------------------------------------------------------------------------------- 1 | #name : has_one 2 | #key : ho 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_one :${1:model}${2:, :dependent => :destroy} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.hoa: -------------------------------------------------------------------------------- 1 | #name : has_one :as 2 | #key : hoa 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_one :${1:model}, :as => :${2:ownable} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.hot: -------------------------------------------------------------------------------- 1 | #name : has_one :through 2 | #key : hot 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | has_one :${1:model}, :through => :${2:through} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.ns: -------------------------------------------------------------------------------- 1 | #name : named_scope 2 | #key : ns 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | named_scope :${1:approved}, :conditions => { :${2:approved} => ${3:true} } -------------------------------------------------------------------------------- /snippets/ruby-mode/model.nsl: -------------------------------------------------------------------------------- 1 | #name : named_scope ... lambda {} 2 | #key : nsl 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | named_scope :${1:approved}, lambda { |i| 7 | { :conditions => { :${2:approved} => ${3:true} } } 8 | } -------------------------------------------------------------------------------- /snippets/ruby-mode/model.vf: -------------------------------------------------------------------------------- 1 | #name : validates_format_of 2 | #key : vf 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | validates_format_of :${1:email}, :with => ${2:/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.vl: -------------------------------------------------------------------------------- 1 | #name : validates_length_of 2 | #key : vl 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | validates_length_of :${1:name}, :maximum => ${2:100}, :minimum => ${3:3} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.vn: -------------------------------------------------------------------------------- 1 | #name : validates_numericality_of 2 | #key : vn 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | validates_numericality_of :${1:value} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.vp: -------------------------------------------------------------------------------- 1 | #name : validates_presence_of 2 | #key : vp 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | validates_presence_of :${1:name} -------------------------------------------------------------------------------- /snippets/ruby-mode/model.vu: -------------------------------------------------------------------------------- 1 | #name : validates_uniqueness_of 2 | #key : vu 3 | #group : rails.model 4 | #condition : (rails/model?) 5 | # -- 6 | validates_uniqueness_of :${1:name} -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.cpath: -------------------------------------------------------------------------------- 1 | #name : collection_path 2 | #key : cpath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(pluralize-string (rails/cur-res-title))`}_path -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.curl: -------------------------------------------------------------------------------- 1 | #name : collection_url 2 | #key : curl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(pluralize-string (rails/cur-res-title))`}_url -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.ncpath: -------------------------------------------------------------------------------- 1 | #name : nested_collection_path 2 | #key : ncpath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:owner}_${2:`(pluralize-string (rails/cur-res-title))`}_path(@$1) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.ncurl: -------------------------------------------------------------------------------- 1 | #name : nested_collection_url 2 | #key : ncurl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:owner}_${2:`(pluralize-string (rails/cur-res-title))`}_url(@$1) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.npath: -------------------------------------------------------------------------------- 1 | #name : nested_resource_path(@resource) 2 | #key : npath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:owner}_${2:`(singularize-string (rails/cur-res-title))`}_path(@$1, @$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.nurl: -------------------------------------------------------------------------------- 1 | #name : nested_resource_url(@resource) 2 | #key : nurl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:owner}_${2:`(singularize-string (rails/cur-res-title))`}_url(@$1, @$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.path: -------------------------------------------------------------------------------- 1 | #name : resource_path(@resource) 2 | #key : path 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(singularize-string (rails/cur-res-title))`}_path(@$1) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pcpath: -------------------------------------------------------------------------------- 1 | #name : prefixed_collection_path 2 | #key : pcpath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:`(pluralize-string (rails/cur-res-title))`}_path -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pcurl: -------------------------------------------------------------------------------- 1 | #name : prefixed_collection_url 2 | #key : pcurl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:`(pluralize-string (rails/cur-res-title))`}_url -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pncpath: -------------------------------------------------------------------------------- 1 | #name : prefixed_nested_collection_path 2 | #key : pncpath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:owner}_${3:`(pluralize-string (rails/cur-res-title))`}_path(@$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pncurl: -------------------------------------------------------------------------------- 1 | #name : prefixed_nested_collection_url 2 | #key : pncurl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:owner}_${3:`(pluralize-string (rails/cur-res-title))`}_url(@$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pnpath: -------------------------------------------------------------------------------- 1 | #name : prefixed_nested_resource_path(@resource) 2 | #key : pnpath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:owner}_${3:`(singularize-string (rails/cur-res-title))`}_path(@$2, @$3) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.pnurl: -------------------------------------------------------------------------------- 1 | #name : prefixed_nested_resource_url(@resource) 2 | #key : pnurl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:owner}_${3:`(singularize-string (rails/cur-res-title))`}_url(@$2, @$3) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.ppath: -------------------------------------------------------------------------------- 1 | #name : prefixed_resource_path(@resource) 2 | #key : ppath 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:`(singularize-string (rails/cur-res-title))`}_path(@$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.purl: -------------------------------------------------------------------------------- 1 | #name : prefixed_resource_url(@resource) 2 | #key : purl 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:new}_${2:`(singularize-string (rails/cur-res-title))`}_url(@$2) -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.rc: -------------------------------------------------------------------------------- 1 | #name : resource collection name 2 | #key : rc 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(pluralize-string (rails/cur-res-title))`}$0 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.rk: -------------------------------------------------------------------------------- 1 | #name : resource class name 2 | #key : rk 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(decamelize-string (singularize-string (rails/cur-res-title)))`}$0 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.ro: -------------------------------------------------------------------------------- 1 | #name : resource object name 2 | #key : ro 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(singularize-string (rails/cur-res-title))`}$0 7 | -------------------------------------------------------------------------------- /snippets/ruby-mode/resources.url: -------------------------------------------------------------------------------- 1 | #name : resource_url(@resource) 2 | #key : url 3 | #group : rails.resources 4 | #condition : (rails/cur-res-title) 5 | # -- 6 | ${1:`(singularize-string (rails/cur-res-title))`}_url(@$1) -------------------------------------------------------------------------------- /string-ext.el: -------------------------------------------------------------------------------- 1 | ;;; string-ext.el --- 2 | 3 | ;; Copyright (C) 2006 Dmitry Galinsky 4 | 5 | ;; Authors: Dmitry Galinsky , 6 | 7 | ;;; License 8 | 9 | ;; This program is free software; you can redistribute it and/or 10 | ;; modify it under the terms of the GNU General Public License 11 | ;; as published by the Free Software Foundation; either version 2 12 | ;; of the License, or (at your option) any later version. 13 | 14 | ;; This program is distributed in the hope that it will be useful, 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | ;; GNU General Public License for more details. 18 | 19 | ;; You should have received a copy of the GNU General Public License 20 | ;; along with this program; if not, write to the Free Software 21 | ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | ;;; Code: 24 | 25 | (require 'cl) 26 | 27 | (defun string-ext/cut (string cut from) 28 | "Cut from STRING fragment CUT from FROM, 29 | FROM must equal :begin or :end. Return result string, 30 | else return nil." 31 | (cond 32 | ((and (eq from :begin) 33 | (string-ext/start-p string cut)) 34 | (substring string (length cut) (length string))) 35 | ((and (eq from :end) 36 | (string-ext/end-p string cut)) 37 | (substring string 0 (- (length string) (length cut)))))) 38 | ;; (t string))) 39 | 40 | (defun string-ext/cut-safe (string cut from) 41 | (let ((str (string-ext/cut string cut from))) 42 | (if str 43 | str 44 | string))) 45 | 46 | (defun string-ext/from-symbol (sym) 47 | "Convert symbol SYM to string." 48 | (string-ext/cut-safe (format "%s" sym) ":" :begin)) 49 | 50 | (defun string-ext/start-p (string start) 51 | "Return t if STRING start with START, else return nil." 52 | (let ((len (length start)) 53 | (orig-len (length string))) 54 | (when (<= len orig-len) 55 | (string= start (substring string 0 len))))) 56 | 57 | (defun string-ext/end-p (string end) 58 | "Return t if STRING end with END, else return nil." 59 | (let* ((len (length end)) 60 | (orig-len (length string)) 61 | (from (- orig-len len))) 62 | (when (<= len orig-len) 63 | (string= end (substring string from orig-len))))) 64 | 65 | (defmacro string-ext/string=~ (regex string &rest body) 66 | "regex matching similar to the =~ operator found in other languages." 67 | (let ((str (gensym))) 68 | `(lexical-let ((,str ,string)) 69 | ;; Use lexical-let to make closures (in flet). 70 | (when (string-match ,regex ,str) 71 | (symbol-macrolet ,(loop for i to 9 collect 72 | (let ((sym (intern (concat "$" (number-to-string i))))) 73 | `(,sym (match-string ,i ,str)))) 74 | (flet (($ (i) (match-string i ,str)) 75 | (sub (replacement &optional (i 0) &key fixedcase literal-string) 76 | (replace-match replacement fixedcase literal-string ,str i))) 77 | (symbol-macrolet ( ;;before 78 | ($b (substring ,str 0 (match-beginning 0))) 79 | ;;match 80 | ($m (match-string 0 ,str)) 81 | ;;after 82 | ($a (substring ,str (match-end 0) (length ,str)))) 83 | ,@body))))))) 84 | 85 | (defun string-ext/decamelize (string) 86 | "Convert from camel_case/string to CamelCase::String." 87 | (let ((case-fold-search nil)) 88 | (replace-regexp-in-string " " "" 89 | (replace-regexp-in-string " " "::" 90 | (capitalize 91 | (replace-regexp-in-string "\_" " " 92 | (replace-regexp-in-string "\/" " " string))))))) 93 | 94 | (defalias 'decamelize-string 'string-ext/decamelize) 95 | 96 | (defun string-ext/camelize (string) 97 | "Convert from CamelCase::String to camel_case/string." 98 | (let ((case-fold-search nil)) 99 | (downcase 100 | (replace-regexp-in-string "::" "/" 101 | (replace-regexp-in-string 102 | "\\([A-Z]+\\)\\([A-Z][a-z]\\)" "\\1_\\2" 103 | (replace-regexp-in-string 104 | "\\([a-z\\d]\\)\\([A-Z]\\)" "\\1_\\2" 105 | string)))))) 106 | 107 | (defalias 'camelize-string 'string-ext/camelize) 108 | 109 | (defun string-ext/empty-p (str) ;(+) 110 | "Return t if string STR is not empty." 111 | (not (and (stringp str) 112 | (not (string-equal "" str)) 113 | (not (string-match "^ +$" str))))) 114 | 115 | (defun string-ext/safe-symbol (str) 116 | "Return symbol from STR and replace and non word chars to '-'." 117 | (intern (replace-regexp-in-string "[^a-zA-z0-9]+" "-" 118 | (downcase str)))) 119 | 120 | (provide 'string-ext) -------------------------------------------------------------------------------- /tests.rails/all.el: -------------------------------------------------------------------------------- 1 | (load "elunit") 2 | (elunit-clear-suites) 3 | 4 | (defsuite rails nil) 5 | 6 | (mapcar 7 | #'load-file 8 | (directory-files "./" t "\\.test\\.el$")) 9 | 10 | (elunit "rails") 11 | -------------------------------------------------------------------------------- /tests.rails/rails-lib.test.el: -------------------------------------------------------------------------------- 1 | (require 'elunit) 2 | (require 'rails-lib) 3 | (require 'rails-reloaded) 4 | 5 | (load-file "test-helper.el") 6 | 7 | (defsuite rails-lib rails) 8 | 9 | (deftest rails/root rails-lib 10 | (my/each-let (rails/projects) 11 | ; with current buffer 12 | ((rails/test/with-file "README" 13 | (assert-equal rails/test/root (rails/root))) 14 | (assert-equal rails/projects (list rails/test/root))) 15 | ; with specific file 16 | ((assert-equal rails/test/root (rails/root (rails/test/file "README"))) 17 | (assert-equal rails/projects (list rails/test/root))) 18 | ; with non rails root file 19 | ((assert-nil (rails/root (rails/test/file "../../README"))) 20 | (assert-nil rails/projects)))) 21 | 22 | (deftest rails/with-root rails-lib 23 | (my/each-let (rails/projects) 24 | ; with valid files 25 | ((my/assert-block-call rails/with-root (rails/test/file "README") 26 | (assert-equal rails/test/root (rails/root)) 27 | (assert-equal rails/projects (list rails/test/root)))) 28 | ; with invalid files 29 | ((my/assert-block-not-call rails/with-root (rails/test/file "../../README") 30 | (assert-nil rails/projects))))) 31 | 32 | (deftest rails/when-root rails-lib 33 | ; with valid files 34 | (my/assert-block-call rails/when-root (rails/test/file "README")) 35 | ; with invalid files 36 | (my/assert-block-not-call rails/when-root (rails/test/file "../../README"))) 37 | 38 | (deftest rails/cut-root rails-lib 39 | ; with absolute file name 40 | (assert-equal "README" (rails/cut-root (rails/test/file "README"))) 41 | ; with relative file name 42 | (assert-equal "../README" (rails/cut-root "../README"))) 43 | 44 | (deftest rails/find-existing-root-for rails-lib 45 | (my/each-let ((rails/projects (list rails/test/root))) 46 | ; valid rails file 47 | ((assert-equal rails/test/root (rails/find-existing-root-for (rails/test/file "README")))) 48 | ; valid relative rails file 49 | ((assert-equal rails/test/root (rails/find-existing-root-for (rails/test/file "app/../README")))) 50 | ; invalid rails file 51 | ((assert-nil (rails/find-existing-root-for (rails/test/file "../../README"))))) 52 | (let (rails/projects) 53 | ; valid file without existing projects 54 | (assert-nil (rails/find-existing-root-for (rails/test/file "README"))))) 55 | 56 | (deftest rails/find-root-for rails-lib 57 | (my/each-let (rails/projects) 58 | ; valid rails file 59 | ((assert-equal rails/test/root (rails/find-root-for (rails/test/file "README")))) 60 | ; valid relative rails file 61 | ((assert-equal rails/test/root (rails/find-root-for (rails/test/file "app/../README")))) 62 | ; invalid rails file 63 | ((assert-nil (rails/find-root-for (rails/test/file "../../README")))))) 64 | 65 | (deftest rails/bundle-func rails-lib 66 | (flet ((rails/foobundle/baz () t)) 67 | (assert-equal 'rails/foobundle/baz (rails/bundle-func 'foobundle "baz")) 68 | (assert-nil (rails/bundle-func 'foobundle "bar")) 69 | (assert-nil (rails/bundle-func 'bazbundle "bar")))) 70 | 71 | (deftest rails/bundle-func-by-buffer rails-lib 72 | (flet ((rails/foobundle/baz () t)) 73 | (let ((buf (make-rails/buffer :type :foobundle))) 74 | (assert-equal 'rails/foobundle/baz (rails/bundles-func-by-buffer buf "baz")) 75 | (assert-nil (rails/bundles-func-by-buffer buf "bar")) 76 | (setf (rails/buffer-type buf) :barbundle) 77 | (assert-nil (rails/bundles-func-by-buffer buf "baz"))))) 78 | 79 | (deftest rails/bundles-func rails-lib 80 | ; empty bundles 81 | (let (rails/bundles-func-list rails/bundles-list) 82 | (assert-nil (rails/bundles-func "foo"))) 83 | (let ((rails/bundles-list '(foo bar)) 84 | rails/bundles-func-list) 85 | ; caching bundles func 86 | (flet ((rails/foo/baz () t)) 87 | (flet ((rails/bar/baz () t)) 88 | (assert-equal '(rails/foo/baz rails/bar/baz) 89 | (rails/bundles-func "baz")) 90 | (assert-equal '(("baz" (rails/foo/baz rails/bar/baz))) 91 | rails/bundles-func-list))) 92 | ;; cached bundles func 93 | (assert-equal '(rails/foo/baz rails/bar/baz) 94 | (rails/bundles-func "baz")))) 95 | 96 | (deftest rails/file-exist-p rails-lib 97 | (assert (rails/file-exist-p rails/test/root "README")) 98 | (assert-nil (rails/file-exist-p rails/test/root "../README"))) 99 | 100 | (deftest rails/find-file rails-lib 101 | (rails/test/with-buffer 102 | (rails/find-file rails/test/root "README") 103 | (assert-equal (buffer-file-name) (rails/test/file "README")))) 104 | 105 | (deftest rails/group-by-goto-item-group rails-lib 106 | (let* ((item-a (make-rails/goto-item :name "a")) 107 | (item-b (make-rails/goto-item :name "b")) 108 | (item-c (make-rails/goto-item :name "c" :group :c)) 109 | (items (list item-a item-b item-c)) 110 | (expected (list (list nil (list item-a item-b)) 111 | (list :c (list item-c))))) 112 | (assert-equal expected (rails/group-by-goto-item-group items)))) 113 | 114 | (deftest rails/directory-to-goto-menu rails-lib 115 | ; default 116 | (let ((expected 117 | (list 118 | (list nil 119 | (list (make-rails/goto-item :name "application.rb" :file "app/controllers/application.rb") 120 | (make-rails/goto-item :name "posts_controller.rb" :file "app/controllers/posts_controller.rb")))))) 121 | (flet ((x-popup-menu (&rest args) nil)) 122 | (assert-equal 123 | expected 124 | (rails/directory-to-goto-menu rails/test/root 125 | "app/controllers/" 126 | "title")))) 127 | 128 | ; name-by 129 | (let ((expected 130 | (list 131 | (list nil 132 | (list (make-rails/goto-item :name "application" :file "app/controllers/application.rb") 133 | (make-rails/goto-item :name "posts_controller" :file "app/controllers/posts_controller.rb")))))) 134 | (flet ((x-popup-menu (&rest args) nil)) 135 | (assert-equal 136 | expected 137 | (rails/directory-to-goto-menu rails/test/root 138 | "app/controllers/" 139 | "title" 140 | :name-by 'file-name-sans-extension)))) 141 | 142 | ; filter-by 143 | (let ((expected 144 | (list 145 | (list nil 146 | (list (make-rails/goto-item :name "posts_controller" :file "app/controllers/posts_controller.rb")))))) 147 | (flet ((x-popup-menu (&rest args) nil)) 148 | (assert-equal 149 | expected 150 | (rails/directory-to-goto-menu rails/test/root 151 | "app/controllers/" 152 | "title" 153 | :name-by 'file-name-sans-extension 154 | :filter-by '(lambda(file) (string-ext/end-p file "_controller.rb" ) ))))) 155 | ; append 156 | (let* ((append-item 157 | (make-rails/goto-item :name "append" :file "README" :group :default)) 158 | (expected 159 | (list 160 | (list nil 161 | (list (make-rails/goto-item :name "application.rb" :file "app/controllers/application.rb") 162 | (make-rails/goto-item :name "posts_controller.rb" :file "app/controllers/posts_controller.rb"))) 163 | (list :default 164 | (list append-item))))) 165 | (flet ((x-popup-menu (&rest args) nil)) 166 | (assert-equal 167 | expected 168 | (rails/directory-to-goto-menu rails/test/root 169 | "app/controllers/" 170 | "title" 171 | :append (list append-item)))))) 172 | -------------------------------------------------------------------------------- /tests.rails/test-helper.el: -------------------------------------------------------------------------------- 1 | (defconst rails/test/root (expand-file-name "../tests.railsapp/")) 2 | 3 | (defmacro rails/test/with-file (file &rest body) 4 | `(save-window-excursion 5 | (with-temp-buffer 6 | (find-file (rails/test/file ,file)) 7 | ,@body 8 | (kill-buffer (current-buffer))))) 9 | 10 | (defmacro rails/test/with-buffer (&rest body) 11 | `(save-window-excursion 12 | (with-temp-buffer 13 | ,@body 14 | (kill-buffer (current-buffer))))) 15 | 16 | (defun rails/test/file (file) 17 | (concat rails/test/root file)) 18 | 19 | (defmacro my/each-let (let-exp &rest body) 20 | `(progn 21 | ,@(mapcar 22 | #'(lambda (expr) 23 | `(let ,let-exp 24 | ,(car expr))) 25 | body))) 26 | 27 | (defmacro my/assert-block-call (block-name block-args &rest body) 28 | `(let ((assert-val 29 | (format "%s can't called" ',block-name))) 30 | (,block-name ,block-args 31 | (setq assert-val nil) 32 | ,@body) 33 | (assert-nil assert-val))) 34 | 35 | (defmacro my/assert-block-not-call (block-name block-args &rest body) 36 | `(let (assert-val) 37 | (,block-name ,block-args 38 | (setq assert-val (format "%s called" ',block-name))) 39 | (assert-nil assert-val) 40 | ,@body)) 41 | -------------------------------------------------------------------------------- /tests/all.el: -------------------------------------------------------------------------------- 1 | (load-file 2 | (concat 3 | (file-name-directory 4 | (locate-library "rails-reloaded")) 5 | "tests/test-helper.el")) 6 | 7 | (rails/tests/load "ext/test-helper") 8 | 9 | (save-window-excursion 10 | (rails/tests/load-test "ext" "core-ext") 11 | (rails/tests/load-test "ext" "files-ext") 12 | (rails/tests/load-test "ext" "inflections") 13 | (rails/tests/load-test "ext" "string-ext")) 14 | 15 | (elk-test-run-all-buffers t) 16 | -------------------------------------------------------------------------------- /tests/app/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/README -------------------------------------------------------------------------------- /tests/app/app/controllers/application.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/controllers/application.rb -------------------------------------------------------------------------------- /tests/app/app/controllers/posts_controller.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/controllers/posts_controller.rb -------------------------------------------------------------------------------- /tests/app/app/helpers/posts_helper.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/helpers/posts_helper.rb -------------------------------------------------------------------------------- /tests/app/app/models/post.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/models/post.rb -------------------------------------------------------------------------------- /tests/app/app/views/posts/_form.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/_form.html.erb -------------------------------------------------------------------------------- /tests/app/app/views/posts/edit.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/edit.html.erb -------------------------------------------------------------------------------- /tests/app/app/views/posts/index.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/index.html.erb -------------------------------------------------------------------------------- /tests/app/app/views/posts/index.xml.builder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/index.xml.builder -------------------------------------------------------------------------------- /tests/app/app/views/posts/new.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/new.html.erb -------------------------------------------------------------------------------- /tests/app/app/views/posts/show.html.erb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/app/views/posts/show.html.erb -------------------------------------------------------------------------------- /tests/app/config/environment.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dmexe/emacs-rails-reloaded/0b95b63805ba23deb1c802f072c4d75d7d221944/tests/app/config/environment.rb -------------------------------------------------------------------------------- /tests/ext/core-ext.elk: -------------------------------------------------------------------------------- 1 | (unless (featurep 'rails-test-helper) 2 | (load-file "../test-helper.el")) 3 | 4 | (require 'core-ext) 5 | (rails/tests/load "ext/test-helper") 6 | 7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 8 | ;; 9 | ;; `when-bind' 10 | ;; 11 | 12 | (deftest "`when-bind' with function passed" 13 | (mocklet (((foo 'var) => 'passed) 14 | ((bar) => 'var)) 15 | (assert-equal 'passed 16 | (when-bind (var (bar)) 17 | (foo var))))) 18 | 19 | (deftest "`when-bind' with variable passed" 20 | (mocklet (((foo 'bar) => 'passed)) 21 | (assert-equal 'passed 22 | (when-bind (var 'bar) 23 | (foo var))))) 24 | 25 | (deftest "`when-bind' with block skiped." 26 | (assert-error "Mock error: not-called" 27 | (mocklet (((foo) => 'passed)) 28 | (when-bind (var nil) 29 | (foo))))) 30 | 31 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 32 | ;; 33 | ;; `define-keys' 34 | ;; 35 | 36 | (deftest "`define-keys' with return valid keymap" 37 | (assert-type-of 'cons (define-keys-test-map))) 38 | 39 | (deftest "`define-keys' with setup valid keys" 40 | (let ((map (define-keys-test-map))) 41 | (assert-eq 'foo (lookup-key map "\C-c a")) 42 | (assert-eq 'bar (lookup-key map "\C-c b")))) 43 | 44 | 45 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 46 | ;; 47 | ;; `funcs-chain' 48 | ;; 49 | (deftest "`funcs-chain'" 50 | (assert-equal 51 | "A" 52 | (funcall (funcs-chain 53 | capitalize 54 | string-to-list 55 | car 56 | char-to-string) "abcd"))) 57 | 58 | ;; end group 59 | -------------------------------------------------------------------------------- /tests/ext/files-ext.elk: -------------------------------------------------------------------------------- 1 | (unless (featurep 'rails-test-helper) 2 | (load-file "../test-helper.el")) 3 | 4 | 5 | (require 'core-ext) 6 | (require 'files-ext) 7 | (rails/tests/load "ext/test-helper") 8 | 9 | (deftest "`files-ext/file-special-p'" 10 | (assert-t (files-ext/file-special-p ".")) 11 | (assert-t (files-ext/file-special-p "..")) 12 | (assert-t (files-ext/file-special-p "#foo.bar")) 13 | (assert-t (files-ext/file-special-p "~foo.bar")) 14 | (assert-nil (files-ext/file-special-p "foo.bar"))) 15 | 16 | (deftest "`files-ext/find-recursive-files'" 17 | (let ((path (concat rails/tests/path "ext/")) 18 | (files '("core-ext" "files-ext" "inflections" "list-ext" "string-ext"))) 19 | (assert-equal files 20 | (files-ext/find-recursive-files 21 | 'file-name-sans-extension 22 | "\\.elk" 23 | path)))) 24 | 25 | (deftest "`files-ext/file-in-directory-p'" 26 | (assert-t (files-ext/file-in-directory-p 27 | "/Users/dima/" 28 | "/Users/dima/foo.bar")) 29 | (assert-t (files-ext/file-in-directory-p 30 | "../" "./foo")) 31 | (assert-t (files-ext/file-in-directory-p 32 | "../" "../foo")) 33 | (assert-nil (files-ext/file-in-directory-p 34 | "../" "../../foo"))) 35 | 36 | (deftest "`files-ext/file-in-directories-p'" 37 | (assert-equal "/Users/dima/" 38 | (files-ext/file-in-directories-p '("/Users/dima/" "/Users/joe/") 39 | "/Users/dima/foo.bar")) 40 | (assert-equal "../" 41 | (files-ext/file-in-directories-p '("../" "/tmp") "./foo")) 42 | (assert-equal "../" 43 | (files-ext/file-in-directories-p '("/tmp" "../" ) "../foo")) 44 | (assert-nil (files-ext/file-in-directories-p 45 | '("../" "/tmp") "../../foo"))) 46 | -------------------------------------------------------------------------------- /tests/ext/inflections.elk: -------------------------------------------------------------------------------- 1 | (unless (featurep 'rails-test-helper) 2 | (load-file "../test-helper.el")) 3 | 4 | (require 'inflections) 5 | (rails/tests/load "ext/test-helper") 6 | 7 | (deftest "inflections can loaded" 8 | (assert-nonnil inflection-singulars) 9 | (assert-nonnil inflection-plurals) 10 | (assert-nonnil inflection-irregulars) 11 | (assert-nonnil inflection-uncountables)) 12 | 13 | (deftest "Can add a new singular inflections rules" 14 | (let ((inflection-singulars inflection-singulars)) 15 | (assert-changed (length inflection-singulars) 16 | (define-inflectors 17 | (:singular "foo$" "bar") 18 | (:singular "foobar$" "baz"))) 19 | (assert-equal "testbar" (singularize-string "testfoo")) 20 | (assert-equal "testbaz" (singularize-string "testfoobar")))) 21 | 22 | (deftest "Can add a new plural inflections rules" 23 | (let ((inflection-plurals inflection-plurals)) 24 | (assert-changed (length inflection-plurals) 25 | (define-inflectors 26 | (:plural "foo$" "bar") 27 | (:plural "foobar$" "baz"))) 28 | (assert-equal "testbar" (pluralize-string "testfoo")) 29 | (assert-equal "testbaz" (pluralize-string "testfoobar")))) 30 | 31 | (deftest "Can add a new irregular inflection rules" 32 | (let ((inflection-irregulars inflection-irregulars)) 33 | (assert-changed (length inflection-irregulars) 34 | (define-inflectors 35 | (:irregular "foo" "bar") 36 | (:irregular "foobar" "baz"))) 37 | (assert-equal "bar" (pluralize-string "foo")) 38 | (assert-equal "baz" (pluralize-string "foobar")) 39 | (assert-equal "foo" (singularize-string "bar")) 40 | (assert-equal "foobar" (singularize-string "baz")))) 41 | 42 | (deftest "Can add a new uncountable inflection rules" 43 | (let ((inflection-uncountables inflection-uncountables)) 44 | (assert-changed (length inflection-uncountables) 45 | (define-inflectors 46 | (:uncountable "foo" "bar"))) 47 | (assert-equal "foo" (pluralize-string "foo")) 48 | (assert-equal "foo" (singularize-string "foo")) 49 | (assert-equal "bar" (pluralize-string "bar")) 50 | (assert-equal "bar" (singularize-string "bar")))) -------------------------------------------------------------------------------- /tests/ext/list-ext.elk: -------------------------------------------------------------------------------- 1 | (unless (featurep 'rails-test-helper) 2 | (load-file "../test-helper.el")) 3 | 4 | 5 | (require 'list-ext) 6 | (rails/tests/load "ext/test-helper") 7 | 8 | (deftest "`list-ext/uniq'" 9 | (assert-equal '(1 2) (list-ext/uniq '(1 1 2 2))) 10 | (assert-equal '(1 2 3) (list-ext/uniq '(1 1 2 2 3))) 11 | (assert-equal '(1 2) (list-ext/uniq '(1 2)))) 12 | 13 | (deftest "`list-ext/group-by'" 14 | (let ((list '((:a 1) 15 | (:b 2) 16 | (:a 3) 17 | (:b 4) 18 | (:c 5)))) 19 | (assert-equal '((:a ((:a 1) (:a 3))) 20 | (:b ((:b 2) (:b 4))) 21 | (:c ((:c 5)))) 22 | (list-ext/group-by 23 | list 24 | 'car)))) 25 | 26 | (deftest "`list-ext/options-value'" 27 | (let ((options '(:one 1 :two 2 :three 3))) 28 | (assert-equal 1 (list-ext/options-value :one options)) 29 | (assert-equal 2 (list-ext/options-value :two options)) 30 | (assert-equal 3 (list-ext/options-value :three options)) 31 | (assert-nil (list-ext/options-value :foo options)))) 32 | 33 | (deftest "`list-ext/swap-tail'" 34 | (let ((list '(1 2 3 4 5))) 35 | (assert-equal '(3 4 5 1 2) (list-ext/swap-tail 3 list)) 36 | (assert-equal '(2 3 4 5 1) (list-ext/swap-tail 2 list)) 37 | (assert-equal '(4 5 1 2 3) (list-ext/swap-tail 4 list)) 38 | (assert-nil (list-ext/swap-tail 0 list)) 39 | (assert-nil (list-ext/swap-tail 6 list)))) 40 | -------------------------------------------------------------------------------- /tests/ext/string-ext.elk: -------------------------------------------------------------------------------- 1 | (unless (featurep 'rails-test-helper) 2 | (load-file "../test-helper.el")) 3 | 4 | (require 'string-ext) 5 | (rails/tests/load "ext/test-helper") 6 | 7 | (deftest "`string-ext/cut'" 8 | (assert-equal "ing" (string-ext/cut "String" "Str" :begin)) 9 | (assert-equal "" (string-ext/cut "String" "String" :begin)) 10 | 11 | (assert-nil (string-ext/cut "String" "Str2" :begin)) 12 | (assert-nil (string-ext/cut "String" "String2" :begin)) 13 | 14 | (assert-equal "Str" (string-ext/cut "String" "ing" :end)) 15 | (assert-equal "" (string-ext/cut "String" "String" :end)) 16 | 17 | (assert-nil (string-ext/cut "String" "ing2" :end)) 18 | (assert-nil (string-ext/cut "String" "String2" :end))) 19 | 20 | (deftest "`string-ext/cut-safe'" 21 | (assert-equal "Str" (string-ext/cut-safe "String" "ing" :end)) 22 | (assert-equal "ing" (string-ext/cut-safe "String" "Str" :begin)) 23 | (assert-equal "String" (string-ext/cut-safe "String" "Str" :end)) 24 | (assert-equal "String" (string-ext/cut-safe "String" "ing" :begin))) 25 | 26 | (deftest "`string-ext/from-symbol'" 27 | (assert-equal "sym" (string-ext/from-symbol :sym)) 28 | (assert-equal "sym" (string-ext/from-symbol 'sym))) 29 | 30 | (deftest "`string-ext/start-p'" 31 | (assert (string-ext/start-p "String" "Str")) 32 | (assert-nil (string-ext/start-p "String" "ing"))) 33 | 34 | (deftest "`string-ext/end-p'" 35 | (assert (string-ext/end-p "String" "ing")) 36 | (assert-nil (string-ext/end-p "String" "Str"))) 37 | 38 | (deftest "`string-ext/string=~'" 39 | (let ((str "One Two Three")) 40 | (assert-equal "Two" (string-ext/string=~ "\\(Two\\)" str $1)) 41 | (assert-equal "Three" (string-ext/string=~ "\\(One\\) \\(Two\\) \\(\Three\\)" str $3)) 42 | (assert-equal "One " (string-ext/string=~ "\\(Two\\)" str $b)) 43 | (assert-equal " Three" (string-ext/string=~ "\\(Two\\)" str $a)) 44 | (assert-equal "One" (string-ext/string=~ "\\(One\\)" str $m)) 45 | (let ((re "\\(NoExist\\)")) 46 | (assert-nil (string-ext/string=~ re str $b)) 47 | (assert-nil (string-ext/string=~ re str $m)) 48 | (assert-nil (string-ext/string=~ re str $a)) 49 | (assert-nil (string-ext/string=~ re str $$1))))) 50 | 51 | (deftest "`string-ext/decamelize'" 52 | (assert-equal "CamelCase" (string-ext/decamelize "camel_case")) 53 | (assert-equal "Camelcase" (string-ext/decamelize "CamelCase")) 54 | (assert-equal "CamelCase::StrIng" (string-ext/decamelize "camel_case/str_ing")) 55 | (assert-equal "2camelCase::StrIng" (string-ext/decamelize "2camel_case/str_ing"))) 56 | 57 | (deftest "`string-ext/camelize'" 58 | (assert-equal "camel_case" (string-ext/camelize "CamelCase")) 59 | (assert-equal "camel_case/str_ing" (string-ext/camelize "CamelCase::StrIng")) 60 | (assert-equal "2camel_case/str_ing" (string-ext/camelize "2camelCase::StrIng"))) 61 | 62 | (deftest "`string-ext/camelize'" 63 | (assert-equal "camel_case" (string-ext/camelize "CamelCase")) 64 | (assert-equal "camel_case/str_ing" (string-ext/camelize "CamelCase::StrIng")) 65 | (assert-equal "2camel_case/str_ing" (string-ext/camelize "2camelCase::StrIng"))) 66 | 67 | (deftest "`string-ext/empty-p'" 68 | (assert (string-ext/empty-p "")) 69 | (assert (string-ext/empty-p " ")) 70 | (assert-nil (string-ext/empty-p " as "))) 71 | 72 | (deftest "`string-ext/safe-symbol'" 73 | (assert-equal 'test (string-ext/safe-symbol "Test")) 74 | (assert-equal 'test-foo (string-ext/safe-symbol "Test Foo"))) 75 | -------------------------------------------------------------------------------- /tests/ext/test-helper.el: -------------------------------------------------------------------------------- 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | ;; core-ext 3 | (defun define-keys-test-map () 4 | (let ((map (make-sparse-keymap))) 5 | (define-keys map 6 | ("\C-c a" 'foo) 7 | ("\C-c b" 'bar)))) 8 | -------------------------------------------------------------------------------- /tests/fringe-helper.el: -------------------------------------------------------------------------------- 1 | ;;; fringe-helper.el --- helper functions for fringe bitmaps 2 | ;; 3 | ;; Copyright (C) 2008 Nikolaj Schumacher 4 | ;; 5 | ;; Author: Nikolaj Schumacher 6 | ;; Version: 0.1.1 7 | ;; Keywords: lisp 8 | ;; URL: http://nschum.de/src/emacs/fringe-helper/ 9 | ;; Compatibility: GNU Emacs 22.x 10 | ;; 11 | ;; This file is NOT part of GNU Emacs. 12 | ;; 13 | ;; This program is free software; you can redistribute it and/or 14 | ;; modify it under the terms of the GNU General Public License 15 | ;; as published by the Free Software Foundation; either version 2 16 | ;; of the License, or (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 | ;;; Commentary: 27 | ;; 28 | ;; fringe-helper contains helper functions for fringe bitmaps. 29 | ;; 30 | ;; `fringe-helper-define' allows you to to define fringe bitmaps using a visual 31 | ;; string replesentation. For example: 32 | ;; 33 | ;; (fringe-helper-define 'test-bitmap '(top repeat) 34 | ;; "XX......" 35 | ;; "..XX...." 36 | ;; "....XX.." 37 | ;; "......XX") 38 | ;; 39 | ;; You can also generate arguments for `define-fringe-bitmap' yourself, by 40 | ;; using `fringe-helper-convert'. 41 | ;; 42 | ;; fringe-helper also provides a few stock bitmaps. They are loaded on demand 43 | ;; by `fringe-lib-load' and adapt to the current fringe size to a certain 44 | ;; extend. 45 | ;; 46 | ;; `fringe-helper-insert' inserts a fringe bitmap at point and 47 | ;; `fringe-helper-insert-region' inserts a fringe bitmap along a region. 48 | ;; `fringe-helper-remove' removes both kinds. 49 | ;; 50 | ;; 51 | ;; Here's an example for enhancing `flymake-mode' with fringe bitmaps: 52 | ;; 53 | ;; (require 'fringe-helper) 54 | ;; (require 'flymake) 55 | ;; 56 | ;; (defvar flymake-fringe-overlays nil) 57 | ;; (make-variable-buffer-local 'flymake-fringe-overlays) 58 | ;; 59 | ;; (defadvice flymake-make-overlay (after add-to-fringe first 60 | ;; (beg end tooltip-text face mouse-face) 61 | ;; activate compile) 62 | ;; (push (fringe-helper-insert-region 63 | ;; beg end 64 | ;; (fringe-lib-load (if (eq face 'flymake-errline) 65 | ;; fringe-lib-exclamation-mark 66 | ;; fringe-lib-question-mark)) 67 | ;; 'left-fringe 'font-lock-warning-face) 68 | ;; flymake-fringe-overlays)) 69 | ;; 70 | ;; (defadvice flymake-delete-own-overlays (after remove-from-fringe activate 71 | ;; compile) 72 | ;; (mapc 'fringe-helper-remove flymake-fringe-overlays) 73 | ;; (setq flymake-fringe-overlays nil)) 74 | ;; 75 | ;; 76 | ;;; Change Log: 77 | ;; 78 | ;; 2008-06-04 (0.1.1) 79 | ;; Fixed bug where `fringe-helper-remove' missed overlays at the end. 80 | ;; Fixed `fringe-lib-load' to work when already loaded. 81 | ;; 82 | ;; 2008-04-25 (0.1) 83 | ;; Initial release. 84 | ;; 85 | ;;; Code: 86 | 87 | (eval-when-compile (require 'cl)) 88 | 89 | (defun fringe-helper-convert (&rest strings) 90 | "Convert STRINGS into a vector usable for `define-fringe-bitmap'. 91 | Each string in STRINGS represents a line of the fringe bitmap. 92 | Periods (.) are background-colored pixel; Xs are foreground-colored. The 93 | fringe bitmap always is aligned to the right. If the fringe has half 94 | width, only the left 4 pixels of an 8 pixel bitmap will be shown. 95 | 96 | For example, the following code defines a diagonal line. 97 | 98 | \(fringe-helper-convert 99 | \"XX......\" 100 | \"..XX....\" 101 | \"....XX..\" 102 | \"......XX\"\)" 103 | (unless (cdr strings) 104 | ;; only one string, probably with newlines 105 | (setq strings (split-string (car strings) "\n"))) 106 | (apply 'vector 107 | (mapcar (lambda (str) 108 | (let ((num 0)) 109 | (dolist (c (string-to-list str)) 110 | (setq num (+ (* num 2) (if (eq c ?.) 0 1)))) 111 | num)) 112 | strings))) 113 | 114 | (defmacro fringe-helper-define (name alignment &rest strings) 115 | "Define a fringe bitmap from a visual representation. 116 | Parameters NAME and ALIGNMENT are the same as `define-fringe-bitmap'. 117 | Each string in STRINGS represents a line of the fringe bitmap as in 118 | `fringe-helper-convert'." 119 | (declare (indent defun)) 120 | `(define-fringe-bitmap ,name 121 | (eval-when-compile (fringe-helper-convert ,@strings)) 122 | nil nil ,alignment)) 123 | 124 | (defun fringe-helper-insert (bitmap pos &optional side face) 125 | "Insert a fringe bitmap at POS. 126 | BITMAP is the name of a bitmap defined with `define-fringe-bitmap' or 127 | `fringe-helper-define'. SIDE defaults to 'left-fringe and can also be 128 | 'right-fringe. FACE is used to determine the bitmap's color. 129 | The function returns an object suitable for passing to 130 | `fringe-helper-remove'." 131 | (let* ((display-string `(,(or side 'left-fringe) ,bitmap . 132 | ,(when face (cons face nil)))) 133 | (before-string (propertize "!" 'display display-string)) 134 | (ov (make-overlay pos pos))) 135 | (overlay-put ov 'before-string before-string) 136 | (overlay-put ov 'fringe-helper t) 137 | ov)) 138 | 139 | (defun fringe-helper-insert-region (beg end bitmap side &optional face) 140 | "Insert fringe bitmaps between BEG and END. 141 | BITMAP is the name of a bitmap defined with `define-fringe-bitmap' or 142 | `fringe-helper-define'. SIDE defaults to 'left-fringe and can also be 143 | 'right-fringe. FACE is used to determine the bitmap's color. The 144 | function returns an overlay covering the entire region, which is suitable 145 | for passing to `fringe-helper-remove'. The region grows and shrinks with 146 | input automatically." 147 | (let* ((display-string `(,(or side 'left-fringe) ,bitmap . 148 | ,(when face (cons face nil)))) 149 | (before-string (propertize "!" 'display display-string)) 150 | (parent (make-overlay beg end)) 151 | ov) 152 | (save-excursion 153 | (goto-char beg) 154 | (goto-char (point-at-bol 2)) 155 | ;; can't use <= here, or we'll get an infinity loop at buffer end 156 | (while (and (<= (point) end) (< (point) (point-max))) 157 | (setq ov (make-overlay (point) (point))) 158 | (overlay-put ov 'before-string before-string) 159 | (overlay-put ov 'fringe-helper-parent parent) 160 | (goto-char (point-at-bol 2)))) 161 | (overlay-put parent 'fringe-helper t) 162 | (overlay-put parent 'before-string before-string) 163 | (overlay-put parent 'insert-in-front-hooks 164 | '(fringe-helper-modification-func)) 165 | (overlay-put parent 'modification-hooks 166 | '(fringe-helper-modification-func)) 167 | parent)) 168 | 169 | (defun fringe-helper-modification-func (ov after-p beg end &optional len) 170 | (if after-p 171 | (if (eq beg end) 172 | ;; evaporate overlay 173 | (when (= (overlay-start ov) (overlay-end ov)) 174 | (delete-overlay ov)) 175 | ;; if new lines are inserted, add new bitmaps 176 | (let ((before-string (overlay-get ov 'before-string)) 177 | fringe-ov) 178 | (save-excursion 179 | (goto-char beg) 180 | (while (search-forward "\n" end t) 181 | (setq fringe-ov (make-overlay (point) (point))) 182 | (overlay-put fringe-ov 'before-string before-string) 183 | (overlay-put fringe-ov 'fringe-helper-parent ov))))) 184 | ;; if a \n is removed, remove the fringe overlay 185 | (unless (= beg end) 186 | (setq beg (max beg (overlay-start ov))) 187 | (setq end (min end (overlay-end ov))) 188 | (save-excursion 189 | (goto-char beg) 190 | (while (search-forward "\n" end t) 191 | (let ((overlays (overlays-in (point) (1+ (point))))) 192 | (while overlays 193 | (when (eq (overlay-get (car overlays) 'fringe-helper-parent) ov) 194 | (delete-overlay (car overlays)) 195 | (setq overlays nil)) 196 | (pop overlays)))))))) 197 | 198 | (defun fringe-helper-remove (fringe-bitmap-reference) 199 | "Remove a fringe bitmap." 200 | (unless (or (not (overlay-buffer fringe-bitmap-reference)) 201 | (overlay-get fringe-bitmap-reference 'fringe-helper-parent)) 202 | ;; region 203 | (dolist (ov (overlays-in (overlay-start fringe-bitmap-reference) 204 | (1+ (overlay-end fringe-bitmap-reference)))) 205 | (when (eq (overlay-get ov 'fringe-helper-parent) fringe-bitmap-reference) 206 | (delete-overlay ov))) 207 | (delete-overlay fringe-bitmap-reference))) 208 | 209 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 210 | 211 | (defun fringe-lib-load (pattern &optional side) 212 | "Load a stock bitmap. 213 | It returns the symbol name of the loaded bitmap, which is suitable for passing 214 | to `fringe-helper-insert'. The actual work of defining the bitmap is only done once. 215 | PATTERN can be one of the following: 216 | 217 | `fringe-lib-exclamation-mark': an exclamation mark 218 | 219 | `fringe-lib-question-mark': a question mark 220 | 221 | `fringe-lib-zig-zag': a zig-zag pattern 222 | 223 | `fringe-lib-wave': a wavy-line pattern 224 | 225 | `fringe-lib-stipple': a stipple pattern 226 | 227 | `fringe-lib-full': a solid color 228 | 229 | SIDE should be either 'left-fringe or 'right-fringe and defaults to the former." 230 | (let ((fringe-width (frame-parameter (selected-frame) 231 | (or side 'left-fringe))) 232 | (alignment (when (eq (car pattern) 'repeat) 233 | (setq pattern (cdr pattern)) 234 | '(top t)))) 235 | (while (> (caar pattern) fringe-width) 236 | (pop pattern)) 237 | (setq pattern (cdar pattern)) 238 | (or (car (memq (car pattern) fringe-bitmaps)) 239 | (define-fringe-bitmap (car pattern) (cdr pattern) nil nil alignment)))) 240 | 241 | 242 | (defconst fringe-lib-exclamation-mark 243 | `((5 fringe-lib-exclamation-mark-5 . 244 | ,(eval-when-compile 245 | (fringe-helper-convert "...XX..." 246 | "..XXXX.." 247 | "..XXXX.." 248 | "...XX..." 249 | "...XX..." 250 | "........" 251 | "........" 252 | "...XX..." 253 | "...XX..."))) 254 | (0 fringe-lib-exclamation-mark-0 . 255 | ,(eval-when-compile 256 | (fringe-helper-convert ".XX....." 257 | ".XX....." 258 | ".XX....." 259 | ".XX....." 260 | ".XX....." 261 | "........" 262 | "........" 263 | ".XX....." 264 | ".XX....."))))) 265 | 266 | (defconst fringe-lib-question-mark 267 | `((5 fringe-lib-question-mark-5 . 268 | ,(eval-when-compile 269 | (fringe-helper-convert "...XX..." 270 | "..XXXX.." 271 | "..X..X.." 272 | "....XX.." 273 | "...XX..." 274 | "...XX..." 275 | "........" 276 | "...XX..." 277 | "...XX..."))) 278 | (0 fringe-lib-question-mark-0 . 279 | ,(eval-when-compile 280 | (fringe-helper-convert ".XX....." 281 | "XXXX...." 282 | "X..X...." 283 | "..XX...." 284 | ".XX....." 285 | ".XX....." 286 | "........" 287 | ".XX....." 288 | ".XX....."))))) 289 | 290 | (defconst fringe-lib-zig-zag 291 | `(repeat 292 | (0 fringe-lib-zig-zag-0 . 293 | ,(eval-when-compile 294 | (fringe-helper-convert "X......." 295 | "X......." 296 | ".X......" 297 | ".X......" 298 | "..X....." 299 | "..X....." 300 | ".X......" 301 | ".X......"))))) 302 | 303 | (defconst fringe-lib-wave 304 | `(repeat 305 | (0 fringe-lib-wave-0 . 306 | ,(eval-when-compile 307 | (fringe-helper-convert "X......." 308 | ".X......" 309 | "..X....." 310 | "..X....." 311 | "..X....." 312 | ".X......" 313 | "X......." 314 | "X......."))))) 315 | 316 | (defconst fringe-lib-stipple 317 | `(repeat 318 | (0 fringe-lib-stipple-0 . 319 | ,(eval-when-compile 320 | (fringe-helper-convert "XXXXXXXX" 321 | "XXXXXXXX" 322 | "XXXXXXXX" 323 | "........" 324 | "........" 325 | "........"))))) 326 | 327 | (defconst fringe-lib-full 328 | `(repeat 329 | (0 fringe-lib-full-0 . 330 | ,(eval-when-compile 331 | (fringe-helper-convert "XXXXXXXX"))))) 332 | 333 | (provide 'fringe-helper) 334 | ;;; fringe-helper.el ends here 335 | -------------------------------------------------------------------------------- /tests/test-helper.el: -------------------------------------------------------------------------------- 1 | (defvar rails/tests/path 2 | (concat 3 | (file-name-directory 4 | (locate-library "rails-reloaded")) 5 | "tests/")) 6 | 7 | (defun rails/tests/load (file) 8 | (load-file (concat rails/tests/path file ".el"))) 9 | 10 | (defun rails/tests/load-test (lib file) 11 | (find-file (concat rails/tests/path lib "/" file ".elk"))) 12 | 13 | (rails/tests/load "el-mock") 14 | (rails/tests/load "fringe-helper") 15 | (rails/tests/load "elk-test") 16 | 17 | (add-to-list 'auto-mode-alist '("\\.elk\\'" . elk-test-mode)) 18 | 19 | (defmacro assert-type-of (expected actual) 20 | "Assert that ALTUAL is type of EXPECTED." 21 | `(unless (eq ,expected ',(type-of actual)) 22 | (error "assert-type-of for <%s> failed: expected type <%s>, was <%s>" 23 | ',(type-of actual) ,expected ',(type-of actual)))) 24 | 25 | (defmacro assert-changed (changed-value &rest body) 26 | "Assert changed CHANGED-VALUE after eval BODY." 27 | `(let ((old-changed-value ,changed-value)) 28 | ,@body 29 | (when (equal ,changed-value old-changed-value) 30 | (error "assert-changed for <%s> failed: <%s> equal <%s>" 31 | ',body ,changed-value old-changed-value)))) 32 | 33 | (provide 'rails-test-helper) 34 | --------------------------------------------------------------------------------