<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blogging about tech stuff]]></title><description><![CDATA[Blogging about tech stuff]]></description><link>https://www.hussain.io</link><generator>RSS for Node</generator><lastBuildDate>Wed, 07 Oct 2026 18:55:02 GMT</lastBuildDate><atom:link href="https://www.hussain.io/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Sovereign AI in the Gulf: Four Tests Beyond Local Data Centres]]></title><description><![CDATA[A fresh wave of coverage on 3 August highlighted Abu Dhabi-based Aleria’s plan to pair NVIDIA systems with DDN storage in the UAE and United States. The underlying company announcement, however, is da]]></description><link>https://www.hussain.io/sovereign-ai-in-the-gulf-four-tests-beyond-local-data-centres</link><guid isPermaLink="true">https://www.hussain.io/sovereign-ai-in-the-gulf-four-tests-beyond-local-data-centres</guid><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[data privacy]]></category><category><![CDATA[Saudi Arabia]]></category><category><![CDATA[UAE ]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Tue, 04 Aug 2026 14:12:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/60ecf4a0fc37a15ec15655e8/7e9a218b-54d3-4d58-a996-61ca8e635eb2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A fresh wave of coverage on 3 August highlighted Abu Dhabi-based Aleria’s plan to pair NVIDIA systems with DDN storage in the UAE and United States. The underlying company announcement, however, is dated 19 March 2026. That distinction is useful: the hardware numbers are significant, but “sovereign AI” should not be measured by GPU counts—or by the date a press release returns to the news cycle.</p>
<p>For Gulf technology buyers, sovereignty is better treated as an operating model. It has at least four separate tests: where data and computation sit; who can administer the system; whether the workload can keep running through geopolitical or supplier disruption; and whether the customer can audit and move its models, data and applications.</p>
<p>The UAE and Saudi Arabia are taking different but increasingly complementary routes. Abu Dhabi is combining dedicated AI factories with residency-controlled software services. Saudi Arabia is expanding domestic public-cloud capacity and formal data-transfer controls. Neither route is automatically “more sovereign”. The answer depends on the workload.</p>
<h2>What the latest infrastructure claims actually say</h2>
<p><a href="https://aleria.ai/company/newsroom/aleria-x-nvidia-x-ddn-vera-ruben-news">Aleria’s March announcement</a> contains two geographically distinct plans. In the United States, it said 8,640 NVIDIA Grace Blackwell Ultra GPUs would be deployed, with plans to expand to 16,000, supported by a 25-megawatt data centre. In the UAE, it said it planned to deploy 28 racks of NVIDIA DGX Vera Rubin NVL72 systems under “full sovereign control”. The company did not disclose the UAE site’s power capacity, contract value, customer identities or an operational date.</p>
<p>That last sentence matters. On 3 August, <a href="https://www.khaleejtimes.com/business/tech/uae-us-abu-dhabi-aleria-sovereign-ai-infrastructure-nvidia-ddn-expansion-chips">Khaleej Times reported the expansion</a>, accurately separating the planned US chip count from the 28 UAE racks. A 16,000-GPU headline can easily be misread as 16,000 GPUs located in Abu Dhabi; Aleria’s primary material does not say that.</p>
<p>A related <a href="https://www.ddn.com/press-releases/ddn-and-nvidia-announce-dsx-factory-the-industrial-standard-for-sovereign-ai-infrastructure/">DDN reference architecture announcement</a> describes a stack built around NVIDIA Vera Rubin platforms, Spectrum-X networking, BlueField-4 DPUs, DDN storage and Aleria’s software layer. DDN says ten sovereign sites are planned over 24 months, with the first three implementations finalised for operational deployment in 2026. These are company claims, not independently published utilisation or performance results.</p>
<h2>The four tests of sovereignty</h2>
<h3>1. Data and compute location</h3>
<p>Local processing reduces exposure to cross-border transfer rules, latency and some geopolitical risks. It does not, by itself, establish who can access the system or what metadata leaves the country.</p>
<p>Abu Dhabi’s government provides a useful software-layer example. On 6 July, the Department of Government Enablement said it had deployed Microsoft 365 Copilot to 26,000 civil servants across 27 entities, adding to 9,000 existing licences for a total of 35,000. DGE said all licences use Advanced Data Residency and that AI processing takes place within the UAE.</p>
<p>Microsoft’s own documentation is more precise about the commitment: for Copilot, the content of interactions and the related semantic index are stored at rest in the relevant Local Region Geography; eligible ADR customers can commit prompts, responses and grounding citations to that geography. Buyers should verify the exact service, tenant configuration and data category rather than treating “local region” as a blanket promise for every log, support process and connected system.</p>
<h3>2. Administrative and cryptographic control</h3>
<p>A facility can be inside the country while privileged access, encryption keys, firmware updates or incident response remain dependent on an overseas supplier. Procurement teams should therefore ask four direct questions: Who holds the keys? Who can obtain emergency access? Where are administrator actions logged? Can the operator run the environment while disconnected from the vendor?</p>
<p>Dedicated or air-gapped infrastructure may score well here, but only if contracts, architecture and operating procedures support the claim. Aleria says customers can own and operate its infrastructure within their jurisdiction. No public technical audit supplied with the announcement proves the full control model, so regulated buyers still need evidence.</p>
<h3>3. Operational resilience</h3>
<p>Sovereignty also means continuing to operate when a cable is cut, a software entitlement fails, a component is export-controlled or a vendor relationship changes. A domestic data centre with a single external hardware, cloud or support dependency may meet residency requirements while remaining operationally fragile.</p>
<p>This is where architecture matters more than branding: spare-parts strategy, offline identity, local security operations, tested backup restoration, regional network diversity and a defined degraded mode. For AI factories, power and cooling capacity are part of the sovereignty boundary too.</p>
<h3>4. Auditability and exit</h3>
<p>The final test is whether the customer can inspect and leave. Useful evidence includes model and dataset lineage, reproducible evaluations in Arabic and English, administrator audit logs, documented data deletion, portable model artefacts, open interfaces and an exit plan that has actually been rehearsed.</p>
<p>Without those controls, “sovereign” can become a premium label attached to infrastructure that remains difficult to audit and expensive to replace.</p>
<h2>UAE and Saudi Arabia are solving different layers</h2>
<p>The UAE currently shows strength in integrated deployments. Abu Dhabi’s 35,000-seat Copilot programme addresses workforce adoption and data residency, while Aleria’s planned 28-rack deployment targets dedicated compute for government and regulated enterprises. The two models can coexist: controlled SaaS for common productivity tasks and private AI factories for highly sensitive or specialised workloads.</p>
<p>Saudi Arabia is building a broader domestic cloud base. Microsoft says its Saudi Arabia East region will become available in Q4 2026 with three availability zones. Google Cloud already offers a Dammam region and documents a KSA Data Boundary control package for supported services. Saudi Arabia’s Personal Data Protection Law and its separate rules for transfers outside the Kingdom add a legal layer that buyers must map to each workload.</p>
<p>The practical difference is not “UAE private, Saudi public”. Both markets use hybrid models. The more useful distinction is maturity by layer: available regions and services, workload-specific residency commitments, local operating capability, and credible exit options.</p>
<h2>Why this matters in MENA</h2>
<p>MENA is not one regulatory or infrastructure market. A UAE residency design cannot be copied into Saudi Arabia by changing the billing address, and an architecture approved for a Saudi commercial workload may not satisfy a government or health-sector buyer elsewhere.</p>
<p>For <strong>CTOs and security leaders</strong>, the immediate task is to turn sovereignty into testable requirements. Classify workloads; map prompts, embeddings, logs, backups and support data; specify key ownership and privileged-access controls; then run a failover and exit exercise before production.</p>
<p>For <strong>government and regulated-sector buyers</strong>, require claim-level evidence. Ask suppliers to separate what is live from what is planned, list every subcontractor and control-plane location, provide independent audit reports, and attach measurable residency, recovery and deletion obligations to the contract.</p>
<p>For <strong>investors and founders</strong>, domestic compute is an enabling layer, not a moat by itself. The durable opportunities are likely to sit above it: Arabic evaluation, sector-specific data governance, secure orchestration, observability, identity, model-risk management and tools that make workloads portable across sovereign environments.</p>
<h2>Conclusion</h2>
<p>The Gulf’s sovereign-AI build-out is moving from policy language into real procurement, cloud regions and large infrastructure plans. But the market needs a stricter scorecard. Location is only the first test; control, resilience, auditability and exit determine whether sovereignty survives contact with production.</p>
<p>The strongest buyers will stop asking, “Is this hosted locally?” and start asking, “Which parts are local, who controls them, how do we verify that, and what happens when a dependency fails?”</p>
<h2>Sources and methodology</h2>
<p>Research cut-off: <strong>4 August 2026, 17:46 Gulf Standard Time (UTC+4)</strong>. Primary company announcements were treated as claims unless supported by official documentation or a second source. No independent benchmark or utilisation data was found for Aleria’s planned UAE deployment.</p>
<ul>
<li><a href="https://aleria.ai/company/newsroom/aleria-x-nvidia-x-ddn-vera-ruben-news">Aleria — Blackwell Ultra and DGX Vera Rubin deployment plan (19 March 2026)</a></li>
<li><a href="https://www.ddn.com/press-releases/ddn-and-nvidia-announce-dsx-factory-the-industrial-standard-for-sovereign-ai-infrastructure/">DDN — Sovereign AI Factory reference architecture (16 March 2026)</a></li>
<li><a href="https://www.dge.gov.ae/en/news/2026-adg-microsoft">Abu Dhabi DGE — 35,000-seat Microsoft 365 Copilot rollout (6 July 2026)</a></li>
<li><a href="https://learn.microsoft.com/en-us/microsoft-365/enterprise/m365-dr-service-copilot?view=o365-worldwide">Microsoft Learn — Copilot data-residency commitments</a></li>
<li><a href="https://news.microsoft.com/source/emea/2026/02/microsoft-confirms-saudi-arabia-datacenter-region-available-for-customers-to-run-cloud-workloads-from-q4-2026/">Microsoft — Saudi Arabia East region availability from Q4 2026</a></li>
<li><a href="https://docs.cloud.google.com/assured-workloads/docs/control-packages/ksa-data-boundary-access-justifications">Google Cloud — KSA Data Boundary controls</a></li>
<li><a href="https://sdaia.gov.sa/en/SDAIA/about/Documents/Personal%20Data%20English%20V2-23April2023-%20Reviewed-.pdf">SDAIA — Saudi Personal Data Protection Law</a></li>
<li><a href="https://u.ae/en/about-the-uae/digital-uae/data/data-protection-laws">UAE Government — data-protection laws</a></li>
<li><a href="https://www.khaleejtimes.com/business/tech/uae-us-abu-dhabi-aleria-sovereign-ai-infrastructure-nvidia-ddn-expansion-chips">Khaleej Times — 3 August report on Aleria’s plan</a></li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Top 10 qualities of a good CTO]]></title><description><![CDATA[A Chief Technology Officer (CTO) is a senior executive who is responsible for the company's technology strategy and implementation. The CTO is typically a member of the executive leadership team and reports to the CEO.
The CTO's role involves setting...]]></description><link>https://www.hussain.io/top-10-qualities-of-a-good-cto</link><guid isPermaLink="true">https://www.hussain.io/top-10-qualities-of-a-good-cto</guid><category><![CDATA[leadership]]></category><category><![CDATA[cto]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Sun, 11 Dec 2022 09:26:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670750676211/8zJSFXBMf.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A Chief Technology Officer (CTO) is a senior executive who is responsible for the company's technology strategy and implementation. The CTO is typically a member of the executive leadership team and reports to the CEO.</p>
<p>The CTO's role involves setting the technical direction of the company, overseeing the development and implementation of new technologies, and ensuring that the technology team is working effectively and efficiently. The CTO is also responsible for aligning the company's technology strategy with its business objectives and ensuring that the technology infrastructure is scalable, secure, and cost-effective.</p>
<p>The CTO is often involved in the decision-making process for major technology initiatives and is responsible for managing the technology budget and resources. They may also play a role in building partnerships and relationships with technology vendors and partners.</p>
<p>Following are the top 10 qualities of a good CTO</p>
<h2 id="heading-1-technical-expertise">1. Technical expertise</h2>
<p>A CTO should have a deep understanding of technology, including current and emerging trends and best practices. This technical expertise allows them to make informed decisions about the direction of the company's technology and ensure that the right solutions are implemented.</p>
<h2 id="heading-2-business-acumen">2. Business acumen</h2>
<p>In addition to technical expertise, a CTO should also have a strong understanding of business principles and how technology can support the company's strategic goals. This allows them to make decisions that align with the business objectives and provide a positive return on investment.</p>
<h2 id="heading-3-leadership-skills">3. Leadership skills</h2>
<p>A CTO should be a strong leader who can motivate and inspire their team to achieve their goals. They should be able to communicate effectively and make difficult decisions when necessary.</p>
<h2 id="heading-4-collaboration">4. Collaboration</h2>
<p>A CTO should be able to work effectively with other members of the leadership team, as well as with other departments within the company. This requires strong communication skills and the ability to foster a collaborative environment.</p>
<h2 id="heading-5-strategic-thinking">5. Strategic thinking</h2>
<p>A CTO should be able to think strategically about the long-term direction of the company's technology. This includes identifying opportunities for innovation and implementing solutions that will support the company's growth and success.</p>
<h2 id="heading-6-adaptability">6. Adaptability</h2>
<p>The technology landscape is constantly changing, and a CTO should be able to adapt to new developments and challenges. This requires being open to new ideas and approaches and being willing to take calculated risks to drive innovation.</p>
<h2 id="heading-7-communication">7. Communication</h2>
<p>A CTO should be an effective communicator, both within their team and across the organization. This includes being able to clearly explain technical concepts to non-technical stakeholders and being able to translate business needs into technical requirements.</p>
<h2 id="heading-8-problem-solving">8. Problem-solving</h2>
<p>A CTO should be able to approach complex problems with a strategic mindset and find creative solutions. This requires being able to analyze data, identify trends, and think outside the box.</p>
<h2 id="heading-9-passion">9. Passion</h2>
<p>A CTO should be passionate about technology and its potential to drive positive change. This passion can be contagious and can inspire others to achieve their best work.</p>
<h2 id="heading-10-empathy">10. Empathy</h2>
<p>A CTO should be empathetic and able to understand the needs and concerns of others. This can help them to build strong relationships and foster a positive working environment.</p>
<p><strong>Overall, the CTO is a key member of the leadership team who plays a critical role in driving the company's technology strategy and ensuring that technology is leveraged to support the company's growth and success.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Implement Redis caching with ExpressJS]]></title><description><![CDATA[In this article, we are going to create a simple ExpressJS project which will call a starwars API to fetch its movie character details. This API is provided by  Swapi . You can find the code for this at  Github .
Installing Redis
Redis is an open-sou...]]></description><link>https://www.hussain.io/implement-redis-caching-with-expressjs</link><guid isPermaLink="true">https://www.hussain.io/implement-redis-caching-with-expressjs</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Express]]></category><category><![CDATA[Redis]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Thu, 29 Aug 2019 08:57:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/cPF2nlWcMY4/upload/v1638435261531/FdUOVs3ng.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we are going to create a simple ExpressJS project which will call a <code>starwars</code> API to fetch its movie character details. This API is provided by  <a target="_blank" href="https://pipedream.com/apps/swapi">Swapi</a> . You can find the code for this at  <a target="_blank" href="https://github.com/qualascend/starwars-redis-express">Github</a> .</p>
<h2 id="heading-installing-redis">Installing Redis</h2>
<p>Redis is an open-source, key-value database. It is widely used for caching as an in-memory data structure. It can also be used as a persistence database.</p>
<h3 id="heading-windows">Windows</h3>
<p>On windows, you can install Redis by downloading it from https://github.com/dmajkic/redis/downloads after unzip run the executable file.</p>
<h3 id="heading-mac">Mac</h3>
<p>On Mac, you can use a Homebrew package manager.</p>
<p>If homebrew is not already installed you can install it by running the following command</p>
<pre><code>/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/<span class="hljs-keyword">install</span>/<span class="hljs-keyword">master</span>/<span class="hljs-keyword">install</span>)<span class="hljs-string">"</span>
</code></pre><p>Once Homebrew is installed you can install Redis</p>
<pre><code><span class="hljs-attribute">brew</span> install redis
</code></pre><h3 id="heading-docker">Docker</h3>
<p>The best way to get Redis running quickly on any operating system is using Docker.</p>
<p>Once docker is successfully installed you can execute the following command to run Redis in the background.</p>
<pre><code>docker run <span class="hljs-comment">--name some-redis -d redis</span>
</code></pre><h2 id="heading-setting-up-our-project">Setting up our project</h2>
<p>Let's start by creating our project directory and <code>cd</code> into it.</p>
<pre><code>mkdir starwars-redis-express
<span class="hljs-built_in">cd</span> starwars-redis-express
</code></pre><p>Initialize a NodeJS project passing the <code>-y</code> flag which accepts all the defaults.</p>
<p><code>npm init -y</code></p>
<p>For this project, we will use ExpressJS as our web framework, Node Fetch library to call starwars API, and Redis library to communicate with Redis.</p>
<p>Install express, node-fetch, and Redis</p>
<p><code>npm i express node-fetch redis</code></p>
<p>Install <code>nodemon</code> as a dev dependency so that we don’t have to manually restart the server again and again after every change.</p>
<p><code>npm i -D nodemon</code></p>
<p>Open <code>package.json</code> and add a script like this</p>
<pre><code><span class="hljs-string">"scripts"</span>: {
  <span class="hljs-string">"start"</span>: <span class="hljs-string">"nodemon index"</span>
}
</code></pre><p>Now let's create a simple express server.</p>
<p>Create <code>index.js</code> file</p>
<pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> PORT = process.env.PORT || <span class="hljs-number">3000</span>;
app.get(<span class="hljs-string">'/startwars/people'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  res.send(<span class="hljs-string">'Star Wars'</span>);
});
app.listen(PORT, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`App listening on port <span class="hljs-subst">${PORT}</span>`</span>);
});
</code></pre><p>Now let's run the server by executing the command npm run start.</p>
<p>If you visit <code>http://localhost:3000/starwars/people</code> you should see a text <strong>Star Wars</strong> on your browser.</p>
<p>The endpoint is <code>startwars</code> because we are going to consume Star Wars API from https://swapi.co/ in this example app.</p>
<p>Let’s call the star wars actual API to fetch the results and send them to the client.</p>
<p>First import the nodefetch libaray</p>
<p><code>const fetch = require('node-fetch')</code></p>
<p>create an <code>async</code> function to call startwars API.</p>
<pre><code><span class="hljs-keyword">const</span> getPeople = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> { id } = req.params;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Fetching people data for id <span class="hljs-subst">${id}</span>`</span>);
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(
      <span class="hljs-string">`https://swapi.co/api/people/<span class="hljs-subst">${req.params.id}</span>`</span>
    );
    <span class="hljs-keyword">const</span> people = <span class="hljs-keyword">await</span> response.json();
    res.send(getResponse(people));
  } <span class="hljs-keyword">catch</span> (err) {
    <span class="hljs-built_in">console</span>.error(err);
    res.status(<span class="hljs-number">500</span>);
  }
};
</code></pre><p>Implement the getResponse function use above</p>
<pre><code>const getResponse = <span class="hljs-function"><span class="hljs-params">(people)</span> =&gt;</span> {
  const { name, height, gender } = people;
  <span class="hljs-keyword">return</span> `<span class="javascript">
    &lt;ul&gt;
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Name: ${name}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Height: ${height}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span>Gender: ${gender}<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span></span>
    &lt;/ul&gt;
  </span>`;
}
</code></pre><p>Change our API definition to include <code>id</code> as the URL parameter</p>
<p><code>app.get('/startwars/people/:id', getPeople);</code></p>
<p>Above API calls the <code>getPeople</code> function which then calls the <code>starwars</code> API to fetch person data by <code>id</code>.</p>
<p>Now if you visit URL <code>http://localhost:3000/startwars/people/1</code> you should get a below response</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638175926034/y76RgvQDj.png" alt="1_-C4T8P8VC61j400ghh5Fbg.png" /></p>
<p>If you check the network logs in the browser our API call approximately take 2 sec to respond.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638176767746/C-3AbDufz.png" alt="1_eIUTHnuqZ3HVP0HTZy0FEw.png" /></p>
<p>Now let's add caching to our API to make it faster</p>
<p>Import the Redis package</p>
<p><code>const redis = require('redis');</code></p>
<p>Connect to Redis client</p>
<pre><code><span class="hljs-keyword">const</span> REDIS_PORT = process.env.REDIS_PORT || <span class="hljs-number">6379</span>;
<span class="hljs-keyword">const</span> client = redis.createClient(REDIS_PORT);
</code></pre><p>Create a middleware function to return the cached response if available</p>
<pre><code>const cachePeople = <span class="hljs-function"><span class="hljs-params">(req, res, next)</span> =&gt;</span> {
  const { id } = req.params;
  client.get(id, <span class="hljs-function"><span class="hljs-params">(err, data)</span> =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
    <span class="hljs-keyword">if</span> (data !== <span class="hljs-literal">null</span>) {
      res.send(getResponse(<span class="hljs-built_in">JSON</span>.parse(data)));
    } <span class="hljs-keyword">else</span> {
      next();
    }
  });
};
</code></pre><p>This function checks if there is an entry against the id in Redis. If it finds one it will return the cached result other will return next() which will allow continuing with the normal API call.</p>
<p>Change the API call line to make use of the above middleware.</p>
<p><code>app.get('/startwars/people/:id', cachePeople, getPeople);</code></p>
<p>Last we need to add a line in our <code>getPeople</code> function right before we send the response to the client to set an entry in Redis after fetching result from <code>starwars</code> API.</p>
<pre><code>client.<span class="hljs-keyword">set</span>(id, <span class="hljs-type">JSON</span>.stringify(people), <span class="hljs-string">'EX'</span>, <span class="hljs-number">3600</span>);
res.send(getResponse(people));
</code></pre><p>This will create a cache entry with key <code>id</code> for 3600 sec.</p>
<p>Now if you visit the URL <code>http://localhost:3000/startwars/people/1</code> first time it will take around ~2sec to load if you refresh it you will see response time will be less than ~10ms</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638176052175/WKd0p1VJdK.png" alt="1_JITCfYFxOG3d-t00q1_gJQ.png" /></p>
<p>If you change the <code>id</code> from 1 to 2 again the first response time will be high but further requests will be served from the cache until the cache entry expires.</p>
<p>That’s it, you check out the code on GitHub.</p>
<p>This article is inspired by Brad’s video tutorial https://www.youtube.com/watch?v=oaJq1mQ3dFI. Follow it to learn a lot of cool things.</p>
<p>Thanks</p>
]]></content:encoded></item><item><title><![CDATA[Add a static form to your NextJs app without serverside code.]]></title><description><![CDATA[NextJS is an amazing framework created by Vercel for developing search engine friendly static and dynamic web applications using ReactJS.
Source on Github.
In this article, we’ll cover how to add a static form to your site which on submit will send a...]]></description><link>https://www.hussain.io/add-a-static-form-to-your-nextjs-app-without-serverside-code</link><guid isPermaLink="true">https://www.hussain.io/add-a-static-form-to-your-nextjs-app-without-serverside-code</guid><category><![CDATA[Next.js]]></category><category><![CDATA[React]]></category><category><![CDATA[static]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Sun, 25 Aug 2019 07:23:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638248421681/HLSAhzxsu.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="https://nextjs.org/">NextJS</a> is an amazing framework created by <a target="_blank" href="https://vercel.com/">Vercel</a> for developing search engine friendly static and dynamic web applications using ReactJS.</p>
<p>Source on <a target="_blank" href="https://github.com/qualascend/staticforms-nextjs-zeit">Github</a>.</p>
<p>In this article, we’ll cover how to add a static form to your site which on submit will send an email to your address.</p>
<p>To add a static form we’ll use a free service called <a target="_blank" href="https://www.staticforms.xyz/">StaticForms</a> which allows you to easily integrate your form with your email.</p>
<p>Following steps are required to create a static form</p>
<ul>
<li>Create an Access Key on <a target="_blank" href="https://www.staticforms.xyz">StaticForms</a></li>
<li>Create a NextJS app using npx</li>
<li>Add Bulma library for styling</li>
<li>Modify the index.js to add the form</li>
<li>Integrate the form to submit to staticforms.xyz action</li>
<li>Deploy to Vercel</li>
</ul>
<h4 id="heading-step-1-create-access-key-on-staticforms">Step 1: Create Access Key on StaticForms</h4>
<ul>
<li>Visit <a target="_blank" href="https://www.staticforms.xyz">https://www.staticforms.xyz</a></li>
<li>Enter your email address under create access key input field and submit by clicking on the button “Create Access Key”</li>
<li>You will receive an email with an access key which we’ll use in our form later.</li>
</ul>
<h4 id="heading-step-2-create-a-nextjs-app">Step 2: Create a NextJS app</h4>
<pre><code>npx <span class="hljs-keyword">create</span>-<span class="hljs-keyword">next</span>-app staticforms
</code></pre><h4 id="heading-step-3-add-bulma-css-library">Step 3: Add Bulma CSS library</h4>
<p>cd into <code>staticforms</code> directory <code>cd staticform</code> and add Bulma library for styling</p>
<pre><code><span class="hljs-built_in">npm</span> i bulma
</code></pre><p>Install NextJS CSS plugin to use CSS library</p>
<pre><code>npm i @zeit/<span class="hljs-keyword">next</span>-css
</code></pre><p>Create in your root directory <code>next.config.js</code> with the following content:</p>
<pre><code><span class="hljs-comment">// next.config.js   </span>
const withCSS <span class="hljs-operator">=</span> <span class="hljs-built_in">require</span>(<span class="hljs-string">'@zeit/next-css'</span>)  

