Browsing all posts tagged software

The Git Bash prompt in Windows is shockingly slow. I found this gist that speeds it up considerably. Simply place this in your user's .bash_profile file.

# Very very fast __git_ps1 implementation 
# 100% pure Bash (no forking) function to determine the name of the current git branch
# Modified from: https://gist.github.com/Ragnoroct/c4c3bf37913afb9469d8fc8cffea5b2f
# Which was inspired by https://gist.github.com/wolever/6525437
function __fastgit_ps1 () {
    branch=""

    local headfile head branch
    local dir="$PWD"

    while [ -n "$dir" ]; do
        if [ -e "$dir/.git/HEAD" ]; then
            headfile="$dir/.git/HEAD"
            break
        fi
        dir="${dir%/*}"
    done

    if [ -e "$headfile" ]; then
        read -r head < "$headfile" || return
        case "$head" in
            ref:*) branch="${head##*/}" ;;
            "") branch="" ;;
            *) branch="${head:0:7}" ;;  #Detached head. You can change the format for this too.
        esac
    fi

    if [ ! -z "$branch" ]; then
        branch="($branch)"
    fi

    # Edit to suit your needs. Note the branch will be wrapped in parenthesis if it's set. Completely empty otherwise.
    export PS1="\[\e]0;\W\a\]\n\[\e[32m\]\u@\H \[\e[33m\]\w\[\e[0m\] \[\033[36m\]$branch\[\033[0m\]\n\$ "
}
export PROMPT_COMMAND=__fastgit_ps1

I've mentioned once before some of the packages I use in Sublime Text, but it's also useful to keep track of the customized settings I use in a few of them. This post will help me track that kind of thing.

FileDiffs

I like WinMerge for doing visual diffs, so that's what I configure here.

{
    "cmd": ["C:\\Program Files (x86)\\WinMerge\\WinMergeU.exe", "$file1", "$file2"]
}

LSP

I like seeing my diagnostic counts in the status bar.

{
  "show_diagnostics_count_in_view_status": true,
}

LSP-ruff

To stay current, I use a custom installation path, which I can keep up to date with the latest release.

{
    "initializationOptions": {
        "globalSettings": {
            "logLevel": "info",
            "path": ["C:\\Python\\Python31203\\Scripts\\ruff.exe"],
            "interpreter": ["C:\\Python\\Python31203\\python.exe"]
        }
    }
}

MarkdownPreview

Just the vanilla parser for me, thanks.

{
    "enabled_parsers": ["markdown"]
}

TodoReview

This config adds a few extra locations to ignore when looking for TODOs:

{
    "exclude_folders": [
        "*.git*",
        "*junkyard*",
        "*logs*",
        "*sample-data*",
        "*venv*",
    ]
}

A 2018 article on how Joel Spolsky broke IT recruiting randomly popped up in my news feed today. I particularly enjoyed the section that discussed IT recruiting, though the bits relating to StackOverflow haven't aged well; that site is beyond having jumped the shark.

I'm not a people manager, but I have assisted in hiring a number of folks over the years. Some of them turned out to be great developers, while others turned out to be terrible. It's so hard to vet folks based on a handful of interviews. Back when in-person interviews were more of a thing, it was easier. Today's online-only world makes that nearly impossible, especially given that some candidates are no longer local.

Having an actual apprenticeship program would make the process so much easier. New candidates could come aboard for a trial period; 6 or 12 months. Financially, it would be treated like a contract position. During this period they could then be evaluated over time:

  • Is the candidate reliable?
  • Are their development skills what they said they were?
  • Can they communicate effectively?
  • Do they complete deliverables on time?

After the apprenticeship is up, they'd become a "journeyman" and a full-time employee. A program of this sort would greatly reduce the ridiculous speed bump some employers put in the way of hiring developers. It would also make it really easy to get rid of the downright awful developers who occasionally creep in.

This really needs to become a thing.

The Future of AI

Feb 14, 2023

