Musings of a dad with too much time on his hands and not enough to do. Wait. Reverse that.

Author: Brad (Page 39 of 57)

Dad. Technologist. Fan of English poet of John Lillison.

Favorite Keyboard Shortcuts

A constant theme at DadOverflow.com is the need to save time given the fact that family and other commitments lay claim to so much of mine. When writing code or prose on a computer, the more I can keep my fingers on the keyboard and minimize having to grab my mouse for particular operations, the more time-efficient I can be. To that end, here are a few keyboard shortcuts–sometimes called hotkeys–I tend to use quite a bit to maximize my time on the keyboard. The cool thing about many of these is that most applications–from Microsoft products to open source–support the same shortcuts.

1. Cut, Copy, and Paste: Ctrl+X, Ctrl+C, Ctrl+V

Let’s just get this one out of the way: those of us who remember typewriters have great appreciation for cut, copy, and paste operations in modern editors. These shortcut keys make quick work of these important functions.

2. Highlighting characters and words: Shift+<arrow key>

Cut, copy, and paste are great, but don’t you have to use the mouse to highlight the word or phrase you want to cut or copy? No, sir! Depending on where your cursor is in your document, you can hold down Shift and then click the left or right arrow key to begin highlighting, character by character, the word or phrase you want to cut or copy. If you want to save some time, hold Shift+Ctrl and then click your left or right arrow key to select an entire word at once. If you want to highlight the entire line, first click your <home> button to place your cursor at the beginning of the line, then hold Shift and click the <end> button. Holding Shift and then clicking either your up arrow key or down will also allow you to select large sections of text.

3. Marking up text: bold, italics, etc.

Often, you’ll want to bold, italicize, underline, or otherwise modify your text in some fashion. Keyboard hotkeys to the rescue! First, highlight the text you want to modify using the techniques I described above. To bold your selected text, select Ctrl+B. To italicize, Ctrl+I. To underline, Ctrl+U (although I’ll note here that not all editors I’ve used support that particular function). To strike through your text, Ctrl+-. There are likely many other ways to modify your text; these are simply the options I use most often.

4. Hyperlink your text: Ctrl+K

Turning you text into hyperlinks to other sites, articles, reports, and so forth is a great way to keep your prose readable but still provide further details where needed. Here again, highlight the text you want with my techniques above and then click Ctrl+K. Most editors will then present you with a dialog where you can Ctrl+V the hyperlink you want to link to.

5. Nesting and unnesting bullets

Using bullets in your writing are:

One challenge with bullet points, though, is when you want to include sub-bullets or, when you’re done listing your sub-bullets, climbing your way back up a level. The Tab key is your friend here. When you’re ready to dive into the sub-bullet pit, click Tab to go down one level. When you’re ready to climb back up a level, Shift+Tab will do the trick.

6. Undoing your mistakes: Ctrl+Z

My ratio of mistakes to successes is about 5:1. So, I use Ctrl+Z quite a bit.

7. Saving your documents: Ctrl+S

Save early, save often. Ctrl+S for the win!

8. New documents: Ctrl+N

Most multi-document interface (MDI) editors support the hotkey Ctrl+N to launch a brand new, blank document.

9. Open a document: Ctrl+O

Within your editor, Ctrl+O should open a dialog to let you choose an existing document to open and edit. That can be helpful if you’re not able to drag-and-drop your document on the canvas of the editor or if the file extension of the document is mapped to a different application.

Positioning Windows with PowerShell

When it comes to multiple monitor displays connected to my workstations–either at home or at work–I’m a little like Tim “the Toolman” Taylor: I need more!  And just as I carefully separate my peas and carrots, I must carefully separate the sort of tasks I perform on each monitor.  For example, I like to do my folder and file browsing in my right most monitor and in my left most monitor, I like to do my command shell work.

