From 346e5a0b4550f9ade15f20499064c23f80cc9629 Mon Sep 17 00:00:00 2001 From: Karlin Fox Date: Sat, 21 Aug 2021 19:14:44 -0700 Subject: [PATCH] Big refresh & refactor, add wdscheme -t, use 0BSD * add wdscheme -t to set shell-local scheme override * refactor: dedupe and use internal functions more often * fix: `install.sh` pointed to old README * improve `install.sh` instructions and hygiene * remove extra loop in `wdl` for bash, matching zsh * quote and escape all var expansions * modernize CHANGELOG to markdown, ISO dates * add note about using `direxpand` for bash * remove old TODOs that won't work (mostly due to inconsistency between env vars, aliases, and persisted slot values across shells.) * Switch to 0BSD License * Fix i var leaking and env var staleness --- CHANGELOG | 55 -------- CHANGELOG.md | 71 +++++++++++ LICENSE | 348 ++------------------------------------------------- README.md | 79 ++++++------ wd.1.gz | Bin 1481 -> 1476 bytes wd/wd.sh | 199 ++++++++++++++++++----------- wd/wd.zsh | 193 ++++++++++++++++++---------- 7 files changed, 379 insertions(+), 566 deletions(-) delete mode 100755 CHANGELOG create mode 100755 CHANGELOG.md diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100755 index a7dd15b..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,55 +0,0 @@ -2.1 - 13-11-2010 - * rewrote file reading with advice from Wayne Seguin - * reformatted and fixed some code style issues - -2.0 - 20-10-2010 - * completed single-file, pure bash rewrite (no longer needs perl) - * env. vars now auto-update - * clear a single slot with a dot: 'wds3 .' - -1.12 - 6-10-2010 - * Hosting on github - * Updated README - * zsh compatibility fixes by Matt Fletcher - -1.11 - 19-03-2004 - * fixed wdenv bug with spaces in dir names - * added bash completion to wdscheme - -1.10 - 24-02-2004 - * fixed quoting in wdaliases.sh - * fixed WDSCHEME usage for local scheme use - * released to sourceforge.net - -1.09 - 12-03-2003 - * added Gary Cramblitt's man page - * fixed install script for Solaris - * fixed bug when passing a dir. to wds - * updated readme.txt a little - -1.08 - 11-19-2003 - * fixed wdscheme.pl -s check (thanks Dave and Frank!) - * now effectively enforces 10 lines in all commands - * copies readme.txt to dist dir on install - -1.07 - 11-16-2003 - * fixed wdenv by making it a separate script as well - * made wdenv only export slots that are filled - * actually removed wd.list and wd.dest (from CVS too :) - -1.06 - 11-10-2003 - * made wdl a script instead of a plain alias - * wdscheme now unsets WDSCHEME - * fixed tarball root dir - * updated readme - * made all scripts use new wdscheme.pl for figuring the current scheme. - * removed unused wd.list and wd.dest - -1.05 - 11-8-2003 - * made recall of empty wd entry not cd - * better error handling of schemes deleted while they are active - * removed WDSCHEME env var from default script use (still checked - on recall, for manual override) - -1.0 - 10-1-2003 - * initial release diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100755 index 0000000..dc536a5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,71 @@ +### 3.0 - 2021-10-03 +* add wdscheme -t to set shell-local scheme override +* refactor: dedupe and use internal functions more often +* fix: `install.sh` pointed to old README +* improve `install.sh` instructions and hygiene +* remove extra loop in `wdl` for bash, matching zsh +* quote and escape all var expansions +* modernize CHANGELOG to markdown, ISO dates +* add note about using `direxpand` for bash +* remove old TODOs that won't work (mostly due to inconsistency + between env vars, aliases, and persisted slot values across shells.) +* Switch to 0BSD License + +### 2.2 - 2019-09-26 +* Improve zsh support + +### 2.1 - 2010-13-11 +* rewrote file reading with advice from Wayne Seguin +* reformatted and fixed some code style issues + +### 2.0 - 2010-20-10 +* completed single-file, pure bash rewrite (no longer needs perl) +* env. vars now auto-update +* clear a single slot with a dot: `wds3 .` + +### 1.12 - 2010-06-10 +* Hosting on github +* Updated README +* zsh compatibility fixes by Matt Fletcher + +### 1.11 - 2004-19-03 +* fixed wdenv bug with spaces in dir names +* added bash completion to `wdscheme` + +### 1.10 - 2004-24-02 +* fixed quoting in `wdaliases.sh` +* fixed `WDSCHEME` usage for local scheme use +* released to sourceforge.net + +### 1.09 - 2003-12-03 +* added Gary Cramblitt's man page +* fixed install script for Solaris +* fixed bug when passing a dir. to `wds` +* updated `readme.txt` a little + +### 1.08 - 2003-11-19 +* fixed `wdscheme.pl -s` check (thanks Dave and Frank!) +* now effectively enforces 10 lines in all commands +* copies readme.txt to dist dir on install + +### 1.07 - 2003-11-16 +* fixed `wdenv` by making it a separate script as well +* made `wdenv` only export slots that are filled +* actually removed `wd.list` and `wd.dest` (from CVS too :) + +### 1.06 - 2003-11-10 +* made `wdl` a script instead of a plain alias +* wdscheme now unsets WDSCHEME +* fixed tarball root dir +* updated readme +* made all scripts use new `wdscheme.pl` for figuring the current scheme. +* removed unused `wd.list` and `wd.dest` + +### 1.05 - 2003-11-08 +* made recall of empty `wd` entry not `cd` +* better error handling of schemes deleted while they are active +* removed `WDSCHEME` env var from default script use (still checked + on recall, for manual override) + +### 1.0 - 2003-10-01 +* initial release \ No newline at end of file diff --git a/LICENSE b/LICENSE index 5b6e7c6..ea533ae 100644 --- a/LICENSE +++ b/LICENSE @@ -1,340 +1,14 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +The BSD Zero Clause License (0BSD) - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Copyright (c) 2003, 2021 by Karlin Fox - Preamble +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 2 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, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 7268456..d71d720 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,19 @@ * Developed by Karlin Fox * With help and advice from David Crosby and Wayne Seguin -Compatible with bash or zsh. Please open an issue if you'd like support for -your favorite shell! - -Working Directory (`wd`) is a simple set of aliases and shell functions that -provides named storage of directories, as well as quick retrieval of +Working Directory (`wd`) is a simple set of aliases and shell functions +providing named storage of directories, as well as quick retrieval of previously-stored directories. It has support for multiple schemes of working directories. +Compatible with bash and zsh. Please open an issue if you'd like support for +your favorite shell! + ## INSTALLATION The easiest way to install (except the man page, see below) is this script: - $ ./install.sh + ./install.sh This will put the necessary files in `$HOME/.wd`. If you want it somewhere else, just put the files in the `wd` directory of the package wherever you @@ -24,16 +24,17 @@ equivalent thereof): export WDHOME="${HOME}/.wd" source "${WDHOME}/wd.sh" + # OR, for ZSH: + # source "${WDHOME}/wd.zsh" shopt -s direxpand # optional, for bash $WD[0-9] env. var. expansion Note that a man page is included but not installed due to platform inconsistency. Please copy the file (`wd.1.gz`) to your man page directory. For Linux, usually `/usr/share/man/man1`. - ## USAGE -There are 10 slots: 0 through 9. Slot 0 is the default, implied slot. +There are 10 slots: 0 through 9. Slot 0 is the default, implied slot. `wdl` lists the contents of the current scheme's slots. Some examples: @@ -46,31 +47,44 @@ Some examples: | `wd` |Jump to the default directory (slot 0) | `wd1` |Jump to the directory in slot 1 | `wdc` |Clear all slots - -Slot contents will persist from session to session. -It's possible to clear only a single slot with `.`, +Slot contents will persist between shell sessions because the current scheme is +stored in $WDHOME. - $ wds3 . +It's possible to clear only a single slot with `.`, e.g. + + wds3 . will result in slot 3 having its contents cleared. - + A set of environment variables named after the slots (`$WD0`, `$WD1`, -etc.) are created and updated as you modify the slots. +etc.) are created and updated as you modify the slots. Note that these +may be out-of-sync when you change schemes from a different shell. If this +happens, running `wdscheme` will print the current scheme and also update +these environment variables. ## SCHEMES Schemes can help you separate sets of directories commonly used for each task you work on on the command line. To change schemes, simply say: - $ wdscheme myscheme + wdscheme myscheme -...where `myscheme` is some label for your scheme. If the scheme file already +...where `myscheme` is some name for your scheme. If the scheme file already exists, wd will clone your current slots to the new scheme file and switch to it. - -If the label is new, a new `.scheme` file is created in `$WDHOME` and the new -scheme's name is recorded in the `$WDHOME/current_scheme` file. + +If the name is new, a new `{name}.scheme` file is created in `$WDHOME` and the +new scheme's name is recorded in the `$WDHOME/current_scheme` file. + +If you want to change the scheme within the context of your current shell only, +use the `-t` option instead: + + wdscheme -t tempscheme + +This will update your environment with an override variable (WDSCHEME) and +will not overwrite the current scheme on disk, meaning other shells will be +unaffected. ## SIMILAR PROJECTS @@ -78,26 +92,17 @@ Working Directory is unique in its schemes and quick aliases, but there are more generic directory management and bookmarking tools out there: * [CDargs](http://www.skamphausen.de/cgi-bin/ska/CDargs) -* [apparix](http://micans.org/apparix) -* [autojump](https://github.com/joelthelion/autojump/wiki) +* [apparix](https://github.com/micans/apparix) +* [autojump](https://github.com/wting/autojump#name) -Attention users of other shells! You can still use wd but you'll have to use -the [legacy version written in sh and perl, wd-1.12](https://github.com/karlin/working-directory/tree/master) +Attention users of shells besides bash or zsh!: you can try the pure-shell version but if it doesn't work for you, try the legacy version written in sh and perl, +[wd-1.12.](https://github.com/karlin/working-directory/tree/master) -## LICENSE - -Working Directory is licensed under the GPL, included in [LICENSE.](https://github.com/karlin/working-directory/blob/master/LICENSE) +## CHANGELOG - Working Directory 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 2 of the License, or - (at your option) any later version. +See [CHANGELOG.md](CHANGELOG.md). - Working Directory 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. +## LICENSE - You should have received a copy of the GNU General Public License - along with Working Direcory; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +Working Directory is licensed under the BSD Zero Clause license, included +in [LICENSE.](LICENSE) \ No newline at end of file diff --git a/wd.1.gz b/wd.1.gz index d842a3276e26e4121cc145feb9739e2d12938709..3c1fc366416882f2f80428a751629719fc7e2436 100644 GIT binary patch literal 1476 zcmV;#1v~m5iwFpFGFf2&19xODF#wHLO>g5i5WVYH41xfgEL=HhPu*eBQxakeP1fxkq~JieKEGmQUmLKEHYjCxvibXJ_xAHvkC zp=#8+b((g%r@kqrp>8F~inVkg zoiuAp!qT=Jkp<8^nuKu{`ol5#3>$Rmd44vdI9P-p9)F@cZJt&0M5Qva=(O3n{p>zY zmf3ygJyciQvVN$Rgukh>Z7p^r>Y8k=J1TV3fvNTUM>Ck(y=ew0>G&1BF|eWS_XiP@ zzy_tPL|=CU;+gxrIDd~A|2U%akLfJ_d8vIz(L4=d4y&Xp64VI(W$8(6WHTa-eX~`TSqvq?f_KQv z;OOAFmeVksq|q{ulGr;`d#Vnxdj1u3;hi(OAiJ}jT$8QzWnU#c{ws8N#K2XG30qf7yFt3I&-DvV2^8mrq*q(&|U0s z4wURz-41Oa%C#1U%2cYxx>LiBwhH04(pY7|*yuG{&{}jbc@WJ0H;_NZNgjUuG_<^^ z;l7rldCM)?6%vQwS7I-BZt&N3tJG6(++_I8E1Xs=bJC3*7(7a(x~h?ofh+?!wIKGx zlo3=((e*|S=>qI}&1L?uEoHO$FaQ;pS&k1fje%qSx9gC0Pc?|K&@iyAZc5$;k}|sC zLB_>X;;{x*E~RQP{v`EQg3~n?7aQDAu zvC?#UHy!qly&(F;={@seWX3H7xA`ndy{X*DTDM5f`)xDy>>7iBqMX&xRd50-%4UuK5{LYBJn&)-rZU)+qin{s%cUxRd-IM`U6fwKL>8{=)sNjq$Ld^bZ@{w0$Uw033d zR=7d?V#V`o+*>oQbs_38Hu-(IuiXBAJsPU7H-bfgg={Qz_I6Wqg|D(H{UwdYWgyT2 zG#||9>;gOIpN6>J|G)6_#l(qZ$a9RW z;xbYKrKx+j-7WT&Kyx;mwoGk-yDC92DdMyCaVvosHldf?~?d z1H2|Y;Mf`m=V`z!;_zl3-GuQZgrh@DoJXFdFuu+9P9qA^DC3ip+nf;+2MU}x98kFg eE+1fWfLewrlCcOJ`t|#g`2PZ@md1qU3IG6w65eP4 literal 1481 zcmV;)1vdI0iwFqp&%aCn19xODF#wHLVNcsg5dH37F+xa9s?;G@olY(4hX4U`2T2qM zAta<~W3TZR+w0r46Y}ML`@Pw9Ot{`%iwaHbowqY@X5LKrctq#A+8Onf)zpjo^oKCH zD(O4vtd&U90gD0dEF zD~u6ky`wr4FmN`Fm1&ccHvS=-#iFF9Or){3C=;9uJ0BkKS{O-BjKddYlDyNn5>Uhj zMkdPEMy;D#x)WA6CYBWIL^>2)RtZyE(kXk{@_tC>_zK9;8;4wYhCi!E!ApBe?TjgR$0(aOPm&6*pl(h}Qwed%7 zdo%)+rz38R!5I$q?L~x)^MORBqRDHI*mHkR`fm|uKac3_XVja08R4*L=+gmK>m2>w z6cy+2@cLJj?|o=pcx(65x5n+Y=eZQ7BhQn@WM538^W}80n$BmzJ{=co?@SP$A#p*U z%U6)y*;*D{N;WpCs(tZ@TnQ_!uNYjQx0Xs#$Rw};5l@m0_6{p)2P9A`5}x4yKN}T4 zqgYVGawBp+S{b=fy0Q6=7yvj2#vyS7X0WtPRcTXGiW1)lvt!3?oXJAEV*h7;*ft1O znM5ABtwtxFhyk6nqyai|+;gyp$?2)0$`yKo4f;Td4$IG>c}F=JqIH5&m2*2X($05A zg%(4%LREA@V9Y{KC_qNr&p>`Zo3AGCKYIZZIm`omDZK}-FVh@^cxM?vMjPdb$8x6rARF+eDU|cOHlZ z!TAHGp=0Jh+XA!)szi*j#sORDGU3-iQbw07tDHO~);V0|RH_nUELq^-()O`eQ`&q`BrsMky|L)KVML&1-9tATn;~tFfR@d`o zZ~=MDbp>+PyMwtvy=V9NYpP$q?nI{bSFq9#?jibAG;v1AO68j&*|0vs{6auT>D*|$ z-i5&}gudcl*ct_`E&0S1sul-CvCi?#YvXhlt;RPuj(I68=mV!vJus+B3<*$<9DQqS z&3uHz_F-r<&X#I5xN4ksQz>JV7GJ~F=xX8U_a8Dk?&um^YLg`h>^$407ICb$qd*|r^`hQhV5 znTdVx^pJc}VIWngj~YHfDMtxtiV4 zl`N%!!Y&$=TTD0YEy^#V-*WG^fv71K`}Rx=3LFSx`(uvLpX z;Ju^gcN{~yV#7Y~MwBCyoo)C(EW8HWDOHBf?DnZv&m4eXtOkVBbU#HW->qmod!YOA zayg!@9!|UU%&k9+)k?ZE?{+n?bvs#}U&Cg6Hocjy9ypH6>1sBKBD$O}X-tdpay31_ zyBRN??c#2^m`4+y9a8>?Yu2}d7l}mHLgluNpEo@V_wodTZNm~BONHGDW$1MFhe>oO zBG=%M1O1-RQ&K4}W&LaYYPAXIS "${WDHOME}/current_scheme" + # Make current default + echo 'default' > "$(_wd_current_scheme_file)" } +# Stores the current scheme name and writes an empty scheme +# to the current scheme file, which either already exists or +# is created as "default". _wd_create_wdscheme() { - echo "Creating new scheme ${WDSCHEME}" - mkdir -p "${WDHOME}" - _wd_set_stored_scheme - echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_env_scheme_filename)" + if [[ ! -f "$(_wd_stored_scheme_file)" ]] ; then + _wd_create_default_wdscheme + fi + echo "Creating new scheme $(_wd_stored_scheme_name)" + if [[ ! -w "${WDHOME}" ]] ; then + mkdir -p "${WDHOME}" + fi + echo "$(_wd_stored_scheme_name)" > "$(_wd_current_scheme_file)" + echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_stored_scheme_file)" } +# Either duplicate the current scheme to the given scheme name and set it as current, +# or create a new, empty one with the given name. _wd_init_wdscheme() { - if [[ -f "${WDHOME}/current_scheme" ]] ; then - if [[ "$(_wd_stored_scheme_filename)" != "$(_wd_env_scheme_filename)" ]] ; then # we have a diff. scheme stored - echo "Cloning $(_wd_stored_scheme_filename) new scheme ${WDSCHEME}" - cp "$(_wd_stored_scheme_filename)" "$(_wd_env_scheme_filename)" # clone it - _wd_set_stored_scheme + if [[ -f "$(_wd_stored_scheme_file)" ]] ; then + if [[ "$(_wd_stored_scheme_name)" != "$1" ]] ; then # we have a diff. scheme stored + echo "Cloning $(_wd_stored_scheme_name) into new scheme ${1}" + cp "$(_wd_stored_scheme_file)" "${WDHOME}/${1}.scheme" # clone it fi else _wd_create_wdscheme fi } +# Set each non-empty slot into an environment variable with the same number, e.g $WD1 _wd_load_wdenv() { - local slots i index + local slots i index line index=0 while read -r line; do slots[$index]="$line" index=$((index + 1)) - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" for (( i = 0 ; i < 10 ; i++ )); do if [[ "${slots[$i]}" != "." ]] ; then @@ -67,62 +113,60 @@ _wd_load_wdenv() done } -# If there is no valid current scheme, assume 'default' -if [[ ! -f "${WDHOME}/${WDSCHEME}.scheme" || -z "${WDSCHEME}" ]] ; then # we don't have it in the env. - if [[ -f "${WDHOME}/current_scheme" ]] ; then # but we do have it stored - if [[ -f "$(_wd_stored_scheme_filename)" ]] ; then - export WDSCHEME="$(_wd_stored_scheme_name)" # load the stored scheme into the env. - else - _wd_create_wdscheme - fi - else - echo "No scheme set, using 'default'." - export WDSCHEME=default - fi -fi - -if [[ -f "${WDHOME}/current_scheme" ]] ; then - # load current scheme slots - _wd_load_wdenv -else - # Store the scheme file if it's not already there - _wd_init_wdscheme -fi +# Load directory slots from the current scheme +_wd_load_wdenv +# Prints the current scheme or sets it to the given scheme name. +# If no argument is given and no scheme is set, sets the current +# scheme to "default". wdscheme() { + local _temp_wdscheme shell_only if [[ -z "$1" ]] ; then - echo "${WDSCHEME}" + _wd_load_wdenv # refresh env vars + echo "$(_wd_stored_scheme_name)" else - export WDSCHEME="$1" + if [[ "-t" == "$1" ]] ; then + shell_only=1 + shift + fi if [[ -f "${WDHOME}/${1}.scheme" ]] ; then + _temp_wdscheme="$1" + + if [[ -n $shell_only ]] ; then + export WDSCHEME="$1" + else + echo "$1" > $(_wd_current_scheme_file) + fi _wd_load_wdenv - _wd_set_stored_scheme else - _wd_init_wdscheme + _wd_init_wdscheme "$1" fi fi } +# Use the list of scheme files to complete partial scheme names +# TODO: wdschemes with spaces don't appear correctly :( _wd_scheme_completion() { local cur schemedir origdir schemelist origdir="${PWD}" schemedir="${WDHOME}" - COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" - # TODO could probably do this without cd to the scheme dir + COMPREPLY=() cd "${schemedir}" - schemelist="$(compgen -G "${cur}*.scheme")" - COMPREPLY=( ${schemelist//.scheme/} ) + schemelist="$(compgen -o nospace -G "${cur}*.scheme")" + for s in "$schemelist"; do + COMPREPLY+=( ${s//.scheme/} ) + done cd "${origdir}" } complete -o nospace -F _wd_scheme_completion wdscheme -# Function to store directories +# Stores directory slots into the current scheme file wdstore() { - local slot dir slots i index + local dir i index line slot slots if [[ -z "$1" ]] ; then # no slot given so use 0 slot="0" @@ -142,7 +186,7 @@ wdstore() while read -r line; do slots[$index]="$line" index=$((index + 1)) - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" # Store the specified dir into the specified slot slots[$slot]="$dir" @@ -153,7 +197,7 @@ wdstore() else echo "." fi - done > "$(_wd_env_scheme_filename)" + done > "$(_wd_stored_scheme_file)" # Update the alias for the new slot alias "wd${slot}=wdretr ${slot}" @@ -162,9 +206,11 @@ wdstore() export "WD${slot}=${dir}" } +# Changes to the directory stored in the given slot of the current scheme file. +# If no slot is given, changes to the director in slot 0. wdretr() { - local slot slots index + local index line slot slots if [[ -z "$1" ]] ; then slot="0" else @@ -175,38 +221,49 @@ wdretr() while read -r line; do slots[$index]="$line" index=$((index + 1)) - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" if [[ "${slots[$slot]}" != '.' ]] ; then cd "${slots[$slot]}" fi } +# Prints the contents of the slots in the current scheme file. wdl() { - local slots j index + local index line index=0 while read -r line; do if [[ "$line" != "." ]] ; then - echo "${index} $line" + echo "${index} ${line}" else - echo "${index}" + echo "$index" fi index=$((index + 1)) - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" } +# Clears all slots in the current scheme file. wdc() { - echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_env_scheme_filename)" + echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_stored_scheme_file)" _wd_load_wdenv } -alias wds='wdstore 0' -for (( i = 0 ; i < 10 ; i++ )); do - alias "wds${i}=wdstore ${i}" -done +# Make wd and wds aliases in a function to prevent variable leakage +_wd_create_aliases() +{ + local i + # Make store aliases wds[0-9], with the default alias "wds" the same as wds0. + alias wds='wdstore 0' + for (( i = 0 ; i < 10 ; i++ )); do + alias "wds${i}=wdstore ${i}" + done + + # Make cd aliases wd[0-9], with the default alias "wd" the same as wd0. + alias wd='wdretr 0' + for (( i = 0 ; i < 10 ; i++ )); do + alias "wd${i}=wdretr ${i}" + done +} -alias wd='wdretr 0' -for (( i = 0 ; i < 10 ; i++ )); do - alias "wd${i}=wdretr ${i}" -done +_wd_create_aliases \ No newline at end of file diff --git a/wd/wd.zsh b/wd/wd.zsh index 0772db1..23ed170 100644 --- a/wd/wd.zsh +++ b/wd/wd.zsh @@ -8,55 +8,106 @@ if [[ -z "${WDHOME}" ]] ; then echo "Using ${WDHOME} as \$WDHOME." fi -_wd_stored_scheme_name() +# Prints the path to the file that holds the name of the current scheme. +# e.g. "~/.wd/current_scheme" +_wd_current_scheme_file() { - echo $(cat "${WDHOME}/current_scheme") + echo "${WDHOME}/current_scheme" } -_wd_stored_scheme_filename() +# Prints only the name of the current scheme. +# e.g. "project" (not the file path like "~/.wd/project.scheme"). +# This may be temporary--when called from wdscheme, +# or it may come from the current scheme file, +# or it may be unset, in which case we use (and store) "default". +_wd_stored_scheme_name() { - echo "${WDHOME}/$(_wd_stored_scheme_name).scheme" + local scheme + if [[ -n "$_temp_wdscheme" ]] ; then + echo "$_temp_wdscheme" + else + if [[ -n "$WDSCHEME" ]] ; then + echo "$WDSCHEME" + else + if [[ -f "$(_wd_current_scheme_file)" ]] ; then + exec 3< "$(_wd_current_scheme_file)" + read scheme <&3 + echo "$scheme" + exec 3<&- + return + else + _wd_create_default_wdscheme + _wd_stored_scheme_name + fi + fi + fi + unset _temp_wdscheme } -_wd_env_scheme_filename() +# Print the path to the current scheme file, which may be constructed from the +# current scheme. The file is created if it doesn't already exist, and a +# default is used if no name is set. +# e.g. "~/.wd/myscheme.scheme" +_wd_stored_scheme_file() { - echo "${WDHOME}/${WDSCHEME}.scheme" + local name stored_scheme_filename + name="$(_wd_stored_scheme_name)" + stored_scheme_filename="${WDHOME}/${name}.scheme" + if [[ -f "$stored_scheme_filename" ]] ; then + + echo "${stored_scheme_filename}" + else + _wd_create_wdscheme + _wd_stored_scheme_file + fi } -_wd_set_stored_scheme() +# Stores "default" as the current scheme. +_wd_create_default_wdscheme() { - echo "${WDSCHEME}" > "${WDHOME}/current_scheme" + # Make current default + echo 'default' > "$(_wd_current_scheme_file)" } +# Stores the current scheme name and writes an empty scheme +# to the current scheme file, which either already exists or +# is created as "default". _wd_create_wdscheme() { - echo "Creating new scheme ${WDSCHEME}" - mkdir -p "${WDHOME}" - _wd_set_stored_scheme - echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_env_scheme_filename)" + if [[ ! -f "$(_wd_stored_scheme_file)" ]] ; then + _wd_create_default_wdscheme + fi + echo "Creating new scheme $(_wd_stored_scheme_name)" + if [[ ! -w "${WDHOME}" ]] ; then + mkdir -p "${WDHOME}" + fi + echo "$(_wd_stored_scheme_name)" > "$(_wd_current_scheme_file)" + echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_stored_scheme_file)" } +# Either duplicate the current scheme to the given scheme name and set it as current, +# or create a new, empty one with the given name. _wd_init_wdscheme() { - if [[ -f "${WDHOME}/current_scheme" ]] ; then - if [[ "$(_wd_stored_scheme_filename)" != "$(_wd_env_scheme_filename)" ]] ; then # we have a diff. scheme stored - echo "Cloning $(_wd_stored_scheme_filename) new scheme ${WDSCHEME}" - cp "$(_wd_stored_scheme_filename)" "$(_wd_env_scheme_filename)" # clone it - _wd_set_stored_scheme + if [[ -f "$(_wd_stored_scheme_file)" ]] ; then + if [[ "$(_wd_stored_scheme_name)" != "$1" ]] ; then # we have a diff. scheme stored + echo "Cloning $(_wd_stored_scheme_name) into new scheme ${1}" + cp "$(_wd_stored_scheme_file)" "${WDHOME}/${1}.scheme" # clone it fi else _wd_create_wdscheme fi } +# Set each non-empty slot into an environment variable with the same number, e.g $WD1 _wd_load_wdenv() { setopt ksh_arrays - local i + local i line typeset -a slots while read -r line; do slots+=("$line") - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" for i in {0..9}; do if [[ "${slots[$i]}" != "." ]] ; then @@ -68,51 +119,48 @@ _wd_load_wdenv() unsetopt ksh_arrays } -# If there is no valid current scheme, assume 'default' -if [[ ! -f "${WDHOME}/${WDSCHEME}.scheme" || -z "${WDSCHEME}" ]] ; then # we don't have it in the env. - if [[ -f "${WDHOME}/current_scheme" ]] ; then # but we do have it stored - if [[ -f "$(_wd_stored_scheme_filename)" ]] ; then - export WDSCHEME="$(_wd_stored_scheme_name)" # load the stored scheme into the env. - else - _wd_create_wdscheme - fi - else - echo "No scheme set, using 'default'." - export WDSCHEME=default - fi -fi - -if [[ -f "${WDHOME}/current_scheme" ]] ; then - # load current scheme slots - _wd_load_wdenv -else - # Store the scheme file if it's not already there - _wd_init_wdscheme -fi +# Load directory slots from the current scheme +_wd_load_wdenv +# Prints the current scheme or sets it to the given scheme name. +# If no argument is given and no scheme is set, sets the current +# scheme to "default". wdscheme() { + local _temp_wdscheme shell_only if [[ -z "$1" ]] ; then - echo "${WDSCHEME}" + _wd_load_wdenv # refresh env vars + echo "$(_wd_stored_scheme_name)" else - export WDSCHEME="$1" + if [[ "-t" == "$1" ]] ; then + shell_only=1 + shift + fi + if [[ -f "${WDHOME}/${1}.scheme" ]] ; then + _temp_wdscheme="$1" + + if [[ -n $shell_only ]] ; then + export WDSCHEME="$1" + else + echo "$1" > $(_wd_current_scheme_file) + fi _wd_load_wdenv - _wd_set_stored_scheme else - _wd_init_wdscheme + _wd_init_wdscheme "$1" fi fi } +# Use the list of scheme files to complete partial scheme names +# TODO: wdschmes can't have spaces for now _wd_scheme_completion() { local cur schemedir origdir schemelist origdir="${PWD}" schemedir="${WDHOME}" - COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" - # TODO could probably do this without cd to the scheme dir + COMPREPLY=() cd "${schemedir}" schemelist="$(compgen -G "${cur}*.scheme")" COMPREPLY=( ${schemelist//.scheme/} ) @@ -120,14 +168,14 @@ _wd_scheme_completion() } complete -o nospace -F _wd_scheme_completion wdscheme -# Function to store directories +# Stores directory slots into the current scheme file wdstore() { setopt ksh_arrays - local slot dir i + local dir i line slot typeset -a slots if [[ -z "$1" ]] ; then - # must be trying to store into slot 0 + # no slot given so use 0 slot="0" else slot="$1" @@ -143,7 +191,7 @@ wdstore() # Read the existing slots from the scheme file while read -r line; do slots+=("$line") - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" # Store the specified dir into the specified slot slots[$slot]="$dir" @@ -154,7 +202,7 @@ wdstore() else echo "." fi - done > "$(_wd_env_scheme_filename)" + done > "$(_wd_stored_scheme_file)" # Update the alias for the new slot alias "wd${slot}=wdretr ${slot}" @@ -164,53 +212,66 @@ wdstore() unsetopt ksh_arrays } +# Changes to the directory stored in the given slot of the current scheme file. +# If no slot is given, changes to the director in slot 0. wdretr() { setopt ksh_arrays - local slot + local line slot typeset -a slots if [[ -z "$1" ]] ; then slot="0" else slot="$1" fi + while read -r line; do slots+=("$line") - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" if [[ "${slots[$slot]}" != '.' ]] ; then cd "${slots[$slot]}" fi unsetopt ksh_arrays } +# Prints the contents of the slots in the current scheme file. wdl() { - local index + local index line index=0 while read -r line; do if [[ "$line" != "." ]] ; then - echo "${index} $line" + echo "${index} ${line}" else - echo "${index}" + echo "$index" fi index=$((index + 1)) - done < "$(_wd_env_scheme_filename)" + done < "$(_wd_stored_scheme_file)" } +# Clears all slots in the current scheme file. wdc() { - echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_env_scheme_filename)" + echo -e ".\n.\n.\n.\n.\n.\n.\n.\n.\n.\n" > "$(_wd_stored_scheme_file)" _wd_load_wdenv } -alias wds='wdstore 0' -for i in {0..9}; do - alias "wds${i}=wdstore ${i}" -done +# Make wd and wds aliases in a function to prevent variable leakage +_wd_create_aliases() +{ + local i + # Make store aliases wds[0-9], with the default alias "wds" the same as wds0. + alias wds='wdstore 0' + for i in {0..9}; do + alias "wds${i}=wdstore ${i}" + done -alias wd='wdretr 0' -for i in {0..9}; do - alias "wd${i}=wdretr ${i}" -done + # Make cd aliases wd[0-9], with the default alias "wd" the same as wd0. + alias wd='wdretr 0' + for i in {0..9}; do + alias "wd${i}=wdretr ${i}" + done +} +_wd_create_aliases unsetopt ksh_arrays \ No newline at end of file