• My experience switching to buffers

    About a year ago I stumbled upon an article explaining the difference between Vim tabs and buffers. The author emphasized that tabs are merely window layouts, and therefore one-file-per-tab idea I was used to at the moment just wasn’t proper. Instead, author suggested the use of buffer commands to switch between multiple files. I decided to give it a shot, and here are some ideas I would like to share after switching to the use of buffers.

    Buffers are open files (they also may not be associated with any files), but they’re not necessarily visible at any given moment. In Vim, windows are not linked to any particular buffer, so you can easily cycle through buffers from within any window.

    First and foremost, you probably want to add set hidden to your .vimrc. This option lets you switch between buffers without having to save files.

    At it’s basics, you only need few commands for operating buffers:

    • Use :ls to list all buffers for this session.
    • To move between next and previous buffers use :bn and :bp respectively.
    • Use :b partial_buffer_name for navigating to the buffer of your choice. Buffer name auto-complete is supported.
    • You can also use :bN, where N is a buffer number to jump to a specific buffer.
    • Get in a habit of closing buffers you will not use with :bd.

    A list of open buffers in Vim.

    The hardest thing about stopping to use tabs and switching to buffers instead is not having the visual aid: I was used to having a list of files always available at a glance, at the top of my screen. To check what files I’m working on now - I have to hit four keys: :ls (fourth being “Enter”).

    Not surprisingly, this taught me to be more mindful about my editing experience. I usually have a clear structure of the files I’m working on in my head. And if the list is getting to long to easily remember, then I’m probably doing something wrong: time to take a break and reset my Vim session.

    The experience overall reminded me of my recent switch to blank keyboard key caps: with no inscriptions to aid you, I first felt a bit at loss, especially with they keys I couldn’t find without looking: like function keys or special symbols. But after some time with the blank key caps, I improved my typing skill, and know where even the most obscure characters hide. The switch helped me to improve my typing experience overall.

    With Vim, it’s a similar story. After getting past the initial confusion, I achieved high level of awareness about my editing sessions. It didn’t make the editing process any faster, but instead much more satisfying.

    But you already new that, since Vim isn’t really about speed.

    UPDATE: Made a few corrections and added a :b partial_buffer_name command thanks to /u/___violet___’s Reddit comment.

  • Impact-driven development

    It is my fifth year working as a professional software engineer, and I think it’s a good time for me to share a few tips, dos, and don’ts I learned throughout past four years. This is the first article in a series of three, and it focuses on development process.

    Moving towards becoming a senior engineer, I noticed paying more attention to the impact my work produces. These days I would much rather compile a number of small simple changes to “wow” the users, as opposed to building unnecessarily complex nice-to-haves. This sounds simple and straight-forward, and some reader might even say “That’s silly, everybody knows that”. However significant number of engineers I meet don’t concentrate on how much impact they produce.

    It’s easy to get caught up in a daily routine: you close an issue after issue, there’s a stable flow of requirements from the business meetings. It’s not always easy to know when to stop and think “Do I really need to do this?”.

    Get the priorities right

    Divide amount of impact task produces by amount of effort you’ll have to put into completing it. Arrange the tasks by this factor.

    More often then not you can drop items with low impact/effort ratio.

    Separate what is needed from what is asked

    Know who the stakeholders are for each task, feature, or a project you work on. Understand their underlying motives. Anyone can fall a victim of an XY problem, it is your responsibility as an engineer to make sure that stakeholders ask for what they actually need.

    Know when to say “No”

    In the very beginning of my career I gladly took every single task thrown at me. It soon became an issue: work that actually needs to get done is not getting done quickly enough. Knowing when to say “No” is an art that takes practice.

    Think about your work

    Beware of routines, repeating the same workflow time after time is damaging when it comes to building software. Stop each time before you proceed to the next step, and ask yourself if you’re performing the task in the best way possible. Be mindful about your work.

    Be a catalyst for change

    Be the first to promote the change. Did you notice a poor practice on a project? Begin a more efficient practice (if it’s appropriate based on your role in a team of course). Don’t go on telling people how wrong what they use is. Show everyone how the new way is better on practice, and your colleagues will adopt successful trend.

    Don’t fall a victim of deferring responsibility: be aware that when multiple people are involved, every member of a group relies on other people to get things done. Be the one to take on responsibility when it’s unclear who should.

  • Managing cd bookmarks with apparix

    A couple of months ago I discovered apparix: a set of commands which augment cd with bookmarks. It really is an amazing feeling when you zap between multiple directories far away just with a couple of keystrokes! Apparix provides three commands I use daily: to, bm, and apparix (program suggests aliasing last one to als). Here’s how I use it:

    $ pwd
    /Users/ruslan
    $ apparix
    --- portals
    --- expansions
    --- bookmarks
    j dotfiles     /Users/ruslan/.dotfiles
    j blog         /Users/ruslan/Projects/ruslanosipov.github.io
    $ to blog
    $ pwd
    /Users/ruslan/Projects/ruslanosipov.github.io
    $ cd source/_posts
    $ bm posts
    added: posts -> /Users/ruslan/Projects/ruslanosipov.github.io/source/_posts
    $ to dotfiles
    $ pwd
    /Users/ruslan/.dotfiles
    $ to posts
    $ pwd
    /Users/ruslan/Projects/ruslanosipov.github.io/source/_posts
    

    The example above is self explanatory: you can see how over the span of a year apparix saves hours of navigating directories you frequent.

    Installation

    If you don’t like reading manuals, installation might be a confusing. But in reality it’s straightforward, you just need to add some functions or aliases to your shell’s configuration file.

    Install apparix using your favorite package manager, and then pipe examples apparix offers into your shell’s rc file.

    apparix --shell-examples >> ~/.bashrc
    

    Open your .bashrc (or another corresponding configuration file), and pick the preferred way of using apparix: you’ll see functions for bash and aliases for csh given as examples. Pick whatever works for your shell, source your rc file, and you’re all set!

    Happy jumping!

  • Ranger - the CLI file manager

    Ranger is a lightweight but powerful file manager with Vi-like key bindings. It shines at exploring file trees, looking for specific files, and performing bulk operations on folders and files. Three column layout will be very similar to Mac OS X users: center column shows contents of the current directory, left column lists contents of a parent directory, and the right column contains preview for the selected file or folder.

    File preview screen in Ranger: parent directory in the left column, current directory in the center column, and selected file preview in the left column.

    Ranger supports movement with familiar to Vi users h, j, k, and l keys, has internal command line which is invoked with :, as well as many other features and key bindings similar to Vi. Another great selling point - Ranger can be extended with custom commands and key bindings. Utility is written in Python, therefore all the commands are nothing more than Python scripts.

    Marking files for deletion in Ranger.  Files highlighted in yellow will be deleted by executing `:delete` command.

    Installation

    Ranger is easy to install and can be found in most public repositories, just install ranger package using your favorite package manager. While you’re at it, you may want to install some external utilities to help Ranger properly display file previews (list is taken from ArchWiki page on Ranger):

    • atool for archives.
    • highlight for syntax highlighting. ![for image previews]]CII.(libcaca)())
    • lynx, w3m or elinks for HTML.
    • mediainfo or perl-image-exiftool for media file information.
    • poppler (pdftotext) for PDF.
    • transmission-cli for BitTorrent information.
    • w3m for image previews.

    After all the dependencies are installed, quickly start up ranger, exit it with q, and run ranger --copy-config=all to generate configuration files in ~/.config/ranger.

    Usage

    Here are a few of the key bindings and commands I found useful:

    • Use spacebar to select files one by one. By selecting multiple files, you can perform bulk operations on them. Use V to perform visual selection. Lowercase v reverses current selection. For instance, you can run :delete after selecting multiple files and folders.
    • As mentioned above, execute :delete to remove currently selected file (or files).
    • To fullscreen a preview window, hit i. Hit i again to return the preview window to it’s normal size.
    • Vi’s gg and G allow you to jump to the top and bottom of the file list respectively.
    • Hit zh to toggle hidden files display.
    • As in Vim, / searches for a file in a current buffer, while n and N let you navigate to the next and previous matches respectively.
    • Similarly, :filter allows you to only limit your view to the files matching a pattern. It’s also interactive - changes are applied as you type.

    If you’re an avid Vim user, you’ll find using Ranger surprisingly intuitive. Otherwise you might get confused and scared away, probably for a good reason. Ranger is designed to provide Vi-like feel for file browsing, and it does that job well.

  • Power of the command line

    Disclaimer: I am not advocating any specific tools or methodologies, but sharing a workflow I find to be efficient and pleasant.

    I am a huge fan of working with CLI applications. I use Vim for editing code, composing emails, and various kinds of writing. When I have to manipulate huge amounts of email, I use Mutt: it’s intuitive tagging and regular expression engine are extremely useful for the task. I employ ack, awk, grep, and sed - Linux utilities which allow for precise and fast text manipulation.

    However, I would not use CLI browsers like elinks or w3m, and the idea of reading every email in Mutt gives me the creeps. I love the visualization web browser offers, something text-based prompt is not able to provide. And it doesn’t have to.

    There are two components to most of the tasks performed on a computer: analyzing output and entering input. Certain tasks employ one component more than the other. In most modern applications it’s rare to have both solid control from the user perspective and a pleasant informative UI. With increased visual component, it’s more time consuming to make the application do what you need, especially if your needs are esoteric. With more editing power, visual display becomes less complex in order to make editing tasks easier.

    Where visual tools fall short

    What is the alternative? Using multiple programs with different levels of control to accomplish one task: to edit text. Each of the programs excels in it’s own field: word processing software allows for beautiful fonts and document presentation, IDE lets you access aggregated meta information about your application. But most of the IDEs and word processors lack the powerful tools needed to manipulate the foundation of what user is working with - plain text.

    Ode to plain text

    I spend a lot of time writing and editing plain text. Be it source code, emails, documentation, or even blog posts. These tasks take up significant amount of my day, and it is only logical to substitute some of the visual presentation capabilities for effectiveness.

    It is hard to mentally process data which is not explicitly and unambiguously visible: different levels of headings, hidden meta information. Unlike more obscuring formats, plain text is all there is - it has nothing to hide. If you don’t see it - it’s not there. If you do see it - you know exactly what it is.

    One of my favorite tips from “Pragmatic Programmer” goes:

    Use a single editor well

    So I learned one editor well, and now I use it for all my writing and editing needs. I don’t have to jump between IDE, browser, and office software. Most of the text I edit is manipulated with one editor. There is only one set of key bindings to know, one skill to master and hone. Fast, without any additional thought, using single text editor and all of it’s powerful features is imprinted in muscle memory. One less task to worry about.

    I write my documents in Markdown format, and later convert them to the desired output using pandoc: be it an HTML page, PDF, or a Microsoft Word document. I use Vim, so I can rearrange paragraphs or manipulate lines within a couple of keystrokes. Since I spend so much time editing text, I also touch type, which makes me even more effective at the given task.

    Harness the power of the command line

    When it comes to bulk manipulating files or working with version control - there is no better candidate then command line applications. There’s no need to go through a number of obscure menus, ticking and unticking checkboxes, and hoping that your desired result can be achieved with a program’s GUI.

    Let’s look at a few scenarios some users face in their daily workflow.

    Creating a backup

    With GUI, you’d have to take multiple steps:

    1. Right click file.
    2. Left click on “Copy”.
    3. Right click on some empty space.
    4. Left click on “Paste”.
    5. Right click on a newly created copy.
    6. Left click on “Rename”.
    7. Switch to a keyboard.
    8. Type file.bak.

    The above steps can be sped up using shortcuts like C-c or C-v, but not by much. Here’s an alternative in bash:

    cp file{,.bak}
    

    While first variant would do great for a novice or a casual user - the second method would be much more preferred by an experienced user whose concern is speed.

    Recursively bulk replacing text in a directory

    Let’s assume we want to do a bulk replace text in a directory and all it’s subdirectories. We have our trusted IDE, let’s assume this IDE is already configured to work with a desired directory.

    1. Open your IDE.
    2. Select “Edit” menu.
    3. Select “Find and Replace” submenu.
    4. Click on a “Find” input field.
    5. Switch to a keyboard.
    6. Type function_to_replace.
    7. Switch to a mouse.
    8. Click on “Replace” input field.
    9. Switch to a keyboard.
    10. Type new_function_name.
    11. Switch to a mouse.
    12. Enable “Search in subdirectories” checkbox.
    13. Click “OK”.

    Again, this can be shortened a bit with some keyboard shortcuts, but not by much. You still have to switch between keyboard and a mouse a total of 4 times, and you still have to click through all the menus. This does get time consuming if you do this often. Now let’s try to perform the same task in command line:

    find . -type f | xargs sed -i 's/function_to_replace/new_function_name/g'
    

    Much faster, if you’re able to memorize the structure. And remembering what the commands do is much easier than it looks. Especially with the help of man or, even better, bro (see http://bropages.org for latter).

    The above example demonstrates one of the biggest advantages of command line interfaces: an ability to redirect an output of one program into another, chaining the tools together. In this example, we first get a list of all files use find tool, and then run sed tool on each of those files in order to replace the text.

    An output from any CLI tool can be fed into any other CLI tool. This allows for countless possibilities and high adaptability to unscripted scenarios.

    Is it worth learning CLI tools over their GUI counterparts?

    This depends on what your intentions are. If you’re a power user who writes and edits a lot of text or manipulates bulk amounts of text on a daily basis - than it’s definitely worth it. Time spent learning these tools will pay off. But if you’re a casual user whose needs end with writing an occasional email or two - then you probably don’t need to worry about this.

    Hell, if you’ve read this far - this means you’re the former case. I can practically guarantee that you will benefit from employing command line tools and modal editors over their GUI counterparts.

    I’ve put together a table for comparison between two. Indeed, there are different times when either GUI or CLI tools excel:

    Factor CLI GUI
    Ability to combine/chain tools Yes No
    Easy to learn No Yes
    Efficient for a novice user No Yes
    Efficient for an experienced user Yes No
    Good for occasional use No Yes
    Good for repetitive tasks Yes No
    Presents visual information well No Yes

    As you can see - both CLI and GUI programs have their pluses and minuses. CLI tools seem to appeal to experienced users, while GUI tools are great for novice users and do excel in representing visual information. No matter what kind of interface you prefer, it’s crucially important to use the right tool for the job.