Showing posts with label vim. Show all posts
Showing posts with label vim. Show all posts

Thursday, October 15, 2009

10 things plain text excels in

Plain text is the simplest text format in the world. It is called plain in contrast with sophisticated formats like Doc, Odt, Pdf and so on. I work with this universal format a lot and I want to share some tasks it can be useful for.
Plain text is based on representing characters as a single stream per file, using a byte for every character (or from one to sixfour bytes if you're using UTF encodings). There is no font choice in plain text, nor any formatting: the focus is on the content and in its logic. When you open windows notepad or vim, you get an example of plain text editor. Stripping out all the presentation logic is in some cases a good thing, as it simplifies the management of data and content.

There is a chapter in The Pragmatic Programmer: From Journeyman to Master (the first Pragmatic bookshelf title) that is titled Power of plain text, and where the advantages of text files upon binary formats are discussed: there is no obsolescence of plain text and one can leverage every kind of existing tool being secure that it can handle plain text. Plain text in UTF-8 will be still readable thirty years from now.
In fact, one of the Unix philosophy pillars is:
Write programs to handle text streams, because that is a universal interface. -- Doug McIllroy
There is no limit to what you can do with data in plain text, because you can chain together hundreds of unix programs which will work seamlessly. In a Unix system, no configuration files work with a unit smaller than a byte: all directives are kept in plain text files, in a structured but human editable form.

As an example, I put together a list of what I am using plain text for. When I really thinked about it the first time I was impressed and pleased:
  • Todo lists: a list of tasks I have to complete in the near future, divided in Urgent/Important/... sections. Since it is a list, items has a "-" before them and I can indent subpoints by using more than one hyphen, like in -- subtask or --- subsubtask". To mark a completed item and gain confidence, I substitute the hyphens with "+", maintaining indentation. Using vim, it is also fairly simple to reorder items or to mark them with a macro.
  • Specifical todo lists: I have one todo list for this blog, for example. A general list can grow too much for being still manageable, so it's a good choice to gather Todos for particular projects in their own list. This is somewhat similar to the Getting Things Done project actions management, but at a simpler level since I do not need a more elaborate one.
  • Source code: this is pretty obvious, but I wanted to point out that source code is usually plain text.
  • Lists of any kind: for example, books I want to read or to find reviews for.
  • Svn diffs and patches: when submitting a patch to a project like Zend Framework or Doctrine, the process involves checking out the Subversion working copy and making the changes needed for addressing a bug or adding a feature. Then, if you do not have commit access, svn diff > myfix.patch saves the changes in a patch you can upload to the bug tracker for evaluation. Patch format builds up on plain text, but it's still readable and before committing on my projects I usually run a svn diff | more to explore the changeset (another example of plain text as a universal interface).
  • Goals: it is mandatory to write your goals for the short and long term, if you are serious about achieving them. Plain text is a good choice since you can find everywhere the programs to edit them, even five years from now.
  • Blog posts: when writing a new article, I start with a blank vim screen (maybe I should use a template) and write all the content, the most important part of a post. Formatting and images are inserted while putting the post online and proofreading it, and emphasis on words and phrases can be specified by '' or * marks.
  • Email: text emails are more portable than html ones and can be forwarded and quoted easily.
  • Wiki articles: when I edit a wiki article, not only on wikipedia but in any wiki, I use wiki formatting, which is a superset of plain text. I have included this usage since wiki formatting is very readable and can be used without a subsequent "real" formatting phase, for instance for lists like my Todo ones.
  • Schedules: I might use Google Calendar in the future, but now that I'm trying out scheduling my working days a simple text file named 2008-10-15.txt is perfect.
The format for simple scheduling is simple:
08:00   wake up&breakfast
08:15   mail&reader
08:30   nakedphp user stories estimation
...
Tabulations, even when using spaces instead of \t characters, are very useful to align text and provide spreadsheet-like capabilities. In the schedule case, I only specify the tasks for the next day so one file it's enough.
There are only two problems that can surge with plain text: encodings and newlines. Specifying UTF-8 and what type of newlines (LF, CRLF, or CR) will make your text files universal and consistent. Compare this requirements to the ones for working with docx files.

While I advocate that web applications are the future choice for many tasks, I have never abandoned plain text. When testing out some new practice like writing goals or maintaining an effective Todo list, I always start from plain text. This way if it simply does not work for me or I am not satisfied with the results, I'll simply delete a folder on my pc. No need to register to powerful web applications such as Remember The Milk: I'm sure it works pretty well for TODO lists and it's globally accessible by every machine connected to the Internet, but I am not ready at the moment. I'm only exploring possibilities, with a next-to-zero cost in time: I only have to open vim or gedit.
Now before registering to dozens of web services, think about using plain text for your lists, goals, schedules... Often the simplest solution is overlooked.

This is by no means an encouragement to write a book in plain text: use complex formats for complex tasks, because they will pay back their heaviness.

Tuesday, October 06, 2009

Getters and setters in vim

While writing an entity class, it's likely you have to manually write a bunch of methods to modify the state of the object, such as setName(), getName(), setDescription(), etc... It is very simple to setup vim, the powerful editor, for setters and getters prototyping, allowing you to tweak them after the one-time generation to add constraints on the parameters and docblock annotations. The boilerplate code for getters and setters can be very boring to write and this tutorial can save you quite some time if you invest a little in setting up this system.
In this how-to I will cover the php case, but feel free to change the template code for the language you want to use.

Disclaimer: I am not suggesting every class should have getters and setters; quite the contrary. In my opinion only certain classes whose responsibility is to maintain state should have these kind of methods, while stateless services should have no getters and no setters as their collaborators are wired in the constructor.

Step 1: vim snippets system
The first step to perform is downloading snippetsEmu, the set of vim scripts which provides support for snippet management. snippy_plugin.vba contains the plugin, while the package snippy_bundles.vba consists in out-of-the-box snippets for various languages, from php to python and C.
The workflow with this plugin is straightforward: you type a keyword for the snippet you want to use (for instance "for" or "if") while in Insert mode, and press Tab. Then the template code is inserted and you are asked to insert the variables of this template, filling in the blanks and pressing tab after each specification. Variables consist in identifiers and of every piece of code that cannot be predetermined too.
For instance, once the system is in place, to create a for construct you would type:
for<tab>i<tab>1<tab>10<tab>doSomething();<tab>
and the result will be:
for ( $i=1; $i < 10; $i++ )
{ 
doSometing();
}
Obviously you can tweak the template of the for snippet to accomodate your coding standard. It's simpler to try it than to explain it.
The installation is a quick process: open the downloaded .vba file with vim and type
:source %
while in Command mode. The vimball system will install the scripts in your .vim directory.

Step 2: setting up .vimrc
Now we need to include the scripts and define the getters/setters template every time vim is started. To do this, we can use the .vimrc hidden file in your home directory, which is read at vim's startup and whose commands are executed as if they were typed in vim Command mode.
These are the lines you need to add to .vimrc for php getters and setters support:
set tabstop=4
set shiftwidth=4
set expandtab
set autoindent
setlocal comments=sr:/*,mb:*,ex:*/
setlocal fo=cqort
source ~/.vim/plugin/snippetsEmu.vim
source ~/.vim/after/ftplugin/php_snippets.vim
exec "Snippet getset /**<CR>@return ".st."Type".et."<CR>/<CR>public function get".st."Name".et."()<CR>{<CR><Tab>return $this->_".st."name".et.";<CR><BS><BS><BS><BS>}<CR><CR>public function set".st."Name".et."($".st."name".et.")<CR>{<CR><Tab>$this->_".st."name".et." = $".st."name".et.";<CR><BS><BS><BS><BS>}<CR>"

The first lines tell vim to use the tab expansion and replacing all tabs with four spaces as said in the Zend Framework coding standard, which is my style of choice for php development. Other settings include auto indentation of lines and auto generation of * in case a docblock comment new line is created. You may want to not use these settings, but you'll have to edit the snippet line accordingly.
The two source commands import the plugin and the php snippets respectively. The second import is necessary to define the shortcuts st and et (start tag and end tag) used in snippets definition.
The last line set up a template for a snippet named getset. To use it, open vim and go to the line where you want to put the couple of methods getSomething() and setSomething(). Then go in Insert mode and type getset<Tab> and compile the various parts of the template, pressing tab after every template variable insertion. Note that you need to define a variable only once, which will be substituted in every place where it appears.
Again, feel free to adapt the snippet to your programming language and coding style. Note that there are no new lines in the template: they are inserted with the <CR> command which simulates the pression of the Enter key. The definition must be kept on one line.

I hope this tip can speed you up while writing boring getters and setters code. If you decide to create new useful snippets, let me know in the comments.

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts