I never know what to write here
167 stories
·
65 followers

On the Dangers of Cryptocurrencies and the Uselessness of Blockchain

6 Comments and 12 Shares

Earlier this month, I and others wrote a letter to Congress, basically saying that cryptocurrencies are an complete and total disaster, and urging them to regulate the space. Nothing in that letter is out of the ordinary, and is in line with what I wrote about blockchain in 2019. In response, Matthew Green has written—not really a rebuttal—but a “a general response to some of the more common spurious objections…people make to public blockchain systems.” In it, he makes several broad points:

  1. Yes, current proof-of-work blockchains like bitcoin are terrible for the environment. But there are other modes like proof-of-stake that are not.
  2. Yes, a blockchain is an immutable ledger making it impossible to undo specific transactions. But that doesn’t mean there can’t be some governance system on top of the blockchain that enables reversals.
  3. Yes, bitcoin doesn’t scale and the fees are too high. But that’s nothing inherent in blockchain technology—that’s just a bunch of bad design choices bitcoin made.
  4. Blockchain systems can have a little or a lot of privacy, depending on how they are designed and implemented.

There’s nothing on that list that I disagree with. (We can argue about whether proof-of-stake is actually an improvement. I am skeptical of systems that enshrine a “they who have the gold make the rules” system of governance. And to the extent any of those scaling solutions work, they undo the decentralization blockchain claims to have.) But I also think that these defenses largely miss the point. To me, the problem isn’t that blockchain systems can be made slightly less awful than they are today. The problem is that they don’t do anything their proponents claim they do. In some very important ways, they’re not secure. They doesn’t replace trust with code; in fact, in many ways they are far less trustworthy than non-blockchain systems. They’re not decentralized, and their inevitable centralization is harmful because it’s largely emergent and ill-defined. They still have trusted intermediaries, often with more power and less oversight than non-blockchain systems. They still require governance. They still require regulation. (These things are what I wrote about here.) The problem with blockchain is that it’s not an improvement to any system—and often makes things worse.

In our letter, we write: “By its very design, blockchain technology is poorly suited for just about every purpose currently touted as a present or potential source of public benefit. From its inception, this technology has been a solution in search of a problem and has now latched onto concepts such as financial inclusion and data transparency to justify its existence, despite far better solutions to these issues already in use. Despite more than thirteen years of development, it has severe limitations and design flaws that preclude almost all applications that deal with public customer data and regulated financial transactions and are not an improvement on existing non-blockchain solutions.”

Green responds: “‘Public blockchain’ technology enables many stupid things: today’s cryptocurrency schemes can be venal, corrupt, overpromised. But the core technology is absolutely not useless. In fact, I think there are some pretty exciting things happening in the field, even if most of them are further away from reality than their boosters would admit.” I have yet to see one. More specifically, I can’t find a blockchain application whose value has anything to do with the blockchain part, that wouldn’t be made safer, more secure, more reliable, and just plain better by removing the blockchain part. I postulate that no one has ever said “Here is a problem that I have. Oh look, blockchain is a good solution.” In every case, the order has been: “I have a blockchain. Oh look, there is a problem I can apply it to.” And in no cases does it actually help.

Someone, please show me an application where blockchain is essential. That is, a problem that could not have been solved without blockchain that can now be solved with it. (And “ransomware couldn’t exist because criminals are blocked from using the conventional financial networks, and cash payments aren’t feasible” does not count.)

For example, Green complains that “credit card merchant fees are similar, or have actually risen in the United States since the 1990s.” This is true, but has little to do with technological inefficiencies or existing trust relationships in the industry. It’s because pretty much everyone who can and is paying attention gets 1% back on their purchases: in cash, frequent flier miles, or other affinity points. Green is right about how unfair this is. It’s a regressive subsidy, “since these fees are baked into the cost of most retail goods and thus fall heavily on the working poor (who pay them even if they use cash).” But that has nothing to do with the lack of blockchain, and solving it isn’t helped by adding a blockchain. It’s a regulatory problem; with a few exceptions, credit card companies have successfully pressured merchants into charging the same prices, whether someone pays in cash or with a credit card. Peer-to-peer payment systems like PayPal, Venmo, MPesa, and AliPay all get around those high transaction fees, and none of them use blockchain.

This is my basic argument: blockchain does nothing to solve any existing problem with financial (or other) systems. Those problems are inherently economic and political, and have nothing to do with technology. And, more importantly, technology can’t solve economic and political problems. Which is good, because adding blockchain causes a whole slew of new problems and makes all of these systems much, much worse.

Green writes: “I have no problem with the idea of legislators (intelligently) passing laws to regulate cryptocurrency. Indeed, given the level of insanity and the number of outright scams that are happening in this area, it’s pretty obvious that our current regulatory framework is not up to the task.” But when you remove the insanity and the scams, what’s left?

EDITED TO ADD: Nicholas Weaver is also adamant about this. David Rosenthal is good, too.

Read the whole story
bronzehedwick
48 days ago
reply
Crypto is one of the rare cases where if we burn it to the ground it will help our species survive.
Jersey City, NJ
Share this story
Delete
5 public comments
pdp68
48 days ago
reply
"This is my basic argument: blockchain does nothing to solve any existing problem with financial (or other) systems. Those problems are inherently economic and political, and have nothing to do with technology. And, more importantly, technology can’t solve economic and political problems. Which is good, because adding blockchain causes a whole slew of new problems and makes all of these systems much, much worse."
Belgium
chrismo
48 days ago
reply
#tech
ReadLots
48 days ago
reply
If we can just move all of the fraud into the blockchain, maybe then it can have purpose - keeping the scammers busy in crypto and leaving us outside of it alone.
acdha
48 days ago
reply
Green's “rebuttal” was disappointingly weak — to be honest, I read it expecting the end to be that he'd picked up some lucrative consulting work from a cryptocurrency company.
Washington, DC
GaryBIshop
48 days ago
reply
Well said!

Use Neovim as your man pager

1 Comment

This post originally appeared on Chris DeLuca's blog

You may know that you can open man pages in a Neovim buffer with :Man. However, you can also configure your shell to open manual pages in a Neovim buffer when called from the command line.

First, if you’re unfamiliar, Neovim ships with the great :Man  command, which opens man pages in a nicely formatted buffer. These buffers are normal Vim buffers, so come equipped with syntax highlighting, can be easily searched, and links to other manual pages can be followed with C-].

" Open the git manual page.
:Man git

You can also open man pages invoked inside Neovim’s terminal emulator using this same man buffer with a little configuration.

# This opens a man buffer?
man git

The man command can be configured to render pages with any program, controlled by the $MANPAGER environment variable.

We could set $MANPAGER to nvim, but that would cause nesting Neovim instances if called from inside a Neovim :terminal.

