- git
which git # /usr/bin/git
/applications/xcode.app/contents/developer/usr/bin/git version # 2.37.1
q # quit
# git commit --amend --author "John Marquez <john@dev.com>"
# delete the last commit (revert)
# http://christoph.ruegg.name/blog/git-howto-revert-a-commit-already-pushed-to-a-remote-reposit.html
# git reset HEAD^ --hard
# config
git help config
git config --list # -l
git config --unset branch.foo.remote
git config --unset branch.foo.merge
git config --global user.name
git config --global user.email
git config --global user.name "john"
git config --global user.email "john@dev.com"
# git gc # cleanup
git branch -r # list remote branches
# git branch -r -d origin/demo # delete remote branch
# git remote prune origin --dry-run # delete all stale remote-tracking branches
git branch -m <oldname> <newname> # rename from any branch
git branch -m <newname> # rename current branch
git status
git status --short # -s
git log -n3 dev/app/lib.mm # git log for file, last n commits, filename is case sensitive
git log -n2 # Sun Oct 5 12:00:00 2014 -0600
git log -n2 --date=local # Sun Oct 5 12:00:00 2014
git log -n2 --date=short # 2014-10-05
git log -n2 --date=iso # 2014-10-05 12:00:00 -0600
git log --name-status
git log --name-status --author=kbcat --merges -n2
git log --name-status --author=kbcat --no-merges -n3 dev/app/file.c
git log --name-status --no-merges -n3
git log --name-only
git log --stat
git log -n3 --pretty=format:"%cd %h%n%s%n-------" --date=local # Sun Oct 5 12:00:00 2014
git log -n3 --pretty=format:"%cd %h%n%s%n-------" --date=iso # 10-05 12:00:00
| sed -e 's/2014-//'
| sed -e 's/ -0600//'
git log --abbrev-commit
git log --abbrev-commit --pretty=oneline
git log --abbrev-commit --pretty=oneline --author=kbcat
git log --abbrev-commit --pretty=oneline --author=kbcat dev/app/file.c
git log --abbrev-commit --pretty=oneline dev/app/file.c
git log --diff-filter=A --name-status # Added
git log --diff-filter=D --name-status # Deleted
git log --diff-filter=M --name-status # Modified
git log --diff-filter=R --name-status # Renamed
git log --diff-filter=AD --name-status # Added or Deleted
git log --before="2017-01-01"
git log --grep="bug" # match commit message
git log -Sfoo # find string occurrences +-
git show HEAD
git show HEAD~
git show HEAD~2
git show HEAD~3
git show f000000
git show f000000 dev/app/file.c
git show --name-status f000000
git show --pretty="format:" --name-only # last commit
git show --pretty="format:" --name-only f000000 # commit
git show --pretty="format:" --name-only stash@{0}
# show all commits in feature branch that are not in main branch
git log main..dev/fb
git log main..dev/fb --no-merges
# add files
git add -A # stage all
git add . # stage mod and new
git add -u # stage mod and del
git add dev/app/lib.*
git checkout -b fb1
git checkout stash
git checkout stash@{1} dev/app/file.c
git checkout stash@{1} -- dev/app/file.c
git checkout f000000 dev/app/file.c
git checkout -b temp stash@{1}
git cherry-pick f000000
git cherry-pick --no-commit f000000 # -n
git cherry-pick --edit f000000 # -e
git tag -a v1.0 -m "..."
git tag -l # list all tags, default shows 1 line of tag message
git tag -l -n3 v1.0 # show 3 lines of tag message
git show v1.0
git push origin [tagname]
git push origin v1.0
# update
git remote show origin
git fetch
git pull
git diff stash # diff working dir w/stash
git diff dev stash@{1} # diff dev branch w/stash
git diff stash@{1} file.c # diff file in working dir w/stash
git diff stash@{1} stash@{0} # diff stash 1 w/stash 0, most recent last
git diff stash@{1} stash@{0} file.c # diff file between stash 1 and stash 0
git diff f000000 f000001 -- file.c # diff file between commit x and commit y
git diff --staged
// git diff stash script, swift 5
for x in (1...20).reversed() {
let stashData = "stash@{\(x)} stash@{\(x - 1)}"
print("cl git diff \(stashData) --name-only")
print("# git stash drop stash@{\(x)}\n")
}
cl git diff stash@{10} stash@{9} --name-only
# git stash drop stash@{10}
cl git diff stash@{9} stash@{8} --name-only
# git stash drop stash@{9}
cl git diff stash@{8} stash@{7} --name-only
# git stash drop stash@{8}
cl git diff stash@{7} stash@{6} --name-only
# git stash drop stash@{7}
cl git diff stash@{6} stash@{5} --name-only
# git stash drop stash@{6}
cl git diff stash@{5} stash@{4} --name-only
# git stash drop stash@{5}
cl git diff stash@{4} stash@{3} --name-only
# git stash drop stash@{4}
cl git diff stash@{3} stash@{2} --name-only
# git stash drop stash@{3}
cl git diff stash@{2} stash@{1} --name-only
# git stash drop stash@{2}
cl git diff stash@{1} stash@{0} --name-only
# cl git diff stash@{1} stash@{0} # kb: up, L+W
# git stash drop stash@{1}
# do not drop stash zero
# interactive rebase, to edit/squash commits
# git rebase -i HEAD~2 # opens vim
# git rebase -i HEAD~3
# git rebase -i HEAD~4
# git rebase -i HEAD~5
# git rebase -i HEAD~6
# git rebase --continue
# git rebase --abort
# git stash save "backup"
git stash list
git stash list --date=local
git stash show # file list
# git stash pop/apply
# show stash sha1 hash
git reflog stash
git blame dev/app/file.c
git blame -L 100,110 dev/app/file.c
# --------------------------------------
- git workflow example 1
clear; git status
git init # initialized empty Git repository in /users/a/dev/app/.git/
git add file1.txt
git commit -m "..."
git log
git add .
git commit -m "..." >> ~/gitCommitLog.txt
10 files changed, 20 insertions(+), 1 deletion(-)
create mode 100644 .gitignore
create mode 100644 HEAD
create mode 100644 c/lib.c
create mode 100644 c/lib.h
create mode 100644 file2.txt
# --------------------------------------
- git workflow example 2
WORKING_FOLDER=~/dev/app/
mkdir -p "$WORKING_FOLDER"
cd "$WORKING_FOLDER"
ls -alt
git init
git status # On branch main
touch .gitignore
echo .DS_Store > .gitignore
git add .gitignore
git add --all
git commit -m "new"
git log --name-status
# --------------------------------------
- git workflow example 3, GitHub
1. init, setup, and commit into local git repo
2. create repo on GitHub
3. push repo to GitHub
# test github connection
ssh -T git@github.com # Hi expressionsoftware! You've successfully authenticated, but GitHub does not provide shell access.
git init
touch .gitignore
echo .DS_Store > .gitignore
git add .gitignore
git commit -m "new"
# ...
# github repo url
ssl: git@github.com:expressionsoftware/foo.git
http: https://github.com/expressionsoftware/foo.git
# add remote and push
git remote add origin git@github.com:expressionsoftware/foo.git
git push -u origin main --porcelain --verbose # include -u (--set-upstream) on first push only
git push -u origin dev
git push origin main
git push origin dev
git push # current branch
# fatal: The current branch dev has no upstream branch.
# To push the current branch and set the remote as upstream, use
# git push --set-upstream origin dev
# clone
git clone git@github.com:expressionsoftware/foo.git # creates folder, default folder name, same as repo name, "foo"
git clone git@github.com:expressionsoftware/foo.git foobar # creates folder "foobar"
git clone git@github.com:expressionsoftware/foo.git . # current empty folder
# --------------------------------------
- .gitignore file
.cfusertextencoding
.ds_store
.fontconfig/
.gitignore~
.lesshst
.trash/
.viminfo
.xauthority
*~*
*.exe
xcuserdata/
# -----------------
app/temp.cpp
temp file 1.txt
# -----------------
# wildcards
# * wildcard requires full path
app/images/*png
*~
*.swp
# ignore all directories and files in a directory
tmp/**/*
- brew
/usr/local/bin/brew -v # 4.0.4
/usr/local/cellar
man brew
brew help
brew home
brew doctor
brew analytics
brew analytics off
brew list
brew list -1 # one entry per line
# brew update # update hb
brew outdated # list outdated packages
brew upgrade $FORMULA
# brew upgrade # upgrade all
brew cleanup -n # show cleanup
brew cleanup $FORMULA
# brew cleanup # cleanup all
brew info bash # 5.2.15
brew install bash # /usr/local/cellar/bash/*/bin/bash
brew info curl # 7.87
brew install curl # /usr/local/cellar/curl/*/bin/curl
brew info erlang # 25.2.2
brew install erlang # /usr/local/cellar/erlang/*/bin/erl
brew info git # 2.39.2
brew install git # /usr/local/cellar/git/*/bin/git
brew info go # 1.19.5
brew install go # /usr/local/cellar/go/*/bin/go
brew info haskell-stack # 2.9.3, GHCi 9.4.4
brew install haskell-stack # /usr/local/cellar/haskell-stack/*/bin/stack
brew info cabal-install # 3.8.1
brew install cabal-install # /usr/local/Cellar/cabal-install/3.8.1.0
brew info ghc@9.2 # 9.2.6
brew install ghc@9.2 # /usr/local/Cellar/ghc@9.2/9.2.6
brew info java # 19.0.2
brew install java # /usr/local/Cellar/openjdk/19.0.2/bin/java
brew info leiningen # 2.10
brew install leiningen # /usr/local/cellar/leiningen/*/bin/lein
brew info make # 4.4
brew install make # /usr/local/Cellar/make/*/bin/gmake
brew info maven # 3.9
brew install maven # /usr/local/Cellar/maven/3.9.0
brew info node.js # 19.7
brew install node.js # /usr/local/cellar/node/*/bin/node
brew info python3 # 3.10.10
brew install python3 # /usr/local/cellar/python/*/bin/python3
brew info rsync # 3.2.7
brew install rsync # /usr/local/cellar/rsync/*/bin/rsync
brew info rust # 1.67.1
brew install rust # /usr/local/cellar/rust/*/bin/rustc
brew info scala # 3.2.2
brew install scala # /usr/local/cellar/scala/*/bin/scala
brew info vapor # 18.6
brew install vapor # /usr/local/cellar/vapor/*/bin/vapor
- antlr
antlr4 # ANTLR Parser Generator 4.12
java -jar /usr/local/lib/antlr-4.12.0-complete.jar # ..
jar tf /usr/local/lib/antlr-4.12.0-complete.jar # toc
# antlr4 Hello.g4 -o ./build/java # gen java
# antlr4 Hello.g4 -Dlanguage=Swift -o ./build/swift # gen swift
# javac build/java/Hello*.java -d build/class # compile java to class
# cd build/class
# grun Hello r1 -tokens # -gui -tokens -tree
# input string to parse, enter, L+D to enter EOF
# grun is an alias to antlr test rig
# java org.antlr.v4.gui.TestRig Hello r1 -tokens # -gui -tokens -tree
# -gui launches TestRig java applet, Parse Tree Inspector gui window
# quit TestRig to exit grun, back to shell
// file: NS.g4
// nested namespace antlr grammar
//
grammar NS;
ns: nsgroup (nsgroup)*
;
nsgroup: 'namespace' nsname? nsbody
;
nsname: ID
;
nsbody: '{' (nsgroup)? '}' | // nested namespace
'{' natext* '}' | // unnested text
'{' '}' // unnested empty
;
natext: (.)+? | UNKNOWN ((.)+? | UNKNOWN)*
;
UNKNOWN : (PUNC | DIGITS)
;
PUNC: ([.,;:/-] | ADDOP | MULOP)+
;
ID: [a-zA-Z]+
;
WS: [ \n]+ -> skip
;
fragment ADDOP: [\\+]
;
fragment MULOP: [\\*]
;
fragment ESC: '\\'
;
fragment DIGITS: DIGIT (DIGIT)*
;
fragment DIGIT: [0-9]
;
// valid namespace grammar
//
namespace { }
namespace foo { }
namespace foo { namespace { } } // nested
namespace foo { namespace bar { } } // nested
namespace foo { int x; namespace bar { } } // nested
namespace a { } namespace b { } namespace c { }
namespace foo { xxx }
namespace foo { 123 }
namespace foo { // }
namespace foo { ... }
namespace foo { 1 2 3 }
namespace foo { 1 + 2 + 3 }
namespace foo { x + y }
// namespace foo { }
// output
// tokens:
[ | |
[ @0 0:8='namespace' <'namespace'> 1:0 ]
[ @1 10:12='foo' <ID> 1:10 ]
[ @2 14:14='{' <'{'> 1:14 ]
[ @3 16:16='}' <'}'> 1:16 ]
[ @4 17:16='<EOF>' <EOF> 1:17 ]
]
// walker
//
enter method line token display type ctx text
enterNs 1 namespace 'namespace' 1 'namespacefoo{}'
enterNsgroup namespace 'namespace' 1 'namespacefoo{}'
enterNsname foo ID 6 'foo'
exitNsname foo ID 6 'foo'
enterNsbody { '{' 2 '{}'
exitNsbody } '}' 3 '{}'
exitNsgroup } '}' 3 'namespacefoo{}'
exitNs } '}' 3 'namespacefoo{}'
// namespace foo { namespace bar { } } // nested
// output
// tokens:
[ | |
[ @0 0:8='namespace' <'namespace'> 1:0 ]
[ @1 10:12='foo' <ID> 1:10 ]
[ @2 14:14='{' <'{'> 1:14 ]
[ @3 16:24='namespace' <'namespace'> 1:16 ]
[ @4 26:28='bar' <ID> 1:26 ]
[ @5 30:30='{' <'{'> 1:30 ]
[ @6 32:32='}' <'}'> 1:32 ]
[ @7 34:34='}' <'}'> 1:34 ]
[ @8 35:34='<EOF>' <EOF> 1:35 ]
]
// walker
//
enter method line token display type ctx text
enterNs 1 namespace 'namespace' 1 'namespacefoo{namespacebar{}}'
enterNsgroup namespace 'namespace' 1 'namespacefoo{namespacebar{}}'
enterNsname foo ID 6 'foo'
exitNsname foo ID 6 'foo'
enterNsbody { '{' 2 '{namespacebar{}}'
enterNsgroup namespace 'namespace' 1 'namespacebar{}'
enterNsname bar ID 6 'bar'
exitNsname bar ID 6 'bar'
enterNsbody { '{' 2 '{}'
exitNsbody } '}' 3 '{}'
exitNsgroup } '}' 3 'namespacebar{}'
exitNsbody } '}' 3 '{namespacebar{}}'
exitNsgroup } '}' 3 'namespacefoo{namespacebar{}}'
exitNs } '}' 3 'namespacefoo{namespacebar{}}'
# separate lexer and parser
# antlr4 XLexer.g4 XParser.g4 -o ./build/java
# javac build/java/XLexer*.java build/java/XParser*.java -d build/class
# cd build/class
# grun X ruleX -tokens demo.h
// TestXListener.java
//
public class TestXListener {
public static void main(String[] args) throws Exception {
XListener x = new XListener();
x.parse();
}
}
// XListener.java
//
import java.util.*;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class XListener extends XBaseListener {
XLexer lexer;
XParser parser;
ParseTree tree;
CommonTokenStream tokenStream;
String file = "foo.h";
public void parse() throws Exception {
CharStream input = CharStreams.fromFileName(file);
lexer = new XLexer(input);
tokenStream = new CommonTokenStream(lexer);
parser = new XParser(tokenStream);
parser.removeErrorListeners(); // remove ConsoleErrorListener
parser.addErrorListener(new XParseErrorListener());
tree = parser.ruleX(); // rule name to process
int errorCount = parser.getNumberOfSyntaxErrors();
if (errorCount > 0) {
System.out.println("\nParser Error Count: " + parser.getNumberOfSyntaxErrors() + "\n");
}
// sim to grun -tokens but wo hidden channel tokens, comments #include #define
// re s:, \[
// r:\n[
System.out.println("\ntokens: " + tokensWithDisplayName(tokenStream.getTokens()) + "\n");
// walker header
System.out.println("enter method line token type ctx text");
ParseTreeWalker.DEFAULT.walk(this, tree);
}
String tokensWithDisplayName(List<Token> list) {
String tokens = list.toString();
System.out.println("debug raw tokens: " + tokens);
Iterator<Token> it = list.iterator();
while (it.hasNext()) {
Token t = it.next();
int type = t.getType();
String displayName = parser.getVocabulary().getDisplayName(t.getType());
tokens = tokens.replace(("<" + type + ">"),
("<" + displayName + ">"));
}
return tokens;
}
@Override
public void enterClassName(XParser.ClassNameContext ctx) {
System.out.println("enterClassName " + ctx.start.getLine() + ", " + ctx.start.getText() + ", " + ctx.start.getType() + ", '" + ctx.getText() + "'");
}
}
// XParseErrorListener.java
//
import java.util.*;
import org.antlr.v4.runtime.*;
public class XParseErrorListener extends BaseErrorListener {
@Override
public void syntaxError(Recognizer<?, ?> recognizer,
Object offendingSymbol,
int line,
int charPositionInLine,
String msg,
RecognitionException e) {
List<String> stack = ((Parser)recognizer).getRuleInvocationStack();
Collections.reverse(stack);
System.err.println("\nParser Error");
System.err.println("rule stack: " + stack);
System.err.println("line " + line + ":" + charPositionInLine + " at " + offendingSymbol + ": " + msg);
}
}
// foo.h
//
namespace Foo {
class Bar;
struct Data {
int val;
Bar lib;
};
}
// output
// tokens:
[ | |
[ @0 0:8='namespace' <'namespace'> 1:0 ]
[ @1 10:12='Foo' <Identifier> 1:10 ]
[ @2 14:14='{' <'{'> 1:14 ]
[ @3 25:29='class' <'class'> 3:4 ]
[ @4 31:33='Bar' <Identifier> 3:10 ]
[ @5 34:34=';' <';'> 3:13 ]
[ @6 45:50='struct' <'struct'> 5:4 ]
[ @7 52:55='Data' <Identifier> 5:11 ]
[ @8 57:57='{' <'{'> 5:16 ]
[ @9 67:69='int' <'int'> 6:8 ]
[ @10 71:73='val' <Identifier> 6:12 ]
[ @11 74:74=';' <';'> 6:15 ]
[ @12 84:86='Bar' <Identifier> 7:8 ]
[ @13 88:90='lib' <Identifier> 7:12 ]
[ @14 91:91=';' <';'> 7:15 ]
[ @15 97:97='}' <'}'> 8:4 ]
[ @16 98:98=';' <';'> 8:5 ]
[ @17 105:105='}' <'}'> 10:0 ]
[ @18 106:105='<EOF>' <EOF> 10:1 ]
]
// walker
//
// enter method line token display type ctx text
enterTranslationUnit 1 namespace 'namespace' 48 'namespaceFoo{classBar;structData{intval;Barlib;};}<EOF>'
enterNamespaceDefinition 1 namespace 'namespace' 48 'namespaceFoo{classBar;structData{intval;Barlib;};}'
enterNsHead 1 namespace 'namespace' 48 'namespaceFoo'
Foo Identifier 132
enterNsKey 1 namespace 'namespace' 48 'namespace'
enterNsName 1 Foo Identifier 132 'Foo'
enterDeclarationseq 3 class 'class' 21 'classBar;structData{intval;Barlib;};'
enterDeclaration 3 class 'class' 21 'classBar;'
enterDeclSpecifier 3 class 'class' 21 'classBar'
enterClassKey 3 class 'class' 21 'class'
enterClassName 3 Bar Identifier 132 'Bar'
enterDeclaration 5 struct 'struct' 66 'structData{intval;Barlib;};'
enterDeclSpecifier 5 struct 'struct' 66 'structData{intval;Barlib;}'
enterClassHead 5 struct 'struct' 66 'structData'
enterClassKey 5 struct 'struct' 66 'struct'
enterClassName 5 Data Identifier 132 'Data'
enterMemberSpecification 6 int 'int' 45 'intval;Barlib;'
enterMemberdeclaration 6 int 'int' 45 'intval;'
val Identifier 132
enterTypeSpecifier 6 int 'int' 45 'int'
enterMemberDeclarator 6 val Identifier 132 'val'
enterMemberdeclaration 7 Bar Identifier 132 'Barlib;'
lib Identifier 132
enterTypeSpecifier 7 Bar Identifier 132 'Bar'
enterClassName 7 Bar Identifier 132 'Bar'
enterMemberDeclarator 7 lib Identifier 132 'lib'
exitNamespaceDefinition 10 } '}' 90 'namespaceFoo{classBar;structData{intval;Barlib;};}'
exitTranslationUnit 10 <EOF> EOF -1 'namespaceFoo{classBar;structData{intval;Barlib;};}<EOF>'
- bash
# exit # exit bash 4
# date format
date +%H:%M:%S # 22:52:01
date '+%m-%d-%y %H:%M:%S' # 08-28-16 20:19:53
date '+%m-%d-%y.%H%M%S' # 08-28-16.201953
echo $BASH # /bin/bash
echo $BASH_VERSION # 3.2.57(1)-release
# 4.4.5(1)-release
bash --version # 3.2.57(1)-release
# 4.4.5(1)-release
echo $HOME # /users/a
echo $HOSTNAME # h9000
echo $RANDOM # 10273, (0-32767)
echo $PATH # /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PATH="${PATH}:/users/a/dev/scala/bin"
export PATH
echo $PATH
echo -e "foo\nbar"
for x in {1..10}
do
echo $x
done
# bash array
declare -a data=("foo" "bar" "...")
for x in "${data[@]}"
do
echo $x
done
cal
cal 2017
cal 10 2017
cal -y
# --------------------------------------
# .zshrc
# .bash_profile
# set min prompt
export PS1='$ '
# alias
alias czs='cat ~/.zshrc'
alias cl='clear;'
alias xfc='~/applications/fileCompare' # xfc f1 f2, do not use fc, a built-in command, see: man zshbuiltins or man fc
alias od='/usr/bin/opendiff' # filemerge, od f1 f2
alias ovs='open -a Visual\ Studio\ Code.app' # open visual studio code
alias oxc='open -a Xcode' # open xcode
alias lss='ls -al'
alias lsv='ls -al /volumes'
alias antlr4='/usr/local/Cellar/openjdk/19.0.2/bin/java -Xmx500M -cp "/usr/local/lib/antlr-4.12.0-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
alias grun='/usr/local/Cellar/openjdk/19.0.2/bin/java -Xmx500M -cp "/usr/local/lib/antlr-4.12.0-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
# git alias
alias gb=' git branch;'
alias gbr=' git branch -r;' # show remote branches
alias gcem=' git config --global user.email;' # john@dev.com
alias gds=' git diff stash;'
alias gl=' git log --name-status;'
alias glm=' git log --name-status --author=john;'
alias glp=' git log --abbrev-commit --pretty=oneline;'
alias glpm=' git log --abbrev-commit --pretty=oneline --author=john;'
alias gmt=' git mergetool;'
alias gp=' git pull;'
alias gs=' git status;'
alias gsl=' git stash list;'
alias gsll=' git stash list --date=local;'
alias gslno=' git stash list --name-only;'
function filehashlog() {
set -x
filehash $1
set +x
}
function filehash() {
openssl sha1 $1
}
function fhash() {
filehash $1 | egrep -o "\b([a-z0-9]+)$"
}
function fcomp() {
local fh1=$(fhash $1)
local fh2=$(fhash $2)
printf "file compare sha1 hash\n%s = %s\n%s = %s\n\n" $fh1 $1 $fh2 $2
if [ $fh1 == $fh2 ]
then
printf "files are equal\n"
else
printf "files are NOT equal\n"
fi
}
# file open chrome
# foc f.c
#
function foc() {
open "$1" -a Google\ Chrome.app
}
# file open preview
# fop a.png
#
function fop() {
open "$1" -a preview
}
# file open safari
# fos f.c
#
function fos() {
open "$1" -a Safari.app
}
# file open text edit
# fote f.txt
#
function fote() {
open "$1" -a textedit
}
# file open visual studio code
# fovs f.c
#
function fovs() {
open "$1" -a Visual\ Studio\ Code.app
}
# file open xcode
# foxc f.c
#
function foxc() {
open "$1" -a xcode
}
# --------------------------------------
# !/bin/bash
# backup copy file w/timestamp script
# bash backupFileScript "file 1.txt"
if (($# == 1)) # one param
then
vTimestamp=$(date "+_%m%d%y_%H%M%S.txt")
vBackupFilename=$1$vTimestamp
echo "file: $1" # file 1.txt
echo "backup: $vBackupFilename" # file 1.txt_100713_203059.txt
# quote for filename space chars
cp "$1" "$vBackupFilename"
else
printf "user error\n1 filename param is required\n"
echo "params: ${#}"
fi
# --------------------------------------
# !/bin/bash
# 2013 Mac CPU Architecture Script
# bash cpuScript "intel core i7"
# returns CPU architecture, either 32 or 64 bit, based on processor name
# http://support.apple.com/kb/HT3696
# bug param count wrong for string w/spaces
# bash cpuScript $(system_profiler SPHardwareDataType | grep -i 'processor name:' | sed -e 's/ *Processor Name: *//')
# params: 3
# version 2.0
# 64-bit CPU Intel
# fix wrap command-substitution $() in double quotes to send 1 string param
# bash cpuScript "$(system_profiler SPHardwareDataType | grep -i 'processor name:' | sed -e 's/ *Processor Name: *//')"
# params: 1
# version 2.0
# 64-bit CPU Intel Core i7
echo "params: ${#}"
ver="2.0"
echo "version $ver"
# lowercase
v1=$(echo $1 | tr '[:upper:]' '[:lower:]')
case $v1 in
"intel core solo"|"intel core duo") echo "32-bit CPU $1"
;;
*) echo "64-bit CPU $1"
;;
esac
# --------------------------------------
bash base conversions
int to binary echo 'obase=2; 256' | bc # 100000000
int to hex echo 'obase=16; 256' | bc # 100
int to hex printf '%x\n' 256 # 100
int to octal echo 'obase=8; 256' | bc # 400
binary to int echo 'ibase=2; 100000000' | bc # 256
hex to int echo $((0x100)) # 256
hex to int echo 'ibase=16; 100' | bc # 256
hex to int printf '%d\n' 0x100 # 256
octal to int echo 'ibase=8; 400' | bc # 256
- bc calculator
echo 2+2 | bc
bc # bc 1.06
bc -h # help
2 + 2 # ...
quit
- clojure (leiningen)
/usr/local/bin/lein -v # Leiningen 2.10 on Java 19.0.2 OpenJDK 64-Bit Server VM
lein -h
quit
L D quit
(quit)
lein repl ;;Clojure 1.11.1
quit
(+ 1 2 3 4 5 6 7 8 9 10) ;;55
(def nums [1 2 3 4 5 6 7 8 9 10])
(apply + nums) ;;55
(for [x [:a :b], y (range 5) :when (odd? y)] [x y]) ;;([:a 1] [:a 3] [:b 1] [:b 3])
(doseq [x [:a :b], y (range 5) :when (odd? y)] (prn x y)) ;;:a 1
:a 3
:b 1
:b 3
nil
(def a 42)
a ;;42
(+ a) ;;42
(+ a 2) ;;44
(/ a 2) ;;21
(* a 2) ;;84
(take 10 (range)) ;;(0 1 2 3 4 5 6 7 8 9)
(map inc (take 10 (range))) ;;(1 2 3 4 5 6 7 8 9 10)
(map #(+ % 2) (take 10 (range))) ;;(2 3 4 5 6 7 8 9 10 11)
- curl
curl -V # 7.79.1
curl http://curl.haxx.se/docs/manpage.html
curl http://www.gutenberg.org/cache/epub/2600/pg2600.txt -o "~/downloads/tolstoyWarAndPeace.txt" # download file
curl http://a.com/a.jpg -o ~/downloads/a.jpg
# http get
curl \
-H "Accept: text/html" \
-H "Content-Type: text/html" \
-H "Cookie: foo=1" \
-o "~/downloads/a.com.txt" \
-v \
https://a.com
# http post json body w/certificate
curl \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Content-Length: 17" \
-H "Cookie: foo=1" \
-H "Cookie: bar=1" \
--cert /etc/ssl/certs/file.crt \
--key /etc/ssl/certs/file.key \
-X POST \
-d '{ "foo" : "bar" }' \
-v \
https://a.com
# http get raw github source file
curl \
-H "Accept: application/vnd.github.raw" \
-H "Content-Type: text/plain" \
-o "~/downloads/Date.swift" \
-v \
https://raw.githubusercontent.com/expressionsoftware/Lib/main/Sources/Lib/Date.swift
- erlang
/usr/local/bin/erl +V # Erlang (SMP,ASYNC_THREADS,HIPE) (BEAM) emulator version 6.3
/usr/local/bin/erlc -help
erl # Erlang/OTP 17 [erts-6.3.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
help().
LG switch command
LG h|? help
LG i interrupt
c connect
LG q quit
q(). quit
code:root_dir(). %"/usr/local/cellar/erlang/17.4/lib/erlang"
erlang:loaded(). %loaded erlang modules, current and/or old code, including preloaded modules
erlang:memory().
erlang:system_info(process_limit). %262144
os:version(). %{14,1,0}
os:cmd("date"). %"Sat Jan 10 05:39:56 MST 2015\n"
io:format("hello Erlang!~n").
self().
process_info(self()).
process_info(self(), links).
processes().
length(processes()).
pwd().
ls().
cd("/users/a/erlang").
P1 = list_to_pid("<0.281.0>"). %<0.281.0>
is_pid(P1). %true
b(). %var bindings
f(). %forget all vars
f(X). %forget X var
string:concat(string:concat("foo", " "), "bar"). %"foo bar"
io:format("~s~n", ["foo bar"]). %foo bar
io:format("~w~n", ["foo bar"]). %[102,111,111,32,98,97,114]
Sq = fun(X) -> X * X end.
Sq(8). %64
math:sqrt(64). # 8.0
math:pi(). %3.141592653589793
now(). %{1420,849205,145416} timestamp from 1-1-1970 GMT
time(). %{17,20,5}
erlang:localtime(). %{{2015,1,9},{17,20,5}}
erlang:localtime_to_universaltime(erlang:localtime()). %{{2015,1,10},{0,20,5}}
T = lists:seq(0, 9). %[0,1,2,3,4,5,6,7,8,9]
T.
length(T). %10
AbcSha512 = crypto:hash(sha512, "abc"). %<<221,175,53,161,147,97,122,186,204,65,115,73,174,32,65,
49,18,230,250,78,137,169,126,162,10,158,238,230,75,...>>
is_binary(AbcSha512). %1
binary_to_list(AbcSha512).
length(binary_to_list(AbcSha512)). %64
lists:foreach(fun(B) -> io:format("~w ", [B]) end, binary_to_list(AbcSha512)).
binary:last(AbcSha512). %159
io:format("~s~n", [[io_lib:format("~2.16.0B ",[X]) || <<X:8>> <= AbcSha512 ]]).
L1 = ["foo", "bar", "foo", "foo++", "FOO", "abc"].
lists:foreach(fun(X) -> io:format("~s~n", [X]) end, L1).
lists:foreach(fun(X) -> io:format("~s~n", [X]) end, lists:sort(L1)). %FOO
abc
bar
foo
foo
foo++
%guid, 2^82 unique
make_ref(). %#Ref<0.0.0.393>
- # grep # regex
# grep -ri -e 'foo' --include '*cpp*'
# grep -ri -E '\[\]' . --include=*.h
# grep -ri -E 'min|max' .
# fgrep -ri 'foo' . # all files
# fgrep -ri 'foo' . --include='*.h'
# fgrep -i 'foo' /users/a/file.txt
-n --line-number
-l --files-with-matches
-c --count
- haskell
ghci
:? help
:q quit
-- haskell comment
:show paths
current working directory: /users/a
module import search paths: .
- java
which java # /usr/bin/java
java -help
java -version # openjdk version "19.0.2" 2023-01-17
# OpenJDK Runtime Environment Homebrew build 19.0.2
# OpenJDK 64-Bit Server VM
echo $CLASSPATH
echo $JAVA_HOME
javac -help
javac Hello.java
java Hello
java -X
jar --help
jar tf foo.jar # toc
https://www.java.com/releases
- # less text viewer
less -? # --help
less -V # --version
-i # --ignore-case # ignore case in searches that do not contain uppercase
-I # --IGNORE-CASE # ignore case in searches and patterns
/regex search string
less iPhone.storyboard
q # quit
- LLDB
http://lldb.llvm.org/lldb-gdb.html
help
# comment
p @import Foundation
p sizeof(int)
p width
po foo
po @"foo".length
po FooType $x = (FooType)1 # cast int to enum Foo
po [0x00000000 description]
po node.position # (x = 0, y = 0, z = -10)
po node.rotation # (x = 1, y = 0, z = 0, w = 6.28318548)
po type(of: self.view)
po self.view.superclass
po [self.view class]
po [self.view superclass]
po cell.contentView.subviews
po _stdlib_getDemangledTypeName(x) # Swift.Array<Swift.Int>
p @import UIKit
po view.bounds.size.width
po indexPath.row
po indexPath.section
po [refreshControl actionsForTarget:self forControlEvent:UIControlEventValueChanged]
p self.view.frame
p (CGRect)[self.view frame]
po $arg1 # use w/exception breakpoint
po [NSUserDefaults.standardUserDefaults dictionaryRepresentation]
po Thread.callStackSymbols
po request.allHTTPHeaderFields
expr width = 25
expr debugFlag = true # reset
fr v
frame variable s # (__NSCFString *) s = 0x0 @"foo"
frame variable k # (__NSCFConstantString *) k = 0x0 @"bar"
frame variable d # (__NSDictionaryI *) d = 0x0 4 key/value pairs
- maven
mvn -h
mvn -v # 3.9 # Maven home: /usr/local/Cellar/maven/3.9.0/libexec
- node.js
/usr/local/bin/node -v # v19.7
node --help
node -e "require('repl').start({ignoreUndefined: true})"
node helloNode.js
# repl
.break
.clear
.exit
.help
.save session.js
.load session.js
LC terminate current command, twice to exit
LD exit
a = [1, 2, 3]; a.forEach(function(x){ console.log(x); });
//--------------------------------------
// node web server, min
// https://localhost:8443
// touch web/public/favicon.ico
var _fs = require('fs'),
_https = require('https'),
_url = require('url')
// lib
_https.createServer(httpsOptions, function(req, res) {
const url = _url.parse(req.url, true)
const fullUrl = fullUrlFunc(req, url.pathname)
console.log("\nrequest url:", fullUrl)
// console.log('request headers:', req.headers)
const response = '{ "hello" : "Node" }' //
res.writeHead(200, { 'Content-Type' : 'application/json' })
res.end(response)
}).listen(8443)
//--------------------------------------
// node web server
const _fs = require("fs"),
_https = require("https"),
_path = require("path"),
_url = require("url"),
rootDir = "web/public"
// lib
function serveFile(res, path) {
const file = rootDir + path
const fileExt = fileExtension(file)
console.log("serve file:", file)
_fs.readFile(file, function(err, data) {
if (fileExt == "css") {
res.writeHead(200, { "Content-Type" : "text/css" })
}
else if (fileExt == "js") {
res.writeHead(200, { "Content-Type" : "text/javascript" })
}
else {
res.writeHead(200, { "Content-Type" : "text/html" })
}
res.write(data)
res.end()
})
}
function serveTextFile(res, path) {
const file = rootDir + path
console.log("serve text file:", file)
_fs.readFile(file, function(err, data) {
res.writeHead(200, { "Content-Type" : "text/plain" })
res.write(data)
res.end()
});
}
function response_404(res, fullUrl) {
res.statusCode = 404
res.statusMessage = "Not found"
const html = '<!doctype html><html><head><title>404</title><meta charset=utf-8><link href="/style.css" rel="stylesheet"></head><body style="margin: 40px 60px 50% 60px;"><h1>Error</h1><br/><h2>Status Code: 404<br/>Resource not found: ' + fullUrl + '</h2></body></html>';
res.end(html)
}
function fileExists(path) {
const relPath = "./" + rootDir + path
if (fs.existsSync(relPath)) {
return true
}
return false
}
function fileExtension(file) {
const basename = _path.basename(file)
const firstDot = basename.indexOf(".")
const lastDot = basename.lastIndexOf(".")
const fileExt = _path.extname(basename).replace(/\.([a-z0-9]+).*/i, "$1") // css, htm
if (firstDot === lastDot) {
return fileExt
}
return basename.slice(firstDot, lastDot) + fileExt
}
_https.createServer(httpsOptions, function(req, res) {
const url = _url.parse(req.url, true)
const fullUrl = fullUrlFunc(req, url.pathname)
console.log("\nrequest url:", fullUrl)
// console.log('request headers:', req.headers)
if (url.pathname == "/") {
serveFile(res, "/index.htm")
}
else if (fileExists(url.pathname) === false) {
response_404(res, fullUrl)
}
else if (url.pathname.toLowerCase().includes("/source/")) {
serveTextFile(res, url.pathname)
}
else {
serveFile(res, url.pathname)
}
}).listen(8443)
//--------------------------------------
// node web server lib
var httpsOptions = {
key: fs.readFileSync("/etc/ssl/localhost/localhost.key.rsa"),
cert: fs.readFileSync("/etc/ssl/localhost/localhost.crt")
}
function fullUrlFunc(req, fullUrl) {
return (req.connection.encrypted ? "https://" : "http://") + req.headers.host + fullUrl
}
- openssl
SHA File Hash
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/openssl.1ssl.html
# openssl sha512 file
# SHA512(/Users/j19/file)= ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
- # pbcopy
# use w github setup
# pbcopy < ~/.ssh/id_rsa.pub # Public Key, share
# pbpaste
- ps – process status
ps aux
ps aux <pid>
- python
python -V # 2.7.16 /usr/bin/python
python3 -V # 3.9.6 /usr/local/bin/python3
python3 -V # 3.9.6 /usr/local/bin/python3 -> /usr/local/cellar/python3/3.9.6/bin/python3
python3 --help
python3 -c "print('foo')"
quit() # LD
pip3 -V # pip 9.0.1 /usr/local/lib/python3.6/site-packages (python 3.6)
# pip 19.2.3 /applications/xcode.app/contents/developer/library/frameworks/python3.framework/versions/3.8/lib/python3.8/site-packages/pip (python 3.8)
sorted(['a', 'c', 'b']) # ['a', 'b', 'c']
sorted(['a', 'c', 'B']) # ['B', 'a', 'c']
sorted(['', ' ', '.', '/', '_']) # ['', ' ', '.', '/', '_']
sorted(['a', 'a.', 'a/', 'a_']) # ['a', 'a.', 'a/', 'a_']
sorted([1, 10, 9, 2, 20, 3]) # [1, 2, 3, 9, 10, 20]
for x in [' ', '.', '/', '_']:
print('\'{}\' = {}'.format(x, ord(x))) # ' ' = 32
'.' = 46
'/' = 47
'_' = 95
# --------------------------------------
# python file hash script, fileHash.py
import hashlib
def getFileHash(filePath):
md5 = hashlib.md5()
sha1 = hashlib.sha1()
sha224 = hashlib.sha224()
sha256 = hashlib.sha256()
sha384 = hashlib.sha384()
sha512 = hashlib.sha512()
with open(file, 'rb') as f:
for chunk in iter(lambda: f.read(8192), b''): # b'' = bytes literal
md5.update(chunk)
sha1.update(chunk)
sha224.update(chunk)
sha256.update(chunk)
sha384.update(chunk)
sha512.update(chunk)
print('md5: ' + md5.hexdigest())
print('sha1: ' + sha1.hexdigest())
print('sha224: ' + sha224.hexdigest())
print('sha256: ' + sha256.hexdigest())
print('sha384: ' + sha384.hexdigest())
print('sha512: ' + sha512.hexdigest())
print('file hash')
file = input('enter filename: ') # /users/a/file.txt
getFileHash(file)
# --------------------------------------
# example
python3 ~/fileHash.py
# file hash
# enter filename: /users/a/file.txt # abc
# md5: 900150983cd24fb0d6963f7d28e17f72
# sha1: a9993e364706816aba3e25717850c26c9cd0d89d
# sha224: 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
# sha256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
# sha384: cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
# sha512: ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
# --------------------------------------
# python azure blob storage sdk
# http://azure.microsoft.com/en-us/documentation/articles/storage-python-how-to-use-blob-storage/
# http://azure.microsoft.com/en-us/documentation/articles/python-how-to-install/
# https://pypi.python.org/pypi/azure
pip3 search azure
pip3 install azure
ls -l /usr/local/lib/python3.5/site-packages
from azure.storage.blob import BlobService
blob_service = BlobService(account_name='__', account_key='__')
blob_containers = blob_service.list_containers
for bc in blob_containers():
print(bc.name)
blobs = blob_service.list_blobs('blobs')
for b in blobs:
print(b.name)
# upload blob
blob_service.put_block_blob_from_path('blobs',
'foo.txt',
'/users/a/temp.txt',
x_ms_blob_content_type='application/txt')
# uploaded blob url
http://foo.blob.core.windows.net/blobs/foo.txt
blob_service.delete_blob('blobs', 'foo.txt')
- R
/library/frameworks/r.framework/resources/r --version
R.Version()
R.Version()$version # 4.2.2 (2022-10-31)"
R.Version()$nickname # Innocent and Trusting
?help # q
quit()
Sys.getenv()
ls()
?ls
ls(pattern = "^m.*")
?rm
# rm(m1)
# rm(list = ls()) # remove all
x = "foo"
nchar(x) # length 3
?matrix
?vector
- ruby
/usr/bin/ruby -v # 2.6.10p210 (2022-04-12 revision 67958) [universal.x86_64-darwin21]
ruby --help
- # sed substitute replace
sed -e s/foo/BAR/ file.txt
sed -e s/foo/BAR/g file.txt
# split
echo foo bar bam | sed 's/ /\n/g'
# foo
# bar
# bam
# --------------------------------------
# sed script html encode file
sed -f script.txt file.txt
sed -f script.txt file.txt > file.txt.out
s/\&/\&/g
s/</\</g
s/>/\>/g
s/"/\"/g
s/'/\'/g
# --------------------------------------
# sed script html decode file
s/\&/\&/g
s/\</</g
s/\>/>/g
s/\"/"/g
s/\'/'/g
- SSH Keys
# man ssh-keygen
# man ssh-agent
# man ssh-add
# ls -al ~/.ssh/
# ls -al /Users/*/.ssh/
# ls ~/.ssh/id_rsa.pub # Public Key, share
# ls ~/.ssh/id_rsa # Private Key, do not share
# ls ~/.ssh/config
# cat ~/.ssh/id_rsa.pub # Public Key, share
# cat ~/.ssh/id_rsa # Private Key, do not share
# cat ~/.ssh/config
## Generate an SSH Key Pair
# ssh-keygen -t rsa -b 4096 -C "email@foo.com"
## Add SSH Private Key to ssh-agent
# eval "$(ssh-agent -s)" # Start the ssh-agent in the background
# ssh-add -K ~/.ssh/id_rsa # Add your SSH Private Key to the ssh-agent and store your passphrase in the keychain
# Enter passphrase for /Users/a/.ssh/id_rsa:
# Identity added: /Users/a/.ssh/id_rsa (email@foo.com)
# Copy SSH Public Key and add to GitHub account, one-time setup
- translate
delete carriage return chars ^M
# tr -d '\r' < /users/a/bookmarks.html > /users/a/bookmarks_2.html
- translate regex replacement, lowercase uppercase
echo "Foo Bar 123" | tr 'A-Z' 'a-z' # foo bar 123
echo "Foo Bar 123" | tr 'a-z' 'A-Z' # FOO BAR 123
echo 'Foo Bar 123' | tr '0-9' '#' # Foo Bar ###
# lowercase
echo "Foo" | tr '[:upper:]' '[:lower:]'
# uppercase
echo "Foo" | tr '[:lower:]' '[:upper:]'
- vim
# 9.0.1023
# vim f.txt
:help
:q # quit, exit, escape from :help
esc # normal mode
. # repeat command
b # move 1 word back
dd # delete line
dw # delete word under cursor
i # insert mode
u # undo
w # move 1 word forward
:open f.txt
:w f.txt # save
:x # save (if changed) and quit
:split # h
:vertical split
L+w w # nav windows
L+w q # close current window, split
:ls
:colorscheme torte # b, zellner w
- line word count
wc -lw main.storyboard
- macOS
- connected servers/volumes
ls -1 /volumes/
ls -Alt /volumes/serverName/folder/
- apps
ls -1 /applications
open -a /applications/textEdit.app 'file.txt'
open -a /applications/xcode.app 'file.txt'
- run app executable from command line
# ./app
- fileMerge diff app
opendiff file1 file2
- diff
compare directories
diff -rq ./dir1 ./dir2 # show files that are diff
diff -rqs ./dir1 ./dir2 # show files that are same
- defaults read/write plist
- view app bundle info
defaults read demo.app/info.plist CFBundleIdentifier # com.foo.demo
defaults read demo.app/info CFBundleVersion
defaults read /users/a/Library/Developer/CoreSimulator/Devices/*/Data/Containers/Bundle/Application/*/.com.apple.mobile_container_manager.metadata.plist MCMMetadataIdentifier # com.foo.demo
- show hidden files
defaults read com.apple.finder AppleShowAllFiles
defaults write com.apple.finder AppleShowAllFiles YES # NO
# killall Finder
- plutil read/write plist
plutil -p info.plist
plutil -convert xml1 info.plist -o - # print plist as xml
- config vars
getconf DARWIN_USER_CACHE_DIR # /var/folders/a0/aaa000/C/
- file flags
ls -lO
chflags uchg file # lock
chflags nouchg file # unlock
chflags -R uchg /dir # lock
chflags -R nouchg /dir # unlock
- extended attributes
# ls -l ~/downloads/ # list file or dir, extended attributes are indicated by an @ char at the end of the ownership and permissions info
# -rw-r--r--@ 1 apaak staff 1024 Sep 12 10:00 foo.app
xattr ~/downloads/foo.app
# xattr -p com.apple.quarantine ~/downloads/foo.app # print attribute, file quarantine
# xattr -d com.apple.quarantine ~/downloads/foo.app # delete attribute
# xattr -c ~/downloads/foo.app # delete all attributes, clear
# xattr -rc ~/downloads # delete all attributes from dir and files
- change file modes
u user (owner)
g group
o other
a all (everyone, ugo)
# chmod 700 ~/downloads/foo.app
# chmod u=rwx ~/downloads/foo.app
# chmod o-rwx ~/downloads/foo.app
u g o octal
rwx rwx rwx mode
100 000 000 400 r user
100 100 100 444 r all
110 000 000 600 rw user
111 000 000 700 rwx user
- file commands
# set file create modified date
touch -t 201701020000 /users/a/file
# copy file
# cp file1.txt file2.txt
# copy folder
# cp -npR ~/temp ~/backup # mac
# cp -nR ~/temp /volumes/10.0.0.100/backup # win
# cut
# echo "a1 a2 a3 ax\nb1 b2 b3 b4 b5" | cut -f 1 -w
# echo "a1 a2 a3 ax\nb1 b2 b3 b4 b5" | cut -f 1,3 -w # output is tab delimited
# a1 a3
# b1 b3
# echo "a1 a2 a3 ax\nb1 b2 b3 b4 b5" | cut -f 1-4 -w
# echo "a1 a2 a3 ax\nb1 b2 b3 b4 b5" | cut -f 1-5 -w
# echo "a1 a2 a3 ax\nb1 b2 b3 b4 b5" | cut -f 1-10 -w
# echo "a0;a1 a2\nb0 b1 b2; b3" | cut -f 1 -d ';' # a0
# b0 b1 b2
# rename/move file
# mv file1.txt file2.txt
# batch file rename w/sed regex, test w/echo
# ls * | sed -e 'p;s/foo/bar/' | xargs -n2 echo # mv
# remove file
# rm tempFile.txt
# remove folder
# rm -dfr tempFolder
# create parent intermediate folders path
# mkdir -p ~/dev/c
# sort file
# sort file1.txt -o file2.txt
# list files
ls -lt ~/temp
ls -ltT ~/temp # seconds
ls -1lhRt ~/temp
ls -l
ls -1 # file names
ls -1R # file names, recursive
ls * | xargs -n1
du -ach ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug/cocoa.app
# file search, default recursive
# sudo find / -iname '*.app'
# find . -iname '*.h'
# find . -iname '*.txt' -depth 1 # top level files
# find . -iname '*.txt' -maxdepth 2 # all files up to max depth
# find . -iname '*.txt' -depth 2 # only depth 2 files
# find ~ -iname 'java'
# find ~/Library/Developer/Xcode/DerivedData/*/Build/Products/Debug/cocoa.app -type f
# find and delete files
# find . -iname '.ds_store' -type f
# find . -iname '.ds_store' -type f -exec rm {} \;
# find . -iname '.ds_store' -type f -print0 | xargs -0 rm
# find and delete git folders
# find . -iname '.git' -type d # find only
# find . -iname '.xgit' -type d -print0 | xargs -0 rm -dfr
# find . -iname '.xgit' -type d -print0 | xargs -0 sudo rm -dfr
# delete git folders
# rm -dfr .xgit
- unzip
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/unzip.1.html
- lipo
lipo /users/a/lib.a -info # Non-fat file: /users/a/lib.a is architecture: x86_64
- make
brew: GNU "make" has been installed as "gmake"
gmake -v # GNU Make 4.4, Built for x86_64-apple-darwin21.6.0
gmake c_lean # WARN "clean" deletes executable and .o files
gmake build --file=Makefile
- nm
# display name list (symbol table)
# llvm symbol table dumper
nm --help
nm --version # apple llvm 14
nm --defined-only /users/a/lib.a
nm --defined-only --demangle /users/a/lib.a
# /Library/Developer/CommandLineTools/usr/bin/llvm-nm
# cd /Library/Developer/CommandLineTools/usr/bin/
# ./llvm-nm -version # apple llvm 14
- otool
# object file display tool
otool -h /users/a/lib.a
otool -D /users/a/lib.a
Archive : /users/a/lib.a
/users/a/lib.a(fooClass.o):
- macOS
- crash reports
- iOS
Xcode -> Window -> Devices and Simulators (CS 2)
View Device Logs
or
1. Catalina: Sync device with Finder Locations
Mojave: Sync device with iTunes
2. open ~/Library/Logs/CrashReporter/MobileDevice
3. ls -alt ~/Library/Logs/CrashReporter/MobileDevice/iphone/*.crash
- disk util
diskutil list
diskutil cs list
diskutil info /volumes/vol1
diskutil eraseVolume JHFS+ untitled_usb_drive "/volumes/a usb drive"
- create macOS bootable install usb drive
diskutil eraseVolume JHFS+ untitled_usb_drive "/volumes/usb drive to erase and use"
sudo "/Applications/Install macOS 12 Beta.app/contents/resources/createinstallmedia" --volume /volumes/untitled_usb_drive # Monterey
sudo "/Applications/Install macOS High Sierra.app/contents/resources/createinstallmedia" --volume /volumes/untitled_usb_drive --applicationpath "/Applications/Install macOS High Sierra.app"
- use bootable install usb drive
reboot, hold the Option key while booting to launch the Startup Manager, select the usb drive as the startup disk to begin install
- ip address
ifconfig
ifconfig | grep "inet "
- spoof mac address
get current mac address and interface name with Option + Click on Wifi icon in menu toolbar
use your actual interface name, eg en0, en1, en2
# networksetup -getmacaddress en0
# sudo ifconfig en0 ether 00:00:00:00:00:00
- network setup
networkSetup -getComputername
networkSetup -printCommands
networkSetup -listAllNetworkServices
networkSetup -getInfo wi-fi # wifi network service, ip address
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/networksetup.8.html
- sound processing
# afinfo soundFile.m4a
# afConvert -f caff -d aac soundFile.m4a soundFile.caf
- sysctl hw.machine # hw.machine: x86_64
- system diagnostics
# sudo sysdiagnose xcode
/var/tmp/sysdiagnose_2013.10.13_15-00-00-MDT_Xcode.tar.gz # output
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/sysdiagnose.1.html
- system_profiler
system_profiler -listDataTypes
system_profiler SPStorageDataType
system_profiler SPSoftwareDataType # System Software Overview
System Version: macOS 13.2 (22D49)
Kernel Version: Darwin 22.3
Boot Volume: Vol
Boot Mode: Normal
Time since boot: 1 day 4:04
Computer Name: dadoes
User Name: rick deckard (rickdeckard)
system_profiler SPHardwareDataType
system_profiler SPHardwareDataType | grep -i 'processor name:' | sed -e 's/ *Processor Name: *//'
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man8/system_profiler.8.html
- versions
14 Sonoma
13 Ventura 2022
12 Monterey
11 Big Sur 2020
10.15 Catalina
10.14 Mojave 2018
10.13 High Sierra
10.12 Sierra 2016 macos
10.11 El Capitan
10.10 Yosemite 2014
10.09 Mavericks
10.08 Mountain Lion 2012 os x
10.07 Lion
10.06 Snow Leopard 2010
10.05 Leopard
10.04 Tiger 2008 mac os x
- xcode
# beta, bash script
for _ in {1..10}
do
killall ReportCrash
killall SourceKitService
killall "Interface Builder Cocoa Touch Tool"
done
- xcodebuild
xcodebuild -help
/usr/bin/xcodebuild -showBuildSettings
xcodebuild -showsdks
xcodebuild -dry-run -project app.xcodeproj
xcodebuild -list -project app.xcodeproj
xcodebuild -showBuildSettings -project app.xcodeproj
# xcodebuild -showBuildSettings -project app.xcodeproj | less
- xcode-select
xcode-select -h
sudo xcode-select --switch /Applications/Xcode-Beta.app
xcode-select -p # /Applications/Xcode-Beta.app/Contents/Developer
- xcrun --show-sdk-path --sdk iphoneos # /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.4.sdk
xcrun --show-sdk-path --sdk macosx # /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk
xcrun --show-sdk-path --sdk watchos # /Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS4.3.sd
xcrun simctl
xcrun simctl terminate booted com.expressionSoftware.app
xcrun simctl launch booted com.apple.Preferences # launch iOS settings
# xcrun simctl delete unavailable # delete devices that are not supported by the current Xcode SDK
xcrun swift-demangle __TFC4Demo6MainVC5debugfT_T_ # Demo.MainVC.debug ()()
8/2/16
notes
8/1/16
Xcode Keyboard Shortcuts
v11.3
KEYS
cmd command/apple C
ctl control L
opt option/alt O
shf shift S
ent enter E
del delete D
spc space _
clk click K
FILE
C T|N new tab/file...
CS T|N new window/new project...
CL N new workspace...
COS N new playground
CO N new group
C O open...
CS O open quickly..., file or symbol name
C > open hidden files, toggle in file-open dialog (CS .)
CO A add files
C W close tab
CS W close window
CLO W close other windows
CL W close current file, back to previous file
CO W close workspace
C S save
CS S duplicate..., save as...
CSO S save as...
CO S save all
CL S create snapshot...
NAVIGATE
C ` next window
C ~ previous window (CS `)
C {|} previous/next tab
CL left back
CL right forward
CL up toggle header/source file, jump to next counterpart
L / next placeholder //<##>
L ? previous placeholder (LS /) //<#placeholder 2#>
C L line number, goto
CL J definition, (cmd + click)
CS L selection
C J editor
CO ` focus next area
CO ~ focus previous area (COS `)
CO < open in... (COS ,)
CO , open in assistant editor
CS J reveal in project navigator
JUMP BAR
L 1 grouped files, recent, unsaved, includes, storyboard outlets
L 2 previous history
L 3 next history
L 4 project
L 5 folder files
L 6 function list, code comment tags, storyboard view controller scene
JUMP BAR CODE COMMENT TAGS
// TODO: ...
// FIXME: ...
// MARK: m1
// ???: wtf
// !!!: foo
EDIT
C Z undo
CS Z redo
CO V special paste
COS V paste and preserve formatting
CD delete to beginning of line
L D delete forward, cursor stationary
L K delete to end of line, paragraph
CL_ emoji & symbols
FIND
C F find
CO F find and replace
CS F find in workspace
COS F find and replace in workspace
C G find next
CS G find previous
C E use selection for find
CS E use selection for replace
CO J filter in navigator
CO L filter in library
FORMAT
CLS T show fonts
EDITOR
show editor only C enter
----------
canvas CO enter
assistant CLO enter
layout >
----------
show completions L_ (esc)
show code actions CS A
edit all in scope CL E
refactor >
----------
selection >
select all symbols
split selection by lines
balance delimiters
select column up LS up
select column down LS down
structure >
re-indent L I
shift right C ]
shift left C [
move line up CO [
move line down CO ]
comment selection, toggle C /
add documentation CO /
code folding >
fold CO left
unfold CO right
unfold all
fold methods & functions COS left
unfold methods & functions COS right
fold comment blocks CLS left
unfold comment blocks CLS right
syntax coloring >
default for file type
none
font size >
increase C +
decrease C -
reset CL 0
theme >
----------
minimap CLS M
authors CLS A
----------
invisibles
----------
show last change for line
create code snippet
----------
jump to definition CLK
select block of text OK
move cursor to start of file C up
move cursor to end of file C down
move cursor to start of line C left (L A)
move cursor to end of line C right (L E)
move cursor left one word O left
move cursor right one word O right
center selection in visible area L L
cycle thru code completion L .
cycle backward thru code completion, reverse L > (LS .)
PRODUCT
C B|R|. build/run/stop
CS K clean
COS K clean build folder
CS R build for running
CS I build for profiling
CL R run without building
C I profile
CS B analyze
CL [|] select previous/next scheme, workspace project
C < edit scheme (CS ,)
CLO U test, xctest
CLO G test again
DEBUG
F6|F7|F8 step over/into/out
CL Y toggle pause, continue
CL C continue to current line
C K clear console
CO K reload console
L F6|F7 step over/into instruction
LS F6|F7 step over/into thread
C \ add breakpoint at current line
C Y toggle activate breakpoints
CS M view memory
VIEW
editor >
focus
show related items L 1
show previous history L 2
show next history L 3
show top level items L 4
show group files L 5
show document items L 6
show code review, hide, toggle COS enter
----------
change editor orientation
reset editor sizes
reset assistant selection COS Z
----------
navigators >
show project navigator C 1
show source control navigator C 2
show symbol navigator C 3
show find navigator C 4
show issue navigator C 5
show test navigator C 6
show debug navigator C 7
show breakpoint navigator C 8
show report navigator C 9
show navigator, hide, toggle C 0
debug area >
activate console CS C
show debug area, hide, toggle CS Y
inspectors >
show file inspector CO 1
show history inspector CO 2
show quick help inspector CO 3
show inspectors CO 0
show library CS L
----------
hide toolbar CO T
hide tab bar
show all tabs CS \
----------
enter full screen, exit, toggle CL F
VIEW - UTILITIES
CO 0 toggle utilities
CO 1 show file inspector
CO 2 show history inspector
CO 3 show quick help inspector
show identity inspector
dae node inspector
CO 4 show attributes inspector
CO 5 show size inspector
CO 6 show connections inspector
CO 7 show bindings inspector, cocoa storyboard
sknode inspector, sprite kit
CO 8 show view effects inspector, cocoa storyboard
CLO 1 show file template library
CLO 2 show code snippet library
CLO 3 show object library
CLO 4 show media library
CS 0 documentation & api reference
CS 1 welcome to xcode
CS 2 devices
IOS SIMULATOR
C 1|2|3|4|5 scale 100/75/50/33/25%
C left|right rotate left/right
CS H home
C K toggle software keyboard
CS K connect hardware keyboard
C S save screen shot
C T slow animations
CS M simulate memory warning
C / open system log...
INTERFACE BUILDER
C D duplicate control
C = size to fit content, select control first
C _ add horizontal guide, drag off top/bottom to remove
C | add vertical guide, drag off left/right to remove, pipe char
C [|] align left/right edges, select controls first
C +|- zoom
C LRUD scroll
LS click control popup menu
SOURCE CONTROL
CO C|X commit.../pull...
FILE MERGE
C A select all diffs, then left or right to select entire file rev
OS
L F2 select menu bar, file, edit, (ctl + fn + F2)
CS / help menu (C ?)
L F3 select dock
C ` select next window
CS ` select previous window (C ~)
CS 3 save screenshot to file
CS 4 save selected area to file
CS 5 onscreen capture controls, use to set screenshot size etc, enter or capture to save screenshot to file
CLS 3 copy screenshot to clipboard
CLS 4 copy selected area to clipboard
C , preferences...
CO_ system preferences emoji & symbols
C L system preferences show all
CO F5 accessibility options
CO = zoom in (enable zoom in accessibility)
CO _ zoom out
CO 8 toggle zoom
C M minimize
C H hide
CO H hide others
CS G finder goto folder /etc
C K finder connect to server
O finder image zoom full size
T target disk mode w/thunderbolt cable, hold T on startup
CO esc force quit applications
CL pwr reboot
OS K apple logo char
3/21/15
iOS Scene Kit Jet
The Scene Kit 3D Jet in flight with clockwise roll, in iPad airspace.
Trailing transparent snapshots are 3D model clones of the jet at variable intervals.
Use SCNView allowsCameraControl to zoom and rotate the entire scene, including models, for different points of view.
* The 3D Jet ship mesh is part of the default Xcode Scene Kit project.



Trailing transparent snapshots are 3D model clones of the jet at variable intervals.
Use SCNView allowsCameraControl to zoom and rotate the entire scene, including models, for different points of view.
* The 3D Jet ship mesh is part of the default Xcode Scene Kit project.



@import SceneKit;
@import GLKit;
@interface ESJet: NSObject
@property (nonatomic) SCNNode * node;
@property (nonatomic, assign) CGFloat velocity;
@property (nonatomic, assign) BOOL roll;
@property (nonatomic, assign) CGFloat rollRate;
-(void)update:(NSTimeInterval)aTime isVisible:(BOOL)aVisible;
-(instancetype)init;
-(instancetype)initWithNode:(SCNNode *)aNode zPosition:(int)aZPosition;
@end
@implementation ESJet
-(void)update:(NSTimeInterval)aTime isVisible:(BOOL)aVisible;
{
CGFloat nextZPosition = self.velocity;
// NSLog(@"jet position: %@", NSStringFromGLKVector3(SCNVector3ToGLKVector3(self.node.position)));
if (aVisible)
{
NSLog(@"jet visible");
}
else
{
//when jet flys off right-side of screen, reposition on left
NSLog(@"...");
nextZPosition = -(self.node.position.x * 1.95);
}
GLKVector3 nextFramePosition = GLKVector3Make(0, 0, nextZPosition);
GLKMatrix4 transform = SCNMatrix4ToGLKMatrix4(self.node.transform);
self.node.transform = SCNMatrix4FromGLKMatrix4(GLKMatrix4TranslateWithVector3(transform, nextFramePosition));
if (self.roll)
{
//rotate jet ~ 1 degree per frame on X axis
GLKQuaternion rot = GLKQuaternionMakeWithAngleAndAxis((M_1_PI * self.rollRate), 1, 0, 0);
GLKQuaternion orientation = GLKQuaternionMultiply(rot, GLKQuaternionMake(self.node.orientation.x,
self.node.orientation.y,
self.node.orientation.z,
self.node.orientation.w));
self.node.orientation = SCNVector4Make(orientation.x, orientation.y, orientation.z, orientation.w);
}
}
-(instancetype)init
{
if (self = [super init])
{
self.velocity = 0.33f;
self.rollRate = (self.velocity * 0.364);
}
return self;
}
-(instancetype)initWithNode:(SCNNode *)aNode zPosition:(int)aZPosition
{
if ([self init])
{
self.node = aNode;
[self.node removeAllActions];
//rotate jet 90 degrees on Y axis, facing right edge of screen
GLKQuaternion rot = GLKQuaternionMakeWithAngleAndAxis(M_PI_2, 0, 1, 0);
self.node.orientation = SCNVector4Make(rot.x, rot.y, rot.z, rot.w);
self.node.position = SCNVector3Make(0, 0, aZPosition);
}
return self;
}
@end
@interface GameViewController: UIViewController<SCNSceneRendererDelegate>
@end
@implementation GameViewController
{
SCNScene * skScene;
SCNView * skView;
SCNNode * cameraNode;
NSMutableArray * nodeSnapshots;
NSDate * frameTimer;
ESJet * jet;
}
-(void)viewDidLoad
{
//default project code here...
skScene = scene;
skView = scnView;
skView.delegate = self;
skView.playing = YES;
nodeSnapshots = [NSMutableArray array];
jet = [[ESJet alloc] initWithNode:ship zPosition:-20];
jet.roll = YES;
}
//SCNSceneRendererDelegate
-(void)renderer:(id<SCNSceneRenderer>)aRenderer updateAtTime:(NSTimeInterval)time
{
void (^cloneNode)() = ^
{
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(q, ^
{
SCNNode * clone = [jet.node clone];
clone.opacity = 0.20f;
[nodeSnapshots addObject:clone];
[skScene.rootNode addChildNode:clone];
});
};
void (^cloneNodeOnTimer)(float) = ^(float interval)
{
if ((frameTimer == nil) || (frameTimer.timeIntervalSinceNow <= -interval))
{
frameTimer = [NSDate date];
cloneNode();
}
};
//SCNSceneRenderer protocol
BOOL nodeIsVisible = [aRenderer isNodeInsideFrustum:jet.node withPointOfView:cameraNode];
if (nodeIsVisible)
{
cloneNodeOnTimer(0.6f);
}
else
{
skView.playing = NO;
jet.node.hidden = YES;
if (nodeSnapshots.count > 0)
{
//remove transparency from last cloned node
((SCNNode *)[nodeSnapshots lastObject]).opacity = 1.0;
}
}
[jet update:time isVisible:nodeIsVisible];
}
//tap any node to render new scene
-(void)handleTap:(UIGestureRecognizer*)gestureRecognize
{
CGPoint tp = [gestureRecognize locationInView:skView];
NSArray * hitTestResults = [skView hitTest:tp options:nil];
if (hitTestResults.count > 0)
{
[nodeSnapshots enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL * stop)
{
[(SCNNode *)obj removeFromParentNode];
}];
[nodeSnapshots removeAllObjects];
jet.node.hidden = NO;
skView.playing = YES;
}
}
3/15/15
iOS Gradient View with Clipped Path
Custom gradient view with support for 3 shapes: default, circle, circle-outline.
Copy path with CGPathCreateCopyByStrokingPath, clip, then draw gradient.

Copy path with CGPathCreateCopyByStrokingPath, clip, then draw gradient.

//swift
import UIKit
class ViewController: UIViewController
{
override func viewDidLoad()
{
super.viewDidLoad()
var gv = [ESGradientView]()
var x = 100
for i in 0...5
{
var g = ESGradientView()
g.frame = CGRect(x:x, y:200, width:100, height:100)
g.gradientColors = i < 3 ? g.gradientColors : [UIColor.redColor().CGColor, UIColor.blackColor().CGColor]
gv.append(g)
self.view.addSubview(g)
x += 110
}
gv[1].shape = .Circle
gv[2].shape = .CircleOutline
gv[4].shape = .Circle
gv[5].shape = .CircleOutline
gv[5].circleOutlineWidth = 1
}
}
class ESGradientView: UIView
{
enum Shape
{
case Default, Circle, CircleOutline
}
var shape = Shape.Default
var circleOutlineWidth:Int = 4
var gradientColors = [UIColor.redColor().CGColor, UIColor.blueColor().CGColor]
var gradientLocations:[CGFloat] = [0, 1]
var gradientEndOffset:CGFloat = 20
override func drawRect(rect: CGRect)
{
var context = UIGraphicsGetCurrentContext()
if (shape == .Circle)
{
let path = getCirclePath(1)
path.addClip()
}
else if (shape == .CircleOutline)
{
let path = getCirclePath(circleOutlineWidth + 2)
var pathRef = CGPathCreateCopyByStrokingPath(path.CGPath, nil, CGFloat(circleOutlineWidth), kCGLineCapRound, kCGLineJoinRound, 1)
UIBezierPath(CGPath: pathRef).addClip()
}
var gradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), gradientColors, gradientLocations)
let gradientEndPoint = CGPointMake(bounds.width - gradientEndOffset, bounds.height - gradientEndOffset)
CGContextDrawLinearGradient(context, gradient!, CGPointZero, gradientEndPoint, UInt32(kCGGradientDrawsAfterEndLocation))
}
func getCirclePath(inset:Int) -> UIBezierPath
{
let center = CGFloat(bounds.width * 0.5)
let radius = CGFloat(center * CGFloat(100 - inset) * 0.01)
let centerPoint = CGPointMake(center, center)
var cp = UIBezierPath(arcCenter:centerPoint, radius:radius, startAngle:0, endAngle:CGFloat(M_PI * 2), clockwise:true)
return cp
}
}
3/7/15
We Can Has WWDC Session Videoz Descriptions?
Javascript to show all WWDC session video descriptions.
Expands sessions to show descriptions and view search matches. *
To use, copy and paste script into browser console and then call show() function.
WWDC
2014
2013
2012
2011
2010
* Usability clue for Apple Web Dev Team
Expands sessions to show descriptions and view search matches. *
To use, copy and paste script into browser console and then call show() function.
var sessions = $$('li.session')
function show()
{
toggle('session active');
}
function hide()
{
toggle('session');
}
function toggle(css)
{
for (var i = 0; i < sessions.length; i++)
{
sessions[i].className = css;
}
}
WWDC
2014
2013
2012
2011
2010
* Usability clue for Apple Web Dev Team
"We can't wait to show you."
2/28/15
iOS Draw Along Bezier Quad Curve Path
//swift
var bp = UIBezierPath()
let startPoint = CGPointMake(200, 400)
let endPoint = CGPointMake(500, 400)
let controlPoint = CGPointMake(350, 150)
bp.moveToPoint(startPoint)
bp.addQuadCurveToPoint(endPoint, controlPoint:controlPoint)
var vp = CAShapeLayer() //debug visual path
vp.path = bp.CGPath
vp.fillColor = UIColor.clearColor().CGColor
vp.strokeColor = UIColor.darkGrayColor().CGColor
vp.lineWidth = 1.0
self.view.layer.addSublayer(vp)
//http://en.wikipedia.org/wiki/Bezier_curve#Quadratic_B.C3.A9zier_curves
func getBezierQuadXY(t:CGFloat, p0:CGFloat, p1:CGFloat, p2:CGFloat) -> CGFloat
{
return ((1-t) * (1-t)) * p0 + 2 * (1-t) * t * p1 + t * t * p2
}
func addNode(pathPercent:CGFloat)
{
var node = CALayer()
node.frame = CGRectMake(0, 0, 20, 20)
node.cornerRadius = 10.0
node.borderColor = UIColor.darkGrayColor().CGColor
node.borderWidth = 1.0
let p = CGPointMake(getBezierQuadXY(pathPercent, startPoint.x, controlPoint.x, endPoint.x),
getBezierQuadXY(pathPercent, startPoint.y, controlPoint.y, endPoint.y))
node.position = p
self.view.layer.addSublayer(node)
}
addNode(0.5)
addNode(0.7)
addNode(0.8)
addNode(0.89)
addNode(1.0)
2/24/15
iOS Autolayout Constraints on Stacked Views




