name mode size
README.md 100644 21.95kB
multifiles-apmod.el 100644 92.77kB
README.md
# multifiles-apmod.el Forked from: https://github.com/magnars/multifiles.el multifiles-apmod.el is a modified version of [multifiles.el](https://github.com/magnars/multifiles.el). The original multifiles.el is by Magnar Sveen. multifiles-apmod.el was modified and added to a lot by Apollia. I changed it so much that I thought it would probably be best not to even try to get my changes merged into the original repo, because many people might be annoyed with my code's verbosity. Also, I never did manage to figure out how to stop read-only buffers from ruining all multifiles, nor how to build large multifiles faster. Nonetheless, I think I made some worthwhile additions - worthwhile enough that I thought I should make this an independent repo, so it would more readily appear in GitHub's search. ----- A [GNU Emacs](https://www.gnu.org/software/emacs/) add-on which lets you view and edit multiple files (or just parts of them) in one buffer. ----- Note, 22:28:24 05/27/2018: Today, a problem with undo-tree.el temporarily caused me to be unable to save all the files in one of my multifiles. I think this glitch resulted from undo-tree.el not being able to handle very long filepaths. (03:02:31 05/28/2018. Definitely filepaths, not just filenames - since I had no trouble with my multifile after moving the file below to a shallower folder, without changing the file's name.) <br>I was trying to save a multifile which contained this file: `/root/00-Workspaces/APSK Initializer Stage 2/Workspace - Apps/APSK-Initializer-Stage-2/Versions of Initialize APSK Stage 2/Actions/Jockeys/For Legacy APSK - Make settings note ~Main Distro of Puppy Setup Kit~ containing ~Detected Puppy Distro~.` After I edited that file in my multifile, it became impossible to save all the files in my multifile because this error kept stopping everything: `progn: Opening output file: file name too long, /tmp/Emacs-Tmp/Undo-Tree/.!root!00-Workspaces!APSK Initializer Stage 2!Workspace - Apps!APSK-Initializer-Stage-2!Versions of Initialize APSK Stage 2!Actions!Jockeys!For Legacy APSK - Make settings note ~Main Distro of Puppy Setup Kit~ containing ~Detected Puppy Distro~..~undo-tree~` I tried disabling undo-tree-mode in my multifile, but that alone didn't fix the problem. Fortunately, I was able to make my multifile saveable again by disabling undo-tree-mode in my non-multifile file buffer "For Legacy APSK - Make settings note ~Main Distro of Puppy Setup Kit~ containing ~Detected Puppy Distro~." To do that, I typed C-x b and part of the above filename to go to my non-multifile file buffer, typed M-x, and ran "undo-tree-mode" to disable undo-tree-mode. ----- Version 2.1 - Released July 19, 2017. To try to make my multifiles get built faster, I added a dangerous feature which you, and even I, probably shouldn't use. I made a setting you can customize via M-x customize which you can set to make multifiles-apmod skip checking for read-only buffers. The reason it's a bad idea to skip those checks is because just one read-only buffer can mess up ALL multifiles. Even without those checks, building large multifiles still takes much longer than I would like. Still not sure how to fix that. Doing M-x byte-compile-file doesn't help as much as I hoped it would. <br><br> Note, July 26, 2017: In the process of cleaning up and releasing my personal GNU Emacs settings folder - http://github.com/Apollia/.emacs.d - I somehow accidentally fixed the problem of multifiles being built slowly! However, I still don't know what was wrong nor how it got fixed. But, just thought I should point out the good news that the slowness is definitely fixable, somehow. ---- Version 2.0 - Released Jan. 10, 2016. This version partway fixes a REALLY bad glitch I discovered today. The glitch is caused by editing read-only buffers in a multifile, which somehow messes up the mirroring in ALL multifiles (even multifiles you weren't editing and which don't contain read-only buffers), and makes it impossible for ALL multifiles to save their embedded files. This has been partly fixed by making it so read-only buffers are blocked from being added to a multifile when a multifile is first being built. However, I don't yet know how to make it impossible to make the embedded buffers read-only *after* they've been added to a multifile. So, unfortunately, it is still possible to run into this horrible glitch accidentally, such as by going to the original buffer of an embedded buffer, and clicking the asterisk at the left of your modeline which toggles whether the buffer is writable or read-only. And to make matters worse, because the mirroring of ALL embedded files in ALL multifiles gets messed up by this glitch, Emacs probably won't even ask you at shutdown if you want to save even the writable embedded files you edited! So, please be careful. If you do run into this horrible problem, then, to save your data, you can copy and paste the entire contents of your multifile into another buffer and save that buffer, which will create one large combined file. Sorry, I don't know of an easy way to merge the changes in that large combined file back into your separate files. ----- multifiles-apmod.el is a modified version of [multifiles.el](https://github.com/magnars/multifiles.el). The original multifiles.el is by Magnar Sveen. multifiles-apmod.el was modified and added to a lot by Apollia. There's additional documentation in the source code of multifiles-apmod.el. **Warning**: I, Apollia, only began seriously using Emacs in Nov. 2015, so I am quite inexperienced with Emacs Lisp coding. So, please be very careful with this add-on, and sorry if I broke anything or did things wrong. Also, see the "Things to Beware Of" section below. Some of my additions include: * A custom header line with information about the mirrored text under your cursor, and your relative location in the mirrored text, and your absolute location in the multifile * Functions to automatically load many files into the multifile of your choice: Mirror_Folder_Into_Multifile Mirror_Files_Into_Multifile * Keychords to easily go to the next or previous chunks of mirrored text: C-Page Up C-Page Down * A keychord to show you the relative line number you're at in a mirrored file: C-Home * Some customizable settings changeable via M-x customize ## Setup To use multifiles-apmod.el, you also need these 3 very useful add-ons: * dash.el - helpful for dealing with lists [https://github.com/magnars/dash.el](https://github.com/magnars/dash.el) * s.el - string manipulation [https://github.com/magnars/s.el](https://github.com/magnars/s.el) * f.el - for working with files and directories in Emacs [https://github.com/rejeep/f.el](https://github.com/rejeep/f.el) To make the add-ons useable by your Emacs, first, put them all in a folder in your .emacs.d folder. You can name that folder whatever you want. (I call mine "Add-Ons".) Then, to tell Emacs to check that folder and its subdirectories for add-ons to load, you can add some code similar to the following to one of your Emacs settings files (such as .emacs or init.el): (add-to-list 'load-path "~/.emacs.d/Add-Ons") (progn (cd "~/.emacs.d/Add-Ons") (normal-top-level-add-subdirs-to-load-path) ) (The above code is based on code from [this page on StackOverflow](http://stackoverflow.com/a/6406114).) To tell Emacs to load the add-ons at startup, put these lines somewhere in one of your Emacs settings files (such as .emacs or init.el): (require 'multifiles-apmod) (require 'dash) (require 's) (require 'f) ; Optional and customizable: (global-set-key (kbd "C-!") 'Mirror_Region_Into_Multifile ) Alternatively, and optionally, you might like to use the [use-packages.el](https://github.com/jwiegley/use-package) add-on instead of the command "require". Optionally, to make multifiles-apmod.el (or any other Emacs add-on) faster, you can byte-compile it. Open multifiles-apmod.el in Emacs, type M-x byte-compile-file, and choose the file multifiles-apmod.el. (You'll get some warnings saying to use the function forward-line instead of goto-line, but I don't recommend that, because I when tried that, it broke the functions Jump_to_Prev_Mirrored_File and Jump_to_Next_Mirrored_File.) ## Usage To enable you to easily manually add chunks of text to a multifile, you can optionally put this somewhere in your Emacs settings: (global-set-key (kbd "C-!") 'Mirror_Region_Into_Multifile ) Select any text in a file's buffer. (You can't mirror text from non-file buffers such as \*scratch\*.) Then, type C-!, and that text will be mirrored into the default multifile. Saving the \*multifile\* buffer should save all the original files. But please be very wary in case there are glitches, or conflicts with other add-ons. To navigate in your multifile, you can use C-Page Up and C-Page Down. And, if you want to see the relative line number, you can press C-Home. Sorry, I don't yet know how you can customize those keychords other than editing multifiles-apmod.el's source code. To load multiple files into a multifile, use the functions Mirror_Folder_Into_Multifile or Mirror_Files_Into_Multifile. For an example - here's the function call I use to load all my little Emacs settings files into one multifile: (Mirror_Folder_Into_Multifile ;Source folder: "/root/.emacs.d/Apollia Settings/" ;Get files recursively "get files recursively" ;nil ;User-specified multifile buffer "*EmacsMF*" ; User-specified major mode for multifile 'lisp-interaction-mode ; 'fundamental-mode ; User-specified sort functions to sort the file list. ; Used after the includer/excluder regexes and ; before the regexes which decide which files ; to put first and last. '( ;string-lessp ; Alphabetical order. Not really necessary to ; use in your Mirror_Folder_Into_Multifile ; calls because string-lessp is used by default ; if your list of sort functions is empty. ; Reverse alphabetical order: ;(lambda (arg1 arg2) ; ;(my-emacs-log "Arg1 %s" arg1) ; ;(my-emacs-log "Arg2 %s" arg2) ; (let (myresult) ; (setq myresult (not (string-lessp arg1 arg2) ) ) ; ;(my-emacs-log "My result %s" myresult) ; myresult ; ) ;) ) ; Include these files: '( ) ; Exclude these files: '( ".+/[.]emacs[.]d/Apollia Settings/Add-ons/Multifiles.+" ".+/[.]projectile" ".+/[.]hg.+" ".+/[.]git.+" ) ; Put these files first: '( ".+/Test Multifiles.+" ".+/Usual Multifiles.+" ".+/Lighters$" ) ; Put these files last: '( ".+/Games.+" ".+Apollia Settings/emacs_init_1" ".+Apollia Settings/Help.txt$" ".+/init.el$" ".+/After M-x Customize Stuff$" ".+/Default List of Workgroups$" ) ; Commands to run in the multifile after mirroring '( ;(tetris) (Jump_to_Prev_Mirrored_File) ; (delete-other-windows) ; (make-frame-command) ) ; Existing file lists to merge in: (list ; MyListOfFiles "/root/.emacs.d/init.el" ) ; Skip flaw check for existing file list ; "skip flaw check for existing file list" nil ; Skip activating multifiles-apmod minor mode ;"skip activating multifiles-apmod minor mode" nil ;Skip displaying relative line number in custom header line ;"skip displaying relative line number in custom header line" nil ) The function call I've been using to make a multifile out of some files from the future version 2.0 of my [Puppy Linux Setup Kit](http://astroblahhh.com/puppy-linux/software/apollias-puppy-linux-setup-kit/). (Mirror_Folders_Into_Multifile ;Source folders: (list ; MyListVariable "/apmnt/truecrypt57/Apollia's Puppy Linux Setup Kit/Global Stuff Copied Into RAM Disk At First Launch/" "/apmnt/truecrypt57/Apollia's Puppy Linux Setup Kit/Launchers/" ) ;Get files recursively "get files recursively" ;nil ;User-specified multifile buffer "*ApskMF*" ; User-specified major mode for multifile 'fundamental-mode ; 'fundamental-mode ; User-specified sort functions to sort the file list. ; Used after the includer/excluder regexes and ; before the regexes which decide which files ; to put first and last. '( ;string-lessp ; Alphabetical order. Not really necessary to ; use in your Mirror_Folder_Into_Multifile ; calls because string-lessp is used by default ; if your list of sort functions is empty. ; Reverse alphabetical order: ;(lambda (arg1 arg2) ; ;(my-emacs-log "Arg1 %s" arg1) ; ;(my-emacs-log "Arg2 %s" arg2) ; (let (myresult) ; (setq myresult (not (string-lessp arg1 arg2) ) ) ; ;(my-emacs-log "My result %s" myresult) ; myresult ; ) ;) ) ; Include these files: '( ) ; Exclude these files: '( ".+/[.]projectile" ".+/[.]hg.+" ".+/[.]git.+" ".+test.+" ) ; Put these files first: '( ".+/Construct.sh$" ".+/Global.sh$" ".+/Launch Site Plan Construction.sh$" ".+/Launch Puppy Setup Kit.sh$" ".+/Prepare for Launch.sh$" ".+/Functions.sh$" ) ; Put these files last: '( ".+/Settings/.+" ) ; Commands to run in the multifile after mirroring '( ;(tetris) (shell-script-mode) (multifiles-apmod-minor-mode) ; (Jump_to_Prev_Mirrored_File) ) ; Existing file lists to merge in: '( ) ) ## Things to Beware Of Please be careful - keep your data backed up, and don't fully trust multifiles-apmod.el, in case I somehow messed something up, or in case there are conflicts with other add-ons you have, etc. See also the "Problems with Other Add-Ons" section below. * Don't make any of your embedded files read only, because editing a read-only embedded file in a multifile will somehow mess up the mirroring in ALL your multifiles - not just the one with the read-only embedded file - and make it so ALL your multifiles will be unable to save the embedded files anymore. As of Version 2.0, buffers which are read-only are blocked from being added to a multifile when the multifile is first built, but, I don't know how to make it impossible to set those buffers to read-only *after* they've already been added to a multifile. And Emacs, by default, has a clickable asterisk on the left of your modeline which you can click to toggle whether your buffer is writable or read-only, so it might be possible to accidentally make a buffer read-only. So, please be careful not to do that. If you do run into this horrible problem, then, to save your data, you can copy and paste the entire contents of your multifile into another buffer and save that buffer, which will create one large combined file. Sorry, I don't know of an easy way to merge the changes in that large combined file back into your separate files. * Be careful if your \*Messages\* buffer is continually being printed to, such as by a constantly occurring error (such as the ones I ran into while I was first trying to build the custom header line). I have had the problem of the stuff in my multifile somehow getting overwritten by a flood of \*Messages\*. * Don't close the original buffers of the files you've mirrored into a multifile, because the multifile won't be able to save those files if you do. * Don't undo so far back that it unmakes the multifile overlays, because redo will fail to recreate overlays. * If you somehow accidentally delete an entire overlay, undo won't be be able to recreate it. Normally, a green bar (or a different color or character if you customized it) will be at the lefthand side of every mirrored line in the multifile. If an overlay has gotten deleted, that green bar will be missing. * Don't delete then try to recreate entire overlays of mirrored text, because attempting to recreate them using Mirror_Region_Into_Multifile or in other ways might be glitchy. * Don't mirror the same text into multiple multifiles, unless the extra multifiles are read-only. Multiple multifiles currently can't update each other - only themselves and the original file. * Multifiles tend to be created much faster if you load in files from a RAM disk rather than a normal physical disk. * Some problems with slowness can be reduced by telling the functions Mirror_Folder_Into_Multifile and Mirror_Files_Into_Multifile to skip displaying the relative line number in the custom header line. * Multifiles in some major modes (such as php-mode or c-mode) seem to work better and faster if you add mostly smaller files and smaller groups of files. Large multifiles can be rather slow to create and use. (Fortunately, not all large multifiles are slow. multifiles-apmod.el works nicely for me with a 1.4 MB Perl multifile made up of files from my [Puppy Linux Setup Kit](http://astroblahhh.com/puppy-linux/software/apollias-puppy-linux-setup-kit/). Except the multifile is much slower to create if I load the files directly from a real disk rather than my Puppy Linux RAM disk. multifiles-apmod.el also works well for me with around 100 small Emacs Lisp files in my Emacs settings folder, though those only add up to about 150 KB total, and I always load them from my Puppy Linux RAM disk.) As of Dec. 20, 2015, I prefer to not even use php-mode for my large PHP multifiles. Instead, I prefer perl-mode, since it does a surprisingly decent job of syntax-coloring PHP files, and works pretty fast even for 2.6 MB of PHP files from [Astroblahhh Desktop](http://astroblahhh.com/software/abdesktop/). To fix the syntax coloring, I had to convert my PHP comments' prefix to # instead of // or /*, and get rid of */ comment suffixes. Also, HTML sections with apostrophes confuse perl-mode, so, to temporarily fix that, I add this immediately after such apostrophes: <?php #'> As of Dec. 21, 2015, I prefer using a perl-mode I slightly modified to masquerade as php-mode, just to make some php-mode-dependent add-ons work: [https://github.com/Apollia/perly-php-mode](https://github.com/Apollia/perly-php-mode) * With a large PHP multifile in php-mode, it seems to work faster near the top of the multifile, and slower the further down you go. ##Problems with Other Add-Ons php-mode [https://github.com/ejmr/php-mode](https://github.com/ejmr/php-mode) php-mode sometimes conflicts somehow with multifiles-apmod.el when automatically loading many files into a multifile, causing the load to get interrupted by an error. For faster, less potentially crashy automatic loading with the functions Mirror_Folder_Into_Multifile and Mirror_Files_Into_Multifile, I suggest telling them to use this major mode: 'fundamental-mode Then you can automatically activate the major mode you actually want after the automatic load is finished by putting something like (php-mode) in your list_of_commands_to_run_in_multifile_after_mirroring. You might also have to add the command (multifiles-apmod-minor-mode 1) since activating (php-mode) that way I guess somehow turns off the multifiles-apmod minor mode. Here's my current favorite alternative to php-mode: https://github.com/Apollia/perly-php-mode Visual Bookmarks [https://github.com/joodland/bm](https://github.com/joodland/bm) With the Visual Bookmarks add-on, you should only work with mirrored text in the multifile, not the original buffer, because if you try to work on it in both buffers, bookmarks in at least one of those buffers will immediately get lost. Also, it only makes temporary bookmarks in non-file buffers such as \*multifile\* or \*scratch\*. It might be OK if all you want is temporary bookmarks anyway, and if you never edit the original buffer, only your multifile. Some alternatives I suggest are: Breadcrumb [https://github.com/pheaver/breadcrumb](https://github.com/pheaver/breadcrumb) Breadcrumb bookmarks persist even if you close and reopen Emacs - except if you open Emacs in debug-init mode, which somehow wipes Breadcrumb bookmarks out. Breadcrumb bookmarks even persist with temporary buffers such as \*scratch\* and multifiles. I wish I knew of a way to make them visible. Bookmark+ [https://github.com/emacsmirror/bookmark-plus](https://github.com/emacsmirror/bookmark-plus) Bookmark+'s bookmarks also persist even with temporary buffers, and can be made visible, but Bookmark+ is very complicated. Tons of features, and depending on what you need, it might be worthwhile to invest the time in trying to figure out how to make it work. As of Dec. 24, 2015, I actually use all 3 of these bookmark add-ons, since I'm finding it convenient to have 3 separate lists of bookmarks which all behave slightly differently. I use Breadcrumb and Visual Bookmarks for more disposable bookmarks. And Bookmark+ for both disposable bookmarks and more persistent bookmarks, such as bookmarks I want to be able to jump to by name, sort of reminiscent of my Navig script (written in Perl) which I constantly use to get around in Puppy Linux. [http://astroblahhh.com/software/perl/apollias-navigation-command-prompt-for-linux.txt](http://astroblahhh.com/software/perl/apollias-navigation-command-prompt-for-linux.txt) ## License Copyright (C) 2011 Magnar Sveen Copyright (C) 2015/2016 Apollia Authors: Magnar Sveen <magnars@gmail.com> Apollia <http://astroblahhh.com/contact-apollia.shtml> Keywords: multiple files; twin files; mirrored files; overlays This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.