News for hackers. Stuff that matters.

Show HN: Notational `ls` - Never get lost in code again (hour long hack)

Hey folks, I just wanted to share a quick script I threw together called notational ls. One of the big problems of any code base (or any filesystem) is that it's hard to tell what's what - folder and file names often trade brevity for clarity.

So I thought about a version of `ls` that works like this:

  > nls
    web: Where python web server files are stored
    ad_hoc: One time scripts 
    ios: Our IOS code
    images
Adding descriptions is really easy too:

  > nls images Images SHARED between both ios and web
    web: Where python web server files are stored
    ad_hoc: One time scripts 
    ios: Our IOS code
    images: Images SHARED between both ios and web
So I whipped up said script in python and pushed it to github for all to use. Code is at https://github.com/newhouseb/nls, feel free to fork as you so please, but I must get back to real work. If there's enough interest it'd be great to turn this into a larger effort of improving the small things in our bash lives. If you're lazy, here's the source anyway (github has comments and sane spacing) - enjoy!

  from subprocess import Popen, PIPE
  import sys
  files = Popen(["ls"], stdout=PIPE).communicate()[0].splitlines()
  notes = {}
  try:  
      nls_file = open('.nls').read().splitlines()
  except IOError:
      nls_file = []
  for entry in nls_file:
      file, note = entry.split(':', 1)
      notes[file] = note
  if len(sys.argv) > 1:
      if len(sys.argv) == 2 and sys.argv[1] == 'bootstrap':
          for file in files:
              if file not in notes:
                  notes[file] = ''
      elif sys.argv[1] in files:
          notes[sys.argv[1]] = ' '.join(sys.argv[2:])
      open('.nls','w').write(
          '\n'.join([file+': '+note for file,note in notes.iteritems()]))
  for file in files:
      if file in notes:
          print '\033[1m' + file + ':\033[0m ' + notes[file].strip()
      else:
          print '\033[1m' + file + '\033[0m'
Note: I know this code isn't perfect, but it was a quick job and is what came to mind first and, most importantly, works. If you want to improve it send me a pull request/fork it on github (this is REALLY easy now with github's recent updates).
( 16 comments | 29 points | on HN )
Re:Show HN: Notational `ls` - Never get lost in code again (... by wisty on Tuesday September 06, 2011 @01:27AM (#2964273)
There's a lot of UNIX tools which are user-unfriendly, simply because they were designed not to be chatty. You can't use nls to pump a list of files into another script, which then uses the list of files to do something else useful. Chatty scripts can't be chained together.

Yet, controlling chatty output is something that is already done, with -v (verbosity) levels.

I wonder how much more usable UNIX would be, if -v was on by default, and there was some easy way to disable it when chaining tools.

Re:Show HN: Notational `ls` - Never get lost in code again (... by _delirium on Tuesday September 06, 2011 @06:10AM (#2964945)
Some distros do experiment with that, since it's relatively easy to ship some default aliases. For example, ls is often aliased to some combination of --color, -l, and -h.
Re:Show HN: Notational `ls` - Never get lost in code again (... by drivebyacct2 on Tuesday September 06, 2011 @01:31AM (#2964289)
Usually `-v` is used to increase verbosity in traditional unix applications (ls, mv, cp, etc). Or maybe I'm missing your point.
Re:Show HN: Notational `ls` - Never get lost in code again (... by wisty on Tuesday September 06, 2011 @01:59AM (#2964352)
Corrected - "increase" -> "control".

My point is, UNIX tools are designed to be easy to use by the expert (easy to chain), but hard for beginners (not chatty).

There's also a lot of neglect towards giving users useful feedback, because feedback just doesn't happen by default, so why improve it?

Re:Show HN: Notational `ls` - Never get lost in code again (... by jemfinch on Tuesday September 06, 2011 @01:31AM (#2964288)
`Popen(["ls"], ...)`? Was `os.listdir` (or, if you must, `sorted(fn for fn in os.listdir('.') if not fn.startswith('.'))` too easy?
Re:Show HN: Notational `ls` - Never get lost in code again (... by zokier on Tuesday September 06, 2011 @02:34AM (#2964435)
An interesting solution would be using xattrs to store descriptions. Freedesktop.org has proposed[1] user.xdg.comment attribute, maybe it could be used.

[1] http://www.freedesktop.org/wiki/CommonExtendedAttributes#lin...

Re:Show HN: Notational `ls` - Never get lost in code again (... by qohen on Tuesday September 06, 2011 @01:32AM (#2964291)
Clickable github link:

https://github.com/newhouseb/nls

Re:Show HN: Notational `ls` - Never get lost in code again (... by colanderman on Tuesday September 06, 2011 @01:28PM (#2966367)
Better yet would be to use extended file attributes to store the description with the file itself. See attr(5)/getfattr(1)/setfattr(1). Unfortunately I don't think extended attributes are preserved by most version control systems :/
Re:Show HN: Notational `ls` - Never get lost in code again (... by haliax on Tuesday September 06, 2011 @02:33AM (#2964432)
A find analogue would be a cool extension of this idea: it'd be cross-language tool that shows you the definition of a given function, or where a function is used, or otherwise lets you run simple queries on your code base.
Re:Show HN: Notational `ls` - Never get lost in code again (... by swaits on Tuesday September 06, 2011 @01:26AM (#2964271)

    cat .nls

?
Re:Show HN: Notational `ls` - Never get lost in code again (... by jacknagel on Tuesday September 06, 2011 @03:28AM (#2964548)
Just for kicks, here's a (terribly ugly) pipeline that will display the contents of .nls and `ls`, with duplicates removed:

ls | cat .nls - | column -t -s: | sort -r | perl -ane 'print unless $x{$F[0]}++'

and then obviously just echo "dirname: description" >> .nls to append to the file.

I would be interested in seeing a better pipeline, one that doesn't need perl/awk/ruby/what have you to remove the duplicates correctly.

Re:Show HN: Notational `ls` - Never get lost in code again (... by colanderman on Tuesday September 06, 2011 @01:24PM (#2966354)
The join(1) command is designed to do exactly this:

join -a2 -t: <(sort .nls) <(ls | sort)

(I think this is different from your pipeline, in that your pipeline will print files in .nls that aren't actually in the directory.)

Re:Show HN: Notational `ls` - Never get lost in code again (... by jacknagel on Tuesday September 06, 2011 @03:34PM (#2966926)
Awesome.
Re:Show HN: Notational `ls` - Never get lost in code again (... by newhouseb on Tuesday September 06, 2011 @04:37AM (#2964705)
Oh hey, this is awesome! I thought about doing something like this but then opted for the (ultimately more flexible) python script.
Re:Show HN: Notational `ls` - Never get lost in code again (... by newhouseb on Tuesday September 06, 2011 @01:32AM (#2964290)
Is fine too, but you wont get non-annotated files. nls was designed to work within your normal workflow, i.e. doesn't require you to think about getting file notes in order to get them.
Re:Show HN: Notational `ls` - Never get lost in code again (... by antimora on Tuesday September 06, 2011 @01:04AM (#2964217)
Interesting utility. Just tried it. Thanks.