Today's Tom Scott video feels very prescient. I too have had the feeling that we are standing on the cusp of something big; though I'm not sure if that something is good or bad. The problem Tom was trying to solve was also interesting (who knew that subtle quirk about GMail's labels?!?).

My text editor of choice when I'm in Linux-land is Vim. One of its most powerful features is the ability to use regular expressions when searching. This capability makes hunting through giant log files so easy. However, I ran into a problem today that I wasn't sure how to work around.

I was looking through a large log file, trying to find the lines that included the text Internal Server Error. Making this difficult, however, were hundreds of such entries that were calling a known failing case. I wanted to weed out these known cases, and with regular expressions, I was able to. The known case I wanted to ignore looked something like the following:

[02/Feb/2023 16:06:14] ERROR [log.py:224] Internal Server Error: /api/v1/some_bad_endpoint/

This endpoint is the only one in the /api root, so I wanted to ignore /api as a part of my search. The magic is through negative look-ahead assertions, the syntax for which I was unfamiliar (\@! being the key). My search command in Vim ended up being:

/Internal Server Error: \/\(api\)\@!

Using this regular expression helped me jump to every instance of the Internal Server Error text that wasn't a call to the known-failing /api root. So handy!

Sublime Text Settings

Jan 17, 2023

I use Sublime Text as my primary code editor, and I use it in a number of places (my work laptop, a personal laptop, my home desktop computer, etc.). As a help to myself in keeping the environments synced, here are the settings I like using within Sublime Text. Having this kind of thing logged somewhere is such a help when setting up new environments.

Last updated: May 15, 2024

{
    "auto_complete_commit_on_tab": true,
    "always_show_minimap_viewport": true,
    "bold_folder_labels": true,
    "caret_extra_top": 2,
    "caret_extra_bottom": 2,
    "color_scheme": "Mariana.sublime-color-scheme",
    "draw_minimap_border": true,
    "ensure_newline_at_eof_on_save": true,
    "font_face": "Consolas",
    "font_size": 10,
    "hardware_acceleration": "opengl",
    "hide_new_tab_button": true,
    "highlight_line": true,
    "highlight_modified_tabs": true,
    "ignored_packages":
    [
        "Vintage",
    ],
    "indent_guide_options": ["draw_normal", "draw_active"],
    "indent_to_bracket": true,
    "index_files": true,
    "revert_font_size": 10,
    "rulers": [80, 100],
    "scroll_speed": 0,
    "show_encoding": true,
    "show_line_endings": true,
    "theme": "Adaptive.sublime-theme",
}

These are the key-bindings that I use:

[
    { "keys": ["ctrl+shift+v"], "command": "paste" },
    { "keys": ["ctrl+v"], "command": "paste_and_indent" },
    { "keys": ["ctrl+="], "command": "file_diff_menu" },
    { "keys": ["ctrl+shift+="], "command": "file_diff_previous" },
    { "keys": ["ctrl+alt+p"], "command": "prompt_select_workspace" },
    { "keys": ["ctrl+shift+'"], "command": "change_quotes" },
    { "keys": ["ctrl+,"], "command": "prev_modification" },
    { "keys": ["ctrl+0"], "command": "revert_font_size" },

    // LSP
    // Jump to next Diagnostic in Tab
    {
        "keys": ["ctrl+k", "n"],
        "command": "lsp_next_diagnostic",
        "context": [{"key": "setting.lsp_active"}]
    },
    // Jump to previous Diagnostic in Tab
    {
        "keys": ["ctrl+k", "p"],
        "command": "lsp_prev_diagnostic",
        "context": [{"key": "setting.lsp_active"}]
    },

    // Origami
    { "keys": ["ctrl+k", "shift+up"], "command": "create_pane", "args": {"direction": "up"} },
    { "keys": ["ctrl+k", "shift+right"], "command": "create_pane", "args": {"direction": "right"} },
    { "keys": ["ctrl+k", "shift+down"], "command": "create_pane", "args": {"direction": "down"} },
    { "keys": ["ctrl+k", "shift+left"], "command": "create_pane", "args": {"direction": "left"} },
    { "keys": ["ctrl+k", "ctrl+up"], "command": "carry_file_to_pane", "args": {"direction": "up"} },
    { "keys": ["ctrl+k", "ctrl+right"], "command": "carry_file_to_pane", "args": {"direction": "right"} },
    { "keys": ["ctrl+k", "ctrl+down"], "command": "carry_file_to_pane", "args": {"direction": "down"} },
    { "keys": ["ctrl+k", "ctrl+left"], "command": "carry_file_to_pane", "args": {"direction": "left"} },
    { "keys": ["ctrl+k", "ctrl+z"], "command": "zoom_pane", "args": {"fraction": 0.9} },
    { "keys": ["ctrl+k", "ctrl+shift+z"], "command": "unzoom_pane", "args": {} },
]

Here also is my Package Control configuration, which includes a list of the packages I have installed on my primary work development system (which is where I do most of my development work anyways):

{
    "bootstrapped": true,
    "in_process_packages":
    [
    ],
    "installed_packages":
    [
        "A File Icon",
        "BracketHighlighter",
        "Center Comment",
        "ChangeQuotes",
        "Django Syntax",
        "DotENV",
        "Emmet",
        "FileDiffs",
        "Indent XML",
        "LSP",
        "LSP-json",
        "LSP-ruff",
        "MarkdownPreview",
        "Origami",
        "Package Control",
        "PackageResourceViewer",
        "PlainTasks",
        "Pretty JSON",
        "RevertFontSize",
        "Side-by-Side Settings",
        "SublimeLinter",
        "Terminus",
        "TodoReview",
    ],
}

I love Sublime Text and use it across a number of my computers. Occasionally, one of my systems becomes down-level, especially in terms of the packages I'm using. I know I can sync my user profiles via Git (or something similar), but occasionally it's good to reset things and start from a fresh profile.

So that I can keep track of what I primarily use, I'm writing down the packages I use on my primary development system.

Last Updated: May 16, 2024

I like using Google Photos, as it has nearly all of the features I care about. However, the search capability is puzzlingly lacking, especially from a company whose core foundation is based on searching for stuff. One of the features that Google touts for Photos is their AI-enhanced searching capability. For instance, if you type a color into the search box, you'll see a listing of photos that feature that color; pretty neat! However, if you search for specific text that appears in your image descriptions, it won't provide any results.

One of things I tend to do for my wildlife pictures is enter the animal's identification into the image description: for example, the description for a picture of a male northern cardinal might look something like Northern Cardinal (Male). Later, if I happen to search for "northern cardinal," no results will be returned! I'd love to be able to search the meta-data (and maybe even the comments) for my photos. It would allow me to use the photos as a database of sorts, which is as it should be.

Dropbox Alternatives?

May 22, 2021

I'm finally getting around to upgrading my increasingly ancient, first-generation Google Pixel smartphone. In so doing, I'm going to have to figure out what kind of file synchronization service I can switch to. Dropbox has been my go-to for this kind of thing for years, and it suits my relatively simple needs pretty well (I primarily use it to sync my KeePass password database). However, Dropbox now caps the free tier of service to a maximum of 3 devices. I have more than three devices that I use it on (they were all grandfathered into the new rules), and activating my new smartphone will mean I no longer have support on my phone.

The primary competition that I see to Dropbox is both Microsoft's OneDrive and Google Drive. The former has better OS integration than the latter (from what I can tell), and neither one has such strict limits on the number of devices that can be used. Does anyone have experience with either of these services in terms of syncing files between devices? If so, I'd enjoy hearing about your experience. Are there other similar services I should know about?

For the past two weeks or so, I've been using Microsoft Edge as my daily driver in the web browsing world. One of the primary motivators for my doing this was Edge's capability to stop auto-playing media, which I find highly annoying. Unfortunately, the advertised feature didn't work for me; at least not on the sites that bug me most (my preferred local news station's website being chief among them). That said, there were a few things I liked and disliked about my experience (note that I have since moved back to Chrome).

What I Liked

  • Migrating data from Chrome took one click, and everything came over: bookmarks, extensions, etc. This was a nice surprise and made transitioning seamless.
  • Since Edge is Chromium-powered, the same set of web developer tools were available. That made my debugging life easier.
  • Edge is very fast, and apparently a lot less resource intensive than Chrome. I'm not sure I perceived any differences, but I was happy to see that things were very snappy.
  • The "picture of the day" on the new tab page was a neat feature. There were some really beautiful photos featured while I used it.

What I Disliked

  • I absolutely hate the way Edge does browser history. When you open your history, a fixed-height dropdown panel appears in the toolbar, which you then must scroll through. Entries pop into view as you scroll, and this part is surprisingly slow. There's apparently no support for opening history in a sidebar by default (though you can pin the view to a sidebar once the popup appears).
  • Auto-play blocking doesn't work. This is the primary feature I was after, but it didn't work for me. It also stinks that it's all or nothing, and not configurable (like I believe Firefox supports).
  • As you might expect, there are a bunch of links to Microsoft content (Office 365, Bing, etc.) all over the place. They're really trying to push their products, and it shows.
  • Bing search is a disappointment. I gave it an honest try, but more often than not I had to scroll way down in the search results to find a result of use. This seemed particularly problematic with technical searches. Google just seems to surface technical content better than Bing. Perhaps that's a function of the overall user base?

