It works by scope as defined by the language, so python may be indentation level, ruby might be “begin” “end”, etc.
Just as option right/left moves by words, think of scope navigation the same, but nested. Down: first go to the end of the next same level scope, if there are no more same level scopes, then go to the end of the current scope and pop up one scope level.
Pseudo:
Scope 1 begin
Scope 2 being
Scope 3 begin
Scope 3 end
Scope 2 end
Scope 4 begin
Scope 4 end
Scope 5 begin
Scope 5 end
Scope 1 end
From Scope 3 begin the Option-down sequence is: Jump to end of scope 3, Pop to end of scope 2, Jump to end of Scope 4, Jump to end of Scope 5, Pop to end of Scope 1.
Here’s an example using javascript:
1:function foo (bar, baz) {
^(1)
2: var x
^(2)
3: if(bar){
^(3)
4: for(var i; i<200;i++) {
^(4)
5: if(i*bar > 1000) {
^(5)^(6)
6: doSomething(i)
7: x = getSomething(i)
^(7)
8: console.log(x)
9: break;
10: }
^(8)
11: else {
12: console.log("no")
^(9)
13: }
^(10)
14: if(i^bar > baz) {
15: doSomethingElse(baz)
16: x = getSomething(i)
17: }
^(11)
18: }
^(12)
19: doSomething2()
20: }
^(13)
21: return x
22:}
Option-down for the following locations:
#1 - Jump to line 22.
#2 - Jump to line 20.
#3 - Jump to line 20.
#4 - Jump to line 18.
#5,#6 - Jump to line 10. (see “Column consideration” below)
#7 - Jump to line 10.
#8 - Jump to line 13.
#9 - Jump to line 13.
#10 - Jump to line 11. (end of next scope)
#11 - Jump to line 12. (pop scope)
#12 - Jump to line 13. (pop scope)
Option-up is similar in reverse:
#13 - Jump to line 3.
#12 - Jump to line 4.
#11 - Jump to line 14.
etc.
Column consideration:
If I recall correctly if the caret is on or after a column that starts a scope it’s considered ‘in’ that scope. So, for example, #6 is in the “if(i*bar …” scope, #5 is in the “if(bar)” scope from line 3. However, taking column/indentation into account isn’t a critical feature to me. It’s good enough just to use the scope at the beginning of the current line.