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!
Monday, April 23, 2012
git Configuration
Posted by D Chu at 7:27 AM 0 comments
Labels: iOS Development, iOS Training, Subversion
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
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:\ :g
Reference
- My previous bog: VIM Tip: Not Containing Pattern(2)
Posted by D Chu at 9:23 PM 0 comments
Labels: VIM
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
orZERO_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
- VIM Tip: Not Containing Pattern (1)
- VIM Doc: pattern and zero width
- René article on VIM Search
- Regular-Expression.Info: Lookahead and Lookbehind Assertions
- Next blog: VIM Tip: Not Containing Pattern (3)
Posted by D Chu at 8:08 PM 0 comments
Labels: VIM
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.
- Create the @protocol
- Add delegate @property to delegator's public @interface
- Use delegate property inside delegator's implementation
- Set the delegate property somewhere inside the delegate's @implmentation
- Implement the protocol's method(s) in the delegate(include <> on @interface)
@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
- Pauls' blog at SU
- In iTunes: iPad and iPhone Application Development, Fall 2011
- My post to SA question about iOS delegate
Posted by D Chu at 9:29 AM 0 comments
Labels: iOS Training