As I said previously, I've since switched back to Chrome, as Edge didn't feel different (or better) enough to get me to stay. I'm debating giving Firefox another try, but I've been really frustrated with how Mozilla has hobbled their browser over time with stupid decisions. Are there other browsers I'm missing out on that you like? A former colleague of mine used the Brave browser, which I haven't yet tried. I'm open to trying alternatives, so let me know if there's one I've overlooked.

I maintain multiple tools at work that all run in Docker containers on the same machine. The overall setup looks like the following diagram:

Tool Network Diagram

The router container on top (nginx) routes traffic to the various application containers based on the hostname seen in each request (each tool has its own internal domain name). Each application has an nginx container for serving static assets, and a gunicorn container to serve the dynamic parts of the application (using the Django framework).

Earlier this week, I was trying to add a redirect rule to one of my application containers (at the application nginx layer), because a URL was changing. As a convenience for users, I wanted to redirect them to the new location so they don't get the annoying "404: Not Found" error. I set up the redirect as a permanent redirect using a rewrite rule in nginx. For some strange reason, the port of the application's nginx layer, which should never be exposed to the outside world, was being appended to the redirect!

Adding the port_in_redirect off; directive to my nginx rules made no difference (or so I thought), and I struggled for an entire day on why this redirect wasn't working properly. At the end of the day, I learned that permanent redirects are aggressively cached by the browser! This annoyance means you need to clear your browser's cache to remove bogus redirects. I wasted an entire day because my stupid browser was using a bogus cached reference. Ugh!

NewsBlur

Jan 9, 2019

I consume nearly all of my news and web reading through RSS feeds, and have done so for many years. Back before July 2013, I used Google Reader, before Google shut it down for good (the bums). Shortly after Google Reader was closed, I switched to NewsBlur, which closely resembles the Google Reader of yore. I cannot imagine surfing the web without it.

The service can be used for free (up to a maximum of 64 feeds, and only 5 stories at a time in the "river of news" mode), but I pay a yearly fee ($36) to have an unlimited number of feeds and stories.

One of the best features of NewsBlur is being able to "train" the reader to know what you like and don't like from various sites. I've trained several of my gaming feeds to exclude anything about Fortnite, because that's a game I have no interest in. As a result, stories on that topic are never shown to me; I'm in control of what I read! Similarly, I've also trained a few feeds to flag articles from authors I like. Those articles are highlighted, and I can view just those highlighted ones if I so choose with the "Focus" mode.

There are lots of other features to recommend about NewsBlur: searching for stories across all of my feeds, sharing stories with friends on the service, a pretty nice Android app, and lots more. If you haven't given NewsBlur a try, be sure to.

SMBC RSS

Jan 3, 2019

One of the web comics I follow is Saturday Morning Breakfast Cereal. The official RSS feed for this comic only includes the comic itself and the associated hover-text joke. To see the extra joke, you have to visit the SMBC website. But no longer!

I've just created a new project on GitHub that fixes this issue. It's another RSS feed generator, and the feed that it generates contains the daily comic, the hover-text joke, and the hidden joke, all inline.

As always, there's room for improvement in a place or two. Let me know if you spot any issues.

Remember the days of Microsoft FrontPage? I first cut my web development teeth using that tool, and at the time I thought it was amazing. Designing a web site was made easy and I really liked the WYSIWYG editing style. I eventually migrated to Adobe Dreamweaver which seemed (and was) even more powerful.

Nearly 20 years have passed since my start in web development. With a computer science degree under my belt, along with 13+ years of professional experience, I can only look back on those days and laugh at my naivety. Those tools seemed slick at the time, but they were pretty clunky in actuality. The HTML and rudimentary CSS that each generated was ugly and bloated. That said, the WYSIWYG movement never really died. With modern companies like Squarespace and Wix.com, the "build it as you go" web model is still alive and kicking.

WordPress now also seems to be headed that way. I use WordPress here at Born Geek, and I just recently updated to version 5.0. The giant new feature in this release is the new Gutenberg editor, which offers a visual means of laying out your content. To a technical minded person like myself, who typically writes posts in Markdown, the editor is incredibly confusing. I don't want to have to insert "blocks" with my mouse every time I need a bulleted list or image.

The new editor in WordPress is no doubt an attempt to win users from the Squarespaces and Wix.coms of today's market. I wonder, however, if this comes at the cost of alienating technical users or users who are simply used to the old look and feel. Giant changes are always likely to have push back, especially with a user base as large as that of WordPress. Given, however, that the Classic Editor plugin already has over one million users, I'd say that this change has a bigger negative opinion than the WordPress powers-that-be might be willing to admit. It will be interesting to see how things progress over the next few months. I'm just thankful that the Classic Editor plugin even exists.

