
Show HN: Notational `ls` - Never get lost in code again (hour long hack) - newhouseb
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.<p>So I thought about a version of `ls` that works like this:<p><pre><code>  &#62; nls
    web: Where python web server files are stored
    ad_hoc: One time scripts 
    ios: Our IOS code
    images
</code></pre>
Adding descriptions is really easy too:<p><pre><code>  &#62; 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
</code></pre>
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!<p><pre><code>  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) &#62; 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'
</code></pre>
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).
======
wisty
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.

~~~
drivebyacct2
Usually `-v` is used to increase verbosity in traditional unix applications
(ls, mv, cp, etc). Or maybe I'm missing your point.

~~~
wisty
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?

------
jemfinch
`Popen(["ls"], ...)`? Was `os.listdir` (or, if you must, `sorted(fn for fn in
os.listdir('.') if not fn.startswith('.'))` too easy?

------
zokier
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...](http://www.freedesktop.org/wiki/CommonExtendedAttributes#line-38)

------
qohen
Clickable github link:

<https://github.com/newhouseb/nls>

------
colanderman
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
:/

------
haliax
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.

------
swaits

        cat .nls
    
    ?

~~~
jacknagel
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.

~~~
colanderman
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.)

~~~
jacknagel
Awesome.

------
antimora
Interesting utility. Just tried it. Thanks.