To work around this, we’ll need help from the neovim-remote  project (at least until Neovim core adds --remote back  ). With that installed, we can call nvr inside a Neovim terminal buffer to open the given file in the same Neovim instance.

I personally would rather not launch a whole Neovim instance just to render a man page if I’m not already inside Neovim, so for this tip we’ll add some detection code to only set the $MANPAGER value inside Neovim. We can do this by checking the value of the $NVIM_LISTEN_ADDRESS environment variable, which will only be set inside an instance of Neovim.

We’ll use the -o flag to open the man page in a new split, to help retain the context of what you’re working on.

In your bash/zsh config file:

if [ -n "${NVIM_LISTEN_ADDRESS+x}" ]; then
 export MANPAGER="/usr/local/bin/nvr -c 'Man!' -o -"
fi

Or for the fish shell:

if test -n "$NVIM_LISTEN_ADDRESS"
 set -x MANPAGER "/usr/local/bin/nvr -c 'Man!' -o -"
end

And that’s it. Happy RTFM!

Read the whole story
bronzehedwick
155 days ago
reply
Quick tip on using neovim as our MANPAGER.
Jersey City, NJ
Share this story
Delete

Legitimizing Blockchain

1 Comment and 4 Shares

Yesterday, 1Password made the following announcement:

I am very unhappy about this.

As of this writing, the replies to this announcement are, by my count, roughly 95% paying customers who are furious with them for doing this, 3% scammers who are jubilant that this is popularizing their scamming tool of choice, and about 2% blockchain-enthusiasts expressing confusion as to why everyone is so mad.

Scanning through that 2%’s twitter bios and timelines, I could see content other than memes and shilling, so it seemed at least plausible to me that these people are scam victims who haven’t gotten to the blow-off yet, and their confusion is genuine. Given that “why is everyone so mad” is a much less intense reaction than fury or jubilation, I assume that many others read through some of the vitriol and had this reaction, but then didn’t post anything themselves.

This post is for two audiences: that 2%, genuinely wondering what the big deal is, and also those who have a vague feeling that cryptocurrency is bad, but don’t see the point of making much of a fuss about it.

This is why we should make a fuss about it.


The objection most often raised in the comments went something like this:

This is just a feature that you don’t like; if it’s not for you, just don’t use it. Why yell at 1Password just for making a feature that makes someone else happy?

To begin with, the actual technical feature appears to be something related to auto-filling in browser-extension UI, which is fine. I don’t object to the feature. I don’t even object to features which explicitly help people store cryptocurrency more securely, as a harm reduction measure.

Also, to get this out of the way now: cryptocurrency is a scam. I’m not going to argue the case for that here. Others have made the argument far more exhaustively, and you can read literally hundreds of pages and watch hours of video explaining why by clicking here.

The issue is with the co-marketing effort: the fact that 1Password is using their well-respected brand to help advertise and legitimize scam-facilitation technology like Solana and Phantom.

Even if we were to accept all this, it’s a scam, 1Password is marketing it, etc, my hypothetical blockchain-curious interlocutor here might further object:

What’s the big deal about legitimizing these things, even if they are fraud? Surely you can just not get defrauded, and ignore the marketing?

That’s true, but it also misses the point: legitimizing and promoting these things does various kinds of harm.

More broadly, although I’m writing about 1Password’s specific announcement here, and a small amount of the reasoning will be specific to password management tools, most of the concerns I’ll describe are fairly general to any company promoting or co-marketing with cryptocurrency, and thus hopefully this post will serve for future instances where we should tell some other company to stop supporting blockchains as well.

So with all that out of the way, here are some of the harms that one might be concerned about, from the least selfish concern to the most.


Concern #1: the well-being of others

I don’t know how to explain to you that you should care about other people, but if you do care about other people, this could hurt them.

First and foremost, the entire scam of cryptocurrency rests upon making people believe that the assets are worth something. Most people are not steeped in the technical minutiae of blockchains, and tend to trust things based on institutional reputation. 1Password has a strong brand, related to information security, and they’re saying that cryptocurrencies are good, so it’s likely to convince a nonzero number of people to put their money into this technology that has enormous non-obvious risks. They could easily lose everything.

Advertising 1Password in this way additionally encourages users to maintain custody of their own blockchain assets on their own devices. Doing so with 1Password is considerably less risky than it might be otherwise, so if this were to only reach people who were already planning to store their wallets on their own computers, then great.

However, this might encourage users who had not previously thought to look at cryptocurrency at all to do so, and if they found it via 1Password they might start using 1Password to store their first few secrets. Storing them in this way, although less risky, is still unreasonably risky, given the lack of any kind of safety mechanisms on blockchain-backed transactions. Even if they’re savvy enough not to get scammed, nobody is savvy enough not to get hacked, particularly by sophisticated technical attacks which are worth leveraging against high-value targets like people with expensive crypto wallets on their computers.

To be clear, crypto exchanges are, on average, extremely bad at the job of not getting their users money stolen, but individual users are likely to be even worse at that job.

Concern #2: economic damage

If you don’t care about other people much, but you still care about living in a functioning society, then the promotion of blockchain based financial instruments is a huge destabilization risk. As Dan Olson explains in the devastating video essay / documentary Line Goes Up, blockchain-based financial instruments share a lot of extremely concerning properties that made mortgage-backed securities and collateralized debt obligations so financially toxic in the 2008 crash. Large-scale adoption of these things could lead to a similar crisis, or even worse, a global deflationary spiral in the style of the one that caused the great depression, setting off the kind of economic damage that could result in mass famine and mass death.

Of course, any individual company or celebrity advertising crypto is not going to trigger an immediate economic collapse. Each of these is a snowflake in an avalanche. I have no illusions that convincing just 1Password to stop this is going to turn the tide of the entire blockchain catastrophe that is unfolding all around us, or indeed that my one little post here is going to make the decisive difference between, 1Password stopping vs. not.

But that’s exactly why I’m trying to persuade you, dear reader, that this is a big deal and we should all try to work together to stop it.

Concern #3: environmental damage

While this specific blockchain is “greener” than others, but given the huge proportion of cryptocurrency generally that is backed by electrical waste, and the cultural and technical incentives that make trading one blockchain asset for another more common than cashing out to dollars, it’s still a legitimate concern that promoting blockchain in general will promote environmental destruction indirectly.

Furthermore, the way that Solana is less energy-intensive than other blockchains is by using proof-of-stake, so there’s a sliding scale here between economic and environmental damage, given that proof-of-stake is designed to accelerate wealth accumulation among non-productive participants, and thereby encourages hoarding. So the reduction in environmental damage just makes the previous point even worse.

Concern #4: increased targeting risk

