<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="pretty-atom-feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  
  <title>Blog Title</title>
  <subtitle>This is a longer description about your blog.</subtitle>
  <link href="https://example.com/feed/feed.xml" rel="self" />
  <link href="https://example.com/" />
  <updated>2026-07-14T17:46:58Z</updated>
  <id>https://example.com/</id>
  <author>
    <name>Your Name</name>
  </author>
  <entry>
    <title>L-System Explorations</title>
    <link href="https://example.com/blog/2026-07-14-l-system-explorations/" />
    <updated>2026-07-14T17:46:58Z</updated>
    <id>https://example.com/blog/2026-07-14-l-system-explorations/</id>
    <content type="html">&lt;h1 id=&quot;l-system-explorations&quot;&gt;L-System Explorations&lt;/h1&gt;
&lt;p&gt;A couple of years ago, I briefly played with a Python script to &lt;a href=&quot;https://github.com/JasmineElm/genuary/blob/main/2024/31.py&quot;&gt;generate svgs&lt;/a&gt; based on L-Systems.  The code was crude, generated a worrying amount of swastika-like images but it was fun to play with.  The initial script suffered some logical issues, such as miss-applying rules, not using the extended syntax, and having a crude method of image generation - calling the script would generate a pseudo-random result each time.  At the time, these were shortcomings that, though mildly annoying, were easy enough to work around through brute-forcing the script; generating hundreds of images, and picking out the most interesting ones.&lt;/p&gt;
&lt;p&gt;Last week, I returned to the idea, fixing logical bugs, and building out functionality to explore the idea more.  Beyond fixing the logical issues, my boals were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a defined CLI interface where rules and axioms can be specified&lt;/li&gt;
&lt;li&gt;extend the L-System grammar to include angle and scale change commands&lt;/li&gt;
&lt;li&gt;Develop methods to take an existing image and produce variant forms of it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My implementation is available &lt;a href=&quot;https://github.com/JasmineElm/lsys&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The script still has randomness at its heart, but it&#39;s now possible to create fractal-like images with a greater degree of control:&lt;/p&gt;
&lt;img src=&quot;https://example.com/blog/2026-07-14-l-system-explorations/fractal.svg&quot; alt=&quot;fractal-like image&quot;&gt;
&lt;p&gt;Similarly, more traditional &amp;quot;nature-like&amp;quot; images are possible:&lt;/p&gt;
&lt;img src=&quot;https://example.com/blog/2026-07-14-l-system-explorations/tree.svg&quot; alt=&quot;fractal tree&quot;&gt;
&lt;h2 id=&quot;using-the-script&quot;&gt;Using the Script&lt;/h2&gt;
&lt;p&gt;Calling the script with no parameters retains the original behaviour; a random set of rules will be created.  The rules are validated to ensure pushes and pops are matched, and opposing directives are not placed next to each other (e.g., &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;-&lt;/code&gt;).&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;python3 lsys.py&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a &lt;a href=&quot;https://github.com/JasmineElm/lsys/blob/main/lsys/config.toml&quot;&gt;configuration file&lt;/a&gt; which sets defaults.  You can either update these configuration items, or pass the parameters directly to the script.  For instance&lt;/p&gt;
&lt;pre class=&quot;language-ini&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Number of iterations to apply the L-System rules to the axiom tree&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;RECURSION_DEPTH&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;13&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in config.toml is equivalent to passing &lt;code&gt;--recursion 13&lt;/code&gt; to the script:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;python3 lsys_main.py &lt;span class=&quot;token parameter variable&quot;&gt;--recursion&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;      &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The resulting file will have a comment describing the rules to generate it:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!--
TITLE: LSYS PARAMS
PARADIGM: geometric
N: 13
AXIOM: F
RULES: {&#39;F&#39;: &#39;FF+&#39;}
INITIAL_ANGLE: 90
ROTATE_ANGLE: 120.0
LINE_LENGTH: 150
CREATED: 2026-07-17 18:51:54
--&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You could use these definitions to manually create a variation, but there is a &lt;code&gt;--read&lt;/code&gt; option which&#39;ll do this for you:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;❯ python3 lsys_main.py &lt;span class=&quot;token parameter variable&quot;&gt;--read&lt;/span&gt; output/F→FF+.svg&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which outputs the following:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token parameter variable&quot;&gt;--rules&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&#39;F&#39;: &#39;FF+&#39;&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--axiom&lt;/span&gt; F &lt;span class=&quot;token parameter variable&quot;&gt;--recursion&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt; --initial-angle &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rotation&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which can then be tweaked to generate variations on the first image.&lt;/p&gt;
&lt;p&gt;Perhaps more usefully, there is also a &lt;code&gt;--variant&lt;/code&gt; flag which will generate a variant of the image, based on the original rules:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;❯ python3 lsys_main.py &lt;span class=&quot;token parameter variable&quot;&gt;--variant&lt;/span&gt; output/F→FF+.svg&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;there is also an &lt;code&gt;--iterate&lt;/code&gt; flag which will generate a series of images, each one a variant of the previous one:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;❯ &lt;span class=&quot;token comment&quot;&gt;# create five variants of the original image&lt;/span&gt;
❯ python3 lsys_main.py &lt;span class=&quot;token parameter variable&quot;&gt;--iterate&lt;/span&gt; output/F→FF+.svg &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All of these features and more can be explored using the script&#39;s &lt;code&gt;--help&lt;/code&gt; flag:&lt;/p&gt;
&lt;pre class=&quot;language-text&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;L-System SVG Generator

options:
  -h, --help            show this help message and exit
  --rules RULES         User-defined L-System rules dictionary (or literal string)
  --axiom AXIOM         Axiom for the L-System
  --initial-angle INITIAL_ANGLE
                        Initial angle for the L-System
  --rotation ROTATION   Rotation angle for the L-System
  --recursion RECURSION
                        Recursion depth for the L-System (overrides config)
  --title TITLE         Title printed in logs
  --paradigm {geometric,stochastic,extended-geometric,extended-stochastic}
                        Rule generation mode
  --bleed BLEED         Margin padding (in mm)
  --options-per-rule OPTIONS_PER_RULE
                        Rule variations per char for stochastic
  --ppmm PPMM           Pixels per mm
  --paper-size PAPER_SIZE PAPER_SIZE
                        Paper size width and height (mm)
  --background-color BACKGROUND_COLOR
                        Background color
  --precision PRECISION
                        Decimal places to round geometry
  --angle-divisors ANGLE_DIVISORS [ANGLE_DIVISORS ...]
                        Acceptable divisors of 360
  --output-dir OUTPUT_DIR
                        Directory path for SVG files
  --scale SCALE         Scale multiplier for length (&lt; &gt;)
  --angle-increment ANGLE_INCREMENT
                        Angle increment for rotation ( ( ) )
  --weight-increment WEIGHT_INCREMENT
                        Weight increment for line thickness (# !)
  --read READ           Read an SVG file and output the command line arguments to recreate it
  --variant VARIANT     Generate a systematic variant of an existing SVG file
  --iterate ITERATE     Progressively generate iterations of an existing SVG file
  -n, --iterations ITERATIONS
                        Number of iterations to generate (used with --iterate)
  --filename {datetime,rules,unix}
                        Syntax for generating output filenames&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Agile Manchester 2024</title>
    <link href="https://example.com/blog/2024-05-26-Agile_Manchester/" />
    <updated>2024-05-25T17:46:58Z</updated>
    <id>https://example.com/blog/2024-05-26-Agile_Manchester/</id>
    <content type="html">&lt;p&gt;I&#39;ve been working in Agile development for a few years, but have never really
&amp;quot;got it&amp;quot;. The models, frameworks, methodologies always felt un-applicable, or
worse, an exercise in kabuki theatre that required extra admin. This is the first
Agile conference that I&#39;ve attended, and it massively helped to reframe my
understanding of Agile, and how we can use it.&lt;/p&gt;
&lt;h2 id=&quot;rewilding-agile&quot;&gt;Rewilding Agile&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;speaker&lt;/em&gt;: &lt;a href=&quot;https://thecynefin.co/&quot;&gt;Dave Snowden&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;First day, first talk. Dave&#39;s talk centred on the industrialisation of Agile.
The competing standards, &amp;quot;certificate factories&amp;quot;, and consultancy firms have
ultimately undermined the core principles of Agile. Instead of simplifying,
focussing on value, and delivering iteratively, Agile has become a sea of
dogmatic jargon that is often more about the process than the product. This
hugely resonated with me for a couple of reasons. First, the sea of jargon is
something I&#39;ve tried unsuccessfully tried to navigate. Second, Dave&#39;s framing in
a wider systemic context was music to my ears. The real world is nowhere near as
pure as vendor&#39;s marketing materials would have us believe. The tools themselves
are not bad, but painstakingly applying them to a complex system is an exercise
in futility. Dave&#39;s talk was a call to arms; we need to rewild Agile,
cross-pollinating methods, finding the best contextual use of tools for our
circumstances. Instead of using pre-defined Agile recipes we should be chefs,
creating our own recipes from the ingredients that work for us. To provide a
framework for this, Dave introduced
&lt;a href=&quot;https://cynefin.io/wiki/Method_hexi_kits&quot;&gt;Hexi&lt;/a&gt;. I was enthused that Hexi was
described as open-source - this seems like an obvious way of unshackling it from
consultancy dogma, although when I tried to find it, I couldn&#39;t. Irrespective,
I&#39;m looking forward to learning more about it, and seeing how it can be applied
to my work.&lt;/p&gt;
&lt;h2 id=&quot;painful-outcomes-7-mistakes-i-made-in-the-shift-to-value-led-development&quot;&gt;Painful outcomes: 7 mistakes I made in the shift to value-led development&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;speaker&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/hollydonohue/&quot;&gt;Holly Donohue&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;loved&lt;/em&gt; Holly&#39;s talk. Whilst Dave&#39;s talk was a call to arms, through using an
abstract, scientific model, Holly grounded her talk in her own experiences. The
combination of humour, humility and experience made for a compelling talk. There
was one slide in particular that immediately made the room relax; &lt;em&gt;Expectation
Vs Reality&lt;/em&gt;. Holly&#39;s talk was one of the many where I was left with a sense of
&amp;quot;of course, why would you do anything different?&amp;quot;. The reality is that even with
self-evident truths, we often fall into the trap of doing the wrong thing.
Saying &amp;quot;the quiet bit out loud&amp;quot;, and reflecting on our mistakes is a cornerstone
of Agile, and Holly&#39;s talk was a great example of this. Holly presented seven
mistakes she made in the shift to value-led development.&lt;/p&gt;
&lt;h3 id=&quot;1-balance-discovery-with-relationships&quot;&gt;1: Balance Discovery with Relationships&lt;/h3&gt;
&lt;p&gt;The product mindset centres on value. This is fine in perfect, emotionless
environments, but we don&#39;t live in a perfect world. Purely focussing on value
means we can alienate customers, or weaponise the Product Mindset. Holly
recounted being asked for a vanity feature; one she knew would gobble up time
and yield no value to customers. The feature, however was requested by a senior
stakeholder. Refusing the request in the name of value value would harm an
essential relationship. Conversely, developing the feature would result in lost
value; the features that added tangible value could not be delivered. Holly
offered the following advice; you need to balance value with relationships.
However logical your argument, you need to consider the emotional impact of your
delivery. building the wrong thing (vanity feature) for the right reasons (to
build social capital) is sometimes necessary to keep things moving. This
introduces a second tension; once you&#39;ve set the precedent that value can be
undermined how can you ensure that the value-led approach is maintained? Holly
suggested that instead of weaponising value, and approach of alternative finding
can help find accommodations. Played out, this could be a vanity feature that
delivers tangible value to the end-user.&lt;/p&gt;
&lt;h3 id=&quot;2-stakeholder-bank-balance&quot;&gt;2: Stakeholder bank balance&lt;/h3&gt;
&lt;p&gt;Building on this, Holly described the importance of stakeholder relationships.
Building capital with stakeholders is essential to unblocking progress. Holly
suggests that the fastest way to do this is to pay in before you withdraw. By
building this capital, you can help ensure that when you need a favour
returning, it is there. A clever way to manage this is to have those
conversations around collaboration, &amp;quot;how can I help you to help us?&amp;quot;. By
bringing the person into the process, we can avoid Project Managers working
against the team because they are implicitly excluded. On reflection, this is
such an obvious point, but it&#39;s a trap I&#39;ve fallen into. Holly noted there was a
cost to this, these relationships need actively maintaining, and this can cut
into our ability to deliver, however managed correctly, it greases the wheels
and removes more fundamental blockers.&lt;/p&gt;
&lt;h3 id=&quot;3-don-t-let-product-be-a-blocker&quot;&gt;3: Don’t let product be a blocker&lt;/h3&gt;
&lt;p&gt;Development is difficult, knowing what to do, and how to do it is hard. A
natural reaction is to build a structure to help guide us. Holly recounted a
situation where the what and how were so complex that management were left
wondering what was happening - where was the value? Presenting to management
that your product team have done lots of valuable research, but have no features
yet is a particularly hard-sell. Holly&#39;s advice was to flip communications; to
focus on the results and impact over the process and discovery.&lt;/p&gt;
&lt;h3 id=&quot;4-change-is-agile-too&quot;&gt;4: Change is Agile too&lt;/h3&gt;
&lt;p&gt;The only constant is change. I think it&#39;s a common experience that &amp;quot;this isn&#39;t
working, let&#39;s rip it up and start again&amp;quot;. Battling against this is hard to do.
Games are rarely won by changing the rules half-way through; there isn&#39;t the
time for teams to master the new rules. Holly&#39;s advice was to make small,
iterative course-corrections; identify what can be improved, and make small
changes to enable this. Alongside this, using metrics to measure these changes
is essential. This allows us to see what is working, and what isn&#39;t. This
approach increases transparency, and helps biulding both agency within the team,
and trust with stakeholders.&lt;/p&gt;
&lt;h3 id=&quot;5-dogma-bad&quot;&gt;5: Dogma = Bad&lt;/h3&gt;
&lt;p&gt;There is always more than one way to skin a cat. Becoming locked into dogma
means we are no longer open to new ways of thinking. I think that this links
back to the previous point; if we constantly change the rules, or assume we work
in a vacuum, we are not open to new ways of thinking. Agile is not agile because
you doggedly follow the process, it is agile because you are able to apply them
contextually. Holly&#39;s advice was to be open to new ways of thinking, to craft,
rather than apply solutions. Whilst this is another obvious point, there is a
clear temptation to assume &amp;quot;it&#39;s not working because we&#39;re not following the
rules correctly&amp;quot;.&lt;/p&gt;
&lt;h3 id=&quot;6-shift-happens&quot;&gt;6: Shift Happens&lt;/h3&gt;
&lt;p&gt;Start thinking about what maturity looks like before you are forced to grow up.
Holly recounted a story of battling for more agency. When she was &amp;quot;called out&amp;quot;
on this, she rapidly had to figure out what agency looked like, how it can be
measured and so on. Don&#39;t get caught out, think about your own (your team&#39;s)
perfect future before it is gifted.&lt;/p&gt;
&lt;h3 id=&quot;7-don-t-burn-out&quot;&gt;7: Don’t burn out&lt;/h3&gt;
&lt;p&gt;As a product owner, there&#39;s a risk of becoming the bottleneck for everything
product; being the punching-bag for management, the product team, and finding
accommodations. A natural response is to do more. Whilst this may work in the
short term, it will result in burn-out. The role is the role, but you have a
personal responsibility to avoid burning out. Holly&#39;s advice was to be aware of
this trap , and actively looking after yourself. Try to find sources of energy,
exercise, hobbies, socialising, and so on. This is a marathon, not a sprint.&lt;/p&gt;
&lt;h2 id=&quot;how-we-improved-our-ability-to-herd-cats-and-deliver-at-scale&quot;&gt;How we improved our ability to herd cats and deliver at scale&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speakers&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/sam-cann-558018a5/&quot;&gt;Samuel Cann&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://www.linkedin.com/in/liamdewes/&quot;&gt;Liam Dewes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cross-team collaboration is hard; It&#39;s certainly a challenge that I recognise.
Samuel and Liam Described a major project to massively engineer the back-end of
their highly complex, interleaved systems. This work impacted, and required the
cooperation of, many teams. They described starting from a traditional
hierarchical structure, and moving to a flatter, more agile one. The key to this
transformation was developing a narrative through which the teams could
understand the impact and importance of the work, and purposefully align their
efforts. To do this, they used the metaphor of the Gordian knot to frame their
solution. I think this is a good framing, but they perhaps missed a trick; the
Gordian knot was either cut or untied. Their metaphor was to cut the knot,
removing the cultural complexity. Their description however suggested they had
to untie the knot by identifying a using the leverage point of &lt;em&gt;purpose&lt;/em&gt;. Rather
than defining ways of working, they gave teams agency to define their own. This
resulted in an emergent, rather than imposed, solution. They noted that as work
progressed, they were conscious of being a decision making bottleneck, and so
they worked to devolve decision making to the teams. Overall, this was an
inspiring talk; wrangling hundreds of developers across multiple countries to
achieve a single goal is no mean feat.&lt;/p&gt;
&lt;h2 id=&quot;you-can-t-talk-to-me-like-that-how-to-hold-unbiased-non-leading-customer-interviews&quot;&gt;You can’t talk to me like that: How to hold unbiased, non-leading customer interviews&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/arasbilgen/&quot;&gt;Aras Bilgen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I loved this workshop. Research is something that I feel that I can do much
better. I&#39;m glad to say I&#39;ve never gone down the route of rattling through a
numbered list of questions on a clipboard, but I am guilty of leading questions.
I often go into interviews with a pre-concieved idea of what the respondent will
say, and I fall into the trap of leading them to that answer. My research is
almost uniformly done alone, I&#39;ll build a mental model of the issues and work
back from that. The unknown unknowns are often the details that are change a
solution from functionally correct to delightfully useful. Aras&#39; workshop was a
great reminder of this. We started with a simple exercise; a simple question
which we had to figure out how to research. Working collaboratively in small
teams, we developed research themes, supporting questions, and finally adding in
prompts and reminders to keep us on track. The value of the team was clear; my
hypotheses were gently challenged, and ideas that I simply could not have come
to alone enriched the research plan. I&#39;m looking forward to putting this into
practice both in my work and in my studies.&lt;/p&gt;
&lt;h2 id=&quot;psychological-safety-the-link-between-speaking-up-complexity-and-high-performing-teams&quot;&gt;Psychological safety: The link between speaking up, complexity and high-performing teams&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.jitgo.uk/blog/&quot;&gt;Jitesh Gosai&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You know when someone nails a talk? This was one of those times. Jitesh used
Prezi to map out the importance of Psychological safety in a team. It&#39;s years
since I&#39;ve used Prezi, and I&#39;d forgotten how effective it can be. Jitesh
described a familiar situation; teams not realising their potential, and a
swirling undercurrent of unspoken issues. They described the importance of
understanding what psychological safety &lt;em&gt;actually means&lt;/em&gt;. Instead of
superficially understanding it as &amp;quot;not being afraid to speak up&amp;quot;, they described
ingraining it into the culture of the team. they described the importance of
having the confidence to speak up, and fostering an environment where it is
valued. An interesting point was around the tension between being a &amp;quot;nice&amp;quot; team,
or a &amp;quot;blunt&amp;quot; team. I think the devil is in the detail here; One team-member&#39;s
comfort level is another&#39;s discomfort. The key is to understand, and adapt to,
the needs of the team. This was one of a number of talks that reinforced the
idea of &amp;quot;emergent&amp;quot; solutions; we should be the gardeners of our teams, not the
architects.&lt;/p&gt;
&lt;h2 id=&quot;nudge-theory-and-influencing-empowered-teams-to-do-the-things-that-matter&quot;&gt;Nudge theory and influencing empowered teams to do the things that matter&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.sarahwells.dev/&quot;&gt;Sarah Wells&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wow. Sarah described a transformational journey at the Financial Times. Moving
platforms, moving from a monolithic architecture to a microservices, and scaling
from ~12 releases per year to ~20,000. Whilst I was picking my jaw up off the
ground from this, she moved onto the meat of the talk; how nudge theory was used
to support this change. Grounded in research, Sarah described how unifying
knowledge, making that knowledge accessible, and making the right thing the
easier to do than the wrong thing, were key to the success of the
transformation. From simple things such as making essential steps mandatory,
through to writing for new hires, the FT used nudges to guide their teams to
enable the transformation. This was a fantastic talk, and I&#39;m looking forward
reading Sarah&#39;s book.&lt;/p&gt;
&lt;h2 id=&quot;crafting-workshops-for-connection-collective-mosaic-making&quot;&gt;Crafting workshops for connection: collective mosaic making&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/jaimella-espley-0a88bb93&quot;&gt;Jaimella Espley&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This was a powerful workshop. I went in to the workshop with little idea of what
to expect, and I was blown away by the power of the exercise. I spend my
professional life talking to people, and appreciate the power of a good
conversation. Jamella&#39;s workshop showed us the power of tactile, physical
objects. I&#39;ve never been to a Lego Serious Play workshop, but the proxy of
building things strikes me as a proxy for engineering solutions rather than
appreciating the human element. The mosaic exercise was different; we were asked
to choose a piece of beach, and describe how it relates to us. composed a mosaic
which described a situation, and related to the wider group the meaning our
creations. As we iterated, and engaged with the mosaics, we found that objects
became layered with meaning; the framing of colleagues&#39; creations gave us a way
of clarifying our own thoughts, and becoming vulnerable in a way that felt safe.
I saw the physicality of the exercise as offerin&lt;/p&gt;
&lt;h2 id=&quot;whats-the-future&quot;&gt;What&#39;s the future?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.lancaster.ac.uk/scc/about-us/people/charles-weir&quot;&gt;Charles Weir&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not Agile, but thought provoking. Charles described his
&lt;a href=&quot;https://ieeexplore.ieee.org/document/10380243&quot;&gt;research&lt;/a&gt; to identify trends
that will define the future of computing. These ranged from the ubiquity of AI
and IoT, through to the importance of privacy and security. We then workshopped
these themes to identify which we thought were linked, why, and how they may
impact us personally. I have a particularly dim view of the future; I believe
technology is advancing more quickly than we can adapt to it. To my mind there&#39;s
an epochal shift coming that will dwarf the industrial revolution. Instead of
concentrating power in the hands of thousands of industry barons working within
established social structures, I can see the power being concentrated in the
hands of a few conglomerates, who have no desire to do anything other than
generate revenue. My view was not shared by the table. The consensus was that
the future of computing offers both risk and opportunity. The risk is that we
are not able to catch the wave of this change, and are left behind. The
opportunity is that we are able to shape the future, and ensure that it is a
positive one.&lt;/p&gt;
&lt;h2 id=&quot;dysfunction-mapping-a-tool-for-empirical-agile-change&quot;&gt;Dysfunction Mapping: A tool for empirical agile change&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/michael-lloyd-124621177/&quot;&gt;Michael Lloyd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You reach the end of a scrum, and something is &lt;em&gt;wrong&lt;/em&gt;. Maybe the scrum missed
its goals, testing wasn&#39;t complete, or the team is dissatisfied. The temptation
is to fix the problem, but the problem is often a symptom of a deeper issue.
Michael&#39;s talk was a great reminder of the importance of understanding the root
cause of a problem. He introduced the concept of &lt;a href=&quot;https://medium.com/@michael_78275/dysfunction-mapping-a-tool-for-effective-agile-coaching-dc4634171b5f&quot;&gt;Dysfunction Mapping&lt;/a&gt;; a tool to
identify and address the root causes of problems in a scrum. The tool is simple;
you start with a symptom, and work back through the dysfunction, purpose,
solution, and measure. The key to this is to identify the root cause of the
problem, rather than the symptom. This is a common trap; we see a problem, and
we fix it. The problem is that the problem is often a symptom of a deeper issue.
Michael&#39;s talk was a great reminder of the importance of understanding the root
cause of a problem.&lt;/p&gt;
&lt;p&gt;Dysfunction mapping is something I want to try in my work. I find myself
surrounded by symptoms, but defining how to address them is often difficult.
Dysfunction mapping looks like a great way to improve systemic issues rather
than treating the symptoms.&lt;/p&gt;
&lt;h2 id=&quot;guiding-stakeholders-along-in-your-agile-product-development-journey&quot;&gt;Guiding stakeholders along in your agile product development journey&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Speaker&lt;/em&gt;: &lt;a href=&quot;https://www.linkedin.com/in/karimqurie/&quot;&gt;Karim Qurie&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There&#39;s a tension between governance and delivering features that &lt;em&gt;users&lt;/em&gt; want.
I&#39;ve seen both sides of this; products that are so user driven that they
Frankenstein together a solution that is a nightmare to maintain, and products
that have so much red tape that they end up in a swamp of slow, painful delivery
that alienates the users. In both cases, the product becomes increasingly unfit
for purpose. Karim&#39;s talk was a great reminder of the importance of balancing
this tension. He described a situation where the product team were delivering
the features asked for the loudest voice, or those that knew the shortcuts to
asking the right person. This resulted in a product that was increasingly
reactively developed. Karim took a leaf out of the ITIL book, and introduced a a
feature request process. Users had a single, open channel to request features.
Other mechanisms were shut down to force users to use this channel. There were
two key reasons that this was successful.&lt;/p&gt;
&lt;h3 id=&quot;1-transparency&quot;&gt;1. Transparency&lt;/h3&gt;
&lt;p&gt;Requests were visible to all users. This meant that users could see what was
being requested, if their idea had already been requested, and where it was in
the backlog.&lt;/p&gt;
&lt;h3 id=&quot;2-alignment-with-metrics&quot;&gt;2. Alignment with Metrics&lt;/h3&gt;
&lt;p&gt;Requests had to be aligned with the North Star metric. This meant that some
requests, whilst reasonable were rejected because they did not align with
business goals.&lt;/p&gt;
&lt;h3 id=&quot;3-communication&quot;&gt;3. Communication&lt;/h3&gt;
&lt;p&gt;Combining the above two points, Karim was able to reinforce the goals of the
organisation. This meant that the product teams were able to deliver features
that satisfied the users, and the business.&lt;/p&gt;
&lt;p&gt;Karim noted that the process broadly worked for both product and platform teams,
though needed adapting for the Platforms he managed. The ownership of the
platform meant that extra care was needed to ensure that the platform was
delivering the right features.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Installing Python 3.11 on Debian</title>
    <link href="https://example.com/blog/2022-12-23-Python_3.11_on_Debian/" />
    <updated>2022-12-23T17:46:58Z</updated>
    <id>https://example.com/blog/2022-12-23-Python_3.11_on_Debian/</id>
    <content type="html">&lt;p&gt;Python &lt;a href=&quot;https://www.python.org/downloads/release/python-3110/&quot;&gt;3.11&lt;/a&gt; has been
out for a couple of months now, and I&#39;m keen to try it out.  Not only is it
reportedly &lt;a href=&quot;https://www.youtube.com/watch?v=TLhRuZ9cJWc&quot;&gt;faster&lt;/a&gt;, but it also
includes &lt;a href=&quot;https://docs.python.org/3/library/toml.html&quot;&gt;Tomllib&lt;/a&gt; which is
something I want to use for life-logging scripts I&#39;m working on for my
&lt;a href=&quot;https://example.com/blog/2020-05-29-keeping_a_journal_in_vim/&quot;&gt;zettelkasten&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There&#39;s no direct way to install this via apt in Bullseye, so I&#39;ve two options:
use a virtual environment, or install from source.&lt;/p&gt;
&lt;p&gt;I could, of course, use Conda (and have done so on my laptop), but the machine
I&#39;m going to install onto has more limited resources.  I&#39;m using a &lt;a href=&quot;https://www.ionos.co.uk/servers/vps&quot;&gt;server&lt;/a&gt; with a single core, and mighty gigabyte of memory,
and 8 GB of diskspace, so running a full-blown Conda environment is likely to be
problematic.  Miniconda
&lt;a href=&quot;https://docs.conda.io/en/latest/miniconda.html&quot;&gt;suggests&lt;/a&gt; it needs 400 meg to
download and install alone.  Once I start creating environments, I&#39;m likely to
outgrow my vps.  So I&#39;m going to install Python 3.11 from source.&lt;/p&gt;
&lt;p&gt;Thankfully, the &lt;a href=&quot;https://www.python.org/downloads/source/&quot;&gt;Python website&lt;/a&gt; has
all the resources I need, so the installation is a fairly straightforward case
of issuing a few commands.&lt;/p&gt;
&lt;p&gt;First, I need to install the dependencies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;software-properties-common&lt;/li&gt;
&lt;li&gt;wget&lt;/li&gt;
&lt;li&gt;pkg-config&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; software-properties-common &lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; pkg-config&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, for the download, unpacking and installation I&#39;ll create a temporary directory&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; ~/scratch
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/scratch&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From there, it&#39;s simply a case of downloading and unpacking:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## find latest version at https://www.python.org/downloads/source/&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tar.xz
&lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-xf&lt;/span&gt; Python-3.11.0.tar.xz
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; Python-3.11.0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and finally installing:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## configure and install&lt;/span&gt;
./configure --enable-optimizations
&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; altinstall&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can check the installation by running &lt;code&gt;python3.11 --version&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;python3.11 &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which should return &lt;code&gt;Python 3.11.0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;alternative install means that the new
version is installed as &lt;code&gt;python3.11&lt;/code&gt; rather than &lt;code&gt;python3&lt;/code&gt;, so you can run both
the original version and the new one side-by-side.  this should mean that the
installation doesn&#39;t break any existing scripts.  As my machine doesn&#39;t have any
python2, I decided to use &lt;code&gt;update-alternatives&lt;/code&gt; to make &lt;code&gt;python&lt;/code&gt; point to the
new &lt;code&gt;python3.11&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-shell&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; update-alternatives &lt;span class=&quot;token parameter variable&quot;&gt;--install&lt;/span&gt; /usr/bin/python python3 /usr/local/bin/python3.11 &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That step&#39;s optional, and certainly not for everyone, but it means that I can
run &lt;code&gt;python3.11&lt;/code&gt; by simply typing &lt;code&gt;python&lt;/code&gt; at the command line - perfect for my
lazy fingers.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>sudo on AWS</title>
    <link href="https://example.com/blog/2021-02-17-sudo_on_aws/" />
    <updated>2021-02-17T12:46:58Z</updated>
    <id>https://example.com/blog/2021-02-17-sudo_on_aws/</id>
    <content type="html">&lt;p&gt;While following the &lt;a href=&quot;https://github.com/snori74/linuxupskillchallenge/&quot;&gt;Linux Upskill challenge&lt;/a&gt;, I came across some unexpected behaviour:  issuing &lt;code&gt;sudo &amp;lt;command&amp;gt;&lt;/code&gt; didn&#39;t prompt me for a password.
No problem I thought; I simply need to set a password for my account.  While I&#39;m thinking of it, let&#39;s update the password for root too, after all our ec2 instance &lt;a href=&quot;https://github.com/snori74/linuxupskillchallenge/blob/master/00-AWS-Free-Tier.md&quot;&gt;isn&#39;t using a firewall&lt;/a&gt; yet.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;su&lt;/span&gt; - root
&lt;span class=&quot;token function&quot;&gt;passwd&lt;/span&gt; root
&lt;span class=&quot;token function&quot;&gt;passwd&lt;/span&gt; ubuntu
&lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Passwords duly set, the password wasn&#39;t prompted:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/rkErZ_0x1b-412.avif 412w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/rkErZ_0x1b-412.webp 412w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/rkErZ_0x1b-412.jpeg&quot; alt=&quot;huh? Why am I not being asked for a password?&quot; width=&quot;412&quot; height=&quot;47&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Let&#39;s check I&#39;m in the &lt;code&gt;sudo&lt;/code&gt; group:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/WZAMwO6F91-583.avif 583w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/WZAMwO6F91-583.webp 583w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/WZAMwO6F91-583.jpeg&quot; alt=&quot;groups looks OK&quot; width=&quot;583&quot; height=&quot;46&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;So there must be some config that means I&#39;m not prompted for a password.  Let&#39;s look at the &lt;code&gt;etc/sudoers&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; /etc/sudoers&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There&#39;s nothing in there that is obviously preventing the password prompt.  &lt;a href=&quot;https://askubuntu.com/questions/153933/no-password-prompt-at-sudo-command&quot;&gt;This&lt;/a&gt;
question on Stack Overflow suggests that the problem may be a file in &lt;code&gt;/etc/sudoers.d&lt;/code&gt;.  Let&#39;s look for all instance of &lt;code&gt;NOPASSWD&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-rl&lt;/span&gt; NOPASSWD /etc/sudoers.d&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;/etc/sudoers.d/90-cloud-init-users&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&#39;s look at the file (note the lazy history expansion):&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;more&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Output&lt;/em&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# User rules for ubuntu&lt;/span&gt;
ubuntu &lt;span class=&quot;token assign-left variable&quot;&gt;ALL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ALL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; NOPASSWD:ALL&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This line means I&#39;ll never be prompted for a password.  Let&#39;s fix that by commenting it out.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;su&lt;/span&gt; - root
&lt;span class=&quot;token function&quot;&gt;vi&lt;/span&gt; /etc/sudoers.d/90-cloud-init-users&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/EIudoO2BBj-658.avif 658w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/EIudoO2BBj-658.webp 658w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/EIudoO2BBj-658.jpeg&quot; alt=&quot;wait, it&#39;s not writeable?&quot; width=&quot;658&quot; height=&quot;165&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Oh! The file isn&#39;t writeable.  I could use &lt;code&gt;visudo&lt;/code&gt; to edit it, but that is defaulting to use &lt;code&gt;nano&lt;/code&gt;. Ugh, no thanks.&lt;/p&gt;
&lt;p&gt;Instead, let&#39;s check, and fix the file permissions&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt; /etc/sudoers.d/90-cloud-init-users&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/ZUlt-ahudL-838.avif 838w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/ZUlt-ahudL-838.webp 838w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/ZUlt-ahudL-838.jpeg&quot; alt=&quot;what permissions does the file have?&quot; width=&quot;838&quot; height=&quot;44&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s owned by root, but root cannot write to it.  Let&#39;s temporarily make the file writeable:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;640&lt;/span&gt; /etc/sudoers.d/90-cloud-init-users&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can edit it, and return the permissions&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/n7s9DwBXG5-386.avif 386w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/n7s9DwBXG5-386.webp 386w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/n7s9DwBXG5-386.jpeg&quot; alt=&quot;editing once the permissions are changed&quot; width=&quot;386&quot; height=&quot;219&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;vi&lt;/span&gt; /etc/sudoers.d/90-cloud-init-users
&lt;span class=&quot;token function&quot;&gt;chmod&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;440&lt;/span&gt; /etc/sudoers.d/90-cloud-init-users
&lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# exit the root acct, we don&#39;t need it any more&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and test that we are being prompted for the password correctly:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt&lt;/span&gt; update&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/Wn0Hibvjr--459.avif 459w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/Wn0Hibvjr--459.webp 459w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2021-02-17-sudo_on_aws/Wn0Hibvjr--459.jpeg&quot; alt=&quot;hooray! we&#39;re asked for a password&quot; width=&quot;459&quot; height=&quot;49&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Linux Upskill Challenge</title>
    <link href="https://example.com/blog/2021-02-16-linux_upskill_challenge/" />
    <updated>2021-02-16T21:44:47Z</updated>
    <id>https://example.com/blog/2021-02-16-linux_upskill_challenge/</id>
    <content type="html">&lt;p&gt;With the pandemic, there have been loads of courses that have been made &lt;a href=&quot;https://www.reddit.com/r/FREECoursesEveryday/&quot;&gt;temporarily free&lt;/a&gt;.  It can be difficult to separate the wheat from the chaff; video courses are better than grinding through dense documentation, but not &lt;a href=&quot;https://en.wikipedia.org/wiki/Learning_pyramid&quot;&gt;as effective as practise&lt;/a&gt;.  Enter the &lt;a href=&quot;https://www.reddit.com/r/linuxupskillchallenge/&quot;&gt;Linux Upskill Challenge&lt;/a&gt;.  The challenge is a good mix of clear instructions and community support that gives a good grounding in Linux Sysadmin.&lt;/p&gt;
&lt;p&gt;As a linux user, there was a temptation to simply use my own machine.  This however runs contrary to the spirit of the challenge.  Instead, creating and maintaining a virtual private server gives a far more authentic experience of Linux System Administration.  Although it&#39;s the first day, I have found the experience of setting up an &lt;code&gt;ec2&lt;/code&gt; instance on AWS invaluable.&lt;/p&gt;
&lt;p&gt;I&#39;m keeping a repo of my notes &lt;a href=&quot;https://github.com/JasmineElm/Linux_Upskill_Challenge&quot;&gt;here&lt;/a&gt; The repo also includes a simple script to manage ec2 instances straight from the command-line rather than use the the web interface.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Terminal Shortcuts</title>
    <link href="https://example.com/blog/2021-02-15-terminal_shortcuts/" />
    <updated>2021-02-15T14:52:05Z</updated>
    <id>https://example.com/blog/2021-02-15-terminal_shortcuts/</id>
    <content type="html">&lt;p&gt;I&#39;m slowly making my way through the
&lt;a href=&quot;https://linuxupskillchallenge.com/&quot;&gt;Linux Upskill Challenge&lt;/a&gt;, and coming across
some basic stuff I&#39;ve completely missed before.&lt;/p&gt;
&lt;p&gt;On a professional basis, I&#39;m using keyboard shortcuts &lt;em&gt;all&lt;/em&gt; the time. Whether
it&#39;s snapping (&lt;code&gt;super&lt;/code&gt;+&lt;code&gt;arrow key&lt;/code&gt;), minimising open windows (&lt;code&gt;super&lt;/code&gt; + &lt;code&gt;d&lt;/code&gt;), or
any of the myriad &lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;...&lt;/code&gt; combos that are second nature to most users.
When it comes to the command-line however, I only knew one: &lt;code&gt;ctrl&lt;/code&gt;+&lt;code&gt;c&lt;/code&gt;. Whilst
this has done me fine for the past ten years, there&#39;s far more to prompt
shortcuts. Although some of the below may have limited use-cases I have a new
favourite way of clearing the prompt (&lt;code&gt;ctrl&lt;/code&gt;+&lt;code&gt;l&lt;/code&gt;).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:left&quot;&gt;Combo&lt;/th&gt;
&lt;th style=&quot;text-align:left&quot;&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;l&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;clear screen (equivalent to the &lt;code&gt;clear&lt;/code&gt; command)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;z&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;send job to background (equivalent to appending a &lt;code&gt;&amp;amp;&lt;/code&gt; to a command )&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Log out of the current session (equivalent to &lt;code&gt;exit&lt;/code&gt; command)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;Move the cursor to the beginning of the line (equivalent to pressing the &lt;code&gt;home&lt;/code&gt; key)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;u&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;delete backwards to the beginning of line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;k&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;delete forwards to the end of line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;w&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;delete previous word (like &lt;code&gt;db&lt;/code&gt; in &lt;code&gt;vi&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;left&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;move back one word&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;right&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;move forwards one word&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;pastes the buffered output of &lt;code&gt;ctrl&lt;/code&gt; + [&lt;code&gt;u&lt;/code&gt; | &lt;code&gt;k&lt;/code&gt; | &lt;code&gt;w&lt;/code&gt;]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;cycle through previous commands (similar to pressing the &lt;code&gt;up&lt;/code&gt; arrow)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;n&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;cycle through next commands (similar to pressing the &lt;code&gt;down&lt;/code&gt; arrow)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;reverse search history (like `history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;r&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;forward search history (like `history&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;suspend output updating screen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; + &lt;code&gt;q&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;resume output updating screen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align:left&quot;&gt;&lt;code&gt;ctrl&lt;/code&gt; +&lt;code&gt;x&lt;/code&gt;,&lt;code&gt;e&lt;/code&gt;&lt;/td&gt;
&lt;td style=&quot;text-align:left&quot;&gt;open &lt;code&gt;$EDITOR&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content>
  </entry>
  <entry>
    <title>Maintaining a Zettelkasten using Bash and Vi</title>
    <link href="https://example.com/blog/2021-01-17-maintaining_a_zettelkasten_using_bash_and_vi/" />
    <updated>2021-01-17T18:31:40Z</updated>
    <id>https://example.com/blog/2021-01-17-maintaining_a_zettelkasten_using_bash_and_vi/</id>
    <content type="html">&lt;p&gt;I&#39;ve mentioned &lt;a href=&quot;https://example.com/blog/2021-01-17-maintaining_a_zettelkasten_using_bash_and_vi/2020-05-29-keeping_a_journal_in_vim&quot;&gt;earlier&lt;/a&gt; that I was trying
to use &#39;basic&#39; tools like &lt;code&gt;Vi&lt;/code&gt; and &lt;code&gt;Bash&lt;/code&gt; preference to gui heavy tools.
Describing Vi and Bash as simple tools does them a disservice. Bash is powerful
enough to be used as a full programming language,even before you factor in the
range of external programs (&lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;perl&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;em&gt;ad infinitum&lt;/em&gt;) that it can
call on. Vi has an established &lt;code&gt;vimscript&lt;/code&gt; language and a long enough lifespan
to ensure anything you are trying to do has been attempted, and likely
documented before. Can these two tools be enough to manage a Zettelkasten
though?&lt;/p&gt;
&lt;h2 id=&quot;whats-a-zettelkasten&quot;&gt;What&#39;s a Zettelkasten?&lt;/h2&gt;
&lt;p&gt;I&#39;m getting ahead of myself. &lt;em&gt;Zettelkasten&lt;/em&gt; is the German term for &#39;slip box&#39;.
It&#39;s the colloquial term used for managing and storing notes. The concept spans
back five hundred years or so to Conrad Gessner, and his
&lt;a href=&quot;https://www.rcpe.ac.uk/heritage/conrad-gesner&quot;&gt;bibliography&lt;/a&gt;, but it&#39;s
&lt;a href=&quot;https://www.youtube.com/watch?v=U2hxygqjx2k&quot;&gt;Niklas Luhmann&lt;/a&gt; who raised the
profile of the idea. In simple terms, knowledge is added to cards. Each card is
contains a contained idea, but each card may reference others. For instance a
card about the stained glass used in Notre-Dame may reference a cards about
medieval glass making, religious iconography in the 13th century, lead smelting,
and so on. Storing the information is important, but linking ideas and knowledge
is where the system comes into its own. Rather than writing an encyclopedia of
knowledge, you end up writing something much closer to a wiki. Ideas are
captured concisely, reviewed regularly, and linked widely.
&lt;a href=&quot;https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes&quot;&gt;This&lt;/a&gt;
book by Sönke Ahrens explains the process, and strategies in far greater (but
wonderfully digestible) detail.&lt;/p&gt;
&lt;h2 id=&quot;what-does-an-electronic-zettelkasten-look-like&quot;&gt;What Does an Electronic Zettelkasten Look Like?&lt;/h2&gt;
&lt;p&gt;If we&#39;re looking at making a wiki; that is absolutely possible, perhaps even in
Vi alone. Using markdown files, it is possible to king files together simply
with minimal effort. Managing and searching files however might need more heavy
lifting. The
&lt;a href=&quot;https://www.edwinwenink.xyz/posts/48-vim_fast_creating_and_linking_notes/&quot;&gt;blog here&lt;/a&gt;
was an excellent resource; the author covers all the functionality I wanted,
specifically, naming of cards, and finding them.&lt;/p&gt;
&lt;p&gt;In large part, I&#39;ve simply copied the code wholesale. The fuzzy-find/insert
function is perfect for my needs:&lt;/p&gt;
&lt;pre class=&quot;language-vimscript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vimscript&quot;&gt;&quot;
&quot; see https://www.edwinwenink.xyz/posts/48-vim_fast_creating_and_linking_notes/
&quot;

&quot; CtrlP function for inserting a markdown link with Ctrl-X
function! CtrlPOpenFunc(action, line)
   if a:action =~ &#39;^h$&#39;
      &quot; Get the filename
      let filename = fnameescape(fnamemodify(a:line, &#39;:t&#39;))
    let filename_wo_timestamp = fnameescape(fnamemodify(a:line, &#39;:t:s/&#92;d+-//&#39;))

      &quot; Close CtrlP
      call ctrlp#exit()
      call ctrlp#mrufiles#add(filename)

      &quot; Insert the markdown link to the file in the current buffer
    let mdlink = &quot;[ &quot;.filename_wo_timestamp.&quot; ]( &quot;.filename.&quot; )&quot;
      put=mdlink
  else
      &quot; Use CtrlP&#39;s default file opening function
      call call(&#39;ctrlp#acceptfile&#39;, [a:action, a:line])
   endif
endfunction

let g:ctrlp_open_func = {
         &#92; &#39;files&#39;: &#39;CtrlPOpenFunc&#39;,
         &#92; &#39;mru files&#39;: &#39;CtrlPOpenFunc&#39;
         &#92; }&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Although I tried the file naming function, I found that my combination of
multiple zettelkasten (One for work, one for study and a general one) meant a
function with hardcoded path wasn&#39;t workable. I decided that a shell function
would be easier to maintain across devices. a simple function to decide what
&lt;code&gt;ZETTEL_DIR&lt;/code&gt; is based on context (is &lt;code&gt;pwd&lt;/code&gt; in a study/work path) means the card
is created in the correct directory.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# New Zettle card&lt;/span&gt;
&lt;span class=&quot;token function-name function&quot;&gt;nz&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;DATE_STR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +&lt;span class=&quot;token string&quot;&gt;&quot;%Y%m%d%H%M&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;TITLE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$*&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;CLEAN_TITLE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; $* &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;s/ /_/g&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;[:upper:]&#39;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;[:lower:]&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;ZETTLE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ZETTLE_DIR&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$DATE_STR&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;-&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$CLEAN_TITLE&lt;/span&gt;.md
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;# &#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$TITLE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ZETTLE&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;vi&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$ZETTLE&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Revisiting Jekyll Blog Scripting</title>
    <link href="https://example.com/blog/2020-12-31-revisiting_jekyll_blog_scripting/" />
    <updated>2020-12-31T19:44:07Z</updated>
    <id>https://example.com/blog/2020-12-31-revisiting_jekyll_blog_scripting/</id>
    <content type="html">&lt;p&gt;It&#39;s nearly five years since I first started blogging using Jekyll.  Although I haven&#39;t exactly been prolific in that time, I have found that my &lt;a href=&quot;https://example.com/blog/2020-12-31-revisiting_jekyll_blog_scripting/code/2015/05/28/script-to-generate-posts.html&quot;&gt;earlier&lt;/a&gt; &lt;a href=&quot;https://example.com/blog/2020-12-31-revisiting_jekyll_blog_scripting/writing/2015/05/28/Script-to-start-Jekyll-Service.html&quot;&gt;attempts&lt;/a&gt;  at scripting are too brittle to be portable.  every time I try to use them somewhere new, I end up manually bodging a fix that rarely finds it&#39;s way back to the original script.&lt;/p&gt;
&lt;p&gt;Rather than polish the current rat&#39;s nest of scripting and aliases, I wanted a single solution that can be dropped into any shell, so I can use it anywhere, whether it is Termux on my phone, WSL, an old Macintosh, or Linux.&lt;/p&gt;
&lt;p&gt;Over the past five years, my tool choices have changed.  Rather than using Atom to write markdown I now write almost exclusively in &lt;a href=&quot;https://example.com/blog/2020-12-31-revisiting_jekyll_blog_scripting/code/2020/05/29/keeping_a_journal_in_vim.html&quot;&gt;vim&lt;/a&gt;.  Similarly, my increasing comfort on the command line means I am better able to figure out a way of starting a Jekyll server &lt;em&gt;at the same time, and in the same shell&lt;/em&gt; as writing the blog post itself.&lt;/p&gt;
&lt;p&gt;Running Jekyll alongside Vi could be done in a number of ways; &lt;code&gt;forking&lt;/code&gt; a shell, making the vim process run in a sub-shell, a different session, or using the &lt;code&gt;! syntax&lt;/code&gt; to run Jekyll &lt;em&gt;within&lt;/em&gt; vim itself.  Whilst any of these would achieve the broad aims of having two processes running simultaneously, I couldn&#39;t find a solution to trigger both with minimal effort.  In the end, the solution was quite simple; &lt;code&gt;tmux&lt;/code&gt;.  A tmux session with both processes can be triggered from a single command.  By sourcing this command at the point the shell loads, I can easily start writing without trying to remember what sequence of events I need to trigger.&lt;/p&gt;
&lt;h2 id=&quot;the-script&quot;&gt;The Script&lt;/h2&gt;
&lt;p&gt;this script is stored in ~/.shell_functions which is sourced in my &lt;code&gt;~/.bashrc&lt;/code&gt;.  There&#39;s no reason that you couldn&#39;t have the script within your &lt;code&gt;~/.bashrc&lt;/code&gt;; I only have it in a separate file to make it easier to maintain.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# New Blog post&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## need to `export $BLOG_DIR` in ~/.bashrc&lt;/span&gt;

&lt;span class=&quot;token function-name function&quot;&gt;jekserve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;xdg-open&lt;/span&gt; http://127.0.0.1:4000/ &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$BLOG_DIR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/
  bundle &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; jekyll serve
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function-name function&quot;&gt;create_post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$BLOG_DIR&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$*&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token assign-left variable&quot;&gt;dte&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +%Y-%m-%d&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token assign-left variable&quot;&gt;tme&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +&lt;span class=&quot;token string&quot;&gt;&quot;%T&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token assign-left variable&quot;&gt;safe_title&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; $title &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;s/ /_/g&#39;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;  &lt;span class=&quot;token function&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;[:upper:]&#39;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;[:lower:]&#39;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;---&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;layout: post&lt;span class=&quot;token entity&quot; title=&quot;&#92;n&quot;&gt;&#92;n&lt;/span&gt;title:  &quot;&lt;/span&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$title&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;ndate:   &lt;span class=&quot;token string&quot;&gt;&quot; &lt;span class=&quot;token variable&quot;&gt;$dte&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$tme&lt;/span&gt; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;ncategories: writing&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;nsynopsis: &lt;span class=&quot;token string&quot;&gt;&quot;change me&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&#92;&lt;/span&gt;n---&lt;span class=&quot;token string&quot;&gt;&quot;&gt;&gt; &lt;span class=&quot;token variable&quot;&gt;$dte&lt;/span&gt;-&lt;span class=&quot;token variable&quot;&gt;$safe_title&lt;/span&gt;.md
  vi &lt;span class=&quot;token variable&quot;&gt;$dte&lt;/span&gt;-&lt;span class=&quot;token variable&quot;&gt;$safe_title&lt;/span&gt;.md
}

nbp() {
  post_title=&lt;span class=&quot;token variable&quot;&gt;$*&lt;/span&gt;
  echo &lt;span class=&quot;token variable&quot;&gt;$post_title&lt;/span&gt;
  tmux new-session -d
  tmux split-window -v
  tmux resize-pane -D 10
  tmux send -t 0:0.1 &quot;&lt;/span&gt;jekserve&lt;span class=&quot;token string&quot;&gt;&quot; C-m
  tmux send -t 0:0.0 &quot;&lt;/span&gt;create_post &lt;span class=&quot;token variable&quot;&gt;$post_title&lt;/span&gt;&quot; C-m
  tmux select-pane &lt;span class=&quot;token parameter variable&quot;&gt;-U&lt;/span&gt;
  tmux &lt;span class=&quot;token parameter variable&quot;&gt;-2&lt;/span&gt; attach-session &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Splitting the script into three functions should make it easier to maintain/debug.  To write a new blog post I simply now need to &lt;code&gt;nbp A Blog Post Title&lt;/code&gt;, and start writing straight away.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>vim Configuration</title>
    <link href="https://example.com/blog/2020-06-09-vim_configuration/" />
    <updated>2020-06-09T00:00:00Z</updated>
    <id>https://example.com/blog/2020-06-09-vim_configuration/</id>
    <content type="html">&lt;h2 id=&quot;my-vim-configuration&quot;&gt;My vim Configuration&lt;/h2&gt;
&lt;p&gt;The more I use vim, the more handy tricks I pick up.  I&#39;m currently using vim to write a 10,000 word assignment; something I would have struggled to consider months ago, but with a reasonably minimal configuration combined with some handy configuration tweaks, my experience of writing for longer periods in a terminal prompt isn&#39;t too shabby.&lt;/p&gt;
&lt;p&gt;My path to learning vim has been a relatively slow one.  There were a few &lt;em&gt;aha&lt;/em&gt; moments, but for the most part, progress was a result of concerted effort to build both knowledge and muscle memory. If you on a similar journey to learn vim, these are the things that I found most useful&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;learn&lt;/em&gt; the basics of movement.&lt;/li&gt;
&lt;li&gt;learn how buffers work (buffers seriously improve your copy/paste game)&lt;/li&gt;
&lt;li&gt;don&#39;t blindly paste other people&#39;s &lt;code&gt;.vimrc&lt;/code&gt; into your own, but&lt;/li&gt;
&lt;li&gt;do experiment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Of course, vim isn&#39;t for everyone.  It wasn&#39;t for me until I found myself &lt;strong&gt;having&lt;/strong&gt; to use it for work.  Choosing a modal editor when you have access to shiny tools like VSCode can be a difficult ask especially when you don&#39;t &lt;a href=&quot;https://stackoverflow.com/questions/1218390/what-is-your-most-productive-shortcut-with-vim&quot;&gt;grok&lt;/a&gt; vim. I&#39;m hardly an expert, but I&#39;ve got to a point where I can productively work without having to consciously thinking about it. An unexpected benefit to vim is that I find myself working more quickly with a higher level of concentration than when using VSCode, or &lt;em&gt;shudder&lt;/em&gt; Word.  There&#39;s no secret to this, it&#39;s purely a result of a minimally decorated terminal having a far smaller cognitive overhead; by default, there is no visual cruft, decorated menus, or even fancy &lt;code&gt;powerline&lt;/code&gt; prompts.  I only see what I am &lt;em&gt;actively working on&lt;/em&gt;.  Extending this idea, I have configured my &lt;code&gt;.vimrc&lt;/code&gt; along the following principles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;simple: Don&#39;t add plug-ins, or reams of &lt;code&gt;viml&lt;/code&gt;, use standard configuration where possible&lt;/li&gt;
&lt;li&gt;minimal: Only configure elements that provide active benefit&lt;/li&gt;
&lt;li&gt;flexible: be open-minded enough to realise my  configuration will evolve&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Below are three pieces of my configuration that i think demonstrate these principles:&lt;/p&gt;
&lt;h2 id=&quot;spell-highlight-toggle&quot;&gt;Spell highlight toggle&lt;/h2&gt;
&lt;p&gt;The majority of my vim use is in writing markdown. Using &lt;code&gt;spell&lt;/code&gt; is key for picking up typos, and simple grammatical errors.  It&#39;s not as advanced as the tools in Word, but on the other hand, I don&#39;t have to deal with the overheads or cost of Word.  Out of the box &lt;code&gt;spell&lt;/code&gt; is fairly decent, but having the visual problems shouting out at me whilst I&#39;m trying to get ideas out is a distraction that I find slows down my writing.  I could configure my colours to be less startling, but that doesn&#39;t solve the problem, and arguably makes spotting bad spellings more difficult.  What I really want is spell check that is &lt;em&gt;off&lt;/em&gt; by default, but can be quickly toggled when needed&lt;/p&gt;
&lt;h2 id=&quot;statusline-style-information-in-the-ruler&quot;&gt;&lt;code&gt;statusline&lt;/code&gt; style information in the ruler&lt;/h2&gt;
&lt;p&gt;By default, vim shows a minimally decorated &lt;code&gt;ruler&lt;/code&gt; that contains the bare minimum of information.  You can add a more informative &lt;code&gt;statusline&lt;/code&gt; that shows, I believe more &lt;em&gt;useful&lt;/em&gt; information, but this is at the expense of screen real estate.  On my laptop, the combined status and ruler take up the better part of 10% of the entire space.  Instead, I take a minimal subset of information, and place that in my statusbar:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://example.com/blog/2020-06-09-vim_configuration/z9uZXa9nYS-185.avif 185w&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://example.com/blog/2020-06-09-vim_configuration/z9uZXa9nYS-185.webp 185w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://example.com/blog/2020-06-09-vim_configuration/z9uZXa9nYS-185.png&quot; alt=&quot;an image of my ruler&quot; width=&quot;185&quot; height=&quot;35&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;The ruler contains word count(&lt;code&gt;650&lt;/code&gt; in this example), whether the files is modified (&lt;code&gt;[+]&lt;/code&gt;), and the &lt;code&gt;line number&lt;/code&gt;:&lt;code&gt;column&lt;/code&gt;.  This is perfect for my needs, anything more would be a waste.&lt;/p&gt;
&lt;h2 id=&quot;toggle-explorer&quot;&gt;Toggle Explorer&lt;/h2&gt;
&lt;p&gt;Usually, I work on a single file, and don&#39;t need to think about jumping between directories; I&#39;m writing essays, not complex code-bases.  When I am writing longer, more complex documents, I do prefer to split sections out into separate files.  For instance, I&#39;m working on a 10,000 word essay that is split thematically into six files. This approach lets me focus on one thing at once.  Whilst vim handles this magnificently, a couple of lines of configuration means I can use &lt;code&gt;:find&lt;/code&gt; or &lt;code&gt;:edit&lt;/code&gt; to open different files with minimal (tab completing) fuss, having a dedicated file browser that I can toggle is a brilliant tweak for me; I can remind myself of the document structure, and open new files with a few keystrokes (&lt;code&gt;&amp;lt;C-E&amp;gt;&lt;/code&gt; to open the browser, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt; for selecting the right one, and &lt;code&gt;enter&lt;/code&gt; to open it)&lt;/p&gt;
&lt;h2 id=&quot;whats-missing&quot;&gt;What&#39;s Missing&lt;/h2&gt;
&lt;p&gt;I alluded to my configuration being a living thing; as my usage evolves, it should be matched by the configuration.  There are a few things I want to investigate further, particularly around getting a better workflow between &lt;code&gt;pandoc&lt;/code&gt; and vim. Things such as pandoc are top of the list; &lt;a href=&quot;https://github.com/vim-pandoc/vim-pandoc&quot;&gt;Vim-Pandoc&lt;/a&gt; is something I want to integrate, together with some sort of workflow around rendering documents automatically.&lt;/p&gt;
&lt;p&gt;My full configuration can be found &lt;a href=&quot;https://github.com/JasmineElm/vim&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Keeping a Journal in Vim</title>
    <link href="https://example.com/blog/2020-05-29-keeping_a_journal_in_vim/" />
    <updated>2020-05-29T00:00:00Z</updated>
    <id>https://example.com/blog/2020-05-29-keeping_a_journal_in_vim/</id>
    <content type="html">&lt;p&gt;For me, keeping  a simple journal, provides a easy way of reflecting on the day. Done right, keeping a diary has been linked to &lt;a href=&quot;https://www.brainpickings.org/2014/09/04/famous-writers-on-keeping-a-diary/&quot;&gt;creativity&lt;/a&gt;, and &lt;a href=&quot;https://www.kent.ac.uk/learning/PDP-and-employability/pdp/reflective.html&quot;&gt;reflective learning&lt;/a&gt;.  Moreover, recording &lt;a href=&quot;https://www.actionforhappiness.org/take-action/find-three-good-things-each-day&quot;&gt;one good thing per day&lt;/a&gt;  has both mental health, and &lt;a href=&quot;https://charlesduhigg.com/the-power-of-habit/&quot;&gt;positive habit forming&lt;/a&gt; benefits.&lt;/p&gt;
&lt;p&gt;Core to my ability to maintain the habit of keeping a journal is making it &lt;em&gt;as easy as possible&lt;/em&gt; to add / maintain entries.  My journal is a brief affair that balances the main benefits of capturing and reflecting on the day&#39;s events with the effort required to do so.&lt;/p&gt;
&lt;h2 id=&quot;why-vim&quot;&gt;Why Vim?&lt;/h2&gt;
&lt;p&gt;Given this focus on simplicity, why would I consider Vim?  Surely I&#39;d be stuck in a single entry forever whilst I try to &lt;a href=&quot;https://github.com/hakluke/how-to-exit-vim&quot;&gt;exit&lt;/a&gt;?&lt;/p&gt;
&lt;p&gt;In fact Vim is perfect for the task of journaling; it is readily, &lt;em&gt;freely&lt;/em&gt; available on my phone via &lt;a href=&quot;https://wiki.termux.com/wiki/Text_Editors#Vim&quot;&gt;termux&lt;/a&gt;, my laptop, or at a push via ssh. Whilst the same may be said about other editors, Vim&#39;s super power as far as journaling is that it can apply templates contextually.  Tying these templates together with Vim&#39;s ability to process shell commands, makes it is possible to create a personalised entry with effectively zero effort.  Using a editor in a terminal means I don&#39;t have the visual cruft of a bespoke app with the associated &lt;a href=&quot;https://www.nngroup.com/articles/zen-mode/&quot;&gt;cognitive load&lt;/a&gt; and &lt;a href=&quot;https://www.nngroup.com/videos/interaction-cost/&quot;&gt;interaction cost&lt;/a&gt;.  Finally, &lt;em&gt;rolling my own&lt;/em&gt; journal process, allwos me to fully own my data.  I&#39;m not tied to a proprietary platform, and don&#39;t have to worry about about how the data is used.&lt;/p&gt;
&lt;h2 id=&quot;ingredients&quot;&gt;Ingredients&lt;/h2&gt;
&lt;p&gt;The solution I have come to is based on three apps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Vim: to create and populate journal entries&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rclone.org/&quot;&gt;rclone&lt;/a&gt; to save entries to a cloud provider&lt;/li&gt;
&lt;li&gt;Bash to handle file creation, and invoking vim/rclone&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first step would be to create a &lt;a href=&quot;https://shapeshed.com/vim-templates/&quot;&gt;template&lt;/a&gt;.  For the journal, this is essentially a journal entry without the detail.  The template may be placed anywhere, but it makes sense to keep it in your &lt;code&gt;.vim&lt;/code&gt; directory.  mine is stored in &lt;code&gt;~/.vim/templates/journal.skeleton&lt;/code&gt;.  Wherever you store yours, it needs sourcing in your &lt;em&gt;local functions&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;language-markdown&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-markdown&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; What happened&lt;/span&gt;


&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; What went well&lt;/span&gt;


&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; What didn&#39;t go well&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we need to create a function to invoke the template.  My function is designed to only trigger if I create a new file in a specific directory, or any of its subdirectories.&lt;/p&gt;
&lt;p&gt;This function is saved in &lt;code&gt;~/.vim/local_functions&lt;/code&gt;.  Again, you can save yours elsewhere, but you&#39;ll need to make sure your &lt;code&gt;.vimrc&lt;/code&gt; is sourcing the correct path&lt;/p&gt;
&lt;pre class=&quot;language-vim&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vim&quot;&gt;
augroup journal
    &lt;span class=&quot;token builtin&quot;&gt;autocmd&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&quot; populate journal template&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;autocmd&lt;/span&gt; VimEnter &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;journal&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   0r ~&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;templates&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;journal&lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt;skeleton

    &lt;span class=&quot;token comment&quot;&gt;&quot; set header for the particular journal&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;autocmd&lt;/span&gt; VimEnter &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;journal&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;JournalMode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;&quot; https://stackoverflow.com/questions/12094708/include-a-directory-recursively-for-vim-autocompletion&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;autocmd&lt;/span&gt; VimEnter &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;journal&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;   &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;k&lt;/span&gt;~&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;documents&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;journal&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;

augroup end&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;we&#39;ll source this function in our &lt;code&gt;.vimrc&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-vim&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vim&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;source&lt;/span&gt; ~&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vim&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;local_functions&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far so good. If I create a file under any sub/directory of &lt;code&gt;~/documents/journal&lt;/code&gt;, vim should paste the template  as it opens.  To make the journal entries a bit more specific why not add the date?  There&#39;s a few ways to achieve this, but in the spirit of keeping things simple, why not take the filename, and process that?  Let&#39;s create the function, again under &lt;code&gt;~/.vim/local_functions&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-vim&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vim&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&quot; set header title for journal &amp;amp; enter writing mode&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;JournalMode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    execute &lt;span class=&quot;token string&quot;&gt;&#39;normal gg&#39;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&quot; filename in format dd-mm-yy.md &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&quot; add a line to file in format ## dd-mm-yy    &lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; filename &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;##&#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39; &#39;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;expand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;%:r&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;call&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setline&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; filename&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    execute &lt;span class=&quot;token string&quot;&gt;&#39;normal o&#39;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;endfunction&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now all we need is a script that will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;create the file&lt;/li&gt;
&lt;li&gt;open it in vim&lt;/li&gt;
&lt;li&gt;save it to our cloud storage&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-bash&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# A Script to create a journal entry, open it in vim, and save it &lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;JOURNAL_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;~/documents/journal/&#39;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# each year gets a dir, each month a subdir&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;ENTRY_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +%Y/%B&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$JOURNAL_DIR&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ENTRY_DIR&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$JOURNAL_DIR&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$ENTRY_DIR&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt; +%d-%m-%y&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;.md
&lt;span class=&quot;token comment&quot;&gt;# my rclone is pointing to an instance of OwnCloud&lt;/span&gt;
rclone copy ~/documents/journal owncloud:journal&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;looking-ahead&quot;&gt;Looking ahead&lt;/h2&gt;
&lt;p&gt;as I&#39;ve been using this, I&#39;ve found myself repeating simple prases.  To reduce this repetition, I&#39;ve added the following abbreviations to my &lt;code&gt;.vimrc&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;language-vim&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-vim&quot;&gt;abbr _ok OK day&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
abbr _gd Good day&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
abbr _pd Poor day&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The journal process I have at the moment is a near perfect for my needs, it is low enough to not &lt;em&gt;get in the way&lt;/em&gt; of keeping the journal itself, meaning I get the benefit without extraneous effort.&lt;/p&gt;
&lt;p&gt;Whilst it&#39;s ideal at the moment, there are a few things that could further enhance the process, namely:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;using a yaml block to capture richer data&lt;/li&gt;
&lt;li&gt;encryption of journal entries&lt;/li&gt;
&lt;li&gt;data analysis / sentiment analysis of journal entries&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the time being though, it&#39;s good enough to be bulding the habit and reflecting on each day.&lt;/p&gt;
</content>
  </entry>
</feed>