Wednesday, January 28, 2015

My vimrc - Vim, Part 1

I'm feeling lazy.  So here's my vimrc.  Behold:

_vimrc

syn on
colors koehler

set ic
set incsearch
set hls

set nu
set nowrap

set sw=4
set ts=4

set ai
set bs=2

set tw=0
set colorcolumn=80

set nobackup

autocmd FileType python   set tabstop=4|set shiftwidth=4|set expandtab

autocmd BufReadPost *
    \ if line("'\"") > 1 && line("'\"") <= line("$") |
    \   exe "normal! g`\"" |
    \ endif

On Windows, save it as %USERPROFILE%\_vimrc (that's underscore vimrc).  On Linux and Mac it's .vimrc, and the dot hides the file from view with most utilities.

The Settings

syn onEnable syntax highlighting
colors koehlerColorscheme: koehler
set icIgnore case when searching
set incsearchIncremental search
set hlsHighlight search results
set nuDisplay line numbers
set nowrapDon't wrap lines
set sw=4Compress tabs
set ts=4Compress tabs
set aiAutomatically indent
set bs=2Allow backspaces
set tw=0Auto-wrap (disabled)
set colorcolumn=80Highlight column 80
set nobackupOmit~ annoying~ backup~ files~

Most of these are self-explanatory, but here are some details on selected items.

colors

There are other colorschemes.  They're located in %ProgramFiles(x86)%\Vim\vim74\colors and Torte is a nice one.

incsearch

Move the screen to display search hits as the search string is typed?  Yes, please.


tw=0

This was buried in my vimrc.  With the setting at zero, it is disabled.  But when the setting is something else, Vim automatically wraps lines to keep them at that setting or less in length.  So, if you need to write Linux kernel code (to a strict 79-column limit), this can help keep you in line.

colorcolumn=80

Paint a line down the 80th column.  Again, keeping you in line in case you work with a bunch of kernel code-developing 79-column nazis (Jon, just kidding, actually I respect your coding style).

nobackup

Vim automatically writes annoying backup files named after the file you were editing with a tilde appended to them.  They're a good idea, but they clutter the filesystem, and if you're a web administrator, they leave potential source code disclosure vulnerabilities lying around.

The autocmds

autocmd FileType python ...
Sets tab settings to read and write Python scripts the way most other developers expect them to be read and written.  Since Python is sensitive to whitespace, this can be useful for keeping the files parseable by the Python interpreter.

autocmd BufReadPost *...
Puts the cursor in the position where it was when you last read the file (if you have ever read the file before).

Fin

Lazyblog, signing out.  G'nite.

Sunday, January 25, 2015

Vi Vies with Vim and Vigor (Or, There's No Place Like Home) - Vim, Part 0

This is the first in a series of articles about using Vim.  If you write code or analyze data, but don't use Vim yet, then you should read this, because Vim gives you super-powers.

Before I get to details, a word about the title.  I spent a summer at my grandmother's house, where she taught me to touch-type on a typewriter in her basement.  One of the sentences I had to type over and over again, presumably to learn to reach the letter 'v' without leaving the home row, was:
Vi Vies with Vim and Vigor
You see, my grandmother was a hardcore UNIX hacker, and she knew that to prepare me to use Vi, she needed to teach me to touch-type.  I am infinitely thankful for this.

In this first installation I'll talk about how to make Vim comfortable: some unique ways to get around, how to copy and paste, the repeat / undo / redo operations.  But I'm going to start off with:

Getting Some

Incredibly, you can get Vim for Windows: http://www.vim.org/download.php#pc



Yes, Virginia -- there is a Santa Claus.

If you're on Linux, use your package manager.  I'm mostly going to use gVim (the GUI version of Vim), though it doesn't make a lick of difference in terms of functionality.

Getting Started

If you never have, take 15 minutes out of your life to run through vimtutor.  It's in the Vim install directory.  You don't have to get to the end (I never did).  If you're already ready already, then read on.

Getting Around (Motions)

Aside from h,j,k,l (left, down, up, and right, respectively), Vim offers other motions:

ggmove to top of file
Gbottom of file
H or Ltop or bottom of window
/whatevermove to next instance of whatever (i.e., search)
*move to next instance of whatever is under cursor
:3move to third line
wmove to the next word
b or emove to beginning or end of word, or next word in the corresponding direction
( or )move to beginning or end of sentence
{ or }move to beginning or end of paragraph
gj"go" down one wrapped line
n or Nmove to next or previous search match
%matching parenthesis, brace, or bracket

These are just a few that I find interesting and useful.  The most interesting things that can be done with motions, though, are edits.

Motion Sickness

Motions can do some pretty cool stuff.  For example, >} will indent all the contiguous lines below the cursor until an empty line is encountered, dn will delete until the next occurrence of the last search, and ggyG will copy the entire buffer.

Although not strictly "motions" per se, there are other selection techniques.  For times when you don't know exactly what you want to select for a particular edit, you can use the v command to enter visual select mode, then move the cursor around as much as you want.  Hit Esc to cancel the selection, or use y to yank (copy) it or d to delete it.

You can also select the word, sentence, or paragraph your cursor is in the middle of, with the aw, as, and ap selections.  For instance:

caw"change a word", moving the cursor to the beginning of that word
ci"change everything in the quotes surrounding the cursor (shout-out to huf for sharing that one)
das"delete a sentence", removing everything between the last and next period
yap"yank (copy) a paragraph"

Where does stuff go when you copy or delete it?

Registers

When you yank (y) or delete (d) text, it is automatically saved for you to paste (p) again.  The place where it is saved is like a clipboard that only Vim can see, and it is called a register (specifically, the unnamed register).  In Vim, registers are named memory locations into which data can be copied (where you specify the register with the " command modifier) and macros recorded (where you specify the register with the q command).  So, you can copy one line -- "ayy -- and then copy another -- "byy -- without losing either copy.  Paste them by typing "ap and "bp respectively.  Deletion works the same way, and there is a "black hole" register named _ (underscore) that allows you to delete stuff without clobbering something you just copied to the unnamed register.  So, you can copy a line into the unnamed register -- yy -- and delete a line into the black hole register -- "_dd -- and then paste the line you originally copied -- p.

Vim has help on all its commands.  For instance, I typed :help "_ to figure out what the "_ register was called, and I found this:

There are nine types of registers:   *registers* *E354*
1. The unnamed register ""
2. 10 numbered registers "0 to "9
3. The small delete register "-
4. 26 named registers "a to "z or "A to "Z
5. four read-only registers ":, "., "% and "#
6. the expression register "=
7. The selection and drop registers "*, "+ and "~ 
8. The black hole register "_
9. Last search pattern register "/

I've already mentioned the unnamed register (1) that is used by default, the named registers (4) that you can choose when to use, and the black hole register (8) that you can use to avoid overwriting the last copy or delete that you did.  The only other one I use is the clipboard register, "+ which I can use to transition into a whole new section...

Sneaking Stuff Into Vim

To finish off the discussion of registers and start the discussion of getting data into Vim, here's the "+ register.  Supposing you've copied something in another app, you can type "+p to paste it in Vim.  Likewise, if you want to copy a paragraph to the clipboard in Vim, you can type "+yap and then paste it into any other application.  You can also :read files into your buffer by name, or execute !!commands to get their output into Vim.

Doing it... Over and Over Again

Suppose you want to do it again.  And again.  And again.  You use . (dot) for that.  For instance, I've got a list of servers that I need to surround in quotes and make comma-separated for some sort of configuration file.  Here's what I'll do:

  • Go to the first line and line insert a quote at the beginning - I"<Esc> 
  • Go to each line and repeatj. (note the trailing dot)
  • Go to the beginning - gg 
  • Append a quote and a comma to the first line - a",<Esc> 
  • Again, go to each line and repeatj. (again, note the trailing dot)
  • For the finale, I'll go to the top, visually select to the bottom, and join all - ggvGJ 
Because I'm an exhibitionist, I took a grainy, low-quality video of me "doing it over and over again" -- inserting quotes and commas, that is:


Undo and Redo

An editor wouldn't be complete without undo and redo.  Undo is obvious: hit u to undo something.  Redo is less obvious (and requires pinky contortions): hit <CTRL>-R to redo something that was undone.

Sometimes I need to undo a few times to see what you did.  And sometimes I use this to undo everything and progressively redo changes when I've totally botched something in my code.  You just want to save the latest to a backup in case you make the mistake of making a change (thus obliterating the redo buffer) before you fast-forward all the way to the idiotic assumption that caused all your pain in the first place.  The procedure usually goes something like this:

  • Add a thousand lines of "great" code and re-factor the hell out of my project
  • Compile, test, and cry because it used to work
  • Save my "brilliant" changes - :w backupfile 
  • Undo everything - 99999u 
  • Repeatedly redo in order to review changes and catch my mistake - <CTRL>-R 
  • Replay all the other (good) changes so I can go back to line 269 and add a $#@*! semicolon - 99999<CTRL>-R 

Fin

So there's part one.  Part two is forthcoming, and will include more slick stuff -- hackin' up binaries, scripting, writing shellcode...  Stay tuned.

Tuesday, January 20, 2015

Windows man pages

If you're a UNIX or Linux person, you know Windows lacks man pages.  So man up and make some.

Create a directory and add it to your path.  Call it man, help, or whatever.

Every time you run into a command whose usage and arguments you need to know, run it with the /? switch and redirect its output into a file in that help directory.

FOR /? > %USERPROFILE%\help\for.txt

Now you've got a file in your path that says this:

Runs a specified command for each file in a set of files.

FOR %variable IN (set) DO command [command-parameters]

  %variable  Specifies a single letter replaceable parameter.
  (set)      Specifies a set of one or more files.  Wildcards may be used.
  command    Specifies the command to carry out for each file.
  command-parameters
             Specifies parameters or switches for the specified command.

To use the FOR command in a batch program, specify %%variable instead
...

Then, the next time you need help on the for command, hit Win+R, type for.txt, and press Enter.  The saved help will pop up immediately in Notepad, because you added the help directory (or whatever you called it) to your path.  You can also use it to stash past examples if you're running or scripting particularly complex commands.

Presto.  Man pages.  Now quit yer whining.

Sunday, January 18, 2015

This One Weird Trick the Visual Studio Team Doesn't Want You to Know!

I find it fascinating that most Windows boxes (these days, I can almost say all of them) have CLR compilers sitting around on their hard drives.  This would make it possible for people to experiment with C# and VB.NET without downloading squat...  But Microsoft forgot to do one thing: set up some file associations.  So this is a write-up on how to set them up in a quick and dirty fashion on any computer so that you can experiment with C# and VB.NET without having to download Visual Studio.

I don't like Visual Studio anyway, probably because I don't work on enterprise stuff.  I shamelessly admit that my codebase is a collection of cheap hacks, and my goal is to be able to crack open an editor, vomit out fifty or a thousand lines of code, execute my tests, and get on with my day.  I also get a smug sense of satisfaction and independence from eschewing an IDE, kind of like choosing to drive a manual transmission car.  (Why don't I use Linux, then?  Quiet, you.  It's because of software requirements.)

So, with no further ado, I present:

Visual Stu-DIY-o

For the impatient, here is the quick and dirty TL;DR:

assoc .cs=CSharpSourceFile
ftype CSharpSourceFile=%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe %1
reg add hkcr\CSharpSourceFile\Shell\edit\command /ve /d "%WINDIR%\System32\notepad.exe %1"

But your .NET compiler might not be located there, or your code warnings and errors may zip by and disappear, or your executable may not get built, or you may have wanted to program VB.NET, et cetera.  If you care about such things, then go through the exercise of locating your compiler, creating a friendly compiler script, and associating that with your source files.  Read on for more.

Find your .NET compiler of choice

You're really just confirming what version you have.  You're doing this because you want to be sure the files exist before you copy and paste the script below.  Fortunately, this is easy, because it's in your path:

  1. Hit Win+R (to get the run dialog)
  2. Type Microsoft.NET
  3. Leap of faith: press Enter
  4. Browse to the Framework\v4.0.30319 directory
  5. Note the absolute path to csc.exe (hint: hit ALT+D, hit End, finish off that directory name with a backslash, and start typing csc, and it will let you auto-complete the path in the address bar; copy this address for later).

A little note: I use the Framework (and not Framework64) directory because I want my MSIL to run in 32- and 64-bit environments.  For my normal projects, I use .NET version 4.0, and for software that must be deployed to mixed and potentially un-maintained platforms (if I told you why, I'd have to kill you), I target .NET 2.0.  Lastly, I use C#, but you don't have to.  At this point, if you want to locate vbc.exe instead (That's the VB.NET Compiler), go ahead and replace csc with vbc.  I won't judge you.  Just remember to actually replace what I put in the script below with the path to vbc.

At this point, we could set the file association directly with the compiler, as in the "TL;DR" section above, but if you double-click your .cs (or .vb) files, and your source code has warnings or errors, a mysterious black box will appear and disappear before you have a chance to review and fix them.  That's why you're going to bother with the next step:

Write a quickie script

Choose a place where this script will live.  Make a "util" or "bin" or "scripts" directory somewhere in your user profile if you don't already have one.  Open Notepad, copy and paste what is below (replace the path to csc if you are targeting a different .NET version, architecture, compiler, etc.), and save it as something.  I chose buildcs4.cmd.  In the Save As dialog, under "Save as type", don't forget to select "All Files (*.*)" so that it does not "helpfully" append the .TXT file extension for you, thus neutering your command script.  Here's my version:

@ECHO OFF
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\csc.exe %*
PAUSE

The PAUSE command is there so you can see the warnings before the script closes.  You can't use an IF ERRORLEVEL command to pause for warnings, because the compiler only returns 1 or greater if there are errors, not if there are warnings, so that is why I include an unconditional PAUSE.  %* tells the command interpreter to pass along all the arguments from the command line.  This is how the filename you double-click will be passed to the C# compiler (or VB.NET compiler, if that's your predilection).

Finally, make the file association

Open an administrative command prompt and invoke these three incantations:

assoc .cs=CSharpSourceFile
ftype CSharpSourceFile=%USERPROFILE%\path\to\buildcs4.cmd %1
reg add hkcr\CSharpSourceFile\Shell\edit\command /ve /d "%WINDIR%\System32\notepad.exe %1"

These define a filetype, set a file association, and add an "Edit" context menu command, respectively.  For more background on all that, type ASSOC /?FTYPE /?, and REG /? on the command-line.

Taking it for a Spin

If you want a test, here's a nice C# sample you can paste into notepad.  I think the traditional hello-world example is pretty boring, so here's something to spice up someone's life:

using System;
using System.Windows.Forms;

class mbox
{
    static public void Main()
    {
        MessageBox.Show(
            "Delete C:\\ - are you sure?",
            "Confirmation",
            MessageBoxButtons.OK,
            MessageBoxIcon.Warning
           );
    }
}

Now save that as hello.cs, and double-click it to compile.  Run the resulting hello.exe to see the result.



Right-click hello.cs and choose Edit when you want to mess about some more.  Aaaaaand, we're done.

Tuesday, January 13, 2015

Windows su and sudo

Wherein I describe a marginal hack for creating su and sudo utilities for Windows.

Frequently I want to get right to work adjusting services configuration with sc.exe.  Or, I might not even need a command prompt in order to figure out what I need -- sometimes I just want to run SysInternals' Process Explorer as an administrator so I can read the thread information and get on with my life.  In these instances, it usually breaks my concentration to now have to go open the system32 folder, locate cmd.exe, right-click it, and click Run as administrator.

Wouldn't it be nice to just be able to hit Win+R (to invoke the Run dialog) and type:

su

...or...

sudo procexp

?

I think so.  And to that end, here is how to set that up.

Elevated Command Prompt (su)


Open a directory that is in your path.  For example, hit Win+R to get the Run dialog, type . (that is a dot), and press return -- most likely, your user profile directory will open.

Right-click an empty area in this directory and click New > Shortcut.

In the location editbox, type %COMSPEC% (which is an environment variable that expands to the location of cmd.exe):


Click Next.  In the name editbox, type su:


Click Finish.  Now, right-click the new file, su.lnk (it will appear as simply su if you do not have Windows Explorer configured to display file extensions).  Under the Start in editbox, you may choose to type %USERPROFILE% or another location so that you start out in the directory of your choosing instead of C:\Windows\System32:


Click the Advanced...  button.  Check the Run as administrator checkbox.  Click OK twice.


Once this is done, if you created the shortcut in a directory that is in your path, then you should be able to hit Win+R, type su, press Enter, acknowledge the UAC dialog, and immediately have an elevated command prompt.

Elevated Single Command (sudo)


For sudo, you will need a shortcut that can accept a parameter to be run as an elevated command.  Copy and paste the shortcut from above, renaming it sudo.  Right-click the shortcut and in the Target editbox, type %COMSPEC% /c start ""


Don't neglect the pair of double quotes -- I'll explain later.  Save the shortcut, and now you can hit Win+R, type sudo procexp (assuming SysInternals' Process Explorer is in your path) and spawn a privileged instance of Process Explorer without having to go find the executable, right-click on it, and select "Run as Administrator".

There you have it.  The su and sudo commands, for Windows.

A Digression


Okay, you might already know that cmd.exe /c will run the command interpreter and execute the command that is specified after the /c switch.  But you might be wondering why the pair of double quotes is necessary after the START command.  As with everything else in Windows, it is because the command interpreter and its minions are made of pain.

If you don't specify these empty quotes, then some day you're going to run sudo followed by something surrounded in quotes.  That day, you will have to go manually start your privileged whatever-the-hell-you-were-doing, because the start command interprets the first quoted string it sees as a title to be displayed in the console window hosting the command interpreter.  So, on that day, start will swallow your argument to sudo and never find any actual command to run.  Then, it will exit immediately, leaving you wondering when the hell tcpview is going to pop up.  Did you have a late night, tcpview?  Are you coming in to work today?  No.  The START command ruined everything.  Because that's what Windows commands do.  They ruin everything.

If you don't believe me, take a look at the first few lines of the help output from the START /? command:


Starts a separate window to run a specified program or command.

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
      [/NODE ] [/AFFINITY ] [/WAIT] [/B]
      [command/program] [parameters]

    "title"     Title to display in window title bar.

It's subtle, isn't it?  And because the actual help for this command is over a hundred lines long, it might take you a while to put two and two together.

Just be glad we're having this conversation so you can move on with your life.  Speaking of which, I've got some sudo commands to run.  Peace.