<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: bimlas</title>
    <description>The latest articles on Forem by bimlas (@bimlas).</description>
    <link>https://forem.com/bimlas</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F152048%2F2c96738c-4f54-4a4d-a16e-2160336471ba.png</url>
      <title>Forem: bimlas</title>
      <link>https://forem.com/bimlas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bimlas"/>
    <language>en</language>
    <item>
      <title>Distraction free desktop workspace for developers</title>
      <dc:creator>bimlas</dc:creator>
      <pubDate>Wed, 26 Jul 2023 13:44:27 +0000</pubDate>
      <link>https://forem.com/bimlas/distraction-free-desktop-workspace-for-developers-1p6k</link>
      <guid>https://forem.com/bimlas/distraction-free-desktop-workspace-for-developers-1p6k</guid>
      <description>&lt;p&gt;Searching for and arranging windows momentarily interrupts the workflow and disrupts the continuity of your thoughts, therefore easily impeding the flow. Consequently, the comfort of the environment you use on a daily basis is important. The following article discusses organizing the workspace and enabling fast switching between windows and virtual desktops. Based on my experience, I have compiled Linux solutions that bring the convenience of Tmux, commonly found in terminal environments, to GUI desktop environments (such as XFCE, KDE, GNOME, etc.). Tiling window managers (AwesomeWM, Qtile, I3, etc.) are optional but highly useful components of the environment. The main goal of Rofi shell scripts is to create an easily usable, fast, and keyboard-driven workflow.&lt;/p&gt;

&lt;p&gt;You can think of the windows in the desktop environment as different panels or views in an IDE, and like panels, windows perform different tasks. An IDE is convenient (among other reasons) because all the necessary tools for a task are in one place, and you know the position of each panel without thinking. So, if you can easily access your windows, then &lt;strong&gt;your operating system itself can be as efficient as an integrated development environment&lt;/strong&gt; ("Unix as IDE").&lt;/p&gt;

&lt;p&gt;The solutions listed below (and &lt;strong&gt;the implementations on the end of this article&lt;/strong&gt;) are inspirational, and you can choose from them according to your preference. Each of them is an optional plugin for your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terminal workflow
&lt;/h2&gt;

&lt;p&gt;The need for switching between running processes and their spatial arrangement has already emerged in the terminal, which is why the frequently mentioned "split" solutions of GNU Screen and Tmux programs were created. Let's assume that you are not using a desktop environment, just a single terminal. If you open a text editor to edit a program's code and you want to view documentation for a specific command, you first have to hide (minimize) the text editor and bring it back to the foreground after reading the documentation because you don't have the ability to display the documentation and the code simultaneously (for the sake of clarity, we will disregard the capabilities of the text editor).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DDxhN9m1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/01-terminal-jobs.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DDxhN9m1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/01-terminal-jobs.gif" alt="terminal jobs" width="640" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The "split" solution in Tmux helps with this by dividing the terminal into two sections, as if they were two glued windows, allowing you to see the subjects of your task side by side. Similarly, you can further divide the terminal into additional sections to open additional applications, but these applications partition the fixed-sized area into further subdivisions, ensuring they do not overlap and remain fully visible. However, as you open more applications, the area allocated to each application becomes smaller and smaller, eventually becoming too small to be usable, thus making the workspace uncomfortable despite the convenience provided by the "split" feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gNn5ZrV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/02-tmux-split.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gNn5ZrV5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/02-tmux-split.gif" alt="tmux split" width="640" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users vary in how they use Tmux, but generally, these styles are popular and address this problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate workspaces for each task
&lt;/h3&gt;

&lt;p&gt;In Tmux, you can create additional workspaces, virtual desktops, so you can have a workspace, for example, where you see the code and documentation side by side, and another workspace where you have a database client and the database documentation open. This way, the programs are grouped logically according to their tasks. You can give names to the groups, and you can easily switch between them using a searchable list (thanks to FZF).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0FryU8Bm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/03-tmux-window-list-fuzzy-filter.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0FryU8Bm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/03-tmux-window-list-fuzzy-filter.gif" alt="tmux window list fuzzy-filter" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The advantage of continuously decreasing size for newly opened applications is that the workspace itself forces you to make it more organized, thus demanding structured work.&lt;/strong&gt; Unnecessary open applications that only occupy space will be closed without request, and only what you actually use will remain on your workspace.&lt;/p&gt;

