├── COPYING ├── GF-QuickStart ├── GF-README ├── Readme.md ├── elscreen-buffer-list.el ├── elscreen-color-theme.el ├── elscreen-dired.el ├── elscreen-dnd.el ├── elscreen-gf.el ├── elscreen-goby.el ├── elscreen-howm.el ├── elscreen-server.el ├── elscreen-speedbar.el ├── elscreen-w3m.el ├── elscreen-wl.el └── elscreen.el /COPYING: -------------------------------------------------------------------------------- 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. 340 | -------------------------------------------------------------------------------- /GF-QuickStart: -------------------------------------------------------------------------------- 1 | ElScreen-GF 1.5.3 Quick Start Guide 2 | 3 | 1) Install ElScreen, ElScreen-GF. 4 | 2) Make sure that the grep on your system is GNU-compatible. 5 | 3) Visit a source code you want to read. 6 | 4) Put the cursor on the keyword you want to search. 7 | 5) Type `C-z C-g G', and `RET'. 8 | 6) Select line you want to jump to. 9 | 7) Type `O'. 10 | 11 | ElScreen-GF also supports GNU ID Utils, cscope and GNU GLOBAL as an 12 | external program to search keywords. For more detail, please refer 13 | README file in this tarball. 14 | -------------------------------------------------------------------------------- /GF-README: -------------------------------------------------------------------------------- 1 | ElScreen-GF 1.5.3 README file 2 | 3 | This is the distribution of ElScreen-GF 1.5.3, released November 2007. 4 | It is an Emacs interface to GNU grep (or its compatibles), GNU ID 5 | Utils, cscope, and GNU GLOBAL. ElScreen-GF makes it easier to search 6 | keyword or token in source codes, list the results, and jump to them. 7 | This will help you to read or hack source codes, especially in a big 8 | source tree. 9 | 10 | It works with ElScreen 1.4.0 or later, on GNU Emacs 21 or later and 11 | XEmacs 21.4 or later. Enjoy! 12 | 13 | 14 | External Programs 15 | ----------------- 16 | ElScreen-GF supports the followings as external program: 17 | 18 | - GNU grep (http://www.gnu.org/software/grep/grep.html) 19 | 20 | grep is famous utility to print lines matching the specified 21 | pattern. GNU grep has several extended features to traditional 22 | grep. Nowadays major state-of-the-art OS may have GNU grep or its 23 | compatible one. 24 | 25 | - GNU ID Utils (http://www.gnu.org/software/idutils/idutils.html) 26 | 27 | This is language-independent (but currently supports C, C++, 28 | Assembly, text. Perl also seems to be supported in the CVS HEAD) 29 | identifier database tool, which stores tokens, literal numbers, or 30 | words of human-readable text. 31 | 32 | - cscope (http://cscope.sourceforge.net/) 33 | 34 | cscope is an interactive tool that allows you to browse through C 35 | source files for specified elements of code. This provides you 36 | the curses-based screen-oriented interface, but ElScreen-GF uses 37 | only line-oriented interface. In addition, ElScreen-GF uses `sort' 38 | to sort its output. 39 | 40 | - GNU GLOBAL (http://www.gnu.org/software/global/) 41 | 42 | GNU GLOBAL is an yet another source code tag system. You can 43 | locate a symbol in the source files. In addition, ElScreen-GF 44 | uses `sort' to sort its output. 45 | 46 | 47 | Files 48 | ----- 49 | This package should contain the following files: 50 | 51 | elscreen-gf.el ElScreen-GF 1.5.3 main file. 52 | README Introduction to ElScreen-GF 1.5.3 (this file) 53 | QuickStart Quick Start Guide 54 | 55 | 56 | Installation 57 | ------------ 58 | Make sure that you have installed ElScreen. Put elscreen-gf.el in 59 | this directory to your load-path, and put following line just next to 60 | ElScreen entry: 61 | 62 | (load "elscreen-gf" "ElScreen-GF" t) 63 | 64 | As mentioned above, you also have to install one of supported external 65 | programs. Please refer their own manuals for more detail. 66 | 67 | 68 | Usage 69 | ----- 70 | The following sequences may valid on ElScreen: 71 | 72 | C-z ElScreen prefix key 73 | C-z C-g ElScreen-GF prefix key 74 | C-z C-g G Run grep 75 | C-z C-g g Run gid (GNU ID Utils) 76 | C-z C-g m Run mkid (GNU ID Utils) 77 | C-z C-g c Run cscope 78 | C-z C-g l Run global (GNU GLOBAL) 79 | C-z C-g t Run gtags (GNU GLOBAL) 80 | C-z C-g u Go back to the point where the previous search 81 | was invoked. 82 | C-z C-g v Show ElScreen-GF version. 83 | 84 | Although a token around the cursor is shown as default value for grep, 85 | gid, cscope and global, you can specify other keyword. Regexp is also 86 | accepted. Once you run grep, gid, cscope or global, ElScreen-GF 87 | buffer is created and becomes active. In this buffer, you may use 88 | following keys: 89 | 90 | n Move cursor to the next entry, vertically down. 91 | p Move cursor to the previous entry, vertically up. 92 | SPC Scroll entries upward full screen. 93 | DEL Scroll entries downward full screen. 94 | < Move cursor to the first entry. 95 | > Move cursor to the last entry. 96 | N Move cursor to the first entry of the next source 97 | file. 98 | P Move cursor to the first entry of the previous 99 | source file. 100 | t Toggle truncated lines. 101 | o Jump to the file and line that the selected entry 102 | specifies. 103 | O Likewise, except the buffer is set to read-only. 104 | C-g Delete running grep, gid, cscope or global process. 105 | q Exit from ElScreen-GF mode. This deletes 106 | ElScreen-GF buffer and its window (or screen when 107 | there is only one window). 108 | v Show ElScreen-GF version. 109 | 110 | 111 | Setup 112 | ----- 113 | You can set the following variables to configure ElScreen-GF. These 114 | can be set in .emacs (or .emacs.d/init.el) file directly or "Options" 115 | in your menu bar. 116 | 117 | elscreen-gf-grep-program-name 118 | elscreen-gf-idutils-gid-program-name 119 | elscreen-gf-idutils-mkid-program-name 120 | elscreen-gf-cscope-program-name 121 | elscreen-gf-global-program-name 122 | elscreen-gf-global-gtags-program-name 123 | 124 | Name of external programs. 125 | 126 | elscreen-gf-mode-truncate-lines 127 | 128 | If non nil, each line of result in the ElScreen-GF mode is 129 | shown in truncated manner by default. The default value is 130 | `t'. 131 | 132 | elscreen-gf-invoke-point-history-length 133 | 134 | Maximum number of invoke-point stored by ElScreen-GF. 135 | invoke-point is the location where gf searches were invoked. 136 | 137 | elscreen-gf-mode-selected-entry-face 138 | 139 | Face used for the selected entry in ElScreen-GF mode. 140 | 141 | elscreen-gf-mode-file-name-face 142 | 143 | Face used for file name in ElScreen-GF mode. 144 | 145 | elscreen-gf-mode-line-number-face 146 | 147 | Face used for line number in ElScreen-GF mode. 148 | 149 | elscreen-gf-mode-pattern-face 150 | 151 | Face used to emphasize the specified keyword in ElScreen-GF 152 | mode. 153 | 154 | elscreen-gf-emphasis-after-jump-face 155 | 156 | Face used to emphasize the selected line after jump. 157 | 158 | 159 | Automatic Database Update 160 | ------------------------- 161 | You can update `ID' GNU ID Utils database or `GTAGS' GNU GLOBAL 162 | database after saveing buffer with using 163 | 164 | elscreen-gf-idutils-mkid-setup-after-save-hook 165 | elscreen-gf-global-gtags-setup-after-save-hook 166 | 167 | for GNU ID Utils and GNU GLOBAL respectively. For instance, you can 168 | add following lines to update `ID' database when saving C source code: 169 | 170 | (add-hook 'c-mode-hook 'elscreen-gf-idutils-mkid-setup-after-save-hook) 171 | 172 | 173 | Where Can I Get ElScreen-GF? 174 | ---------------------------- 175 | ElScreen-GF (and ElScreen) is available from the following anonymous 176 | ftp site. 177 | 178 | ftp://ftp.morishima.net/pub/morishima.net/naoto/ElScreen/ 179 | 180 | 181 | Bug Reports 182 | ----------- 183 | ElScreen-GF is maintained by Naoto Morishima. Please mail bug 184 | reports and any comments to: 185 | 186 | naoto@morishima.net 187 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ElScreen 2 | ========== 3 | 4 | 5 | This is a fork of 6 | [ElScreen](http://www.morishima.net/~naoto/elscreen-en/?lang=en) 7 | updated for Emacs 24 and `package.el`. ElScreen is an Emacs utility 8 | with which you can have multiple screens (window-configuration) on 9 | your GNU Emacs as well as GNU screen on terminal. 10 | 11 | If you use emacs-lisp applications which have many windows (like 12 | Gnus, irchat, Wanderlust, Mew...), ElScreen makes it easy to 13 | switch to a different screen, with its configuration unchanged. 14 | You can also create and kill screen, jump to them, rename the 15 | screen, and so on. 16 | 17 | This version of ElScreen does not require any external dependencies. 18 | 19 | 20 | Installation 21 | ------------ 22 | 23 | 24 | The preferred way to install ElScreen is through 25 | [MELPA](https://melpa.org/) and `package.el`. If you have Emacs 24, 26 | you should already have `package.el`. To enable MELPA, add something 27 | like the following in your `.emacs.d` file: 28 | 29 | (add-to-list 'package-archives 30 | '("melpa" . "https://melpa.org/packages/") t) 31 | 32 | Once you have installed ElScreen, you can activate it like so: 33 | 34 | (elscreen-start) 35 | 36 | 37 | Usage 38 | ----- 39 | You may use following sequences on ElScreen: 40 | 41 | `C-z c`
42 | `C-z C-c`
43 | Create a new screen and switch to it. 44 | 45 | `C-z C`
46 | Create a new screen with the window-configuration of 47 | the current screen. 48 | 49 | `C-z k`
50 | `C-z C-k`
51 | Kill current screen. 52 | 53 | `C-z M-k`
54 | Kill current screen and buffers. 55 | 56 | `C-z K`
57 | Kill other screens. 58 | 59 | `C-z n`
60 | `C-z C-n`
61 | Switch to the "next" screen in a cyclic order. 62 | 63 | `C-z p`
64 | `C-z C-p`
65 | Switch to the "previous" screen in a cyclic order. 66 | 67 | `C-z a`
68 | `C-z C-a`
69 | Toggle to the screen selected previously. 70 | 71 | `C-z '`
72 | Prompt for a screen number to switch to. 73 | 74 | `C-z "`
75 | Present a list of all screens for selection. 76 | 77 | `C-z 0..9`
78 | Jump to the screen number 0-9. 79 | 80 | `C-z C-s`
81 | Swap current screen with previous one. 82 | 83 | `C-z w`
84 | `C-z C-w`
85 | Show a list of screen. 86 | 87 | `C-z A`
88 | Allow the user to enter a name for the current screen. 89 | 90 | `C-z m`
91 | `C-z C-m`
92 | Repeat the last message displayed in the mini-buffer. 93 | 94 | `C-z t`
95 | `C-z C-t`
96 | 97 | `C-z b`
98 | Switch to the screen in which specified buffer is 99 | splayed. 100 | 101 | `C-z C-f`
102 | Create new screen and open file. 103 | 104 | `C-z C-r`
105 | Create new screen and open file but don't allow changes. 106 | 107 | `C-z d`
108 | Create new screen and run dired. 109 | 110 | `C-z M-x`
111 | Read function name, then call it with new screen. 112 | 113 | `C-z i`
114 | Show/hide the screen number in the mode line. 115 | 116 | `C-z T`
117 | Show/hide the tab on the top of each frame. 118 | 119 | `C-z v`
120 | Display ElScreen version. 121 | 122 | `C-z ?`
123 | Show key bindings of ElScreen and Add-On softwares. 124 | 125 | 126 | 127 | Setup 128 | ----- 129 | You can set the following variables to configure ElScreen. These 130 | can be set in `.emacs` file directly or "Options" in your menu bar. 131 | 132 | elscreen-prefix-key 133 | 134 | ElScreen prefix-key. The default value is `\C-z`. 135 | 136 | elscreen-buffer-to-nickname-alist 137 | 138 | The pairs of buffer-name and corresponding screen nickname or function 139 | that returns nickname, which are listed by 140 | `elscreen-display-screen-name-list` only when major-mode cannot 141 | determine its screen nickname. The default value is: 142 | 143 | '(("^dired-mode$" . 144 | (lambda () 145 | (format "Dired(%s)" dired-directory))) 146 | ("^Info-mode$" . 147 | (lambda () 148 | (format "Info(%s)" (file-name-nondirectory Info-current-file)))) 149 | ("^mew-draft-mode$" . 150 | (lambda () 151 | (format "Mew(%s)" (buffer-name (current-buffer))))) 152 | ("^mew-" . "Mew") 153 | ("^irchat-" . "IRChat") 154 | ("^liece-" . "Liece") 155 | ("^lookup-" . "Lookup")) 156 | 157 | elscreen-mode-to-nickname-alist 158 | 159 | The pairs of major-mode and corresponding screen nickname or function 160 | that returns nickname, which are listed by 161 | `elscreen-display-screen-name-list`. The default value is: 162 | 163 | '(("[Ss]hell" . "shell") 164 | ("compilation" . "compile") 165 | ("-telnet" . "telnet") 166 | ("dict" . "OnlineDict") 167 | ("*WL:Message*" . "Wanderlust")) 168 | 169 | elscreen-startup-command-line-processing 170 | 171 | If non `nil`, ElScreen processes command line arguments of Emacsen when 172 | starting up, and opens files with new screens if needed. The default 173 | value is `t`. 174 | 175 | elscreen-display-screen-number 176 | 177 | If non `nil`, show the number of the current screen in mode line. The 178 | default value is `t`. 179 | 180 | elscreen-display-tab 181 | 182 | Specify how the tabs at the top of frame should be displayed. `t` means 183 | to display tabs whose width should be calculated automatically. A 184 | value of integer means to display tabs with fixed width of this value. 185 | `nil` means don't display tabs. The default value is `t`. 186 | 187 | elscreen-tab-display-control 188 | 189 | If non `nil`, display the tab (labeled with `[<->]`) to switch to 190 | next/previous screen or create new screen at the most left side of the 191 | tab line. The default value is `t`. 192 | 193 | elscreen-tab-display-kill-screen 194 | 195 | Location of the icon (`[X]`) to kill corresponding screen on each tab. 196 | Possible values are `'left`, `'right` and `nil` (to hide icons). The 197 | default value is `'left`. 198 | 199 | 200 | Bugs 201 | ---- 202 | Under multiple-frame environment, screen numbers displayed on mode 203 | line of each frame is changed at the same time. On GNU Emacs 21, tabs 204 | also has this restriction. 205 | 206 | 207 | Acknowledgment 208 | -------------- 209 | Many people contributed to ElScreen by reporting problems or suggesting 210 | various improvements. Here is a list of these people. 211 | 212 | * Tohru Sugayama 213 | * Yoshinobu Takenaga 214 | * Masatoshi Takamura 215 | * Jin Kashimura 216 | * Takahiko Sakai 217 | * Norio Suzuki 218 | * Yoshitatsu Takeshita 219 | * Yoichi Nakayama 220 | * sen_ml@eccosys.com 221 | * Dan Debertin 222 | * Yoshinori Koseki 223 | * Hideyuki Shirai 224 | * Masahiro Ishiyama 225 | * Alexy Khrabrov 226 | -------------------------------------------------------------------------------- /elscreen-buffer-list.el: -------------------------------------------------------------------------------- 1 | ;;; 2 | 3 | ;; This code is free software; you can redistribute it and/or modify 4 | ;; it under the terms of the GNU General Public License as published 5 | ;; by the Free Software Foundation; either version 3, or (at your 6 | ;; option) any later version. 7 | ;; 8 | ;; This code is distributed in the hope that it will be useful, but 9 | ;; WITHOUT ANY WARRANTY; without even the implied warranty of 10 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | ;; General Public License for more details. 12 | ;; 13 | ;; You should have received a copy of the GNU General Public License 14 | ;; along with Emacs. If not, see http://www.gnu.org/licenses. 15 | 16 | (provide 'elscreen-buffer-list) 17 | (require 'elscreen) 18 | 19 | ;; From escreen.el 20 | (defun buffer-dead-p (buffer) 21 | (not (static-if (fboundp 'buffer-live-p) 22 | (buffer-live-p buffer) 23 | ;; Emacs 18 doesn't have buffer-live-p. 24 | ;; Killed buffers have no names. 25 | (buffer-name buffer)))) 26 | 27 | ;; From escreen.el 28 | (defun reorder-buffer-list (new-list) 29 | "Set buffers in NEW-LIST to be the most recently used, in order." 30 | (when new-list 31 | (let (firstbuf buf) 32 | (while new-list 33 | (setq buf (car new-list)) 34 | (when (stringp buf) 35 | (setq buf (get-buffer buf))) 36 | (unless (buffer-dead-p buf) 37 | (bury-buffer buf) 38 | (unless firstbuf 39 | (setq firstbuf buf))) 40 | (setq new-list (cdr new-list))) 41 | (setq new-list (buffer-list)) 42 | (while (not (eq (car new-list) firstbuf)) 43 | (bury-buffer (car new-list)) 44 | (setq new-list (cdr new-list)))))) 45 | 46 | 47 | (defun elscreen-get-buffer-list (screen) 48 | "Return buffer-list of SCREEN." 49 | (let ((screen-property (elscreen-get-screen-property screen))) 50 | (get-alist 'buffer-list screen-property))) 51 | 52 | (defun elscreen-set-buffer-list (screen buflist) 53 | "Set buffer-list of SCREEN to BUFLIST." 54 | (let ((screen-property (elscreen-get-screen-property screen))) 55 | (set-alist 'screen-property 'buffer-list buflist) 56 | (elscreen-set-screen-property screen screen-property))) 57 | 58 | (defun elscreen-save-buffer-list (&optional screen) 59 | "Save the buffer-list order for SCREEN, or current screen" 60 | (elscreen-set-buffer-list (or screen 61 | (elscreen-get-current-screen)) 62 | (buffer-list))) 63 | 64 | (defun elscreen-load-buffer-list (&optional screen) 65 | "Set emacs' buffer-list order to that of SCREEN, or current screen" 66 | (reorder-buffer-list (elscreen-get-buffer-list 67 | (or screen 68 | (elscreen-get-current-screen))))) 69 | 70 | (defadvice elscreen-goto-internal (around manage-buffer-list activate) 71 | "Manage screen-specific buffer lists." 72 | (when (and elscreen-buffer-list-enabled 73 | (elscreen-screen-live-p (elscreen-get-previous-screen))) 74 | (elscreen-save-buffer-list (elscreen-get-previous-screen))) 75 | ad-do-it 76 | (when elscreen-buffer-list-enabled 77 | (elscreen-load-buffer-list (elscreen-get-current-screen)))) 78 | 79 | (defcustom elscreen-buffer-list-enabled nil 80 | "Whether to save and load screen-local buffer lists." 81 | :type 'boolean 82 | :group 'elscreen) 83 | 84 | (defun toggle-elscreen-buffer-list (&optional arg) 85 | (interactive "P") 86 | (setq elscreen-buffer-list-enabled 87 | (cond ((null arg) (not elscreen-buffer-list-enabled)) 88 | (t (> arg 0)))) 89 | (message "Screen-specific buffer lists %s" 90 | (if elscreen-buffer-list-enabled "enabled" "disabled"))) 91 | 92 | (fset 'enable-elscreen-buffer-list 93 | (apply-partially 'toggle-elscreen-buffer-list 1)) 94 | (fset 'disable-elscreen-buffer-list 95 | (apply-partially 'toggle-elscreen-buffer-list 0)) 96 | -------------------------------------------------------------------------------- /elscreen-color-theme.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-color-theme.el 4 | ;; 5 | (defconst elscreen-color-theme-version "0.0.0 (November 19, 2007)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: November 19, 2007 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; 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; see the file COPYING. If not, write to 22 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 | 24 | (provide 'elscreen-color-theme) 25 | (require 'elscreen) 26 | 27 | (defcustom elscreen-color-theme-override-theme nil 28 | "Non-nil to override theme's faces" 29 | :type 'boolean 30 | :group 'color-theme) 31 | 32 | (defcustom elscreen-color-theme-tab-background-face-function 33 | 'elscreen-color-theme-tab-background-face-default-function 34 | "Function to generate a face for background of the tabs of ElScreen." 35 | :type 'function 36 | :group 'color-theme) 37 | 38 | (defcustom elscreen-color-theme-tab-control-face-function 39 | 'elscreen-color-theme-tab-control-face-default-function 40 | "Function to generate a face for the control tab of ElScreen." 41 | :type 'function 42 | :group 'color-theme) 43 | 44 | (defcustom elscreen-color-theme-tab-current-screen-face-function 45 | 'elscreen-color-theme-tab-current-screen-face-default-function 46 | "Function to generate a face for the current tab of ElScreen." 47 | :type 'function 48 | :group 'color-theme) 49 | 50 | (defcustom elscreen-color-theme-tab-other-screen-face-function 51 | 'elscreen-color-theme-tab-other-screen-face-default-function 52 | "Function to generate a face for inactive tabs of ElScreen." 53 | :type 'function 54 | :group 'color-theme) 55 | 56 | (defsubst elscreen-color-theme-generate-color (color weight) 57 | (let* ((max-value (car (color-values "white"))) 58 | (dividing-value (round (/ max-value 2))) 59 | (unit-value (round (/ dividing-value 16)))) 60 | (apply 'format "#%02x%02x%02x" 61 | (mapcar 62 | (lambda (value) 63 | (let* ((sign (if (< dividing-value value) -1 1)) 64 | (adjustment (* sign unit-value weight))) 65 | (+ value adjustment))) 66 | (color-values color))))) 67 | 68 | (defun elscreen-color-theme-tab-background-face-default-function (theme) 69 | (let* ((params (color-theme-frame-params theme)) 70 | (background (cdr (assoc 'background-color params))) 71 | (faces 72 | (when background 73 | `(:background 74 | ,(elscreen-color-theme-generate-color background 8))))) 75 | (when faces `((t ,faces))))) 76 | 77 | (defun elscreen-color-theme-tab-control-face-default-function (theme) 78 | (let* ((params (color-theme-frame-params theme)) 79 | (foreground (cdr (assoc 'foreground-color params))) 80 | (background (cdr (assoc 'background-color params))) 81 | (faces (nconc 82 | (when foreground `(:foreground ,foreground)) 83 | (when background `(:background ,background))))) 84 | (when faces `((t ,faces))))) 85 | 86 | (defalias 'elscreen-color-theme-tab-current-screen-face-default-function 87 | 'elscreen-color-theme-tab-control-face-default-function) 88 | 89 | (defun elscreen-color-theme-tab-other-screen-face-default-function (theme) 90 | (let* ((params (color-theme-frame-params theme)) 91 | (foreground (cdr (assoc 'foreground-color params))) 92 | (background (cdr (assoc 'background-color params))) 93 | (faces (nconc 94 | (when foreground 95 | `(:foreground 96 | ,(elscreen-color-theme-generate-color foreground 12))) 97 | (when background 98 | `(:background 99 | ,(elscreen-color-theme-generate-color background 4)))))) 100 | (when faces `((t ,faces))))) 101 | 102 | (defadvice color-theme-install (around elscreen-color-theme-install activate) 103 | (let* ((theme-faces (color-theme-faces (color-theme-canonic theme))) 104 | (elscreen-faces 105 | (delete nil 106 | (mapcar 107 | (lambda (face-name) 108 | (unless (and (not elscreen-color-theme-override-theme) 109 | (assoc face-name theme-faces)) 110 | (let* ((face-fn 111 | (symbol-value 112 | (intern 113 | (concat (replace-regexp-in-string 114 | "^elscreen" 115 | "elscreen-color-theme" 116 | (symbol-name face-name)) 117 | "-function")))) 118 | (faces (funcall face-fn theme))) 119 | (when faces (list face-name faces))))) 120 | '(elscreen-tab-background-face 121 | elscreen-tab-control-face 122 | elscreen-tab-current-screen-face 123 | elscreen-tab-other-screen-face))))) 124 | ad-do-it 125 | (when elscreen-faces 126 | (color-theme-install-faces elscreen-faces)))) 127 | -------------------------------------------------------------------------------- /elscreen-dired.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-dired.el 4 | ;; 5 | (defconst elscreen-dired-version "0.1.0 (November 6, 2005)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: August 9, 2004 9 | ;; Revised: November 6, 2005 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-dired) 26 | (require 'elscreen) 27 | 28 | 29 | ;;; Code: 30 | 31 | (defadvice dired-find-file-other-window (around elscreen-dired-find-file-other-window activate) 32 | (let ((window-configuration (current-window-configuration)) 33 | (buffer nil)) 34 | ad-do-it 35 | (unless (eq major-mode 'dired-mode) 36 | (setq buffer (current-buffer)) 37 | (set-window-configuration window-configuration) 38 | (elscreen-find-and-goto-by-buffer buffer t)))) 39 | -------------------------------------------------------------------------------- /elscreen-dnd.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-dnd.el 4 | ;; 5 | (defconst elscreen-dnd-version "0.0.0 (December 15, 2005)") 6 | ;; 7 | ;; Author: Hideyuki Shirai 8 | ;; Naoto Morishima 9 | ;; Created: December 15, 2005 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-dnd) 26 | (require 'elscreen) 27 | 28 | (defcustom elscreen-dnd-open-file-new-screen t 29 | "If non-nil, always create new screen to open dropped files." 30 | :type 'boolean 31 | :group 'dnd) 32 | 33 | 34 | ;; Code: 35 | 36 | (defmacro elscreen-dnd-drag-n-drop (ad-do-it) 37 | (` (progn 38 | (elscreen-notify-screen-modification-suppress 39 | (, ad-do-it)) 40 | (elscreen-notify-screen-modification 'force)))) 41 | 42 | (defadvice dnd-handle-one-url (around elscreen-dnd-handle-open-url activate) 43 | (if (not elscreen-dnd-open-file-new-screen) 44 | ad-do-it 45 | (let ((dnd-open-file-other-window nil) 46 | file-buffer) 47 | (save-window-excursion 48 | ad-do-it 49 | (setq file-buffer (current-buffer))) 50 | (if (elscreen-screen-modified-p 'dnd-handle-one-url) 51 | (elscreen-find-and-goto-by-buffer file-buffer 'create) 52 | (elscreen-find-screen-by-buffer file-buffer 'create))))) 53 | 54 | (mapc 55 | (lambda (drag-n-drop-function) 56 | (eval (` (defadvice (, drag-n-drop-function) (around elscreen-dnd-drag-n-drop activate) 57 | (elscreen-dnd-drag-n-drop ad-do-it))))) 58 | (list 'x-dnd-handle-drag-n-drop-event 'mac-drag-n-drop 'w32-drag-n-drop)) 59 | -------------------------------------------------------------------------------- /elscreen-gf.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-gf.el 4 | ;; 5 | (defconst elscreen-gf-version "1.5.3 (November 07, 2007)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Based on: grep-family.el 9 | ;; by Youki Kadobayashi 10 | ;; Created: June 23, 1996 11 | ;; Revised: November 07, 2007 12 | 13 | ;; This program is free software; you can redistribute it and/or modify 14 | ;; it under the terms of the GNU General Public License as published by 15 | ;; the Free Software Foundation; either version 2, or (at your option) 16 | ;; 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; see the file COPYING. If not, write to 25 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 26 | 27 | (provide 'elscreen-gf) 28 | (require 'elscreen) 29 | (require 'ring) 30 | 31 | ;;; User Customizable Variables: 32 | 33 | (defgroup elscreen-gf nil 34 | "ElScreen-GF -- Grep Family on ElScreen" 35 | :tag "ElScreen-GF" 36 | :group 'tools) 37 | 38 | (defcustom elscreen-gf-grep-program-name "grep" 39 | "Program invoked by \\[elscreen-gf-grep] command." 40 | :type 'string 41 | :group 'elscreen-gf) 42 | 43 | (defcustom elscreen-gf-idutils-gid-program-name "gid" 44 | "Program invoked by \\[elscreen-gf-idutils-gid] command." 45 | :type 'string 46 | :group 'elscreen-gf) 47 | 48 | (defcustom elscreen-gf-idutils-mkid-program-name "mkid" 49 | "Program invoked by \\[elscreen-gf-idutils-mkid] command." 50 | :type 'string 51 | :group 'elscreen-gf) 52 | 53 | (defcustom elscreen-gf-cscope-program-name "cscope" 54 | "Program invoked by \\[elscreen-gf-cscope] command." 55 | :type 'string 56 | :group 'elscreen-gf) 57 | 58 | (defcustom elscreen-gf-global-program-name "global" 59 | "Program invoked by \\[elscreen-gf-global] command." 60 | :type 'string 61 | :group 'elscreen-gf) 62 | 63 | (defcustom elscreen-gf-global-gtags-program-name "gtags" 64 | "Program invoked by \\[elscreen-gf-global-gtags] command." 65 | :type 'string 66 | :group 'elscreen-gf) 67 | 68 | (defcustom elscreen-gf-mode-truncate-lines t 69 | "If non-nil, truncate each line in ElScreen-GF mode." 70 | :tag "Truncate lines in ElScreen-GF mode." 71 | :type 'boolean 72 | :group 'elscreen-gf) 73 | 74 | (defvar elscreen-gf-invoke-point-history) 75 | 76 | (defcustom elscreen-gf-invoke-point-history-length 8 77 | "Length of histories for the locations where gf searchs were invoked." 78 | :tag "Length of histries for invoke-point." 79 | :type '(integer :size 4) 80 | :set (lambda (symbol value) 81 | (when (and (numberp value) 82 | (>= value 4) 83 | (<= value 64)) 84 | (custom-set-default symbol value) 85 | (let ((old-history (when (boundp 'elscreen-gf-invoke-point-history) 86 | elscreen-gf-invoke-point-history))) 87 | (setq elscreen-gf-invoke-point-history (make-ring value)) 88 | (when (and old-history (ring-p old-history)) 89 | (while (and (not (ring-empty-p old-history)) 90 | (< (ring-length elscreen-gf-invoke-point-history) 91 | value)) 92 | (ring-insert-at-beginning elscreen-gf-invoke-point-history 93 | (ring-remove old-history 0))))))) 94 | :group 'elscreen-gf) 95 | 96 | (defface elscreen-gf-mode-selected-entry-face 97 | '((t (:underline t))) 98 | "Face used for the selected entry in ElScreen-GF mode." 99 | :group 'elscreen-gf) 100 | 101 | (defface elscreen-gf-mode-file-name-face 102 | '((((class color) (background dark)) 103 | (:foreground "khaki" :bold t)) 104 | (((class color) (background light)) 105 | (:foreground "DarkSlateBlue" :bold t)) 106 | (t (:bold t))) 107 | "Face used for file name in ElScreen-GF mode." 108 | :group 'elscreen-gf) 109 | 110 | (defface elscreen-gf-mode-line-number-face 111 | '((((class color) (background dark)) 112 | (:foreground "gray" :bold t)) 113 | (((class color) (background light)) 114 | (:foreground "gray50" :bold t)) 115 | (t (:bold t))) 116 | "Face used for line number in ElScreen-GF mode." 117 | :group 'elscreen-gf) 118 | 119 | (defface elscreen-gf-mode-pattern-face 120 | '((((class color) (background dark)) 121 | (:foreground "tomato" :bold t)) 122 | (((class color) (background light)) 123 | (:foreground "tomato" :bold t)) 124 | (t (:bold t))) 125 | "Face used to emphasize the specified keyword in ElScreen-GF mode." 126 | :group 'elscreen-gf) 127 | 128 | (defface elscreen-gf-emphasis-after-jump-face 129 | '((((class color) (background light)) 130 | (:background "LightSteelBlue1")) 131 | (((class color) (background dark)) 132 | (:background "SteelBlue")) 133 | (t (:bold t))) 134 | "Face used to emphasize the selected line after jump." 135 | :group 'elscreen-gf) 136 | 137 | ;;; Key bindings: 138 | 139 | (defvar elscreen-gf-map (make-sparse-keymap) 140 | "Keymap for elscreen-gf.") 141 | (define-key elscreen-gf-map "G" 'elscreen-gf-grep) 142 | (define-key elscreen-gf-map "m" 'elscreen-gf-idutils-mkid) 143 | (define-key elscreen-gf-map "g" 'elscreen-gf-idutils-gid) 144 | (define-key elscreen-gf-map "c" 'elscreen-gf-cscope) 145 | (define-key elscreen-gf-map "t" 'elscreen-gf-global-gtags) 146 | (define-key elscreen-gf-map "l" 'elscreen-gf-global) 147 | (define-key elscreen-gf-map "u" 'elscreen-gf-go-back-to-latest-invoke-point) 148 | (define-key elscreen-gf-map "v" 'elscreen-gf-display-version) 149 | 150 | (define-key elscreen-map "\C-g" elscreen-gf-map) 151 | 152 | (defvar elscreen-gf-mode-map (make-sparse-keymap) 153 | "keymap used in elscreen-gf mode.") 154 | (define-key elscreen-gf-mode-map "n" 'elscreen-gf-mode-next-line) 155 | (define-key elscreen-gf-mode-map "p" 'elscreen-gf-mode-previous-line) 156 | (define-key elscreen-gf-mode-map " " 'elscreen-gf-mode-scroll-up) 157 | (define-key elscreen-gf-mode-map "\177" 'elscreen-gf-mode-scroll-down) 158 | (define-key elscreen-gf-mode-map "<" 'elscreen-gf-mode-beginning-of-buffer) 159 | (define-key elscreen-gf-mode-map ">" 'elscreen-gf-mode-end-of-buffer) 160 | (define-key elscreen-gf-mode-map "N" 'elscreen-gf-mode-next-file) 161 | (define-key elscreen-gf-mode-map "P" 'elscreen-gf-mode-previous-file) 162 | (define-key elscreen-gf-mode-map "t" 'elscreen-gf-mode-truncate-lines-toggle) 163 | (define-key elscreen-gf-mode-map "o" 'elscreen-gf-mode-jump-to-entry) 164 | (define-key elscreen-gf-mode-map "O" 'elscreen-gf-mode-jump-to-entry-read-only) 165 | (define-key elscreen-gf-mode-map "\C-g" 'elscreen-gf-mode-search-quit) 166 | (define-key elscreen-gf-mode-map "q" 'elscreen-gf-mode-exit) 167 | (define-key elscreen-gf-mode-map "v" 'elscreen-gf-display-version) 168 | 169 | 170 | ;;; Internal Functions and Variables: 171 | 172 | (defvar elscreen-gf-invoke-point-history 173 | (make-ring elscreen-gf-invoke-point-history-length)) 174 | 175 | (defsubst elscreen-gf-overlay-create (start end face) 176 | (let ((overlay (make-overlay start end))) 177 | (overlay-put overlay 'face face) 178 | (overlay-put overlay 'evaporate t) 179 | overlay)) 180 | 181 | (defsubst elscreen-gf-move-overlay-create (overlay-symbol start end face) 182 | (let ((overlay (condition-case nil 183 | (symbol-value overlay-symbol) 184 | (error nil)))) 185 | (if (overlayp overlay) 186 | (move-overlay overlay start end (current-buffer)) 187 | (set overlay-symbol (elscreen-gf-overlay-create start end face)) 188 | (setq overlay (symbol-value overlay-symbol))) 189 | overlay)) 190 | 191 | (defun elscreen-gf-define-major-mode-token (major-mode token-chars) 192 | (let ((thing-symbol (intern (format "%s-thing" (symbol-name major-mode))))) 193 | (put major-mode 'elscreen-gf-major-mode-thing thing-symbol) 194 | (put thing-symbol 'token-chars token-chars) 195 | (put thing-symbol 'end-op 196 | `(lambda () 197 | (re-search-forward (concat "\\=[" ,token-chars "]*") nil t))) 198 | (put thing-symbol 'beginning-op 199 | `(lambda () 200 | (if (re-search-backward (concat "[^" ,token-chars "]") nil t) 201 | (forward-char) 202 | (goto-char (point-min))))))) 203 | 204 | (elscreen-gf-define-major-mode-token 'c-mode "a-zA-Z0-9_") 205 | (elscreen-gf-define-major-mode-token 'perl-mode "a-zA-Z0-9_") 206 | (elscreen-gf-define-major-mode-token 'emacs-lisp-mode "-a-zA-Z0-9/+:<>") 207 | 208 | (defsubst elscreen-gf-major-mode-token-chars (major-mode) 209 | (get (get major-mode 'elscreen-gf-major-mode-thing) 'token-chars)) 210 | 211 | (defsubst elscreen-gf-db-directory (file-name &optional directory) 212 | (let ((directory (expand-file-name 213 | (or directory 214 | (and (buffer-file-name) 215 | (file-name-directory (buffer-file-name))) 216 | default-directory))) 217 | (previous-directory nil)) 218 | (catch 'found 219 | (while (and directory 220 | (not (and previous-directory 221 | (string= directory previous-directory)))) 222 | (if (file-exists-p (concat directory file-name)) 223 | (throw 'found directory)) 224 | (setq previous-directory directory) 225 | (setq directory (file-name-directory 226 | (directory-file-name directory))))))) 227 | 228 | 229 | ;;; ElScreen-GF mode 230 | 231 | (defconst elscreen-gf-mode-to-nickname-alist 232 | '(("^elscreen-gf-mode$" . (lambda () 233 | (format "ElScreen-GF%s" 234 | (if (and (elscreen-gf-process-exclusive-p 235 | elscreen-gf-idutils-mkid-process 236 | 'noerror) 237 | (elscreen-gf-process-exclusive-p 238 | elscreen-gf-global-gtags-process 239 | 'noerror)) 240 | "" " (!)"))))) 241 | "*Alist composed of the pair of mode-name and corresponding screen-name.") 242 | (elscreen-set-mode-to-nickname-alist 'elscreen-gf-mode-to-nickname-alist) 243 | 244 | (defun elscreen-gf-goto-screen-create (target-directory) 245 | (let ((buffer (get-buffer-create "ElScreen-GF"))) 246 | (elscreen-find-and-goto-by-buffer buffer 'create) 247 | (switch-to-buffer buffer) 248 | (elscreen-gf-mode target-directory) 249 | (let ((buffer-read-only nil)) 250 | (erase-buffer)))) 251 | 252 | (defvar elscreen-gf-pattern) 253 | (defvar elscreen-gf-invoke-point) 254 | (defvar elscreen-gf-filter-odd-string) 255 | (defvar elscreen-gf-selected-entry-overlay) 256 | (defun elscreen-gf-mode (target-directory) 257 | "Major mode for jumping to the entries. 258 | 259 | Key bindings: 260 | \\{elscreen-gf-mode-map}" 261 | (setq major-mode 'elscreen-gf-mode) 262 | (setq mode-name "ElScreen-GF") 263 | (use-local-map elscreen-gf-mode-map) 264 | (setq buffer-read-only t) 265 | (setq case-fold-search nil) 266 | (setq truncate-lines elscreen-gf-mode-truncate-lines) 267 | (set (make-local-variable 'elscreen-gf-pattern) nil) 268 | (set (make-local-variable 'elscreen-gf-invoke-point) nil) 269 | (set (make-local-variable 'elscreen-gf-filter-odd-string) nil) 270 | (set (make-local-variable 'elscreen-gf-selected-entry-overlay) nil) 271 | (setq default-directory target-directory) 272 | 273 | (auto-fill-mode nil)) 274 | 275 | (defun elscreen-gf-mode-selected-entry-overlay () 276 | (elscreen-gf-move-overlay-create 277 | 'elscreen-gf-selected-entry-overlay 278 | (point-at-bol) (point-at-eol) 279 | 'elscreen-gf-mode-selected-entry-face)) 280 | 281 | (defun elscreen-gf-mode-next-line () 282 | "Move the current entry vertically down." 283 | (interactive) 284 | (let ((current-line (line-number-at-pos))) 285 | (cond 286 | ((< current-line 4) 287 | (goto-char (point-min)) 288 | (forward-line 3)) 289 | ((< current-line (line-number-at-pos (point-max))) 290 | (forward-line 1))) 291 | (elscreen-gf-mode-selected-entry-overlay))) 292 | 293 | (defun elscreen-gf-mode-previous-line () 294 | "Move the current entry vertically up." 295 | (interactive) 296 | (let ((current-line (line-number-at-pos))) 297 | (cond 298 | ((< 4 current-line) 299 | (forward-line -1)) 300 | (t 301 | (goto-char (point-min)) 302 | (forward-line 3))) 303 | (elscreen-gf-mode-selected-entry-overlay))) 304 | 305 | (defun elscreen-gf-mode-scroll-up () 306 | "Scroll entries upward full screen." 307 | (interactive) 308 | (scroll-up) 309 | (elscreen-gf-mode-selected-entry-overlay)) 310 | 311 | (defun elscreen-gf-mode-scroll-down () 312 | "Scroll entries downward full screen." 313 | (interactive) 314 | (scroll-down) 315 | (elscreen-gf-mode-selected-entry-overlay)) 316 | 317 | (defun elscreen-gf-mode-beginning-of-buffer () 318 | "Move the current entry to the beginning of the entries." 319 | (interactive) 320 | (goto-char (point-min)) 321 | (forward-line 3) 322 | (elscreen-gf-mode-selected-entry-overlay)) 323 | 324 | (defun elscreen-gf-mode-end-of-buffer () 325 | "Move the current entry to the end of the entries." 326 | (interactive) 327 | (goto-char (point-max)) 328 | (forward-line -1) 329 | (elscreen-gf-mode-selected-entry-overlay)) 330 | 331 | (defun elscreen-gf-mode-next-file () 332 | (interactive) 333 | (cond 334 | ((save-excursion 335 | (beginning-of-line) 336 | (looking-at "^\\([^:\n]+\\):\\([0-9]+\\):")) 337 | (let ((file-name (match-string 1))) 338 | (goto-char (point-max)) 339 | (re-search-backward (concat "^" file-name ":")) 340 | (forward-line))) 341 | (t 342 | (re-search-forward "^\\([^:\n]+\\):\\([0-9]+\\):" nil t) 343 | (beginning-of-line))) 344 | (elscreen-gf-mode-selected-entry-overlay)) 345 | 346 | (defun elscreen-gf-mode-previous-file () 347 | (interactive) 348 | (cond 349 | ((save-excursion 350 | (beginning-of-line) 351 | (looking-at "^\\([^:\n]+\\):\\([0-9]+\\):")) 352 | (let ((file-name (match-string 1))) 353 | (goto-char (point-min)) 354 | (re-search-forward (concat "^" file-name ":")) 355 | (forward-line -1) 356 | (beginning-of-line))) 357 | (t 358 | (re-search-backward "^\\([^:\n]+\\):\\([0-9]+\\):" nil t))) 359 | (when (looking-at "^\\([^:\n]+\\):\\([0-9]+\\):") 360 | (let ((file-name (match-string 1))) 361 | (goto-char (point-min)) 362 | (re-search-forward (concat "^" file-name ":")) 363 | (beginning-of-line))) 364 | (elscreen-gf-mode-selected-entry-overlay)) 365 | 366 | (defun elscreen-gf-mode-truncate-lines-toggle () 367 | "Toggle truncated lines." 368 | (interactive) 369 | (let ((window-start (window-start)) 370 | (line-number-in-window 0)) 371 | (beginning-of-line) 372 | (save-excursion 373 | (while (> (point) window-start) 374 | (setq line-number-in-window (1+ line-number-in-window)) 375 | (vertical-motion -1))) 376 | (setq truncate-lines (not truncate-lines)) 377 | (recenter line-number-in-window))) 378 | 379 | (defvar elscreen-gf-emphasis-after-jump-overlay nil) 380 | (defun elscreen-gf-mode-jump-to-entry () 381 | "Jump to the current entry." 382 | (interactive) 383 | (when (save-excursion 384 | (beginning-of-line) 385 | (looking-at "^\\([^:\n]+\\):\\([0-9]+\\):")) 386 | (when (not (eq (marker-buffer (cdr elscreen-gf-invoke-point)) 387 | (current-buffer))) 388 | (ring-insert elscreen-gf-invoke-point-history elscreen-gf-invoke-point)) 389 | (let ((file-name (match-string 1)) 390 | (line (string-to-number (match-string 2))) 391 | (pattern elscreen-gf-pattern) 392 | token-chars nontoken-chars) 393 | (isearch-update-ring pattern) 394 | (elscreen-find-file file-name) 395 | (setq token-chars 396 | (or (elscreen-gf-major-mode-token-chars major-mode) 397 | (elscreen-gf-major-mode-token-chars 'elscreen-gf-mode) 398 | "a-zA-Z0-9")) 399 | (setq nontoken-chars (format "[^%s]" token-chars)) 400 | (goto-char (point-min)) 401 | (forward-line (1- line)) 402 | (let ((case-fold-search nil)) 403 | (goto-char (or (and (re-search-forward 404 | (format "\\(^\\|%s\\)\\(%s\\)\\(%s\\|$\\)" 405 | nontoken-chars pattern nontoken-chars) 406 | (point-at-eol) t) 407 | (match-beginning 2)) 408 | (and (search-forward pattern (point-at-eol) t) 409 | (match-beginning 0)) 410 | (point-at-bol)))) 411 | (elscreen-gf-move-overlay-create 'elscreen-gf-emphasis-after-jump-overlay 412 | (point-at-bol) (point-at-eol) 413 | 'elscreen-gf-emphasis-after-jump-face)))) 414 | 415 | (defun elscreen-gf-mode-jump-to-entry-read-only () 416 | (interactive) 417 | (elscreen-gf-mode-jump-to-entry) 418 | (read-only-mode 'toggle)) 419 | 420 | (defvar elscreen-gf-search-process nil) 421 | 422 | (defun elscreen-gf-mode-search-quit (&optional force) 423 | (interactive) 424 | (when (and (not (elscreen-gf-process-exclusive-p 425 | elscreen-gf-search-process 'noerror)) 426 | (or force 427 | (yes-or-no-p 428 | (format "Really quit %s? " 429 | (process-name elscreen-gf-search-process))))) 430 | (delete-process elscreen-gf-search-process))) 431 | 432 | (defun elscreen-gf-mode-exit () 433 | (interactive) 434 | (let* ((current-screen (elscreen-get-current-screen)) 435 | (buffer (get-buffer "ElScreen-GF")) 436 | (screen (when (buffer-live-p buffer) 437 | (elscreen-find-screen-by-buffer buffer)))) 438 | (when screen 439 | (elscreen-goto-internal screen) 440 | (mapc 441 | (lambda (window) 442 | (if (one-window-p) 443 | (elscreen-kill screen) 444 | (delete-window window))) 445 | (get-buffer-window-list buffer))) 446 | (when buffer 447 | (kill-buffer buffer)) 448 | (when (elscreen-screen-live-p screen) 449 | (elscreen-set-window-configuration 450 | screen (elscreen-current-window-configuration))) 451 | (when (elscreen-screen-live-p current-screen) 452 | (elscreen-goto-internal current-screen)))) 453 | 454 | ;;; Fundamental functions shared among GNU grep/GNI ID Utils/cscope/GNU global 455 | 456 | (defun elscreen-gf-process-exclusive-p (process &optional noerror) 457 | (let ((exclusive-p (not (and (processp process) 458 | (eq (process-status process) 'run))))) 459 | (when (not (or exclusive-p noerror)) 460 | (message "Sorry, %s is running now. Try again later." 461 | (process-name process))) 462 | exclusive-p)) 463 | 464 | (defsubst elscreen-gf-search-token-at-point () 465 | (let* ((thing (or (get major-mode 'elscreen-gf-major-mode-thing) 'word)) 466 | (thing-at-point (or (thing-at-point thing) ""))) 467 | (set-text-properties 0 (length thing-at-point) nil thing-at-point) 468 | thing-at-point)) 469 | 470 | (defvar elscreen-gf-search-pattern-history nil) 471 | (defsubst elscreen-gf-search-read-pattern (prompt &optional pattern-default) 472 | (let* ((pattern-default (or pattern-default 473 | (elscreen-gf-search-token-at-point) 474 | ""))) 475 | (read-string prompt (cons pattern-default 0) 476 | 'elscreen-gf-search-pattern-history))) 477 | 478 | (defun elscreen-gf-search-regexp-dot-to-token (regexp token) 479 | (let ((index 0) 480 | (token-length (length token))) 481 | (save-match-data 482 | (while (setq index (string-match "\\." regexp index)) 483 | (if (and (/= index 0) 484 | (string= (substring regexp (1- index) index) "\\")) 485 | (setq index (1+ index)) 486 | (setq regexp (concat (substring regexp 0 index) 487 | token 488 | (substring regexp (1+ index)))) 489 | (setq index (+ index token-length)))))) 490 | regexp) 491 | 492 | (defun elscreen-gf-read-selection (title prompt option-defs) 493 | (let ((candidate-buffer (generate-new-buffer " *ElScreen-GF-Read-Selection*")) 494 | candidate-window-height 495 | (minibuffer-map (copy-keymap minibuffer-local-map)) 496 | window frame-last-window mini-hist) 497 | ;; prepare candidate buffer 498 | (with-current-buffer candidate-buffer 499 | (setq buffer-read-only t) 500 | (let ((buffer-read-only nil)) 501 | (erase-buffer) 502 | (insert title "\n" 503 | (mapconcat 504 | (lambda (option-def) 505 | (apply 'format " %s) %s\n" option-def)) 506 | option-defs nil)) 507 | (goto-char (point-min)) 508 | (save-excursion 509 | (while (not (eobp)) 510 | (when (looking-at "^ \\([0-9a-z]\\)) .*$") 511 | (put-text-property 512 | (match-beginning 1) (match-end 1) 'face 'bold)) 513 | (forward-line 1))) 514 | (setq candidate-window-height (line-number-at-pos (point-max))) 515 | (set-buffer-modified-p nil))) 516 | ;; prepare candidate window 517 | (save-window-excursion 518 | (setq frame-last-window 519 | (previous-window (frame-first-window))) 520 | (while (minibuffer-window-active-p frame-last-window) 521 | (setq frame-last-window (previous-window frame-last-window))) 522 | (while (and (not (one-window-p)) 523 | (or (< (window-width frame-last-window) 524 | (frame-width)) 525 | (< (window-height frame-last-window) 526 | (+ candidate-window-height window-min-height)))) 527 | (setq window frame-last-window) 528 | (setq frame-last-window (previous-window window)) 529 | (delete-window window)) 530 | (select-window (split-window frame-last-window)) 531 | (shrink-window (- (window-height) candidate-window-height)) 532 | (switch-to-buffer candidate-buffer) 533 | ;; make keymap for minibuffer 534 | (suppress-keymap minibuffer-map t) 535 | (define-key minibuffer-map "\C-m" 'undefined) 536 | (define-key minibuffer-map "\C-g" 'abort-recursive-edit) 537 | (mapc 538 | (lambda (option-def) 539 | (define-key minibuffer-map (car option-def) 'self-insert-and-exit)) 540 | option-defs) 541 | ;; read key from minibuffer 542 | (unwind-protect 543 | (assoc 544 | (read-from-minibuffer prompt nil minibuffer-map nil 'mini-hist) 545 | option-defs) 546 | (kill-buffer candidate-buffer))))) 547 | 548 | (defsubst elscreen-gf-run-search-command (command-name pattern command directory line-parser) 549 | (put 'elscreen-gf-mode 'elscreen-gf-major-mode-thing 550 | (or (get major-mode 'elscreen-gf-major-mode-thing) 'word)) 551 | (let ((invoke-point (cons (elscreen-get-current-screen) (point-marker)))) 552 | (elscreen-gf-goto-screen-create directory) 553 | (setq elscreen-gf-pattern pattern) 554 | (setq elscreen-gf-invoke-point invoke-point)) 555 | (let ((buffer-read-only nil)) 556 | (insert "DIR: " (abbreviate-file-name directory) "\n" 557 | "CMD: " command " (reformatted by gf)\n\n")) 558 | (message "Running %s..." command-name) 559 | (setq elscreen-gf-search-process 560 | (start-process command-name (current-buffer) 561 | "sh" "-c" command "2> /dev/null")) 562 | (process-put elscreen-gf-search-process 563 | 'elscreen-gf-search-line-parser line-parser) 564 | (set-process-filter elscreen-gf-search-process 'elscreen-gf-search-filter) 565 | (set-process-sentinel elscreen-gf-search-process 'elscreen-gf-search-sentinel)) 566 | 567 | (defun elscreen-gf-search-filter (process string) 568 | (set-buffer (process-buffer process)) 569 | (save-excursion 570 | (let* ((string (concat elscreen-gf-filter-odd-string string)) 571 | (token-chars (or (elscreen-gf-major-mode-token-chars major-mode) 572 | "a-zA-Z0-9")) 573 | (nontoken-chars (format "[^%s]" token-chars)) 574 | (line-parser (process-get process 'elscreen-gf-search-line-parser)) 575 | (buffer-read-only nil)) 576 | (goto-char (point-max)) 577 | (save-excursion (insert string)) 578 | (while (and (not (eobp)) (looking-at ".*\n")) 579 | (beginning-of-line) 580 | (let* ((line (buffer-substring (point-at-bol) (point-at-eol))) 581 | (line-elms (funcall line-parser line)) 582 | (file-name (nth 0 line-elms)) 583 | (line-number (nth 1 line-elms)) 584 | (source (nth 2 line-elms)) 585 | start end) 586 | (when line-elms 587 | (delete-region (point-at-bol) (point-at-eol)) 588 | (elscreen-gf-overlay-create 589 | (point) (progn (insert (file-relative-name file-name)) (point)) 590 | 'elscreen-gf-mode-file-name-face) 591 | (insert ":") 592 | (elscreen-gf-overlay-create 593 | (point) (progn (insert line-number) (point)) 594 | 'elscreen-gf-mode-line-number-face) 595 | (insert ":") 596 | (save-excursion (insert (nth 0 source))) 597 | (forward-char (nth 1 source)) 598 | (setq start (point) end (+ start (nth 2 source))) 599 | (while (or (and (eq (point) start) 600 | (save-excursion 601 | (re-search-forward 602 | (format "\\(%s\\)\\(%s\\|$\\)" 603 | elscreen-gf-pattern nontoken-chars) 604 | end t)) 605 | (eq (match-beginning 1) start)) 606 | (re-search-forward 607 | (format "%s\\(%s\\)\\(%s\\|$\\)" 608 | nontoken-chars elscreen-gf-pattern 609 | nontoken-chars) 610 | end t)) 611 | (elscreen-gf-overlay-create (match-beginning 1) (match-end 1) 612 | 'elscreen-gf-mode-pattern-face) 613 | (goto-char (match-end 1))))) 614 | (forward-line)) 615 | (setq elscreen-gf-filter-odd-string 616 | (buffer-substring (point-at-bol) (point-at-eol))) 617 | (delete-region (point-at-bol) (point-at-eol))))) 618 | 619 | (defun elscreen-gf-search-sentinel (process event) 620 | (let ((status (string-match "finished" event))) 621 | (message "Running %s... done" (process-name elscreen-gf-search-process)) 622 | (setq elscreen-gf-search-process nil) 623 | (set-buffer (process-buffer process)) 624 | (elscreen-gf-mode-selected-entry-overlay))) 625 | 626 | ;;; GNU grep 627 | 628 | (defun elscreen-gf-grep (&optional pattern file-name-re) 629 | "Run grep, with user-specified args, and collect output 630 | in the ElScreen-GF buffer." 631 | (interactive) 632 | (cond 633 | ((not (executable-find elscreen-gf-grep-program-name)) 634 | (error "grep not found.")) 635 | ((elscreen-gf-process-exclusive-p elscreen-gf-search-process) 636 | (let* ((pattern (or pattern 637 | (elscreen-gf-search-read-pattern "Run grep (pattern): "))) 638 | (buffer-file-name (or (buffer-file-name) "")) 639 | (file-name-re-default (concat 640 | (file-name-directory buffer-file-name) 641 | "*" 642 | (when (file-name-extension buffer-file-name) 643 | ".") 644 | (file-name-extension buffer-file-name))) 645 | (file-name-re (or file-name-re 646 | (read-string 647 | "Run grep (files): " 648 | (cons file-name-re-default 0) nil "*"))) 649 | (token-chars (or (elscreen-gf-major-mode-token-chars major-mode) 650 | "a-zA-Z0-9")) 651 | (token-chars-re (format "[%s]" token-chars)) 652 | (nontoken-chars-re (format "[^%s]" token-chars)) 653 | (pattern-tokenize (elscreen-gf-search-regexp-dot-to-token 654 | pattern token-chars-re)) 655 | (command (format "%s -IHn %s %s" 656 | elscreen-gf-grep-program-name 657 | (format "'\\(^\\|%s\\)\\(%s\\)\\(%s\\|$\\)'" 658 | nontoken-chars-re 659 | pattern-tokenize 660 | nontoken-chars-re) 661 | file-name-re))) 662 | (elscreen-gf-run-search-command 663 | "grep" pattern-tokenize command default-directory 664 | 'elscreen-gf-grep-line-parser))))) 665 | 666 | (defun elscreen-gf-grep-line-parser (line) 667 | (when (string-match "^\\([^:\n]+\\):\\([0-9]+\\):\\(.*\\)$" line) 668 | (let ((file-name (match-string 1 line)) 669 | (line-number (match-string 2 line)) 670 | (source (match-string 3 line))) 671 | (list file-name line-number (list source 0 (length source)))))) 672 | 673 | ;;; GNU ID Utils 674 | 675 | (defsubst elscreen-gf-idutils-id-directory (&optional directory) 676 | (elscreen-gf-db-directory "ID" directory)) 677 | 678 | (defvar elscreen-gf-idutils-mkid-process nil) 679 | 680 | (defun elscreen-gf-idutils-mkid (&optional directory) 681 | "Run mkid, with user-specified args." 682 | (interactive) 683 | (cond 684 | ((not (executable-find elscreen-gf-idutils-mkid-program-name)) 685 | (error "mkid not found.")) 686 | ((elscreen-gf-process-exclusive-p elscreen-gf-idutils-mkid-process) 687 | (let ((default-directory 688 | (or (and directory (file-directory-p directory) directory) 689 | (read-directory-name "Run mkid (target): " 690 | (or (elscreen-gf-idutils-id-directory) 691 | default-directory) nil t))) 692 | (command (format "%s" elscreen-gf-idutils-mkid-program-name))) 693 | (message "Running mkid...") 694 | (setq elscreen-gf-idutils-mkid-process 695 | (start-process "mkid" nil "sh" "-c" command)) 696 | (set-process-sentinel elscreen-gf-idutils-mkid-process 697 | 'elscreen-gf-idutils-mkid-sentinel) 698 | (elscreen-notify-screen-modification 'force-immediately))))) 699 | 700 | (defun elscreen-gf-idutils-mkid-sentinel (process event) 701 | (let ((status (string-match "finished" event))) 702 | (message "Running mkid... %s" (if status "done" "error")) 703 | (setq elscreen-gf-idutils-mkid-process nil) 704 | (elscreen-notify-screen-modification 'force-immediately))) 705 | 706 | (defun elscreen-gf-idutils-mkid-after-save () 707 | (when (and (buffer-file-name) 708 | (elscreen-gf-process-exclusive-p 709 | elscreen-gf-idutils-mkid-process 'noerror)) 710 | (let ((id-directory (elscreen-gf-idutils-id-directory))) 711 | (when id-directory 712 | (elscreen-gf-idutils-mkid id-directory))))) 713 | 714 | (defun elscreen-gf-idutils-mkid-setup-after-save-hook () 715 | (make-local-variable 'after-save-hook) 716 | (add-hook 'after-save-hook 'elscreen-gf-idutils-mkid-after-save)) 717 | 718 | (defun elscreen-gf-idutils-gid (&optional pattern) 719 | "Run gid, with user-specified args, and collect output 720 | in the ElScreen-GF buffer." 721 | (interactive) 722 | (cond 723 | ((not (executable-find elscreen-gf-idutils-gid-program-name)) 724 | (when (yes-or-no-p "gid not found; execute grep instead? ") 725 | (elscreen-gf-grep))) 726 | ((not (elscreen-gf-idutils-id-directory)) 727 | (funcall 728 | (nth 2 (elscreen-gf-read-selection 729 | "Cannot locate `ID'; what instead?" 730 | "Select action: " 731 | '(("m" "Execute mkid to generate `ID'" elscreen-gf-idutils-mkid) 732 | ("g" "Execute grep" elscreen-gf-grep)))))) 733 | ((elscreen-gf-process-exclusive-p elscreen-gf-search-process) 734 | (let* ((pattern (or pattern 735 | (elscreen-gf-search-read-pattern "Run gid (pattern): "))) 736 | (token-chars (or (elscreen-gf-major-mode-token-chars major-mode) 737 | "a-zA-Z0-9")) 738 | (token-chars-re (format "[%s]" token-chars)) 739 | (pattern-tokenize (elscreen-gf-search-regexp-dot-to-token 740 | pattern token-chars-re)) 741 | (directory (elscreen-gf-idutils-id-directory)) 742 | (command (format "%s --regexp '^(%s)$'" 743 | elscreen-gf-idutils-gid-program-name pattern))) 744 | ;; XXX: gid does not raise error even if given regexp starts with '*', 745 | ;; so we should check it here. 746 | (when (string-match "^\\*" pattern) 747 | (error "Invalid regexp: %s" pattern)) 748 | (elscreen-gf-run-search-command 749 | "gid" pattern-tokenize command directory 750 | 'elscreen-gf-grep-line-parser))))) 751 | 752 | ;;; cscope 753 | 754 | (defsubst elscreen-gf-cscope-cross-ref-directory (&optional directory) 755 | (elscreen-gf-db-directory "cscope.out" directory)) 756 | 757 | (defun elscreen-gf-cscope (&optional pattern directory) 758 | "Run cscope, with user-specified args, and collect output 759 | in the ElScreen-GF buffer." 760 | (interactive) 761 | (cond 762 | ((not (executable-find elscreen-gf-cscope-program-name)) 763 | (when (yes-or-no-p "cscope not found; execute grep instead? ") 764 | (elscreen-gf-grep))) 765 | ((elscreen-gf-process-exclusive-p elscreen-gf-search-process) 766 | (let* ((pattern (or pattern 767 | (elscreen-gf-search-read-pattern 768 | "Run cscope (pattern): "))) 769 | (directory (or (and directory (file-directory-p directory) directory) 770 | (elscreen-gf-cscope-cross-ref-directory) 771 | (read-directory-name "Run cscope (target): " 772 | default-directory nil t))) 773 | (token-chars (or (elscreen-gf-major-mode-token-chars major-mode) 774 | "a-zA-Z0-9")) 775 | (token-chars-re (format "[%s]" token-chars)) 776 | (pattern-tokenize (elscreen-gf-search-regexp-dot-to-token 777 | pattern token-chars-re)) 778 | (query-type-def (elscreen-gf-read-selection 779 | "Available query type for cscope: " 780 | "Select query type: " 781 | '(("0" "Find this C symbol" 0) 782 | ("1" "Find this function definition" 1) 783 | ("2" "Find functions calling this function" 3)))) 784 | (query-type (nth 2 query-type-def)) 785 | (command (format "%s -LR -%d '%s' | sort -k 1,1 -k 3,3n" 786 | elscreen-gf-cscope-program-name query-type pattern)) 787 | (line-parser (intern 788 | (format "elscreen-gf-cscope-line-parser-query-type-%s" 789 | (car query-type-def))))) 790 | (elscreen-gf-run-search-command 791 | "cscope" pattern-tokenize command directory line-parser))))) 792 | 793 | (defsubst elscreen-gf-cscope-line-parser-string-match (line) 794 | (string-match "^\\([^ ]+\\) \\([^ ]+\\) \\([0-9]+\\) \\(.*\\)$" line)) 795 | 796 | (defun elscreen-gf-cscope-line-parser-common (line) 797 | (when (elscreen-gf-cscope-line-parser-string-match line) 798 | (let ((file-name (match-string 1 line)) 799 | (line-number (match-string 3 line)) 800 | (function-name (match-string 2 line)) 801 | (source (match-string 4 line))) 802 | (list file-name line-number 803 | (list (format "[%s] %s" function-name source) 804 | (+ (length function-name) 3) (length source)))))) 805 | 806 | (defalias 'elscreen-gf-cscope-line-parser-query-type-0 807 | 'elscreen-gf-cscope-line-parser-common) 808 | 809 | (defun elscreen-gf-cscope-line-parser-query-type-1 (line) 810 | (when (elscreen-gf-cscope-line-parser-string-match line) 811 | (let ((file-name (match-string 1 line)) 812 | (line-number (match-string 3 line)) 813 | (source (match-string 4 line))) 814 | (list file-name line-number (list source 0 (length source)))))) 815 | 816 | (defalias 'elscreen-gf-cscope-line-parser-query-type-2 817 | 'elscreen-gf-cscope-line-parser-common) 818 | 819 | ;;; GNU global 820 | 821 | (defsubst elscreen-gf-global-tags-directory (&optional directory) 822 | (elscreen-gf-db-directory "GTAGS" directory)) 823 | 824 | (defvar elscreen-gf-global-gtags-process nil) 825 | 826 | (defun elscreen-gf-global-gtags (&optional directory) 827 | "Run gtags, with user-specified args." 828 | (interactive) 829 | (cond 830 | ((not (executable-find elscreen-gf-global-gtags-program-name)) 831 | (error "gtags not found.")) 832 | ((elscreen-gf-process-exclusive-p elscreen-gf-global-gtags-process) 833 | (let ((default-directory 834 | (or (and directory (file-directory-p directory) directory) 835 | (read-directory-name "Run gtags (target): " 836 | (or (elscreen-gf-global-tags-directory) 837 | default-directory) nil t))) 838 | (command (format "%s" elscreen-gf-global-gtags-program-name))) 839 | (message "Running gtags...") 840 | (setq elscreen-gf-global-gtags-process 841 | (start-process "gtags" nil "sh" "-c" command)) 842 | (set-process-sentinel elscreen-gf-global-gtags-process 843 | 'elscreen-gf-global-gtags-sentinel) 844 | (elscreen-notify-screen-modification 'force-immediately))))) 845 | 846 | (defun elscreen-gf-global-gtags-sentinel (process event) 847 | (let ((status (string-match "finished" event))) 848 | (message "Running gtags... %s" (if status "done" "error")) 849 | (setq elscreen-gf-global-gtags-process nil) 850 | (elscreen-notify-screen-modification 'force-immediately))) 851 | 852 | (defun elscreen-gf-global-gtags-after-save () 853 | (when (and (buffer-file-name) 854 | (elscreen-gf-process-exclusive-p 855 | elscreen-gf-global-gtags-process 'noerror)) 856 | (let ((tags-directory (elscreen-gf-global-tags-directory))) 857 | (when tags-directory 858 | (elscreen-gf-global-gtags tags-directory))))) 859 | 860 | (defun elscreen-gf-global-gtags-setup-after-save-hook () 861 | (make-local-variable 'after-save-hook) 862 | (add-hook 'after-save-hook 'elscreen-gf-global-gtags-after-save)) 863 | 864 | (defvar elscreen-gf-global-5.0-or-later-p) 865 | (defsubst elscreen-gf-global-5.0-or-later-p () 866 | (unless (boundp 'elscreen-gf-global-5.0-or-later-p) 867 | (let (global-version) 868 | (with-temp-buffer 869 | (call-process elscreen-gf-global-program-name nil t nil "--version") 870 | (setq global-version (string-to-number 871 | (buffer-substring (point-min) (point-max))))) 872 | (setq elscreen-gf-global-5.0-or-later-p (and global-version 873 | (<= 5.0 global-version))))) 874 | elscreen-gf-global-5.0-or-later-p) 875 | 876 | (defun elscreen-gf-global (&optional pattern directory) 877 | "Run global, with user-specified args, and collect output 878 | in the ElScreen-GF buffer." 879 | (interactive) 880 | (cond 881 | ((not (executable-find elscreen-gf-global-program-name)) 882 | (when (yes-or-no-p "global not found; execute grep instead? ") 883 | (elscreen-gf-grep))) 884 | ((not (elscreen-gf-global-tags-directory)) 885 | (funcall 886 | (nth 2 (elscreen-gf-read-selection 887 | "Cannot locate `GTAGS'; what instead?" 888 | "Select action: " 889 | '(("t" "Execute gtags to generate `GTAGS'" elscreen-gf-global-gtags) 890 | ("g" "Execute grep" elscreen-gf-grep)))))) 891 | ((elscreen-gf-process-exclusive-p elscreen-gf-search-process) 892 | (let* ((pattern (or pattern 893 | (elscreen-gf-search-read-pattern 894 | "Run global (pattern): "))) 895 | (directory (or (and directory (file-directory-p directory) directory) 896 | (elscreen-gf-global-tags-directory) 897 | (read-directory-name "Run global (target): " 898 | default-directory nil t))) 899 | (token-chars (or (elscreen-gf-major-mode-token-chars major-mode) 900 | "a-zA-Z0-9")) 901 | (token-chars-re (format "[%s]" token-chars)) 902 | (pattern-tokenize (elscreen-gf-search-regexp-dot-to-token 903 | pattern token-chars-re)) 904 | (query-type (nth 2 (elscreen-gf-read-selection 905 | "Available query type for GNU GLOBAL: " 906 | "Select query type: " 907 | '(("0" "Find this object definition" "") 908 | ("1" "Find this object references" " -r"))))) 909 | (command (format 910 | (cond 911 | ((elscreen-gf-global-5.0-or-later-p) 912 | "%s%s --result=grep -e '%s' | sort -t : -k 1,1 -k 2,2n") 913 | (t 914 | "%s -x%s -e '%s' | sort -k 3,3 -k 2,2n")) 915 | elscreen-gf-global-program-name query-type pattern)) 916 | (line-parser (if (elscreen-gf-global-5.0-or-later-p) 917 | 'elscreen-gf-grep-line-parser 918 | 'elscreen-gf-global-line-parser))) 919 | (elscreen-gf-run-search-command 920 | "global" pattern-tokenize command directory line-parser))))) 921 | 922 | (defun elscreen-gf-global-line-parser (line) 923 | (when (string-match "^[^ ]+ +\\([0-9]+\\) +\\([^ ]+\\) \\(.*\\)$" line) 924 | (let ((file-name (match-string 2 line)) 925 | (line-number (match-string 1 line)) 926 | (source (match-string 3 line))) 927 | (list file-name line-number (list source 0 (length source)))))) 928 | 929 | ;;; Going back to the latest invoke-point. 930 | 931 | (defun elscreen-gf-go-back-to-latest-invoke-point () 932 | (interactive) 933 | (while (not (or (ring-empty-p elscreen-gf-invoke-point-history) 934 | (let ((invoke-point 935 | (ring-ref elscreen-gf-invoke-point-history 0))) 936 | (buffer-live-p (marker-buffer (cdr invoke-point)))))) 937 | (ring-remove elscreen-gf-invoke-point-history 0)) 938 | (if (ring-empty-p elscreen-gf-invoke-point-history) 939 | (message "No more invoke-points to go back to.") 940 | (let* ((invoke-point (ring-remove elscreen-gf-invoke-point-history 0)) 941 | (invoke-point-screen (car invoke-point)) 942 | (invoke-point-marker (cdr invoke-point)) 943 | (invoke-point-buffer (marker-buffer invoke-point-marker)) 944 | (invoke-point-position (marker-position invoke-point-marker)) 945 | (invoke-point-buffer-screen-list 946 | (elscreen-find-screens 947 | `(lambda (screen) 948 | (elscreen-goto-internal screen) 949 | (not (null (get-buffer-window ,invoke-point-buffer)))))) 950 | (get-marker-window 951 | (lambda (marker) 952 | (catch 'found 953 | (save-window-excursion 954 | (mapc 955 | (lambda (window) 956 | (select-window window) 957 | (when (eq (point) (marker-position marker)) 958 | (throw 'found window))) 959 | (get-buffer-window-list (marker-buffer marker)))) 960 | nil)))) 961 | (cond 962 | ((null invoke-point-buffer-screen-list) 963 | ;; No screens showing invoke-point-buffer, so create new screen 964 | ;; and show it. 965 | (elscreen-create) 966 | (switch-to-buffer invoke-point-buffer) 967 | (goto-char invoke-point-position)) 968 | ((memq invoke-point-screen invoke-point-buffer-screen-list) 969 | ;; invoke-point-screen shows invoke-point-buffer, so go to the 970 | ;; screen and select the window showing the buffer. If there are 971 | ;; two or more window showing the buffer, we prefer the window 972 | ;; whose buffer's point is invoke-point-position. Anyway, 973 | ;; we are moving point to it. 974 | (elscreen-goto invoke-point-screen) 975 | (select-window (or (funcall get-marker-window invoke-point-marker) 976 | (get-buffer-window invoke-point-buffer))) 977 | (goto-char invoke-point-position)) 978 | ((catch 'found 979 | (mapc 980 | (lambda (screen) 981 | (let (window) 982 | (when (save-window-excursion 983 | (elscreen-goto-internal screen) 984 | (setq window (funcall get-marker-window 985 | invoke-point-marker))) 986 | ;; There is (at least one) screen showing buffer whose 987 | ;; point is invoke-point-position, so show it. 988 | (elscreen-goto screen) 989 | (select-window window) 990 | (throw 'found t)))) 991 | invoke-point-buffer-screen-list))) 992 | (t 993 | ;; invoke-point-screen does not show invoke-point-buffer, and 994 | ;; the others does not show invoke-point-buffer whose point is 995 | ;; invoke-point-position; so we're showing one of screens showing 996 | ;; invoke-point-buffer and moving point to invoke-point-position. 997 | (elscreen-goto (car invoke-point-buffer-screen-list)) 998 | (select-window (get-buffer-window invoke-point-buffer)) 999 | (goto-char invoke-point-position)))))) 1000 | 1001 | ;;; Help 1002 | 1003 | (defvar elscreen-gf-help "ElScreen-GF keys: 1004 | \\[elscreen-gf-grep] Run grep 1005 | \\[elscreen-gf-idutils-mkid] Run mkid (GNU ID Utils) 1006 | \\[elscreen-gf-idutils-gid] Run gid (GNU ID Utils) 1007 | \\[elscreen-gf-cscope] Run cscope 1008 | \\[elscreen-gf-global-gtags] Run gtags (GNU GLOBAL) 1009 | \\[elscreen-gf-global] Run global (GNU GLOBAL) 1010 | \\[elscreen-gf-go-back-to-latest-invoke-point] Go back to the latest invoke-point. 1011 | \\[elscreen-gf-display-version] Display ElScreen-GF version") 1012 | (elscreen-set-help 'elscreen-gf-help) 1013 | 1014 | (defun elscreen-gf-display-version () 1015 | "Display ElScreen-GF version." 1016 | (interactive) 1017 | (elscreen-message (concat "ElScreen-GF version " elscreen-gf-version))) 1018 | -------------------------------------------------------------------------------- /elscreen-goby.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-goby.el 4 | ;; 5 | (defconst elscreen-goby-version "0.0.0 (July 14, 2005)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Nara Institute of Science and Technology, Japan 9 | ;; Created: July 14, 2005 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-goby) 26 | (require 'elscreen) 27 | 28 | 29 | ;;; Code: 30 | 31 | (defadvice goby-view-mode (before elscreen-goby-view-mode activate) 32 | (set (make-local-variable 'elscreen-display-tab) nil)) 33 | 34 | (defadvice goby-view-quit (before elscreen-goby-view-quit activate) 35 | (kill-local-variable 'elscreen-display-tab)) 36 | -------------------------------------------------------------------------------- /elscreen-howm.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-howm.el 4 | ;; 5 | (defconst elscreen-howm-version "0.1.3 (September 14, 2008)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: November 06, 2005 9 | ;; Revised: September 14, 2008 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-howm) 26 | (require 'elscreen) 27 | 28 | ;;; User Customizable Variables: 29 | 30 | (defcustom elscreen-howm-mode-to-nickname-alist 31 | '(("^howm-\\(menu-mode$\\|view-\\)" . "howm(menu)")) 32 | "*Alist composed of the pair of mode-name and corresponding screen-name." 33 | :type '(alist :key-type string :value-type (choice string function)) 34 | :tag "Howm major-mode to nickname alist" 35 | :set (lambda (symbol value) 36 | (custom-set-default symbol value) 37 | (elscreen-rebuild-mode-to-nickname-alist)) 38 | :group 'howm) 39 | (elscreen-set-mode-to-nickname-alist 'elscreen-howm-mode-to-nickname-alist) 40 | 41 | (defcustom elscreen-howm-buffer-to-nickname-alist 42 | '(("\\.howm$" . elscreen-howm-mode-buffer-to-nickname)) 43 | "*Alist composed of the pair of regular expression of 44 | buffer-name and corresponding screen-name." 45 | :type '(alist :key-type string :value-type (choice string function)) 46 | :tag "Howm buffer to nickname alist" 47 | :set (lambda (symbol value) 48 | (custom-set-default symbol value) 49 | (elscreen-rebuild-buffer-to-nickname-alist)) 50 | :group 'howm) 51 | (elscreen-set-buffer-to-nickname-alist 'elscreen-howm-buffer-to-nickname-alist) 52 | 53 | 54 | ;;; Code: 55 | 56 | ;; delete other windows when howm-menu is invoked 57 | (defadvice howm-menu (around elscreen-howm-menu activate) 58 | (delete-other-windows) 59 | ad-do-it) 60 | 61 | ;; create new page with new screen 62 | (defadvice howm-create-file-with-title (around elscreen-howm-create-file-with-title activate) 63 | (save-current-buffer 64 | (elscreen-create)) 65 | ad-do-it) 66 | 67 | ;; open existing page with new screen 68 | (defadvice howm-view-open-item (around elscreen-howm-view-open-item activate) 69 | (let ((window-configuration (elscreen-current-window-configuration)) 70 | howm-item-buffer) 71 | ad-do-it 72 | (setq howm-item-buffer (current-buffer)) 73 | (elscreen-apply-window-configuration window-configuration) 74 | (elscreen-find-and-goto-by-buffer howm-item-buffer 'create))) 75 | 76 | (eval-after-load "howm-view" 77 | '(unless (fboundp 'howm-view-open-item) 78 | (elscreen-message "This version of elscreen-howm does not work well with your howm. Upgrade howm to version 1.3.3 or later, or downgrade elscreen-howm to version 0.0.1."))) 79 | 80 | ;; screen nickname 81 | (defun elscreen-howm-mode-buffer-to-nickname () 82 | (format "howm(%s%s%s)" 83 | elscreen-howm-title 84 | (if (zerop (length elscreen-howm-title)) "" ":") 85 | (substring (buffer-name (current-buffer)) 0 -5))) 86 | 87 | (defun elscreen-howm-mode-update-title () 88 | (let ((title (howm-title-at-current-point))) 89 | (when (not (string-equal elscreen-howm-title title)) 90 | (setq elscreen-howm-title title) 91 | (elscreen-notify-screen-modification 'force-immediately)))) 92 | 93 | (defun elscreen-howm-mode-initialize () 94 | (set (make-local-variable 'elscreen-howm-title) 95 | (howm-title-at-current-point)) 96 | (add-hook 'post-command-hook 'elscreen-howm-mode-update-title t t)) 97 | 98 | (add-hook 'howm-mode-on-hook 'elscreen-howm-mode-initialize) 99 | 100 | ;; kill screen when exiting from howm-mode 101 | (defun howm-save-and-kill-buffer/screen () 102 | (interactive) 103 | (let* ((file-name (buffer-file-name))) 104 | (if (save-excursion 105 | (goto-char (point-min)) 106 | (re-search-forward "[^ \t\r\n]" nil t)) 107 | (howm-save-buffer) 108 | (set-buffer-modified-p nil) 109 | (when (file-exists-p file-name) 110 | (delete-file file-name) 111 | (message "(Deleted %s)" (file-name-nondirectory file-name)))) 112 | (kill-buffer nil) 113 | (unless (elscreen-one-screen-p) 114 | (elscreen-kill)))) 115 | 116 | (eval-after-load "howm-mode" 117 | '(progn 118 | (define-key howm-mode-map 119 | "\C-c\C-c" 'howm-save-and-kill-buffer/screen))) 120 | -------------------------------------------------------------------------------- /elscreen-server.el: -------------------------------------------------------------------------------- 1 | ;;; elscreen-server.el --- server support for elscreen 2 | ;; 3 | (defconst elscreen-server-version "0.2.0 (November 23, 2007)") 4 | ;; 5 | ;; Author: Hideyuki Shirai 6 | ;; Naoto Morishima 7 | ;; Created: October 11, 2007 8 | ;; Revised: November 23, 2007 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; 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; see the file COPYING. If not, write to 22 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 | 24 | ;;; Commentary: 25 | 26 | ;;; Code: 27 | 28 | (require 'elscreen) 29 | (require 'dframe) 30 | 31 | (defcustom elscreen-server-dont-use-dedicated-frame t 32 | "*Non-nil to use dframe-attached-frame if frame is dedicated." 33 | :type 'boolean 34 | :group 'server) 35 | 36 | (defun elscreen-server-visit-files-new-screen (buffer-list) 37 | "Create a screen for each buffer in BUFFER-LIST." 38 | (let* ((selected-frame (selected-frame)) 39 | (dframe-attached-frame (dframe-attached-frame selected-frame))) 40 | (when (and elscreen-server-dont-use-dedicated-frame 41 | (framep dframe-attached-frame)) 42 | (select-frame dframe-attached-frame)) 43 | (let ((screen (car (mapcar 44 | (lambda (buffer) 45 | (elscreen-find-screen-by-buffer buffer 'create)) 46 | buffer-list)))) 47 | (and screen 48 | (elscreen-goto screen))) 49 | (elscreen-notify-screen-modification 'force-immediately) 50 | (select-frame selected-frame))) 51 | 52 | (eval-after-load "server" 53 | ;; For server.el distributed with GNU Emacs 54 | '(progn 55 | (defadvice server-visit-files (after elscreen-server-visit-files activate) 56 | (elscreen-server-visit-files-new-screen ad-return-value)))) 57 | 58 | (provide 'elscreen-server) 59 | ;;; elscreen-server.el ends here 60 | -------------------------------------------------------------------------------- /elscreen-speedbar.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-speedbar.el 4 | ;; 5 | (defconst elscreen-speedbar-version "0.0.0 (November 18, 2007)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: November 18, 2007 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation; either version 2, or (at your option) 13 | ;; 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; see the file COPYING. If not, write to 22 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 23 | 24 | (provide 'elscreen-speedbar) 25 | (require 'elscreen) 26 | 27 | (defcustom elscreen-speedbar-find-file-in-screen t 28 | "Non-nil to use ElScreen to open file when the selected file is being 29 | opened in the attached frame." 30 | :type 'boolean 31 | :group 'speedbar) 32 | 33 | (defadvice speedbar-frame-mode (after elscreen-speedbar-frame-mode activate) 34 | (with-current-buffer speedbar-buffer 35 | (set (make-local-variable 'elscreen-display-tab) nil))) 36 | 37 | (defadvice speedbar-find-file-in-frame (around elscreen-speedbar-find-file-in-frame activate) 38 | (let ((buffer (find-file-noselect file))) 39 | (if (or (get-buffer-window buffer 0) 40 | dframe-power-click 41 | (numberp speedbar-select-frame-method) 42 | (not elscreen-speedbar-find-file-in-screen)) 43 | (let ((dframe-power-click (and (not elscreen-speedbar-find-file-in-screen) 44 | dframe-power-click))) 45 | ad-do-it) 46 | (dframe-select-attached-frame speedbar-frame) 47 | (elscreen-find-and-goto-by-buffer buffer 'create)) 48 | (elscreen-notify-screen-modification 'force-immediately))) 49 | -------------------------------------------------------------------------------- /elscreen-w3m.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-w3m.el 4 | ;; 5 | (defconst elscreen-w3m-version "0.2.2 (July 26, 2006)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: August 6, 2004 9 | ;; Revised: July 26, 2006 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-w3m) 26 | (require 'elscreen) 27 | 28 | ;; Code: 29 | 30 | (defconst elscreen-w3m-mode-to-nickname-alist 31 | '(("^w3m-mode" . 32 | (lambda (buf) 33 | (with-current-buffer buf 34 | (let ((graphic (and window-system 35 | w3m-show-graphic-icons-in-header-line))) 36 | (concat 37 | (when (and graphic w3m-use-favicon w3m-favicon-image) 38 | (concat 39 | (propertize 40 | " " 41 | 'display w3m-favicon-image) 42 | (propertize 43 | " " 44 | 'display '(space :width 0.5)))) 45 | (w3m-current-title))))))) 46 | "*Alist composed of the pair of mode-name and corresponding screen-name.") 47 | (elscreen-set-mode-to-nickname-alist 'elscreen-w3m-mode-to-nickname-alist) 48 | 49 | (defun elscreen-w3m-mailto-url-popup-function (buffer) 50 | (elscreen-find-and-goto-by-buffer buffer 'create)) 51 | 52 | (defadvice w3m-copy-buffer (around elscreen-w3m-copy-buffer activate) 53 | (let ((current-buffer (current-buffer))) 54 | (if (< (elscreen-get-number-of-screens) 10) 55 | (elscreen-create) 56 | (split-window) 57 | (other-window 1)) 58 | (unless (ad-get-arg 0) 59 | (ad-set-arg 0 current-buffer)) 60 | ad-do-it)) 61 | 62 | (defadvice w3m-favicon-retrieve (around elscreen-w3m-favicon-retrieve activate) 63 | ad-do-it 64 | (run-at-time 1 nil 'elscreen-notify-screen-modification 'force-immediately)) 65 | 66 | (defun elscreen-w3m-initialize () 67 | (setq w3m-pop-up-frames nil) 68 | (setq w3m-pop-up-windows nil) 69 | (setq w3m-use-tab nil) 70 | (setq w3m-use-tab-menubar nil) 71 | (setq w3m-use-header-line nil) 72 | (setq w3m-mailto-url-popup-function-alist 73 | '((cmail-mail-mode . elscreen-w3m-mailto-url-popup-function) 74 | (mail-mode . elscreen-w3m-mailto-url-popup-function) 75 | (message-mode . elscreen-w3m-mailto-url-popup-function) 76 | (mew-draft-mode . elscreen-w3m-mailto-url-popup-function) 77 | (mh-letter-mode . elscreen-w3m-mailto-url-popup-function) 78 | (wl-draft-mode . elscreen-w3m-mailto-url-popup-function))) 79 | (elscreen-screen-modified-hook-setup 80 | (w3m-fontify-after-hook 'force-immediately))) 81 | 82 | (add-hook 'w3m-load-hook 'elscreen-w3m-initialize) 83 | -------------------------------------------------------------------------------- /elscreen-wl.el: -------------------------------------------------------------------------------- 1 | ;; -*- Mode: Emacs-Lisp -*- 2 | ;; 3 | ;; elscreen-wl.el 4 | ;; 5 | (defconst elscreen-wl-version "0.8.0 (November 03, 2007)") 6 | ;; 7 | ;; Author: Naoto Morishima 8 | ;; Created: March 24, 2001 9 | ;; Revised: November 03, 2007 10 | 11 | ;; This program is free software; you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation; either version 2, or (at your option) 14 | ;; any later version. 15 | ;; 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | ;; 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program; see the file COPYING. If not, write to 23 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 24 | 25 | (provide 'elscreen-wl) 26 | (require 'elscreen) 27 | (require 'wl) 28 | 29 | 30 | ;;; User Customizable Variables: 31 | 32 | (defcustom elscreen-wl-draft-use-elscreen t 33 | "Non-nil to use ElScreen when Wanderlust prepares draft buffer. 34 | This option will override the option `wl-draft-use-frame'." 35 | :type 'boolean 36 | :group 'wl-draft) 37 | 38 | (defcustom elscreen-wl-display-biff-on-tab t 39 | "Non-nil to use ElScreen's tab to display biff icon instead of 40 | mode-line." 41 | :type 'boolean 42 | :set (lambda (symbol value) 43 | (custom-set-default symbol value) 44 | (let ((buf (get-buffer wl-folder-buffer-name))) 45 | (when buf 46 | (with-current-buffer buf 47 | (wl-mode-line-buffer-identification)))) 48 | (elscreen-notify-screen-modification 'force-immediately)) 49 | :group 'wl-highlight) 50 | 51 | (defcustom elscreen-wl-mode-to-nickname-alist 52 | '(("^wl-folder-mode$" . (lambda (buf) 53 | (elscreen-wl-nickname-with-biff-status "Folder"))) 54 | ("^wl-summary-mode$" . (lambda (buf) 55 | (elscreen-wl-nickname-with-biff-status 56 | (wl-summary-buffer-folder-name)))) 57 | ("^wl-draft-mode$" . (lambda (buf) 58 | (let ((buffer-name (buffer-name)) 59 | (subject (std11-field-body "Subject"))) 60 | (format "WL(%s%s)" 61 | buffer-name 62 | (if (zerop (length subject)) 63 | "" 64 | (concat "[" subject "]")))))) 65 | ("^wl-" . "Wanderlust")) 66 | "*Alist composed of the pair of mode-name and corresponding screen-name." 67 | :type '(alist :key-type string :value-type (choice string function)) 68 | :tag "Wanderlust major-mode to screen nickname alist" 69 | :set (lambda (symbol value) 70 | (custom-set-default symbol value) 71 | (elscreen-rebuild-mode-to-nickname-alist)) 72 | :group 'wl) 73 | (elscreen-set-mode-to-nickname-alist 'elscreen-wl-mode-to-nickname-alist) 74 | 75 | 76 | ;;; Code: 77 | 78 | (defmacro elscreen-wl-draft-create-buffer (ad-do-it) 79 | `(let ((wl-draft-use-frame wl-draft-use-frame) 80 | (wl-draft-reply-buffer-style wl-draft-reply-buffer-style)) 81 | (when elscreen-wl-draft-use-elscreen 82 | (setq wl-draft-use-frame nil) 83 | (setq wl-draft-reply-buffer-style 'full) 84 | (elscreen-create)) 85 | ,ad-do-it 86 | (when elscreen-wl-draft-use-elscreen 87 | (make-local-variable 'kill-buffer-hook) 88 | (add-hook 'kill-buffer-hook 89 | (lambda () 90 | (when `(buffer-live-p ,(current-buffer)) 91 | (elscreen-kill))))))) 92 | 93 | (defadvice wl-draft-create-buffer (around 94 | elscreen-ad-wl-draft-create-buffer 95 | activate) 96 | (elscreen-wl-draft-create-buffer ad-do-it)) 97 | 98 | (defadvice wl-draft-reedit (around 99 | elscreen-ad-wl-draft-reedit 100 | activate) 101 | (elscreen-wl-draft-create-buffer ad-do-it)) 102 | 103 | (defadvice wl-jump-to-draft-buffer (around 104 | elscreen-ad-wl-jump-to-draft-screen 105 | activate) 106 | (let ((original-buffer (current-buffer)) 107 | draft-buffer) 108 | ad-do-it 109 | (when elscreen-wl-draft-use-elscreen 110 | (setq draft-buffer (current-buffer)) 111 | (if (not (eq original-buffer draft-buffer)) 112 | (progn 113 | (switch-to-buffer original-buffer) 114 | (elscreen-find-and-goto-by-buffer draft-buffer)))))) 115 | 116 | (defmacro elscreen-wl-compensate-summary-window (ad-do-it) 117 | `(let ((wl-draft-use-frame (or wl-draft-use-frame 118 | elscreen-wl-draft-use-elscreen))) 119 | ,ad-do-it)) 120 | 121 | (defadvice wl-draft-forward (around elscreen-ad-wl-draft-forward activate) 122 | (elscreen-wl-compensate-summary-window ad-do-it)) 123 | 124 | (defadvice wl-draft-reply (around elscreen-ad-wl-draft-forward activate) 125 | (elscreen-wl-compensate-summary-window ad-do-it)) 126 | 127 | ;; Biff on ElScreen's tab 128 | 129 | (defsubst elscreen-wl-nickname-with-biff-status (name) 130 | (concat 131 | (when (and wl-biff-check-folder-list elscreen-wl-display-biff-on-tab) 132 | (concat 133 | (if wl-modeline-biff-status 134 | wl-modeline-biff-state-on 135 | wl-modeline-biff-state-off) 136 | (propertize " " 'display '(space :width 0.5)))) 137 | (format "WL(%s)" name))) 138 | 139 | (add-hook 'wl-biff-notify-hook 140 | (lambda () 141 | (when elscreen-wl-display-biff-on-tab 142 | (setq wl-modeline-biff-status t) 143 | (elscreen-notify-screen-modification 'force-immediately)))) 144 | 145 | (add-hook 'wl-biff-unnotify-hook 146 | (lambda () 147 | (when elscreen-wl-display-biff-on-tab 148 | (setq wl-modeline-biff-status nil) 149 | (elscreen-notify-screen-modification 'force-immediately)))) 150 | 151 | (defadvice wl-mode-line-buffer-identification (around elscreen-wl-mode-line-buffer-identification activate) 152 | (let ((wl-biff-check-folder-list wl-biff-check-folder-list)) 153 | (when elscreen-wl-display-biff-on-tab 154 | (setq wl-biff-check-folder-list nil)) 155 | ad-do-it)) 156 | -------------------------------------------------------------------------------- /elscreen.el: -------------------------------------------------------------------------------- 1 | ;;; elscreen.el --- Emacs window session manager 2 | 3 | ;; Author: Naoto Morishima 4 | ;; Based on: screens.el 5 | ;; by Heikki T. Suopanki 6 | ;; Created: June 22, 1996 7 | ;; Revised: April 11, 2012 by Emanuel Evans 8 | ;; Maintainer: Akinori MUSHA 9 | ;; Homepage: https://github.com/knu/elscreen 10 | ;; Version: 20180321 11 | ;; Package-Requires: ((emacs "24")) 12 | ;; Keywords: window, convenience 13 | 14 | ;; This file is NOT part of GNU Emacs. 15 | 16 | ;;; License: 17 | 18 | ;; This program is free software; you can redistribute it and/or modify 19 | ;; it under the terms of the GNU General Public License as published by 20 | ;; the Free Software Foundation; either version 2, or (at your option) 21 | ;; any later version. 22 | ;; 23 | ;; This program is distributed in the hope that it will be useful, 24 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 25 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 | ;; GNU General Public License for more details. 27 | ;; 28 | ;; You should have received a copy of the GNU General Public License 29 | ;; along with this program; see the file COPYING. If not, write to 30 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, 31 | ;; USA. 32 | 33 | ;;; Commentary: 34 | 35 | ;; This is a fork of ElScreen designed to be installed with 36 | ;; package.el. It does not require APEL (it also probably does not 37 | ;; work with XEmacs). In order to start using ElScreen, add 38 | ;; (elscreen-start) to your emacs configuration. For help on how to 39 | ;; use elscreen, try \C-z ?. 40 | 41 | ;;; Code: 42 | 43 | ;;; User Customizable Variables: 44 | 45 | (require 'dired) 46 | 47 | (declare-function iswitchb-read-buffer "iswitchb") 48 | 49 | (defconst elscreen-version "20180321") 50 | 51 | (defgroup elscreen nil 52 | "ElScreen -- Screen Manager for Emacs" 53 | :tag "ElScreen" 54 | :group 'environment) 55 | 56 | (defcustom elscreen-prefix-key "\C-z" 57 | "*Prefix key for ElScreen commands." 58 | :tag "Prefix Key of ElScreen" 59 | :type '(string :size 10) 60 | :set (lambda (symbol value) 61 | (when (boundp 'elscreen-map) 62 | (elscreen-set-prefix-key value)) 63 | (custom-set-default symbol value)) 64 | :group 'elscreen) 65 | 66 | (defcustom elscreen-default-buffer-name "*scratch*" 67 | "*Name of a buffer in new screen." 68 | :tag "Name of Default Buffer" 69 | :type '(string :size 24) 70 | :group 'elscreen) 71 | 72 | (defcustom elscreen-default-buffer-initial-major-mode initial-major-mode 73 | "*Major mode command symbol to use for the default buffer." 74 | :tag "Major Mode for Default Buffer" 75 | :type 'function 76 | :group 'elscreen) 77 | 78 | (defcustom elscreen-default-buffer-initial-message initial-scratch-message 79 | "*Initial message displayed in default buffer. 80 | If this is nil, no message will be displayed." 81 | :tag "Message to Display in the Default Buffer" 82 | :type '(choice (text :tag "Message") 83 | (const :tag "none" nil)) 84 | :group 'elscreen) 85 | 86 | (defcustom elscreen-mode-to-nickname-alist 87 | '(("^dired-mode$" . 88 | (lambda () 89 | (format "Dired(%s)" dired-directory))) 90 | ("^Info-mode$" . 91 | (lambda () 92 | (format "Info(%s)" (file-name-nondirectory Info-current-file)))) 93 | ("^mew-draft-mode$" . 94 | (lambda () 95 | (format "Mew(%s)" (buffer-name (current-buffer))))) 96 | ("^mew-" . "Mew") 97 | ("^irchat-" . "IRChat") 98 | ("^liece-" . "Liece") 99 | ("^lookup-" . "Lookup")) 100 | "*Alist composed of the pair of name of major-mode and corresponding screen-name." 101 | :tag "Alist to Derive Screen Names from Major Modes" 102 | :type '(alist :key-type string :value-type (choice string function)) 103 | :set (lambda (symbol value) 104 | (custom-set-default symbol value) 105 | (when (fboundp 'elscreen-rebuild-mode-to-nickname-alist) 106 | (elscreen-rebuild-mode-to-nickname-alist))) 107 | :group 'elscreen) 108 | 109 | (defcustom elscreen-buffer-to-nickname-alist 110 | '(("[Ss]hell" . "shell") 111 | ("compilation" . "compile") 112 | ("-telnet" . "telnet") 113 | ("dict" . "OnlineDict") 114 | ("*WL:Message*" . "Wanderlust")) 115 | "*Alist composed of the pair of regular expression of 116 | buffer-name and corresponding screen-name." 117 | :tag "Alist to Derive Screen Names from Major Modes" 118 | :type '(alist :key-type string :value-type (choice string function)) 119 | :set (lambda (symbol value) 120 | (custom-set-default symbol value) 121 | (when (fboundp 'elscreen-rebuild-buffer-to-nickname-alist) 122 | (elscreen-rebuild-buffer-to-nickname-alist))) 123 | :group 'elscreen) 124 | 125 | (defcustom elscreen-display-screen-number t 126 | "*Non-nil to display the number of current screen in the mode line." 127 | :tag "Show/Hide Screen Number on the mode-line" 128 | :type 'boolean 129 | :group 'elscreen) 130 | 131 | (defcustom elscreen-display-tab t 132 | "*Specify how the tabs at the top of frame should be displayed. 133 | t means to display tabs whose width should be calculated automatically. 134 | A value of integer means to display tabs with fixed width of this value. 135 | nil means don't display tabs." 136 | :tag "Specify how the tabs at the top of frame should be displayed" 137 | :type '(choice (const :tag "Show (automatic width tab)" t) 138 | (integer :tag "Show (fixed width tab)" :size 4 :value 16) 139 | (const :tag "Hide" nil)) 140 | :set (lambda (symbol value) 141 | (when (or (booleanp value) 142 | (and (numberp value) 143 | (> value 0))) 144 | (custom-set-default symbol value) 145 | (when (fboundp 'elscreen-tab-update) 146 | (elscreen-tab-update t)))) 147 | :group 'elscreen) 148 | 149 | (make-obsolete-variable 'elscreen-tab-display-create-screen 150 | 'elscreen-tab-display-control "2012-04-11") 151 | (defcustom elscreen-tab-display-control t 152 | "*Non-nil to display control tab at the most left side." 153 | :tag "Show/Hide the Control Tab" 154 | :type 'boolean 155 | :set (lambda (symbol value) 156 | (custom-set-default symbol value) 157 | (when (fboundp 'elscreen-tab-update) 158 | (elscreen-tab-update t))) 159 | :group 'elscreen) 160 | 161 | (defcustom elscreen-tab-display-kill-screen 'left 162 | "*Location of the icons to kill a screen on each tab. Possible values are 'left, 'right, or nil (to hide them)." 163 | :tag "Location of Buttons to Kill Screen on Each Tab" 164 | :type '(choice (const :tag "Left" left) 165 | (const :tag "Right" right) 166 | (const :tag "None" nil)) 167 | :set (lambda (symbol value) 168 | (custom-set-default symbol value) 169 | (when (fboundp 'elscreen-tab-update) 170 | (elscreen-tab-update t))) 171 | :group 'elscreen) 172 | 173 | (defface elscreen-tab-background-face 174 | '((((type x w32 mac ns) (class color)) 175 | :background "Gray50") 176 | (((class color)) 177 | (:background "black"))) 178 | "Face to fontify background of tab line." 179 | :group 'elscreen) 180 | 181 | (defface elscreen-tab-control-face 182 | '((((type x w32 mac ns) (class color)) 183 | (:background "white" :foreground "black" :underline "Gray50")) 184 | (((class color)) 185 | (:background "white" :foreground "black" :underline t)) 186 | (t (:underline t))) 187 | "Face for control tab." 188 | :group 'elscreen) 189 | 190 | (defface elscreen-tab-current-screen-face 191 | '((((class color)) 192 | (:background "white" :foreground "black")) 193 | (t (:underline t))) 194 | "Face for current screen tab." 195 | :group 'elscreen) 196 | 197 | (defface elscreen-tab-other-screen-face 198 | '((((type x w32 mac ns) (class color)) 199 | :background "Gray85" :foreground "Gray50") 200 | (((class color)) 201 | (:background "blue" :foreground "black" :underline t))) 202 | "Face for tabs other than current screen one." 203 | :group 'elscreen) 204 | 205 | 206 | ;;; Key & Menu bindings: 207 | 208 | (defvar elscreen-map (make-sparse-keymap) 209 | "Keymap for ElScreen.") 210 | (define-key elscreen-map "\C-c" 'elscreen-create) 211 | (define-key elscreen-map "c" 'elscreen-create) 212 | (define-key elscreen-map "C" 'elscreen-clone) 213 | (define-key elscreen-map "\C-k" 'elscreen-kill) 214 | (define-key elscreen-map "k" 'elscreen-kill) 215 | (define-key elscreen-map "\M-k" 'elscreen-kill-screen-and-buffers) 216 | (define-key elscreen-map "K" 'elscreen-kill-others) 217 | (define-key elscreen-map "\C-p" 'elscreen-previous) 218 | (define-key elscreen-map "p" 'elscreen-previous) 219 | (define-key elscreen-map "\C-n" 'elscreen-next) 220 | (define-key elscreen-map "n" 'elscreen-next) 221 | (define-key elscreen-map "\C-a" 'elscreen-toggle) 222 | (define-key elscreen-map "a" 'elscreen-toggle) 223 | (define-key elscreen-map "'" 'elscreen-goto) 224 | (define-key elscreen-map "\"" 'elscreen-select-and-goto) 225 | (define-key elscreen-map "0" 'elscreen-jump-0) 226 | (define-key elscreen-map "1" 'elscreen-jump) 227 | (define-key elscreen-map "2" 'elscreen-jump) 228 | (define-key elscreen-map "3" 'elscreen-jump) 229 | (define-key elscreen-map "4" 'elscreen-jump) 230 | (define-key elscreen-map "5" 'elscreen-jump) 231 | (define-key elscreen-map "6" 'elscreen-jump) 232 | (define-key elscreen-map "7" 'elscreen-jump) 233 | (define-key elscreen-map "8" 'elscreen-jump) 234 | (define-key elscreen-map "9" 'elscreen-jump-9) 235 | (define-key elscreen-map "\C-s" 'elscreen-swap) 236 | (define-key elscreen-map "\C-w" 'elscreen-display-screen-name-list) 237 | (define-key elscreen-map "w" 'elscreen-display-screen-name-list) 238 | (define-key elscreen-map "\C-m" 'elscreen-display-last-message) 239 | (define-key elscreen-map "m" 'elscreen-display-last-message) 240 | (define-key elscreen-map "\C-t" 'elscreen-display-time) 241 | (define-key elscreen-map "t" 'elscreen-display-time) 242 | (define-key elscreen-map "A" 'elscreen-screen-nickname) 243 | (define-key elscreen-map "b" 'elscreen-find-and-goto-by-buffer) 244 | (define-key elscreen-map "\C-f" 'elscreen-find-file) 245 | (define-key elscreen-map "\C-r" 'elscreen-find-file-read-only) 246 | (define-key elscreen-map "d" 'elscreen-dired) 247 | (define-key elscreen-map "\M-x" 'elscreen-execute-extended-command) 248 | (define-key elscreen-map "i" 'elscreen-toggle-display-screen-number) 249 | (define-key elscreen-map "T" 'elscreen-toggle-display-tab) 250 | (define-key elscreen-map "?" 'elscreen-help) 251 | (define-key elscreen-map "v" 'elscreen-display-version) 252 | (define-key elscreen-map "j" 'elscreen-link) 253 | (define-key elscreen-map "s" 'elscreen-split) 254 | 255 | (defun elscreen-set-prefix-key (prefix-key) 256 | (when (not (eq elscreen-prefix-key prefix-key)) 257 | (when elscreen-prefix-key 258 | (global-set-key elscreen-prefix-key 259 | (get 'elscreen-prefix-key 260 | 'global-map-original-definition)) 261 | (define-key minibuffer-local-map elscreen-prefix-key 262 | (get 'elscreen-prefix-key 'minibuffer-local-map-original-definition))) 263 | (put 'elscreen-prefix-key 'global-map-original-definition 264 | (lookup-key global-map prefix-key)) 265 | (put 'elscreen-prefix-key 'minibuffer-local-map-original-definition 266 | (lookup-key minibuffer-local-map prefix-key))) 267 | (global-set-key prefix-key elscreen-map) 268 | (define-key minibuffer-local-map prefix-key 'undefined) 269 | (setq elscreen-prefix-key prefix-key)) 270 | 271 | (defvar elscreen-help "ElScreen keys: 272 | \\[elscreen-create] Create a new screen and switch to it 273 | \\[elscreen-clone] Create a new screen with the window-configuration of current screen 274 | \\[elscreen-kill] Kill current screen 275 | \\[elscreen-kill-screen-and-buffers] Kill current screen and buffers 276 | \\[elscreen-kill-others] Kill other screens 277 | \\[elscreen-next] Switch to the \"next\" screen in a cyclic order 278 | \\[elscreen-previous] Switch to the \"previous\" screen in a cyclic order 279 | \\[elscreen-toggle] Toggle to the screen selected previously 280 | \\[elscreen-select-and-goto] Jump to the specified screen 281 | \\[elscreen-jump-0] 282 | : Jump to the screen # 283 | \\[elscreen-jump-9] 284 | \\[elscreen-swap] Swap current screen with previous one 285 | \\[elscreen-display-screen-name-list] Show list of screens 286 | \\[elscreen-screen-nickname] Name current screen 287 | \\[elscreen-display-last-message] Show last message 288 | \\[elscreen-display-time] Show time 289 | \\[elscreen-find-and-goto-by-buffer] Switch to the screen in which specified buffer is displayed 290 | \\[elscreen-find-file] Create new screen and open file 291 | \\[elscreen-find-file-read-only] Create new screen and open file but don't allow changes 292 | \\[elscreen-dired] Create new screen and run dired 293 | \\[elscreen-execute-extended-command] Read function name, then call it with new screen 294 | \\[elscreen-toggle-display-screen-number] Show/hide the screen number in the mode line 295 | \\[elscreen-toggle-display-tab] Show/hide the tab at the top of screen 296 | \\[elscreen-display-version] Show ElScreen version 297 | \\[elscreen-help] Show this help" 298 | "Help shown by elscreen-help-mode") 299 | 300 | ;;; alist utility functions (taken from APEL): 301 | 302 | (defun elscreen--put-alist (key value alist) 303 | "Set cdr of an element (KEY . ...) in ALIST to VALUE and return ALIST. 304 | If there is no such element, create a new pair (KEY . VALUE) and 305 | return a new alist whose car is the new pair and cdr is ALIST." 306 | (let ((elm (assoc key alist))) 307 | (if elm 308 | (progn 309 | (setcdr elm value) 310 | alist) 311 | (cons (cons key value) alist)))) 312 | 313 | (defun elscreen--set-alist (symbol key value) 314 | "Set cdr of an element (KEY . ...) in the alist bound to SYMBOL to VALUE." 315 | (or (boundp symbol) 316 | (set symbol nil)) 317 | (set symbol (elscreen--put-alist key value (symbol-value symbol)))) 318 | 319 | (defun elscreen--del-alist (key alist) 320 | "Delete an element whose car equals KEY from ALIST. 321 | Return the modified ALIST." 322 | (let ((pair (assoc key alist))) 323 | (if pair 324 | (delq pair alist) 325 | alist))) 326 | 327 | (defun elscreen-window-history-supported-p () 328 | (and (fboundp 'window-prev-buffers) 329 | (fboundp 'window-next-buffers) 330 | (fboundp 'set-window-prev-buffers) 331 | (fboundp 'set-window-next-buffers))) 332 | 333 | (defun elscreen-get-all-window-history-alist () 334 | (when (elscreen-window-history-supported-p) 335 | (mapcar (lambda (window) 336 | (let ((prevs (window-prev-buffers window)) 337 | (nexts (window-next-buffers window))) 338 | (cons window (cons prevs nexts)))) 339 | (window-list)))) 340 | 341 | (defun elscreen-restore-all-window-history-alist (history-alist) 342 | (when (elscreen-window-history-supported-p) 343 | (mapc (lambda (entry) 344 | (let* ((window (car entry)) 345 | (histories (cdr entry)) 346 | (prevs (car histories)) 347 | (nexts (cdr histories))) 348 | (when (window-valid-p window) 349 | (set-window-prev-buffers window prevs) 350 | (set-window-next-buffers window nexts)))) 351 | history-alist))) 352 | 353 | (defun elscreen--remove-alist (symbol key) 354 | "Delete an element whose car equals KEY from the alist bound to SYMBOL." 355 | (and (boundp symbol) 356 | (set symbol (elscreen--del-alist key (symbol-value symbol))))) 357 | 358 | ;;; Internal Functions: 359 | 360 | (defvar elscreen-frame-confs nil 361 | "Alist that contains the information about screen configurations.") 362 | 363 | (defun elscreen-current-window-configuration () 364 | (list (current-window-configuration) (point-marker))) 365 | 366 | (defun elscreen-default-window-configuration () 367 | (let ((default-buffer (get-buffer elscreen-default-buffer-name))) 368 | (save-window-excursion 369 | (set-window-dedicated-p (selected-window) nil) 370 | (delete-other-windows) 371 | (if default-buffer 372 | (switch-to-buffer default-buffer) 373 | (switch-to-buffer (get-buffer-create elscreen-default-buffer-name)) 374 | (funcall elscreen-default-buffer-initial-major-mode) 375 | (insert elscreen-default-buffer-initial-message) 376 | (set-buffer-modified-p nil)) 377 | (elscreen-current-window-configuration)))) 378 | 379 | (defun elscreen-apply-window-configuration (elscreen-window-configuration) 380 | (let ((window-configuration (car elscreen-window-configuration)) 381 | (marker (cadr elscreen-window-configuration))) 382 | (set-window-configuration window-configuration) 383 | (when (marker-buffer marker) 384 | (goto-char marker)))) 385 | 386 | (defsubst elscreen-copy-tree (tree) 387 | (if (fboundp 'copy-tree) 388 | (copy-tree tree) 389 | (elscreen-copy-tree-1 tree))) 390 | 391 | (defun elscreen-copy-tree-1 (tree) 392 | (let (clone) 393 | (while (consp tree) 394 | (setq clone (cons (or (and (consp (car tree)) 395 | (elscreen-copy-tree-1 (car tree))) 396 | (car tree)) 397 | clone)) 398 | (setq tree (cdr tree))) 399 | (nconc (nreverse clone) tree))) 400 | 401 | (defmacro elscreen-save-screen-excursion (&rest body) 402 | "Execute BODY, preserving ElScreen meta data. 403 | Return the value of the last form in BODY." 404 | `(let ((original-buffer-list (buffer-list)) 405 | (original-buffer-live-p nil) 406 | (original-elscreen-window-configuration 407 | (elscreen-current-window-configuration)) 408 | (original-frame-confs (elscreen-copy-tree elscreen-frame-confs)) 409 | (original-window-histories (elscreen-get-all-window-history-alist))) 410 | (unwind-protect 411 | (save-window-excursion ,@body) 412 | (setq elscreen-frame-confs original-frame-confs) 413 | (elscreen-apply-window-configuration 414 | original-elscreen-window-configuration) 415 | (mapc 416 | (lambda (buffer) 417 | (when (buffer-live-p buffer) 418 | (bury-buffer buffer) 419 | (setq original-buffer-live-p t))) 420 | original-buffer-list) 421 | (when original-buffer-live-p 422 | (while (not (memq (car (buffer-list)) original-buffer-list)) 423 | (bury-buffer (car (buffer-list))))) 424 | (elscreen-restore-all-window-history-alist original-window-histories)))) 425 | 426 | (defsubst elscreen-get-frame-confs (frame) 427 | (assoc-default frame elscreen-frame-confs)) 428 | 429 | (defun elscreen-make-frame-confs (frame &optional keep-window-configuration) 430 | (when (null (elscreen-get-frame-confs frame)) 431 | (let ((selected-frame (selected-frame)) 432 | elscreen-window-configuration) 433 | (save-current-buffer 434 | (select-frame frame) 435 | (setq elscreen-window-configuration 436 | (if keep-window-configuration 437 | (elscreen-current-window-configuration) 438 | (elscreen-default-window-configuration))) 439 | (elscreen--set-alist 'elscreen-frame-confs frame 440 | (list 441 | (cons 'screen-property 442 | (list 443 | (cons 0 (list 444 | (cons 'window-configuration 445 | elscreen-window-configuration))))) 446 | (cons 'screen-history (list 0)) 447 | (cons 'modified-inquirer nil) 448 | (cons 'screen-to-name-alist-cache nil))) 449 | (elscreen-apply-window-configuration elscreen-window-configuration) 450 | (elscreen-notify-screen-modification 'force-immediately) 451 | (select-frame selected-frame))))) 452 | 453 | (defun elscreen-delete-frame-confs (frame) 454 | (elscreen--remove-alist 'elscreen-frame-confs frame)) 455 | 456 | (add-hook 'after-make-frame-functions 'elscreen-make-frame-confs) 457 | (add-hook 'delete-frame-functions 'elscreen-delete-frame-confs) 458 | 459 | (defsubst elscreen-get-conf-list (type) 460 | (assoc-default type (elscreen-get-frame-confs (selected-frame)))) 461 | 462 | (defsubst elscreen-set-conf-list (type conf-list) 463 | (let ((frame-conf (elscreen-get-frame-confs (selected-frame)))) 464 | (elscreen--set-alist 'frame-conf type conf-list))) 465 | 466 | (defun elscreen-get-screen-property (screen) 467 | (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) 468 | (assoc-default screen screen-property-list))) 469 | 470 | (defun elscreen-set-screen-property (screen property) 471 | (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) 472 | (elscreen--set-alist 'screen-property-list screen property) 473 | (elscreen-set-conf-list 'screen-property screen-property-list))) 474 | 475 | (defun elscreen-delete-screen-property (screen) 476 | (let ((screen-property-list (elscreen-get-conf-list 'screen-property))) 477 | (elscreen--remove-alist 'screen-property-list screen) 478 | (elscreen-set-conf-list 'screen-property screen-property-list))) 479 | 480 | (defun elscreen-get-number-of-screens () 481 | "Return total number of screens." 482 | (length (elscreen-get-conf-list 'screen-property))) 483 | 484 | (defun elscreen-one-screen-p () 485 | "Return t if there is only one screen." 486 | (= (elscreen-get-number-of-screens) 1)) 487 | 488 | (defun elscreen-get-screen-list () 489 | "Return a list of screen numbers." 490 | (mapcar 'car (elscreen-get-conf-list 'screen-property))) 491 | 492 | (defun elscreen-screen-live-p (screen) 493 | "Return t when SCREEN is alive." 494 | (not (null (elscreen-get-screen-property screen)))) 495 | 496 | (defun elscreen-get-window-configuration (screen) 497 | "Return pair of window-configuration and marker of SCREEN 498 | from `elscreen-frame-confs', a cons cell." 499 | (let ((screen-property (elscreen-get-screen-property screen))) 500 | (assoc-default 'window-configuration screen-property))) 501 | 502 | (defun elscreen-set-window-configuration (screen winconf) 503 | "Set pair of window-configuration and marker of SCREEN to WINCONF." 504 | (let ((screen-property (elscreen-get-screen-property screen))) 505 | (elscreen--set-alist 'screen-property 'window-configuration winconf) 506 | (elscreen-set-screen-property screen screen-property))) 507 | 508 | (defun elscreen-get-screen-nickname (screen) 509 | "Return nickname of SCREEN from `elscreen-frame-confs', a string." 510 | (let ((screen-property (elscreen-get-screen-property screen))) 511 | (assoc-default 'nickname screen-property))) 512 | 513 | (defun elscreen-set-screen-nickname (screen nickname) 514 | "Set nickname of SCREEN to NICKNAME." 515 | (let ((screen-property (elscreen-get-screen-property screen))) 516 | (elscreen--set-alist 'screen-property 'nickname nickname) 517 | (elscreen-set-screen-property screen screen-property))) 518 | 519 | (defun elscreen-delete-screen-nickname (screen) 520 | "Remove nickname of SCREEN from `elscreen-frame-confs'." 521 | (let ((screen-property (elscreen-get-screen-property screen))) 522 | (elscreen--remove-alist 'screen-property 'nickname) 523 | (elscreen-set-screen-property screen screen-property))) 524 | 525 | (defun elscreen-append-screen-to-history (screen) 526 | (let ((screen-history (elscreen-get-conf-list 'screen-history))) 527 | (setcdr (last screen-history) (list screen)))) 528 | 529 | (defun elscreen-delete-screen-from-history (screen) 530 | (let ((screen-history (elscreen-get-conf-list 'screen-history))) 531 | (setq screen-history (delq screen screen-history)) 532 | (elscreen-set-conf-list 'screen-history screen-history))) 533 | 534 | (defun elscreen-set-current-screen (screen) 535 | (let ((screen-history (elscreen-get-conf-list 'screen-history))) 536 | (setq screen-history (cons screen (delq screen screen-history))) 537 | (elscreen-set-conf-list 'screen-history screen-history))) 538 | 539 | (defun elscreen-get-current-screen () 540 | (car (elscreen-get-conf-list 'screen-history))) 541 | 542 | (defun elscreen-get-previous-screen () 543 | (cadr (elscreen-get-conf-list 'screen-history))) 544 | 545 | (defun elscreen-status-label (screen &optional default) 546 | (let ((default (or default " ")) 547 | (current-screen (elscreen-get-current-screen)) 548 | (previous-screen (elscreen-get-previous-screen))) 549 | (cond 550 | ((eq screen current-screen) "+") 551 | ((eq screen previous-screen) "-") 552 | (t default)))) 553 | 554 | (defvar elscreen-notify-screen-modification-suppress-flag nil) 555 | (defmacro elscreen-notify-screen-modification-suppress (&rest body) 556 | `(let ((elscreen-notify-screen-modification-suppress-flag t)) 557 | ,@body)) 558 | 559 | (defvar elscreen-screen-update-hook nil) 560 | (defun elscreen-run-screen-update-hook () 561 | (when elscreen-frame-confs 562 | (elscreen-notify-screen-modification-suppress 563 | (run-hooks 'elscreen-screen-update-hook))) 564 | (remove-hook 'post-command-hook 'elscreen-run-screen-update-hook)) 565 | 566 | (defun elscreen-screen-modified-p (inquirer) 567 | (let* ((inquirer-list (elscreen-get-conf-list 'modified-inquirer)) 568 | (modified (null (memq inquirer inquirer-list)))) 569 | (add-to-list 'inquirer-list inquirer) 570 | (elscreen-set-conf-list 'modified-inquirer inquirer-list) 571 | modified)) 572 | 573 | (defun elscreen-set-screen-modified () 574 | (elscreen-set-conf-list 'modified-inquirer nil) 575 | (add-hook 'post-command-hook 'elscreen-run-screen-update-hook)) 576 | 577 | (defvar elscreen-screen-modified-hook-pwc nil) 578 | (defun elscreen-notify-screen-modification (&optional mode) 579 | (when (and (not (window-minibuffer-p)) 580 | (not elscreen-notify-screen-modification-suppress-flag) 581 | (or (eq mode 'force) 582 | (eq mode 'force-immediately) 583 | (null elscreen-screen-modified-hook-pwc) 584 | (not (fboundp 'compare-window-configurations)) 585 | (not (compare-window-configurations 586 | (current-window-configuration) 587 | elscreen-screen-modified-hook-pwc)))) 588 | (setq elscreen-screen-modified-hook-pwc 589 | (current-window-configuration)) 590 | (elscreen-set-screen-modified) 591 | (when (eq mode 'force-immediately) 592 | (elscreen-run-screen-update-hook)))) 593 | 594 | (defmacro elscreen-screen-modified-hook-setup (&rest hooks-and-functions) 595 | (cons 596 | 'progn 597 | (mapcar 598 | (lambda (hook-or-function) 599 | (let ((mode ''normal)) 600 | (when (listp hook-or-function) 601 | (setq mode (nth 1 hook-or-function)) 602 | (setq hook-or-function (nth 0 hook-or-function))) 603 | (cond 604 | ((string-match "-\\(hooks?\\|functions\\)$" 605 | (symbol-name hook-or-function)) 606 | `(add-hook (quote ,hook-or-function) 607 | (lambda (&rest ignore) 608 | (elscreen-notify-screen-modification ,mode)))) 609 | (t ;; Assume hook-or-function is function 610 | `(defadvice ,hook-or-function (around 611 | elscreen-screen-modified-advice 612 | activate) 613 | ad-do-it 614 | (elscreen-notify-screen-modification ,mode)))))) 615 | hooks-and-functions))) 616 | 617 | (elscreen-screen-modified-hook-setup 618 | (recenter 'force) (change-major-mode-hook 'force) 619 | other-window 620 | window-configuration-change-hook window-size-change-functions 621 | (handle-switch-frame 'force) ;; GNU Emacs 21 622 | (delete-frame 'force) 623 | (Info-find-node-2 'force)) 624 | 625 | (defun elscreen-get-screen-to-name-alist-cache () 626 | (elscreen-get-conf-list 'screen-to-name-alist-cache)) 627 | 628 | (defun elscreen-set-screen-to-name-alist-cache (alist) 629 | (elscreen-set-conf-list 'screen-to-name-alist-cache alist)) 630 | 631 | (defvar elscreen-mode-to-nickname-alist-symbol-list nil) 632 | (defvar elscreen-mode-to-nickname-alist-internal nil) 633 | (defun elscreen-rebuild-mode-to-nickname-alist () 634 | (setq elscreen-mode-to-nickname-alist-internal 635 | (apply 'append 636 | (mapcar 'symbol-value 637 | elscreen-mode-to-nickname-alist-symbol-list))) 638 | (elscreen-notify-screen-modification 'force-immediately)) 639 | (defun elscreen-set-mode-to-nickname-alist (mode-to-nickname-alist-symbol) 640 | (add-to-list 'elscreen-mode-to-nickname-alist-symbol-list 641 | mode-to-nickname-alist-symbol) 642 | (elscreen-rebuild-mode-to-nickname-alist)) 643 | (elscreen-set-mode-to-nickname-alist 'elscreen-mode-to-nickname-alist) 644 | 645 | (defvar elscreen-buffer-to-nickname-alist-symbol-list nil) 646 | (defvar elscreen-buffer-to-nickname-alist-internal nil) 647 | (defun elscreen-rebuild-buffer-to-nickname-alist () 648 | (setq elscreen-buffer-to-nickname-alist-internal 649 | (apply 'append 650 | (mapcar 'symbol-value 651 | elscreen-buffer-to-nickname-alist-symbol-list))) 652 | (elscreen-notify-screen-modification 'force-immediately)) 653 | (defun elscreen-set-buffer-to-nickname-alist (buffer-to-nickname-alist-symbol) 654 | (add-to-list 'elscreen-buffer-to-nickname-alist-symbol-list 655 | buffer-to-nickname-alist-symbol) 656 | (elscreen-rebuild-buffer-to-nickname-alist)) 657 | (elscreen-set-buffer-to-nickname-alist 'elscreen-buffer-to-nickname-alist) 658 | 659 | (defsubst elscreen-get-alist-to-nickname (alist op mode-or-buffer-name) 660 | (catch 'found 661 | (progn 662 | (mapc 663 | (lambda (map) 664 | (let ((nickname nil) 665 | (condition-data (car map)) 666 | (string-or-function (cdr map))) 667 | (when (funcall op condition-data mode-or-buffer-name) 668 | (cond 669 | ((functionp string-or-function) 670 | (setq nickname 671 | (condition-case nil 672 | (funcall string-or-function) 673 | (wrong-number-of-arguments 674 | (funcall string-or-function (current-buffer)))))) 675 | (t 676 | (setq nickname string-or-function))) 677 | (throw 'found (cons 'nickname nickname))))) 678 | alist) 679 | nil))) 680 | 681 | (defun elscreen-get-screen-to-name-alist (&optional truncate-length padding) 682 | (when (elscreen-screen-modified-p 'elscreen-get-screen-to-name-alist) 683 | (elscreen-notify-screen-modification-suppress 684 | (elscreen-set-window-configuration (elscreen-get-current-screen) 685 | (elscreen-current-window-configuration)) 686 | (let* ((screen-list (sort (elscreen-get-screen-list) '<)) 687 | screen-name screen-to-name-alist nickname-type-map) 688 | (elscreen-save-screen-excursion 689 | (mapc 690 | (lambda (screen) 691 | ;; If nickname exists, use it. 692 | (setq screen-name (elscreen-get-screen-nickname screen)) 693 | ;; Nickname does not exist, so examine major-mode and buffer-name. 694 | (when (null screen-name) 695 | (elscreen-goto-internal screen) 696 | 697 | (setq nickname-type-map 698 | (mapcar 699 | (lambda (window) 700 | (with-current-buffer (window-buffer window) 701 | (or (elscreen-get-alist-to-nickname 702 | elscreen-mode-to-nickname-alist-internal 703 | 'string-match (symbol-name major-mode)) 704 | (elscreen-get-alist-to-nickname 705 | elscreen-buffer-to-nickname-alist-internal 706 | 'string-match (buffer-name)) 707 | (cons 'buffer-name (buffer-name))))) 708 | (window-list))) 709 | 710 | (let (nickname-list) 711 | (while (> (length nickname-type-map) 0) 712 | (let ((type (caar nickname-type-map)) 713 | (name (cdar nickname-type-map))) 714 | (when name 715 | (setq nickname-list (cons name nickname-list))) 716 | (setq nickname-type-map 717 | (if (eq type 'nickname) 718 | (delete (car nickname-type-map) nickname-type-map) 719 | (cdr nickname-type-map))))) 720 | (setq screen-name 721 | (mapconcat 'identity (reverse nickname-list) ":")))) 722 | 723 | (elscreen--set-alist 'screen-to-name-alist screen screen-name)) 724 | screen-list)) 725 | 726 | (elscreen-set-screen-to-name-alist-cache screen-to-name-alist)))) 727 | 728 | ;; Arguments of truncate-length and padding are deprecated. 729 | (if truncate-length 730 | (let ((screen-to-name-alist 731 | (copy-alist (elscreen-get-screen-to-name-alist-cache)))) 732 | (elscreen-message "Arguments for `elscreen-get-screen-to-name-alist' are deprecated. Use elscreen-truncate-screen-name for each screen-name.") 733 | (mapc 734 | (lambda (screen-to-name) 735 | (setcdr screen-to-name 736 | (elscreen-truncate-screen-name (cdr screen-to-name) 737 | truncate-length padding))) 738 | screen-to-name-alist) 739 | screen-to-name-alist) 740 | (elscreen-get-screen-to-name-alist-cache))) 741 | 742 | (defun elscreen-truncate-screen-name (screen-name truncate-length &optional padding) 743 | (let ((truncate-length (max truncate-length 4))) 744 | (cond 745 | ((> (string-width screen-name) truncate-length) 746 | (concat (truncate-string-to-width screen-name (- truncate-length 3) 747 | nil ?.) 748 | "...")) 749 | (padding 750 | (truncate-string-to-width screen-name truncate-length nil ?\ )) 751 | (t 752 | screen-name)))) 753 | 754 | (defun elscreen-goto-internal (screen) 755 | "Set the configuration of windows, buffers and markers previousuly 756 | stored as SCREEN." 757 | (let ((elscreen-window-configuration 758 | (elscreen-get-window-configuration screen))) 759 | (elscreen-apply-window-configuration elscreen-window-configuration))) 760 | 761 | (defvar elscreen-create-hook nil) 762 | (defun elscreen-create-internal (&optional noerror) 763 | "Create a new screen. 764 | If NOERROR is not nil, no message is displayed in mini buffer 765 | when error is occurred." 766 | (cond 767 | ((>= (elscreen-get-number-of-screens) 10) 768 | (unless noerror 769 | (elscreen-message "No more screens.")) 770 | nil) 771 | (t 772 | (let ((screen-list (sort (elscreen-get-screen-list) '<)) 773 | (screen 0)) 774 | (elscreen-set-window-configuration 775 | (elscreen-get-current-screen) 776 | (elscreen-current-window-configuration)) 777 | (while (eq (nth screen screen-list) screen) 778 | (setq screen (+ screen 1))) 779 | (elscreen-set-window-configuration 780 | screen (elscreen-default-window-configuration)) 781 | (elscreen-append-screen-to-history screen) 782 | (elscreen-notify-screen-modification 'force) 783 | (run-hooks 'elscreen-create-hook) 784 | screen)))) 785 | 786 | (defun elscreen-kill-internal (screen) 787 | (elscreen-delete-screen-property screen) 788 | (elscreen-delete-screen-from-history screen) 789 | screen) 790 | 791 | (defun elscreen-find-screens (condition) 792 | (let ((screen-list (sort (elscreen-get-screen-list) '<)) 793 | result) 794 | (save-current-buffer 795 | (elscreen-set-window-configuration 796 | (elscreen-get-current-screen) 797 | (elscreen-current-window-configuration)) 798 | (elscreen-notify-screen-modification-suppress 799 | (elscreen-save-screen-excursion 800 | (mapc 801 | (lambda (screen) 802 | (when (funcall condition screen) 803 | (setq result (cons screen result)))) 804 | screen-list)) 805 | result)))) 806 | 807 | (defun elscreen-find-screen (condition) 808 | (catch 'elscreen-find-screen 809 | (elscreen-find-screens `(lambda (screen) 810 | (when (funcall ,condition screen) 811 | (throw 'elscreen-find-screen screen)))))) 812 | 813 | (defun elscreen-find-screen-by-buffer (buffer &optional create) 814 | (let* ((buffer (if (bufferp buffer) buffer (get-buffer buffer))) 815 | (screen (when buffer 816 | (elscreen-find-screen 817 | `(lambda (screen) 818 | (elscreen-goto-internal screen) 819 | (not (null (get-buffer-window ,buffer)))))))) 820 | (when (and buffer (null screen) create) 821 | (cond 822 | ((setq screen (elscreen-create-internal 'noerror)) 823 | (save-window-excursion 824 | (elscreen-goto-internal screen) 825 | (switch-to-buffer buffer t) 826 | (elscreen-set-window-configuration 827 | screen (elscreen-current-window-configuration)))) 828 | (t 829 | (setq screen (elscreen-get-current-screen)) 830 | (elscreen-goto-internal screen) 831 | (save-selected-window 832 | (select-window (split-window)) 833 | (switch-to-buffer buffer t))))) 834 | screen)) 835 | 836 | (defun elscreen-find-screen-by-major-mode (major-mode-or-re) 837 | (let ((major-mode-re (cond 838 | ((stringp major-mode-or-re) 839 | major-mode-or-re) 840 | ((symbolp major-mode-or-re) 841 | (format "^%s$" (regexp-quote 842 | (symbol-name major-mode-or-re)))) 843 | (t nil)))) 844 | (when major-mode-re 845 | (elscreen-find-screen 846 | (lambda (screen) 847 | (elscreen-goto-internal screen) 848 | (save-selected-window 849 | (catch 'found 850 | (mapc 851 | (lambda (window) 852 | (select-window window) 853 | (when (string-match major-mode-re (symbol-name major-mode)) 854 | (throw 'found t))) 855 | (window-list)) 856 | nil))))))) 857 | 858 | (defvar elscreen-last-message "Welcome to ElScreen!" 859 | "Last shown message.") 860 | (defun elscreen-message (message &optional sec) 861 | "Display MESSAGE in mini-buffer for SEC seconds. 862 | Default value for SEC is 3." 863 | (when message 864 | (setq elscreen-last-message message) 865 | (message "%s" message) 866 | (sit-for (or sec 3))) 867 | (message nil)) 868 | 869 | 870 | ;;; User Interfaces: 871 | 872 | (defun elscreen-create () 873 | "Create a new screen and switch to it." 874 | (interactive) 875 | (let ((screen (elscreen-create-internal))) 876 | (if screen 877 | (elscreen-goto screen)))) 878 | 879 | (defun elscreen-clone (&optional screen) 880 | "Create a new screen with the window-configuration of SCREEN. 881 | If SCREEN is ommitted, current-screen is used." 882 | (interactive) 883 | (let ((screen (or screen (elscreen-get-current-screen))) 884 | clone elscreen-window-configuration) 885 | (cond 886 | ((not (elscreen-screen-live-p screen)) 887 | (elscreen-message "There is no such screen, cannot clone")) 888 | ((setq clone (elscreen-create-internal)) 889 | (save-window-excursion 890 | (elscreen-goto-internal screen) 891 | (setq elscreen-window-configuration 892 | (elscreen-current-window-configuration))) 893 | (elscreen-set-window-configuration clone elscreen-window-configuration) 894 | (elscreen-goto clone))))) 895 | 896 | (defvar elscreen-kill-hook nil) 897 | (defun elscreen-kill (&optional screen) 898 | "Kill SCREEN. If optional argument SCREEN is 899 | ommitted, current-screen is killed." 900 | (interactive "P") 901 | (let ((screen (or (and (numberp screen) screen) 902 | (elscreen-get-current-screen)))) 903 | (cond 904 | ((not (elscreen-screen-live-p screen)) 905 | (elscreen-message "There is no such screen, cannot kill") 906 | nil) 907 | ((elscreen-one-screen-p) 908 | (elscreen-message "There is only one screen, cannot kill") 909 | nil) 910 | (t 911 | (elscreen-kill-internal screen) 912 | (elscreen-goto-internal (elscreen-get-current-screen)) 913 | (elscreen-notify-screen-modification 'force) 914 | (run-hooks 'elscreen-kill-hook) 915 | screen)))) 916 | 917 | (defun elscreen-kill-screen-and-buffers (&optional screen) 918 | "Kill buffers on SCREEN and SCREEN itself. If optional 919 | argument SCREEN is omitted, current screen is killed." 920 | (interactive) 921 | (let* ((screen (or screen (elscreen-get-current-screen))) 922 | (elscreen-window-configuration 923 | (elscreen-get-window-configuration screen))) 924 | (when (elscreen-kill screen) 925 | (save-window-excursion 926 | (elscreen-apply-window-configuration elscreen-window-configuration) 927 | (mapc 928 | (lambda (buffer) 929 | (when (buffer-live-p buffer) 930 | (kill-buffer buffer))) 931 | (mapcar 'window-buffer (window-list)))) 932 | screen))) 933 | 934 | (defun elscreen-kill-others (&optional screen) 935 | "Kill screens other than SCREEN. If optional argument SCREEN 936 | is ommitted, current screen will survive." 937 | (interactive) 938 | (let* ((screen (or screen (elscreen-get-current-screen))) 939 | (screen-list (when (elscreen-screen-live-p screen) 940 | (delq screen (sort (elscreen-get-screen-list) '<)))) 941 | screen-list-string) 942 | (cond 943 | ((not (elscreen-screen-live-p screen)) ;; XXX 944 | (when (called-interactively-p 'any) 945 | (elscreen-message "There is no such screen"))) 946 | ((null screen-list) 947 | (when (called-interactively-p 'any) 948 | (elscreen-message "There is only one screen, cannot kill"))) 949 | ((or 950 | (not (called-interactively-p 'any)) 951 | (yes-or-no-p (format "Really kill screens other than %d? " screen))) 952 | (setq screen-list-string (mapconcat 953 | (lambda (screen) 954 | (elscreen-kill-internal screen) 955 | (number-to-string screen)) 956 | screen-list ",")) 957 | (elscreen-goto-internal screen) 958 | (elscreen-notify-screen-modification 'force-immediately) 959 | (when (called-interactively-p 'any) 960 | (elscreen-message (format "screen %s killed" screen-list-string))))) 961 | screen-list)) 962 | 963 | (defvar elscreen-goto-hook nil) 964 | (defun elscreen-goto (screen) 965 | "Switch to screen SCREEN." 966 | (interactive "NGoto screen number: ") 967 | (cond 968 | ((eq (elscreen-get-current-screen) screen)) 969 | ((elscreen-screen-live-p screen) 970 | (elscreen-set-window-configuration 971 | (elscreen-get-current-screen) 972 | (elscreen-current-window-configuration)) 973 | (elscreen-set-current-screen screen) 974 | (elscreen-goto-internal screen) 975 | (elscreen-notify-screen-modification 'force) 976 | (run-hooks 'elscreen-goto-hook) 977 | screen) 978 | (t 979 | (elscreen-message (format "No screen %d" screen)) 980 | nil))) 981 | 982 | (defun elscreen-next () 983 | "Switch to the next screen." 984 | (interactive) 985 | (cond 986 | ((elscreen-one-screen-p) 987 | (elscreen-message 988 | (format "You cannot escape from screen %d!" 989 | (elscreen-get-current-screen)))) 990 | (t 991 | (let* ((screen-list (sort (elscreen-get-screen-list) '<)) 992 | (next-screen 993 | (or (nth 1 (memq (elscreen-get-current-screen) screen-list)) 994 | (car screen-list)))) 995 | (elscreen-goto next-screen))))) 996 | 997 | (defun elscreen-previous () 998 | "Switch to the previous screen." 999 | (interactive) 1000 | (cond 1001 | ((elscreen-one-screen-p) 1002 | (elscreen-message 1003 | (format "You cannot escape from screen %d!" 1004 | (elscreen-get-current-screen)))) 1005 | (t 1006 | (let* ((screen-list (sort (elscreen-get-screen-list) '>)) 1007 | (previous-screen 1008 | (or (nth 1 (memq (elscreen-get-current-screen) screen-list)) 1009 | (car screen-list)))) 1010 | (elscreen-goto previous-screen))))) 1011 | 1012 | (defun elscreen-toggle () 1013 | "Toggle to the screen selected previously." 1014 | (interactive) 1015 | (cond 1016 | ((elscreen-one-screen-p) 1017 | (elscreen-message 1018 | (format "You cannot escape from screen %d!" 1019 | (elscreen-get-current-screen)))) 1020 | (t 1021 | (elscreen-goto (elscreen-get-previous-screen))))) 1022 | 1023 | (defun elscreen-jump () 1024 | "Switch to specified screen." 1025 | (interactive) 1026 | (let ((next-screen (string-to-number (string last-command-event)))) 1027 | (if (and (<= 0 next-screen) (<= next-screen 9)) 1028 | (elscreen-goto next-screen)))) 1029 | (defalias 'elscreen-jump-0 'elscreen-jump) 1030 | (defalias 'elscreen-jump-9 'elscreen-jump) 1031 | 1032 | (defun elscreen-swap () 1033 | "Interchange screens selected currently and previously." 1034 | (interactive) 1035 | (cond 1036 | ((elscreen-one-screen-p) 1037 | (elscreen-message "There is only one screen, cannot swap")) 1038 | (t 1039 | (let* ((current-screen (elscreen-get-current-screen)) 1040 | (previous-screen (elscreen-get-previous-screen)) 1041 | (current-screen-property 1042 | (elscreen-get-screen-property current-screen)) 1043 | (previous-screen-property 1044 | (elscreen-get-screen-property previous-screen))) 1045 | (elscreen-set-screen-property current-screen previous-screen-property) 1046 | (elscreen-set-screen-property previous-screen current-screen-property) 1047 | (elscreen-goto-internal (elscreen-get-current-screen)))))) 1048 | 1049 | (defun elscreen-screen-nickname (nickname) 1050 | "Set nickname for current screen to NICKNAME." 1051 | (interactive "sSet window title to: ") 1052 | (cond 1053 | ((zerop (length nickname)) 1054 | (elscreen-delete-screen-nickname (elscreen-get-current-screen))) 1055 | (t 1056 | (elscreen-set-screen-nickname (elscreen-get-current-screen) nickname))) 1057 | (elscreen-notify-screen-modification 'force)) 1058 | 1059 | (defun elscreen-display-screen-name-list () 1060 | "Display the list of screens in mini-buffer." 1061 | (interactive) 1062 | (let ((screen-list (sort (elscreen-get-screen-list) '<)) 1063 | (screen-to-name-alist (elscreen-get-screen-to-name-alist))) 1064 | (elscreen-message 1065 | (mapconcat 1066 | (lambda (screen) 1067 | (let ((screen-name (assoc-default screen screen-to-name-alist))) 1068 | (format "%d%s %s" screen 1069 | (elscreen-status-label screen "") 1070 | screen-name))) 1071 | screen-list " ")))) 1072 | 1073 | 1074 | ;;; Help 1075 | 1076 | (defvar elscreen-help-symbol-list nil) 1077 | (defun elscreen-set-help (help-symbol) 1078 | (add-to-list 'elscreen-help-symbol-list help-symbol t)) 1079 | (elscreen-set-help 'elscreen-help) 1080 | 1081 | (defun elscreen-help () 1082 | "Show key bindings of ElScreen and Add-On softwares." 1083 | (interactive) 1084 | (with-output-to-temp-buffer "*ElScreen Help*" 1085 | (princ (substitute-command-keys 1086 | (mapconcat 'symbol-value 1087 | elscreen-help-symbol-list "\n\n"))) 1088 | (help-print-return-message))) 1089 | 1090 | 1091 | ;;; Utility Functions 1092 | 1093 | (defun elscreen-display-version () 1094 | "Display ElScreen version." 1095 | (interactive) 1096 | (elscreen-message (concat "ElScreen version " elscreen-version))) 1097 | 1098 | (defun elscreen-toggle-display-screen-number () 1099 | "Toggle the screen number in the mode line." 1100 | (interactive) 1101 | (setq elscreen-display-screen-number (null elscreen-display-screen-number)) 1102 | (elscreen-notify-screen-modification 'force)) 1103 | 1104 | (defun elscreen-toggle-display-tab () 1105 | "Toggle the tab on the top of screen." 1106 | (interactive) 1107 | (setq elscreen-display-tab (null elscreen-display-tab)) 1108 | (elscreen-notify-screen-modification 'force)) 1109 | 1110 | (defun elscreen-display-last-message () 1111 | "Repeat the last message displayed in the mini-buffer." 1112 | (interactive) 1113 | (elscreen-message elscreen-last-message 5)) 1114 | 1115 | (defun elscreen-display-time () 1116 | "Show system information." 1117 | (interactive) 1118 | (elscreen-message 1119 | (format "%s %s / %s" 1120 | (current-time-string) 1121 | (nth 1 (current-time-zone)) 1122 | (mapconcat 1123 | (lambda (load) 1124 | (format "%.2f" (/ load 100.0))) 1125 | (load-average) " ")))) 1126 | 1127 | (defun elscreen-select-and-goto () 1128 | (interactive) 1129 | (let* ((screen-list (sort (elscreen-get-screen-list) '<)) 1130 | (screen-to-name-alist (elscreen-get-screen-to-name-alist)) 1131 | (command-list '(("c" . elscreen-create) 1132 | ("n" . elscreen-next) 1133 | ("p" . elscreen-previous) 1134 | ("t" . elscreen-toggle))) 1135 | (truncate-length (- (frame-width) 6)) 1136 | (candidate-window-height (max (+ (elscreen-get-number-of-screens) 4) 1137 | window-min-height)) 1138 | (candidate-buffer (get-buffer-create 1139 | (format " *ElScreen-select:%s*" 1140 | (prin1-to-string (selected-frame))))) 1141 | (candidate (concat 1142 | "Current screen list: \n\n" 1143 | (mapconcat 1144 | (lambda (screen) 1145 | (format " %d%s %s\n" screen 1146 | (elscreen-status-label screen) 1147 | (elscreen-truncate-screen-name 1148 | (assoc-default screen screen-to-name-alist) 1149 | truncate-length))) 1150 | screen-list nil))) 1151 | (prompt "Select screen or (c)reate, (n)ext, (p)revious, (t)oggle: ") 1152 | (minibuffer-map (copy-keymap minibuffer-local-map)) 1153 | window frame-last-window command-or-target-screen mini-hist) 1154 | ;; prepare window to show candidates 1155 | (save-window-excursion 1156 | (setq frame-last-window (previous-window (frame-first-window))) 1157 | (while (minibuffer-window-active-p frame-last-window) 1158 | (setq frame-last-window (previous-window frame-last-window))) 1159 | (while (and (not (one-window-p)) 1160 | (or (< (window-width frame-last-window) 1161 | (frame-width)) 1162 | (< (window-height frame-last-window) 1163 | (+ candidate-window-height window-min-height)))) 1164 | (setq window frame-last-window) 1165 | (setq frame-last-window (previous-window window)) 1166 | (delete-window window)) 1167 | (select-window (split-window frame-last-window)) 1168 | (shrink-window (- (window-height) candidate-window-height)) 1169 | ;; now switch to the buffer for candidates and fill it 1170 | (switch-to-buffer candidate-buffer) 1171 | (let ((buffer-read-only nil)) 1172 | (erase-buffer) 1173 | (insert candidate) 1174 | (goto-char (point-min)) 1175 | (save-excursion 1176 | (while (not (eobp)) 1177 | (when (looking-at "^ \\([0-9]\\)\\(.\\) \\(.*\\)$") 1178 | (put-text-property 1179 | (match-beginning 1) (match-end 1) 'face 'bold) 1180 | (cond 1181 | ((string= (match-string 2) "+") 1182 | (put-text-property 1183 | (match-beginning 3) (match-end 3) 'face 'bold)))) 1184 | (forward-line 1))) 1185 | (setq buffer-read-only t) 1186 | (set-buffer-modified-p nil)) 1187 | ;; make keymap for minibuffer 1188 | (suppress-keymap minibuffer-map t) 1189 | (define-key minibuffer-map "\C-g" 'abort-recursive-edit) 1190 | (define-key minibuffer-map "\C-m" 'exit-recursive-edit) 1191 | (define-key minibuffer-map "q" 'exit-recursive-edit) 1192 | (define-key minibuffer-map " " 'exit-recursive-edit) 1193 | (mapc 1194 | (lambda (command) 1195 | (define-key minibuffer-map (car command) 'self-insert-and-exit)) 1196 | command-list) 1197 | (mapc 1198 | (lambda (screen) 1199 | (define-key minibuffer-map (number-to-string screen) 1200 | 'self-insert-and-exit)) 1201 | screen-list) 1202 | ;; read key from minibuffer 1203 | (unwind-protect 1204 | (setq command-or-target-screen 1205 | (read-from-minibuffer prompt nil minibuffer-map 1206 | nil 'mini-hist)) 1207 | (kill-buffer candidate-buffer))) 1208 | (cond 1209 | ((string= command-or-target-screen "")) 1210 | ((assoc-default command-or-target-screen command-list) 1211 | (funcall (assoc-default command-or-target-screen command-list))) 1212 | (t 1213 | (elscreen-goto (string-to-number command-or-target-screen)))))) 1214 | 1215 | (defun elscreen-find-and-goto-by-buffer (&optional buffer create noselect) 1216 | "Go to the screen that has the window with buffer BUFFER, 1217 | creating one if none already exists." 1218 | (interactive) 1219 | (let* ((prompt "Go to the screen with specified buffer: ") 1220 | (create (or create (called-interactively-p 'any))) 1221 | (buffer-name (or (and (bufferp buffer) (buffer-name buffer)) 1222 | (and (stringp buffer) buffer) 1223 | (and (featurep 'iswitchb) 1224 | (iswitchb-read-buffer prompt)) 1225 | (read-buffer prompt))) 1226 | (target-screen (elscreen-find-screen-by-buffer 1227 | (get-buffer-create buffer-name) create))) 1228 | (when target-screen 1229 | (elscreen-goto target-screen) 1230 | (unless noselect 1231 | (select-window (get-buffer-window buffer-name)))) 1232 | target-screen)) 1233 | 1234 | (defun elscreen-find-file (filename) 1235 | "Edit file FILENAME. 1236 | Switch to a screen visiting file FILENAME, 1237 | creating one if none already exists." 1238 | (interactive "FFind file in new screen: ") 1239 | (elscreen-find-and-goto-by-buffer (find-file-noselect filename) 'create)) 1240 | 1241 | (defun elscreen-find-file-read-only (filename) 1242 | "Edit file FILENAME with new screen but don't allow changes. 1243 | Like \\[elscreen-find-file] but marks buffer as read-only. 1244 | Use \\[toggle-read-only] to permit editing." 1245 | (interactive "FFind file read-only in new screen: ") 1246 | (elscreen-find-file filename) 1247 | (setq buffer-read-only t)) 1248 | 1249 | (defun elscreen-dired (dirname &optional switches) 1250 | (interactive (progn 1251 | (or (featurep 'dired) (require 'dired)) 1252 | (dired-read-dir-and-switches "in new screen "))) 1253 | (elscreen-find-and-goto-by-buffer (dired-noselect dirname switches) 'create)) 1254 | 1255 | (defun elscreen-execute-extended-command (prefix-arg) 1256 | (interactive "P") 1257 | (let ((prefix-arg prefix-arg) 1258 | (prefix-key (key-description elscreen-prefix-key)) 1259 | target-screen) 1260 | (setq this-command (intern (completing-read 1261 | ;; Note: this has the hard-wired 1262 | ;; "C-u" and "M-x" string bug in common 1263 | ;; with all Emacs's. 1264 | ;; (i.e. it prints C-u and M-x regardless of 1265 | ;; whether some other keys were actually bound 1266 | ;; to `execute-extended-command' and 1267 | ;; `universal-argument'. 1268 | (cond ((eq prefix-arg '-) 1269 | (format "- %s M-x " prefix-key)) 1270 | ((equal prefix-arg '(4)) 1271 | (format "C-u %s M-x " prefix-key)) 1272 | ((integerp prefix-arg) 1273 | (format "%d %s M-x " 1274 | prefix-arg prefix-key)) 1275 | ((and (consp prefix-arg) 1276 | (integerp (car prefix-arg))) 1277 | (format "%d %s M-x " 1278 | (car prefix-arg) prefix-key)) 1279 | (t 1280 | (format "%s M-x " prefix-key))) 1281 | obarray 'commandp t nil 1282 | 'extended-command-history))) 1283 | (if (setq target-screen (elscreen-create-internal 'noerror)) 1284 | (elscreen-goto target-screen) 1285 | (select-window (split-window))) 1286 | (command-execute this-command t))) 1287 | 1288 | 1289 | ;;; Mode Line & Menu & Tab 1290 | 1291 | ;; GNU Emacs 1292 | (defvar elscreen-mode-line-string "[0]") 1293 | (defun elscreen-mode-line-update () 1294 | (when (elscreen-screen-modified-p 'elscreen-mode-line-update) 1295 | (setq elscreen-mode-line-string 1296 | (format "[%d]" (elscreen-get-current-screen))) 1297 | (force-mode-line-update))) 1298 | 1299 | (let ((point (memq 'mode-line-position mode-line-format)) 1300 | (elscreen-mode-line-elm '(elscreen-display-screen-number 1301 | (" " elscreen-mode-line-string)))) 1302 | (when (and (null (member elscreen-mode-line-elm mode-line-format)) point) 1303 | (setcdr point (cons elscreen-mode-line-elm (cdr point))))) 1304 | 1305 | (add-hook 'elscreen-screen-update-hook 'elscreen-mode-line-update) 1306 | 1307 | ;; Menu 1308 | 1309 | (define-key-after (lookup-key global-map [menu-bar]) [elscreen] 1310 | (cons "ElScreen" (make-sparse-keymap "ElScreen")) 'buffer) 1311 | 1312 | (defvar elscreen-menu-bar-command-entries 1313 | (list (list 'elscreen-command-separator 1314 | 'menu-item 1315 | "--") 1316 | (list 'elscreen-create 1317 | 'menu-item 1318 | "Create Screen" 1319 | 'elscreen-create 1320 | :help "Create a new screen and switch to it") 1321 | (list 'elscreen-clone 1322 | 'menu-item 1323 | "Clone Screen" 1324 | 'elscreen-clone 1325 | :help "Create a new screen with the window-configuration of current screen") 1326 | (list 'elscreen-kill 1327 | 'menu-item 1328 | "Kill Screen" 1329 | 'elscreen-kill 1330 | :help "Kill current screen") 1331 | (list 'elscreen-kill-screen-and-buffers 1332 | 'menu-item 1333 | "Kill Screen and Buffers" 1334 | 'elscreen-kill-screen-and-buffers 1335 | :help "Kill current screen and buffers") 1336 | (list 'elscreen-kill-others 1337 | 'menu-item 1338 | "Kill Other Screens" 1339 | 'elscreen-kill-others 1340 | :help "Kill other screens") 1341 | (list 'elscreen-next 1342 | 'menu-item 1343 | "Next Screen" 1344 | 'elscreen-next 1345 | :help "Switch to the \"next\" screen in a cyclic order") 1346 | (list 'elscreen-previous 1347 | 'menu-item 1348 | "Previous Screen" 1349 | 'elscreen-previous 1350 | :help "Switch to the \"previous\" screen in a cyclic order") 1351 | (list 'elscreen-toggle 1352 | 'menu-item 1353 | "Toggle Screen" 1354 | 'elscreen-toggle 1355 | :help "Toggle to the screen selected previously") 1356 | (list 'elscreen-command-separator 1357 | 'menu-item 1358 | "--") 1359 | (list 'elscreen-toggle-display-screen-number 1360 | 'menu-item 1361 | "Display Screen Number" 1362 | 'elscreen-toggle-display-screen-number 1363 | :help "Display screen number on the mode line" 1364 | :button '(:toggle . elscreen-display-screen-number)) 1365 | (list 'elscreen-toggle-display-tab 1366 | 'menu-item 1367 | "Display Tab" 1368 | 'elscreen-toggle-display-tab 1369 | :help "Display tab on the top of screen" 1370 | :button '(:toggle . elscreen-display-tab)))) 1371 | 1372 | (defun elscreen-menu-bar-update (&optional force) 1373 | (when (and (lookup-key (current-global-map) [menu-bar elscreen]) 1374 | (or force 1375 | (elscreen-screen-modified-p 'elscreen-menu-bar-update))) 1376 | (let ((screen-list (sort (elscreen-get-screen-list) '<)) 1377 | (screen-to-name-alist (elscreen-get-screen-to-name-alist)) 1378 | (elscreen-menu nil)) 1379 | (setq elscreen-menu 1380 | (mapcar 1381 | (lambda (screen) 1382 | (list (string-to-char (number-to-string screen)) 1383 | 'menu-item 1384 | (format "%d%s %s" screen 1385 | (elscreen-status-label screen) 1386 | (elscreen-truncate-screen-name 1387 | (assoc-default screen screen-to-name-alist) 25)) 1388 | 'elscreen-jump 1389 | :keys (format "%s %d" 1390 | (key-description elscreen-prefix-key) 1391 | screen))) 1392 | screen-list)) 1393 | (setq elscreen-menu 1394 | (nconc elscreen-menu elscreen-menu-bar-command-entries)) 1395 | (setq elscreen-menu 1396 | (cons 'keymap (cons "Select Screen" elscreen-menu))) 1397 | (define-key (current-global-map) [menu-bar elscreen] 1398 | (cons (copy-sequence "ElScreen") elscreen-menu))))) 1399 | 1400 | (add-hook 'elscreen-screen-update-hook 'elscreen-menu-bar-update) 1401 | 1402 | ;; Tab 1403 | 1404 | (defvar elscreen-tab-format nil) 1405 | (make-variable-buffer-local 'elscreen-tab-format) 1406 | 1407 | (defsubst elscreen-tab-create-keymap (&rest definitions) 1408 | (let ((keymap (make-sparse-keymap)) 1409 | (key-function-pairs 1410 | (eval-when-compile 1411 | (mapcar 1412 | (lambda (key) 1413 | (cons key 'ignore)) 1414 | (list 'mouse-1 'mouse-2 'mouse-3 1415 | 'down-mouse-1 'down-mouse-2 'down-mouse-3 1416 | 'drag-mouse-1 'drag-mouse-2 'drag-mouse-3))))) 1417 | (while definitions 1418 | (elscreen--set-alist 'key-function-pairs (car definitions) (cadr definitions)) 1419 | (setq definitions (cddr definitions))) 1420 | (mapc 1421 | (lambda (key-function-pair) 1422 | (let ((key (car key-function-pair)) 1423 | (function (cdr key-function-pair))) 1424 | (define-key keymap (vector 'header-line key) function))) 1425 | key-function-pairs) 1426 | keymap)) 1427 | 1428 | (defsubst elscreen-tab-width () 1429 | (if (numberp elscreen-display-tab) 1430 | elscreen-display-tab 1431 | (let* ((number-of-screens (elscreen-get-number-of-screens)) 1432 | (available-width 1433 | (- (frame-width) (if elscreen-tab-display-control 4 0))) 1434 | (tab-width 1435 | (round (- (/ available-width number-of-screens) 1436 | (if elscreen-tab-display-kill-screen 5.5 1.5))))) 1437 | (max (min tab-width 16) 1)))) 1438 | 1439 | (defun elscreen-tab-escape-% (string) 1440 | (if (string-match "%" string) 1441 | (let ((retval "") 1442 | start (end 0) substring) 1443 | (while (setq start end) 1444 | (setq end (next-property-change start string)) 1445 | (setq substring (replace-regexp-in-string 1446 | "%" "%%" (substring string start end))) 1447 | (set-text-properties 0 (length substring) 1448 | (text-properties-at start string) substring) 1449 | (setq retval (concat retval substring))) 1450 | retval) 1451 | string)) 1452 | 1453 | (defun elscreen-tab-update (&optional force) 1454 | (when (and (not (window-minibuffer-p)) 1455 | (or (elscreen-screen-modified-p 'elscreen-tab-update) force)) 1456 | (walk-windows 1457 | (lambda (window) 1458 | (with-current-buffer (window-buffer window) 1459 | (when (and (boundp 'elscreen-tab-format) 1460 | (equal header-line-format elscreen-tab-format) 1461 | (or (not (eq (window-buffer window) 1462 | (window-buffer (frame-first-window)))) 1463 | (not elscreen-display-tab))) 1464 | (kill-local-variable 'elscreen-tab-format) 1465 | (setq header-line-format nil)))) 1466 | 'other 'other) 1467 | 1468 | (when elscreen-display-tab 1469 | (let ((screen-list (sort (elscreen-get-screen-list) '<)) 1470 | (screen-to-name-alist (elscreen-get-screen-to-name-alist)) 1471 | (current-screen (elscreen-get-current-screen)) 1472 | (half-space (propertize 1473 | " " 1474 | 'display '(space :width 0.5))) 1475 | (tab-separator (propertize 1476 | " " 1477 | 'face 'elscreen-tab-background-face 1478 | 'display '(space :width 0.5))) 1479 | (control-tab (propertize 1480 | "<->" 1481 | 'face 'elscreen-tab-control-face 1482 | 'local-map (elscreen-tab-create-keymap 1483 | 'mouse-1 'elscreen-previous 1484 | 'mouse-2 'elscreen-create 1485 | 'mouse-3 'elscreen-next) 1486 | 'help-echo "mouse-1: previous screen, mouse-2: create new screen, mouse-3: next screen"))) 1487 | (with-current-buffer (window-buffer (frame-first-window)) 1488 | (kill-local-variable 'elscreen-tab-format) 1489 | (when elscreen-tab-display-control 1490 | (setq elscreen-tab-format 1491 | (nconc 1492 | elscreen-tab-format 1493 | (list 1494 | control-tab 1495 | tab-separator)))) 1496 | 1497 | (mapc 1498 | (lambda (screen) 1499 | (let ((kill-screen 1500 | (propertize 1501 | "[X]" 1502 | 'local-map (elscreen-tab-create-keymap 1503 | 'mouse-1 `(lambda (e) 1504 | (interactive "e") 1505 | (elscreen-kill ,screen)) 1506 | 'M-mouse-1 `(lambda (e) 1507 | (interactive "e") 1508 | (elscreen-kill-screen-and-buffers ,screen))) 1509 | 'help-echo (format "mouse-1: kill screen %d, M-mouse-1: kill screen %d and buffers on it" screen screen)))) 1510 | (setq elscreen-tab-format 1511 | (nconc 1512 | elscreen-tab-format 1513 | (list 1514 | (propertize 1515 | (concat 1516 | (when (or (eq elscreen-tab-display-kill-screen 'left) 1517 | (eq elscreen-tab-display-kill-screen t)) 1518 | kill-screen) 1519 | half-space 1520 | (propertize 1521 | (format "%d%s%s%s" 1522 | screen 1523 | (elscreen-status-label screen) 1524 | half-space 1525 | (elscreen-tab-escape-% 1526 | (elscreen-truncate-screen-name 1527 | (assoc-default screen screen-to-name-alist) 1528 | (elscreen-tab-width) t))) 1529 | 'help-echo (assoc-default screen screen-to-name-alist) 1530 | 'local-map (elscreen-tab-create-keymap 1531 | 'mouse-1 `(lambda (e) 1532 | (interactive "e") 1533 | (elscreen-goto ,screen)))) 1534 | (when (eq elscreen-tab-display-kill-screen 'right) 1535 | (concat half-space kill-screen))) 1536 | 'face (if (eq current-screen screen) 1537 | 'elscreen-tab-current-screen-face 1538 | 'elscreen-tab-other-screen-face)) 1539 | tab-separator))))) 1540 | screen-list) 1541 | 1542 | (setq elscreen-tab-format 1543 | (nconc 1544 | elscreen-tab-format 1545 | (list 1546 | (propertize 1547 | (make-string (window-width) ?\ ) 1548 | 'face 'elscreen-tab-background-face 1549 | 'local-map (elscreen-tab-create-keymap))))) 1550 | 1551 | (setq header-line-format elscreen-tab-format)))))) 1552 | 1553 | (add-hook 'elscreen-screen-update-hook 'elscreen-tab-update) 1554 | 1555 | ;;; Unsupported Functions... 1556 | 1557 | (defun elscreen-link () 1558 | (interactive) 1559 | (cond 1560 | ((null (one-window-p)) 1561 | (elscreen-message "current screen must not have two or more window!")) 1562 | ((or (null (elscreen-get-previous-screen)) 1563 | (elscreen-one-screen-p)) 1564 | (elscreen-message "must specify previous screen!")) 1565 | ((and (elscreen-goto (elscreen-get-previous-screen)) 1566 | (null (one-window-p))) 1567 | (elscreen-goto (elscreen-get-previous-screen)) 1568 | (elscreen-message "previous screen must not have two or more window!")) 1569 | (t 1570 | (let ((elscreen-link-buffer (current-buffer))) 1571 | (elscreen-kill) 1572 | (switch-to-buffer-other-window elscreen-link-buffer))))) 1573 | 1574 | (defun elscreen-split () 1575 | (interactive) 1576 | (if (and (null (one-window-p)) 1577 | (< (elscreen-get-number-of-screens) 10)) 1578 | (let ((elscreen-split-buffer (current-buffer))) 1579 | (delete-window) 1580 | (elscreen-create) 1581 | (switch-to-buffer elscreen-split-buffer) 1582 | (elscreen-goto (elscreen-get-previous-screen))) 1583 | (elscreen-message "cannot split screen!"))) 1584 | 1585 | ;;; Start ElScreen! 1586 | 1587 | ;;;###autoload 1588 | (defun elscreen-start () 1589 | (interactive) 1590 | (mapc 1591 | (lambda (frame) 1592 | (elscreen-make-frame-confs frame 'keep)) 1593 | (frame-list)) 1594 | (let ((prefix-key elscreen-prefix-key) 1595 | (elscreen-prefix-key nil)) 1596 | (elscreen-set-prefix-key prefix-key))) 1597 | 1598 | (provide 'elscreen) 1599 | 1600 | ;;; elscreen.el ends here 1601 | --------------------------------------------------------------------------------