Even if you’re a full blown sociopath with no concern for others and an iron-clad confidence that you can navigate the collapse of the financial system without any harm to you personally, there is still a pretty big negative here: increased risk from threat actors. Even if you like and use blockchain, and want to use this feature, this risk still affects you.

If 1Password happened to have some features that blockchain nerds could use to store their secrets, then attackers might have some interest in breaking in to 1Password, and could possibly work on tools to do so. That’s the risk of existing on the Internet at all. But if 1Password loudly advertises, repeatedly, that they are will be integrating with a variety of cryptocurrency providers, then this will let attackers know that 1Password is the preferred cryptocurrency storage mechanism.

This further means that attackers will start trying to figure out ways to target 1Password users, on the assumption that we’re more likely to have crypto assets lying around on our filesystems; not only developing tools to break in to 1Password but developing tools to fingerprint users who have the extension installed, who have accounts on the service, whose emails show up on the forum, etc.

Now, of course, 1Password users keep plenty of high-value information inside 1Password already; that’s the whole point. But cryptocurrency is special because of the irreversible nature of transactions, and the immediacy of the benefit to cybercriminals specifically.

If you steal all of someone’s bank passwords, you could potentially get a bunch of their money, but it is expensive and risky for the criminals. The transactions can be traced directly to actual human account holders immediately; anti-money-laundering regulations mean that this can usually be accomplished even across international borders. Transfers can be reversed.

This discrepancy between real money and cryptocurrency is exactly why ransomware was created by cryptocurrency. It makes cryptocurrency attractive specifically to the kinds of people who have expertise and resources to mount wide-spectrum digital attacks against whole populations.

Of course, if they develop tools to fingerprint and hack 1Password users, but they don’t luck out and find easy-to-steal crypto on your computer, they might as well try to steal other things of value, like your identity, credit information, and so on. These are higher-risk, but now that they’ve built all that infrastructure and hacked all these machines, there’s a big sunk cost that makes it more worthwhile.

Please Stop

I really hope that 1Password abandons this destructive scheme. Even if they fully walk this back, I will still find it much harder to recommend their product in the future; there will need to be some active effort to repair trust with their user community. If I’ve convinced you of the problems here, please let them know as a reply to the tweet, the email linked from their blog post, their community forum, or the Reddit post of the announcement, so that they can get a clear signal that this is unacceptable.

Read the whole story
bronzehedwick
164 days ago
reply
Shame on 1Password for piling on the #CryptoDisaster. Your reputation is your brand. Don’t ruin it.
Jersey City, NJ
jepler
165 days ago
reply
Earth, Sol system, Western spiral arm
Share this story
Delete

There Are Too Many Video Games

1 Comment and 6 Shares

Now that my title has savagely baited your click, let's talk about the weirdness of the game industry and the big mess we're all in.

If you don't want to read my words, just look at the chart above. A good long look. Let the absurdity sink in. Make your own conclusions from there.

I've been working continuously making indie video games longer than, let's say, anyone. I was one of the first to correctly describe the indie bubble, writing blog posts that got many views and got me sweet gigs working for free giving talks at conferences. (The GDC free lunch was lousy, but hey, it was free.)

This is only the latest article in my ongoing saga, The State of the Indie Game Industry, and things have gone absurd.

So let's get to it: There are too many indie games. If my country was healthy, stable, and on a sustainable path, most of them would not exist, including mine. That they do exist is a symptom of misplaced priorities, crappy opportunities for ambitious youth, and ongoing damage to our society.

Do I think you should keep writing your dream game? Sure. Why not? I'm not slapping the mouse out of your hand. Let us, however, take a minute to look at the world you are sending your baby into.

This took a long time to write and will earn me a lot of shouting online. But if I can crush just one young person’s dreams, it will all have been worthwhile.

Let's Look At The Absurdity

The chart at the top is the number of video games released on Steam each year, the vast majority of them indie. That's over 43000 titles in 5 years. A full 23 a day. (Over 30/day in 2021.)

(And that's just Steam. Add mobile and itch.io and homebrews and so on and the figure gets even crazier.)

If I lose you below, if I seem dumb or confusing, just come back to this figure. It's the North Star.

It's absurd! I keep using that word, but if the shoe fits ...

Want to know what is being written? Here is a great site to see the newest games on Steam. Take a look. A key point: Most of the games you see aren't ripoffs, aren't cheap or thrown together. Most of what you see took real work and investment, even if only in our precious and irreplaceable time.

What does this number imply?

Well, nobody wants this many games. Nobody. We have hard sales figures to prove it.

Almost eight billion humans on this planet, and you can't find anyone who cares. Most of these games sell to the writer's immediate friends, and nobody else.

Maybe you are in this business to make money. Maybe you want to bring people joy. (Cash is not the only measure of value!) By either measure, most of these titles are failures.

If you are happy that only 10 people play your game, fine, I guess. However, you should ask if you can't be bringing more people happiness with your limited time in the one life you get on this Earth.

Yeah, I know. I know. Just 3 paragraphs to go lol.

Let’s Provide An Exit Lane From this Post Now

Actually, I can make one point now and you can just skip the rest of it. These numbers are the key fact about the video game industry. Do you know an ambitious, fresh-faced, hard-working youngster who has a dream of writing the next great computer game?

Take this chart and shove it in the kid's face. A good looooong look. If a kid wants to write games (let alone, God help us, going into debt studying gamedev in college), you have a moral obligation to do this. They might keep at it, but they need to be warned.

That's all I have to say! Goodnight!

(pause)

Still here? Then let's dive deeper.

This is such a huge amount of product it's really hard to comprehend it. So much effort, so much ambition, most of which will vanish forever into a hole. In a world where human energy and ambition is very finite. (And I'll get back to this.)

Why did this happen? And is it good? Is it even sustainable? (Remember, everything that is not sustainable MUST end.)

The story of a rat with the ability to keep his family from ever being horribly killed by poison, but he blows it off to get a job selling $300/plate tweezer food to rich assholes. A perfect representation of American values.

It's Not Just Vidya, Of Course

An aside: I am fully aware this phenomenon isn't just video games.

Spotify now gets over 60000 new songs a day. Amazon now has millions of books. My country has over 550 scripted TV shows in production. And then all of the blogs and podcasts and Twitch streams and webcomics and YouTubers and VTubers and on and on and on ...

Yeah, I'm saying there's too many songs. And I know, musicians are the most precious and valuable and significant people there are. I know this because it's what musicians keep telling me. But 60000 a day? Sheesh!

Our children are taught to dream of nothing grander then adding to this indigestible mountainous hoard of distractions. Most created alone. Almost all consumed alone in a room in our atomized society. Seeking wheat in chaff. Mountains of chaff. OCEANS of chaff.