&lt;p&gt;However, this solution has several disadvantages for me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you need to open more and more applications for a task, you will once again have limited space, requiring you to create new workspaces. One possible solution is to group the workspaces by naming them (e.g., splitting the &lt;code&gt;fix-db-issue&lt;/code&gt; workspace into &lt;code&gt;fix-db-issue_code&lt;/code&gt; and &lt;code&gt;fix-db-issue_db-client&lt;/code&gt;), but this is not efficient; clearly, it is a workaround.&lt;/li&gt;
&lt;li&gt;Based on the list of workspaces, you cannot see which applications are open in each workspace. For example, if my colleague requested a database query from me, I knew that I already had a pre-opened database client, but I couldn't remember which task it was related to or which workspace it appeared in. Although I could search among the workspace names textually, it would have been simpler to search for the name of the application itself, relying solely on text search. &lt;strong&gt;The mixed use of spatial memory and textual search is not efficient.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Separate sessions for each task
&lt;/h3&gt;

&lt;p&gt;In Tmux, workspaces are associated with a session, but you can create multiple sessions, which means you can keep tasks in separate sessions. The advantage of this approach is that you can see each application in full size on its own workspace, and you only use splits when you actually want to view applications side by side, such as comparing two documents. This is more convenient than constantly moving applications to another workspace due to decreasing sizes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RI0LQ4Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/04-tmux-multiple-sessions.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RI0LQ4Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/04-tmux-multiple-sessions.gif" alt="tmux multiple sessions" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While the force that enforces organization is eliminated, it still feels more natural to &lt;strong&gt;switch between views of applications, rather than tasks. So, only the applications you want to see together will be on the screen&lt;/strong&gt;, even if multiple applications are associated with the task you're working on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single session for each task
&lt;/h3&gt;

&lt;p&gt;The solution that appeals to me the most is to have everything within a single session, regardless of the task, and use window naming for grouping. This provides a more flexible structure compared to keeping windows in thematic silos. You can easily navigate between tasks without worrying about which session to place a temporary window in for a quick task. The split feature is still available to view two windows side by side if needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u6hBRlvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/05-tmux-single-session.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u6hBRlvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/05-tmux-single-session.png" alt="tmux single session" width="800" height="483"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Desktop environment workflow
&lt;/h2&gt;

&lt;p&gt;The solutions provided by Tmux are highly efficient, and many individuals who primarily use terminal applications are satisfied with them and do not require anything more. However, the problem is that we often need to use not only terminal applications but also other types of applications. For example, certain documentation may only be viewable with a PDF reader, web browsers are graphical applications, and some people prefer using VSCode over Vim or Emacs.&lt;/p&gt;

&lt;p&gt;In a desktop environment, alongside terminal applications, you can open GUI programs, which are often essential requirements nowadays. One advantage of windows compared to Tmux is that instead of using splits, you can open two separate, independent windows that can be freely moved within the available space. These windows can overlap, allowing you to arrange and resize them freely. This provides more flexibility and fewer restrictions, but it can also lead to a potentially chaotic desktop where things become less transparent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qZZewO1G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/06-classical-desktop.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qZZewO1G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/06-classical-desktop.png" alt="classical desktop" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make your desktop more organized, you can maximize the windows to full size. However, if your intention is to view two windows side by side, whenever you switch to a third window, you would need to bring the side-by-side windows to the foreground again. This is not a convenient solution as it requires additional effort to maintain the desired window arrangement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ms8au-lm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/07-switch-overlaping-windows.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ms8au-lm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/07-switch-overlaping-windows.gif" alt="switch overlaping windows" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although the desktop environment can handle workspaces, many people do not use them because they may find them cumbersome to use. However, if you do move the windows you want to see side by side to a separate workspace, you need to find a solution to see the list of all open windows in one place; otherwise, you would have to mentally keep track of which window is in which workspace.&lt;/p&gt;

&lt;p&gt;Typically, we switch between windows based on a list of windows, whether through the desktop panel, a menu, or by pressing &lt;code&gt;Alt+Tab&lt;/code&gt;. The problem with this approach is that you have to search through the list and go through each item, which can be time-consuming and stressful, especially when there are many open windows.&lt;/p&gt;

&lt;p&gt;If a well-organized workflow can already be achieved in the terminal, what options do we have to make the desktop environment just as convenient?&lt;/p&gt;

&lt;h3&gt;
  
  
  Window list filter
&lt;/h3&gt;

