You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I get a lot of plain text files with various extensions such as .1 or .inc and currently they only show the icon in QuickLook. Looking at one such file with mdls I see it has a dynamic type. But the content type tree includes public.data. Would it be possible to extend support to ALL filetypes?
From what I can tell, it's all the same issue. The kMDItemContentType and kMDItemContentTypeTree data can either be missing or dynamic for some files and this is causing issues.
Fun with UTIs
Found this to be very helpful in understanding what is happening.
Right now the plugin registers itself at the highest point that makes sense in both the physical and functional hierarchies.
public.data and public.content
There is a good case to be made for changing public.content to public.text but that's not a discussion we need to have here. Let's figure out how we can get this plugin working for more files.
Reacted by TJ Luoma, Mark Wilson, Quar, Rainer M Krug, muyinliu and Glenn 'devalias' Grant
Yep, I encountered this issue too. Even pre Catalina, in fact even pre Mojave. Just recently I was working on QLOPML on a 10.13 machine.
Had the same issue; macOS would identify files only by the dyn.* type. In my main application I had registered UTIs and file types. But they were not identified as such. What I did is add all dynamic types to my plist.
If anyone has any details on what the file type list looks like for the "Generic" QuickLook plugin that ships with macOS it might lend a clue. Or possibly, it's just hardcoded as the final fallback. I hope that's not the case.
tl;dr on the dyn.* namespace:
the values are base32 encoded query strings. So the suggestion to add them info.plist is not really viable as it's whack-a-mole on an infinite grid... 😞
Also, I tried creating a custom dyn.* adopting the public.data UTI without any extension. But that didn't work either. Setting the extension to * or nothing at all, also didn't work.
Somehow the UTI is not recognized as being inherited from public.data although the type tree clearly shows that it is. It also correctly displays the preview if the generator is specified directly:
So the problem really is, that macOS can't seem to map dyn.ah62d4rv4ge80w5u (*.in) to public.data. And therefore skips QLStephen because it does not seem to apply to the extension. Which is funny, because it clearly works for *.m files and the Text.qlgenerator.
I was sent here from #81. I used to have a working qlstephen setup but haven't since Catalina.
I have rebooted my machine, brew cask reinstall qlstephen (v1.5.1), and followed the instructions in the README, and I still can't QuickLook on some files like LICENSE, CHANGELOG, or Makefile.
So, I've come up with what I think might be a workable solution, though I'm looking for thoughts and feedback on it.
Rather than having to worry about generating dyn.* UTIs, etc., all we really need to do is simply have a way to tell the system that an unknown filename extension (e.g. .map) conforms to public.plain-text. By doing so, we then allow the system’s built-in text quicklook plugin to be used to preview the contents.
The solution I came up with is based on the assumption that only the end-user is going to know what filename extensions they come across and whether those files are text-based or not. It uses 2 different apps:
QLStephen.app: the primary app you interact with. It holds a list of the filename extensions that you've mapped to being treated as text. To map a particular filename extension to be treated as text, we declare that it conforms to “public.plain-text”. By doing so, we then allow the system’s built-in text quicklook plugin to be used to preview the contents. To implement these file mappings on the system, QLStephen.app uses a second application, “QLStephen Dummy.app”, in which the mappings are declared in the UTExportedTypeDeclarations of its Info.plist file. QLStephen.app also adds a Service so that you can right-click/control-click on any file in the Finder, and choose “Quick Look with QLStephen ✅” (yes, this is a bit misleading, I guess). This automatically opens it in QLStephen.app, and if it’s found to be text-based, is added to the list of file extension mappings. Then, after updating the dummy app, you can deselect and then reselect the file in the Finder to preview its contents as text.
QLStephen Dummy.app: This app is created in the ~/Applications/ folder. As mentioned previously, this is a dummy app that declares the file extension mappings in its ‘UTExportedTypeDeclarations` key in its Info.plist file. After modifying the Info.plist of the installed app, it is codesigned to run locally.
To be clear, these 2 apps exist separately from the QuickLook plugin which is still installed into ~/Library/QuickLook.
Some notes/known issues:
• Despite having a “Kind” column for you to fill out a file extension’s description, it appears the Finder will always refer to the kind as “Plain Text Document”. (I think declaring the documents in the CFBundleDocumentTypes as well might convince Launch Services to use their descriptions).
• There are some filename extensions that still won’t preview even though they are text-based: .css files and .strings files are 2 examples I’ve encountered.
Open Info.plist to edit it, at ~/Library/QuickLook/QLStephen.qlgenerator/Contents.
To navigate there, you can right click QLstephen.qlgenerator and "Show Package Contents" or use a code editor to get there
Add the relevant dyn.a... to Info.plist like in the following:
@NSGod Should be possible to merge those into one app right? @alexchandel: Possibly, though I didn't really like the idea of having an app modify its own Info.plist while it's running (which would probably invalidate its code signature), and then have it re-codesign itself while it's running. I thought it'd be easier to use a dummy stand-in app.
Granted, I can sometimes come up with solutions that tend to be overly complex.
Add application extensions.app with the goal to define UTIs:
toy.explicit (for .toy-explicit extension) conforming to public.plain-text
toy.a0 (for .toy-a0 extension) conforming to public.plain-text
toy.a1 (for .toy-a1 extension) conforming to toy.a0
toy.a2 (for .toy-a2 extension) conforming to toy.a1
toy.l0 (for .toy-l0 extension) conforming to public.data
toy.l1 (for .toy-l1 extension) conforming to toy.l0
toy.l2 (for .toy-l2 extension) conforming to toy.l1
Add files for each UTI + an unknown one with extension .toy-unknown
To test checkout extensions-problem-showcase and run make && make install, in this state only .toy-a0, .toy-a1, .toy-a2 and .toy-explicit should have preview/thumbnail generated (first 3 by Text.qlgenerator, last by QLStephen because it is explicitly in its list of UTIs).
Activity
tsdorsey commentedon Feb 5, 2020
Please move all discussion of file types and extensions in here.
#30 #32 #81 #82 #89
Apple's UTI reference documentation.
From what I can tell, it's all the same issue. The kMDItemContentType and kMDItemContentTypeTree data can either be missing or dynamic for some files and this is causing issues.
tsdorsey commentedon Feb 5, 2020
To add to the set of tested files, here is what happens when you use the LICENSE file in this repo. I also copied it and added
.1to the end of it.tsdorsey commentedon Feb 5, 2020
Fun with UTIs
Found this to be very helpful in understanding what is happening.
Right now the plugin registers itself at the highest point that makes sense in both the physical and functional hierarchies.
public.data and public.content
There is a good case to be made for changing public.content to public.text but that's not a discussion we need to have here. Let's figure out how we can get this plugin working for more files.
knaaptime commentedon Feb 6, 2020
Hi, thanks for your work on this. I want to add +1 for yaml support. Fwiw, that has been implemented here but hasn't been updated in quite awhile
tsdorsey commentedon Feb 6, 2020
@relikd I found this: PrivateLogs
I have to use sudo when enabling/disabling private logs but it worked.
Here is a log of running
qlmanage -p LICENSE.1This is a copy of the LICENSE file in this repo with a .1 extension added.
This confirms my suspicion that this is due to macOS setting the kMDItemContentType to a "dyn.*" value.
relikd commentedon Feb 6, 2020
Thanks for the PrivateLogs link.
Yep, I encountered this issue too. Even pre Catalina, in fact even pre Mojave. Just recently I was working on QLOPML on a 10.13 machine.
Had the same issue; macOS would identify files only by the
dyn.*type. In my main application I had registered UTIs and file types. But they were not identified as such. What I did is add all dynamic types to my plist.Additionally, I found this blog post very helpful: Analysis of UTIs (had to search a while to find this post again).
tsdorsey commentedon Feb 7, 2020
If anyone has any details on what the file type list looks like for the "Generic" QuickLook plugin that ships with macOS it might lend a clue. Or possibly, it's just hardcoded as the final fallback. I hope that's not the case.
tsdorsey commentedon Feb 7, 2020
tl;dr on the dyn.* namespace:
the values are base32 encoded query strings. So the suggestion to add them info.plist is not really viable as it's whack-a-mole on an infinite grid... 😞
relikd commentedon Feb 8, 2020
Do you happen to know which of them might be the generic QL plugin?
The best I got is
/System/Library/QuickLook/Text.qlgenerator, which conforms to:But then I'm not sure why
.mfiles are previewed:And why QLstephen fails for e.g., the
.inextension:relikd commentedon Feb 8, 2020
Also, I tried creating a custom
dyn.*adopting thepublic.dataUTI without any extension. But that didn't work either. Setting the extension to*or nothing at all, also didn't work.Somehow the UTI is not recognized as being inherited from
public.dataalthough the type tree clearly shows that it is. It also correctly displays the preview if the generator is specified directly:qlmanage -g ~/Library/QuickLook/QLStephen.qlgenerator -c "_" -p MANIFEST.inSo the problem really is, that macOS can't seem to map
dyn.ah62d4rv4ge80w5u(*.in) topublic.data. And therefore skips QLStephen because it does not seem to apply to the extension. Which is funny, because it clearly works for*.mfiles and theText.qlgenerator.[-]Add support for dynamic types[/-][+]Add support for dynamic and unknown UTI types[/+]philfreo commentedon Feb 24, 2020
I was sent here from #81. I used to have a working qlstephen setup but haven't since Catalina.
I have rebooted my machine,
brew cask reinstall qlstephen(v1.5.1), and followed the instructions in the README, and I still can't QuickLook on some files likeLICENSE,CHANGELOG, orMakefile.14 remaining items
jchannon commentedon Dec 3, 2020
Execute
mdls -name kMDItemContentType ~/path/to/file.extto get thedynvalue, add it to the plistJoeStrout commentedon Dec 4, 2020
I am trying this solution on macOS 10.15.7, but I get "zsh: command not found: lsregister". Any suggestions?
relikd commentedon Dec 4, 2020
I guess its in a non-PATH. You can created a symlink or use the full path instead:
lsregister@ -> /System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister
NSGod commentedon Feb 4, 2021
So, I've come up with what I think might be a workable solution, though I'm looking for thoughts and feedback on it.
Rather than having to worry about generating
dyn.*UTIs, etc., all we really need to do is simply have a way to tell the system that an unknown filename extension (e.g..map) conforms topublic.plain-text. By doing so, we then allow the system’s built-in text quicklook plugin to be used to preview the contents.The solution I came up with is based on the assumption that only the end-user is going to know what filename extensions they come across and whether those files are text-based or not. It uses 2 different apps:
QLStephen.app: the primary app you interact with. It holds a list of the filename extensions that you've mapped to being treated as text. To map a particular filename extension to be treated as text, we declare that it conforms to “public.plain-text”. By doing so, we then allow the system’s built-in text quicklook plugin to be used to preview the contents. To implement these file mappings on the system, QLStephen.app uses a second application, “QLStephen Dummy.app”, in which the mappings are declared in theUTExportedTypeDeclarationsof its Info.plist file. QLStephen.app also adds a Service so that you can right-click/control-click on any file in the Finder, and choose “Quick Look with QLStephen ✅” (yes, this is a bit misleading, I guess). This automatically opens it in QLStephen.app, and if it’s found to be text-based, is added to the list of file extension mappings. Then, after updating the dummy app, you can deselect and then reselect the file in the Finder to preview its contents as text.QLStephen Dummy.app: This app is created in the ~/Applications/ folder. As mentioned previously, this is a dummy app that declares the file extension mappings in its ‘UTExportedTypeDeclarations` key in its Info.plist file. After modifying the Info.plist of the installed app, it is codesigned to run locally.To be clear, these 2 apps exist separately from the QuickLook plugin which is still installed into
~/Library/QuickLook.Some notes/known issues:
• Despite having a “Kind” column for you to fill out a file extension’s description, it appears the Finder will always refer to the kind as “Plain Text Document”. (I think declaring the documents in the
CFBundleDocumentTypesas well might convince Launch Services to use their descriptions).• There are some filename extensions that still won’t preview even though they are text-based:
.cssfiles and.stringsfiles are 2 examples I’ve encountered.I have a
qlstephen.appbranch where I pushed this to in my fork: https://github.com/NSGod/qlstephen/tree/qlstephen.app.A link to a compiled and signed binary: https://markdouma.com/developer/QLStephen.zip
I welcome any feedback.
xupefei commentedon Feb 4, 2021
As another solution, I wrote a Fish script that automatically detect the UTI type of a given file and append the
dyn.*type to QLStephen:Usage for Fish shell:
plpxsk commentedon May 3, 2021
To summarize the current workaround, below are instructions to quick look a given file or file type (
*.Rmdin the below example).This was tested on macOS Big Sur 11.3 Terminal (zsh).
Run the following command on an existing file of interest to find a string that begins with
dyn.a...:Open
Info.plistto edit it, at~/Library/QuickLook/QLStephen.qlgenerator/Contents.To navigate there, you can right click
QLstephen.qlgeneratorand "Show Package Contents" or use a code editor to get thereAdd the relevant
dyn.a...toInfo.plistlike in the following:Reset quick look with a)
qlmanage -rand b) Relaunch Finder:Apple menu - Force Quit ... - Finder - Relaunch.muyinliu commentedon Aug 5, 2021
Works fine, thanks!
Note: command
killall Finderequal to Relaunch Finder.alexchandel commentedon Aug 28, 2021
@NSGod Should be possible to merge those into one app right?
NSGod commentedon Aug 29, 2021
Granted, I can sometimes come up with solutions that tend to be overly complex.
the fix for known/unknown child UTIs to be handled by QLStephen, reso…
toy commentedon Feb 17, 2022
After several evenings I've stumbled upon a fix and would appreciate a confirmation.
First to showcase the problem:
https://github.com/whomwah/qlstephen/compare/master...toy:extensions-problem-showcase?expand=1
toy.explicitextensions.appwith the goal to define UTIs:toy.explicit(for.toy-explicitextension) conforming topublic.plain-texttoy.a0(for.toy-a0extension) conforming topublic.plain-texttoy.a1(for.toy-a1extension) conforming totoy.a0toy.a2(for.toy-a2extension) conforming totoy.a1toy.l0(for.toy-l0extension) conforming topublic.datatoy.l1(for.toy-l1extension) conforming totoy.l0toy.l2(for.toy-l2extension) conforming totoy.l1.toy-unknownTo test checkout extensions-problem-showcase and run
make && make install, in this state only.toy-a0,.toy-a1,.toy-a2and.toy-explicitshould have preview/thumbnail generated (first 3 by Text.qlgenerator, last by QLStephen because it is explicitly in its list of UTIs).Fix:
https://github.com/toy/qlstephen/compare/extensions-problem-showcase...toy:extensions-showcase-fix?expand=1
Just change the bundle id so that it starts with
com.apple.and suddenly all test files get the preview/tumbnail.To test checkout extensions-showcase-fix and run
make && make install(wait forqlmanage -mto show the list, sometimes repeatingmake && make installis needed).If confirmed #135 is the fix unless someone has a better idea
ocodo commentedon May 10, 2023
For anyone wanting the bash/zsh version of the fish function posted by @xupefei
Add it to your
~/.bashrcor~/.zshrcto have it available when a new shell is opened.colossatr0n commentedon Feb 25, 2024
If you're getting a "bad pattern" error in ZSH, here's a different version of @jasonm23's script:
0xdevalias commentedon Oct 16, 2025
If you also want the
kMDItemContentTypeTreeyou can do:eg.