At work, I interface with a lot of Linux servers, so I tend to have a few command shells open at once connected to these systems.  Since I like to have these shells in my left most monitor, I sought out a solution to automatically launch and proportionally position multiple command shells in my left most monitor.  Initially, I did this with an AutoIt script.  That was an OK solution, but I didn’t find it all that flexible.  I work at home occasionally and my multiple monitor setup is different between home and work.  I found it challenging to make my AutoIt script sufficiently adaptive between each environment.  So, I embarked on a PowerShell solution for my problem.  Here’s how I went about crafting my solution:

Step 1: Establish a windows positioning solution

AutoIt already has a nice window positioning library included with it, but PowerShell does not.  Fortunately, someone wrote a great solution called Set-Window.  I downloaded this script and made two small alterations:

  1. I turned the script into a PowerShell module (PSM1) so that more than one PowerShell script I write can take advantage of this tool and
  2. I changed the script’s ProcessName parameter to ProcessId.  That way, I could pass the script the process id of the window I want to position and there would be no ambiguity as to the exact window I want to change.  You can find my modifications here.

Step 2: Figure out where my left most window is

To be honest, I never explored whether or not AutoIt could give me all the properties of the monitors attached to my workstation, but I knew PowerShell could and that was enough for me.  The .NET namespace System.Windows.Forms.Screen contains an AllScreens function that easily gives me all the details I want.  All I need to do is sort by the X coordinate and grab the first returned record to capture the properties of my left most monitor:


1
2
3
4
5
Add-Type -AssemblyName System.Windows.Forms
$left_most_screen = [System.Windows.Forms.Screen]::AllScreens|sort -Property {$_.WorkingArea.X}|select -First 1
$x = $left_most_screen.WorkingArea.X
$screen_width = $left_most_screen.WorkingArea.Width
$screen_height = $left_most_screen.WorkingArea.Height

Step 3: Launch my command shell instances and position them accordingly

The last step is to run a loop for the number of command shells I want to open.  At present, I’m setting a variable to 2 shells, but I can always change that variable and the script will automatically adjust.  Note that for my shells, I’m using the Ubuntu instance of the Windows Subsystem for Linux (WSL).  In each loop, the script performs three tasks:

  1. It launches a new shell instance
  2. It does some simple math to figure out where to place the shell in the left most monitor and
  3. It calls Set-Window to do the positioning

One note: on my work monitor, when I first call Set-Window on a command shell, it mysteriously sets a slightly smaller height and width for the window.  I’ve found that the easiest fix for this problem is to simply call Set-Window a second time:


1
2
3
4
5
6
7
8
9
1..$nbr_of_windows_to_open|%{
    $app = Start-Process $ubuntu_path -PassThru
    Start-Sleep -Seconds 3
    $y = ( ($_ - 1) * ($screen_height / $nbr_of_windows_to_open) )
    $h = ( $screen_height / $nbr_of_windows_to_open )
    Set-Window -ProcessId $app.Id -X $x -Y $y -Width $screen_width -Height $h -Passthru
    # strangely, on some monitors, the first Set-Window doesn't quite take, but setting it again seems to work
    Set-Window -ProcessId $app.Id -X $x -Y $y -Width $screen_width -Height $h -Passthru
}

You can find my full solution here.  To truly functionalize this solution, I can (and do) take two more steps:

  1. Wrap my PowerShell script in a batch script.  In a BAT file, I can write a command like so: powershell -command “& ‘C:\somePath\launch_ubuntu_windows.ps1’ ” -ExecutionPolicy Bypass
  2. Call that BAT file from Slickrun

But wait, there’s more

I recently replaced my work laptop.  More memory, more power…a true Tim “The Toolman” Taylor moment.  I’m now running the script I described above to launch and neatly place a couple of command shells in my new-and-improved system.  But a frustrating situation occurs to me, not all the time, but enough to be annoying.  I will launch my shells, do a few hours of work, then get up to stretch my legs, get some coffee or otherwise move away from my workstation.  Before moving away, I lock my workstation like any decently security-minded person would.  When I get back, quite often, all my applications, including my command shells, have shifted off my extended monitors and on to my main monitor, negating all the work I did to line them up just right on my extended displays.  I don’t want to re-run my “launch” script again because I don’t need to open more shells–just reposition the ones I already have open.  What I now need is a repositioning script!