I'm getting ahead of myself. All I want to point out is that if there is a problem here, it's way bigger than video games. But I know video games. So I'll talk about that for now.

One main character only cares about playing jazz (!?) music and nothing else. Other main character only cares about eating as much food as possible. A perfect repres … Oh, never mind.

Where Is All This Stuff Coming From, Anyway?

Who is making those 30 games a day in 2021? I don't think anyone really knows. Are they young? Old? Where do they live? Are they hobbyists or aspiring professionals? I'm very interested, but I'm mainly focused on one question:

Why make art that nobody wants?

Because one thing I'm sure of about the people who make these games: They aren't dumb. They know how bad the odds are. Even if they dream of breaking out and getting a huge audience with their first game (or book or song), they will be under no such delusions while making their SECOND one.

Why create in the face of such mountains of unwanted content?

And don't give me homilies about "All art is valuable." "All creation is precious." "All babies are beautiful." "All our children are above average." None of these things are true.

Why create just for the sake of creation? Let’s discuss.

I am in LOVE with this illustration from the WikiHow page on getting over your fear of sharks. She kind of looks like she’s hitting on the shark, and the shark feels like its boundaries are being seriously tested.

Creation Gives Life Meaning and Satisfies the Drive to Improve the World

I have enormous sympathy for young people and the world they face. I got kids, and I'm old enough to remember when things were (a little) better.

There are many people who are built with talent, drive, and energy. With a desire to make, to build, to change the world, a passion for positive power that will not be quenched. It's a beautiful trait of humanity. When you see it in a kid, it's amazing.

Making art satisfies those urges. The world gives increasingly fewer ways to do so.

(Everything from here on will be focused on my country, the United States, but I bet people everywhere will find some of it familiar.)

If a young person is driven to improve the world, what outlets do they have? Social atomization (with an assist from Covid) has drained charities, social groups, and fraternal organizations. Church has been forgotten. Charity has been ineptly taken over by governments. An increasing number of jobs are simply meaningless. Politics is venal and controlled by the oligarchy, determined to crush any spirited opposition.

The passion to build and create, if given no proper outlet, will curdle into bitterness. It will drive you mad.

Thus, many create art. A thousand novels, a million songs, all heaped upon the compost pile. It keeps the suicide rate down.

Let me make one thing clear: If you need to make art, do it. If you want to put a game on Steam, do it. I'm not a bully. I'm more on your side than you could ever imagine.

But at some point, you have to stop and see what is in front of your eyes.

The cost of a video game development degree at DigiPen, offered without comment.

Time and Energy Is Finite, and Things Ain't Lookin' Good

If a society produces nothing but dysfunction and art, it has a problem.

If my Empire wants to go full Bread and Circuses, that is fine. However, you DO have to make sure you can provide the bread before you get to make the circuses.

This is a whole another blog post, so I'll paint with broad strokes for now. My city, Seattle, is crumbling. We don't have the energy to maintain the roads, and our bridges are literally falling apart. We can't even maintain what our grandparents built, let alone make any grand new projects.

The days of the Moon Landing and building the Interstate Highway System are behind us. All our dreams now are small. The glorious projects that could feed the ambitions of the young just aren't happening.

Plus, my city of Seattle doesn't have a road without a big pothole in it. Fixing potholes is actual work. It's tiring, and it's dirty, and how could doing something that actually benefits people ever compete with Living! A! Life! In! Art! (tm)

If you want a job with actual meaning, that ACTUALLY makes peoples lives better, there is plenty that needs doing. The problem, of course, is that jobs that actually have meaning involve actual work and thus SUCK.

The least popular pony is Applejack. She is also the only one who has a real job. This is, of course, a coincidence.

I Don't Know How To Fix a Pothole. Do YOU!?

Time is a zero sum game. If a bunch of people expend their energy making games, and a larger group of people waste their time playing them, and nobody steps up to do the things that need doing, well, that's bad right?

(Note: If you want people to do these jobs, you do need to pay a living wage with benefits. Otherwise, you just get more video games.)

Writing a game nobody plays discharges your energy and creates the feeling of achievement, but it's all empty calories and then your car falls into a sinkhole. If your game succeeds, it’s even worse. Your customers are now also expending all of their energy too, playing your game alone in a room. Meanwhile, sinkholes.

THAT is why I say there are too many indie games. They aren't sustainable. There is too much time wasted, and that will be true until time is applied to making the world work and bridges not fall down and food be in stores. Probably your time.

Hell, forget full-time jobs. If you volunteered at a food bank for one afternoon, you would do more good than spending 20 years writing games nobody plays. And I bet you'd feel more satisfaction too. And you'd get out of the house and maybe even make a friend.

Yes, you can call me an old Boomer and be angry at me for observing all this, if it makes you feel better. No, it will not make it less true.

You should definitely totally pwn me with your groovy Simpsons memes. Ageism is the hip new bigotry all the cool kids can get in on, deadass, no cap.

Fortunately, This Doesn't Apply To You

Sure, indulging ourselves in endless creation while the world crumbles is bad. Fortunately, that doesn't apply to your game. Your game is great! (And so is mine.) Your blog post is fine! (And so is mine.) Don't worry. The problem will always be the other guy's fault.

Still, I can't tell you to not make games. I can't say, "Give up your dreams of the easy life sitting and making art indoors." Sure, at some point, we will need more people doing work that it isn't getting done. Yet, I have a POWERFUL mental block that keeps me from saying you or I should do it.

Art is what we teach our kids is the most valuable thing. The Disney movie Coco is about a boy from a family of shoemakers who wants to blow them off and be a musician. Disney will never, ever make a movie about a musician who dreams of making shoes. Even though, well, try going a week without music and then a week without shoes and see which is more necessary.

And All This Applies To Me As Well

You are entirely entitled to ask why I keep writing video games. (And blog posts.) It's fair. Am I part of the problem? Yes. Of course. This is the sort of problem that makes us all complicit.

I'm more than happy to tell another guy to fill potholes. Everybody wants to go to Heaven, nobody wants to die.

Fortunately, there is good news for us all.

At this point, you might be thinking, "Well, if there is a problem, what is the solution? What do we need to change?" What makes you think it'll be your decision? The answer is, if anything changes, it will be because the world changes it for us. Changing this sort of problem is generally forced from outside, and it hurts. The machines we make run until they break.

Just an aside, but … Did anyone note the exact year when the heroes of movies stopped being regular humans without wizard powers?

Will the World Carry Us Forever?

It should be pointed out that being able to create such an absurd amount of art nobody wants comes from great wealth and privilege. These tens of thousands of games are being made, for the most part, by affluent children of Empire. The poor don't have that much time to waste.

