Monday, April 23, 2012

git Configuration

I have not used git for my source code repository on my Mac. Today, I realized that git is not available in my Terminal. Actually, after googling, I found that git is in my Mac, but not in my PATH.

The git sits in my /usr/local/git folder.  The binary tool is at bin there. So I need to add git to my PATH. This can be done by vim editor:

vim ~/.profile

Add or update the following line:

export PATH="$PATH:/usr/local/git/bin:"

Save the change and exit VIM.

Run the following command to load the path from .profile:

source ~/.profile

Now the git is available in Terminal!

Read More...

Friday, April 13, 2012

VIM Tip: Not Containing Pattern (3)

I find out that Lookaround zero width assertions are very powerful and useful. The more I use it the more I like it. Think this search strategy as match a pattern with addition zero width or hidden pattern together.  This can filter some parts out, which cannot be done just by matching a pattern.

I have used this technique resolving many of finding and replacing issues. Normally, I use search first to make sure the results meeting my expectations. Then I use replacement to substitute the results with my expected contents. Here are some examples. As you can see that it is very productive. For sure, it does require a lots of brain energy to think and to try hard. However, this will sharp you brains. I really enjoy learning and using VIM.

Examples


Let take pseudo codes I used in my previous blog as example. A simple search is to find character 's', and the next character is 't' as zero width, look ahead.  The search command is:

/st\@=

This tells that first token is 's'. The search engine searches for the token as a pattern. When it is found, the engine stops at the found position in the string. Then, the engine looks for the next token 't'. The look-ahead tells the engine to construct the next search for the second token from the substring afterward the first token.  The engine continues to search for the second token as an immediate match. If there is a match, the complete pattern is found. The first token 's' is a matched result as return; if there is no match, the match is failed.



The next simple example is look-behind zero width assertion command:

/\(s\)\@<=t

The pattern to be matched is 't', which is also the first token. The second token is a group of characters 's'. When the first token is found, the search engine stops. The look-behind tells the search engine to take the substring behind as the next search from this position.  If the match (second token) is found right behind the position, a complete match successes, and the first matched token is returned as a result. The following snapshot shows three results of 'ring's:



More Complexed Examples


The following text are some blocks of foo...bar:

foo
  test baz
  something for you
  gave me your beer
bar

foo
  test ba
  something for you
  gave me your beer
bar

foo
  test bae
  foo
  something for you
    gave me your beer
  bar
bar

Here is a command of searching for foo...bar block containing 'baz':

/foo\(\_.\{-}baz\)\@=\_.\{-}bar

Notice that the text within the foo...bar block may contain multiple lines of text. Here \_. is for multi-lines of text. \{-} is none-greedy match, which means matches 0 or more of the preceding atom, as few as possible.  The above search can be described as searching for:

'foo' as start, next zero width pattern: 0 or multiple lines of text till 'baz', then 0 or multiple lines of text till hit 'bar'



You may verify the command by break the search command into two parts, the first part is:

/foo\(\_.\{-}baz\)\@=



The command of searching for foo...bar loop not containing 'baz':

/foo\(\_.\{-}baz\)\@!\_.\{-}bar



Search for the most inner foo...bar block command:

/foo\(\_.\{-}foo\_.\{-}bar\)\@!\_.\{-}bar



Sometimes, I want to add line break tags to the end of a line, but not to the empty lines.  This command can be used to add <br /><br /> to the end of any none-empty lines:

:%s:.\@<=$:<br/><br/>:g



The next example is a very useful one. I often use VIM convert program codes into HTML format. Some times, I need to convert a group of spaces into &nbsp;s, except the first space. This is an excellent case to use lookahead zero width assertion. I figure it out and it becomes my favorite the search and replace commands.

/\(\s\)\@<=\(\s\)\+



After examining the results, I use the following replacement command to do the conversion:

:%s:\s\@<=\s:\&nbsp;:g



Reference


Read More...

Friday, April 06, 2012

VIM Tip: Not Containing Pattern (2)

In my previous VIM tip blog, I mentioned about searching for a pattern of a expected word with not expected word afterwords, for example, 'tablespace' followed by a word not starting with 't'. When I tried to the pattern in an opposite way, I could not figure out how to do a match. For example, a word not starting with 't' followed by a word of 'tablespace'.

I think that I figure it out now, but it took me a while to google and digest the related information. I think it is worthwhile to study this. I am writing this blog to summarize my findings.

Lookahead and Lookbehand Zero-width Assertions


At first I thought about match a pattern not containing another pattern should be as simple as using a negate or ! operator to identify not-containing-pattern. There may be a not operator in VIM search, but I could not find it. What I found is Lookaround Zero-width Assertion.

In VIM, the way of search for a pattern not containing another pattern is very smart and elegant. The basic search is to find all matched patterns, and the matched items are returned as results. In VIM, the following is a search command:

/PATTERN

the pattern can be a regular expression.

In VIM, zero width pattern is a pattern to be matched but not in the search results. Think zero width pattern as additional match condition, it can be described as either of following ways:

PATTREN + ZERO_WIDTH_ATOM or
ZERO_WIDTH_ATOM + PATTERN

