code https://michaelwelford.com/ en Wrapping selected text in Vim, easy... no? https://michaelwelford.com/post/wrapping-selected-text-vim-easy-no <span class="field field--name-title field--type-string field--label-hidden">Wrapping selected text in Vim, easy... no?</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 26/07/2021 - 08:35</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>A common want when editing code or prose, né, necessity is to wrap some selected text with something else - it could be an opening / closing tag combo, or some kind of logging method or even some kind of formatting function. Here are some common examples:</p> <ol> <li>Wrap with delimiter characters <br>e.g. <code>Hi!</code> to <code>&quot;Hi!&quot;</code> </li> <li>Wrap with a method <br>e.g. <code>&quot;a string&quot;</code> to <code>wrapped(&quot;a string&quot;)</code> </li> <li>Wrap with a tag <br>e.g. <code>Boo!</code> to <code>&lt;div&gt;Boo!&lt;/div&gt;</code> </li> <li>Wrap with a method and do some pre/post cleanup <br>e.g. <code>&lt;?php echo $var ?&gt;</code> to <code>&lt;?php Output::text($var) ?&gt;</code> </li> </ol> <p>The common way of approaching the first three scenarios is by using a plugin such as <a rel="noopener noreferrer" target="_blank" href="https://github.com/tpope/vim-surround">surround</a>, <a rel="noopener noreferrer" target="_blank" href="https://github.com/machakann/vim-sandwich">sandwich</a> or <a rel="noopener noreferrer" target="_blank" href="https://github.com/sirver/UltiSnips">UltiSnips</a> - but how about 4? In my particular case I also wanted to support wrapping with different methods on the <code>Output</code> object and map them to different keys. So using plugins didn’t quite cut the hotdog relish. Time to roll up the sleeves.</p> <h2><a id="user-content-break-it-down-james-brown" href="#break-it-down-james-brown" name="break-it-down-james-brown" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Break it down (James Brown)</h2> <p>Ok, let’s decompose this into the following rough components:</p> <ol> <li>Capture the selected text into a variable</li> <li>Clear the text</li> <li>Do any clean up around the text</li> <li>Re-insert the text from the variable</li> <li>Map that all to a key or command</li> </ol> <h3><a id="user-content-capture-the-selected-text-into-a-variable" href="#capture-the-selected-text-into-a-variable" name="capture-the-selected-text-into-a-variable" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Capture the selected text into a variable</h3> <p>This sounds easy right? Just yank it into a register and copy that… somehow… is there already a built in method for that? Pretty sure there isn’t so you end up with something like:</p> <pre><code class="language-vim">function! GetVisualSelection() &quot; Get from the start of the visual selection, '&lt; let [line_start, column_start] = getpos(&quot;'&lt;&quot;)[1:2] &quot; To the end of the visual selection, '&gt; let [line_end, column_end] = getpos(&quot;'&gt;&quot;)[1:2] let lines = getline(line_start, line_end) if len(lines) == 0 return '' endif &quot; Take into account the selection setting let lines[-1] = lines[-1][: column_end - (&amp;selection == 'inclusive' ? 1 : 2)] let lines[0] = lines[0][column_start - 1:] return join(lines, &quot;\n&quot;) endfunction </code></pre> <h3><a id="user-content-insert-text-at-current-cursor" href="#insert-text-at-current-cursor" name="insert-text-at-current-cursor" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Insert text at current cursor</h3> <p>Let’s skip 2 and 3 (they are actually trivial, yay) and let’s ponder inserting text - again that should be built-in but you can’t simply put in something like <code>exe &quot;normal i&quot; . text</code> as that’s not fool proof depending on what <code>text</code> is. For this you’ll probably want something like:</p> <pre><code class="language-vim">function! InsertText(text) let cur_line_num = line('.') let cur_col_num = col('.') let orig_line = getline('.') let modified_line = \ strpart(orig_line, 0, cur_col_num - 1) \ . a:text \ . strpart(orig_line, cur_col_num - 1) &quot; Replace the current line with the modified line. call setline(cur_line_num, modified_line) &quot; Place cursor on the last character of the inserted text. call cursor(cur_line_num, cur_col_num + strlen(a:text)) endfunction </code></pre> <h3><a id="user-content-putting-it-all-together" href="#putting-it-all-together" name="putting-it-all-together" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Putting it all together</h3> <p>Let’s see what a full approach might look like:</p> <pre><code class="language-vim">function! GetVisualSelection() &quot; Get from the start of the visual selection, '&lt; let [line_start, column_start] = getpos(&quot;'&lt;&quot;)[1:2] &quot; To the end of the visual selection, '&gt; let [line_end, column_end] = getpos(&quot;'&gt;&quot;)[1:2] let lines = getline(line_start, line_end) if len(lines) == 0 return '' endif &quot; Take into account the selection setting let lines[-1] = lines[-1][: column_end - (&amp;selection == 'inclusive' ? 1 : 2)] let lines[0] = lines[0][column_start - 1:] return join(lines, &quot;\n&quot;) endfunction function! InsertText(text) let cur_line_num = line('.') let cur_col_num = col('.') let orig_line = getline('.') let modified_line = \ strpart(orig_line, 0, cur_col_num - 1) \ . a:text \ . strpart(orig_line, cur_col_num - 1) &quot; Replace the current line with the modified line. call setline(cur_line_num, modified_line) &quot; Place cursor on the last character of the inserted text. call cursor(cur_line_num, cur_col_num + strlen(a:text)) endfunction function! WrapIt(wrapper) let sel = GetVisualSelection() &quot; Create the full end text we want let text = '?php ' . a:wrapper . '(' . sel . ') ?' &quot; Delete everything inside the opening and closing angled brackets normal di&lt; call InsertText(text) endfunction vmap &lt;localleader&gt;wt &lt;esc&gt;:call WrapIt('Output::text')&lt;cr&gt; vmap &lt;localleader&gt;wi &lt;esc&gt;:call WrapIt('Output::id')&lt;cr&gt; vmap &lt;localleader&gt;wa &lt;esc&gt;:call WrapIt('Output::attrib')&lt;cr&gt; vmap &lt;localleader&gt;wh &lt;esc&gt;:call WrapIt('Output::html')&lt;cr&gt; </code></pre> <p>Personally I have the <code>WrapIt</code> function and the mappings in a project scoped vimrc but the <code>GetVisualSelection</code> and <code>InsertText</code> functions are ripe for putting in a global autoload functions files.</p> <p>So with that in place I can select some text using, say, <code>viw</code> and hit <code>,it</code> (my localleader is a comma) et voilà - text wrapped and cleaned up!</p></div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/vim" hreflang="en">vim</a></div> <div class="field__item"><a href="/tag/yakshaving" hreflang="en">yakshaving</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/meal" hreflang="en">meal</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">26/07/2021</div> </div> Sun, 25 Jul 2021 23:05:19 +0000 admin 47 at https://michaelwelford.com Drupal tech blogging https://michaelwelford.com/series/drupal-tech-blogging <span class="field field--name-title field--type-string field--label-hidden">Drupal tech blogging</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 23/09/2019 - 15:37</span> <div class="field field--name-field-posts field--type-viewfield field--label-above"> <div class="field__label">List of blog posts</div> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_2 js-view-dom-id-badcabe2b631cc5ea012e6eb27ec4329a878a23286b62bb529354c46aac07899"> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/building-tech-blog-2019-introduction" hreflang="en">Building a tech blog in 2019, an introduction</a></li> </ol> </div> </div> </div> </div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/bespoke" hreflang="en">bespoke</a></div> <div class="field__item"><a href="/tag/drupal" hreflang="en">Drupal</a></div> <div class="field__item"><a href="/tag/php" hreflang="en">php</a></div> </div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> <div class="field__item"><a href="/category/technology" hreflang="en">technology</a></div> </div> </div> Mon, 23 Sep 2019 06:07:48 +0000 admin 38 at https://michaelwelford.com Building a tech blog in 2019, an introduction https://michaelwelford.com/post/building-tech-blog-2019-introduction <span class="field field--name-title field--type-string field--label-hidden">Building a tech blog in 2019, an introduction</span> <div class="field field--name-field-series-listing field--type-viewfield field--label-hidden"> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_3 js-view-dom-id-2c2629daf93265b05b750d51688c57ab145031d1e1d2ef92d0e1d98ad881f2e8"> <div class="view-header"> This is part of the series: <a href="/series/drupal-tech-blogging" hreflang="en">Drupal tech blogging</a> </div> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/building-tech-blog-2019-introduction" hreflang="en">Building a tech blog in 2019, an introduction</a></li> </ol> </div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 23/09/2019 - 10:50</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2><a id="user-content-the-who-and-the-what-now" href="#the-who-and-the-what-now" name="the-who-and-the-what-now" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>The who and the what now</h2> <p>Squarespace, Wix, Wordpress, static site generators, ya da ya da - there are so many options nowadays to a get a blog going that it takes a certain type of crazy to want to roll your own or use something seemingly over the top like <a rel="noopener noreferrer" target="_blank" href="http://drupal.org">Drupal</a>. Yes, remember Drupal, the No. 3 most popular CMS? Well some of us haven’t forgotten and even though it’s probably (<em>probably</em>?) a terrible choice for someone who just wants to <em>getshitdonenow</em> it is perhaps a fine choice for someone who likes to shave yaks, tinker with features and lean toward <a href="/post/extreme-value-delivery">extreme value delivery</a>.</p> <p>Given that, it is no surprise that this blog is running on Drupal and I’m going to spend a few posts going over what is under the hood and pointing out some tricks that this old dog can still perform. <em>Woof!</em></p> <h2><a id="user-content-yeah-yeah-thats-nice-but-really-why" href="#yeah-yeah-thats-nice-but-really-why" name="yeah-yeah-thats-nice-but-really-why" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Yeah yeah, that’s nice, but really <em>why</em>?</h2> <p>So I maybe crazy but I’m not stark raving. There be <a rel="noopener noreferrer" target="_blank" href="https://en.wikipedia.org/wiki/Hamlet">method to the madness</a> or at least I want to do stuff that I would find annoying on other setups, namely:</p> <ul> <li>Different types of categorisation</li> <li>Automated image handling</li> <li>Patterns for auto generating URLs</li> <li>Content modelling</li> <li>Full markdown support</li> <li>Posting via API</li> <li>Scheduling, published at vs update dates</li> <li>Sync via cli</li> <li>Fully flexible sane themeing for fluid typography</li> <li>Schmancy things like proper quotes, punctuation</li> <li>Lazy loading of all the things</li> <li>Posting to 3rd party services</li> </ul> <p>Yes I don’t <em>need</em> some of those things but I sure as hell <em>wants</em> them and as a dev I <em>can</em> have them so let’s get cracking.</p> <h2><a id="user-content-the-base-setup" href="#the-base-setup" name="the-base-setup" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>The base setup</h2> <p>Let’s kick off with what’s going on at a base level. Here are the Drupal 8 contributed modules “of note” that are installed to get us a part of the way:</p> <ul> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/admin_toolbar">Admin Toolbar</a> + <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/adminimal_admin_toolbar">Adminimal Admin Toolbar</a> for better drop down menus and shortcuts when in the backend</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/viewfield">Viewfield</a> to show views / lists of information inside a blog post</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/markdown">Markdown</a> for markdown support (more on that later)</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/pathologic">Pathologic</a> for correcting paths in posts</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/insert">Insert</a> for inserting images into the markdown</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/entity_pager">Entity Pager</a> for simple next and previous buttons lazy stylee</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/publication_date">Publication Date</a> to have a separate date of publication vs updated</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/popular_tags">Popular Tags</a> to make tagging of posts a bit more sensible</li> <li> <a rel="noopener noreferrer" target="_blank" href="https://www.drupal.org/project/draggableviews">Draggable Views</a> for arranging posts that are in series with ye olde drag and drop</li> </ul> <p>…plus a bunch of the usual suspects: Entity Browser, File Entity, Media Entity Browser, Pathauto, Redirect, Scheduler, Token, Metatag, Adminimal Theme, Prism etc.</p> <h2><a id="user-content-whats-next" href="#whats-next" name="whats-next" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>What’s next</h2> <p>That’s all well and good but that is just a grab bag of <em>stuff</em> that doesn’t really add up to a blogging system that fits together into a cohesive whole. So that’s what I hope to put out over the next few months, including:</p> <ul> <li>How to get markdown going with all the bells and gfm whistles</li> <li>Implementing the concept of <em>Series</em> of posts</li> <li>Syncing</li> <li>Front matter API support (actually I am currently developing that from scratch!)</li> <li>Optimisation etc.</li> </ul> <p>Eventually I hope to make a profile (Drupal for distribution) out of it with a couple of themes but let’s see how we go.</p></div> <div class="field field--name-field-series field--type-entity-reference field--label-above"> <div class="field__label">// @Series</div> <div class="field__item"><a href="/series/drupal-tech-blogging" hreflang="en">Drupal tech blogging</a></div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/drupal" hreflang="en">Drupal</a></div> <div class="field__item"><a href="/tag/bespoke" hreflang="en">bespoke</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/snack" hreflang="en">snack</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">23/09/2019</div> </div> Mon, 23 Sep 2019 01:20:25 +0000 admin 37 at https://michaelwelford.com More tmux scripting https://michaelwelford.com/post/more-tmux-scripting <span class="field field--name-title field--type-string field--label-hidden">More tmux scripting</span> <div class="field field--name-field-series-listing field--type-viewfield field--label-hidden"> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_3 js-view-dom-id-858bf723935523bda6b33c4cce6fc3c04a1b610cfc933a80afa53f57ba2b1f53"> <div class="view-header"> This is part of the series: <a href="/series/customising-tmux" hreflang="en">Customising Tmux</a> </div> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/more-tmux-scripting" hreflang="en">More tmux scripting</a></li> <li><a href="/post/saving-time-preset-tmux-setup" hreflang="en">Saving time with a preset tmux setup</a></li> <li><a href="/post/lets-put-current-itunes-track-tmux-status-line" hreflang="en">Let&#039;s put the current iTunes track into the Tmux status line</a></li> </ol> </div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 15/09/2019 - 17:02</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Following on from <a href="/post/saving-time-preset-tmux-setup">Saving time with a preset tmux setup</a> I recently created a more <del>convoluted</del> indepth setup.</p> <h2><a id="user-content-the-script" href="#the-script" name="the-script" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>The Script</h2> <p><code>setup.sh</code>:</p> <pre><code class="language-bash">#!/bin/zsh # Note that this assumes base index of 1 CWD=$(pwd) SESSION_NAME=&quot;$1&quot; # detach from a tmux session if in one tmux detach &gt; /dev/null # Create a new session, -d means detached itself set -- $(stty size) # $1 = rows $2 = columns tmux new-session -d -s $SESSION_NAME -x &quot;$2&quot; -y &quot;$(($1 - 1))&quot; tmux new-window -t $SESSION_NAME:1 -n 'code' tmux new-window -t $SESSION_NAME:2 -n 'test' tmux new-window -t $SESSION_NAME:3 -n 'php' tmux new-window -t $SESSION_NAME:4 -n 'vim' tmux new-window -t $SESSION_NAME:5 -n 'falcon' tmux new-window -t $SESSION_NAME:5 -n 'task' ## Test Window tmux select-window -t $SESSION_NAME:2 tmux split-window -h -l70 tmux split-window -v -l50 tmux select-pane -t 1 tmux send-keys &quot;~pct&quot; C-m tmux send-keys &quot;v&quot; C-m tmux select-pane -t 2 tmux send-keys &quot;~pct&quot; C-m tmux send-keys &quot;/usr/local/bin/chromedriver --url-base=/wd/hub&quot; C-m tmux select-pane -t 3 tmux send-keys &quot;~pct&quot; C-m ## PHP Window tmux select-window -t $SESSION_NAME:3 tmux split-window -h -l70 tmux select-pane -t 1 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;vl ep&quot; C-m tmux select-pane -t 2 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;php -a&quot; C-m ## Vim Window tmux select-window -t $SESSION_NAME:4 tmux send-keys &quot;cd ~/.config&quot; C-m ## Falcon Window tmux select-window -t $SESSION_NAME:5 tmux split-window -h -p50 tmux select-pane -t 1 tmux send-keys &quot;~falcon&quot; C-m tmux select-pane -t 2 tmux send-keys &quot;~falcon&quot; C-m ## Taskwarrior tmux select-window -t $SESSION_NAME:6 tmux send-keys &quot;~/.config&quot; C-m tmux send-keys &quot;t&quot; C-m ## Main Window tmux select-window -t $SESSION_NAME:1 tmux rename-window 'code' tmux split-window -h -l70 tmux split-window -v -l50 tmux select-pane -t 2 tmux send-keys &quot;~pcp&quot; C-m tmux select-pane -t 3 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;figlet -f roman Ready! | lolcat -t&quot; C-m tmux select-pane -t 1 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;v&quot; C-m # Finally attach to it tmux attach -t $SESSION_NAME </code></pre> <p>Now this is mostly standard fare (covered in the linked post) but I think there are a few additions worth jumping into.</p> <h2><a id="user-content-directory-hashes" href="#directory-hashes" name="directory-hashes" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Directory hashes</h2> <p>Zsh has a wonderful feature called a directory hash which looks like the following:</p> <pre><code class="language-bash">hash -d dir=~/dir </code></pre> <p>This will then allow you to put <code>~dir</code> in the place of any shell command where a directory could be used and also you just type in <code>~dir</code> to cd into it.</p> <h2><a id="user-content-triggering-a-leader-command-on-vim-startup" href="#triggering-a-leader-command-on-vim-startup" name="triggering-a-leader-command-on-vim-startup" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Triggering a leader command on Vim startup</h2> <p>It’s quite usual to have a number of common config files editable via some Vim mappings. e.g. <code>&lt;leader&gt;ev</code> to edit the Vim config, <code>&lt;leader&gt;et</code> to edit the Tmux config etc. But what if you wanted to directly trigger such a mapping on Vim startup?</p> <p>One way to achieve this is with the following in your <code>.zshrc</code>:</p> <pre><code class="language-bash">run_vim_leader() { com=&quot;NormLead $1&quot; nvim -c &quot;$com&quot; } alias vl='run_vim_leader' </code></pre> <p>…paired with the following vimscript in my <code>.vimrc</code>:</p> <pre><code class="language-vim">function! ExecuteLeader(suffix) let l:leader = get(g:,&quot;mapleader&quot;,&quot;\\&quot;) if l:leader == ' ' let l:leader = '1' . l:leader endif execute &quot;normal &quot;.l:leader.a:suffix endfunction command! -nargs=1 NormLead call ExecuteLeader(&lt;f-args&gt;) nnoremap &lt;leader&gt;ev :edit $MYVIMRC&lt;cr&gt; </code></pre> <p>Now you can simply do <code>vl ev</code> to edit your <code>.vimrc</code> from your shell. At this point, you may be saying to yourself <em>ahem, I could just make an alias in <insert shell of choice></em> …but then how would you use that when you are in Vim itself? and what if you want to run <em>other</em> leader commands on startup? huh?! tenuous / contrived? I think not.</p> <h2><a id="user-content-starting-up-slime-and-a-php-repl" href="#starting-up-slime-and-a-php-repl" name="starting-up-slime-and-a-php-repl" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Starting up slime and a PHP REPL</h2> <p>Having a local REPL to try out random snippets is a great time saver. An easy enough way to do this with Vim is using the <a rel="noopener noreferrer" target="_blank" href="https://github.com/jpalardy/vim-slime">Slime</a> plugin. In my case I setup a Tmux split on the right running php in interactive mode (<code>php -a</code>) which I can send test code to from Vim with just a <c-c><c-c> (either from visual mode or of the current paragraph). To get Vim to startup ready to go I have the following in my <code>.vimrc</code>:</p> <pre><code class="language-vim">nnoremap &lt;leader&gt;ep :call StartSlime()&lt;cr&gt; function! StartSlime() execute 'bd' let g:startify_disable_at_vimenter=1 execute 'new' execute 'only' execute 'set ft=php' call append(0, &quot;&lt;?php&quot;) endfunction </code></pre> <p>Essentially this will:</p> <ul> <li>destroy the Startify buffer</li> <li>make a new buffer</li> <li>make it the only buffer</li> <li>set the filetype to php</li> <li>append <code>&lt;?php</code> to the top of the buffer</li> </ul> <p>I then start this up via the <code>run_vim_leader</code> bash function via <code>vl ep</code> (see above).</p> <h2><a id="user-content-the-complete-php-window" href="#the-complete-php-window" name="the-complete-php-window" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>The complete PHP window</h2> <p>Just to bring that all together here is the complete PHP window part of the Tmux setup script:</p> <pre><code class="language-bash">tmux select-window -t $SESSION_NAME:3 tmux split-window -h -l70 tmux select-pane -t 1 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;vl ep&quot; C-m tmux select-pane -t 2 tmux send-keys &quot;~pcp&quot; C-m tmux send-keys &quot;php -a&quot; C-m </code></pre> <p>…sweet!</p></div> <div class="field field--name-field-series field--type-entity-reference field--label-above"> <div class="field__label">// @Series</div> <div class="field__item"><a href="/series/customising-tmux" hreflang="en">Customising Tmux</a></div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/vim" hreflang="en">vim</a></div> <div class="field__item"><a href="/tag/tmux" hreflang="en">tmux</a></div> <div class="field__item"><a href="/tag/terminal" hreflang="en">terminal</a></div> <div class="field__item"><a href="/tag/bespoke" hreflang="en">bespoke</a></div> <div class="field__item"><a href="/tag/yakshaving" hreflang="en">yakshaving</a></div> <div class="field__item"><a href="/tag/bash" hreflang="en">bash</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/meal" hreflang="en">meal</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">15/09/2019</div> </div> Sun, 15 Sep 2019 07:32:01 +0000 admin 36 at https://michaelwelford.com Customising Tmux https://michaelwelford.com/series/customising-tmux <span class="field field--name-title field--type-string field--label-hidden">Customising Tmux</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 30/09/2018 - 10:17</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>This is a series on customising the best terminal multiplexer on the planet, Tmux.</p></div> <div class="field field--name-field-posts field--type-viewfield field--label-above"> <div class="field__label">List of blog posts</div> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_2 js-view-dom-id-51fb0e0155b5ae331aeb947d8462af08e7b144ccb1648998846c3021d877ba16"> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/more-tmux-scripting" hreflang="en">More tmux scripting</a></li> <li><a href="/post/saving-time-preset-tmux-setup" hreflang="en">Saving time with a preset tmux setup</a></li> <li><a href="/post/lets-put-current-itunes-track-tmux-status-line" hreflang="en">Let&#039;s put the current iTunes track into the Tmux status line</a></li> </ol> </div> </div> </div> </div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/tmux" hreflang="en">tmux</a></div> </div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> Sun, 30 Sep 2018 00:47:12 +0000 admin 30 at https://michaelwelford.com Saving time with a preset tmux setup https://michaelwelford.com/post/saving-time-preset-tmux-setup <span class="field field--name-title field--type-string field--label-hidden">Saving time with a preset tmux setup</span> <div class="field field--name-field-series-listing field--type-viewfield field--label-hidden"> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_3 js-view-dom-id-858bf723935523bda6b33c4cce6fc3c04a1b610cfc933a80afa53f57ba2b1f53"> <div class="view-header"> This is part of the series: <a href="/series/customising-tmux" hreflang="en">Customising Tmux</a> </div> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/more-tmux-scripting" hreflang="en">More tmux scripting</a></li> <li><a href="/post/saving-time-preset-tmux-setup" hreflang="en">Saving time with a preset tmux setup</a></li> <li><a href="/post/lets-put-current-itunes-track-tmux-status-line" hreflang="en">Let&#039;s put the current iTunes track into the Tmux status line</a></li> </ol> </div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 16/09/2018 - 14:32</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Programming is all about doing the same thing… <em>over and over again, ad nauseam</em>. No, not the computer, the poor programmer as they work on similar projects bouncing around all the different tools.</p> <p>For example, let’s take Drupal development - usually once you are in the midst of it, you may be accessing:</p> <ul> <li>An editor (Vim, <em>naturally</em>)</li> <li>A terminal for running system commands e.g. <code>drush cr</code>, <code>drush cedit</code>, <code>drupal generate:module</code> etc.</li> <li>Maybe a todo list / notes</li> <li>Log output</li> <li>Watch output e.g. <code>npm run watch</code> </li> <li>Test output e.g. <code>phpunit</code>, <code>codeception</code> etc.</li> <li>File ops e.g. <code>ranger</code> </li> <li>Reference material</li> <li>etc.</li> </ul> <p>That may end up looking a bit like this:</p> <img src="/sites/default/files/styles/max_1300x1300/public/2018-09/Screen%20Shot%202018-09-16%20at%202.42.34%20pm.png" width="1300" height="814" alt="Drupal development screenshot" class="image-max_1300x1300" data-insert-type="image" data-entity-type="file" data-entity-uuid="insert-max_1300x1300-312a4c52-4a6e-424d-b3e4-658cdbb073b1" /> <p><strong>Note</strong> the Tmux status, bottom left, where it shows that I am in the first window of three.</p> <p>As this is typical, wouldn’t it be nice if, I don’t know, you could run a command such as <code>tmd &lt;name of session&gt;</code> and it would set everything up <em>just so</em>. Also, over time, we could then refine this setup and get all the benefits of finessing it - or have multiple scripts depending on the type of project.</p> <h2><a id="user-content-the-script" href="#the-script" name="the-script" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>The script</h2> <p>No problem, take a look at this script <code>drupal.sh</code>:</p> <pre><code class="language-bash">#!/bin/zsh # Note that this assumes base index of 1 # check for existence of required things # $1 is the name of the window # we are in the directory of the drupal project if [ $# -eq 0 ] then echo &quot;No arguments supplied, requires name of window.&quot; exit 1 fi CWD=$(pwd) SESSION_NAME=&quot;$1&quot; # detach from a tmux session if in one tmux detach &gt; /dev/null # Create a new session, -d means detached itself set -- $(stty size) # $1 = rows $2 = columns tmux new-session -d -s $SESSION_NAME -x &quot;$2&quot; -y &quot;$(($1 - 1))&quot; tmux new-window -t $SESSION_NAME:1 -n 'code' tmux new-window -t $SESSION_NAME:2 -n 'logs' tmux new-window -t $SESSION_NAME:3 -n 'zsh' ## Logs window tmux select-window -t $SESSION_NAME:2 # Start up the logs listener tmux send-keys &quot;vbin/tail -f /var/log/apache2/error.log | clog drupal&quot; C-m ## Zsh window tmux select-window -t $SESSION_NAME:3 tmux rename-window 'Zsh' ## Main Window tmux select-window -t $SESSION_NAME:1 tmux rename-window 'code' # Split into left and right tmux split-window -h -p30 # Right ready for taking commands / tests. tmux select-pane -t 2 tmux send-keys &quot;figlet -f roman Ready! | lolcat -t&quot; C-m # Left for neovim. tmux select-pane -t 1 tmux send-keys &quot;v&quot; C-m # Finally attach to it tmux attach -t $SESSION_NAME </code></pre> <h2><a id="user-content-how-it-works" href="#how-it-works" name="how-it-works" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>How it works</h2> <p>The process can be broken down as follows:</p> <ul> <li>Creating a new session</li> <li>Creating windows</li> <li>Creating panes</li> <li>Sending commands to the panes / windows</li> </ul> <h3><a id="user-content-creating-a-new-session" href="#creating-a-new-session" name="creating-a-new-session" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Creating a new session</h3> <p>Creating a new session is as simple as <code>tmux new-session -s &lt;name-of-session&gt;</code>. In the example script I have a bit more going on:</p> <pre><code class="language-bash"># Create a new session, -d means detached itself set -- $(stty size) # $1 = rows $2 = columns tmux new-session -d -s $SESSION_NAME -x &quot;$2&quot; -y &quot;$(($1 - 1))&quot; </code></pre> <p>What I am doing here is getting the current screen resolution and then creating a detached session of that size - the reason being that if you don’t specify a size using the <code>-x</code> parameter then if you try to specify window split sizes it will <em>wig out</em> since it has no point of reference for “size”.</p> <h3><a id="user-content-creating-windows" href="#creating-windows" name="creating-windows" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Creating windows</h3> <p>Creating a window can be accomplished via <code>tmux new-window -n &lt;name-of-window&gt;</code>. In the example we have:</p> <pre><code class="language-bash">tmux new-window -t $SESSION_NAME:1 -n 'code' tmux new-window -t $SESSION_NAME:2 -n 'logs' tmux new-window -t $SESSION_NAME:3 -n 'zsh' </code></pre> <p>Here we create three windows - the <code>-t</code> flag is so that we can specify the target of the windows, which in this case is the session that we just created and the index of where they should appear.</p> <p>We can then target windows with <code>tmux select-window -t &lt;name-of-session&gt;:&lt;index&gt;</code> for further commands.</p> <h3><a id="user-content-creating-panes" href="#creating-panes" name="creating-panes" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Creating panes</h3> <p>Often you will want to split up a window into multiple panes. This can be done with something like <code>tmux split-window -h -p&lt;percentage&gt;</code> where <code>-h</code> signifies a horizontal split (guess how a vertical split is specified?) and <code>-p</code> signifies a percentage split. In the example I create a 30 percent split but you can of course specify by pixel if that is your jam.</p> <p>Once you have created one or more splits, you can target panes with <code>tmux select-pane -t &lt;index-of-pane&gt;</code> for more commands.</p> <h3><a id="user-content-sending-commands-to-the-panes--windows" href="#sending-commands-to-the-panes--windows" name="sending-commands-to-the-panes--windows" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Sending commands to the panes / windows</h3> <p>Lastly, once we have our windows and panes ready, we can send them further commands to start things up. Some examples from the above:</p> <ul> <li> <code>tmux send-keys &quot;vbin/tail -f /var/log/apache2/error.log | clog drupal&quot; C-m</code> </li> </ul> <p>(run the <code>tail</code> command in watch mode against the apache error log, piped into <a rel="noopener noreferrer" target="_blank" href="https://taskwarrior.org/docs/clog/what.html">clog</a> - the <code>C-m</code> is used to send an <code>&lt;Enter&gt;</code> to a pane or window)</p> <ul> <li> <code>tmux send-keys &quot;figlet -f roman Ready! | lolcat -t&quot; C-m</code> </li> </ul> <p>(run <code>figlet</code> with the string “Ready!”, piped into lolcat in true colour mode )</p> <h2><a id="user-content-finishing-up" href="#finishing-up" name="finishing-up" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Finishing up</h2> <p>Rounding out the script we have a call to <code>tmux attach -t &lt;name-of-session&gt;</code> which makes it visible. In the script, the name of the session is passed in as a parameter. For extra convenience I have the following alias in my <code>.zshrc</code> to run this script:</p> <pre><code class="language-bash">alias tmd='~/.config/tmux/drupal.sh' </code></pre> <p>Obviously you <em>don’t</em> have to attach to a Tmux session - if you had the need, your script could start up all kinds of processes and then you could attach only to check it whilst doing other things (or not!). Tmux also supports multiple people attaching to a session, sending commands to specific sessions, saving sessions (via plugins) etc. The possibilities <em>runneth over</em>.</p></div> <div class="field field--name-field-series field--type-entity-reference field--label-above"> <div class="field__label">// @Series</div> <div class="field__item"><a href="/series/customising-tmux" hreflang="en">Customising Tmux</a></div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/tmux" hreflang="en">tmux</a></div> <div class="field__item"><a href="/tag/vim" hreflang="en">vim</a></div> <div class="field__item"><a href="/tag/terminal" hreflang="en">terminal</a></div> <div class="field__item"><a href="/tag/bespoke" hreflang="en">bespoke</a></div> <div class="field__item"><a href="/tag/drupal" hreflang="en">Drupal</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/meal" hreflang="en">meal</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">16/09/2018</div> </div> Sun, 16 Sep 2018 05:02:32 +0000 admin 29 at https://michaelwelford.com Let's put the current iTunes track into the Tmux status line https://michaelwelford.com/post/lets-put-current-itunes-track-tmux-status-line <span class="field field--name-title field--type-string field--label-hidden">Let&#039;s put the current iTunes track into the Tmux status line</span> <div class="field field--name-field-series-listing field--type-viewfield field--label-hidden"> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_3 js-view-dom-id-858bf723935523bda6b33c4cce6fc3c04a1b610cfc933a80afa53f57ba2b1f53"> <div class="view-header"> This is part of the series: <a href="/series/customising-tmux" hreflang="en">Customising Tmux</a> </div> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/more-tmux-scripting" hreflang="en">More tmux scripting</a></li> <li><a href="/post/saving-time-preset-tmux-setup" hreflang="en">Saving time with a preset tmux setup</a></li> <li><a href="/post/lets-put-current-itunes-track-tmux-status-line" hreflang="en">Let&#039;s put the current iTunes track into the Tmux status line</a></li> </ol> </div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sat, 08/09/2018 - 14:59</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>When you go <em>full terminal</em> it can be nice to know what music is playing for when it really sucks/rocks. Wouldn’t it be nice to get something like this into your Tmux status bar:</p> <img src="/sites/default/files/2018-09/Screen%20Shot%202018-09-08%20at%207.37.57%20pm.png" width="521" height="45" alt="tmux itunes example" data-insert-type="image" data-entity-type="file" data-entity-uuid="ee9b5852-4c75-42f8-bc3e-aca1cc92aa5b" /> <p>(the answer is <em>yes</em>)</p> <h2><a id="user-content-lets-do-this" href="#lets-do-this" name="lets-do-this" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Let’s do this</h2> <p>First you need to get the following into a script file, let’s say we put this into <code>~/.config/itunes_status.sh</code>.</p> <pre><code class="language-bash">#!/usr/bin/env bash ITUNES_TRACK=$(osascript &lt;&lt;EOF if appIsRunning(&quot;iTunes&quot;) then tell app &quot;iTunes&quot; to get the name of the current track end if on appIsRunning(appName) tell app &quot;System Events&quot; to (name of processes) contains appName end appIsRunning EOF) if [[ ! -z &quot;$ITUNES_TRACK&quot; ]]; then ITUNES_ARTIST=$(osascript &lt;&lt;EOF if appIsRunning(&quot;iTunes&quot;) then tell app &quot;iTunes&quot; to get the artist of the current track end if on appIsRunning(appName) tell app &quot;System Events&quot; to (name of processes) contains appName end appIsRunning EOF) TRACK_LEN=${#ITUNES_TRACK} if [[ &quot;$TRACK_LEN&quot; -gt 30 ]]; then ITUNES_TRACK=`echo &quot;$ITUNES_TRACK&quot; | cut -c -30` ITUNES_TRACK+=... fi ARTIST_LEN=${#ITUNES_ARTIST} if [[ &quot;$ARTIST_LEN&quot; -gt 20 ]]; then ITUNES_ARTIST=`echo &quot;$ITUNES_ARTIST&quot; | cut -c -20` ITUNES_ARTIST+=... fi echo '#[fg=#99a4bc]♫#[fg=#b4b4b9]' &quot;$ITUNES_TRACK&quot; '#[fg=#787882]-#[fg=#b4b4b9]' &quot;$ITUNES_ARTIST&quot; exit else echo &quot;#[fg=#787882]No music playing&quot; fi </code></pre> <p>Essentially this does the following:</p> <ul> <li>Check if iTunes is running, and if so grab the name of the track</li> <li>If we have a track name, also grab the artist</li> <li>If the track name is over 30 characters in length, truncate and insert an ellipsis</li> <li>If the artist name is over 20 characters in length, do the same</li> <li>Output this with some colours and space it out</li> <li>Otherwise write “No music playing”</li> </ul> <h2><a id="user-content-insert-into-the-tmux-status-bar" href="#insert-into-the-tmux-status-bar" name="insert-into-the-tmux-status-bar" class="heading-permalink" aria-hidden="true" title="Permalink"><svg class="heading-permalink-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style="-ms-transform: rotate(360deg); -webkit-transform: rotate(360deg); transform: rotate(360deg);" preserveAspectRatio="xMidYMid meet" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5c0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5c0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" fill="#bfdaff"/></svg></a>Insert into the Tmux status bar</h2> <p>Ok, so that’s nice an’ all but we need to get that into the Tmux status. That can be accomplished by inserting something like the following into your <code>.tmux.conf</code>:</p> <pre><code class="language-bash">set -g status-right &quot;#(~/.config/itunes_status.sh) #[fg=#57575e]│ #[fg=white]%d/%m/%Y %H:%M &quot; </code></pre> <p><strong>Note</strong> as a “bonus” I have also put in the time after the iTunes track (yes, yes, such a generous bonus). If you are wondering what those colour hex values are, they come from the <a rel="noopener noreferrer" target="_blank" href="https://github.com/fenetikm/falcon">falcon</a> theme (made by moi). Don’t forget that you will need to make this script executable too.</p></div> <div class="field field--name-field-series field--type-entity-reference field--label-above"> <div class="field__label">// @Series</div> <div class="field__item"><a href="/series/customising-tmux" hreflang="en">Customising Tmux</a></div> </div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/tmux" hreflang="en">tmux</a></div> <div class="field__item"><a href="/tag/terminal" hreflang="en">terminal</a></div> <div class="field__item"><a href="/tag/applescript" hreflang="en">applescript</a></div> <div class="field__item"><a href="/tag/bash" hreflang="en">bash</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/snack" hreflang="en">snack</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">08/09/2018</div> </div> Sat, 08 Sep 2018 05:29:20 +0000 admin 28 at https://michaelwelford.com How to determine the name of a Drupal dynamic permission https://michaelwelford.com/post/how-determine-name-drupal-dynamic-permission <span class="field field--name-title field--type-string field--label-hidden">How to determine the name of a Drupal dynamic permission</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sun, 02/09/2018 - 12:41</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Here’s something…. <em>funny</em> aka painful.</p> <p>I tried to take a shortcut in determining a dynamic permission for a workflow by just looking at the names of the classes on the permssions page and I saw this:</p> <pre><code>edit-permissions-use-study-plan-transition-archive edit-permissions-use-study-plan-transition-create-new-draft </code></pre> <p>etc.</p> <p>One incorrectly thought that maybe the name of the permission was <code>use study plan transition create new draft</code> but no - there is no way to tell which one of those dashes translates to underscores.</p> <p><strong>Hold the boat</strong></p> <p>If one looks a bit further (I just did this) in at the markup for the actual checkboxes on the permissions one will then find:</p> <pre><code class="language-html">&lt;input class=&quot;rid-anonymous js-rid-anonymous form-checkbox&quot; data-drupal-selector=&quot;edit-anonymous-use-study-plan-transition-archive&quot; type=&quot;checkbox&quot; id=&quot;edit-anonymous-use-study-plan-transition-archive&quot; name=&quot;anonymous[use study_plan transition create_new_draft]&quot; value=&quot;1&quot;&gt; </code></pre> <p>…where <code>use study_plan transition create_new_draft</code> can be seen.</p> <p>Before I <em>actually used my eyes and clicked around</em> I was going to say that the code to find these things out is a trivial:</p> <pre><code class="language-php">$role = Role::load('admin'); $all_permissions = $role-&gt;getPermissions(); </code></pre> <p>etc.</p> <p>Note that you can also use the <code>EntityTypeManager</code> to load up your roles but the storage is of type <code>user_storage</code> <em>of course</em>!</p></div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/drupal" hreflang="en">Drupal</a></div> <div class="field__item"><a href="/tag/php" hreflang="en">php</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/snack" hreflang="en">snack</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">02/09/2018</div> </div> Sun, 02 Sep 2018 03:11:47 +0000 admin 26 at https://michaelwelford.com The Vim expand region plugin https://michaelwelford.com/post/vim-expand-region-plugin <span class="field field--name-title field--type-string field--label-hidden">The Vim expand region plugin</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Sat, 25/08/2018 - 17:09</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Do you have a cramp in your hand from typing <code>viw</code> or <code>vi(</code> etc. ? Do you sometimes select something whilst editing only to think, hmmm, if only I could now easily easily select <em>just a bit more</em>?</p> <p>Well you need Vim awesomeness No. 17676865, the <a rel="noopener noreferrer" target="_blank" href="https://github.com/terryma/vim-expand-region">vim-expand-region</a> plugin!</p> <p>When I originally added this plugin in I didn’t bother to configure it and so it didn’t hit full awesome - but now I have put in the following plus the addition of <a rel="noopener noreferrer" target="_blank" href="https://github.com/kana/vim-textobj-line">two</a> <a rel="noopener noreferrer" target="_blank" href="https://github.com/kana/vim-textobj-indent">more</a> text object plugins:</p> <pre><code class="language-vim">let g:expand_region_text_objects = { \ 'iw' :0, \ 'iW' :0, \ 'i&quot;' :0, \ 'i''' :0, \ 'i]' :1, \ 'ib' :1, \ 'iB' :1, \ 'il' :1, \ 'ip' :1, \ 'ie' :0, \ } vmap v &lt;Plug&gt;(expand_region_expand) vmap &lt;C-v&gt; &lt;Plug&gt;(expand_region_shrink) </code></pre> <p>So now, by just hitting <code>vv</code> I can select a word, then another <code>v</code> for the line, then another for the paragraph etc. Win!</p></div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/vim" hreflang="en">vim</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/bite" hreflang="en">bite</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">25/08/2018</div> </div> Sat, 25 Aug 2018 07:39:04 +0000 admin 25 at https://michaelwelford.com Making your own colour scheme: Introduction https://michaelwelford.com/post/making-your-own-colour-scheme-introduction <span class="field field--name-title field--type-string field--label-hidden">Making your own colour scheme: Introduction</span> <div class="field field--name-field-series-listing field--type-viewfield field--label-hidden"> <div class="field__item field__item-label-hidden"> <div class="views-element-container"><div class="view view-series-listing view-id-series_listing view-display-id-block_3 js-view-dom-id-edb34150bb98508ac493a866e409e5d643d1326c2c6d247353af7e6aee102ec1"> <div class="view-header"> This is part of the series: <a href="/series/making-your-own-colour-scheme" hreflang="en">Making your own colour scheme</a> </div> <div class="view-content"> <div class="item-list"> <ol> <li><a href="/post/making-your-own-colour-scheme-introduction" hreflang="en">Making your own colour scheme: Introduction</a></li> </ol> </div> </div> </div> </div> </div> </div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><span lang="" about="/user/1" typeof="schema:Person" property="schema:name" datatype="">admin</span></span> <span class="field field--name-created field--type-created field--label-hidden">Mon, 13/08/2018 - 06:36</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>There’s nothing quite like a tailored suit - so comfortable, so thoughtful, so knowing, so… <em>you</em>. Don’t like the cuffs? Change them. Not sitting correctly over the shoes? Have them re-hemmed. Not enough velvet? No problemo.</p> <p>Or so I imagine if I could afford one.</p> <p>But what <em>I can</em> afford is my own colour scheme.</p> <p>I have been making changes to <a rel="noopener noreferrer" target="_blank" href="https://github.com/fenetikm/falcon">falcon</a> over the last few months or so and I am about to make another major release as this time I think I have got it right.</p> <p>Unlike a suit, a colour scheme has to be a work horse and not a show pony. Like good design and timeless classics like Helvetica or the LBD it has to be something that <em>works</em>. Something that is gimmicky and garish like a fascinator will annoy and grate over time. Sure, wear it to the races but not to work every day.</p> <p>And so I think I am finally at the point, on the second time around, where everything is balanced and working well. I mean, just look at it:</p> <p><img src="/sites/default/files/falcon_01-fs8.png" alt="Falcon screenshot" /></p> <p>I like it so much that I have created settings for most things that I use - Vim, the terminal, ranger etc. and hey, even this Drupal theme.</p> <p>So how does one get started making a colour scheme? Well, earnest and imagined reader, you are in luck! This is going to be the first in a series of constructing your own colour scheme. I will go through getting started to tweaking everything possible for <em>all the things</em>.</p> <p>Stay tuned.</p></div> <div class="field field--name-field-category field--type-entity-reference field--label-above"> <div class="field__label">// @Category</div> <div class="field__items"> <div class="field__item"><a href="/category/code" hreflang="en">code</a></div> <div class="field__item"><a href="/category/ideas" hreflang="en">ideas</a></div> </div> </div> <div class="field field--name-field-blog-tags field--type-entity-reference field--label-above"> <div class="field__label">// @Tags</div> <div class="field__items"> <div class="field__item"><a href="/tag/vim" hreflang="en">vim</a></div> <div class="field__item"><a href="/tag/bespoke" hreflang="en">bespoke</a></div> <div class="field__item"><a href="/tag/syntax" hreflang="en">syntax</a></div> <div class="field__item"><a href="/tag/terminal" hreflang="en">terminal</a></div> <div class="field__item"><a href="/tag/tmux" hreflang="en">tmux</a></div> <div class="field__item"><a href="/tag/design" hreflang="en">design</a></div> <div class="field__item"><a href="/tag/falcon" hreflang="en">falcon</a></div> </div> </div> <div class="field field--name-field-size field--type-entity-reference field--label-above"> <div class="field__label">// @Size</div> <div class="field__item"><a href="/size/snack" hreflang="en">snack</a></div> </div> <div class="field field--name-published-at field--type-published-at field--label-above"> <div class="field__label">// @</div><div class="field__item">13/08/2018</div> </div> Sun, 12 Aug 2018 21:06:33 +0000 admin 22 at https://michaelwelford.com