Don't blame capitalism for these problems. Capitalism is the instrument that made the surpluses that made it possible for you to write art nobody wants in the first place.

The reason a young, enterprising indie dev can churn out product is because that person is surrounded by cheap products made overseas in punishing conditions by people we never see. These are the delicious fruits of Empire.

Why do they do it? Why do these unseen masses make all my junk for me?

Well, they do it to get dollars. (That our government is devaluing as quickly as it can.) And they do it because we have a powerful military that keeps world order. (Even though we can't keep our carriers from burning down to the water line.)

I'll write all the games I want, while I can. BUT. Suppose the rest of the world starts saying, "Um, actually, we don't want to bust our humps making crap for debt forever. We're tripling our prices." Then my whole world goes to pieces.

I HOPE I'M WRONG. I look at the way things are actually going right now, and I see the end of a lot of stuff we got too used to. Our artist paradise is only one of them. I want to be wrong, very badly. I'm sending kids into this world, and I don't want it to suck for them.

We won't be able to afford spending this much time making things nobody wants. And you know something? We never could afford it.

We don't need to debate if I'm right or not. The world will decide the issue for us. If that day comes, well, all this "Any amount of art is valuable!" nonsense will be the least of the cherished illusions you'll be forced to surrender.


EDIT (2/3/21) - Someone mad. This person commented the n-word on my post like 900 times. I can’t find a Delete All Comments By User command on Substack, and I kind of can’t believe it doesn’t have one. I am forced to leave up those hundreds of comments as a testimonial to why this feature is needed.

EDIT 2 (2/3/21) - The offending comments finally disappeared, though it took some time and I did complain to Substack. Not sure what happened here. Substack’s docs indicate that banning a user doesn’t delete comments. Maybe there is an error there.

EDIT 3 (2/5/21) - This post made someone super mad, and they kept spamming the post with obscene comments. Substack has been removing them manually, but they say this has never happened before, which is why they don’t have proper mod tools. I’m forced to switch my blog to only comments for paid subscribers, which totally sucks, but it necessary.

It’s hard to look back at your life’s work and wonder if you took the wrong path. If you want to explore the fruits of my misspent youth, they are all available on Steam and pretty fun. As always subscribing to my unnecessary blog is free …

Subscribe now



Read the whole story
bronzehedwick
183 days ago
reply
Jersey City, NJ
zippy72
183 days ago
reply
FourSquare, qv
Share this story
Delete
1 public comment
LeMadChef
185 days ago
reply
"There is too much art and not enough people to fill potholes"

Is that really your argument? I cannot comprehend...

Oh, the other argument is "You only have a limited number of hours in your life, don't create art, do some other thing that has value (which I will not reveal)".

What the actual eff?
Denver, CO

No, Apple Did Not Crowdfund :focus-visible in Safari

1 Comment

It’s not every week the release notes for a preview build of a web browser ignite Yet Another Twitter Teacup Storm (YATTS™), but that’s what happened when Safari Technology Preview 138 dropped late last week. At least, it’s what happened in the Twitter Teacups I tend to sip.

Just in case you missed it, here’s the summary:

  1. The WebKit team released Safari Technology Preview 138, and the release notes for same.
  2. The “CSS” section of the release notes started with a line saying:
    Enabled :focus-visible pseudo-class by default (r286783, r286776, r286775)
  3. A few people, including Jen Simmons, gave credit to Igalia for implementing :focus-visible by means of a crowdfunding project (more on that in a moment).
  4. KABOOM

I suppose I could be a bit more explicit in step 4, but I don’t really want to get into speculating on apparent motives and assumptions by others, because that’s not the point of this post. The point of this post is to clear up what seems to be a very common misunderstanding.

What I kept seeing people saying was something to the effect of, “Why the hell did Apple have to crowdfund this feature?” And that’s wrong in two ways:

  1. Apple doesn’t have to crowdfund anything, up to and including colonization of the Moon. (They might have to ask for a few bucks to do Venus or Mars.)
  2. Apple didn’t crowdfund :focus-visible.

This isn’t me splitting hairs, either. Nobody at Apple asked the crowd to fund anything. Nobody at Apple asked Igalia to crowdfund anything. They didn’t even ask Igalia to implement :focus-visible, and then Igalia decided to crowdfund the work. In fact, all of those assumptions get things almost exactly backwards — which is understandable! It’s what we expect from our experience of how the web has developed since at least the late 1990s. But here, something new happened.

So, let me summarize what happened using yet another ordered list:

  1. Igalia noticed they’d done a fair bit of work adding features to all the browser engines (e.g., CSS Grid), with each project supported by a single paying client, and thought, “Wait a minute, the web is a commons. Why are features being driven one client at a time?”
  2. Of its own volition, Igalia decided to experiment with the idea of letting the web community (the “crowd”) vote for implementation of a missing browser feature with their wallets (the “funding”). They called this ongoing experiment Open Prioritization, and launched it in 2019.
  3. There were six possible projects, chosen by Igalia through their own set of criteria, for the community to vote on by pledging monetary support:
    • CSS lab() colors in Firefox
    • :focus-visible in WebKit/Safari
    • HTML inert in WebKit/Safari
    • Selector list arguments for :not() in Chrome
    • CSS Containment support in WebKit/Safari
    • CSS d (SVG path) support in Firefox
  4. The winner was implementing :focus-visible in WebKit/Safari, and by “winner”, I mean that project got the most monetary commitment from the members of the community.
  5. Igalia matched the community contributions dollar for dollar, and moved forward with the work.
  6. The work was done, and submitted to the WebKit code base. (Along the way, inconsistencies and other problems were discovered, addressed, and fixes contributed to engines other than WebKit.)
  7. The WebKit team accepted Igalia’s contributions, and are now shipping them in a preview build of Safari for developers to test out.

In other words: the community (more precisely, a portion of it) voted on which feature was most needed, Igalia implemented it, and Apple accepted it. Apple’s role in this process came at the end, not the beginning.

And no, this is not the usual thing! It’s not supposed to be. Igalia is deeply committed to not just advancing the web, but to an unprecedented extent democratizing that advancement. It isn’t anything like a pure democratic effort, at least not yet, but these are early days and the initiative is structured to meet the current constraints of the environment (read: living under capitalism means coders gotta get paid).

But why is Igalia doing this? Time for another list! Just to switch things up, this one will be unordered:

  • Because the community should have more of a say in what gets prioritized in browsers. The community can be large collections of individuals, or it could be small collections of small companies, or a mix.
  • Because in every browser team, there’s always a priority list, and sometimes good features get pushed down that list for various reasons. It could be lack of expertise. It could be lack of time. It could be lack of interest. It could be interference by higher-ups. It doesn’t matter.
  • Because browser teams — not any one team, but the unfortunately small number of browser teams — are a bottleneck. No matter how much money the companies who employ those teams throw at them, they will always be a bottleneck, because resources are finite.

And this brings us to why I think “Wait, shouldn’t the $browser_name team have already done $feature_name by now? Why did an outside party have to do it?” is a little short-sighted. There will always be a $feature_name that the $browser_name team hasn’t done yet, for any value of $browser_name you care to posit. Today it could be WebKit; tomorrow, Chromium. In ten years, maybe there will be teams at Amazon and Huawei, making browser engines that compete for user share. Maybe not. Doesn’t actually matter, because however many or few engines there are, no matter what their priorities are, this problem will persist.

This is also why I’m not getting into Apple’s funding levels and priorities for WebKit and the web. Yes, there is much Apple-the-company can be criticized about, and personally, I am one of the biggest fans browser-engine diversity ever had, but that is a different conversation. Even if you could somehow wave a magic wand and open all platforms everywhere to engine diversity, and simultaneously cause a thousand browsers to bloom, we would still have the same basic problem. Open Prioritization would still need to exist.

For another piece of evidence on that point, look at the second Open Prioritization project: MathML-Core, whose goal is to bring full cross-browser support for the MathML Core specification to browsers, starting with Chrome (which needs the most work in this area) and then moving on to other engines (which need less work, but still need work). Doing this will not only improve support for web-wide math markup and its visual rendering, but will also improve the accessibility of math content on the web by making math a first-class content type in browsers. And you can even now contribute to this effort with a pledge of your own!

“But wait, why didn’t $browser_name already finish implementing MathML Core?” It doesn’t matter. Whether or not $browser_name (whichever one that is) should have done this by now, they haven’t. Maybe they would have done it eventually, but again, that doesn’t matter. We can make it happen now.

That’s what happened with :focus-visible in WebKit, which helped improve other engines; it’s what will happen with MathML Core in various browsers; and it could very well be what happens with other features in the future. Igalia would love nothing more than to see more and more projects launch, even if they don’t get hired to do the work for a single one of them. This isn’t us spackling over the cracks of browser teams’ neglect. This is us trying to chart an entirely new way to advance browser engines.

I go deeper into all of the above, as well as how Open Prioritization is designed to be an open forum and not some private reserve of Igalia’s, in a 17-minute talk delivered at W3C TPAC in fall 2021, available and captioned on Igalia’s YouTube channel. This post sort of summarizes it, but there are more examples and details in the talk, so if you’re interested, please do check that out.

Just in case your eyes sort of glazed and you skipped to the end to see if there was a TL;DR, here it is:

The addition of :focus-visible to WebKit was lead by the community, done by Igalia, and contributed to WebKit without any involvement from Apple except in the sense of their reviewing patches and accepting the contributions. Many of us are mad at Apple for a lot of good reasons, but please don’t let the process of venting that anger tar the goals and achievements of Open Prioritization. The future browser-feature priority you save may be your own.


Have something to say to all that? You can add a comment to the post, or email Eric directly.

Read the whole story
bronzehedwick
199 days ago
reply
I didn't realize the extent of Igalia's efforts. I like it.
Jersey City, NJ
Share this story
Delete

DIY Neovim fzy search

1 Comment

This post originally appeared on Chris DeLuca's blog

There are plenty of fuzzy search solutions for Neovim, most notably Telescope  , but sometimes you just want something fast and simple.

Enter fzy  , a fast command line program with a slick search algorithm. It is a good unix citizen, operating on newline delimited lists passed through stdin  , making it easy to integrate into all sorts of tools, including editors.

It’s own documentation shows an example integration with Vim. However, that implementation relies on the system()  function to display the fuzzy finder, which no longer works for interactive commands in Neovim  .

Yes, there is a fzy plugin for neovim  , but why not take the opportunity to learn some Neovim Lua, and write an implementation ourselves.

Along the way, we’ll learn how to load and test Lua files, invoke floating windows, handle interactive terminal inputs, create flexible functions, and add mappings.

This guide assumes some familiarity with Vim/Neovim, as well as a basic understanding of Lua. If you’re unfamiliar with Lua, I’d recommend reading Learn Lua in 15 minutes  before starting. If that sounds fun, fire up your terminal and follow along. Otherwise, skip to the end for the final script .

Setup

Neovim picks up Lua files to include in the lua folder, so we’ll create a file there called fuzzy-search.lua.

mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/lua"
nvim "${XDG_CONFIG_HOME:-$HOME/.config}/nvim/lua/fuzzy-search.lua"

We’ll need a function for our fuzzy searching, so let’s add one with a debug value to test. We need to access this function from anywhere, so we’ll make it global by omitting the local keyword. By convention, global variables in Lua start with an uppercase letter.

FuzzySearch = function()
print('Hello, search!')
end

Neovim provides some handy methods for loading Lua files and functions. We’ll use luafile  to load our fuzzy-search.lua into Neovim’s memory, and the lua  command to then call our newly added FuzzySearch command while we’re testing.

:luafile % " Interpret the current file as lua.
:lua FuzzySearch() " Should print 'Hello, search!' in the message area.

We’ll need to re-run those two commands every time we make a change to see their effects.

Summoning the floating window

We can no longer use the system() hack to interact with terminal programs inside Neovim, but we have access to something better: floating windows! We could make it a split buffer, but since a search interface is an ephemeral UI component that is fine to overlap existing content and should be dismissed the moment a selection is made, a floating window seems ideal.

To do this, Neovim provides the nvim_open_win()  API method, which we can access from the vim.api Lua table. This method takes 3 arguments:

  1. {buffer}, for which buffer to display, by buffer ID.
  2. {enter}, boolean for whether to enter the window or not.
  3. {config}, a table of options.

For {buffer}, we ultimately want to display a new terminal buffer with the search, so we’ll need to create one here. We’ll use the nvim_create_buf  API method to create a fresh buffer, and we’ll start a terminal session inside it in a later step. nvim_create_buf returns the ID of the buffer it just created, so it can be passed to nvim_open_win() directly. It has 2 boolean arguments; the first for whether the buffer will be “listed” by commands like :ls  , and the second for if it should be treated as a “scratch” buffer, which sets some options common to throw-away work. Since this is a temporary window, we’ll want to set this to unlisted and scratch.

For {enter}, we want to start typing our search as soon as the popup window is invoked, without having to do C-w C-l or whatever, so we’ll set this to true.

So far, our function should now look like this:

FuzzySearch = function()
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{}
)
end

