{"id":19866367,"url":"https://github.com/emilyst/home","last_synced_at":"2025-12-18T03:27:53.925Z","repository":{"id":20226882,"uuid":"23498717","full_name":"emilyst/home","owner":"emilyst","description":"My home directory's settings","archived":false,"fork":false,"pushed_at":"2024-05-15T17:27:35.000Z","size":11099,"stargazers_count":89,"open_issues_count":0,"forks_count":6,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-06-08T11:32:41.995Z","etag":null,"topics":["vim-configuration","zshrc"],"latest_commit_sha":null,"homepage":null,"language":"Vim Script","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emilyst.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-08-30T19:06:15.000Z","updated_at":"2024-06-01T21:54:50.000Z","dependencies_parsed_at":"2024-05-16T06:01:30.552Z","dependency_job_id":null,"html_url":"https://github.com/emilyst/home","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilyst%2Fhome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilyst%2Fhome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilyst%2Fhome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emilyst%2Fhome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emilyst","download_url":"https://codeload.github.com/emilyst/home/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224298971,"owners_count":17288457,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["vim-configuration","zshrc"],"created_at":"2024-11-12T15:25:36.539Z","updated_at":"2025-12-18T03:27:53.844Z","avatar_url":"https://github.com/emilyst.png","language":"Vim Script","funding_links":[],"categories":["Vim Script"],"sub_categories":[],"readme":"Home\n====\n\nThis repository contains configuration meant for use on my Linux or\nmacOS computers. Often, these are called \"dot files\" in casual use\nbecause the filenames and directory names begin with a leading dot,\nwhich hides them from view on those operating systems. That makes them\nconvenient for configuration.\n\nIf you're reading this on a file system, you're seeing the only\nnon-hidden portion of a source-controlled set of configuration files\ndesigned for use on Linux and macOS. The canonical version is hosted at\n[GitHub](https://github.com/emilyst/home). (See the [notes](#notes) on\nhow to hide this file, too.)\n\nI have a few custom approaches regarding how I set up, use, and maintain\nthis repository, which I'll describe here. This is necessary because\nturning your home directory into a giant Git repository is very weird\nand not recommended under most circumstances. The techniques I describe\nbelow help mitigate that weirdness.\n\nNote that this repository contains _configuration_, not setup itself.\nNothing here is meant to take over and act decisively of its own accord.\nIt does not install things. It does not change global system settings.\nThat is left for me, as a user, to do. It merely configures relevant\nprograms if they exist.\n\nOne last thing: I'm describing how I set up and use this not so that you\ncan use my home repository as is. It's personal to me, meets my specific\nneeds, and comes with no guarantees whatsoever. What's right for me is\nalmost certainly not right for anyone else. However, if you want to know\nhow my setup works and accomplish a similar setup for yourself, read on.\n\n\nSetup\n-----\n\nTo set up, `git-clone(1)` is not recommended. The home directory already\nexists, so we don't need to create a new working tree, which\n`git-clone(1)` would do. An unqualified `git clone` would also set up\nthe default Git directory. I don't want either of those things to\nhappen.\n\nInstead, I treat my home directory as an existing working tree to\ninitialize with `git-init(1)`. I also use a non-default Git directory\nwhich won't be found by Git automatically. This will prevent most\ntooling from seeing my home directory as a repository under most\ncircumstances.\n\nTo do this, I explicitly set the Git directory and the Git working tree\nfor all Git commands which manipulate the home repository. I use an\nalias which conveniently sets all these. I call it `home`, simply\nenough. The `home` alias can be used in place of the `git` command to\nmanage my home directory configuration.\n\n    alias home=\"git --work-tree=$HOME --git-dir=$HOME/.home.git\"\n\nNote that this sets the Git directory under \"`$HOME/.home.git`\" instead\nof \"`$HOME/.git`.\" That effectively both hides the Git configuration\nfrom both its own tooling (unless the `home` alias is used) and from\nnormal directory listings. Another very neat thing about this alias is\nthat it will refer to the home repository, no matter which directory is\nthe current one, even if I'm in another Git repository at the time.\n\nWith this in mind, let's see how a first-time setup works using a recent\nversion of Git. Assume first that Git is installed and that SSH auth to\nGitHub is established. Then, I run the following.\n\n    alias home=\"git --work-tree=$HOME --git-dir=$HOME/.home.git\"\n    home init\n    home remote add origin https://github.com/emilyst/home.git\n    home fetch --all\n    home reset --hard origin/master\n    home submodule update --init --rebase\n\nAfterwards, always use the `home` alias to interact with the home\nrepository. (This alias is configured for Zsh by my current\nconfiguration.) Local \"master\" tracks \"origin/master\" automatically\nduring this setup, thanks to recent versions of Git.\n\n\nLayout and Editing\n------------------\n\nAll files and directories are ignored by default so that I only version\nthe few files which matter to me. This is done using a sneaky trick:\na special \"`.gitignore.home`\" file which lives in my home repository\nthat doesn't get used unless the current Git directory is the one for\nthe home repository. I wanted to avoid having a file named\n\"`.gitignore`\" in my home directory which excludes everything because\nGit and certain other tools will look for it.\n\nTo pull this off, first, I added a configuration stanza to the _bottom_\nof [my global Git configuration](.gitconfig) like the following.\n\n    [includeIf \"gitdir:~/.home.git\"]\n    \tpath = .gitconfig.home\n\nThat file [only gets included if the current Git directory\nmatches](https://www.git-scm.com/docs/git-config#_conditional_includes).\nThen, [in that included configuration file](.gitconfig.home), I can set\na new `core.excludesFile` setting which overrides the original (which is\nwhy it has to be at the bottom).\n\n    [core]\n    \texcludesfile = ~/.gitignore.home\n\nFinally, [.gitignore.home](.gitignore.home) is configured to exclude\neverything by containing a single wildcard.\n\nThe reason for all this conditional inclusion rigmarole is for the same\nreason I use a custom Git directory—so that no naive tooling goes\nrecursing up the directory tree looking for items to ignore and uses\nthat file by mistake.\n\nBecause the home repository ignores _everything_, any added file or\ndirectory I want to track in my home repository needs to be added\nforcefully: e.g., `home add -f \u003cpath/to/file\u003e`. (Any empty directory\nneeds to contain a `.gitignore` file to be added, as usual.)\n\nAs a result, the repository can live directly in the home directory and\nignore everything by default. Because it uses a custom Git directory,\nthere's no need to use symbolic linking or copying. It can coexist\nalongside anything else that lives in `$HOME`, and Git ignores anything\nI haven't explicitly told it to track. The only updates it sees are\nchanges to the files which it does track, which can be committed\nnormally (e.g., using `home commit -av` or similar). If I want to track\nsomething new, I can add it explicitly as I've described above.\n\n\n### Submodules ###\n\nSee [submodules](#submodules-1) for more about submodules in general and\nwhy I use them.\n\nMost of my submodules are Vim plugins, and currently, I install them as\npackages to [`$HOME/.vim/pack/default`](.vim/pack/default). At the same\ntime, I also add a relative symbolic link from the package directory to\nthe [`$HOME/.vim/pack/default/start`](.vim/pack/default/start)\ndirectory.\n\nOther submodules go where appropriate, usually in a hidden place if\nI can manage. See [submodules](#submodules-1) below for more information\non setup.\n\n\n### Local Hierarchy ###\n\nThere is an entire local Unix-like hierarchy under\n[`$HOME/.local`](.local). It is complete enough that I can install most\nprograms to that directory by running `./configure\n--prefix=\"$HOME/.local\"`, provided the program uses GNU [autoconf].\n\nMost of those directories stay empty and stay in the home repository\nonly so that they will exist for this purpose. However, a couple are\npopulated with things I want to exist on any computer and which are\nmachine-independent. For example, there are some scripts in\n[`$HOME/.local/bin`](.local/bin), and there is a Vim/Common Lisp\nsubmodule under [`$HOME/.local/share`](.local/share).\n\nFor more about the Unix hierarchy, see the `hier(7)` manual page\n(particularly the \"`/usr`\" section).\n\n\nUpdating\n--------\n\nPushing up updates to GitHub is not difficult.\n\n    home push\n\nWhen I pull them down, I also run a command which pulls down any\n[submodule](#submodules-1) updates I've pushed up previously. The\ncommand I use will discover which commit I've updated that submodule to,\nand then it will rebase the submodule's current branch onto that commit.\n(This prevents each submodule from being in a \"detached HEAD\" state at\nall times so that I can work inside that submodule like a normal Git\nrepository more easily.)\n\n    home pull \u0026\u0026 home submodule update --init --rebase\n\nIn my [`$HOME/.gitconfig`](.gitconfig), there is an alias that sets\n`supdate` to do that awkward submodule command, so the command actually\nlooks like this when I type it.\n\n    home pull \u0026\u0026 home supdate\n\n\nSubmodules\n----------\n\nIn several cases, my home directory includes the entirety of a project\nfrom elsewhere. Many of my Vim plugins are included this way since they\nhave their own Git repositories on GitHub. Therefore, I add them to the\nhome repository as [submodules], allowing me to incorporate those\nrepositories into my own, yet keeping them and their histories distinct.\n\nThere is a little complexity involved. I have to check the submodules\nfor updates and commit those updates to my home repository on a regular\nbasis. When updates have been added in one place, I need to pull down\nthe updates in another place.\n\nAt the same time, though, there are advantages. Updates aren't\nautomatic: I opt into them. I know what each update is, and\nI incorporate it intentionally into the home repository. I can _undo_\nany update. Finally, I can track down an update to a submodule which\naffected my configuration deleteriously using `git-bisect(1)`.\n\nAdding a new submodule also has to be forced, due to the global ignore\nrules. I always do this with relative paths.\n\n    home submodule add -f \u003crepository\u003e \u003crelative/path/to/destination\u003e\n\nIf I have added a Vim package, I clone it into\n[`$HOME/.vim/pack/default`](.vim/pack/default), and then from\n[`$HOME/.vim/pack/default/start`](.vim/pack/default/start),\nI symbolically link from the package directory to the current directory\n(relatively). That allows adding and removing packages from the current\nVim configuration temporarily by moving the symbolic links only.\n\nOccasionally (perhaps once or twice a week), I update all the submodules\nto ensure I have the latest versions.\n\n    home submodule update --init --remote --rebase\n\nI have this sub-command aliased to `supgrade` for easier use.\n\n    home supgrade\n\nAfter doing that, I need to commit whatever submodule pointers have been\nupdated.\n\n    home commit -av\n\nUsually I'll call this commit \"Submodule updates\" and list the\nsubmodules which were updated in the description. This is all sort of\nmore manual than a plugin manager, but it allows me to bisect my\nconfiguration, in case a submodule changes radically out from under me.\n\nRemoving a submodule is rather awkward. In theory, it's possible in\nrecent versions of Git merely to `rm` them.\n\n    home rm \u003cpath/to/submodule\u003e\n\nThen that change can be committed.\n\n    home commit -av\n\nHowever, I also often make sure the actual files have themselves been\ncleared out. This may also need to be repeated when the update which\ncommit which removes the submodule is applied on another computer.\n\nThis command also leaves the Git directory for the submodule behind, and\nit can leave configuration behind as well. Sometimes I'll delete these\nas well. Configuration for a submodule lives in `.home.git/config`,\n_not_ under the submodule directory itself (which normally only contains\na text file called \"`.git`\" which contains the path to that\nconfiguration). That means I use commands like these to clean up.\n\n    rm -rf \u003cpath/to/submodule\u003e\n    rm -rf $HOME/.home.git/modules/\u003cpath/to/submodule\u003e\n\nThis is just extra cleanup that's often not needed but sometimes can\nhelp if you add another submodule with the same name or just want to\nreclaim the space (or peace of mind).\n\nWhen pulling down updates to a computer after deleting a submodule on\nanother one, I will do those latter steps because I'm not always\nconfident the `git-submodule(1)` update will clear out what needs to be\ncleared.\n\n\nNotes\n-----\n\nBelow are a few additional notes on the process.\n\n\n### Hiding the README on macOS ###\n\nThe README can be hidden, too, on macOS—from view in Finder, at least.\nTo do so, run a command to change its \"hidden\" flag.\n\n    chflags hidden $HOME/README.md\n\nThis will tidy up your view of your home directory in Finder. The file\nstill exists, and it's visible in any directory listing (even one that\ndoesn't show hidden files, unfortunately), but it will otherwise be out\nof the way.\n\n\nLicense\n-------\n\nI hereby license any _original_ work in this repository into the public\ndomain under the Creative Commons CC0 license. To view a copy of this\nlicense, visit https://creativecommons.org/publicdomain/zero/1.0/ or\nsend a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042,\nUSA.\n\nNote that I cannot relicense any anything which is not my own, original\nwork (including but not limited to submodules).\n\n\n[autoconf]: https://www.gnu.org/software/autoconf/\n[submodules]: https://git-scm.com/book/en/v2/Git-Tools-Submodules\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femilyst%2Fhome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femilyst%2Fhome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femilyst%2Fhome/lists"}