The first one is called as lookahead zero width assertion, and second one as lookbehind zero width assertion. Assertion here means matched or not matched. The above two are positive assertions. If we take negative or not matched into consideration, there are four types of look around with zero width assertions. They are:

/PATTERN[ZERO_WIDTH_ATOM\@=]
/PATTERN[ZERO_WIDTH_ATOM\@!]
/[ZERO_WIDTH_ATOM\@<=]PATTERN
/[ZERO_WIDTH_ATOM\@<!]PATTERN

Note: [...] is used as optional and also as separator from pattern, [ or ] are not part of search.

As my understanding, VIM uses symbolic like character for look around. As other special characters in VIM, \ is used to indicate look around with zero width assertion. The following table summarizes characters used for this type of search:

\@  indicate lookahead
\@<  lookbehind
=  positive match
!  negative or not match.

In above searches, PATTERN is to be matched. If ZERO_WIDTH_ATOM is supplied, it will be used as additional assertion. If there is any match, the matched pattern items will be returned as results, but ZERO_WIDTH_ATOM is not in the results. That's why it called as zero width.

According to VIM documentation, the definition of ATOM is a character, or a character class, or a group (indicated by \(...\) braces).

Think the Search as a Program


Lets think those type of searches as a program. Here I have the following c-style pseudo codes:

Results getMatchedResults(
   string context,               // basic
   string pattern,
   string zero_width_pattern,    // zero_width pattern
   bool match_zero_width_pattern,
   bool lookahead)
{
  results = EMPTY_LIST;
  result = getMatchedResult(context, pattern);
  while (result != EMPTY)
  {
    if (zero_pattern != EMPTY)
    {
      if ( lookahead ) {
        context_tmp = getNextContextByLookahead(context, result);
        result_tmp = getMatchedResult(context_tmp, zero_width_pattern);
      } else {
        context_tmp = getNextContextByLookbehind(context, result);
        result_tmp = getMatchedResultByLookbehind(context_tmp,
                       zero_width_pattern);
      }
      if ( result_tmp == EMPTY ) {
        if (match_zero_width_pattern) {
          result = EMPTY;
        }
      } else {
        if (!match_zero_width_pattern) {
          retult = EMPTY;
        }
      }
    }
    if ( result != EMPTY ) {
      results.add(result);
      context = geNextContextByLookahread(context, result);
      result = getMatchedResult(context, pattern);
    }
  }
  return results;
}

The pseudo codes are very straightforward. Actually, VIM search is based on Regex as its search engine. The above search expression commands are basic Regex patterns.


References


Read More...

Sunday, April 01, 2012

Steps to Delegate in iOS

I am back to the course of iOS Development by Stanford University. Last week, I watched Lesson 9 Table Views(October 25, 2011). Instructor Paul Hegarty mentioned 5 steps about Delegate at 1:04:15.

He talked the confusion for new developers when they use protocols.  The 5 steps are clear explanation on how to use and implement protocols. He also showed the steps in his demo.



  1. Create the @protocol
  2. Add delegate @property to delegator's public @interface
  3. Use delegate property inside delegator's implementation
  4. Set the delegate property somewhere inside the delegate's @implmentation
  5. Implement the protocol's method(s) in the delegate(include <> on @interface)


In the demo, the protocol CalculatorProgramsTableViewControllerDelegate is created in CalculatorProgramsTableViewController.h:

@class CalculatorProgramsTableViewController;

@protocol CalculatorProgramsTableViewControllerDelegate

@optional
- (void)calculatorProgramsTableViewController:(CalculatorPorgramTableViewController *)sender
                                 choseProgram:(id)program;
@end

In CalculatorProgramsTableViewController.h, the delegate is created in the controller as weak id <...> delegate:

@interface CalculatorProgramsTableViewController : UITableViewController
...
// Define a property delegate
@property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate> delegate;
...
@end

In its .m file, the delegate property is defined by @synthesize delegate = _delegate.

@implementation CalculatorProgramsTableViewController
...
@synthesize delegate = _delegate;
...
@end

In the event of a row cell being selected, the delegate is used:

#progma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView
    didSeelectRowAtIndexPath:(NSIndexPath *)indexPath
{
  id program = [self.programs objectAtIndex:indexPath.row];
  [self.delegate calculatorProgramsTableViewController:self
                                          choseProgram:porgram];
}

Next, where the delegate is set? in the event of controller segue. The delegate method is implemented in the controller:

@implementation CalculatorGraphViewController
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue
                 sender:(id)sender
{
  if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) {
    NSArray * programs = [[NSUserDefaults standardUserDefaults]
      objectForKey:FAVORITES_KEY];
    [segue.destinationViewController setPrograms:programs];
    [segue.destinationViewController setDelegate:self]; // set delegate
  }
}

Lastly, in order for the graphic view controller to know the change of a program, the controller has to implement the delegate method. The protocol method will be called when the delegate sends out its message: a row in table view being selected:

// in .h file, the protocal delegate is defined as the controller's interface
@interface CalculatorGraphViewController : NSOjbect
             <CalculatorProgramsTableViewControllerDelegate>
...
@end

//In .m The protocol method is implemented
- (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender
                                chooseProgram:(id)program
{
  self.calculatorProgram = program;
}

"That's all we need. OK!", Paul said.

References


Read More...