Finally, for {config}, we’ll be setting several options here, largely to position the window. There are five required properties, relative/external, width, height, col, and row, so let’s set them first.

Every Neovim window requires either the relative or external key to be set. external is only relevant for external GUI applications, so we’ll keep it simple and only set relative. relative controls where the window is positioned relative to, aka, where it’s x/y position originates from. Our window can be relative to the editor, the current window, or the cursor position. This is a global search, so we’ll set relative to editor. This means that our new window’s 0/0 x and y position starts at the 0/0 x and y values of the entire editor.

Width and height are simple: how many rows, for height, and columns, for width, does our window occupy? Let’s keep this straight forward for now, and set width to 10 and height to 5.

col and row control where on the grid the window should appear from. This is our starting x and y values. Again, let’s keep this simple and set each to 0.

Our function should now look like this.

FuzzySearch = function()
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
width = 10,
height = 5,
col = 0,
row = 0,
}
)
end

Now, if you run luafile on your fuzzy-search.lua file again, and then lua FuzzySearch(), our floating window should appear over the top right of your editor!

Our basic floating window

Type :bd to close it.

Great, we have a floating window, but it’s not going to be very helpful looking like a postage stamp in the upper left. Let’s adjust the size, and center the window.

Centering the window

To center the window, we’ll need to calculate the mid-point for our window’s horizontal and vertical edge based on the window size and the size of Neovim itself, with our good friend Math.

