Snippets
Collection of my code snippets
Tags:
force push with --lease for safety
10-06-20
%Just found out, via tweet, from
the insightful joshdholtz that there is a safer alternative to
git push --force
Time to update my aliases:
alias gs="gst"
-alias gpf="gp --force"
+alias gpf="gp --force-with-lease"
alias gdc="gd --cached"
I use zsh shell's git plugin that is why you see "gst" for git status
and "gp" for git push
. Highly recommend it
Source:
- [ git]
open notion links
07-06-20
%Recently I've started using Notion app for note
taking. There came times when I wanted to write about a specific directory,
but then came the problem of how to link the dic to notion page. How about a
tiny bash script? OSX's built in open command is capable of opening links so
I copied the link from notion and put in a docs.sh
script. Boom! It opens
the notion page but in the browser not the app 😟.
After some digging I found this
repo for a chrome extension that
opens notion links in the app. Taking a look at the source code it simply
adds a /native
in the url to open in the app. Updated my script and now it
works 😀.
#!/usr/bin/env bash
open https://www.notion.so/native/Custom-Brew-Tap-e6f4faef5130442f94c9b06575806fc0
exit 0
If I continue to do this perhaps I'll write a small tool to create the script files for me.
twtxt config alias
30-05-20
%Recently I started using twtxt. I installed it with brew then setup it up via the quick setup command. The problem is when you put a config file location other then the default when you call the command you get a "✗ Config file not found or not readable. You may want to run twtxt quickstart." error. This is super annoying so I aliased the command to always include the location of my config file.
alias gpf="gp --force"
+ alias tw="twtxt -c ~/.twtxt/config"
Now posting is as easy as:
$ tw tweet "authoring a snippet on how to configure alias twtxt"
jsx comments
26-05-20
%The other day at work we have an html comment in jsx slip on to stage. Made me relize I didn't know how to leave comments in jsx myself.
So as a reminder DON'T do this:
<div>
<!-- comment here -->
<h2>Hello world</h2>
</div>
Instead do this:
<div>
{/* comment here */}
<h2>Hello world</h2>
</div>
source:
creating k8s registry secrets
29-03-20
%Hosting side projects in kubernetes and using gitlab container registry? This is the command I run to create the needed secret for the cluster to pull the image:
$ kubectl create secret docker-registry cool-project-gitlab \
--docker-server=registry.gitlab.com \
--docker-username=gitlab+deploy-token-666666 \
--docker-password=xxxxxxxxxxxxxxxxxxxx \
--docker-email=xxxxxxxxx@xmail.com
Then in the deployment.yml use the gitlab registry image and newly created image secret:
containers:
image: registry.gitlab.com/btbtravis/cool-project:0.0.1
imagePullPolicy: IfNotPresent
name: cool-project-api
imagePullSecrets:
- name: cool-projects-gitlab
- [ kubernetes]
vim open file under cursor
06-03-20
%Half my time in the editor I'm not coding, I'm just browsing the file system trying to understand how things are connected. Trying figure out what needs to change in order to complete my task. This module imports this module which imports this module... There are many ways to navigate the file system and read files. Since I primarily code in VIM there are two main ways I navigate.
One is using the file explorer from plugin, NerdTree. It is great for getting a general overview of folder structure of a project and moving, deleting, or creating new files. Also really good for finding sibling files using the :NerdTreeFind command which I have remapped to
This is where the goto file comes in. Using the following commands in conjunction with moving up and down the jump list, navigation is easy. Here is an example where I use the goto command and a few of its variations.
{{< asciicast-with-caption id="307951" title="demo using vim's goto and jumplist commands" >}}
The most helpful ones to learn are
- <g><f> goto file, same window
- <c-w><f> goto file, new split
- <c-w><g><f> goto file, new tab
Also don't forget to use the jump list
- <c-o> or in my case remapped to <Leader><i> to jump backwards
Resources:
- [ vim]
vim spelling
05-03-20
%Exampled by the errors in my blog posts, spelling is not my strength. Never was. Always felt focusing on spelling limited my vocabulary. So I rely on tech. From the first red squiggly line in MS Word to now.
Web UI base tools:
The problem with these is I have to leave the terminal. Tech Motto: Never leave the terminal. So I use vim's built-in. It is surprisingly good.
In action:
{{< asciicast-with-caption id="307766" title="demo using vim's builtin spell check" >}}
Config:
I write in both English and German so I have key maps for both
nnoremap <leader>se :setlocal spell spelllang=en<CR>
nnoremap <leader>sd :setlocal spell spelllang=de<CR>
nnoremap <leader>sn :setlocal nospell<CR>
Other spelling and writing tools: https://www.are.na/travis-shears/writing-bqnwud28d50
- [ vim]
git repo backup
23-02-20
%Backup a git repo without thats not hosted on remote repo with:
$ git bundle create /tmp/pass_"$(date +%s)".bundle --all
Then to confirm bundle:
$ git bundle verify /tmp/pass_1582448923.bundle
When you need to restore the backup into a new repo folder:
$ git clone -b master /tmp/pass_1582448923.bundle newrepo
I recently used this to backup my ~/.pass-store pass repo. Basically it's a folder full of .gpg files each encrypting a password. Don't want to store it on a remote host so I back it up locally. Create a git bundle then I encrypt the resulting bundle file and store it somewhere safe.
$ gpg --symmetric ./pass_1582448923.bundle
source:
vim fzf plugin
30-01-20
%I've used several fuzzy finder utilities in vim over the years like Command T or CtrlP. They both have there pluses and minuses but never found them to be that fast especially with large code bases I'm often working in. Fzf for me is superior so I was excited to see a plugin that integrates Fzf so well into vim. Its not just useful for finding files but works great with buffers, files with git changes, commands, marks, and even lines in open buffers.
My vim config for Fzf is as follows:
nnoremap <Leader>pb :Buffers<CR>
nnoremap <Leader>pf :GFiles<CR>
nnoremap <Leader>pg :GFiles?<CR>
nnoremap <Leader>pm :Marks<CR>
nnoremap <Leader>pc :History:<CR>
nnoremap <Leader>pl :Lines<CR>
This allows me to easily zip around my code base with speed.
{{< asciicast-with-caption id="296788" title="demo using fzf in vim" >}}
sources:
jq json processor
30-01-20
%One of my oldest snippets is how to Pretty print JSON in the shell. This method works great for simple things where you just need to get an idea of the JSON structure, it has the bonus of using python which you probably already have installed. The problem is when you want to do more complex tasks it is quite limited in terms of parsing. Thats where jq comes in
$ curl https://review-noticket-xxxxxxxx.eu/xxxxx/static/loadable-stats.json | jq '.entrypoints .sharedHeader .assets' | rg --invert-match map`
Simply piping to jq pretty prints the JSON but by passing a query string, ex ".entrypoints .sharedHeader .assets", you dig into the JSON and easily get what you need. This is easily combinable with other shell utilities like in the example above which gets a list of asset URLs than uses ripgrep invert-match to clean out the source map URLs from the list. This is now my perfered way of working with JSON in the shell.
source:
watch command
27-01-20
%Currently at work we occasionally have to redeploy pods that have the same image tag but different SHA hashes. The problem stems from the k8s deployments not picking up the changes and thus a manually killing of the production pods is required. When they are restarted the SHA is checked and new image pulled, during this process I like to watch along at the running pods to make sure things are going smoothly.
I use to use the built in watch argument of k8s get pods command -w:
$ kubectl get pods -n shop -w
But this produces a really cluttered terminal output so I started just running the command on loop
$ while true; do; kubectl get pods -n shop ; sleep 5; done
Then a coworker showed me the watch command which has a much cleaner interface and outputs to a much clearer less/more like non scrolling output.
$ watch -n 5 'kubectl get pods -n shop'
The watch command is availble via brew
$ brew install watch
source:
- [ watch]
move file range
27-01-20
%Recently had to move a range of files and some zsh expansions came in handy.
$ for x in {1..6}; do mv AAAA.S01E0"$x".mkv ./a-$x.mkv; done
source:
https://serverfault.com/questions/370403/copy-a-range-of-files-in-command-line-zsh-bash
zsh git plugin
27-01-20
%I use git exclusive from the command line and while it's interface is very clear since I spend so much time I'm willing to trade some of that clarity for speed. ZSH has a great plugin for really fast git tasks. Two of my favorite are pushing while setting a upstream branch and adding patches.
GPSUP, git set upstream and push shortcut
I push new git branches a few times a day and my previous work flow was to:
$ gp
fatal: The current branch NOTICKET-XXX has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin NOTICKET-XXX
followed by the classic fuck command:
$ fuck
which then runs the proper push command setting upstream. News flash! This call all be accomplished with a single plugin command:
$ gpsup
GAPA, git add patch
I like small commits and the key to that for me is adding by patch. This short cut turns
$ git add --patch
to
$ gapa
Can't recommend the zsh git plugin enough! There are too many shortcut commands to be worth memorizing but I think gpsup and gapa are worth it. For a big list of commands it checkout the docs here
for loops in bash / zsh shells
12-01-20
%Looping directly in the shell is something I do at lease once a week and it's a great time saver. Here I want to run through a concrete example of how to use for loops to mass move and rename files.
During process of getting this snippet section of my site off the ground I realize I had put a bunch of markdown files into named directories when I could have just named the files better and done without the directories. What I needed to do was mv the files out of these dirs and rename them to the name of the dir plus add the ".en.md" extension.
Here is the old directory structure:
$ tree
.
└── snippets
├── _index.en.md
├── aws-cloud-front-inval
│  └── index.en.md
├── aws-s3-sync
│  └── index.en.md
├── ffmpeg-screen-casts
│  └── index.en.md
├── find-folder
│  └── index.en.md
├── git-better-git-add
│  └── index.en.md
├── git-log-grep
│  └── index.en.md
├── git-move-branch
│  └── index.en.md
.
.
To start with I preformed the operation in question a single time to prove it works:
$ mv ./who-is-using-that-port/index.en.md ./who-is-using-that-port.en.md && rm -r ./who-is-using-that-port
Then I copy this command to the clipboard for later and use command history pull up a previous for loop command and switch the shell command entry external editing in vim mode, for me <C-x><C-e>. As we are essentially writing a quick bash script in-line we need vim powers! While in vim if you need the file list a quick :r !ls does the trick. These little efficiencies like using command history are not just faster but make it so you don't have to remember the bash syntax.
Resulting vim buffer with the for loop:
for x in \
aws-s3-sync \
ffmpeg-screen-casts \
find-folder \
git-better-git-add \
git-log-grep \
...
git-move-branch \
vim-window-resize ; do mv ./"$x"/index.en.md ./"$x".en.md && rm -r "$x" ; done
Resulting new file structure:
$ tree
.
└── snippets
├── _index.en.md
├── aws-cloud-front-inval.en.md
├── aws-s3-sync.en.md
├── ffmpeg-screen-casts.en.md
├── find-folder.en.md
├── git-better-git-add.en.md
├── git-log-grep.en.md
├── git-move-branch.en.md
.
.
Perfect, all files have been renamed properly and the empty directories deleted. This technique has lots of other applications besides moving and renaming files. Earlier this week while debugging api at work I dumped bunch of json responses into a file so I could search for translation key.
$ for x in \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx \
https://api.poeditor.com/v2/download/file/xxx ; do curl $x >> /tmp/translations.json; done
custom placeholders solution
11-01-20
%This little bit of magic I believe I picked up from watching a Luke Smith video. The point is to leave placeholders in the form of the text "<++>" in your code/writing then quickly snap to and fill them in later.
" placeholder magic
nnoremap <Space><Space> <Esc>/<++<CR>"_c4l
nnoremap <Space>n <Esc>l/<++><CR>h
" always fill p reg with <++>
:autocmd VimEnter * :call setreg('p', '<++>')
- Thanks to the vim enter hook the magic placeholder text is always in my p register so its easy to put with <"><p>
- Then to jump to the next placeholder and immediately start editing it with a simple <Space><Space>
{{< asciicast-with-caption id="293101" title="placeholders demo" >}}
source:
- [ vim]
super powers of the arg list
11-01-20
%Vim help:
The argument list *argument-list* *arglist*
If you give more than one file name when starting Vim, this list is remembered as the argument list. You can jump to each file in this list.
If you have been using vim a while you will be comfortable with the buffer list but often it's full of random files, terminal sessions, and other none file buffers, this is where arglist comes in. It starts out as list of files that were initially opened when the vim session was launched ex:
nvim ./a.txt ./b.txt ./c.txt
would start vim with three buffers in both arglist and buffer list. You can cycle through the arglist with files via :next, :prev. Further files opened will not be automatically added to the arglist so it's essentially a clean sub list of the buffer list. Helpful commands include :rew to jump back to the first file you edited this session. Also :all which opens all buffers of the arglist in splits.
Where I find the arglist particularly powerful is for mass file edits. Here is an day to day example:
- get files in questing into the arglist either pipe files to vim or from in vim override initial arglist.
- from cli
$ rg -i 'snippet_typ.*vim' --files-with-matches | xargs nvim
- from inside vim (harder because no autocomplete)
:args `rg -i 'snippet_typ.*vim' --files-with-matches`
- now lets change all the posts front-matter to draft = true
:argdo %s/draft: false/draft: false/g | update
thats it all the files have been modified and saved. Its best to use this kind of thing with version control so during an interactive git add you can verify each modification.
For more complex edits I load files into the list a similar way then make quick manual and move to next file with :wn which also saves.
custom ripgrep
11-01-20
%In the past I used full plugin level text searching solutions the likes of :Rg, :Grep, :Ag from the vim grep plugin. Recently I've found it faster and more customizable to just run :term do my searching from there and then opening file under cursor in new split with <C-W><f>. Doing the searches directly in terminal builds more on all the tricks I've devolved outside of vim world. However launching terminals all the time is also has it's pain points, so now I've come up with a simple key mapping to run searches in a new scratch window without having to go full term.
yank the search term then <Leader><s> pulls up a new scratch buffer with the search pre-filled but with the ability to still edit and add further customisations.
nnoremap <Leader>s :Sscratch<CR>:read ! rg -i <C-R>"
here I use the technique to search for all snippet files tagged with vim
{{< asciicast-with-caption id="293019" title="demo of using the jump list" >}}
plugins:
remapping ability to jump
11-01-20
%Moving efficiently in vim is a massive topic but recently I just wanted to take advantage of the jump list more but by xQuartz / xterm mac terminal setup meant the default key mappings we being intercepted as promote / demote pane. Simple remap did the trick
nnoremap <Leader>i <C-i>
nnoremap <Leader>o <C-o>
In the following demo I open this very post then navigate to my .nvimrc and yank the code remapping snippet. With the snipped yanked, using this using jump list via <C-O>, I jump back to the markdown file I was editing and put.
{{< asciicast-with-caption id="292978" title="demo of using the jump list" >}}
- [ vim]
replae <s> with spell and nohl
11-01-20
%When is the last time you used the <s> key in vim? May not know what it even does?
The vim help pages lists it as substitute:
4.2 Substitute *:substitute*
*:s* *:su*
:[range]s[ubstitute]/{pattern}/{string}/[flags] [count]
In real use I find this visual selection putting or using <c> along with movement keys much better for substituting text. This leave the s key in normal mode open to be remapped! Here are two mappings I have so far:
- turn off highlighting with a quick <s><s>
nnoremap ss :noh<CR>
- turn on spell check in a given language
nnoremap <leader>se :setlocal spell spelllang=en<CR>
nnoremap <leader>sd :setlocal spell spelllang=de<CR>
- [ vim]
resizing vim windows with arrow keys
11-01-20
%If your comfortable in vim you only use the j,h,k,l movement keys leaving the arrow keys open to do something more useful like window resizing!
" Remap arrow keys to resize window
nnoremap <Up> :resize -2<CR>
nnoremap <Down> :resize +2<CR>
nnoremap <Left> :vertical resize -2<CR>
nnoremap <Right> :vertical resize +2<CR>
{{< asciicast-with-caption id="292983" title="demo window resizing" >}}
- [ vim]
uploadable ffmpeg screen casts
11-01-20
%I prefer tools like https://asciinema.org/ when I want to show terminal tricks and cli tools I build, but sometimes you need to show something that breaks out of the terminal. In this case I record a .mov screen cast using quicktime then do several transformations using ffmpeg to get a small uploaded web friendly .webm file.
- cut down the video if need be
$ ffmpeg -i movie.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4
- scale down the .mov file to something more web friendly
$ ffmpeg -i vim_dic.mov -filter:v scale=512:-1 -c:a copy vim_dic_small.mov
- convert the .mov to .webm
$ ffmpeg -i vim_dic_small.mov -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis vim_dic.webm
If you don't have ffmpeg is available via brew
source:
configure more gitlab runners
11-01-20
%$ docker run --rm -t -i -v /home/travis/runner:/etc/gitlab-runner --name gitlab-runner-hypert-web gitlab/gitlab-runner register
Gitlab's ci pipelines are superpowerful and not hard to setup but you do have to get runners going. For me running gitlab in out of a docker container this is how I add runners to a new project
source:
who last edited a file
11-01-20
%$ git log -1 -- alice/alice/public/themes/core/views/layouts/src/css/main.scss
Sometimes you just need to know how to blame
source:
- [ git]
search git logs with grep
11-01-20
%$ git log --grep=NUTS-5288 --since=3.month
Have I already made commits for this Jira ticket?
source: