{"version":"https:\/\/jsonfeed.org\/version\/1","title":"niess.space JSON Feed","home_page_url":"https:\/\/niess.space\/","feed_url":"https:\/\/niess.space\/json","items":[{"id":"7ef91838-d237-483d-94d3-cabd50dd5d58","title":"Vivaldi: The best browser for WebDevs","url":"https:\/\/niess.space\/vivaldi","date_published":"2021-06-13T00:00:00+02:00","content_html":"<p>Let me tell you about the web browser that I've been using for the longest time in my life (in different incarnations basically since the late 90s). I'm talking about <a href=\"https:\/\/vivaldi.com\">Vivaldi<\/a>, <strong>the<\/strong> browser for power users and - in my opinion - web developers.<\/p>\n<h2>A bit of history<\/h2>\n<p>Vivaldi is in a sense the legacy of the Opera browser. It has the same founder and in large parts the same team. A team that was a big contributor to the open web standards we all use today (most notably CSS). A team that popularized features like tabbed browsing, mouse gestures and spatial navigation.<\/p>\n<p>When Opera abandoned its own engine in 2013 and switched to the Blink, all the greatness that was the Opera browser, was abandoned. Fortunately this lead to the founding of Vivaldi, which is also based on Chromium, but with the dedication to be a powerhouse browser with all the features you could ever need (hiding those, you don't).<\/p>\n<h2>Features for Web Developers<\/h2>\n<p>As web developers, we spend a lot of time in the browser and it fullfils multiple roles for us. It is a research tool that enables us to search the web for the answers we need to do our job. On the other hand it is what we use to view our finished products. It is what we test our webapps with, what we need for debugging and for optimizing performance.<\/p>\n<p>For the latter, Vivaldi offers everthing you know from Chrome. It <strong>includes the Chrome Dev Tools<\/strong> and allows you to install everything from the Chrome Web Store. Just <a href=\"https:\/\/www.theverge.com\/2019\/4\/8\/18300772\/microsoft-google-services-removed-changed-chromium-edge-browser\">as Microsoft Edge<\/a>, it removed or replaced lots of Google services in Chrome, that generally make Vivaldi less of a resource hog and feel a bit faster. In contrast to Edge, you can opt back into many of these services, if you want.<\/p>\n<p>In this article, I want to concentrate on how Vivaldi helps you as a research tool.<\/p>\n<h3>Two Level Tab Stacks<\/h3>\n<p><img src=\"https:\/\/niess.space\/assets\/content\/17-Vivaldi-2-Line-Tab-Stack.png\" alt=\"two level tab stacks\" \/><\/p>\n<p>When you research a certain topic, like <em>&quot;What do I need to authenticate an app with AzureAD OIDC?&quot;<\/em>, you tend to pile up lots of open tabs. Vivaldi has <a href=\"https:\/\/help.vivaldi.com\/desktop\/tabs\/tab-stacks\/\">tab-stacking<\/a> to help you organize your tabs. A tab stack is just a tab that has multiple sub-tabs. In Vivaldi this is displayed as a second line of tabs (hence two-level).<\/p>\n<p>You can automatically stack open tabs by host (e.g. all Stackoverflow questions in in one tab). You can also manually drag tabs to stack them or you can opt to open related tabs in a stack.<\/p>\n<h3>Extremely powerful search<\/h3>\n<div class=\"relative w-full pb-[56.25%]\">\n    <iframe class=\"absolute inset-0 w-full h-full border-0\" src=\"https:\/\/www.youtube.com\/embed\/oKcLkGQms44\" allowfullscreen><\/iframe>\n<\/div>\n<p>Just as every <a href=\"https:\/\/niess.space\/st4\">good text editor<\/a> has something like a command palette built-in, Vivaldi has <a href=\"https:\/\/help.vivaldi.com\/desktop\/shortcuts\/quick-commands\/\">Quick Commands<\/a>. They allow you to:<\/p>\n<ul>\n<li>search all open tabs and open the result<\/li>\n<li>search and open recently closed tabs<\/li>\n<li>search through all the commands inside Vivaldi (like saving all open tabs to a session, screenshotting the page, or creating a note)<\/li>\n<li>and much more.<\/li>\n<\/ul>\n<h3>Sessions<\/h3>\n<p><a href=\"https:\/\/help.vivaldi.com\/desktop\/tabs\/session-management\/\">Sessions<\/a> are a great feature that could use a better user experience, though. Lets say we have two dozen tabs open in our research on AzureAD but need to focus on something else. What we can do, is hit Cmd+E and chose <strong>Save open tabs as session<\/strong>. We can then close everything and start fresh.<\/p>\n<p>Apple has pretty much copied this feature in the coming Safari 15 (along with coloring the UI according to the current website). In Safari this will be called Tab Groups and you can do one thing, that you can't currently in Vivaldi: You can continue a tab group &quot;session&quot;. In Vivaldi you currently still need to save a new session (and optionally remove the old one).<\/p>\n<p>What's cool, though,  is that a session even stores the full browsing history for every tab plus individual scroll states. That quickly gets you back on track.<\/p>\n<h3>Note-taking<\/h3>\n<p><em>&quot;No thank you, not another note-taking app!&quot;<\/em> is what you probably think right now. For me, this is mostly true, I use <a href=\"https:\/\/obsidian.md\">Obsidian<\/a> for my notes and personal knowledge base.<\/p>\n<p>The <a href=\"https:\/\/help.vivaldi.com\/desktop\/panels\/notes\/\">notes in Vivaldi<\/a> are sort-of an in-between. I use them while researching a topic on the web. I can quickly take clippings of websites, or write down tips and advice I read on websites (automatically storing the website I got them from and a screenshot). The notes use Markdown, so when I'm ready to clean them up, I can easily move them to Obsidian.<\/p>\n<h3>History<\/h3>\n<p><img src=\"https:\/\/niess.space\/assets\/content\/11-Vivaldi-History.png\" alt=\"Browsing History\" \/><\/p>\n<p>Browsing history seems like an obvious feature, but no browser displays it as well as Vivaldi. It has an actual calendar view of your browsing history which helps a lot if you want to find a website that you recently visited but can't remember.<\/p>\n<h3>Email and RSS feeds (beta)<\/h3>\n<p><img src=\"https:\/\/niess.space\/assets\/content\/vivaldi-rss.png\" alt=\"RSS Feeds\" \/><\/p>\n<p>These are new features in Vivaldi. You already live in the browser anyways, so why have an extra app for your email or news feeds?<\/p>\n<p>Both are still in beta, but seem to work quite well (they are blazing fast, even with lots of messages). I have been desperately waiting for both of these to be added (back) to Vivaldi (Opera in the olden days already had mail and RSS).<\/p>\n<p>Many interesting developers regularly write interesting articles. Discovering them is a central way for me to keep up to date and hone my craft (the other way is my developer list on Twitter). Having an RSS reader integrated in the browser seems obvious and natural to me.<\/p>\n<h2>Essential Extensions<\/h2>\n<ul>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/alpinejs-devtools\/fopaemeedckajflibkpifppcankfmbhk\">Alpine.js devtools<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/vuejs-devtools\/nhdogjmejiglipccpnnnanhbledajbpd\">Vue.js devtools<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/livewire-devtools\/ahcmcdmhdcgbpklkdhpejphjekpmhkll\">Livewire devtools<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/pinboard-pro\/pmgaobiflaffpllgnepmhcnbdhfgnpna\">Pinboard Pro<\/a>, I save and organize my bookmarks on pinboard.in and this seems to be the best browser extension to manage them (<a href=\"https:\/\/apps.apple.com\/us\/app\/pins-for-pinboard\/id1547106997\">Pins for Pinboard<\/a> is the best one for iOS, btw.)<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/tab-snooze\/pdiebiamhaleloakpcgmpnenggpjbcbm\">Tab Snooze<\/a>, allows you to snooze a tab so that it automatically appears at a later time of your choosing. I use this <strong>all the time<\/strong> and am really mad the Vivaldi people haven't build this in, yet, even though I have been pestering them about this for <a href=\"https:\/\/forum.vivaldi.net\/topic\/24659\/tab-snooze-keep-for-later-time\">many<\/a> many years. ;-)<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/ublock-origin\/cjpalhdlnbpafiamejdnhcphjbkeiagm\">uBlock Origin<\/a>, Vivaldi has integrated tracker- and ad-blocking but it's not quite enough, so we still need this (for now).<\/li>\n<li>\n<a href=\"https:\/\/chrome.google.com\/webstore\/detail\/bitwarden-free-password-m\/nngceckbapebfimnlniiiahkandclblb\">Bitwarden<\/a>, switched to this from Lastpass (after they botched their privacy policy) and never looked back.<\/li>\n<\/ul>\n<h2>Closing thoughts<\/h2>\n<p>Vivaldi is among my favorite software, I would gladly pay for it (I paid for Opera in the past) but I realize there is no business model for a paid browser. I'd like to thank the <a href=\"https:\/\/vivaldi.com\/team\/\">team<\/a> for all the work, sweat and love they put into Vivaldi and would like to leave with two suggestions for improvement.<\/p>\n<p>The session management is great, but others are quickly catching up and the user experience needs to improve. I would love something where you can just switch between sessions or start a new session (pretty much what Apple is doing now).<\/p>\n<p>Vivaldi really has to to implement tab snoozing. When your browser is always open, tabs become to-dos. It's just very useful to be able to make a tab re-appear when it's relevant to me.<\/p>\n<p>If you haven't already, go <a href=\"https:\/\/vivaldi.com\">download Vivaldi<\/a> and enjoy your new primary browser. If you want to discuss this or leave me a note, leave a comment on <a href=\"https:\/\/twitter.com\/dakira\/status\/1404182768922337287\">this tweet<\/a>.<\/p>\n","author":{"name":"Matthias Niess"}},{"id":"5927d039-f5ae-4721-a363-e1937922e0bf","title":"Laravel Blade Components","url":"https:\/\/niess.space\/laravel-blade-components","date_published":"2021-06-03T00:00:00+02:00","content_html":"<p>Here is my opinion on Blade: It is the most powerful and easy to use templating engine on the planet. At least in the PHP universe, but I haven't seen anything better anywhere else I looked (Python\/Java).<\/p>\n<p>The Laravel community usually agrees on <em>the way<\/em> you should use Laravel features and that's usually: <em>Stick with the defaults<\/em>. In the case of Blade it's what you get when you use any of the <a href=\"https:\/\/laravel.com\/docs\/starter-kits\">starter kits<\/a> (Breeze or Jetstream with Livewire). Both of them make heavy use of Blade components. The Blade documentation also reflects the change away from using Blade template inheritance to fully building layouts with components only.<\/p>\n<blockquote class=\"twitter-tweet\"><p lang=\"en\" dir=\"ltr\">Anyone of my <a href=\"https:\/\/twitter.com\/hashtag\/laravel?src=hash&amp;ref_src=twsrc%5Etfw\">#laravel<\/a> friends that can explain in short what advantages that I have with using blade components instead of partials? Or are they just two words for the same thing? <br><br>Looks quite similar to me.<\/p>&mdash; \udb40\udc74\udb40\udc6f\udb40\udc6d\udb40\udc61\udb40\udc73\udb40\udc6e\udb40\udc6f\udb40\udc72\udb40\udc72\udb40\udc65Tomas Norre \ud83d\udc18 \ud83e\udde1 \ud83c\udfcc\ufe0f\u200d\ud83d\udc27 \ud83c\udfc3 (@tomasnorre) <a href=\"https:\/\/twitter.com\/tomasnorre\/status\/1397573603865018379?ref_src=twsrc%5Etfw\">May 26, 2021<\/a><\/blockquote> <script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script>\n<p>When I saw Tomas comment on Twitter, I figured there are still some misconceptions on what is what.<\/p>\n<h2>What regular Blade includes (partials) can do<\/h2>\n<p>Blades <code>@include<\/code> directive basically allows you to include any blade file within another blade file, optionally passing data or variables into the partial.<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #FF7B72\">@include<\/span><span style=\"color: #C9D1D9\">(<\/span><span style=\"color: #A5D6FF\">&#39;partials.nav&#39;<\/span><span style=\"color: #C9D1D9\">,[<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  <\/span><span style=\"color: #A5D6FF\">&#39;current_site&#39;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #FF7B72\">=&gt;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #D2A8FF\">request<\/span><span style=\"color: #C9D1D9\">()<\/span><span style=\"color: #FF7B72\">-&gt;<\/span><span style=\"color: #D2A8FF\">route<\/span><span style=\"color: #C9D1D9\">()<\/span><span style=\"color: #FF7B72\">-&gt;<\/span><span style=\"color: #D2A8FF\">getPath<\/span><span style=\"color: #C9D1D9\">(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  <\/span><span style=\"color: #A5D6FF\">&#39;data&#39;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #FF7B72\">=&gt;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #A5D6FF\">&#39;some data&#39;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">])<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>The <a href=\"https:\/\/laravel.com\/docs\/blade#including-subviews\">@include documentation<\/a> has some more examples and a big note that tells you components are better.<\/p>\n<h2>What components bring to the table<\/h2>\n<p>Components were <a href=\"https:\/\/laravel.com\/docs\/6.x\/blade#components-and-slots\">introduced<\/a> with Laravel 6 but still had an awkward usage experience that forced you to write lots of boilerplate. With Laravel 7 the syntax was changed to an HTML-tag style syntax which developers are already used to from frontend frameworks like VueJS or React.<\/p>\n<p>There are two main ways you can use components: As a Blade view with corresponding PHP class and as a Blade view only (<a href=\"https:\/\/laravel.com\/docs\/blade#anonymous-components\">anonymous component<\/a>). The third way is an <a href=\"https:\/\/laravel.com\/docs\/8.x\/blade#inline-component-views\">inline-component<\/a> where you only have the PHP class and output the view using a <code>render()<\/code> method. You can think of the PHP classes as little controllers only for the component (to fetch data or do other things).<\/p>\n<p>The <strong>main<\/strong> difference between components and includes is the ability to have slots (and of course the PHP classes). For example, lets say we want to create a button component. We would create a file <em>button.blade.php<\/em> in <code>resources\/views\/components<\/code><\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">@props([<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    &#39;type&#39; =&gt; &#39;submit&#39;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">])<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">&lt;<\/span><span style=\"color: #7EE787\">button<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">{{<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">$attributes-<\/span><span style=\"color: #C9D1D9\">&gt;merge([&#39;class&#39; =&gt; &#39;inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500&#39;]) }}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    type=&quot;{{ $type }}&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    {{ $slot }}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">&lt;\/<\/span><span style=\"color: #7EE787\">button<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>In our Blade templates we can just use it like this:<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">&lt;<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;Press Here&lt;\/<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>This will render a beautiful blue submit button. If we need it to be a regular button, we can just add the type. If we need to add CSS classes, we can just add them and they will be merged with the existing classes.<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">&lt;<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">type<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;button&quot;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">class<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;mt-5&quot;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">disabled<\/span><span style=\"color: #C9D1D9\">&gt;More Margin&lt;\/<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>You can add any attributes you want and the <code>$attributes<\/code> variable will render them. If you want to require attributes (or set defaults) you must set them as props, like above.<\/p>\n<p>You can also have multiple slots like this:<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">&lt;<\/span><span style=\"color: #7EE787\">x-modal<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    &lt;<\/span><span style=\"color: #7EE787\">x-slot<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">name<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;header&quot;<\/span><span style=\"color: #C9D1D9\">&gt;The TITLE&lt;\/<\/span><span style=\"color: #7EE787\">x-slot<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    Content of a modal<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    &lt;<\/span><span style=\"color: #7EE787\">x-slot<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">name<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;footer&quot;<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        &lt;<\/span><span style=\"color: #7EE787\">x-secondary-button<\/span><span style=\"color: #C9D1D9\">&gt;Cancel&lt;\/<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        &lt;<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;Submit&lt;\/<\/span><span style=\"color: #7EE787\">x-button<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    &lt;\/<\/span><span style=\"color: #7EE787\">x-slot<\/span><span style=\"color: #C9D1D9\">&gt;    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">&lt;\/<\/span><span style=\"color: #7EE787\">x-modal<\/span><span style=\"color: #C9D1D9\">&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>The named slots will be available as <code>$header<\/code> and <code>$footer<\/code> in your template.<\/p>\n<h2>The main selling point of components<\/h2>\n<p>So beautiful thing about this, is that it keeps your main templates clean so you can quickly see what's going on. It also hides all those Tailwind classes and helps prevent redundancies. Whenever I need something twice, I extract it to a Blade component.<\/p>\n<p>Soon you will have nice re-usable component libraries that you can extract to a package and use in all of your apps.<\/p>\n<p>You can also add a lot of magic to your components and even go as far as having a whole datatable hidden in a Blade component.<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">&lt;<\/span><span style=\"color: #7EE787\">x-datatable<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">:model<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;$products&quot;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">search<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">sortable<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">take<\/span><span style=\"color: #C9D1D9\">=<\/span><span style=\"color: #A5D6FF\">&quot;10&quot;<\/span><span style=\"color: #C9D1D9\"> <\/span><span style=\"color: #79C0FF\">pagination<\/span><span style=\"color: #C9D1D9\">\/&gt;<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>This will render the full table of the given model with a search field, sortable columns and pagination (powered by Livewire).<\/p>\n<p>This is an elegance you cannot achieve with regular Blade includes.<\/p>\n","author":{"name":"Matthias Niess"}},{"id":"5b4605b1-b979-426e-85fe-8ae13477e9e6","title":"Sublime Text 4 and Laravel","url":"https:\/\/niess.space\/st4","date_published":"2021-06-02T00:00:00+02:00","content_html":"<p>Sublime Text 4 <a href=\"https:\/\/www.sublimetext.com\/blog\/articles\/sublime-text-4\">is finally out<\/a> and it's time to go back to your favorite text editor. I will give you a short overview of what's new with Sublime Text and go over the differences with PHPStorm and VSCode (VIM users are not the target audience, sorry Michael Dyrynda \ud83e\udd37\u200d\u2642\ufe0f).<\/p>\n<h2>What's new?<\/h2>\n<ul>\n<li>It's fast. It's even faster than before with hardware acceleration and support for M1.<\/li>\n<li>It finally has code intelligence (called context-aware auto-complete) and with that, first class support for language servers (LSP).<\/li>\n<li>It has a new license model: Buy a license, get 3 years of updates.<\/li>\n<li>It as a new name: <strong>Sublime Text<\/strong>, no version number. With the new license model, Sublime Text will now continuously receive updates, so no more need for major releases.<\/li>\n<li>It has an amazing new default theme, light and dark, so no need to fight! Dark is better, though.<\/li>\n<li>It has full TypeScript support!<\/li>\n<li>It has an easy way to display files in split panes called <em>Tab Multi Select<\/em> that is integrated in a dozen places.<\/li>\n<\/ul>\n<p>To see the features illustrated, check out <a href=\"https:\/\/www.youtube.com\/watch?v=O91i9rL8VxM\">this overview video<\/a>.<\/p>\n<h2>Why try it (or not)?<\/h2>\n<p>If you're a full-blown IDE person and cannot live without all those nice refactoring features in your day to day work, you're probably going to stay with PHPStorm. If you're good with what <a href=\"https:\/\/intelephense.com\">Intelliphense<\/a> has to offer plus niceties like automatically adding <em>use statements<\/em> or expanding FQCNs, Sublime Text is for you.<\/p>\n<p>For VSCode users the only downside seems to be that ST4 is not free. Other than that you will see the same level of code completion capabilities and a <em>way<\/em> snappier editor.<\/p>\n<h2>How I use Sublime Text for Laravel Development<\/h2>\n<p>Before I go into the details of how I set ST up exactly, I want to write a little about how I use it and its features on a daily basis.<\/p>\n<h3>Testing<\/h3>\n<p>I practice TDD whenever it makes sense, so the first thing is usually do is generate a functional test. In that test-file I just type verbatim text of what I want to test (i.e. &quot;it displays a list of blog posts&quot;). Pressing ctrl+e converts this text to a proper test method that I just need to fill with life.<\/p>\n<div class=\"-mb-10\">\n  <video preload autoplay loop muted playsinline width=\"100%\">\n    <source src=\"https:\/\/niess.space\/assets\/content\/screencast_generate_tests.mp4\" type=\"video\/mp4\">\n  <\/video>\n<\/div>\n<p>To run tests, I just press <code>ctrl+shift+n<\/code> (nearest) while the cursor is inside the method I want to test. <code>ctrl+shift+l<\/code> (last) will repeat the last test run.<\/p>\n<h3>Creating things<\/h3>\n<p>For files that are not generated by artisan, I press <code>Cmd+Shift+n<\/code> to create a new file. I can use tab-autocompletion to navigate folders from the project root or start the filename with a colon (:) to create the file in the directory of the currently open file.<\/p>\n<p>As soon as I have an existing file, I usually use snippets (linked below) to create code structures. <code>_c<\/code> will create a class (getting the classname from the filename). The PHP Companion plugin helps adding the correct namespace (I use <code>F6<\/code> for this).<\/p>\n<p>The snippets <code>_f<\/code> and <code>_pf<\/code> help creating public functions and protected functions respectively.<\/p>\n<h3>PHP Stuff<\/h3>\n<p>PHP Companion as some more nice features. It allows me to easily class\/constructor properties by pressing <code>F7<\/code> and just typing the name.<\/p>\n<div class=\"-mb-10\">\n  <video preload autoplay loop muted playsinline width=\"100%\">\n    <source src=\"https:\/\/niess.space\/assets\/content\/screencast_properties.mp4\" type=\"video\/mp4\">\n  <\/video>\n<\/div>\n<p>When using PHP classes, I press <code>F10<\/code> to import the fully qualified classname as a use statement at the top of the file (automatically sorted). When implementing an interface or an abstract class, there's also the option to import all methods that need to be implemented. No extra shortcut, I just use the command palette (<code>cmd+shift+p<\/code>).<\/p>\n<h3>Autocomplete<\/h3>\n<p>I'm not sure how autocomplete works without a language server, but the default in ST4 is already so good, that I haven't bothered with installing Intelliphense of Psalm, yet. I do use the Tailwind plugin to get all the Tailwind classes.<\/p>\n<h3>Linting<\/h3>\n<p>For linting I use phpcs and tlint by Tighten. Especially tlint has great linting for code quality (like unused imports). I've heard great things about Psalm, but haven't tried it with ST4, yet.<\/p>\n<h2>My setup for Laravel Development<\/h2>\n<h3>Installation \/ Upgrade<\/h3>\n<p>ST4 will detect existing ST3 configuration files in <code>~\/Library\/Application Support\/Sublime Text 3<\/code> (Mac) or <code>~\/.config\/sublime-text-3<\/code> (Linux). It will copy the existing config to the new location at <code>~\/Library\/Application Support\/Sublime Text<\/code> or <code>~\/.config\/sublime-text<\/code> respectively. If you want to start fresh, just create an empty config directory.<\/p>\n<p>If you haven't done so already, you should also install <a href=\"https:\/\/www.sublimemerge.com\">Sublime Merge<\/a>, it works really nice in concert with Sublime Text (i.e. getting the history or blame for the current file).<\/p>\n<p>You should also make sure the CLI <a href=\"https:\/\/www.sublimetext.com\/docs\/command_line.html\">is available<\/a> for both tools, so that you can run <code>subl<\/code> or <code>smerge<\/code> in a terminal.<\/p>\n<h3>Plugins<\/h3>\n<p>Here's a list of all plugins I'm using.<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/github.com\/SublimeText\/AFileIcon\">A File Icon<\/a>, pretty icons for your files<\/li>\n<li>\n<a href=\"https:\/\/github.com\/ice9js\/ace-jump-sublime\">AceJump<\/a>, quickly move the cursor to a specific position<\/li>\n<li>\n<a href=\"https:\/\/github.com\/skuroda\/Sublime-AdvancedNewFile\">AdvancedNewFile<\/a>, better creation of new files and renaming<\/li>\n<li>\n<a href=\"https:\/\/github.com\/colinta\/SublimeChangeQuotes\">ChangeQuotes<\/a>, change from double to single quotes or vice-versa<\/li>\n<li>\n<a href=\"https:\/\/github.com\/sindresorhus\/editorconfig-sublime\">EditorConfig<\/a>, read and apply <a href=\"https:\/\/editorconfig.org\">.editorconfig<\/a> files<\/li>\n<li>\n<a href=\"https:\/\/emmet.io\">Emmet<\/a>, generate HTML plus tools to work with HTML (like <em>wrap selection with tag<\/em>)<\/li>\n<li>\n<a href=\"https:\/\/github.com\/Medalink\/laravel-blade\">Laravel Blade Highlighter<\/a>, add syntax for Laravel Blade templates<\/li>\n<li>\n<a href=\"https:\/\/github.com\/austenc\/blade-spacer\">Laravel Blade Spacer<\/a>, automatically adds spaces to Laravel Blade syntax for readability<\/li>\n<li>\n<a href=\"https:\/\/github.com\/erichard\/SublimePHPCompanion\">PHP Companion<\/a>, essential for PHP development<\/li>\n<li>\n<a href=\"https:\/\/github.com\/gerardroche\/sublime-phpck\">PHP Completions Kit<\/a>, provides PHP completions for Sublime Text<\/li>\n<li>\n<a href=\"https:\/\/github.com\/adael\/SublimePhpCsFixer\">PHP CS Fixer<\/a>, code style fixer<\/li>\n<li>\n<a href=\"https:\/\/github.com\/gerardroche\/sublime-phpunit\">PHPUnitKit<\/a>, run your PHPUnit tests in Sublime Texts console<\/li>\n<li>\n<a href=\"http:\/\/www.sublimelinter.com\/\">SublimeLinter<\/a>, code linting<\/li>\n<li>\n<a href=\"https:\/\/github.com\/tighten\/tlint-sublime-plugin\">SublimeLinter-contrib-tlint<\/a>, support for <a href=\"https:\/\/github.com\/tighten\/tlint\">tighten\/tlint<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/github.com\/SublimeLinter\/SublimeLinter-php\">SublimeLimyer-php<\/a>, lint PHP<\/li>\n<li>\n<a href=\"https:\/\/github.com\/SublimeLinter\/SublimeLinter-phpcs\">SublimeLinter-phpcs<\/a>, lint code style problems<\/li>\n<li>\n<a href=\"https:\/\/github.com\/danklammer\/tailwind-sublime-autocomplete\">Tailwind CSS Autocomplete<\/a>\n<\/li>\n<li>\n<a href=\"https:\/\/github.com\/vuejs\/vue-syntax-highlight\">Vue Syntax Highlight<\/a>\n<\/li>\n<\/ul>\n<p>This is what I used for ST3 and it works <em>way<\/em> better in ST4 because of the new context-aware code-completion. I haven't tried LSP plugins, yet, but have seen others using <a href=\"https:\/\/github.com\/sublimelsp\/LSP-intelephense\">Intelliphense<\/a>, <a href=\"https:\/\/psalm.dev\/docs\/running_psalm\/language_server\/\">Psalm<\/a>, and the VSCode <a href=\"https:\/\/github.com\/sublimelsp\/LSP-tailwindcss\">TailwindCSS Intellisense<\/a> with great success.<\/p>\n<h3>Settings<\/h3>\n<p>Here's my commented settings file.<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ prevent autocompletion on pressing ENTER<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;auto_complete_commit_on_tab&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ don&#39;t be smart<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;detect_indentation&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;folder_exclude_patterns&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #A5D6FF\">&quot;.git&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #A5D6FF\">&quot;.idea&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #A5D6FF\">&quot;node_modules&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #A5D6FF\">&quot;storage\/framework&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;font_face&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;Ubuntu Mono&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;font_size&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">20<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;hide_tab_scrolling_buttons&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;hide_new_tab_button&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;highlight_line&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;highlight_modified_tabs&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ draw some lines to show me what indention level I&#39;m in<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;indent_guide_options&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;draw_normal&quot;<\/span><span style=\"color: #C9D1D9\">, <\/span><span style=\"color: #A5D6FF\">&quot;draw_active&quot;<\/span><span style=\"color: #C9D1D9\">],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ this is important, ST4 indexer will ignore files in .gitignore by default<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;index_exclude_gitignore&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;line_padding_bottom&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">2<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;line_padding_top&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">2<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;show_errors_inline&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;show_panel_on_build&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;tab_size&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">4<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ use the new beautiful dark theme<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;theme&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;Default Dark.sublime-theme&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;ignored_packages&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #A5D6FF\">&quot;Vintage&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;show_tab_close_buttons&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;translate_tabs_to_spaces&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;trim_automatic_white_space&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;trim_trailing_white_space_on_save&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;word_wrap&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h3>Package Settings<\/h3>\n<p>Some extra settings for the packages I use. These live in <code>Packages\/User<\/code> which you can find when you search the Command Palette for <em>Browse Packages<\/em>.<\/p>\n<h4>AdvancedNewFile.sublime-settings .<\/h4>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;rename_default&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;&lt;filepath&gt;&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<p>I add a file for the default theme to be able to quickly adjust the text-size of the interface (not the editor), to make it more legible when presenting. Just uncomment the two font lines, when you need to present to a remote audience.<\/p>\n<h4>Default Dark.sublime-theme .<\/h4>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;rules&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;class&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;sidebar_label&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #8B949E\">\/\/ &quot;font.face&quot;: &quot;SF Pro Display&quot;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #8B949E\">\/\/ &quot;font.size&quot;:  25,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h4>Markdown.sublime-settings .<\/h4>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;trim_automatic_white_space&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;trim_trailing_white_space_on_save&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;word_wrap&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">true<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h4>PHP Companion.sublime-settings .<\/h4>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ default visibility of class variables<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;visibility&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;public&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h4>SublimeLinter.sublime-settings .<\/h4>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #8B949E\">\/\/ SublimeLinter Settings - User<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;linters&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #79C0FF\">&quot;phpcs&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;@disable&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #79C0FF\">false<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;args&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">                <\/span><span style=\"color: #A5D6FF\">&quot;--standard=PSR2&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">                <\/span><span style=\"color: #A5D6FF\">&quot;--exclude=Squiz.Scope.MethodScope,PSR1.Methods.CamelCapsMethodName&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;executable&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;phpcs&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;excludes&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">                <\/span><span style=\"color: #A5D6FF\">&quot;*.html&quot;<\/span><span style=\"color: #C9D1D9\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">                <\/span><span style=\"color: #A5D6FF\">&quot;*.blade.php&quot;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            ]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #79C0FF\">&quot;tlint&quot;<\/span><span style=\"color: #C9D1D9\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;args&quot;<\/span><span style=\"color: #C9D1D9\">: [],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">            <\/span><span style=\"color: #79C0FF\">&quot;executable&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;tlint&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #79C0FF\">&quot;paths&quot;<\/span><span style=\"color: #C9D1D9\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #79C0FF\">&quot;linux&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;~\/.composer\/vendor\/bin&quot;<\/span><span style=\"color: #C9D1D9\">],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #79C0FF\">&quot;osx&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;~\/.composer\/vendor\/bin&quot;<\/span><span style=\"color: #C9D1D9\">],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">        <\/span><span style=\"color: #79C0FF\">&quot;windows&quot;<\/span><span style=\"color: #C9D1D9\">: []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h3>Key Bindings<\/h3>\n<p>My non-default key bindings.<\/p>\n<pre class=\"shiki\" style=\"background-color: #0d1117\"><code><span class=\"line\"><span style=\"color: #C9D1D9\">[<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ add namespace<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;f6&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;import_namespace&quot;<\/span><span style=\"color: #C9D1D9\"> }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ add constructor property<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;f7&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;insert_php_constructor_property&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ add namespace to class (expand to fully qualified class name)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;f9&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;expand_fqcn&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ add FQCN to use statements<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;f10&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;find_use&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ ace jump to a word<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;ctrl+,&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;ace_jump_word&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ test function closest to the cursor<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;ctrl+shift+n&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;phpunit_test_nearest&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">  \t<\/span><span style=\"color: #8B949E\">\/\/ re-run last test<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;ctrl+shift+l&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;phpunit_test_last&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ convert sentence to test method<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;ctrl+e&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;php_unit_test_method&quot;<\/span><span style=\"color: #C9D1D9\"> },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    <\/span><span style=\"color: #8B949E\">\/\/ reveal current file in sidebar<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">    { <\/span><span style=\"color: #79C0FF\">&quot;keys&quot;<\/span><span style=\"color: #C9D1D9\">: [<\/span><span style=\"color: #A5D6FF\">&quot;super+shift+r&quot;<\/span><span style=\"color: #C9D1D9\">], <\/span><span style=\"color: #79C0FF\">&quot;command&quot;<\/span><span style=\"color: #C9D1D9\">: <\/span><span style=\"color: #A5D6FF\">&quot;reveal_in_side_bar&quot;<\/span><span style=\"color: #C9D1D9\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C9D1D9\">]<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre>\n<h3>Snippets and Plugins<\/h3>\n<p>You can find my (very simple) snippets in this gist: <a href=\"https:\/\/gist.github.com\/dakira\/6d9e4674aa1af7d0ddf0302c4a079bbf\">Sublime Text Snippets<\/a>.<\/p>\n<p>The custom plugin that converts sentences to test methods is available in this gist: <a href=\"https:\/\/gist.github.com\/dakira\/65380f181a53376f9fe0cc86c6272288\">PHPUnitTestMethodPlugin.py<\/a>. Some version of this plugin was written by Jeffrey Way but it has been modified since, not sure about the actual author.<\/p>\n<h2>Closing thoughts<\/h2>\n<p>In my opinion Sublime Text 4 is a joy to use as a daily driver. It probably won't replace your PHPStorm or VIM\u2026 but it might. If you have any comments, please reply to <a href=\"https:\/\/twitter.com\/dakira\/status\/1399899117531406342\">this tweet<\/a>.<\/p>\n","author":{"name":"Matthias Niess"}}]}