module.exports <span class="hljs-operator">=</span> withCSS({  
  cssLoaderOptions: {  
    url: <span class="hljs-literal">false</span>  
  }  
})
</code></pre><h4 id="heading-step-5-create-the-form">Step 5: Create the form</h4>
<p>Modify index.js<code>./pages/index.js</code> under pages directory with following code.</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="cd3e4b6ba275674e2df92455501d98d0"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a href="https://gist.github.com/hussainanjar/cd3e4b6ba275674e2df92455501d98d0" class="embed-card">https://gist.github.com/hussainanjar/cd3e4b6ba275674e2df92455501d98d0</a></div><p>Don’t forget to replace the access key with your own access key.</p>
<p>The code above uses <code>useState</code> react hook to manage the state. <code>onChange</code> event on each field keeps the <code>contact</code> object in the state updated. <code>onSubmit</code> event is used to handle the submission and the form data is posted to action<code>https://api.staticforms.xyz/submit</code> using NodeJS <code>fetch</code> API.</p>
<h4 id="heading-step-4-deploy-to-vercel">Step 4: Deploy to Vercel</h4>
<p><a target="_blank" href="https://vercel.com/">Vercel</a> provides a super simple platform to deploy serverless applications. And it's out of the box support for NextJs makes it even easier.</p>
<p>First install the now platform globally</p>
<pre><code>npm i <span class="hljs-operator">-</span>g <span class="hljs-built_in">now</span>
</code></pre><p>And then simply type <code>now</code> to deploy your application to the platform.</p>
<pre><code><span class="hljs-built_in">now</span>
</code></pre><p>Once the deployment is complete you should receive URL to test your application online, something similar to <code>[https://staticforms.hussainanjar.now.sh](https://staticforms.hussainanjar.now.sh)</code></p>
<p>You can run the <code>now</code> platform locally using the following command.</p>
<pre><code><span class="hljs-attribute">now</span> dev
</code></pre><p>You can check out the repo here <a target="_blank" href="https://github.com/qualascend/staticforms-nextjs-zeit">https://github.com/qualascend/staticforms-nextjs-zeit</a></p>
<p>That's it!</p>
]]></content:encoded></item><item><title><![CDATA[Awesomeness of Sublime Text Editor]]></title><description><![CDATA[Sublime Text is one of the coolest text editor for code I have come across. If you are new to Sublime and are really interested in learning about the power of Sublime I would highly recommend you to attend a free video course on [Tuts+ conducted by J...]]></description><link>https://www.hussain.io/awesomeness-of-sublime-text-editor</link><guid isPermaLink="true">https://www.hussain.io/awesomeness-of-sublime-text-editor</guid><category><![CDATA[Sublime Text]]></category><category><![CDATA[editors]]></category><category><![CDATA[code]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Fri, 05 Dec 2014 08:28:27 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/7EWs6pwc6Bw/upload/v1638435065920/neyWLdqA1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a target="_blank" href="http://www.sublimetext.com/">Sublime Text</a> is one of the coolest text editor for code I have come across. If you are new to Sublime and are really interested in learning about the power of Sublime I would highly recommend you to attend a free video course on [Tuts+ conducted by Jeffrey Way] (https://code.tutsplus.com/courses/perfect-workflow-in-sublime-text-2).</p>
<p>If you are in a hurry and would like to quickly know some benefits of Sublime Text continue reading.</p>
<h2 id="heading-shortcut-keys">Shortcut keys</h2>
<p>In shortcut keys, I'll be using <code>super</code> which is <code>cmd</code> key if you are using <strong>Mac</strong> and <code>ctrl</code> key if you are using <strong>Window</strong>.</p>
<ul>
<li><code>super + p</code> - Open any file using fuzzy search</li>
<li><code>super + shift + p</code> - Access to complete Sublime menu using fuzzy search</li>
<li><code>super + r</code> - Search methods in current file</li>
<li><code>super + i</code> - Instant incremental search in current file</li>
<li><code>super + /</code> - Toggle commenting out line</li>
<li><code>option</code> - For column select using mouse</li>
<li><code>super + w</code> - Closes current tab</li>
<li><code>super + =</code> - Zoom in</li>
<li><code>super + _</code> - Zoom out</li>
<li><code>super + d</code> - Selects next matching word</li>
<li><code>super + ctrl + g</code> - Select all matching words</li>
<li><code>super + shift + l</code> - Writes on all selected lines at the same time</li>
</ul>
<h2 id="heading-package-control">Package Control</h2>
<p>Heart of Sublime Text are its plugins and the easiest way to install plugins is through Package Control.</p>
<p>Install Package control easily using steps mentioned over here <a href="https://sublime.wbond.net/installation">https://sublime.wbond.net/installation</a></p>
<p>Once Package control is installed just press <code>super+shift+p</code> to open command prompt and type <em>install</em> and press enter to open search for package control. </p>
<p>Search for any package you want to install and just press enter. Some plugins may require you to restart Sublime.</p>
<h2 id="heading-snippets">Snippets</h2>
<p>Snippets are smart templates that will insert text for you and adapt it to their context. For e.g. in an HTML file if you type in <code>&lt;a</code> and then press tab it will complete the tag template for you <code>&lt;a href=""&gt;&lt;/a&gt;</code>.</p>
<p>To see what snippets are already installed with Sublime, press <code>super+shit+p</code> and type <strong>Snippets</strong>, select the one you want to use, and press enter.</p>
<p>You can also install snippets created by the community. For e.g. I use groovy language and by default Sublime doesn't come with groovy snippets. To install them open command prompt using <code>super+shit+p</code> and type <strong>install</strong>, press enter to open Package control and type <strong>groovy snippets</strong>, select the groovy snippets plugin, and press enter.</p>
<p>To test groovy snippets create a new groovy file and type <code>for</code> and press <code>tab</code> <strong>for</strong> syntax will be completed by groovy snippets.</p>
<p>You can even create your own <a target="_blank" href="http://sublime-text-unofficial-documentation.readthedocs.org/en/latest/extensibility/snippets.html#snippets-file-format">snippets</a>.</p>
<h2 id="heading-plugins">Plugins</h2>
<p>As mentioned above plugins is what makes Sublime Text so special, and now that we have already installed package control, let's review some nice plugins.</p>
<p>All plugins mentioned below can be installed using Package Control. Press <code>super+shift+p</code> type <strong>install</strong> press enter to open Package control search, type in the name of the plugin you want to install, and press enter.</p>
<h4 id="heading-emmethttpemmetio"><a target="_blank" href="http://emmet.io/">Emmet</a></h4>
<p>Emmet (previously known as Zen Coding) is a web developer’s toolkit that can greatly improve your HTML &amp; CSS workflow.</p>
<h4 id="heading-advanced-new-filehttpssublimewbondnetpackagesadvancednewfile"><a target="_blank" href="https://sublime.wbond.net/packages/AdvancedNewFile">Advanced New File</a></h4>
<p>This plugin allows for faster file creation within a project. Press <code>supet+alt+n</code> and type the incomplete path of the file with the extension you want to create and press enter. It will also create the directory if it doesn't already exist</p>
<h4 id="heading-sublime-linterhttpwwwsublimelintercomenlatest"><a target="_blank" href="http://www.sublimelinter.com/en/latest/">Sublime Linter</a></h4>
<p>SublimeLinter is a plugin for Sublime Text 3 that provides a framework for linting code. Whatever language you code in, SublimeLinter can help you write cleaner, better, more bug-free code.</p>
<h4 id="heading-gisthttpsgithubcomcondemilgist"><a target="_blank" href="https://github.com/condemil/Gist">Gist</a></h4>
<p>A Sublime Text 2/3 plugin for creating and editing GitHub Gists.</p>
<h4 id="heading-http-requesterhttpsgithubcombraindamageincsublimehttprequester"><a target="_blank" href="https://github.com/braindamageinc/SublimeHttpRequester">Http Requester</a></h4>
<p>Makes HTTP requests using the selected text as URL + headers. Useful for testing REST APIs from Sublime Text 2 editor.</p>
<h4 id="heading-live-reloadhttpssublimewbondnetpackageslivereload"><a target="_blank" href="https://sublime.wbond.net/packages/LiveReload">Live Reload</a></h4>
<p>A web browser page reloading plugin for the Sublime Text editor.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I have hardly covered 10% of what Sublime Text can do. Again do attend the free video course on [Tuts+ conducted by Jeffrey Way] (https://code.tutsplus.com/courses/perfect-workflow-in-sublime-text-2).</p>
<p>Thanks and I hope it was helpful.</p>
]]></content:encoded></item><item><title><![CDATA[Setting up SonarQube for Grails project]]></title><description><![CDATA[SonarQube is an open-source platform to manage code quality. It covers many aspects of code quality like Complexity, Coding rules, Duplications, Unit tests coverage, etc.
It's really easy to configure SonarQube with your Grails project.
Download and ...]]></description><link>https://www.hussain.io/setting-up-sonarqube-for-grails-project</link><guid isPermaLink="true">https://www.hussain.io/setting-up-sonarqube-for-grails-project</guid><category><![CDATA[Spring]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Mon, 01 Dec 2014 08:42:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1638434324665/GFif69ir2.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><a href="http://www.sonarqube.org/">SonarQube</a> is an open-source platform to manage code quality. It covers many aspects of code quality like Complexity, Coding rules, Duplications, Unit tests coverage, etc.</p>
<p>It's really easy to configure SonarQube with your Grails project.</p>
<h4 id="heading-download-and-install">Download and Install</h4>
<p>Download SonarQube and SonarQube Runner from http://www.sonarqube.org/downloads/</p>
<p>Extract the archived files in your preferred directory. I have extracted them in <code>/usr/sonarqube-4.5.1</code> and <code>/usr/sonar-runner-2.4</code></p>
<h4 id="heading-configure-sonarqube">Configure SonarQube</h4>
<p>Configure SonarQube properties by editing file on following path</p>
<p><code>/usr/sonarqube-4.5.1/conf/sonar.properties</code></p>
<p>In this file you will configure settings for database that will be used by SonarQube. I have MySql installed locally so uncomment following lines.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># User credentials.</span>
<span class="hljs-comment"># Permissions to create tables, indices and triggers must be granted to JDBC user.</span>
<span class="hljs-comment"># The schema must be created first.</span>
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
...
...
...
<span class="hljs-comment">#----- MySQL 5.x</span>
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=<span class="hljs-literal">true</span>&amp;characterEncoding=utf8&amp;rewriteBatchedStatements=<span class="hljs-literal">true</span>&amp;useConfigs=maxPerformance
</code></pre>
<p>As mentioned in the file you need to first create a database with name <code>sonar</code> </p>
<pre><code class="lang-sql"><span class="hljs-keyword">create</span> <span class="hljs-keyword">database</span> sonar;
</code></pre>
<p>and then create a user that has full permission on the sonar database.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">USER</span> <span class="hljs-string">'sonar'</span>@<span class="hljs-string">'localhost'</span> <span class="hljs-keyword">IDENTIFIED</span> <span class="hljs-keyword">BY</span> <span class="hljs-string">'sonar'</span>;
<span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">ALL</span> <span class="hljs-keyword">PRIVILEGES</span> <span class="hljs-keyword">ON</span> sonar.* <span class="hljs-keyword">TO</span> <span class="hljs-string">'sonar'</span>@<span class="hljs-string">'%'</span> <span class="hljs-keyword">WITH</span> <span class="hljs-keyword">GRANT</span> <span class="hljs-keyword">OPTION</span>;
</code></pre>
<p>Now start SonarQube server using the following command.</p>
<p><code>/usr/sonarqube-4.5.1/bin/macosx-universal-64/sonar.sh start</code></p>
<p>As I'm using OSX that's why I have chosen <code>macosx-universal-64</code> architecture, use the one suitable based on your operating system.</p>
<p>Now you need to install some plug-ins for SonarQube to work for Grails.</p>
<p>In your browser navigate to <code>http://localhost:9000/</code>. Click on <strong>login</strong> link on top right corner of the page.</p>
<p>Enter user-name and password default is <code>admin \ admin</code></p>
<p>Click on <strong>Settings</strong> in the top right corner, then click on <strong>Update Center</strong> under the System menu item on the left. From the Update center you can install / un-install and upgrade your plug-ins, first page shows all the plug-ins already installed with SonarQube.</p>
<p>Click on <strong>Available Plugins</strong>, you need to install 3 plugins for the scope of this article.</p>
<ul>
<li>Groovy - <em>Enables analysis of Groovy projects.</em></li>
<li>Cobertura - <em>Get code coverage with Cobertura.</em></li>
<li>SCM Activity - <em>Collects and reports information from SCM.</em></li>
</ul>
<p>Search each of these plugins on the available plugins page and install them. Once installation is complete restart SonarQube for the plugins to take effect.</p>
<h4 id="heading-configuring-sonar-runner">Configuring Sonar Runner</h4>
<p>Configure Sonar Runner properties by editing file on following path</p>
<p><code>/usr/sonar-runner-2.4/conf/sonar-runner.properties</code></p>
<p>Uncomment following line for Sonar Runner to connect to MySql database.</p>
<pre><code class="lang-bash"><span class="hljs-comment">#----- MySQL</span>
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=<span class="hljs-literal">true</span>&amp;amp;characterEncoding=utf8
</code></pre>
<h4 id="heading-configuring-grails-project">Configuring Grails project</h4>
<p>Create <code>sonar-project.properties</code> at the root of your Grails project with the following values.</p>
<pre><code class="lang-bash">sonar.projectKey=com.domain.my-project
sonar.projectName=My Project
sonar.projectVersion=1.0