We can get the width of the editor via the columns  global option, exposed in the vim.o  options table, and the height via lines  , exposed in the same.

Let’s start with the width. Our formula is pretty simple: subtract the width of the popup from the total columns in the editor (the width), and divide that by two to get the midway point. We need to subtract the popup’s width, since it would be pushed too far to the right without compensating for the space it takes up. We’ll finish by wrapping the whole expression in the Lua built-in math.min, since col expects whole numbers.

math.min((vim.o.columns - 10) / 2)

We’ll do something almost identical for row (aka height), but instead of using vim.o.columns, we’ll use vim.o.lines.

math.min((vim.o.lines - 5) / 2 - 1)

Notice that we’re also adding an extra subtraction by one. This is because vim.o.lines returns the total lines in the current window, including the status line and the message area. That’s an extra two lines to account for. Since we want to center the popup vertically, to find how much to compensate by, we divide the extra lines by two, giving us one to subtract.

Our function should now look like this.

FuzzySearch = function()
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
width = 10,
height = 5,
col = math.min((vim.o.columns - 10) / 2),
row = math.min((vim.o.lines - 5) / 2 - 1),
}
)
end

Looking over this code, there’s some repetition causing maintenance overhead: we’re writing literals for the width and height twice. We’ll need to change these values soon, so let’s refactor to use local variables for these values. Add a variable for width and height at the top of the FuzzySearch function, since we’ll want them to be available throughout the scope. Our code should now look like this:

FuzzySearch = function()
local width = 10
local height = 5
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
width = width,
height = height,
col = math.min((vim.o.columns - width) / 2),
row = math.min((vim.o.lines - height) / 2 - 1),
}
)
end

If you test this code, you’ll get something like this.

Basic centered floating window

Not much to look at, but at least it’s centered. But why is it only one line high, instead of five? Well, it actually is five lines high, but we can’t tell because our window has no outline style or contents. Let’s fix the former, then move on to the latter.

Styling the window

Floating window styles are controlled by two properties, style and border. As of this writing, style only has one valid value: "minimal". Fortunately, this option disables lots of inappropriate UI configurations for our search window, such as number and spell (see the docs for the full list).

border has several built in options, as well as an option to define your own border characters (this is what Telescope does). Feel free to play around with the options, but for the purpose of this guide we’ll be using "shadow". I like this style because it’s visually uncluttered, and makes clear that this window is “above” others.

While it’s not styling, let’s take a moment here to set the noautocmd option to true. This disables buffer events for the window, since we won’t be using them and it’s a good practice to limit the scope of our programs as much as sensible. Feel free to set this to false later if you do end up using these methods.

Our function should now look like this.

FuzzySearch = function()
local width = 10
local height = 5
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
style = 'minimal',
border = 'shadow',
noautocmd = true,
width = width,
height = height,
col = math.min((vim.o.columns - width) / 2),
row = math.min((vim.o.lines - height) / 2 - 1),
}
)
end

Test this code and you should get something like this.

Styled floating window

Looking good. Or, at least like a stylish postage stamp. Alright, let’s move on to the contents of the window.

Launching a fzy terminal

There are several ways Neovim offers for creating a new terminal instance, but we’ll be using the termopen()  function, since it offers the most API control.

We can ask it to provide a “standard” interactive terminal session, or to launch running a specific command. We’ll call it after our floating window setup code, using a basic command to gather files for fzy to search, taken from their documentation, that should work on most systems.

vim.fn.termopen('find . -type f | fzy')

The find command will grab every regular file in your current directory tree, and pass it to fzy. Testing this code will produce a result similar to this.

Cramped results from fzy

Hooray! You should be able to search for a file, move up and down in the list via C-n and C-p, and select a file with Enter. However, you may be noticing some slight issues.

  1. The window is too small to see the results properly.
  2. Depending on your settings, you might not be in terminal mode  automatically when you enter the window, causing you to have to type i before you can search.
  3. Selecting a file produces a [Process exited 0] message, making you press Enter again before continuing.
  4. Selecting a result does not open it!

Solving the second issue is dead simple: we call startinsert  before running termopen() via nvim_command  .

vim.api.nvim_command('startinsert')

We’ll address each of the other issues, but let’s tackle the window size first, so we can better see what we’re doing.

Dynamic width and height

Alright, back to window sizing. We can improve the display by taking full advantage of the amount of space we have available to us. Since we already re-factored our width and height to single variables, we simply modify them where they are declared.

Wouldn’t it be nice to stretch the width of the popup window to however large the Neovim instance is? Easy. We change the width variable to equal vim.o.columns, minus four. The number four is arbitrary; it gives two columns of space between the edge of the Neovim instance and the popup window, which feels right to me. Feel free to experiment with your own values.

local width = vim.o.columns - 4

For setting the height, we want to show all the results that fzy shows, or, in other words, we want our popup window to be as tall as the fzy output. fzy defaults to displaying ten search results at a time. This number can be controlled via the --lines option, but changing that will be left as an exorcise for the reader. For now, we’ll redefine height to be equal to 11, which is the default 10 results fzy displays, plus an extra line for the search prompt.

local height = 11

We now have an adaptive display window that shows our searches more clearly.

Dynamic window width

But what happens on very large screens? Our window will stretch all the way across, packing the results at the left, and wasting space on the right. We can spend a moment fixing this by setting a max width for the window. The window will still center, so the eye won’t have to travel all the way to the edge to see results. The standard max line length for Vim is a sensible 80 columns, so we’ll stick to that for our window.