My repositioning script works exactly like my “launch” script, only, instead of starting brand new command shell processes, it uses PowerShell’s Get-Process cmdlet to find the already open command shells, get their PIDs, and reposition them the same way as I did before.  Here’s a snippet:


1
2
3
4
5
6
7
8
9
10
$running_ubuntu_pids = Get-Process|?{$_.Name -eq "Ubuntu"}|select Id
$count = 1
foreach($uPid in $running_ubuntu_pids){
    $y = ( ($count - 1) * ($screen_height / $running_ubuntu_pids.Count) )
    $h = ( $screen_height / $running_ubuntu_pids.Count )
    Set-Window -ProcessId $app.Id -X $x -Y $y -Width $screen_width -Height $h -Passthru
    # strangely, on some monitors, the first Set-Window doesn't quite take, but setting it again seems to work
    Set-Window -ProcessId $app.Id -X $x -Y $y -Width $screen_width -Height $h -Passthru
    $count++
}

What next?

So far, I’ve only played around with launching and position 2-3 command shells.  If I ever get the urge to launch four or more, I should probably work out the math to position all those shells in a grid-like pattern.  Also, it’d be nice to have a script that launches, positions, and repositions all types of applications, not just my command shells.  Maybe even a script that will memorize the current positions of my applications and use that to reposition them as needed.

Grouping and counting by date

Subtitle: In one line

The other day at work, I had a file of a bunch of activities and the dates on which they occurred.  Something like this:

What I wanted to do was to get a count of the number of activities occurring on each day, so I fired up a PowerShell command shell and ran the following one-liner:


1
ipcsv "C:\my_path\test_data.csv"|group event_date|select Name, Count

That line produced these results:


1
2
3
4
5
6
7
8
Name       Count
----       -----
8/23/2018     10
9/19/2018      8
7/3/2018      18
10/13/2018    15
11/2/2018      9
10/1/2018     15

Nice.  I have my counts, but it’d be even better if my dates were in order.  Let’s try to sort those suckers:


1
ipcsv "C:\my_path\test_data.csv"|sort event_date|group event_date|select Name, Count

That produced:


1
2
3
4
5
6
7
8
Name       Count
----       -----
10/1/2018     15
10/13/2018    15
11/2/2018      9
7/3/2018      18
8/23/2018     10
9/19/2018      8

Not the kind of sorting I was looking for.  It sorted the dates like they were strings.  Wait a minute…


1
2
3
4
5
PS C:\WINDOWS\system32> (ipcsv "C:\my_path\test_data.csv")[0].event_date.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                                          
-------- -------- ----                                     --------                                                                                                                          
True     True     String                                   System.Object

Just as I suspected: PowerShell is importing those dates as strings!  If I want to sort my results by date, I’ll have to cast that date to a proper datetime data type first.  Here’s what I came up with:


1
ipcsv "C:\my_path\test_data.csv"|select -Property @{Name="event_dt"; Expression={[datetime]$_.event_date}}|sort event_dt|group event_dt|select Name, Count

And the results:


1
2
3
4
5
6
7
8
Name                   Count
----                   -----
7/3/2018 12:00:00 AM      18
8/23/2018 12:00:00 AM     10
9/19/2018 12:00:00 AM      8
10/1/2018 12:00:00 AM     15
10/13/2018 12:00:00 AM    15
11/2/2018 12:00:00 AM      9

Nice!  I generated my counts and sorted by date all in one line of code.  Sweet!

« Older posts Newer posts »

© 2024 DadOverflow.com

Theme by Anders NorenUp ↑