Khalid's Shell
9 subscribers
3 photos
11 links
Download Telegram
Welcome to Khalid's Shell. This is the channel for my blog: blog.khalidrafi.tech/en

Khalid's Shell is the playground for my technical expertise. I share my knowledge with the world as I learn and try different stuffs. Explore my gems and pearls as I dive into the ocean of technology.

My topics of interest are: Linux, Open Source, Emacs, Privacy, Cybersecurity etc.

Hope you have a great time here!
👍1
So far, the only terminal where I've found proper Bangla language support is Emacs' terminal. My switch from Neovim to Emacs was primarily for Bangla support. But once I dove in, I realized Emacs is a powerhouse. I wish I used it from the beginning instead of Neovim. Besides offering perfect Vim emulation, it's packed with incredible features.

For instance, I can now use Vim-style keybindings right here in Telegram – something that wouldn't be possible without Emacs. As a result, even die-hard Vim users might be forced to run Vim inside Emacs for good unicode support or to get Vim editing style everywhere! I'd like to invite you all, especially Vim/Neovim users, to try Emacs. It's a very powerful editor that you can mold to your workflow.

And regarding the editor wars? I have to side with the wisdom of Spacemacs:

The best editor is neither Emacs nor Vim, it's Emacs and Vim!
🚀 Take your terminal experience to the next level!

With fish shell, you'll get:
• Live suggestions as you type
• Freedom from typing the same command repeatedly
• Automatic identification of incorrect commands
• An easy configuration interface

Read: https://blog.khalidrafi.me/en/fish-smart-friendly-shell?ref=telegram
Bitlbee brings IM platforms such as WhatsApp, Telegram etc. to IRC client. It works as a gateway between IRC and other chat platforms. If you prefer IRC clients and don't want to install extra apps (or if you, like me, want to chat within Emacs), then this might be useful to you. Bitlbee brings all your chats into one interface. You can also use Pidgin to chat on multiple platforms with one client.
My situation after using Emacs for a few months. Don't use Emacs!
Khalid's Shell pinned «Welcome to Khalid's Shell. This is the channel for my blog: blog.khalidrafi.tech/en Khalid's Shell is the playground for my technical expertise. I share my knowledge with the world as I learn and try different stuffs. Explore my gems and pearls as I dive…»
Two very useful motion keys in the Vim editing style are f and t.

f - jumps to a specific character to the right (cursor lands on the character)

t - jumps till (just before) a character to the right

For Example:
- To delete everything up to quotation mark: dt"
- To jump to next comma: f,

Reverse Motion:
F - jumps to character to the left
T - jumps till character to the left

These motion keys are very helpful. They provide precise navigation and editing within lines. You can easily delete/copy something till a char, or jump to it.
The domain of Khalid's Shell has been changed. From now on, you can read Khalid's Shell from the link blog.khalidrafi.tech/en. Please update your bookmarks. Some surprises are coming soon!
Forwarded from Infinite
Deployed my Git website with Radicle Explorer. It's just so better than Gitea! Please share your feedback. How is it?

git.khalidrafi.tech
I have forked Emacs EAT and merged some PRs from the upstream:

- Fish integration #133
- * eat.el (eat-1): Make returned buffer current #193
- feat: Add buffer renaming based on terminal title #246

You guys can use the fork from here: git.khalidrafi.tech/emacs-eat

The recommended way to fork it is using Radicle CLI. But if you don't want to install it, the Git clone URL is also available in the clone button.
In JavaScript, we often use if...else if...else chain to handle conditions. But, there is a cleaner way to write this code, objects. For example, look at the following code:

for (tab in issueElems) {
if (tab === "open") {
openIssues.innerHTML = "";
openCount.className = "loading loading-spinner loading-xs text-info";
showSpinner(searchSpinner, searchSpinnerText, openIssuesSpinner);
}
else if (tab === "closed") {
closedIssues.innerHTML = "";
closedCount.className = "loading loading-spinner loading-xs text-info";
showSpinner(searchSpinner, searchSpinnerText, closedIssuesSpinner);
}
else {
allIssues.innerHTML = "";
allCount.className = "loading loading-spinner loading-xs text-info";
showSpinner(searchSpinner, searchSpinnerText, allIssuesSpinner);
}
}


Now, if we define an object like the following beforehand:

let issueElems = {
all: {
count: allIssuesCount,
issues: allIssues,
spinner: allIssuesSpinner,
},

open: {
count: openIssuesCount,
issues: openIssues,
spinner: openIssuesSpinner,
tab: openTab,
},

closed: {
count: closedIssuesCount,
issues: closedIssues,
spinner: closedIssuesSpinner,
tab: closedTab,
},
};


The code becomes as simple as this:

for (tab in issueElems) {
let c = issueElems[tab];
c.issues.innerHTML = "";
c.count.className = "loading loading-spinner loading-xs text-info";
showSpinner(searchSpinner, searchSpinnerText, c.spinner);
}


There is also switch...case, but it works in a very absurd way. If you don't add break to case clauses, it keeps going to the next case clause. It starts with the first matching case clause and continues until the break statement is encountered. That's why objects are the best way to handle this matter. What do you use? Share your ideas!
When we create HTML with JavaScript, the code can easily get messed up. If you have only been using appendChild() and document.createElement() for this, I pity you! And, I pity the readers of your code even more!! It must be a repetitive mess of the aforementioned methods. Today, I'll tell you some functions which will make this task more convenient and the code cleaner:

1. Object.assign()

With the Object.assign() method, you can create an Element along with its relevant properties, such as textContent, className etc., in one statement. For example:

const docBadge = Object.assign(document.createElement("div"), {
textContent: "Documentation",
className: "badge badge-info text-white",
});


Without Object.assign(), you would have written this in an unorganized way. Assignments to relevant properties would be separate, and even worse, you might place them far from the initial declaration. This would disturb readers of your code.

2. Element.append()

With the append() method of an Element, you can append multiple elements, or even text nodes, after the last child of the Element. Unlike appendChild(), this also accepts strings which are inserted as Text nodes. Thus it saves you from creating a Text node each time you wanna insert some text. Let's take a look at the following comparison.

Suppose, you have a following code written with the ol' school appendChild():

issueBody.appendChild(topBadges);
issueBody.appendChild(issueTitle);
issueBody.appendChild(issueDescription);
issueBody.appendChild(issueLabels);
issueBody.appendChild(document.createTextNode("\n"));
issueBody.appendChild(issueDivider);
issueBody.appendChild(document.createTextNode("\n"));
issueBody.appendChild(issueData);


Now, just take a look at the following code rewritten using append():

issueBody.append(
topBadges,
issueTitle,
issueDescription,
issueLabels,
"\n",
issueDivider,
"\n",
issueData,
);


Easier and cleaner!

There's also prepend() which does the opposite. It will add stuffs before the first child of the Element.

3. Element.before() and Element.after():

The before() method of an Element inserts a set of elements or text nodes just before the given Element. And, after() does the obvious opposite, i.e., inserts after the given element.

issueBody.after(issueAuthor, issueDate, issueModal);
issueBody.before(issueStatus, issueTitle);


4. Element.replaceWith()

The replaceWith() method of an Element replaces the given Element with a set of elements or Text nodes.

for (const issue of issues) {
if (issue.status === "closed"){
issueOpen.replaceWith(issueClosed);
}
}


What functions or methods do you use the most when creating or modifying DOM? Share in comments!
The Vite server always makes us open the browser manually after starting. If the browser opens automatically when the server starts, it makes our work a bit more convenient. To use this feature of Vite, enable the server.open option in your Vite config file (vite.config.js or vite.config.ts) like this:

export default defineConfig({
plugins: [react()],
server: {
open: true,
}
})


Additionally, if you wish, you can also specify the browser and its arguments. For that, you need to set the BROWSER and BROWSER_ARGS environment variables in your project's .env file. For example, if you want to open the browser using the command chromium --password-store=basic, write the following in the .env file:

BROWSER=chromium
BROWSER_ARGS=--password-store=basic


Don't forget to let me know in the comments if you liked the tutorial. Thank you.
Khalid's Shell
The Vite server always makes us open the browser manually after starting. If the browser opens automatically when the server starts, it makes our work a bit more convenient. To use this feature of Vite, enable the server.open option in your Vite config file…
If you don't want the browser to open every time, you can also use the vite --open command. If the vite command is set as the dev script in the package.json file (which is set by default when you create a Vite project using npm create vite@latest), then you can also use the npm run dev -- --open command.
Please open Telegram to view this post
VIEW IN TELEGRAM
Which LLM router do you use? I'm using GoModel, because it's fast.