&lt;p&gt;The most basic requirement that arises is to not have to go through the list of windows one by one, but to have a filterable list that allows you to easily switch between open applications. Rofi provides a solution for this, allowing you to &lt;strong&gt;access all open applications from one place and filter them&lt;/strong&gt;. With Rofi, you can quickly find the desired window by typing a few letters, even if there are 26 other windows alongside it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SizMG9Cd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/08-rofi-window-switcher.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SizMG9Cd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/08-rofi-window-switcher.gif" alt="rofi window switcher" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The advantage of this solution is that you can group your windows by moving them to different workspaces, yet still find them all in one central location.&lt;/p&gt;

&lt;h3&gt;
  
  
  Separate browser windows instead of tabs
&lt;/h3&gt;

&lt;p&gt;If you already have a filterable list of windows, there is no need to continue searching among the tabs within the browser. It is simpler to view each browser page in a separate window and search for the tab name in the window list. The creators of Chrome also recognized that it is easier to search for tabs textually (&lt;a href="https://blog.google/products/chrome/search-your-tabs-bookmarks-and-history-in-the-chrome-address-bar/"&gt;https://blog.google/products/chrome/search-your-tabs-bookmarks-and-history-in-the-chrome-address-bar/&lt;/a&gt;), but with a general window filtering feature, you can use this functionality with any browser. If you only want to search among the browser tabs and exclude other applications, start by filtering based on a partial match of the browser's name (e.g., for Chrome, use &lt;code&gt;chr&lt;/code&gt;) and vica-versa (to exclude browser filter by &lt;code&gt;-chr&lt;/code&gt;). You don't need to worry about resource consumption because having two separate browser windows requires only slightly more resources than having two tabs.&lt;/p&gt;

&lt;p&gt;To open a link in a new tab, you need to click on it with the middle mouse button. If you want to open it in a new window, use the &lt;code&gt;Ctrl+Shift+LeftClick&lt;/code&gt; combination. To open a new, empty tab, you can use the &lt;code&gt;Ctrl+T&lt;/code&gt; combination, and for opening a new window, you can use &lt;code&gt;Ctrl+N&lt;/code&gt;. There are browser extensions available that automatically open every link in a new window, but they don't always work with different Chromium-based browsers (Vivaldi, Brave, Edge, etc.), so I do not recommend them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Windows with names
&lt;/h3&gt;

&lt;p&gt;To make the windows truly searchable, you need to know their names or at least some keyword that can narrow down the list of windows enough for you to easily identify them. Most applications use the title of the document or content within them as the window name, but this is not always straightforward. For example, if you are comparing a live version of a website with a version under development, both browser tabs may have the same title because the real difference lies in the URL. To make this information accessible, you can use a Userscript that appends the current domain name to the webpage title, so it will appear in the list of windows as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D84YPKut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/09-domain-in-browser-title.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D84YPKut--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/09-domain-in-browser-title.png" alt="domain in browser title" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A similar problem exists with terminal applications where, even though the shell sets the title of the terminal window to include the name of the running application and the current path, it's not always sufficient for identification. To ensure that each opened terminal always has a distinctive title, you can create a shortcut that prompts you to provide a title before opening the terminal. This way, you can set a meaningful title that helps you easily identify the terminal window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8XxZXwqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/10-named-terminal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8XxZXwqd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/10-named-terminal.png" alt="named terminal" width="761" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Switch or launch project
&lt;/h3&gt;

&lt;p&gt;If you already have a searchable window list that allows you to search among the opened windows, it would be great if you could launch the necessary application for your task if it's not already open. We can use &lt;code&gt;rofi -show drun -show-icons&lt;/code&gt; as an app launcher. Even better, it would be ideal if it could open the entire project you want to work on instead of just the application. Luckily, Rofi is highly versatile and capable of doing this: if the entered text is not found in the list of opened windows, you can switch to the next Rofi mode, which contains projects and SSH hosts, and open them in the appropriate way.&lt;/p&gt;

&lt;p&gt;This is one possible way to expand the functionality of Rofi and customize the management of opened windows and projects. The exact implementation will depend on the system you are using and how Rofi is configured on your system. The Rofi documentation and configuration files will help you customize the settings and extend the functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lEaFwBsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/11-swicth-window-or-launch-project.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lEaFwBsN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/11-swicth-window-or-launch-project.gif" alt="switch window or launch project" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to opening the project, it performs the necessary basic steps for your work (such as executing the &lt;code&gt;git pull&lt;/code&gt; command, displaying the output of &lt;code&gt;git status&lt;/code&gt;, etc.). Furthermore, since the project can be easily reopened, there's no need to keep it open if you no longer need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arrange windows, group windows to views
&lt;/h3&gt;

&lt;p&gt;In addition to window switching, it would be great to manage the layout of windows, allowing you to easily move two windows to another workspace and display them side by side. &lt;strong&gt;Dynamic tiling window managers implement window layouts similar to Tmux for GUI applications&lt;/strong&gt;, providing a similar workflow where windows are automatically resized when new applications are opened, similar to how Tmux behaves. However, &lt;strong&gt;the real advantage of tiling window managers lies in their scriptability, allowing you to customize their behavior to suit your specific needs&lt;/strong&gt;. For example, you can easily resize the window headers to make them readable in a screencast.&lt;/p&gt;

&lt;p&gt;To overcome the drawback of continuously decreasing window size in dynamic tiling, while still taking advantage of automatic window arrangement, you can write a script for the window list that groups windows with a button press. This approach allows you to achieve the desired window grouping and layout while utilizing the benefits of a dynamic tiling window manager. By scripting and customizing the behavior, you can tailor the window manager to your specific requirements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KMqQE15W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/12-group-windows-by-tiling-wm.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KMqQE15W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/raw/main/screencast/12-group-windows-by-tiling-wm.gif" alt="group windows by tiling wm" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(for some reasons, this GIF is not works in Dev.to, so here's a link: &lt;a href="https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/blob/main/screencast/12-group-windows-by-tiling-wm.gif"&gt;https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/blob/main/screencast/12-group-windows-by-tiling-wm.gif&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Look at the desktop names in window list!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;By default, windows are maximized on the &lt;code&gt;main&lt;/code&gt; workspace.&lt;/li&gt;
&lt;li&gt;Window grouping is done exclusively using the window list (no additional hotkey is required).&lt;/li&gt;
&lt;li&gt;The current window (file browser) is the "source" window.&lt;/li&gt;
&lt;li&gt;If you hover over a window in the list (image viewer) and press &lt;code&gt;Shift+Enter&lt;/code&gt; instead of &lt;code&gt;Enter&lt;/code&gt; for window switching, both the current window and the selected window are moved to a newly created workspace (&lt;code&gt;#1&lt;/code&gt;) for simultaneous viewing (dynamic tiling).&lt;/li&gt;
&lt;li&gt;If you want to add an additional window (web browser) to the group, find any member of the group in the list and press &lt;code&gt;Shift+Enter&lt;/code&gt; on it (thus, &lt;code&gt;Shift+Enter&lt;/code&gt; means "grouping").&lt;/li&gt;
&lt;li&gt;To remove a window from the group (image viewer), move it back to the &lt;code&gt;main&lt;/code&gt; group, where it will be maximized according to the workspace settings.&lt;/li&gt;
&lt;li&gt;When a group has fewer than 2 members (because you moved the web browser to the &lt;code&gt;main&lt;/code&gt; group), the group is disbanded, and the last remaining member (file browser) is automatically moved to the &lt;code&gt;main&lt;/code&gt; group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please note that these instructions assume a specific workflow and usage of window management. The actual implementation may require configuring your window manager or using a script to achieve the desired behavior.&lt;/p&gt;

&lt;p&gt;The workspaces will actually be optional views rather than continuous parts of your workflow, but due to their ease of use, you will likely use them frequently. For example, you can easily move one element of a three-member group to a new group with a fourth application, and when you're done with your task, you can move it back to its original position in the three-member group.&lt;/p&gt;

&lt;p&gt;You probably wouldn't want to replace your desktop environment just to have organized windows, but fortunately, it's not necessary because &lt;strong&gt;tiling window managers can usually be easily integrated into existing desktop environments&lt;/strong&gt;. This means that your system remains the same, but the appearance of window borders and the behavior of windows are determined by the tiling window manager. For example, in Linux Mint XFCE Edition, there is a setting that allows you to easily switch between window managers with a single click (Desktop Settings, but be sure to disable XFWM4 automatic restart in the Session settings first).&lt;/p&gt;

&lt;p&gt;During the writing of the article, I made an effort to ensure that my implementations could be used in any desktop environment and tried to avoid using tiling window managers. However, I simply couldn't find a way to achieve the desired functionality using tools like &lt;code&gt;wmctrl&lt;/code&gt;, &lt;code&gt;xdotool&lt;/code&gt;, and similar window manipulation applications. Tiling window managers have events, hooks and make it easy to create and modify workspaces, but &lt;strong&gt;simpler command-line applications cannot handle windows at such an abstract level&lt;/strong&gt; because it's simply not their purpose to provide a comprehensive solution for every task. If I insisted on using these applications, I would have to implement the hook mechanism and other abstract solutions that tiling window managers already provide, which would complicate the goal of simplification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scripts, implementation
&lt;/h2&gt;

&lt;p&gt;You can find the implementation of the mentioned features &lt;strong&gt;and the latest ideas&lt;/strong&gt; in the following repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers"&gt;https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please star if you like it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Continue the list
&lt;/h2&gt;

&lt;p&gt;These ideas can be applied in other areas as well. For example, if you consider Vim tabs as alternatives to workspaces and the buffer list as the equivalent of Rofi, you can create a similar workflow in Vim.&lt;/p&gt;

&lt;p&gt;I hope this description has given you some ideas on how to make your everyday work more efficient and enjoyable. Please continue the list with your own ideas and share tips with us! You can reply on &lt;a href="https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/discussions"&gt;https://github.com/bimlas/howto-distraction-free-desktop-workspace-for-developers/discussions&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(PS.: The article was translated by AI)&lt;/p&gt;

</description>
      <category>rofi</category>
      <category>productivity</category>
      <category>tmux</category>
      <category>workflow</category>
    </item>
    <item>
      <title>What is the purpose of Madza's poll?</title>
      <dc:creator>bimlas</dc:creator>
      <pubDate>Thu, 24 Sep 2020 22:06:40 +0000</pubDate>
      <link>https://forem.com/bimlas/what-is-the-purpose-of-mazda-s-poll-25f8</link>
      <guid>https://forem.com/bimlas/what-is-the-purpose-of-mazda-s-poll-25f8</guid>
      <description>&lt;p&gt;Sorry &lt;a class="comment-mentioned-user" href="https://dev.to/madza"&gt;@madza&lt;/a&gt;
, but I couldn’t miss this opportunity. :D I hope you are not angry. :)&lt;/p&gt;

&lt;p&gt;You ask a lot of questions about user habits and wonder what your goal is: do you do some research, or do you look at which topic DEVs like the most?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>fun</category>
    </item>
    <item>
      <title>Intro to Zettelkasten, second brain, etc. and TiddlyWiki</title>
      <dc:creator>bimlas</dc:creator>
      <pubDate>Mon, 21 Sep 2020 12:45:12 +0000</pubDate>
      <link>https://forem.com/bimlas/intro-to-zettelkasten-second-brain-etc-and-tiddlywiki-180i</link>
      <guid>https://forem.com/bimlas/intro-to-zettelkasten-second-brain-etc-and-tiddlywiki-180i</guid>
      <description>&lt;p&gt;Zettelkasten, Evergreen Notes, digital garden, second brain, ...&lt;/p&gt;

&lt;p&gt;I've been busy with these productivity topics about learning and note-taking lately and as I look at, this topic is becoming more and more interesting for many. Although I exemplify possible solutions with &lt;a href="https://tiddlywiki.com/"&gt;TiddlyWiki&lt;/a&gt;, keep in mind that &lt;a href="https://zettelkasten.de/posts/zettelkasten-improves-thinking-writing/"&gt;Zettelkasten&lt;/a&gt; was originally implemented on paper, so the topic of this post is an implementation that can be implemented anywhere, regardless of software.&lt;/p&gt;

&lt;p&gt;The purposes of Zettelkasten and similar knowledgebases are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easily recall your long-forgotten thoughts&lt;/li&gt;
&lt;li&gt;Clarify your knowledge of a particular topic&lt;/li&gt;
&lt;li&gt;To notice contradictions and shortcomings during the dialogue with the Notes&lt;/li&gt;
&lt;li&gt;Create new ideas from your existing knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Related topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://groups.google.com/g/tiddlywiki/c/Re11x96t-qI"&gt;https://groups.google.com/g/tiddlywiki/c/Re11x96t-qI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://groups.google.com/g/tiddlywiki/c/pBVtEa5CVYI"&gt;https://groups.google.com/g/tiddlywiki/c/pBVtEa5CVYI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I think &lt;strong&gt;&lt;a href="https://tiddlywiki.com/empty.html"&gt;TiddlyWiki empty edition&lt;/a&gt; is exactly the software you need for a Zettelkasten-type note collection&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displays "physically" separate notes that we can handle as if they were made of paper: you can leave all of them on "the desk" that you want to manage right now and you can put the rest in "the drawer"&lt;/li&gt;
&lt;li&gt;It basically works by not support for renaming tiddlers, which fits the Zettelkasten mindset (permanent titles)&lt;/li&gt;
&lt;li&gt;Backlinks can be easily displayed in the tiddler info bar&lt;/li&gt;
&lt;li&gt;It does not include table of contents, which may be due to link-based navigation&lt;/li&gt;
&lt;li&gt;Tags are basically only used for grouping (if ToC-type usage is ignored)&lt;/li&gt;
&lt;li&gt;The selected text can be extracted into a separate tiddler and replaced with a link (refactoring of notes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The main principles of the "second brain" kind of knowledgebase&lt;/strong&gt; in my opinion are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write notes about everything to make sure that thoughts and experiences are not lost, in addition, the wording helps to understand the topic&lt;/li&gt;
&lt;li&gt;Add a unique ID to your notes so you can clearly identify them even with a text search (so you get a list of backlinks)&lt;/li&gt;
&lt;li&gt;There should be only one well-defined idea on a note&lt;/li&gt;
&lt;li&gt;Because of link-based navigation, use links instead of text search to look for a topic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Wording helps with understanding&lt;/strong&gt;, thus instead of copying someone's writing, opinion, solution, describe it in your own words, because only then will you become aware of what you actually understood while you have to articulate, "have to say back".&lt;/p&gt;

&lt;p&gt;If you just copy, you gather the information without actually interpreting it, but while writing the text, you need to interpret your thoughts so that you can put them on paper in a meaningful way. This will shed light on the dark spots, points you don't really understand yet, and it will encourage you to gather more information on that topic (even during a dialogue with your own notes), so it will lead to real understanding. It will become your habit that instead of scanning and reviewing the text quickly, you will actually start reading the text, interpreting what is described, so your reading efficiency will also improve.&lt;/p&gt;

&lt;p&gt;It is necessary to use IDs in paper form to identify the notes because you have no other option. In digital form, &lt;strong&gt;each of your notes actually has a unique ID&lt;/strong&gt; (path, in-database ID, URL), but if you use this, you will depend on the implementation (vendor lock-in): if you want to migrate to another system where links are marked differently (e.g. the title identifies the note instead of a generated ID), it will be difficult to migrate (if it can be solved at all). Therefore, it is worth using a notation system that works in all circumstances (even with a simple text search), e.g. the form "2020-09-19_20-24". There is no line break in the unique ID (which would make it difficult to find with a text search), it does not depend on character encoding (so it even works in filenames, it does not need to be modified in URLs because it does not contain accented letters), so it is a universal solution.&lt;/p&gt;

&lt;p&gt;However, since this name is not verbose, it is a good idea to display the title of the note along with its ID. It is a software-dependent solution, but the best solution is, for example, if the note can be identified by an ID, but we also display the title in the text in the search results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A note should be on a signle topi&lt;/strong&gt;c and be as short as possible; if it's already too long, it probably includes more topics.&lt;/p&gt;

&lt;p&gt;When you put headlines in a note, it is a clear indication that the note is about multiple topics (e.g., a Mammal note has a Dog and Cat headline). Put these paragraphs in a separate note and just place a link in their original location (note refactoring) so that if you use text search, you're sure to find what you're looking for - if the text you're looking for were under a headline within a note, you wouldn't find it in the search results (e.g. you would search for the word "dobberman" and only Mammals would appear in the results, you probably wouldn't consider it, but you would already notice the title Dog).&lt;/p&gt;

&lt;p&gt;Creating &lt;strong&gt;connection between notes requires nothing but links and backlinks&lt;/strong&gt; (see &lt;a href="https://groups.google.com/g/tiddlywiki/c/Re11x96t-qI/m/GYuMKHx0AQAJ"&gt;details&lt;/a&gt;) because they can be used to implement tags (&lt;a href="https://groups.google.com/g/tiddlywiki/c/Re11x96t-qI/m/9f9LL5GRGAAJ"&gt;details&lt;/a&gt;), fields (&lt;a href="https://groups.google.com/g/tiddlywiki/c/Re11x96t-qI/m/WoqDEuJzGQAJ"&gt;details&lt;/a&gt;), and table of contents (&lt;a href="https://zettelkasten.de/posts/three-layers-structure-zettelkasten/#middle-layer-structure-notes"&gt;details&lt;/a&gt;). It follows that when using a wiki-like annotation method, we can search for a topic by following links instead of text search, because we can find more accurate results that we think are as opposed to having to search a list of notes that contain those words (&lt;strong&gt;must to read &lt;a href="https://tefkos.comminfo.rutgers.edu/Courses/e530/Readings/Beal%202008%20full%20text%20searching.pdf"&gt;details&lt;/a&gt; about the weakness of full text search&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backlinks are only useful if they show really relevant content&lt;/strong&gt;. For example, on Wikipedia, the list of &lt;a href="https://en.wikipedia.org/wiki/Special:WhatLinksHere/Wiki"&gt;backlinks&lt;/a&gt; to &lt;a href="https://en.wikipedia.org/wiki/Wiki"&gt;Wiki&lt;/a&gt; page contains a bunch of unrelated information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Aeronautics page mentions "Wiki" in the &lt;a href="https://en.wikipedia.org/wiki/Aeronautics#Research"&gt;footnote&lt;/a&gt; in connection with a link&lt;/li&gt;
&lt;li&gt;Batman also mentions it in the &lt;a href="https://en.wikipedia.org/wiki/Batman#External_links"&gt;footnote&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I could list, but this is the case in most places&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I think we need to choose when to refer to a word and when not. We need to stick to the Zettelkasten principles to first describe what we want, but don't place links in it until we're completely done with the note: we visit the related notes and only link to the really relevant places. For example, if I write a note about squirrels, it would not be worthwhile to link from that note to the note about mammals itself, but only to the note that collects rodents. While this is more time consuming than linking to key words on an ad-hoc basis, a list of backlinks will be really useful if you don't have to sort between them because they are all really closely related to that particular note.&lt;/p&gt;

&lt;p&gt;One of &lt;strong&gt;the advantages of this kind of note-taking&lt;/strong&gt;, for example, is that it took me about 15 minutes to write it all down. In fact, all I had to do was translate my previously written and thought-out notes into English and make small changes to it.&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://groups.google.com/g/tiddlywiki/c/2yRiVsbAv9g/m/vKBIC5CjBQAJ"&gt;https://groups.google.com/g/tiddlywiki/c/2yRiVsbAv9g/m/vKBIC5CjBQAJ&lt;/a&gt; for the original thread and &lt;a href="https://zettelkasten.de/posts/overview/"&gt;https://zettelkasten.de/posts/overview/&lt;/a&gt; for more information about Zettelkasten.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>learning</category>
      <category>writing</category>
      <category>notetaking</category>
    </item>
    <item>
      <title>Fosh: Execute shell commands in multiple directories grouped by tags</title>
      <dc:creator>bimlas</dc:creator>
      <pubDate>Tue, 16 Apr 2019 19:35:40 +0000</pubDate>
      <link>https://forem.com/bimlas/fosh-execute-shell-commands-in-multiple-directories-grouped-by-tags-4jbp</link>
      <guid>https://forem.com/bimlas/fosh-execute-shell-commands-in-multiple-directories-grouped-by-tags-4jbp</guid>
      <description>&lt;p&gt;For developers who &lt;strong&gt;running the same command in different directories&lt;/strong&gt; repeatedly, Fosh is a productivity tool that saves time by &lt;strong&gt;executing the command without having to change the directory&lt;/strong&gt;. Unlike other similar tools, Fosh does not bound to a certain software (like Git for example), it can &lt;strong&gt;execute any shell command&lt;/strong&gt;. &lt;strong&gt;It works at least on Windows and Linux&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you prefer Bash, have a look at &lt;a href="https://github.com/bimlas/bash-mosh/"&gt;https://github.com/bimlas/bash-mosh/&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manage multiple Git repositors together&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Checkout the same branch for project and its submodules&lt;/li&gt;
&lt;li&gt;Commit with the same message: walk through the repos without interruption and copy / paste the same commit message&lt;/li&gt;
&lt;li&gt;Prevent early push: you do not have to remember which repositories have modified, just look at them at the end of the day to see where you need to push&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Control multiple vagrant machines at the same time&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The essence of the code in a nutshell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;for(dir in selectedDirectories) {
  cd(dir);
  shellCommand();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This also means the name: &lt;code&gt;for ... shell ...&lt;/code&gt; -&amp;gt; &lt;code&gt;fosh&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install -g fosh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Get the source code, report bugs, open pull requests, or just star because you didn't know that you need it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://gitlab.com/bimlas/node-fosh"&gt;https://gitlab.com/bimlas/node-fosh&lt;/a&gt; (official repository)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/bimlas/node-fosh"&gt;https://github.com/bimlas/node-fosh&lt;/a&gt; (mirror, star if you like it)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Tag: Assign tags to directories
&lt;/h3&gt;

&lt;p&gt;The tags can be specified as command-line parameters prefixed with &lt;code&gt;@&lt;/code&gt;, directories should be listed in the prompt, or piped to stdin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ fosh tag "@pictures" "@personal"
fosh: tag &amp;gt; /home/myself/photos
fosh: tag &amp;gt; /home/mom/my_little_family

$ echo -e "/home/myself/photos \n /home/mom/my_little_family" | fosh tag "@pictures" "@personal"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Find Git repositories
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Tagging Git repositories&lt;/strong&gt; under the current directory (&lt;code&gt;./&lt;/code&gt;) with&lt;br&gt;
"git-repos" tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Linux / Windows Git Bash / ...
$ find "./" -name ".git" -printf "%h\n" | fosh tag "@git-repos"

# Windows PowerShell
$ Get-ChildItem './' -Recurse -Directory -Hidden -Filter '.git' | ForEach-Object { Split-Path $_.FullName -Parent } | fosh tag '@git-repos'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;On Windows you can use Everything search engine's &lt;code&gt;es&lt;/code&gt; &lt;a href="https://www.voidtools.com/support/everything/command_line_interface/"&gt;command-line interface&lt;/a&gt; to find Git repositories rapidly&lt;/strong&gt;. Use the following command in PowerShell for this (omit the path of the root directory (&lt;code&gt;./src&lt;/code&gt;) to find everywhere):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ es -regex '^\.git$' './src' | Split-Path -Parent | fosh tag '@git-repos'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  List: Prints the path of the tag list file
&lt;/h3&gt;

&lt;p&gt;You can edit it in a texteditor (Notepad, Vim, etc.).&lt;/p&gt;

&lt;h3&gt;
  
  
  Run: Execute commands in multiple directories
&lt;/h3&gt;

&lt;p&gt;Arguments can be tags and paths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ fosh run "@git-repos" "../wip-project"
fosh: run &amp;gt; git status --short --branch

__ @1 awesome-project (/home/me/src/) ________________________________________
## master
AM README.md
 M package.json

__ @2 git-test (/home/me/src/) _______________________________________________
## master...origin/master
 M README.adoc
 M encoding/cp1250-encoding-dos-eol.txt
 M encoding/dos-eol.txt

__ @3 wip-project (/home/me/helping-tom/) ____________________________________
## master...origin/master
 M example-code.js

==============================================================================
fosh: run &amp;gt; another command and so on ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Filtering the directory list
&lt;/h4&gt;

&lt;p&gt;If you want to &lt;strong&gt;execute a command only in certain directories&lt;/strong&gt;, you can select them by their index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fosh: run &amp;gt; @1,3 git status --short --branch

__ @1 awesome-project (/home/me/src/) ________________________________________
## master
AM README.md
 M package.json

__ @3 wip-project (/home/me/helping-tom/) ____________________________________
## master...origin/master
 M example-code.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Execute in the most recently used directories
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;This is useful if the output is long&lt;/strong&gt; and you want to execute additional commands on certain directories. In this case, open a new terminal window (so you can look back at results in the current terminal) and run the program without arguments: the directory list is always stored when tag or directory arguments are given, but if you run it without arguments, it executes the commands on the last specified directories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ fosh run "@git-repos" "../wip-project"
fosh: run &amp;gt; git status --short --branch

__ @1 awesome-project (/home/me/src/) ________________________________________
## master
AM README.md
...

# Another terminal

$ fosh run
fosh: WARNING: Using most recently used directory list
fosh: run &amp;gt; @3 git diff

__ @3 wip-project (/home/me/helping-tom/) ____________________________________
 example-code.js | 1 +
 1 file changed, 1 insertion(+)

diff --git a/example-code.js b/example-code.js
index 12b5e40..733220f 100644
--- a/example-code.js
+++ b/example-code.js
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>showdev</category>
      <category>productivity</category>
      <category>terminal</category>
      <category>git</category>
    </item>
  </channel>
</rss>