Since we’re subtracting four from the total width, and we want to trigger the max after we would naturally reach 80 columns, we’ll set the width at 85 columns.

After our local variable declarations, we’ll add our conditional.

if (vim.o.columns >= 85) then
width = 80
end

Now the entirety of our function should look like this.

FuzzySearch = function()
local width = vim.o.columns - 4
local height = 11
if (vim.o.columns >= 85) then
width = 80
end
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
style = 'minimal',
border = 'shadow',
noautocmd = true,
width = width,
height = height,
col = math.min((vim.o.columns - width) / 2),
row = math.min((vim.o.lines - height) / 2 - 1),
}
)
vim.fn.termopen('find . -type f | fzy')
end

Let’s move on to solving the third and fourth problems mentioned above—not actually being able to open the file searched for!

Opening the searched for file

We want to perform an action—edit a file—when the terminal process for fzy exits, which happens after the file is selected. We know from the fzy man page  that on exit the currently selected item is printed to stdout, which is how we can detect which file is selected.

The termopen() function takes a table of event-driven callbacks as it’s second argument. We’ll be using the appropriately named on_exit.

vim.fn.termopen('find . -type f', {on_exit = function()
-- code goes here.
end})

Let’s get rid of the extra Enter press. Inside the on_exit callback, we’ll call bdelete  , meaning that once the terminal process exits, we’ll automatically delete the buffer. We’ll add the ! option, which will delete the buffer even if there are changes to it. This buffer should never have meaningful changes, so we never want that safety (otherwise, if there were changes, bdelete would produce an error).

vim.api.nvim_command('bdelete!')

If you test the function, the popup window should immediately dismiss after a file is selected. Excellent!

Now we can move on to opening the file searched for. We know that fzy prints the path to the selected file to {stdout}. Maybe there’s an argument that Neovim passes {stdout} to the terminal event callbacks? However, the on_exit  callback only receives the job id  , the exit code, and the event type, which in this case is always “exit”.

There must be a better way to solve this, but how I’ve figured it out is to write the contents of {stdout} to a file as part of the fzy pipeline, then read the file contents back in the on_exit function. If you know of a better method, hit me up on Twitter  .

Since the file we’re creating is totally throw-away, you could say temporary, we’ll use Neovim’s tempname()  function to generate a unique temporary file name in a clean path.

local file = vim.fn.tempname()

Then we can save the output fzy (which is {stdout}) to our file with simple Unix redirection  and Lua concatenation  .

'find . -type f | fzy > ' .. file

Back inside our on_exit callback function, and after our bdelete call, is where we can access the file we wrote. Lua provides a robust filesystem API  which we can use to open a stream to the file and read the contents into a variable. We’ll open the file stream as read only, keeping the principle of only asking for what we need.

local f = io.open(file, 'r')
local stdout = f:read('*all')

We should also clean up after ourselves, removing the temporary file from disk and closing the file stream.

f:close()
os.remove(file)

Now we have the file path stored in the stdout variable; we can use the nvim_command Neovim API method to :edit it!

vim.api.nvim_command('edit ' .. stdout)

Our whole function should now look like this.

FuzzySearch = function()
local width = vim.o.columns - 4
local height = 11
if (vim.o.columns >= 85) then
width = 80
end
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
style = 'minimal',
border = 'shadow',
noautocmd = true,
width = width,
height = height,
col = math.min((vim.o.columns - width) / 2),
row = math.min((vim.o.lines - height) / 2 - 1),
}
)
local file = vim.fn.tempname()
vim.fn.termopen('find . -type f | fzy > ' .. file, {on_exit = function()
vim.api.nvim_command('bdelete!')
local f = io.open(file, 'r')
local stdout = f:read('*all')
f:close()
os.remove(file)
vim.api.nvim_command('edit ' .. stdout)
end})
end

Test the function; selecting a file should open it. Yay! We have a fully working solution.

Implementing the search command

Wouldn’t it be nice to be able to access our function outside of our fuzzy-search.lua file? Say, in our init.vim or init.lua file?

Lua includes a simple yet powerful module system  , which we can leverage with only a few changes to our file.

All we need to do is return our function, and that will expose it to require statements. However, to make it possible to add further exportable functions to this file in the future, and to adhere to convention, we’ll add our function to a table.

local M = {}
M.FuzzySearch = function()
-- all our code.
end
return M

We name the returned variable M, again, to follow convention.

This adds fuzzy-search as a module to the Neovim environment. In a Lua file within the Neovim context, we could add our function to the environment with:

local fs = require'fuzzy-search'
fs.FuzzySearch()

Notice there’s no .lua extension or leading lua directory name in the require—Neovim/Lua handles this for us so we don’t have to type all that.

Now, in our init.vim or init.lua file, we can create a mapping to this function by requiring our search file inline, and parsing it with the built-in lua  command.

Say we wanted to map <leader>f, we would add, for init.vim:

nnoremap <leader>f <cmd>lua require'fuzzy-search'.FuzzySearch()<CR>

Or for init.lua:

vim.api.nvim_set_keymap('n', '<leader>f', '<cmd>lua require"fuzzy-search".FuzzySearch()<CR>')

The final script

We did it. Here’s our completed code.

-- ~/.config/nvim/lua/fuzzy-search.lua
local M = {}
M.FuzzySearch = function()
local width = vim.o.columns - 4
local height = 11
if (vim.o.columns >= 85) then
width = 80
end
vim.api.nvim_open_win(
vim.api.nvim_create_buf(false, true),
true,
{
relative = 'editor',
style = 'minimal',
border = 'shadow',
noautocmd = true,
width = width,
height = height,
col = math.min((vim.o.columns - width) / 2),
row = math.min((vim.o.lines - height) / 2 - 1),
}
)
local file = vim.fn.tempname()
vim.fn.termopen('find . -type f | fzy > ' .. file, {on_exit = function()
vim.api.nvim_command('bdelete!')
local f = io.open(file, 'r')
local stdout = f:read('*all')
f:close()
os.remove(file)
vim.api.nvim_command('edit ' .. stdout)
end})
end
return M

Download the search code.

Improvement ideas

This script is just a starting point. Here’s some ideas for improvements.

  • Allow mappings to specify how they want to open the file (split/vsplit/tab/etc).
  • Allow mappings to change the file gathering command, e.g. fd  or my personal favoriate, git ls-files  .
  • Allow mappings to change the number of results returned.
  • Get rid of that file write!

I implemented some of these in my own dotfiles  .

Wrap up

That’s it! Thanks for reading.

Read the whole story
bronzehedwick
208 days ago
reply
This ended up being much longer than anticipated, but I'm proud of the content.
Jersey City, NJ
Share this story
Delete
Next Page of Stories