Dotfile madness (2019)
0x46.net
0x46.net
Please don't. Include the example configuration in your docs (/usr/share/PROG..) and mention it in the manual. Statistically user will have hundreds of apps installed but will only ever customize a small fraction them. So creating config unconditionally on first run is one of the worst contributors to homedir pollution.
Another argument is version upgrades: if you create configur on first run, you forever bake in the set of options present in that version. If later a new option is added, user will have no idea about it.
It's much better to just have a sane implicit default value for each setting when config is not present. Then you can list the default config in your docs or offer a CLI flag --print-default-config or --copy-default-config.
Windows has `%APPDATA%` and `%LOCALAPPDATA%` that are accessible with `ShGetKnownFolderPath`[0], using the appropriate `KNOWNFOLDERID`[1]; all programs should put their configuration and cache data in these paths.
Windows also doesn't know what the dot at the beginning of a file/folder means. Instead, it and NTFS have something that's arguably better: a hidden file attribute `FILE_ATTRIBUTE_HIDDEN`[2], that's again settable/gettable when a file/directory is created or polled, rather than regex-ing for a full-stop.
The worst irony is Microsoft software creating dot-files and dot-dirs on Windows[3][4][5].
[0]: https://learn.microsoft.com/en-us/windows/win32/api/shlobj_c...
[1]: https://learn.microsoft.com/en-us/windows/win32/shell/knownf...
[2]: https://learn.microsoft.com/en-gb/windows/win32/api/fileapi/...
[3]: https://github.com/dotnet/sdk/issues/8678
[4]: https://github.com/OmniSharp/omnisharp-roslyn/issues/953
There are many ways to access the filesystem on Windows. CMD.exe and PowerShell respect `..` to go to the parent directory, as does MSVC C++17 with `std::filesystem`, and .NET, with `System.IO.Path.Combine(String, String)`.
In PowerShell and .NET, there's also the `System.IO.DirectoryInfo.Parent` property, and of course, the equivalent `std::filesystem::path::parent_path` in MSVC C++.
At least in case of std::filesystem, everything in std::filesystem::path is purely lexical. So, to get actual parent of some path, you'll need to go through std::filesystem::directory_entry and std::filesystem::read_symlink().
--
E.g. on Windows: "path\to\..\file" is always the equivalent of "path\file". Whereas on unixy systems "path/to/../file" may take you to a completely different parent directory.
That said, Unix shells can muddy the waters a bit. They may choose to act lexically with some commands.
Worth noting here that Plan 9 is using lexical names[1], and the Go standard library offers the function path.Clean[2] to achieve similar results. If your language/library/OS doesn't offer this behavior by default, it's likely a good idea to add/reimplement this function, unless you need bug-for-bug compatibility.
[1]: https://web.archive.org/web/20220824070659/https://9p.io/sys...
Unless an app uses \\?\ prefixes and special API for navigation, which is rare, ime.
Environment.GetFolderPath( SpecialFolder.LocalApplicationData)
in Windows this maps to ~/AppData/Local
An in Linux to ~/.local/share
so it is configured wellSoftware should ideally adhere to OS norms. Better still, software shouldn't be opaque about where global/user-specific cache/config data is stored, and should prompt users to choose (or set sane defaults, again adhering to OS norms).
IMO the video game industry is a big offender of home-folder pollution, with saves and configs being splattered all over %USERPROFILE%\Documents, %USERPROFILE%\My Documents\ (which is a legacy holdover from Windows XP), %USERPROFILE%\Saved Games (which does have a corresponding KNOWNFOLDERID), etc etc.
Right now the offenders in my $HOME not following $XDG are games, LibreWolf via Mozilla, Xmonad, GnuPG, and anything related to npm (with their maintainers closing any issued opened about support $XDG).
I recognize this is probably because I first learned about config files on a Unixy system, it's not the "native way" for Windows, and other people have stronger cases for their preference, but this is my preference and I'm stickin to it :)
When in Rome, do as the Romans do.
Yeah, but then again, when you visit Rome for a short vacation as a tourist, the English versions of menus and such help, no?
Just saying, some degree of consideration for non-natives is a good thing, as it will help the tourism business generate more revenue. Same for OSes: give me at least an option of staying with my old habits until I get used to the new ones, then there's a higher chance I'll switch.
That is impossible because in Linux there is no drive letters and you cannot have the same path to a file as in Windows.
People aren't obligated to "comply" with the XDG specification either. It's not a bug to just use $HOME.
There is a difference between being cross-platform, and being Linux but mangling it so it technically works on other platforms.
https://stackoverflow.com/a/42700844/512904
> being Linux but mangling it so it technically works on other platforms
Sounds like the easiest way to solve this problem. I don't blame or shame developers for choosing it.
This is simple and works everywhere:
char * home = getenv("USERPROFILE");
if (home) {
// Use home directory
}
The answer demonstrating the Windows API way has the following code to accomplish the same thing: WCHAR profilePath[MAX_PATH];
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, profilePath);
if (SUCCEEDED(result)) {
// Use home directory
}
Yeah, I seriously doubt open source developers want to deal with this Windows bullshit. I sure don't. Maybe if you're getting paid.Just because you aren't used to it doesn't mean it's 'bullshit'. Might I provide a counterexample to the 'simplicity' of Linux? Developing video games natively on Linux is such a pain point that the industry has standardised around simply translating Windows syscalls and Direct3D shaders to their Linux equivalents, because the latter is so heavily fragmented to develop natively for. Also known as Proton.
Honestly I don't even disagree with you. I think POSIX sucks. I think even the libc sucks. However there is no way you can look at the Windows API mess above and think it's somehow better than the portable and clean getenv function call. Maybe you can "get used" to that cruft but I can't. If I had to deal with code like that the first thing I'd do is abstract it away so I don't have to deal with it anymore. That's exactly how Windows is and should be treated by everyone.
Video games, your counter example, are probably the most platform-specific software imaginable. There's a reason pretty much everybody uses an engine these days. There is no way you can compare that stuff to getting a user's home directory and writing files in there.
Also, for video games it ultimately doesn't matter how sucky the APIs are since it's all about market share anyway and people will use whatever they need to get it done. First parties don't put in effort into porting games to Linux because they don't see the money. Valve puts in effort because it gives them their own platform that they control and therefore leverage over Microsoft and its app store. Emulation and compatibility layers are a proven solution when first parties aren't playing ball. If they don't want to make it work on Linux, people will make it work whether they want it or not.
Also, you're comparing something it makes zero sense to compare. People are not saying 'you need to fetch $USERPROFILE without calling getenv'. People are saying 'you need to not store random garbage in $USERPROFILE'. Calling getenv("APPDATA") is a perfectly fine way of fetching FOLDERID_RoamingAppData, the same way you weren't going to bother calling getpwuid if $HOME was undefined.
It's just some example code. Real code will probably try a number of variables.
> Calling getenv("APPDATA") is a perfectly fine way of fetching FOLDERID_RoamingAppData
Okay then. Top level post said you needed a Win32 function for this. If you can do that without those functions, I suppose it's easy enough to support.
> calling getpwuid if $HOME was undefined
$HOME is set by login and ssh to whatever is in the passwd database. Can it ever be undefined? Seems like something is seriously wrong if it is.
int writeConfigFile(ConfigFile file) {
#if defined(_WIN32)
// Windows-specific function
#elif defined(__linux__)
// Linux-specific function
#elif defined(__APPLE__)
// macOS-specific function
With modern C++, there's probably a way to do this in a nicer manner, and achieve runtime polymorphism with virtual functions or a lambda (function pointer) table.As another sibling commenter wrote, .NET already has a platform-agnostic function to write to a `user program data` folder that nicely maps to the platform-specific directories. Other GC languages (Java, Go, etc) likely have similar abstractions.
As for scripting... A cross-platform project with scripts that also targets Windows should (in my opinion) have PowerShell `.ps1` scripts accompanying any `.sh` scripts. Better still, scripting should be done in a language that's truly platform-agnostic, like Python.
You proved my point. Creating an #ifdef mess with polymorphism, virtual methods and indirection is the very definition of going out of one's way to support something that really doesn't need any support.
This is just part of the cost of developing cross-platform, and I'm sorry, but to me, dismissing this as 'going out of one's way' is just being sloppy.
I felt a great disturbance in the source, as if hundreds of BSD users suddenly cried out in terror and were suddenly silenced.
I initially did think of simply letting the build system handle it (CMake can do this excellently, as can Meson, probably) by simply choosing different source files for different target OSs, but when typing out the parent comment, I forgot about it in my train of thought.
Come to think of it, this is far more elegant.
Linux doesn't hide anything. It's POSIX and GNU programs that choose not show anything that starts with a dot by default. As far as Linux is concerned they're just normal files on the file system.
It doesn't have to be that way. Personally I have my system configured so that all "hidden" files are shown because I hate the concept of hidden anything. I used to do this in Windows too.
> The specific functionality being used does not 'work just fine everywhere'.
It kind of does. "Program reads configuration from a file" seems like a really basic thing that every operating system supports. There really is no need to directly depend on any Windows API stuff. Even worse would be suggesting the use of the registry.
> It is not the case that Linux functionality is How Computing Works with every deviation being 'out of the way', not even in a hypothetical world where Linux isn't the drastic minority of machines by an order of magnitude.
And yet Windows is the system getting "half-baked ports of Unix-first software" here. Why should the developers be shamed for not going of their way to support Windows conventions for Unix software?
People develop software on and for the systems they actually care about. Windows is the legacy proprietary system people only support because it gets them paid. At least I hope someone got paid to port ssh to Windows because I sure wouldn't want to do it otherwise.
I would actually argue otherwise: the registry is the perfect place to put configuration data, provided Microsoft's guidelines[0] on registry key creation/deletion and hive use are followed. I would argue every OS should have its own 'registry' for a universal location to set configuration for programs.
On the other hand, if every application has its own configuration file, then every application shall have its own configuration file parsing/serialising/deserialising routine. It's also what has led to this explosion of 'config file formats': .json, .yaml, .ini, .conf, .cfg, .toml, .xml.
I guess this is why people dislike systemd so much: it reminds them too much of Windows.
[0]: https://learn.microsoft.com/en-us/windows/win32/sysinfo/regi...
You appear to have an attitude of UNIX/Linux > Windows, which is unfortunate. The two OS families are different, but I personally believe neither is superior to the other. Both OSs suck in their own ways, both OSs are better in their own ways (this conclusion after using Windows and Linux both on a 70:30 time ratio).
Windows is in every way as modern an OS as Linux is, but just like Linux, has inherited strange baggage from its 40-year-old past, like 'a file cannot have COM in its name'.
Few people follow that stuff. I wouldn't be surprised if Microsoft's own people didn't follow that stuff. The result is of course a mess that users have to clean up with software like CCleaner or whatever people use these days.
It sucks even if those guidelines are followed. Configuration is data and belongs to the users. I know people who really like portable applications that they can keep on a USB drive and use anywhere and this registry bullshit breaks that.
> I would argue every OS should have its own 'registry' for a universal location to set configuration for programs.
And I would argue otherwise. The Windows registry is essentially a poor excuse for a proper file system. I think at least one Linux desktop environment tried to reinvent this crap and it sucked just as hard.
> every application shall have its own configuration file parsing/serialising/deserialising routine
The Windows registry values are essentially memory dumps of C types. It's perfectly possible to simply dump raw bytes into binary files on Linux too if you don't care about stuff like endianness. The result would be strictly superior to the Windows registry because the files are being stored in a real file system.
> I guess this is why people dislike systemd so much: it reminds them too much of Windows.
I like systemd.
Windows is the system everyone actually uses - even developers!. I write software because I care about people using it.
> Why should the developers be shamed for not going of their way to support Windows conventions for Unix software?
Because it's wrong on Unix, and even wrong on Linux, and once you are doing the right thing on Linux it is no longer out of your way.
Btw, many native, no-linux windows apps, including Microsoft ones love to create their bs folders like “My Games”, “Microsoft Visual Studio (c)(tm) <yearname> Pile of Whatever” or “Android Projects” right in ~/Documents. This “way” is unenforceable even in OS’es own company.
For example the folder might look empty but in fact it could contain thousands of hidden files. You want to delete it as it is empty but accidentally delete important system files.
Even worse, imagine if all files on an USB drive are marked as hidden. You see that the drive is empty but when you attempt to copy something to it see a message that there is no free space.
One more example. Imagine if you have a project and want to edit an .env file. But as dotfiles are hidden in Linux you don't see this file and cannot open it. It turns out that Windows Explorer which doesn't hide dotfiles is much better for developing projects with Docker!
There should be no hidden files. We cannot do anything with Windows and their MS-DOS legacy but Linux could stop hiding dotfiles in GUI and CLI commands.
The standard Unix folders (usr, var, etc) are also hidden—to be honest, this is a compromise because the Unix filesystem hierarchy sucks, but we are saddled with it for backwards compatibility reasons.
I did appreciate the relative clarity of old macOS systems—everything in the OS was in “System Folder”, the rest of the filesystem was yours, and you could freely move applications without breaking anything, uninstall them by putting them in the trash, etc.
There is no need to hide such files. Just display them as system files in Explorer.
> The standard Unix folders (usr, var, etc) are also hidden
Again there is no need to do it. Just move them to a directory named "System files".
Thumbnail caches are not stored on USB drives, they’re stored somewhere else, away from your files.
By the way, I'm pondering setting my XDG_*_HOME vars on Linux/BSD to use the macOS paths like ~/Library, just to see if the standard is actually being followed.
If a user doesn't know what .ssh/ or .bash_history are, and it can hurt them to accidentally delete or modify them, why show them by default? It's like training wheels on a bike.
>For example the folder might look empty but in fact it could contain thousands of hidden files. You want to delete it as it is empty but accidentally delete important system files.
If it is possible for a regular user to accidentally brick a system like this, it was doomed to begin with. If a user doesn't know what a dotfile is they shouldn't have administrative privileges, and if they do get them there is no safeguard to stop them destroying the system. It's not a dotfile issue.
>Imagine if you have a project and want to edit an .env file. But as dotfiles are hidden in Linux you don't see this file and cannot open it. It turns out that Windows Explorer which doesn't hide dotfiles is much better for developing projects with Docker!
In what reality is someone developing software and building Docker containers who doesn't understand the concept of hidden files? Seems awfully contrived.
This is really the problem with the home directory. It’s supposed to be the place where the user puts their files, but it’s also a place where applications put their files, usually without asking the user.
The battle is lost - the home directory territory should be ceded to applications and the user should have a separate space in which to manage their files.
This can sort of be achieved with the $XDG_CONFIG_HOME environment variable, but not all software respects it, so in practical terms it’s a lot easier just to leave $HOME to be the application config dumping ground.
Because they are there. To prevent accidental deletion you can show an icon with a skull and crossbones or name a directory "configuration files" so that it is obvious what's in there.
> if they do get them there is no safeguard to stop them destroying the system
If the folder are named or labeled as "operating system" then the user will probably understand that it is better not to mess with it.
> In what reality is someone developing software and building Docker containers who doesn't understand the concept of hidden files?
Hiding hidden files is annoying because you have to add -a to ls command, have to add an option in Bash to include then when matching against a star pattern and to configure Explorer so that it shows them. It would be easier without them.
This will make users more likely to delete it thinking it's a virus.
> If the folder are named or labeled as "operating system" then the user will probably understand that it is better not to mess with it.
Big assumption that most people know what an operating system is.
Have you ever heard of aliases?
You have permissions to prevent from accidental deletions.
By default, Explorer hides hidden files (and goes one step further and doesn't display file extensions: why???), so do Finder, Dolphin, Nautilus, and even `ls` by default.
file extensions are the mistake here really not them being hidden.
> One more example. Imagine if you have a project and want to edit an .env file. But as dotfiles are hidden in Linux you don't see this file and cannot open it.
How likely is it that someone is going to want to edit a .env file and not know how to view hidden files?
Well then configuration files can simply not be in the same directory as your files. Easy fix.
But they don't need to be hidden by being special, they can just be "hidden" by living in a subdirectory that you don't look inside.
Of course, it doesn't help just to complain about the issue in a void, so I've also submitted like 10 PRs and filed quite a few issues. Projects like pnpm and Poetry took note, and now they comply!
Someone's gotta clean up house, and I don't mind doing the dirty work.
Exa is the latest, trendy ls alternative.
I don’t think you should remove the Exa example but you certainly should show how to use ls to do something similar for those people still living in the dark ages—ls was created in the 1970s and it hasn’t kept up with the times all that well [1].
I created an ‘ll’ alias for Exa using the Fish shell; obviously you make shell-appropriate aliases in Bash or Z shell:
function ll
exa --color always --long --no-user --no-permissions --all --icons $argv
end
[1]: https://the.exa.website/introductionNo need to have a rosetta stone of alternatives to demonstrate an illustrative example where the basic tool that everybody already knows and understands at a glance works.
I'm not saying that exa, or fish, or ripgrep, or any other trendy tool is bad.
Admittedly, the ~/.bashrc etc. files should be there too - but I wanted it to look cleaner :P
You should fix this. While macOS and its system applications and bundled applications don't adhere to the XDG Base Directory Specification; many programs that run on macOS do.
In fact, almost all of the programs you list run on macOS and (by definition) use the XDG Base Directory Specification. So I would clean that up to not give an incomplete statement.
BTW, the macOS directory structure [1] has been documented since macOS (MacOS X back in the day) shipped in 2001.
[1]: https://developer.apple.com/library/archive/documentation/Fi...
Is there an exact phrasing you would prefer?
The classic Unix utilities and apps typically use $HOME on macOS, while their modern, often Rust-based replacements—WezTerm, Exa, fd, broot, Fish, etc.—use XDG.
Vim uses ~/.vimrc while Neovim uses XDG.
I.e. if it's empty, or if the first character is not a forward slash, then use the default?
Dotfile madness - https://news.ycombinator.com/item?id=19063727 - Feb 2019 (514 comments)
However, this particular topic on this particular message board is about dotfiles and the alternatives.
Dotfiles are a clumsy mechanism that came from the early days of Unix.
There are better alternatives that provide the same lack of "unknown/unnecessary" directories and files in the user's home directory/folder.
Each of Windows/MacOS/XDG-compliant OSs has the equivalent of:
1. A configuration directory 2. A storage directory that is maintained between user logins and/or application execution 3. A temporary/cache directory that is not guaranteed to be maintained between user logins or application execution.
The different languages/runtimes also have ways of retrieving these locations which are cross-platform but return the correct values and should be used by all applications that are written to modern standards.
There are better alternatives
Let’s define “better” first.
You made me curious and didn't deliver ! The anguish !
As the saying goes, layers are only added, never removed. The world where people respect XDG is not one that can be achieved anymore.
The trick is to use the XDG Base Dir Spec, only if the old ~/.name location doesn't exist. Old users are happy because it doesn't break compatibility and new users are happy because nobody's dropping 10 sacks of potatoes on their metaphorical doorstep
I don't know what's the situation with desktop linux, may it's better, maybe it's worse, but even on a headless dev server it's already a lost cause. Trying to convince everybody to move to a new standard is a hopeless task, imo, best to move on.
And in my opinion .ssh and .gnupg are okay since in some contexts, the "XDG variables" haven't been initialized in certain circumstances when using those utilities.
But yeah, I'll have to look into those - maybe there is something I can do to fix that
rm -r ~/.foo/cache ~/bar/cache ~/baz/data/app/cache [20 more apps..]
is less ergonomic than rm -r ~/.cache/\* rm -rf ~/.*/cacheEach of the data, config, and cache envvars would all be set to ~/.data in this setup (though “data” isn’t a name I’d use)
It doesn't seem like you understand much about the specification? I'd recommend reading it, or at least a short summary I've made available here: https://xdgbasedirectoryspecification.com/
(God forbid I should use remote CVS again, but if I do, I sure don't want to have to debug where the fuck it's sticking .cvspass now.)
There are another 41 things in .config, including Bitcoin, Calibre, Chromium, DjVuLibre, Gomuks, htop, Inkscape, Mumble, OpenSCAD, Transmission, and other things. If I had to choose, I would say that those are the things "going against the grain of the ecosystem". But I think it's fine. As long as it doesn't change in another ten years to be .Config, or .conf, or Configuration, or either Configuration or Configuración depending on whether I installed the machine in English or Spanish. Because then I am seriously going to look into government surplus cruise missiles.
Some of those already do, though. At least Vim and Emacs do, and I personally have zsh in .config as well.
Instead of lamenting that Unix isn't more like Oberon, and trying to make it more like Oberon, consider that possibly the secret of Unix's success is that its ad-hoc protocols and conventions embody ideas that work very well, so instead of replacing them with untested rational planning, you should try to learn from them. Embrace the chaos.
Fuck you so much.
Also, would you please stop posting unsubstantive/flamebait comments more generally? It's not what this site is for, and it destroys what it is for.
Literally every program I’ve installed for the last several months--WezTerm, Neovim, bat, broot and many more just use XDG by default. Most of the time, the user doesn’t have to do anything, though they might initially be confused if they’re looking for their config files.
vs
> the de-facto community standard
Feels like you’re just selectively defining “community” to exclude XDG. Maybe there’s a good reason, but you haven’t really described it.
Whoever defined $HOME as a place to stick configuration files was also “just some group.”
So are ISO, W3C, IETF, etc.
> dropping config files in .programname is the de-facto community standard
Dropping litter and open-air defecation are de-facto community standards in some unfortunate parts of the world. That's not an argument to keep doing it.
It affects how every single program is launched
That is true, but used as an argument for this subject is tangential and overblown. Look at your .bashrc and tell which parts are too fundamental to not be stored elsewhere, if really needed.
/home/you/personal/
source code in
/home/you/src/
The home is not a place supposed to store random "regular files"
A lot of data is managed by software and by convection there is a dot before them
Unmanaged/Arbitrary data like random pictures or notes are personal and should end up in $HOME/personal
git repos are special managed data, thus they all end up in $HOME/sources
$HOME is supposed to let software to create their data folder and optimally without the dot
The data here includes config (which is read & write like data file)
$HOME/.config or XDG spec is monkey patch that do the wrong thing.
GUI file manager should open $HOME/personal as initial location
Terminal should open $HOME to let user access software's data file with shorter path (aka without .config/ )
You don't know if i am mad or being brilliant or simply brain dead, but i am making perfect scene.
So the next best is to find another place as your home as the OP explains. That's what I do.
XDG is a great standard, but it seems it’s not enough. Probably time to abandoned home and put all personal files somewhere else — a subdirectory of home will do. And no standard name — call it what you want so no one can hijack it either.
As well as some stuff dumped in the home directory too. The defense on both Windows and Linux is to just keep your own documents elsewhere, or at least in a subfolder of the home directory.
Chrome and a number of other software insists on creating some of these directories (e.g. Downloads) too.
However you can fix that by setting XDG_DESKTOP_DIR and XDG_DOWNLOAD_DIR in ${XDG_CONFIG_HOME}/user-dirs.dir to something else (e.g. your home directory).
% cat ~/.config/user-dirs.dirs
XDG_DESKTOP_DIR="$HOME"
XDG_DOWNLOAD_DIR="$HOME"
Yet still: % ls -ld ~/Desktop
drwxr-xr-x 2 mt mt 4096 Oct 22 18:04 /home/mt/Desktop/
Sometimes there's a ~/Downloads directory too. But not today.I have no idea what keeps creating these. It's pretty annoying as I have a lot of intentionally short-named things in my ~ for easy shell usage, and it really sticks out.
inotify doesn't support reporting the PID of the process that triggered the event, but it seems fanotify does. Maybe I should set up a watcher for this.
systemctl enable --now xdg-user-dirs-update.service
and just to be safe I have a snippet that parses that file and exports the variables in my login shell like .profile(fish in this example but would be similar for other shells)
sed -nE 's/^([^=#]+)=(.*)/set -gx \1 \2/gp' <"$XDG_CONFIG_HOME/user-dirs.dirs" | sourceThe idea is that instead of creating a bunch of dotfiles and having to read a bunch of documentation, one declaratively states which features they want, say, for zsh or vim or git or xdg, etc; and then home-manager will create and manage them (typically they live in `$HOME/.config/whatever`).
https://github.com/nix-community/home-manager. Some examples on GitHub: https://github.com/search?q=filename%3Ahome.nix.
Centralization solve the problem in this case but have the downside that the central configuration file will become bloated and requires more memory in the long run.
``` if config_dir == '' or config_dir[0] == '/': ```
Storing your files in /home is also bad because usually /home uses Linux-specific filesystem and you won't be able to access your files from Windows. Storing files in NTFS partition solves this problem.
Also, /home may be mounted anywhere, including some NTFS partition.
If you don't like having a separate directory for config files you can set your XDG variables appropriately.
As someone who uses linux to get other tasks done, rather than as a hobby in itself, I would rather have an aesthetically sub-optimal standard than have no idea what's going on.