Since I no longer subscribe to my local newspaper, I now primarily read daily comic strips through RSS feeds. comicsrss.com carries the vast majority of the strips I read, but several key strips are not included. It turns out that these missing strips are all owned by King Features which, frustratingly, doesn't provide RSS feeds to their strips.

I have now fixed that.

My new project, comics-rss, is now available for users interested in creating RSS feeds to the comic strips provided by King Features. The project is admittedly brittle at the moment, but it has worked well for me so far. A number of improvements are planned:

  1. The script currently caches the comic strips locally, linking to the cached copy. I'd like to provide an option to use direct links instead, skipping the cache altogether.
  2. Cached strips are not currently cleaned up, so the folder into which they are stored will grow each day. I'll be adding an "expired" configuration option to clean things up.
  3. Error checking in the configuration file isn't very robust, and needs to be improved.

I would be interested in any feedback you might have on this project. If you find bugs or have suggestions for improvement, be sure to file them on the project issues board.

As I age, my vision is getting worse (and it's already pretty bad). At work, I use a three monitor setup: my laptop is the middle screen, and two external monitors sit to either side. Given the large screen real estate, and given my increasingly bad eyesight, I've been having a tough time finding my mouse pointer. Windows has an option to show the location of the mouse pointer when you press the Ctrl key, but that has limited usefulness (though I do use it from time to time).

I recently stumbled upon a neat feature in Windows 10 that has helped me tremendously. There are several mouse-specific features in the Ease of Access section of the Windows settings. The pointer size can be adjusted (which is helpful to a degree), but the most helpful feature is the Pointer Color setting. There's an option to adjust the pointer color based on whatever color is beneath it. It took a little getting used to, but I can now find the mouse pointer a lot easier than I could before.

Lenovo Thinkpads have an on-screen display for various hot-keys. For example, when you change the monitor brightness, or the volume level, an on-screen overlay will display showing the current brightness level or volume level, respectively. Twice, I have received laptops from Lenovo that have this software installed, but the on-screen display never appears. Frustrated by this bug, I used the Dependency Walker to troubleshoot this problem a while back, and subsequently found the solution.

Simply install the Visual Studio 2010 C++ redistributable, available from Microsoft (make sure to install the x86 version, even on a 64-bit system; the on-screen display application is a 32-bit process). Once this package is installed, and the laptop rebooted, the problem should go away.

GitLab defaults its time zone to UTC, which may not be what you want. Thankfully, you can update the value directly from your gitlab.rb file. Here's the relevant line:

gitlab_rails['time_zone'] = 'America/New_York'

Once you've added the field, simply reconfigure and restart:

sudo gitlab-ctl reconfigure
sudo gitlab-ctl restart

A list of all the available timezones is available on Wikipedia.

I have created a GitHub repo storing several Firefox extension utility scripts that I wrote. Here's the rundown on what this repository contains:

compareLocales.pl
Compares all of the locales it finds against a "master" locale (en-US by default) and reports the number of exact duplicate entries for each. This is useful for figuring out which locales have not been updated.
entityToProperty.pl
Converts a given list of locale entities into corresponding properties. Handy for migrating existing entity localizations into a .properties file.
removeLocaleEntries.pl
This script removes a given list of entries from all of the locale folders it finds in the current working directory and below. Useful for cleaning up strings that are no longer needed.

Hopefully others will find these scripts to be useful. I hope to add additional scripts to this repository over time.

I have a Samsung Galaxy Tab 7.0 Plus running the Ice Cream Sandwich version (4.0.4) of Android. For some unexplained reason, the location services feature stopped working a few months ago, but only for what seemed like a few applications. Google Plus no longer knew my location, Radar Now no longer knew it, and the stock web browser was also clueless. Google Maps, on the other hand, knew right where I was. Since I use the tablet in the house, GPS isn't much help. I frustratingly was unable to fix things, until today, when I stumbled on a solution. Here's how I did it:

  1. I opened up Settings » Location services and unchecked the Location and Google search option
  2. I rebooted my device
  3. Back in Settings » Location services, I rechecked the Location and Google search option
  4. I then toggled the Use wireless networks option, and answered a prompt that appeared about using my network location in third-party apps (or something similar; I don't have the exact message in front of me).
  5. Success!

Using GPS to lock in on my position worked outside, but that alone didn't seem to set things right. Disabling the above option, rebooting, and then re-enabling it seemed to do the trick. Hopefully this will help anyone else who might have a similar problem.