The containing view (gray border) vertically resizes to fit child views.
Containing view is hidden when child view heights total 0.
5 screenshots
1. View layout before applying constraints
2. 3 child views, heights 100
3. Green view height 0
4. Green and blue view height 0
5. Red view height 20, green view height 40
@implementation ViewController
{
UIView * cv; //container view, clear w/gray border
UIView * tv; //top view, red
UIView * mv; //middle view, green
UIView * bv; //bottom view, blue
NSDictionary * bindings;
NSMutableArray * verticalConstraints;
}
-(void)viewDidLoad
{
[super viewDidLoad];
[self createControls];
[self setupConstraints];
}
-(void)setupConstraints
{
self.view.translatesAutoresizingMaskIntoConstraints = NO;
cv.translatesAutoresizingMaskIntoConstraints = NO;
tv.translatesAutoresizingMaskIntoConstraints = NO;
mv.translatesAutoresizingMaskIntoConstraints = NO;
bv.translatesAutoresizingMaskIntoConstraints = NO;
bindings = NSDictionaryOfVariableBindings(cv, tv, mv, bv);
verticalConstraints = [NSMutableArray array];
[self setupHorizontalConstraints];
[self setupVerticalConstraints];
}
-(void)setupHorizontalConstraints
{
NSMutableArray * hConstraints = [NSMutableArray array];
//container view
[hConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[cv(200)]"
options:0
metrics:nil
views:bindings]];
//top view
[hConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[tv]-|"
options:0
metrics:nil
views:bindings]];
//match middle view w/top view
[hConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[mv(tv)]"
options:0
metrics:nil
views:bindings]];
//match bottom view w/top view
[hConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[bv(tv)]"
options:0
metrics:nil
views:bindings]];
[self.view addConstraints:hConstraints];
}
-(void)setupVerticalConstraints
{
[self.view removeConstraints:verticalConstraints];
[verticalConstraints removeAllObjects];
[verticalConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[cv]-20-|"
options:0
metrics:nil
views:bindings]];
//view heights, container vertical margin
NSDictionary * metrics = @{ @"th" : @(tv.frame.size.height),
@"mh" : @(mv.frame.size.height),
@"bh" : @(bv.frame.size.height),
@"cm" : @(tv.frame.size.height + mv.frame.size.height + bv.frame.size.height > 0 ? 8 : 0) };
[verticalConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-cm-[tv(th)][mv(mh)][bv(bh)]-cm-|"
options:NSLayoutFormatAlignAllCenterX
metrics:metrics
views:bindings]];
[self.view addConstraints:verticalConstraints];
}
//init controls w/temp width and position for general layout, before implementing constraints
-(void)createControls
{
int vWidth = 100;
int vHeight = 100;
int cHeight = vHeight * 3;
cv = [[UIView alloc] initWithFrame:CGRectMake(20, 20, vWidth, cHeight)];
tv = [[UIView alloc] initWithFrame:CGRectMake(10, 0, vWidth, vHeight)];
mv = [[UIView alloc] initWithFrame:CGRectMake(10, 100, vWidth, vHeight)];
bv = [[UIView alloc] initWithFrame:CGRectMake(10, 200, vWidth, vHeight)];
cv.layer.borderColor = [UIColor lightGrayColor].CGColor;
cv.layer.borderWidth = 1;
tv.backgroundColor = [UIColor redColor];
mv.backgroundColor = [UIColor greenColor];
bv.backgroundColor = [UIColor blueColor];
[self.view addSubview:cv];
[cv addSubview:tv];
[cv addSubview:mv];
[cv addSubview:bv];
}
-(void)hideView:(UIView *)aView
{
aView.frame = CGRectMake(0, 0, aView.frame.size.width, 0);
[self setupVerticalConstraints];
}
-(void)resizeView:(UIView *)aView height:(int)aHeight
{
aView.frame = CGRectMake(0, 0, aView.frame.size.width, aHeight);
[self setupVerticalConstraints];
}
-(void)showView:(UIView *)aView
{
aView.frame = CGRectMake(0, 0, aView.frame.size.width, 100);
[self setupVerticalConstraints];
}
Subscribe to:
Posts (Atom)