sonar.sources=src/groovy,grails-app/services,grails-app/controllers,grails-app/domain,grails-app/utils,<span class="hljs-built_in">test</span>/unit
sonar.language=grvy
sonar.sourceEncoding=UTF-8

<span class="hljs-comment"># Path to the Cobertura XML report</span>
sonar.groovy.cobertura.reportPath=target/test-reports/cobertura/coverage.xml
</code></pre>
<p>Change <code>sonar.projectKey</code> and <code>sonar.projectName</code> as required. For the coverage to work properly make sure you specify all directories where your groovy code exists, your can exclude and include other directories as you need.</p>
<h4 id="heading-analyzing-the-grails-project">Analyzing the Grails project</h4>
<p>Before you analyze your Grails project using Sonar Runner, make sure the code coverage plugin is installed in your project (http://grails.org/plugin/code-coverage) and you will have to execute the following command to generate cobertura xml file to be used by sonar.</p>
<p><code>grails test-app -coverage -xml</code></p>
<p>Now analyze your project by running the following command from the root of your Grails project</p>
<p><code>/opt/sonar-runner-2.4/bin/sonar-runner</code></p>
<p>If everything went well you should be able to see data related to your project in SonarQube at <code>http://localhost:9000/</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1638434324665/GFif69ir2.png" alt="sonar-sc.png" /></p>
]]></content:encoded></item><item><title><![CDATA[Reinitializing jquery event on ajax response]]></title><description><![CDATA[I had a jquery change event attached to a checkbox that was part of a div.
<div id="test-div">
<input type="checkbox" checked="checked" value="1" class="test-chkbox" />
</div>

Using the following JQuery code a change event was attached to the above ...]]></description><link>https://www.hussain.io/reinitializing-jquery-event-on-ajax-response</link><guid isPermaLink="true">https://www.hussain.io/reinitializing-jquery-event-on-ajax-response</guid><category><![CDATA[jQuery]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Tue, 31 Jan 2012 12:17:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/idmvPhF8t4E/upload/v1638447442913/fmOFDBOcB.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I had a jquery change event attached to a checkbox that was part of a div.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"test-div"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span> <span class="hljs-attr">checked</span>=<span class="hljs-string">"checked"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"test-chkbox"</span> /&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>Using the following JQuery code a change event was attached to the above check-box</p>
<pre><code class="lang-javascript">$(<span class="hljs-string">".test-chkbox"</span>).change(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    $.ajax({
        <span class="hljs-attr">type</span>: <span class="hljs-string">"GET"</span>,
        <span class="hljs-attr">url</span>: <span class="hljs-string">"some-action"</span>,
        <span class="hljs-attr">data</span>: <span class="hljs-built_in">this</span>.value,
        <span class="hljs-attr">cache</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">response</span>) </span>{
            $(<span class="hljs-string">"#test-div"</span>).replaceWith(response);
        }
    });
});
</code></pre>
<p>Response of ajax contained the same check-box but the change event was no more attached to it, so to solve the issue I changed jQuery code as specified below.</p>
<pre><code class="lang-javascript">$(<span class="hljs-built_in">document</span>).on(<span class="hljs-string">"change"</span>, <span class="hljs-string">".test-chkbox"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    $.ajax({
        <span class="hljs-attr">type</span>: <span class="hljs-string">"GET"</span>,
        <span class="hljs-attr">url</span>: <span class="hljs-string">"some-action"</span>,
        <span class="hljs-attr">data</span>: <span class="hljs-built_in">this</span>.value,
        <span class="hljs-attr">cache</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">response</span>) </span>{
            $(<span class="hljs-string">"#test-div"</span>).replaceWith(response);
        }
    });
});
</code></pre>
<p>The above change made sure that the change event is always attached to the check-box even after the ajax response.</p>
<p>Note: Older versions of jQuery use <strong>.delegate</strong> and <strong>.live</strong> instead of .<strong>on</strong></p>
]]></content:encoded></item><item><title><![CDATA[Basic Usage of VIM Editor]]></title><description><![CDATA[In this blog, we are going to discuss the very basic usage of the VIM editor.
What is VIM
Vim is an advanced text editor that seeks to provide the power of the de-facto Unix editor 'VI', in short VIM is an improved version of VI text editor.
Modes in...]]></description><link>https://www.hussain.io/basic-usage-of-vim-editor</link><guid isPermaLink="true">https://www.hussain.io/basic-usage-of-vim-editor</guid><category><![CDATA[vim]]></category><category><![CDATA[editors]]></category><dc:creator><![CDATA[Hussain Fakhruddin]]></dc:creator><pubDate>Sun, 30 Oct 2011 12:23:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/TDV1i2f7rcc/upload/v1638447784013/1vnhwOvn2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we are going to discuss the very basic usage of the VIM editor.</p>
<h5 id="heading-what-is-vim"><strong>What is VIM</strong></h5>
<p>Vim is an advanced text editor that seeks to provide the power of the de-facto Unix editor 'VI', in short VIM is an improved version of VI text editor.</p>
<h5 id="heading-modes-in-vim"><strong>Modes in VIM</strong></h5>
<p>VIM has six different modes, you can switch between these modes to perform different actions on the file you are editing. Here we will discuss NORMAL, INSERT and COMMAND-LINE modes.</p>
<h5 id="heading-using-vim"><strong>Using VIM</strong></h5>
<p>By default, VIM opens in NORMAL mode. Type <strong>vim</strong> and press enter to open a blank file.</p>
<blockquote>
<p><code>vim</code></p>
</blockquote>
<p>Type <strong><code>vim newfile</code></strong> to open a blank file with a name <strong>'newfile'</strong> or edit a file by typing <strong><code>vim oldfile</code></strong> to edit an old file.</p>
<blockquote>
<p><code>vim newfile</code></p>
<p><code>vim oldfile</code></p>
</blockquote>
<p>To edit the file you need to enter the <strong>INSERT</strong> mode press <strong><code>i</code></strong> to enter this mode. Type anything you want and once you are done save or exit the file by entering the <strong>COMMAND-LINE</strong> mode.</p>
<p>If you are currently in <strong>INSERT</strong> mode press <strong>ESC</strong> to exit the <strong>INSERT</strong> mode and then press <strong><code>:</code></strong> to enter the <strong>COMMAND-LINE</strong> mode. You can use following commands in this mode.</p>
<blockquote>
<p><code>:w</code>   -  save the file</p>
<p><code>:q</code>   -  exit</p>
<p><code>:wq</code> -  save and exit</p>
<p><code>:q!</code> -  exit without saving</p>
</blockquote>
<p>If you initially opened a blank new file just by entering <strong><code>vim</code></strong> you can type the name of the file after the above command to save the file with the name you want.</p>
<blockquote>
<p><code>:w mynewfile</code></p>
<p><code>:wq mynewfile</code></p>
</blockquote>
]]></content:encoded></item></channel></rss>