assorted-commits Mailing List for Assorted projects (Page 14)
Brought to you by:
yangzhang
You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(9) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
(86) |
Feb
(265) |
Mar
(96) |
Apr
(47) |
May
(136) |
Jun
(28) |
Jul
(57) |
Aug
(42) |
Sep
(20) |
Oct
(67) |
Nov
(37) |
Dec
(34) |
2009 |
Jan
(39) |
Feb
(85) |
Mar
(96) |
Apr
(24) |
May
(82) |
Jun
(13) |
Jul
(10) |
Aug
(8) |
Sep
(2) |
Oct
(20) |
Nov
(31) |
Dec
(17) |
2010 |
Jan
(16) |
Feb
(11) |
Mar
(17) |
Apr
(53) |
May
(31) |
Jun
(13) |
Jul
(3) |
Aug
(6) |
Sep
(11) |
Oct
(4) |
Nov
(17) |
Dec
(17) |
2011 |
Jan
(3) |
Feb
(19) |
Mar
(5) |
Apr
(17) |
May
(3) |
Jun
(4) |
Jul
(14) |
Aug
(3) |
Sep
(2) |
Oct
(1) |
Nov
(3) |
Dec
(2) |
2012 |
Jan
(3) |
Feb
(7) |
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
(4) |
Aug
(5) |
Sep
(2) |
Oct
(3) |
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
(9) |
Apr
(5) |
May
|
Jun
(2) |
Jul
(1) |
Aug
(10) |
Sep
(1) |
Oct
(2) |
Nov
|
Dec
|
2014 |
Jan
(1) |
Feb
(3) |
Mar
(3) |
Apr
(1) |
May
(4) |
Jun
|
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2016 |
Jan
(1) |
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2017 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <yan...@us...> - 2010-03-03 22:58:47
|
Revision: 1577 http://assorted.svn.sourceforge.net/assorted/?rev=1577&view=rev Author: yangzhang Date: 2010-03-03 22:58:40 +0000 (Wed, 03 Mar 2010) Log Message: ----------- added demo of empty lines (isolated island vertices) in metis Added Paths: ----------- sandbox/trunk/src/misc/metis/ sandbox/trunk/src/misc/metis/Makefile sandbox/trunk/src/misc/metis/README sandbox/trunk/src/misc/metis/graph.txt sandbox/trunk/src/misc/metis/graph.txt.part.2 Added: sandbox/trunk/src/misc/metis/Makefile =================================================================== --- sandbox/trunk/src/misc/metis/Makefile (rev 0) +++ sandbox/trunk/src/misc/metis/Makefile 2010-03-03 22:58:40 UTC (rev 1577) @@ -0,0 +1,2 @@ +graph.txt.part.2: graph.txt + kmetis5.0pre2 graph.txt 2 Added: sandbox/trunk/src/misc/metis/README =================================================================== --- sandbox/trunk/src/misc/metis/README (rev 0) +++ sandbox/trunk/src/misc/metis/README 2010-03-03 22:58:40 UTC (rev 1577) @@ -0,0 +1 @@ +demo of empty lines (isolated island vertices) in metis Added: sandbox/trunk/src/misc/metis/graph.txt =================================================================== --- sandbox/trunk/src/misc/metis/graph.txt (rev 0) +++ sandbox/trunk/src/misc/metis/graph.txt 2010-03-03 22:58:40 UTC (rev 1577) @@ -0,0 +1,11 @@ +10 12 +5 3 2 +1 3 4 +5 4 2 1 +2 3 6 7 +1 3 6 +5 4 7 +6 4 + +10 +9 Added: sandbox/trunk/src/misc/metis/graph.txt.part.2 =================================================================== --- sandbox/trunk/src/misc/metis/graph.txt.part.2 (rev 0) +++ sandbox/trunk/src/misc/metis/graph.txt.part.2 2010-03-03 22:58:40 UTC (rev 1577) @@ -0,0 +1,10 @@ +0 +0 +0 +0 +0 +0 +0 +1 +1 +1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-03 06:16:14
|
Revision: 1576 http://assorted.svn.sourceforge.net/assorted/?rev=1576&view=rev Author: yangzhang Date: 2010-03-03 06:16:08 +0000 (Wed, 03 Mar 2010) Log Message: ----------- fix Modified Paths: -------------- scala-commons/trunk/src/commons/Collections.scala Modified: scala-commons/trunk/src/commons/Collections.scala =================================================================== --- scala-commons/trunk/src/commons/Collections.scala 2010-03-03 05:54:59 UTC (rev 1575) +++ scala-commons/trunk/src/commons/Collections.scala 2010-03-03 06:16:08 UTC (rev 1576) @@ -778,7 +778,7 @@ if (iter hasNext) { val x = iter.next if (p(x)) loop - else Iterator single x ++ iter + else (Iterator single x) ++ iter } else { iter } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-03 05:55:05
|
Revision: 1575 http://assorted.svn.sourceforge.net/assorted/?rev=1575&view=rev Author: yangzhang Date: 2010-03-03 05:54:59 +0000 (Wed, 03 Mar 2010) Log Message: ----------- more fixes; link to grizzled Modified Paths: -------------- scala-commons/trunk/README scala-commons/trunk/src/commons/Collections.scala scala-commons/trunk/src/commons/Control.scala Modified: scala-commons/trunk/README =================================================================== --- scala-commons/trunk/README 2010-03-03 00:33:42 UTC (rev 1574) +++ scala-commons/trunk/README 2010-03-03 05:54:59 UTC (rev 1575) @@ -41,7 +41,7 @@ Changes ------- -version 0.3 +version 0.2 - updated for Scala 2.8 - imported code from RelationalCloud project @@ -60,10 +60,6 @@ - `Collections.iterator2array` - `Collections.concat` deprecated by `xs reduceLeft (_ ++ _)` -version 0.2 - -- updated for Scala 2.7.2 - version 0.1 - initial release, for use with Scala 2.7.0 @@ -74,10 +70,12 @@ Code found here generally tries to complement code in the following other handy libraries: +- the [Grizzled] utility library - the [Scala standard library] -- the [ScalaX] community library +- the [ScalaX] community library (not actively maintained) - the [ScalaZ] library [Scala standard library]: http://www.scala-lang.org/docu/files/api/ -[scalax]: http://scalax.scalaforge.org/ -[scalaz]: http://wiki.workingmouse.com/index.php/Scalaz +[ScalaX]: http://scalax.scalaforge.org/ +[ScalaZ]: http://wiki.workingmouse.com/index.php/Scalaz +[Grizzled]: http://www.clapper.org/software/scala/grizzled-scala/ Modified: scala-commons/trunk/src/commons/Collections.scala =================================================================== --- scala-commons/trunk/src/commons/Collections.scala 2010-03-03 00:33:42 UTC (rev 1574) +++ scala-commons/trunk/src/commons/Collections.scala 2010-03-03 05:54:59 UTC (rev 1575) @@ -2,9 +2,6 @@ import scala.collection.{mutable => mut} -// TODO: Is there a way to avoid having to explicitly handle both Iterators and -// Iterables? - // TODO: Pretty much anywhere I take a number, I'd like to make the facility // more general, but without (say) incurring the reflection costs associated // with structural typing. @@ -781,7 +778,7 @@ if (iter hasNext) { val x = iter.next if (p(x)) loop - else Iterator single x append iter + else Iterator single x ++ iter } else { iter } Modified: scala-commons/trunk/src/commons/Control.scala =================================================================== --- scala-commons/trunk/src/commons/Control.scala 2010-03-03 00:33:42 UTC (rev 1574) +++ scala-commons/trunk/src/commons/Control.scala 2010-03-03 05:54:59 UTC (rev 1575) @@ -13,16 +13,6 @@ finally { x.close } /** - * Time some code. - */ - def time(f: =>Any): Long = { - val start = System.currentTimeMillis - f - val stop = System.currentTimeMillis - stop - start - } - - /** * Return Some(f) if the function succeeded, or None if there was an * Exception. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-03 00:33:48
|
Revision: 1574 http://assorted.svn.sourceforge.net/assorted/?rev=1574&view=rev Author: yangzhang Date: 2010-03-03 00:33:42 +0000 (Wed, 03 Mar 2010) Log Message: ----------- added start of (broken) RichIterator test Added Paths: ----------- scala-commons/trunk/src/test/commons/ scala-commons/trunk/src/test/commons/RichIterator.scala Added: scala-commons/trunk/src/test/commons/RichIterator.scala =================================================================== --- scala-commons/trunk/src/test/commons/RichIterator.scala (rev 0) +++ scala-commons/trunk/src/test/commons/RichIterator.scala 2010-03-03 00:33:42 UTC (rev 1574) @@ -0,0 +1,18 @@ +package commons + +import org.specs._ + +class RichIteratorTest extends Specification { + def testIter { + val xs = 0 to 5 toList; + for ((k,chunk) <- xs.iterator chunkAs (x => (x/2, x))) + for (x <- chunk) + println(k + " " + x) + for ((k,chunk) <- xs.iterator iterChunkAs (x => (x/2, x))) + for (x <- chunk) + println(k + " " + x) + for (split <- xs iterSplitOn (_ % 3 == 0)) + for (x <- split) + println(x) + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-03 00:12:40
|
Revision: 1573 http://assorted.svn.sourceforge.net/assorted/?rev=1573&view=rev Author: yangzhang Date: 2010-03-03 00:12:34 +0000 (Wed, 03 Mar 2010) Log Message: ----------- imported code from RelationalCloud project; more fixes to build on scala 2.8 Modified Paths: -------------- scala-commons/trunk/README scala-commons/trunk/src/commons/Collections.scala scala-commons/trunk/src/commons/Control.scala scala-commons/trunk/src/commons/Io.scala scala-commons/trunk/src/commons/Misc.scala Added Paths: ----------- scala-commons/trunk/src/commons/Jdbc.scala scala-commons/trunk/src/commons/RichIterator.scala scala-commons/trunk/src/commons/TableFormatter.scala scala-commons/trunk/src/commons/Timer.scala Modified: scala-commons/trunk/README =================================================================== --- scala-commons/trunk/README 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/README 2010-03-03 00:12:34 UTC (rev 1573) @@ -44,6 +44,14 @@ version 0.3 - updated for Scala 2.8 +- imported code from RelationalCloud project + - Closeable views + - Jdbc + - RichIterator + - TableFormatter + - Timer + - `in` operator + - removeCBlockComments - removed unnecessary functions - `Collections.sortCounts` deprecated by `SeqLike.sortBy` - `Collections.take` deprecated by `List.take Modified: scala-commons/trunk/src/commons/Collections.scala =================================================================== --- scala-commons/trunk/src/commons/Collections.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Collections.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -12,6 +12,19 @@ object Collections { // + // Convenience + // + + /** + * Let yourself write `x in xs`. + **/ + class InOperand[A](x: A) { + def in(xs: Seq[A]) = xs contains x + def notIn(xs: Seq[A]) = !(xs contains x) + } + implicit def toInOperand[A](x: A) = new InOperand(x) + + // // Tuples // @@ -141,10 +154,7 @@ // TODO: The next line induces a bug in Scala. // val (x,y): (Seq[a],Seq[a]) = spanBy(s)(f(_) == cur) val (x,y) = spanBy(s)(f(_) == cur) - Stream.cons( - Stream fromIterator x.iterator, - r(Stream fromIterator y.iterator) - ) + Stream.cons(x.toStream, r(y.toStream)) } case Stream.Empty => Stream.Empty } @@ -518,7 +528,7 @@ */ def indexGroups[a,b](xs: Seq[a])(f: a => b) = { val i = Iterator from 0 - xs.toStream.iterator chunkBy f map (_ map (x => i.next)) + xs.iterator.toStream chunkBy f map (_ map (x => i.next)) } /** @@ -658,7 +668,7 @@ */ def show(showLeaf: a => String): String = { def r(t: Tree[a]): Stream[String] = t match { - case Branch(ts) => (ts map r flatten) map (" " + _) + case Branch(ts) => (ts.toStream map r flatten) map (" " + _) case Leaf(x) => List(showLeaf(x)) toStream } r(this) mkString "\n" @@ -675,7 +685,7 @@ * Flatten the leaves into a single stream. */ def flatten: Stream[a] = this match { - case Branch(ts) => (ts map (_.flatten) flatten) + case Branch(ts) => (ts.toStream map (_.flatten) flatten) case Leaf(x) => Stream cons (x, Stream empty) } } @@ -699,7 +709,7 @@ def r(n: TreeNode[a], lvl: Int): Stream[String] = { Stream cons ( " " * lvl + n.value, - (n.children map (n => r(n, lvl+1)) flatten) + (n.children.toStream map (n => r(n, lvl+1)) flatten) ) } r(this,0) mkString "\n" @@ -724,8 +734,8 @@ case Leaf(x) => Leaf(f(x)) } def flatten[b](f: a => b): Stream[b] = this match { - case And(ts) => (ts map (_ flatten f) flatten) - case Or(ts) => (ts map (_ flatten f) flatten) + case And(ts) => (ts.toStream map (_ flatten f) flatten) + case Or(ts) => (ts.toStream map (_ flatten f) flatten) case Not(t) => t flatten f case Leaf(x) => Stream cons (f(x), Stream empty) } Modified: scala-commons/trunk/src/commons/Control.scala =================================================================== --- scala-commons/trunk/src/commons/Control.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Control.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -43,7 +43,7 @@ /** * Invoke f(i) for all i from 0 on. */ - def loop[a](f: Int => a) = for (val x <- Stream from 0) f(x) + def loop[a](f: Int => a) = for (x <- Stream from 0) f(x) /** * Stream the repetition of f. Modified: scala-commons/trunk/src/commons/Io.scala =================================================================== --- scala-commons/trunk/src/commons/Io.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Io.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -22,6 +22,13 @@ implicit def Reader2TextReader(r: Reader) = TextReader(r) implicit def TextReader2Reader(tr: TextReader) = tr.in + implicit def writer2closeable(w: java.io.Writer) = + new Closeable { def close = w.close } + implicit def raf2closeable(f: java.io.RandomAccessFile) = + new Closeable { def close = f.close } + implicit def istream2closeable(i: java.io.InputStream) = + new Closeable { def close = i.close } + // // Files // Added: scala-commons/trunk/src/commons/Jdbc.scala =================================================================== --- scala-commons/trunk/src/commons/Jdbc.scala (rev 0) +++ scala-commons/trunk/src/commons/Jdbc.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,120 @@ +// Based on <http://scala.sygneca.com/code/simplifying-jdbc>. + +package commons + +import java.sql.{DriverManager, Connection, ResultSet, PreparedStatement, Statement, Date, Timestamp}; + +object Jdbc { + private def strm[X](f: RichResultSet => X, rs: ResultSet): Stream[X] = + if (rs.next) Stream.cons(f(new RichResultSet(rs)), strm(f, rs)) + else { rs.close(); Stream.empty }; + + implicit def conn2Statement(conn: Connection): Statement = conn.createStatement; + + implicit def query[X](s: String, f: RichResultSet => X)(implicit stat: Statement) = { + strm(f,stat.executeQuery(s)); + } + + private def iter[X](f: RichResultSet => X, rs: ResultSet) = new Iterator[X] { + var lastNext = rs.next + def hasNext = lastNext + def next = { + if (!lastNext) throw new Exception + val ret = f(new RichResultSet(rs)) + lastNext = rs.next + ret + } + } + + implicit def iquery[X](s: String, f: RichResultSet => X)(implicit stmt: Statement) = { + iter(f,stmt.executeQuery(s)) + } + + implicit def rrs2Boolean(rs: RichResultSet) = rs.nextBoolean; + implicit def rrs2Byte(rs: RichResultSet) = rs.nextByte; + implicit def rrs2Int(rs: RichResultSet) = rs.nextInt; + implicit def rrs2Long(rs: RichResultSet) = rs.nextLong; + implicit def rrs2Float(rs: RichResultSet) = rs.nextFloat; + implicit def rrs2Double(rs: RichResultSet) = rs.nextDouble; + implicit def rrs2String(rs: RichResultSet) = rs.nextString; + implicit def rrs2Date(rs: RichResultSet) = rs.nextDate; + implicit def rrs2Timestamp(rs: RichResultSet) = rs.nextTimestamp; + + implicit def resultSet2Rich(rs: ResultSet) = new RichResultSet(rs); + implicit def rich2ResultSet(r: RichResultSet) = r.rs; + class RichResultSet(val rs: ResultSet) { + + var pos = 1 + def apply(i: Int) = { pos = i; this } + + def nextBoolean: Boolean = { val ret = rs.getBoolean(pos); pos = pos + 1; ret } + def nextByte: Byte = { val ret = rs.getByte(pos); pos = pos + 1; ret } + def nextInt: Int = { val ret = rs.getInt(pos); pos = pos + 1; ret } + def nextLong: Long = { val ret = rs.getLong(pos); pos = pos + 1; ret } + def nextFloat: Float = { val ret = rs.getFloat(pos); pos = pos + 1; ret } + def nextDouble: Double = { val ret = rs.getDouble(pos); pos = pos + 1; ret } + def nextString: String = { val ret = rs.getString(pos); pos = pos + 1; ret } + def nextDate: Date = { val ret = rs.getDate(pos); pos = pos + 1; ret } + def nextTimestamp: Timestamp = { val ret = rs.getTimestamp(pos); pos = pos + 1; ret } + + def foldLeft[X](init: X)(f: (ResultSet, X) => X): X = rs.next match { + case false => init + case true => foldLeft(f(rs, init))(f) + } + def map[X](f: ResultSet => X) = { + var ret = List[X]() + while (rs.next()) + ret = f(rs) :: ret + ret.reverse; // ret should be in the same order as the ResultSet + } + } + + implicit def ps2Rich(ps: PreparedStatement) = new RichPreparedStatement(ps); + implicit def rich2PS(r: RichPreparedStatement) = r.ps; + + implicit def str2RichPrepared(s: String)(implicit conn: Connection): RichPreparedStatement = conn prepareStatement(s); + + class RichPreparedStatement(val ps: PreparedStatement) { + var pos = 1; + private def inc = { pos = pos + 1; this } + + def execute[X](f: RichResultSet => X): Stream[X] = { + pos = 1; strm(f, ps.executeQuery) + } + def <<: Stream[X] = execute(f); + + def execute = { pos = 1; ps.execute } + def <<! = execute; + + def addBatch = { pos = 1; ps.addBatch } + def executeBatch = { pos = 1; ps.executeBatch } + + def <<(b: Boolean) = { ps.setBoolean(pos, b); inc } + def <<(x: Byte) = { ps.setByte(pos, x); inc } + def <<(i: Int) = { ps.setInt(pos, i); inc } + def <<(x: Long) = { ps.setLong(pos, x); inc } + def <<(f: Float) = { ps.setFloat(pos, f); inc } + def <<(d: Double) = { ps.setDouble(pos, d); inc } + def <<(o: String) = { ps.setString(pos, o); inc } + def <<(x: Date) = { ps.setDate(pos, x); inc } + def <<(x: Timestamp) = { ps.setTimestamp(pos, x); inc } + } + + implicit def conn2Rich(conn: Connection) = new RichConnection(conn); + + class RichConnection(val conn: Connection) { + def <<(sql: String) = new RichStatement(conn.createStatement) << sql; + def <<(sql: Seq[String]) = new RichStatement(conn.createStatement) << sql; + } + + implicit def st2Rich(s: Statement) = new RichStatement(s); + implicit def rich2St(rs: RichStatement) = rs.s; + + class RichStatement(val s: Statement) { + def <<(sql: String) = { s.execute(sql); this } + def <<(sql: Seq[String]) = { for (x <- sql) s.execute(x); this } + } + + def queryOne(s: String)(implicit stat: Statement) = + query(s, rs => rs:Int).head +} Modified: scala-commons/trunk/src/commons/Misc.scala =================================================================== --- scala-commons/trunk/src/commons/Misc.scala 2010-03-02 22:53:31 UTC (rev 1572) +++ scala-commons/trunk/src/commons/Misc.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -90,4 +90,10 @@ override def next = base + i.next override def hasNext = i.hasNext } + + /** + * Remove C block comments. + */ + def removeCBlockComments(s: String) = s.replaceAll("/\\*(?:.|[\\n\\r])*?\\*/", "") + } Added: scala-commons/trunk/src/commons/RichIterator.scala =================================================================== --- scala-commons/trunk/src/commons/RichIterator.scala (rev 0) +++ scala-commons/trunk/src/commons/RichIterator.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,72 @@ +package commons + +import scala.collection.{mutable => mut} + +class RichIterator[X](it: Iterator[X]) { + /** Note that this is dangerous in that the states of the sub-iterators and + * the iterator are tightly coupled. */ + def iterChunkAs[K,Y](f: X => (K,Y)) = new Iterator[(K,Iterator[Y])] { + var xform = if (it.hasNext) Some(f(it.next)) else None + def hasNext = xform != None + def next = { + if (!hasNext) throw new Exception + val key = xform.get._1 + val subiter = new Iterator[Y] { + def hasNext = xform != None && xform.get._1 == key + // as long as we're not past the end and we're on the active key + def next = { + if (!hasNext) throw new Exception + val ret = xform.get._2 + xform = if (it.hasNext) Some(f(it.next)) else None + ret + } + } + (key, subiter) + } + } + def iterChunkBy[K](f: X => K) = iterChunkAs(x => (f(x), x)) + + def iterSplitOn(isCut: X => Boolean) = new Iterator[Iterator[X]] { + var fresh = true + def next: Iterator[X] = { + if (fresh) fresh = false + else it dropWhile isCut + it takeWhile (!isCut(_)) + } + def hasNext:Boolean = fresh || { it dropWhile isCut; it hasNext } + } + + def chunkAs[K,Y](f: X => (K,Y)) = new Iterator[(K,Seq[Y])] { + val bit = it.buffered + def hasNext = bit.hasNext // nextElt != None + def next = { + if (!bit.hasNext) throw new Exception + val chunk = new mut.ArrayBuffer[Y] + var xform = f(bit.head) // (nextElt.get) + val key = xform._1 + // as long as we're not past the end and we're on the active key + while (bit.hasNext && xform._1 == key) { + chunk += xform._2 + bit.next // consume it + if (bit.hasNext) xform = f(bit.head) + } + (key, chunk) + } + } + def chunkBy[K](f: X => K) = chunkAs(x => (f(x), x)) +} + +class CachedIterator[X](it: Iterator[X]) extends Iterator[X] { + var last: X = _ + def hasNext = it.hasNext + def next = { + last = it.next + last + } +} + +object RichIterator { + implicit def toRichIterator[X](it: Iterator[X]) = new RichIterator(it) + implicit def toRichIterator[X](it: Iterable[X]) = new RichIterator(it.iterator) + implicit def toRichIterator[X](it: Array[X]) = new RichIterator(it.iterator) +} Added: scala-commons/trunk/src/commons/TableFormatter.scala =================================================================== --- scala-commons/trunk/src/commons/TableFormatter.scala (rev 0) +++ scala-commons/trunk/src/commons/TableFormatter.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,13 @@ +package commons + +case class TableFormatter(val rows: Iterable[List[Any]]) { + val xss = rows map (_ map (_ toString) toArray) toArray + override def toString = { + val fmt = ( + for ((x,i) <- xss(0).zipWithIndex) yield { + "%" + (xss map (_(i).length) reduceLeft (Math.max(_,_))) + "s" + } + ).mkString(" | ") + xss map (String.format(fmt, _: _*)) mkString "\n" + } +} Added: scala-commons/trunk/src/commons/Timer.scala =================================================================== --- scala-commons/trunk/src/commons/Timer.scala (rev 0) +++ scala-commons/trunk/src/commons/Timer.scala 2010-03-03 00:12:34 UTC (rev 1573) @@ -0,0 +1,26 @@ +package commons + +object Timer { + + /** + * Return the time in milliseconds taken to run f. + */ + def time(f: =>Any): Long = { + val start = System.currentTimeMillis + f + val stop = System.currentTimeMillis + stop - start + } + + /** + * Evaluate f, printing the time it took. + */ + def printTime[A](f: =>A) = { + val start = System.currentTimeMillis + val ret = f + val stop = System.currentTimeMillis + println("...took " + (stop - start) / 1000. + " s") + ret + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-02 22:53:37
|
Revision: 1572 http://assorted.svn.sourceforge.net/assorted/?rev=1572&view=rev Author: yangzhang Date: 2010-03-02 22:53:31 +0000 (Tue, 02 Mar 2010) Log Message: ----------- updated Collections to build with scala 2.8; added notes to README Modified Paths: -------------- scala-commons/trunk/README scala-commons/trunk/src/commons/Collections.scala Modified: scala-commons/trunk/README =================================================================== --- scala-commons/trunk/README 2010-03-01 05:26:28 UTC (rev 1571) +++ scala-commons/trunk/README 2010-03-02 22:53:31 UTC (rev 1572) @@ -41,6 +41,17 @@ Changes ------- +version 0.3 + +- updated for Scala 2.8 +- removed unnecessary functions + - `Collections.sortCounts` deprecated by `SeqLike.sortBy` + - `Collections.take` deprecated by `List.take + - `Collections.untilNull` deprecated by `Iterator.continually` and + `takeWhile` + - `Collections.iterator2array` + - `Collections.concat` deprecated by `xs reduceLeft (_ ++ _)` + version 0.2 - updated for Scala 2.7.2 Modified: scala-commons/trunk/src/commons/Collections.scala =================================================================== --- scala-commons/trunk/src/commons/Collections.scala 2010-03-01 05:26:28 UTC (rev 1571) +++ scala-commons/trunk/src/commons/Collections.scala 2010-03-02 22:53:31 UTC (rev 1572) @@ -52,7 +52,7 @@ def camelToLower(s: String, sep: String) = { val xs = for (c <- s) - yield if (c.isUpperCase) sep + c.toLowerCase else c + yield if (c.isUpper) sep + c.toLower else c xs mkString "" } def camelToUnder(s: String) = camelToLower(s, "_") @@ -76,8 +76,8 @@ // TODO: Is there a way to "chain" views? Then Iterable2FilterMap is // unnecessary and can be removed. - implicit def Iterable2FilterMap[T](s: Iterable[T]) = new FilterMap(s.elements) - implicit def Iterable2Iterator[T](s: Iterable[T]) = s.elements + implicit def Iterable2FilterMap[T](s: Iterable[T]) = new FilterMap(s.iterator) + implicit def Iterable2Iterator[T](s: Iterable[T]) = s.iterator implicit def Iterator2FilterMap[T](s: Iterator[T]) = new FilterMap(s) class FilterMap[T](s: Iterator[T]) { @@ -107,7 +107,7 @@ */ def last = { var last = i.next - for (val x <- i) { last = x } + for (x <- i) { last = x } last } } @@ -129,14 +129,12 @@ class RichStream[a](val s: Stream[a]) { // TODO: Fix this; it's dangerously inefficient and could cause a stack // overflow (see StreamRecursion test in sandbox)! - // TODO: Rename; confusing enough with groupBy != Haskell's groupBy, which - // is in turn == groupByPairwise. /** * This splits up the stream by using spanBy * <p> - * <code>[1..9].groupBy(_/3) == [[1,2],[3,4,5],[6,7,8]]</code> + * <code>[1..9].chunkBy(_/3) == [[1,2],[3,4,5],[6,7,8]]</code> */ - def groupBy[b](f: a => b) = { + def chunkBy[b](f: a => b) = { def r(s: Stream[a]): Stream[Stream[a]] = s match { case Stream.cons(h,t) => { val cur = f(h) @@ -144,11 +142,11 @@ // val (x,y): (Seq[a],Seq[a]) = spanBy(s)(f(_) == cur) val (x,y) = spanBy(s)(f(_) == cur) Stream.cons( - Stream fromIterator x.elements, - r(Stream fromIterator y.elements) + Stream fromIterator x.iterator, + r(Stream fromIterator y.iterator) ) } - case Stream.empty => Stream.empty + case Stream.Empty => Stream.Empty } r(s) } @@ -163,8 +161,8 @@ def sum(xs: Iterator[Int]) = xs.foldLeft(0)(_+_) def sum(xs: Seq[Double]) = xs reduceLeft ((x:Double,y:Double)=>x+y) def sum(xs: Iterator[Double]) = xs reduceLeft ((_:Double)+(_:Double)) - def mean(xs: Seq[Int]) = sum(xs.elements) / xs.size - def mean(xs: Seq[Double]) = sum(xs.elements) / xs.size + def mean(xs: Seq[Int]) = sum(xs.iterator) / xs.size + def mean(xs: Seq[Double]) = sum(xs.iterator) / xs.size def median(xs: Seq[Long]) = xs(xs.length / 2) import scala.util.Sorting @@ -204,24 +202,7 @@ (min1,min2) } - // TODO: Rename. /** - * Destructively sort the array by the tuples' second elements, and return - * the array. - */ - def sortCounts[a](xs: Array[(a,Int)]) = { - Sorting.stableSort(xs, (p: (a,Int), q: (a,Int)) => p._2 > q._2) - xs - } - - // TODO: Rename. - /** - * Return an array of the mappings in the Map, sorted by their entry-values. - */ - def sortCounts[a](h: mut.Map[a,Int]): Seq[(a,Int)] = - sortCounts(h toArray) - - /** * Given an iterator, return a HashMap from each distinct element to its * count. */ @@ -237,9 +218,7 @@ */ def topHist[a](xs: Iterator[a], n: Int): (mut.HashMap[a,Int], Seq[(a,Int)]) = { val h = hist(xs) - val sorted = sortCounts(h) - val took = take(sorted, n) - (h, took) + (h, h.toArray sortBy (_._2) take n) } /** @@ -283,20 +262,6 @@ } /** - * Return an iterator that yields invocations of f until it returns null. - * Useful for, e.g., Java's IO stream abstractions. - */ - def untilNull[a](f: => a) = new Iterator[a] { - var upcoming = f - override def hasNext = upcoming != null - override def next = { - val emit = upcoming - upcoming = f - emit - } - } - - /** * For each x in xs, if p(x), then x is a header, and it owns all the xs * after it until the next x for which p(x) holds. The return value is the * header and its body. @@ -335,9 +300,7 @@ val h = new mut.HashMap[a,mut.Set[b]] with mut.MultiMap[a,b] { override def makeSet = new mut.HashSet[b] } - for ((k,v) <- xs) { - h add (k,v) - } + for ((k,v) <- xs) h addBinding (k,v) h } @@ -357,11 +320,6 @@ } /** - * Convert an iterator to array. - */ - def iterator2array[a](xs: Iterator[a]) = xs.toList.toArray - - /** * A combination of take and drop. * <p> * <code>span(3)([a,b,c,d,e]) == ([a,b,c],[d,e])</code> @@ -450,7 +408,7 @@ * pairwise([]) == [] * </code> */ - def pairwise[a](xs: Iterable[a]) = xs.elements zip (xs.elements drop 1) + def pairwise[a](xs: Iterable[a]) = xs.iterator zip (xs.iterator drop 1) /** * Same as Haskell's groupBy. Groups together equal elements, letting the @@ -494,7 +452,7 @@ * remaining elements are repeat(gen). */ def pad[a](n: Int, e: => a, s: Iterator[a]) = - Stream.concat(Stream.fromIterator(s), repeat(e)) take n + Stream.concat(s.toStream, repeat(e)) take n /** * Truncate elements off the end of the sequence that satisfy the given @@ -517,13 +475,13 @@ } def argmax(xs: Seq[Int]) = - xs.elements.zipWithIndex reduceLeft { + xs.iterator.zipWithIndex reduceLeft { (a:(Int,Int),b:(Int,Int)) => (a,b) match { case ((x,i),(y,j)) => if (x > y) a else b } } def argmin(xs: Seq[Int]) = - xs.elements.zipWithIndex reduceLeft { + xs.iterator.zipWithIndex reduceLeft { (a:(Int,Int),b:(Int,Int)) => (a,b) match { case ((x,i),(y,j)) => if (x < y) a else b } @@ -560,7 +518,7 @@ */ def indexGroups[a,b](xs: Seq[a])(f: a => b) = { val i = Iterator from 0 - Stream fromIterator xs.elements groupBy f map (_ map (x => i.next)) + xs.toStream.iterator chunkBy f map (_ map (x => i.next)) } /** @@ -576,7 +534,7 @@ * </code> */ def zipx[a](xss: Seq[Iterable[a]]): Stream[Seq[a]] = { - val is = xss map (_.elements) + val is = xss map (_.iterator) def rec: Stream[Seq[a]] = if (is forall (_.hasNext)) Stream.cons(is map (_.next), rec) else Stream.empty @@ -588,20 +546,14 @@ * length of the resulting list is the length of the shortest input list. */ def zipx[a](xss: Iterable[Seq[a]]) = { - val width = xss.elements.next.length + val width = xss.iterator.next.length val iters = for (i <- 0 until width) - yield xss.elements map (_(i)) + yield xss.iterator map (_(i)) List(iters: _*) } /** - * Concatenate iterators. - */ - def concat[a](iters: Seq[Iterator[a]]) = - iters reduceLeft ((x: Iterator[a], y: Iterator[a]) => x ++ y) - - /** * Eliminate consecutive duplicates. */ def uniq[a](xs: Seq[a]) = groupPairwiseBy(xs)(_==_) map (_.head) @@ -654,7 +606,7 @@ def coord[a](i: Int, xss: Iterable[Seq[a]]): (Int, Int) = { var x = i var y = 0 - for (val xs <- xss) { + for (xs <- xss) { if (x <= xs.length) { return (x,y) } else { x -= (xs.length + 1); y += 1 } } @@ -706,7 +658,7 @@ */ def show(showLeaf: a => String): String = { def r(t: Tree[a]): Stream[String] = t match { - case Branch(ts) => Stream concat (ts map r) map (" " + _) + case Branch(ts) => (ts map r flatten) map (" " + _) case Leaf(x) => List(showLeaf(x)) toStream } r(this) mkString "\n" @@ -723,7 +675,7 @@ * Flatten the leaves into a single stream. */ def flatten: Stream[a] = this match { - case Branch(ts) => Stream concat (ts map (_.flatten)) + case Branch(ts) => (ts map (_.flatten) flatten) case Leaf(x) => Stream cons (x, Stream empty) } } @@ -733,11 +685,11 @@ /** * Build a tree whose i-th level branch has a fanout of xs(i). */ - def treeFromFanouts[a](gen: => a, fanouts: Seq[Int]): Tree[a] = + def treeFromFanouts[a: ClassManifest](gen: => a, fanouts: Seq[Int]): Tree[a] = fanouts match { case Seq() => Leaf(gen) case Seq(fanout, rest@_*) => - Branch(replicate(fanout, treeFromFanouts(gen, rest)).toArray) + Branch(replicate(fanout, treeFromFanouts(gen, rest)).toArray[Tree[a]]) } } @@ -747,7 +699,7 @@ def r(n: TreeNode[a], lvl: Int): Stream[String] = { Stream cons ( " " * lvl + n.value, - Stream concat (n.children map (n => r(n, lvl+1))) + (n.children map (n => r(n, lvl+1)) flatten) ) } r(this,0) mkString "\n" @@ -772,8 +724,8 @@ case Leaf(x) => Leaf(f(x)) } def flatten[b](f: a => b): Stream[b] = this match { - case And(ts) => Stream concat (ts map (_ flatten f)) - case Or(ts) => Stream concat (ts map (_ flatten f)) + case And(ts) => (ts map (_ flatten f) flatten) + case Or(ts) => (ts map (_ flatten f) flatten) case Not(t) => t flatten f case Leaf(x) => Stream cons (f(x), Stream empty) } @@ -827,16 +779,6 @@ loop } - /** - * Take an elements from a list. - */ - def take[a](src: Seq[a], n: Int) = { - val count = n min src.length - val dst = new Array[a](count) - src.elements take count copyToArray (dst, 0) - dst - } - // // Misc // This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-01 05:26:34
|
Revision: 1571 http://assorted.svn.sourceforge.net/assorted/?rev=1571&view=rev Author: yangzhang Date: 2010-03-01 05:26:28 +0000 (Mon, 01 Mar 2010) Log Message: ----------- added demo of nested class ctor Added Paths: ----------- sandbox/trunk/src/java/NestedClassCtor.java Added: sandbox/trunk/src/java/NestedClassCtor.java =================================================================== --- sandbox/trunk/src/java/NestedClassCtor.java (rev 0) +++ sandbox/trunk/src/java/NestedClassCtor.java 2010-03-01 05:26:28 UTC (rev 1571) @@ -0,0 +1,7 @@ +public class NestedClasses { + public static class Foo { + } + public static void main(String[] args) { + new NestedClasses.Foo(); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-03-01 05:25:43
|
Revision: 1570 http://assorted.svn.sourceforge.net/assorted/?rev=1570&view=rev Author: yangzhang Date: 2010-03-01 05:25:37 +0000 (Mon, 01 Mar 2010) Log Message: ----------- adopted Spinner for jhat example Modified Paths: -------------- sandbox/trunk/src/java/Spinner.java Added Paths: ----------- sandbox/trunk/src/java/Spinner.mk Modified: sandbox/trunk/src/java/Spinner.java =================================================================== --- sandbox/trunk/src/java/Spinner.java 2010-02-16 23:09:20 UTC (rev 1569) +++ sandbox/trunk/src/java/Spinner.java 2010-03-01 05:25:37 UTC (rev 1570) @@ -1,8 +1,10 @@ public class Spinner { public static void main(String[] args) { - int i = 0; - while (true) { - if (++i == Integer.MAX_VALUE) System.out.print('.'); + long i = 0; + long limit = args.length > 0 ? Long.parseLong(args[0]) : Long.MAX_VALUE; + long start = System.currentTimeMillis(); + while (System.currentTimeMillis() - start < limit) { + if (++i == Long.MAX_VALUE) { System.out.print('.'); System.out.flush(); } } } } Added: sandbox/trunk/src/java/Spinner.mk =================================================================== --- sandbox/trunk/src/java/Spinner.mk (rev 0) +++ sandbox/trunk/src/java/Spinner.mk 2010-03-01 05:25:37 UTC (rev 1570) @@ -0,0 +1,5 @@ +jhat: Spinner.class + java -agentlib:hprof=format=b Spinner 1000 + jhat java.hprof +%.class: %.java + javac $< This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-16 23:09:29
|
Revision: 1569 http://assorted.svn.sourceforge.net/assorted/?rev=1569&view=rev Author: yangzhang Date: 2010-02-16 23:09:20 +0000 (Tue, 16 Feb 2010) Log Message: ----------- added brainstormed notes on external algorithm approach Added Paths: ----------- mailing-list-filter/trunk/algorithms.jnt Added: mailing-list-filter/trunk/algorithms.jnt =================================================================== (Binary files differ) Property changes on: mailing-list-filter/trunk/algorithms.jnt ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-16 23:09:17
|
Revision: 1568 http://assorted.svn.sourceforge.net/assorted/?rev=1568&view=rev Author: yangzhang Date: 2010-02-16 23:09:07 +0000 (Tue, 16 Feb 2010) Log Message: ----------- started rewrite to use external algorithms Modified Paths: -------------- mailing-list-filter/trunk/src/mlf.py Modified: mailing-list-filter/trunk/src/mlf.py =================================================================== --- mailing-list-filter/trunk/src/mlf.py 2010-02-13 01:34:07 UTC (rev 1567) +++ mailing-list-filter/trunk/src/mlf.py 2010-02-16 23:09:07 UTC (rev 1568) @@ -13,7 +13,7 @@ from commons.log import * from contextlib import closing, contextmanager import getpass, logging, shelve, email, re, os, imaplib, itertools -import argparse, collections, subprocess, shutil +import argparse, collections, subprocess, shutil, cPickle as pickle from commons import log, startup, seqs, networking, files, sqlhash from commons.path import path @@ -65,6 +65,9 @@ else: imap.logout() +@contextmanager +def dummyctx(): yield + # # Functions for fetching messages from the server. # @@ -162,6 +165,7 @@ if midsrc is None: midsrc = mid2msg special_keys = ['maxuid', 'procuid'] for i, (mid, msg) in enumerate(midsrc.iteritems()): + if i % 10000 == 0: log.debug('readscan', i) if mid not in special_keys and msg.uid >= minuid: if midsrc is mid2msg: yield msg else: yield mid2msg[mid] @@ -321,14 +325,114 @@ with login_imap(cfg) as imap: fetch_new_mail(cfg, imap) - mark_relevant_threads(cfg) + g['reversed'] = reverse(g['fetched']) + g['sorted-reversed'] = sort(g['reversed']) + g['fetched'] = union(g['fetched'], g['sorted-reversed']) + g['flagged'] = flag_relevant(g['unioned']) + process(g) + sync_server(g['flagged']) + #reverse_graph('fetched', 'reversed') + #sort_graph('reversed', 'sorted-reversed') + #union_graphs('fetched', 'sorted-reversed', 'unioned') + #flag_relevant('unioned', 'flagged') + #sync_server('flagged') + + def gen_graph(path): + with file(path) as f: + for line in f: + yield ('path', []) + + def reverse_graph(g): + for line in g: + aoeu + + def union_graphs(g0, g1): + aoeu + + + if not os.path.exists(dbpath(cfg, 'tagged')): + tagged = set() + else: + with file(dbpath(cfg, 'tagged')) as f: tagged = pickle.load(f) + + tagged = tag_roots(cfg) + with file(dbpath(cfg, 'tagged'), 'w') as f: pickle.dump(tagged, f, 2) + + tagged = tag_connected(cfg, tagged) + + return + #mark_relevant_threads(cfg) + shutil.copy(dbpath(cfg, 'threaded'), dbpath(cfg, 'flagged')) - with login_imap(cfg) as imap: + with (dummyctx() if cfg.no_fetch else login_imap(cfg)) as imap: with closing(opendb(cfg, 'threaded')) as midsrc: with closing(opendb(cfg, 'flagged', 'w')) as mid2msg: flag_relevant_msgs(cfg, imap, midsrc, mid2msg) - os.rename(dbpath(cfg, 'fetched'), dbpath(cfg, 'fetched-old')) - os.rename(dbpath(cfg, 'flagged'), dbpath(cfg, 'fetched')) + #os.rename(dbpath(cfg, 'fetched'), dbpath(cfg, 'fetched-old')) + #os.rename(dbpath(cfg, 'flagged'), dbpath(cfg, 'fetched')) +#class graph_op(object): pass +def read(path): return partial(_read_graph, path) +def reverse(g): return partial() +def union(g1, g2): return partial('union') +def materialize(g): return g() + +def _read_graph(path): + with file(path) as f: + return f.read() + +def _reverse_graph(g): + outpath = g() + +def tag_roots(cfg, tagged): + log.info('roots', 'tagging roots; len(tagged) =', len(tagged)) + with closing(opendb(cfg, 'threaded')) as m: + count = 0 + for msg in itermsgs(m, 0): + if ( cfg.sender in msg.get('From', '') or + cfg.sender in msg.get('To', '') or + cfg.sender in msg.get('Cc', '') ): + tagged.add(msg['Message-ID']) + count += 1 + log.debug('roots', + 'count', count, + 'len(tagged)', len(tagged), + 'msgid', msg['Message-ID']) + log.info('roots', 'tagged', count, 'roots; len(tagged) =', len(tagged)) + +def refs(msg): + a = msg.get_all('In-Reply-To', []) + b = msg.get_all('References', []) + return ' '.join(a + b).replace('><', '> <').split() + +def tag_connected(cfg, tagged): + ''' + Scan messages, tagging anything that + already tagged. + ''' + + def dfs_tag(msg): + for refid in refs(msg): + if refid not in tagged: + tagged.add(refid) + # disk seeks here, but there shouldn't be too many, and locality in + # time means they're probably in the already cache (since we're + # scanning from earliest message to latest, and most messages are + # received in order, i.e. most references are back-references) + dfs_tag(msgs[ref]) + + log.info('tag_connected', 'tagging connected; len(tagged) =', len(tagged)) + with closing(opendb(cfg, 'threaded')) as m: + for msg in itermsgs(m, 0): + msgid = msg['Message-ID'] + + if ( cfg.sender in msg.get('From', '') or + cfg.sender in msg.get('To', '') or + cfg.sender in msg.get('Cc', '') ): + if msgid in tagged or any(refid in tagged for refid in refs(msg)): + dfs_tag(msg) + log.info('tag_connected', + 'tagged', count, 'msgs; len(tagged) = ', len(tagged)) + startup.run_main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-13 01:34:17
|
Revision: 1567 http://assorted.svn.sourceforge.net/assorted/?rev=1567&view=rev Author: yangzhang Date: 2010-02-13 01:34:07 +0000 (Sat, 13 Feb 2010) Log Message: ----------- added simple spammodule extension from tutorial Added Paths: ----------- sandbox/trunk/src/py/ext-tut/ sandbox/trunk/src/py/ext-tut/setup.py sandbox/trunk/src/py/ext-tut/spammodule.c Added: sandbox/trunk/src/py/ext-tut/setup.py =================================================================== --- sandbox/trunk/src/py/ext-tut/setup.py (rev 0) +++ sandbox/trunk/src/py/ext-tut/setup.py 2010-02-13 01:34:07 UTC (rev 1567) @@ -0,0 +1,9 @@ +from distutils.core import setup, Extension + +module1 = Extension('spammodule', + sources = ['spammodule.c']) + +setup (name = 'SpamModule', + version = '1.0', + description = 'This is a demo package', + ext_modules = [module1]) Added: sandbox/trunk/src/py/ext-tut/spammodule.c =================================================================== --- sandbox/trunk/src/py/ext-tut/spammodule.c (rev 0) +++ sandbox/trunk/src/py/ext-tut/spammodule.c 2010-02-13 01:34:07 UTC (rev 1567) @@ -0,0 +1,24 @@ +#include <Python.h> +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + return Py_BuildValue("i", sts); +} + +static PyMethodDef SpamMethods[] = { + {"system", spam_system, METH_VARARGS, + "Execute a shell command."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +PyMODINIT_FUNC +initspam(void) +{ + (void) Py_InitModule("spam", SpamMethods); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-09 03:12:40
|
Revision: 1566 http://assorted.svn.sourceforge.net/assorted/?rev=1566&view=rev Author: yangzhang Date: 2010-02-09 03:12:30 +0000 (Tue, 09 Feb 2010) Log Message: ----------- added regex-check scalac plugin Added Paths: ----------- sandbox/trunk/src/scala/regex-check-plugin/ sandbox/trunk/src/scala/regex-check-plugin/Makefile sandbox/trunk/src/scala/regex-check-plugin/RegexCheck.scala sandbox/trunk/src/scala/regex-check-plugin/RegexTest.scala sandbox/trunk/src/scala/regex-check-plugin/scalac-plugin.xml Added: sandbox/trunk/src/scala/regex-check-plugin/Makefile =================================================================== --- sandbox/trunk/src/scala/regex-check-plugin/Makefile (rev 0) +++ sandbox/trunk/src/scala/regex-check-plugin/Makefile 2010-02-09 03:12:30 UTC (rev 1566) @@ -0,0 +1,9 @@ +all: RegexTest.class +com/sygneca/regexcheck/RegexCheck.class: RegexCheck.scala + scalac -classpath /usr/local/lib/scala-compiler.jar $< +RegexCheck.jar: com/sygneca/regexcheck/RegexCheck.class + jar cf $@ com/ scalac-plugin.xml +RegexTest.class: RegexTest.scala RegexCheck.jar + scalac -classpath . -Xplugin:RegexCheck.jar $< +clean: + rm -rf com/ RegexCheck.jar *.class Added: sandbox/trunk/src/scala/regex-check-plugin/RegexCheck.scala =================================================================== --- sandbox/trunk/src/scala/regex-check-plugin/RegexCheck.scala (rev 0) +++ sandbox/trunk/src/scala/regex-check-plugin/RegexCheck.scala 2010-02-09 03:12:30 UTC (rev 1566) @@ -0,0 +1,47 @@ +// From <http://old.nabble.com/Compiler-Plug-In-Documentation-td15459459.html> + +package com.sygneca.regexcheck + +import scala.tools.nsc._ +import scala.tools.nsc.plugins._ +import java.util.regex._ + +class RegexCheckPlugin(val global : Global) +extends Plugin +{ + val name = "regexcheck" + override val description = "check that regular expressions compile" + val components = List(new RegexCheckComponent(global)) +} + +class RegexCheckComponent(val global : Global) +extends PluginComponent +{ + import global._ + + override val phaseName = "regexcheck" + override val runsAfter = List("typer") + + def newPhase(prev : Phase) = new StdPhase(prev) { + def apply(unit : CompilationUnit) = newTransformer(unit).transformUnit(unit) + } + + def newTransformer(unit : CompilationUnit) = new Transformer { + + object Name { def unapply(s : Name) = Some(s.toString) } + + override def transform(tr : Tree) : Tree = tr match { + case ref@Apply(Select(Select(Select(Select(Ident(Name("java")), Name("util")), + Name("regex")), Name("Pattern")), Name("compile")), + List(Literal(Constant(ptrn)))) => + try { + java.util.regex.Pattern.compile(ptrn.toString) + } catch { + case e : PatternSyntaxException => + unit.error(ref.pos, "Bad regular expression syntax: \""+e.getPattern+"\"") + } + ref + case _ => super.transform(tr) + } + } +} Added: sandbox/trunk/src/scala/regex-check-plugin/RegexTest.scala =================================================================== --- sandbox/trunk/src/scala/regex-check-plugin/RegexTest.scala (rev 0) +++ sandbox/trunk/src/scala/regex-check-plugin/RegexTest.scala 2010-02-09 03:12:30 UTC (rev 1566) @@ -0,0 +1,6 @@ +import java.util.regex._ +object RegexTest extends Application { + val goodPat = Pattern.compile("Hello, world!") + val badPat = Pattern.compile("Hello, world + + private object Component extends PluginComponent { + val global: VarHunter.this.global.type = VarHunter.this.global + // Using the Scala Compiler 2.8.x the runsAfter should be written as below + val runsAfter = List[String]("refchecks"); + val phaseName = VarHunter.this.name + def newPhase(_prev: Phase) = new VarHunterPhase(_prev) + + class VarHunterPhase(prev: Phase) extends StdPhase(prev) { + override def name = VarHunter.this.name + + def apply(unit: CompilationUnit) { + // For exploratory purposes, enable this code. Allows to browse the + // whole AST using a GUI. + if (false) + VarHunter.this.global.treeBrowsers.create().browse(unit.body) + + for (tree @ ValDef(_, _, _, _) <- unit.body) { + if ((tree.symbol.flags & Flags.MUTABLE) != 0) { + unit.error(tree.pos, "variables are not allowed !!!") + } + } + } + } + } +} Added: sandbox/trunk/src/scala/varhunter-plugin/scalac-plugin.xml =================================================================== --- sandbox/trunk/src/scala/varhunter-plugin/scalac-plugin.xml (rev 0) +++ sandbox/trunk/src/scala/varhunter-plugin/scalac-plugin.xml 2010-02-09 03:08:12 UTC (rev 1565) @@ -0,0 +1,4 @@ +<plugin> + <name>varhunter</name> + <classname>mycompilerplugin.VarHunter</classname> +</plugin> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-08 03:09:50
|
Revision: 1564 http://assorted.svn.sourceforge.net/assorted/?rev=1564&view=rev Author: yangzhang Date: 2010-02-08 03:09:40 +0000 (Mon, 08 Feb 2010) Log Message: ----------- more extensive exploration of continuations and implementations of `yield` Modified Paths: -------------- sandbox/trunk/src/scala/Continuations.mk sandbox/trunk/src/scala/Continuations.scala Modified: sandbox/trunk/src/scala/Continuations.mk =================================================================== --- sandbox/trunk/src/scala/Continuations.mk 2010-02-08 02:05:32 UTC (rev 1563) +++ sandbox/trunk/src/scala/Continuations.mk 2010-02-08 03:09:40 UTC (rev 1564) @@ -4,6 +4,9 @@ fsc -Xplugin:/opt/scala-cont/continuations/build/pack/selectivecps-plugin.jar -deprecation -classpath $(CLASSPATH) $< run: all scala -classpath .:$(CLASSPATH) Continuations +gen: Continuations_cps.scala +Continuations_cps.scala: Continuations.scala + fsc -Xplugin:/opt/scala-cont/continuations/build/pack/selectivecps-plugin.jar -deprecation -classpath $(CLASSPATH) -Xprint:selectivecps $< > $@ clean: rm -f Continuations.class .PHONY: run clean Modified: sandbox/trunk/src/scala/Continuations.scala =================================================================== --- sandbox/trunk/src/scala/Continuations.scala 2010-02-08 02:05:32 UTC (rev 1563) +++ sandbox/trunk/src/scala/Continuations.scala 2010-02-08 03:09:40 UTC (rev 1564) @@ -1,48 +1,33 @@ -import scala.continuations.ControlContext._ +import scala.continuations.cps +import scala.continuations.ControlContext.{shift,reset,suspendable} -/* -class YieldReturnIterator[+T] extends Iterator[T] { - private[this] var nextValue: Option[Option[T]] = None - private[this] var getNext: () => Unit = null - protected def yieldReturn(x: T): Unit @cps[Unit, Unit] = { - shift { cont => - nextValue = Some(Some(x)) - getNext = cont - } - } - protected def body: Unit @cps[Unit, Unit] { - getNext = { () => - reset { - body - nextValue = Some(None) - getNext = null - } - } - } - def hasNext: Boolean = { - if (nextValue.isEmpty) - getNext() - nextValue.get.isDefined - } - def next: String = { - if (nextValue.isEmpty) - getNext() - val e = nextValue.get.get - nextValue = None - e - } -} +// To see the plugin-rewritten source, use the `gen` make target. -class My(array: Array[String]) extends YieldReturnIterator[String] { - def body = for (s <- array) yieldReturn(s) -} -*/ - object Continuations { def main(args: Array[String]) { + basics + println + nondelim + println + yielditer + println + symmetricYield + println + trampolineYield + } + + def basics { + // Prints: + // + // outside pre + // inside pre + // outside post + // inside mid + // outside post + // inside post reset { println("outside pre") - val shi = shift { k: (Unit => Unit) => + shift { k: (Unit => Unit) => println("inside pre") k() println("inside mid") @@ -50,11 +35,23 @@ println("inside post") } println("outside post") - } // reset always just returns Unit + } println - reset { + // reset returns the evaluation of its first shift (that's where the + // computation may diverge). + // + // Prints: + // + // outside pre + // inside pre + // outside post 2 + // inside mid 0.1 + // outside post 4 + // inside post 0.1 + // 6 + val six = reset { println("outside pre") val a = shift { k: (Int => Double) => println("inside pre") @@ -62,39 +59,345 @@ println("inside mid " + b) val c = k(4) // pass a 4 println("inside post " + c) + "6" } println("outside post " + a) - 6.0 - } // reset always just returns Unit + 0.1 + } + println(six) println - def next = shift { k: (Int => Unit) => + // reset and shift don't have to be syntactically nested/statically associated + def threesome = shift { k: (Int => Unit) => k(1) k(2) k(3) } + reset { println(threesome) } // prints 1 2 3 + reset { println(threesome) } // prints 1 2 3 - reset { println(next) } // prints 1 2 3 - reset { println(next) } // prints 1 2 3 + println + // You can have multiple shifts per reset. + // + // Prints: + // + // 1 + // 1 + // 2 + // 3 + // 2 + // 1 + // 2 + // 3 + // 3 + // 1 + // 2 + // 3 + reset { println(threesome); println(threesome) } + println - //var nextVal: Int = 0 - //var getNext: () => Int = null - //def next2 = shift { k: (Unit => Unit) => - // getNext = { () => - // nextVal += 1 - // k() - // nextVal - // } - //} + // for-loops, while-loops work inside shifts + def threesome2 = shift { k: (Int => Unit) => for (i <- 1 to 3) k(i) } + def threesome3 = shift { k: (Int => Unit) => + var i = 0 + while (i < 3) { i += 1; k(i) } + } - //reset { - // next2 - // println(getNext) - // next2 - // println(getNext) - //} + // But shifts don't work inside for-loops/while-loops. + // reset { + // var i = 0 + // while (i < 3) threesome + // () + // } + // reset { + // for (i <- 0 to 3) threesome + // } + + // They *do* work in ifs/defs, and only if the `else` also is CPS. + reset { + if (true) threesome + else threesome + if (true) { threesome; () } + else { threesome; () } + // This doesn't work; if/else must return the same cps-type + // if (true) { threesome; () } + // else threesome + () + } + reset { + def foo = + if (true) threesome + else threesome + def foo2 = { + if (true) threesome + else threesome + () + } + foo + foo2 + () + } + + // Need own looping constructs. See `loopWhile` for a general, reusable + // construct. Need to specify types because of recursion. Unfortunately, + // no way to leverage existing map/foreach/etc (a la for loops), because + // that would imply doing a CPS break-up of the map/foreach/etc. + reset { + def loop(i: Int): Unit @suspendable = { + if (i < 3) { threesome; loop(i+1) } + } + loop(0) + } + + // The continuation really is just a regular function of the specified + // signature. Here, we "leak" it out of the whole shift-reset. (The only + // part of the code that is "transformed"/broken up is inside reset, + // broken up around the shift; this is what the type annots are for.) + // + // Prints: + // + // in shift + // outside reset, before kstore() + // in reset, after shift + // outside reset, after kstore() + val kstore = reset { + shift { k: (Unit => Unit) => println("in shift"); k } + println("in reset, after shift") + } + println("outside reset, before kstore()") + kstore() + println("outside reset, after kstore()") } + + def nondelim { + // We can't implement non-delimited continuations, because anything + // outside of reset can't be broken up and must be run + // in-line/immediately. + + def callCC(f: (Unit => Unit) => Unit) = + reset { shift { k: (Unit => Unit) => f(k); 3 }; println("cont") } + + println("callCC returns " + callCC { + k: (Unit => Unit) => { + println("inside callCC") + k() + } + } ) + + println("callCC returns " + callCC { + k: (Unit => Unit) => { + println("inside callCC") + // If you comment this out, then only "cont" won't get printed, + // but everything outside the reset runs. + // k() + } + } ) + } + + // A reusable continuation-split looping construct. + def loopWhile(cond: =>Boolean)(body: =>(Unit @suspendable)): Unit @suspendable = { + if (cond) { + body + loopWhile(cond)(body) + } + } + + def yielditer { + { + class Gen { + var prodCont: Unit => Unit = null + var i = 0 + def prod = { + reset { + i += 1 + shift { k: (Unit => Unit) => prodCont = k } + + i += 1 + shift { k: (Unit => Unit) => prodCont = k } + + i += 1 + shift { k: (Unit => Unit) => prodCont = k } + } + } + prodCont = { x: Unit => prod } + def next = { prodCont(); i } + } + val it = new Gen + println(it.next) + println(it.next) + println(it.next) + // Prints 3 again, because the continuation (after the last shift) does + // nothing. + println(it.next) + } + + println + + { + class Gen { + var prodCont: Unit => Unit = null + var i = 0 + def prod = { + reset { + // Recall that the plugin can't handle shifts inside `while`s, but + // can handle our own looping constructs. + loopWhile (true) { + i += 1 + shift { k: (Unit => Unit) => prodCont = k } + } + } + } + prodCont = { x: Unit => prod } + def next = { prodCont(); i } + } + val it = new Gen + println(it.next) + println(it.next) + println(it.next) + } + + println + + { + class Gen { + var prodCont: Unit => Unit = null + var nextVal = 0 + def yld(i: Int) = shift { k: (Unit => Unit) => nextVal = i; prodCont = k } + def prod = { + reset { + var i = 0 + loopWhile (true) { + i += 1 + yld(i) + } + } + } + prodCont = { x: Unit => prod } + def next = { prodCont(); nextVal } + } + val it = new Gen + println(it.next) + println(it.next) + println(it.next) + } + } + + def symmetricYield { + // Another way to provide yield, using continuations at the consumer as + // well (requiring the consumer to be transformed, i.e. can't provide + // conventional Iterator interface with this approach). From + // <http://stackoverflow.com/questions/2137619/scala-equivalent-to-python-generators/2146456#2146456>. + + abstract class Generator[T] { + var producerCont : (Unit => Unit) = null + var consumerCont : (T => Unit) = null + + protected def body : Unit @suspendable + + reset { + body + } + + def generate(t : T) : Unit @suspendable = + shift { + (k : Unit => Unit) => { + producerCont = k + if (consumerCont != null) + consumerCont(t) + } + } + + def next : T @suspendable = + shift { + (k : T => Unit) => { + consumerCont = k + if (producerCont != null) + producerCont() + } + } + } + + val g = new Generator[Int] { + def body = { + var i = 0 + loopWhile(i < 10) { + generate(i) + i += 1 + } + } + } + + reset { + loopWhile(true) { + println("Generated: "+g.next) + } + } + } + + def trampolineYield { + // From + // <http://stackoverflow.com/questions/2201882/implementing-yield-yield-return-using-scala-continuations/2215182#2215182>. + sealed trait Iteration[+R] + case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R] + case object Done extends Iteration[Nothing] + + def trampoline[R](body: => Iteration[R]): Iterator[R] = { + def loop(thunk: () => Iteration[R]): Stream[R] = { + thunk.apply match { + case Yield(result, next) => Stream.cons(result, loop(next)) + case Done => Stream.empty + } + } + loop(() => body).iterator + } + + // Poor man's yield. + + val itr1 = trampoline { + Yield(1, () => Yield(2, () => Yield(3, () => Done))) + } + + for (i <- itr1) { println(i) } + + println + + // Rich man's yield. + + def iterator[R](body: => Unit @cps[Iteration[R],Iteration[R]]): Iterator[R] = + trampoline { + reset[Iteration[R],Iteration[R]] { body ; Done } + } + + def yld[R](result: R): Unit @cps[Iteration[R],Iteration[R]] = + shift((k: Unit => Iteration[R]) => Yield(result, () => k(()))) + + // Example. + + val itr2 = iterator[Int] { + yld(1) + yld(2) + yld(3) + } + + for (i <- itr2) { println(i) } + + println + + // Something more advanced. + + def power(number: Int, exponent: Int): Iterator[Int] = iterator[Int] { + def loop(result: Int, counter: Int): Unit @cps[Iteration[Int],Iteration[Int]] = { + if (counter < exponent) { + yld(result) + loop(result * number, counter + 1) + } + } + loop(number, 0) + } + + for (i <- power(2, 8)) { println(i) } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-08 02:05:42
|
Revision: 1563 http://assorted.svn.sourceforge.net/assorted/?rev=1563&view=rev Author: yangzhang Date: 2010-02-08 02:05:32 +0000 (Mon, 08 Feb 2010) Log Message: ----------- added iedit Modified Paths: -------------- configs/trunk/src/emacs/yang.el Added Paths: ----------- configs/trunk/src/emacs/iedit.el Added: configs/trunk/src/emacs/iedit.el =================================================================== --- configs/trunk/src/emacs/iedit.el (rev 0) +++ configs/trunk/src/emacs/iedit.el 2010-02-08 02:05:32 UTC (rev 1563) @@ -0,0 +1,204 @@ +;;; iedit.el --- Edit multiple regions with the same content simultaneously. + +;; Copyright (C) 2010 Victor Ren + +;; Time-stamp: <2010-01-25 10:37:47 erenyin> +;; Author: Victor Ren <victor.ren <at> ericsson.com> +;; Keywords: region replace simultaneous +;; Version: 0.31 +;; X-URL: + +;; This file is not part of GNU Emacs, but it is distributed under +;; the same terms as GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. + +;;; Commentary: + +;; This package provides a more intuitive way of replace-string operation: +;; - Mark the contents in the buffer +;; - Start iedit minor mode - by press C-; +;; All of the same contents in the buffer are highlighted +;; - Edit one of the contents +;; The change is applied to other contents simultaneously +;; - Finish - by pressing C-; again +;; +;; So I call it in-place "replace-string". +;; +;;; Suggested key bindings: +;; +;; (define-key global-map (kbd "C-;") 'iedit-mode) +;; +;; todo: +;; - Start from isearch +;; - Use symbol at current point by default +;; - Toggle displaying lines except lines contains matches +;; - Adjust region when iedit mode is active +;; - Lazy highlight feature (from isearch) +;; - Help information +;; +;; Change log: +;; +;; 2010/01/25 Disable updating other regions when undo-in-progress since they +;; are already updated by undo +;; +;;; Code: + +(eval-when-compile (require 'cl)) + +(defgroup iedit nil + "Edit multiple regions with the same content simultaneously." + :prefix "iedit-" + :group 'replace + :group 'convenience) + +(defcustom iedit-occurrence-face 'highlight + "*Face used for the occurrences' default values." + :type 'face + :group 'iedit) + +(defvar iedit-mode-hook nil + "Function(s) to call after starting up an iedit.") + +(defvar iedit-mode-end-hook nil + "Function(s) to call after terminating an iedit.") + +(defvar iedit-mode nil) ;; Name of the minor mode + +(make-variable-buffer-local 'iedit-mode) + +(or (assq 'iedit-mode minor-mode-alist) + (nconc minor-mode-alist + (list '(iedit-mode iedit-mode)))) + +(defvar iedit-occurrences nil + "The occurrences slot contains a list of overlays used to indicate +the position of each occurrence. In addition, the occurrence overlay is +used to provide a different face configurable via +`iedit-occurrence-face'." ) + +(make-variable-buffer-local 'iedit-occurrences) + +(defvar iedit-mode-map nil + "Keymap used while iedit mode is enabled.") + +(if iedit-mode-map + nil + (setq iedit-mode-map (make-sparse-keymap)) + ;; Default key bindings + (define-key iedit-mode-map (kbd "TAB") 'iedit-next-occurrence) + (define-key iedit-mode-map (kbd "<S-tab>") 'iedit-prev-occurrence) + (define-key iedit-mode-map (kbd "<S-iso-lefttab>") 'iedit-prev-occurrence)) + +(or (assq 'iedit-mode minor-mode-map-alist) + (setq minor-mode-map-alist + (cons (cons 'iedit-mode iedit-mode-map) minor-mode-map-alist))) + +(defun iedit-mode (beg end) + "Toggle iedit mode. +Commands: +\\{iedit-mode-map}" + (interactive "r") + (if iedit-mode + (iedit-done) + (progn + (or (and mark-active (not (equal beg end))) + (error "No region select, cannot enable iedit mode")) + (deactivate-mark) + (iedit-start (buffer-substring beg end))))) + +(defun iedit-start (occurrence-exp) + "Start an iedit for the occurrence-exp in the current buffer." + (setq iedit-mode " Iedit") + (setq iedit-occurrences nil) + (force-mode-line-update) + (run-hooks 'iedit-mode-hook) + (add-hook 'mouse-leave-buffer-hook 'iedit-done) + (add-hook 'kbd-macro-termination-hook 'iedit-done) + ;; Find and record each occurrence's markers and add the overlay to the occurrences + (save-excursion + (goto-char (point-min)) + (while (search-forward occurrence-exp nil t) + (let ((start (copy-marker (match-beginning 0) t)) + (end (copy-marker (point) t))) + (let ((occurrence (iedit-make-occurrence-overlay))) + (push occurrence iedit-occurrences) + (move-overlay occurrence start end)))))) + +(defun iedit-done () + "Exit iedit mode." + (when iedit-occurrences + (dolist (occurrence iedit-occurrences) + (delete-overlay occurrence)) + (setq iedit-occurrences nil)) + (remove-hook 'mouse-leave-buffer-hook 'iedit-done) + (remove-hook 'kbd-macro-termination-hook 'iedit-done) + (setq iedit-mode nil) + (force-mode-line-update) + (run-hooks 'iedit-mode-end-hook)) + +(defun iedit-make-occurrence-overlay (&optional name) + "Create an overlay for an occurrence in a iedit. +Add the appropriate properties for the overlay to provide: a face +used to display a occurrence's default value, and modification hooks +to update occurrences if the user starts typing." + (let ((occurrence (make-overlay (point) (point) (current-buffer) nil t))) + (overlay-put occurrence 'face iedit-occurrence-face) + (overlay-put occurrence 'insert-in-front-hooks '(iedit-occurrence-update)) + (overlay-put occurrence 'insert-behind-hooks '(iedit-occurrence-update)) + (overlay-put occurrence 'modification-hooks '(iedit-occurrence-update)) + occurrence)) + +(defun iedit-occurrence-update (occurrence after beg end &optional change) + "Update all occurrences. +This modification hook is triggered when a user edits any occurrence +and is responsible for updating all other occurrences." + (when (and after (not undo-in-progress)) ; undo will do all the work + (let ((value (buffer-substring (overlay-start occurrence) (overlay-end occurrence))) + (inhibit-modification-hooks t)) + (save-excursion + (dolist (like-occurrence iedit-occurrences) + (if (not (eq like-occurrence occurrence)) + (progn + (goto-char (overlay-start like-occurrence)) + (delete-region (overlay-start like-occurrence) + (overlay-end like-occurrence)) + (insert value)))))))) + +(defun iedit-next-occurrence () + "Move point forward to the next occurrence in the `iedit'. +If there are no more occurrences in the iedit, point is moved to the +last occurrence." + (interactive) + (let* ((occurrences iedit-occurrences) + (next-pos (loop for occurrence in (reverse occurrences) + for start = (overlay-start occurrence) + when (< (point) start) + return start))) + (if (not (null next-pos)) + (goto-char next-pos)))) + +(defun iedit-prev-occurrence () + "Move point backward to the previous occurrence in the `iedit'. +If there are no more occurrences in the iedit, point is moved to the first occurrence." + (interactive) + (let* ((occurrences iedit-occurrences) + (prev-pos (loop for occurrence in occurrences + for end = (overlay-end occurrence) + when (> (point) end) + return (overlay-start occurrence)))) + (if (not (null prev-pos)) + (goto-char prev-pos)))) + +(provide 'iedit) Modified: configs/trunk/src/emacs/yang.el =================================================================== --- configs/trunk/src/emacs/yang.el 2010-02-05 19:33:40 UTC (rev 1562) +++ configs/trunk/src/emacs/yang.el 2010-02-08 02:05:32 UTC (rev 1563) @@ -268,6 +268,9 @@ (global-set-key (read-kbd-macro "C-=") 'zoom-frm-in) (global-set-key (read-kbd-macro "C-0") 'zoom-frm-unzoom) +(require 'iedit) +(define-key global-map (kbd "C-c C-r") 'iedit-mode) + ;; }}} ;; modes {{{ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-05 19:33:50
|
Revision: 1562 http://assorted.svn.sourceforge.net/assorted/?rev=1562&view=rev Author: yangzhang Date: 2010-02-05 19:33:40 +0000 (Fri, 05 Feb 2010) Log Message: ----------- added txt2bin Added Paths: ----------- sandbox/trunk/src/one-off-scripts/txt2bin/ sandbox/trunk/src/one-off-scripts/txt2bin/txt2bin.cc Added: sandbox/trunk/src/one-off-scripts/txt2bin/txt2bin.cc =================================================================== --- sandbox/trunk/src/one-off-scripts/txt2bin/txt2bin.cc (rev 0) +++ sandbox/trunk/src/one-off-scripts/txt2bin/txt2bin.cc 2010-02-05 19:33:40 UTC (rev 1562) @@ -0,0 +1,38 @@ +#include <iostream> +#include <sstream> +#include <string> +#include <arpa/inet.h> +using namespace std; + +void put(int x) { + int y = htonl(x); + cout.write(reinterpret_cast<const char*>(&y), sizeof y); +} + +int get() { + int x; + return cin.read(reinterpret_cast<char*>(&x), sizeof x) ? ntohl(x) : -2; +} + +int main(int argc, char **argv) { + if (argc != 2) throw exception(); + if (string(argv[1]) == "-c") { + string line; + while (getline(cin, line)) { + stringstream ss(line); + int x; + while (ss >> x) { + if (x < 0) throw exception(); + put(x); + } + put(-1); + } + } else { + int x; + while ((x = get()) != -2) { + if (x == -1) cout << '\n'; + else cout << x << " "; + } + } + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-04 18:57:18
|
Revision: 1561 http://assorted.svn.sourceforge.net/assorted/?rev=1561&view=rev Author: yangzhang Date: 2010-02-04 18:57:03 +0000 (Thu, 04 Feb 2010) Log Message: ----------- more playing with continuations Modified Paths: -------------- sandbox/trunk/src/scala/Continuations.scala Modified: sandbox/trunk/src/scala/Continuations.scala =================================================================== --- sandbox/trunk/src/scala/Continuations.scala 2010-02-04 18:49:25 UTC (rev 1560) +++ sandbox/trunk/src/scala/Continuations.scala 2010-02-04 18:57:03 UTC (rev 1561) @@ -1,11 +1,100 @@ import scala.continuations.ControlContext._ +/* +class YieldReturnIterator[+T] extends Iterator[T] { + private[this] var nextValue: Option[Option[T]] = None + private[this] var getNext: () => Unit = null + protected def yieldReturn(x: T): Unit @cps[Unit, Unit] = { + shift { cont => + nextValue = Some(Some(x)) + getNext = cont + } + } + protected def body: Unit @cps[Unit, Unit] { + getNext = { () => + reset { + body + nextValue = Some(None) + getNext = null + } + } + } + def hasNext: Boolean = { + if (nextValue.isEmpty) + getNext() + nextValue.get.isDefined + } + def next: String = { + if (nextValue.isEmpty) + getNext() + val e = nextValue.get.get + nextValue = None + e + } +} + +class My(array: Array[String]) extends YieldReturnIterator[String] { + def body = for (s <- array) yieldReturn(s) +} +*/ + object Continuations { def main(args: Array[String]) { reset { - println("first") - shift { k: (Unit => Unit) => k(k(())) } - println("last") + println("outside pre") + val shi = shift { k: (Unit => Unit) => + println("inside pre") + k() + println("inside mid") + k() + println("inside post") + } + println("outside post") + } // reset always just returns Unit + + println + + reset { + println("outside pre") + val a = shift { k: (Int => Double) => + println("inside pre") + val b = k(2) // think of there being two cothreads; this thread msg-passes a 2 + println("inside mid " + b) + val c = k(4) // pass a 4 + println("inside post " + c) + } + println("outside post " + a) + 6.0 + } // reset always just returns Unit + + println + + def next = shift { k: (Int => Unit) => + k(1) + k(2) + k(3) } + + reset { println(next) } // prints 1 2 3 + reset { println(next) } // prints 1 2 3 + + println + + //var nextVal: Int = 0 + //var getNext: () => Int = null + //def next2 = shift { k: (Unit => Unit) => + // getNext = { () => + // nextVal += 1 + // k() + // nextVal + // } + //} + + //reset { + // next2 + // println(getNext) + // next2 + // println(getNext) + //} } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-04 18:49:35
|
Revision: 1560 http://assorted.svn.sourceforge.net/assorted/?rev=1560&view=rev Author: yangzhang Date: 2010-02-04 18:49:25 +0000 (Thu, 04 Feb 2010) Log Message: ----------- added build file for Continuations example Added Paths: ----------- sandbox/trunk/src/scala/Continuations.mk Added: sandbox/trunk/src/scala/Continuations.mk =================================================================== --- sandbox/trunk/src/scala/Continuations.mk (rev 0) +++ sandbox/trunk/src/scala/Continuations.mk 2010-02-04 18:49:25 UTC (rev 1560) @@ -0,0 +1,9 @@ +CLASSPATH = /opt/scala-cont/continuations/build/build.library +all: Continuations.class +Continuations.class: Continuations.scala + fsc -Xplugin:/opt/scala-cont/continuations/build/pack/selectivecps-plugin.jar -deprecation -classpath $(CLASSPATH) $< +run: all + scala -classpath .:$(CLASSPATH) Continuations +clean: + rm -f Continuations.class +.PHONY: run clean This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-02-04 16:02:59
|
Revision: 1559 http://assorted.svn.sourceforge.net/assorted/?rev=1559&view=rev Author: yangzhang Date: 2010-02-04 16:02:49 +0000 (Thu, 04 Feb 2010) Log Message: ----------- added scala 2.8 continuations example Added Paths: ----------- sandbox/trunk/src/scala/Continuations.scala Added: sandbox/trunk/src/scala/Continuations.scala =================================================================== --- sandbox/trunk/src/scala/Continuations.scala (rev 0) +++ sandbox/trunk/src/scala/Continuations.scala 2010-02-04 16:02:49 UTC (rev 1559) @@ -0,0 +1,11 @@ +import scala.continuations.ControlContext._ + +object Continuations { + def main(args: Array[String]) { + reset { + println("first") + shift { k: (Unit => Unit) => k(k(())) } + println("last") + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-31 20:33:44
|
Revision: 1558 http://assorted.svn.sourceforge.net/assorted/?rev=1558&view=rev Author: yangzhang Date: 2010-01-31 20:33:34 +0000 (Sun, 31 Jan 2010) Log Message: ----------- install system-wide toast as well Modified Paths: -------------- configs/trunk/bootstrap.bash Modified: configs/trunk/bootstrap.bash =================================================================== --- configs/trunk/bootstrap.bash 2010-01-30 18:10:45 UTC (rev 1557) +++ configs/trunk/bootstrap.bash 2010-01-31 20:33:34 UTC (rev 1558) @@ -127,6 +127,8 @@ export PATH="$HOME/.toast/armed/bin:$PATH" fi +fetch http://toastball.net/toast/toast | dosu perl -x - arm toast + # setup stow if ! has stow This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-30 18:10:55
|
Revision: 1557 http://assorted.svn.sourceforge.net/assorted/?rev=1557&view=rev Author: yangzhang Date: 2010-01-30 18:10:45 +0000 (Sat, 30 Jan 2010) Log Message: ----------- tweak so bootstrap.bash doesn't throw up Modified Paths: -------------- shell-tools/trunk/src/bash-commons/common.bash Modified: shell-tools/trunk/src/bash-commons/common.bash =================================================================== --- shell-tools/trunk/src/bash-commons/common.bash 2010-01-26 19:24:52 UTC (rev 1556) +++ shell-tools/trunk/src/bash-commons/common.bash 2010-01-30 18:10:45 UTC (rev 1557) @@ -531,7 +531,7 @@ refresh-opt() { local pkg_user= - if [[ "$PKG_USER" ]] ; then + if [[ "${PKG_USER:-}" ]] ; then pkg_user="$PKG_USER" elif sudo -u pkg echo -n ; then pkg_user=pkg This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-26 19:25:03
|
Revision: 1556 http://assorted.svn.sourceforge.net/assorted/?rev=1556&view=rev Author: yangzhang Date: 2010-01-26 19:24:52 +0000 (Tue, 26 Jan 2010) Log Message: ----------- added gss api (kerberos) auth for csail logins Modified Paths: -------------- configs/trunk/src/ssh/config Modified: configs/trunk/src/ssh/config =================================================================== --- configs/trunk/src/ssh/config 2010-01-25 03:44:49 UTC (rev 1555) +++ configs/trunk/src/ssh/config 2010-01-26 19:24:52 UTC (rev 1556) @@ -395,6 +395,11 @@ HostName nms.csail.mit.edu User yang +Host login.csail.mit.edu svn.csail.mit.edu linerva.mit.edu + GSSAPIAuthentication yes + GSSAPIKeyExchange yes + GSSAPIDelegateCredentials yes + Host cs HostName login.csail.mit.edu User yang This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-25 03:44:58
|
Revision: 1555 http://assorted.svn.sourceforge.net/assorted/?rev=1555&view=rev Author: yangzhang Date: 2010-01-25 03:44:49 +0000 (Mon, 25 Jan 2010) Log Message: ----------- added surround.vim Added Paths: ----------- configs/trunk/src/vim/doc/surround.txt configs/trunk/src/vim/plugin/surround.vim Added: configs/trunk/src/vim/doc/surround.txt =================================================================== --- configs/trunk/src/vim/doc/surround.txt (rev 0) +++ configs/trunk/src/vim/doc/surround.txt 2010-01-25 03:44:49 UTC (rev 1555) @@ -0,0 +1,218 @@ +*surround.txt* Plugin for deleting, changing, and adding "surroundings" + +Author: Tim Pope <vim...@tp...> *surround-author* +License: Same terms as Vim itself (see |license|) + +This plugin is only available if 'compatible' is not set. + +INTRODUCTION *surround* + +This plugin is a tool for dealing with pairs of "surroundings." Examples +of surroundings include parentheses, quotes, and HTML tags. They are +closely related to what Vim refers to as |text-objects|. Provided +are mappings to allow for removing, changing, and adding surroundings. + +Details follow on the exact semantics, but first, consider the following +examples. An asterisk (*) is used to denote the cursor position. + + Old text Command New text ~ + "Hello *world!" ds" Hello world! + [123+4*56]/2 cs]) (123+456)/2 + "Look ma, I'm *HTML!" cs"<q> <q>Look ma, I'm HTML!</q> + if *x>3 { ysW( if ( x>3 ) { + my $str = *whee!; vlllls' my $str = 'whee!'; + +While a few features of this plugin will work in older versions of Vim, +Vim 7 is recommended for full functionality. + +MAPPINGS *surround-mappings* + +Delete surroundings is *ds* . The next character given determines the target +to delete. The exact nature of the target are explained in |surround-targets| +but essentially it is the last character of a |text-object|. This mapping +deletes the difference between the "inner" object and "an" object. This is +easiest to understand with some examples: + + Old text Command New text ~ + "Hello *world!" ds" Hello world! + (123+4*56)/2 ds) 123+456/2 + <div>Yo!*</div> dst Yo! + +Change surroundings is *cs* . It takes two arguments, a target like with +|ds|, and a replacement. Details about the second argument can be found +below in |surround-replacements|. Once again, examples are in order. + + Old text Command New text ~ + "Hello *world!" cs"' 'Hello world!' + "Hello *world!" cs"<q> <q>Hello world!</q> + (123+4*56)/2 cs)] [123+456]/2 + (123+4*56)/2 cs)[ [ 123+456 ]/2 + <div>Yo!*</div> cst<p> <p>Yo!</p> + +*ys* takes an valid Vim motion or text object as the first object, and wraps +it using the second argument as with |cs|. (Unfortunately there's no good +mnemonic for "ys".) + + Old text Command New text ~ + Hello w*orld! ysiw) Hello (world)! + +As a special case, *yss* operates on the current line, ignoring leading +whitespace. + + Old text Command New text ~ + Hello w*orld! yssB {Hello world!} + +There is also *yS* and *ySS* which indent the surrounded text and place it +on a line of its own. + +In visual mode, a simple "s" with an argument wraps the selection. This is +referred to as the *vs* mapping, although ordinarily there will be +additional keystrokes between the v and s. In linewise visual mode, the +surroundings are placed on separate lines. In blockwise visual mode, each +line is surrounded. + +An "S" in visual mode (*vS*) behaves similarly but always places the +surroundings on separate lines. Additionally, the surrounded text is +indented. In blockwise visual mode, using "S" instead of "s" instead skips +trailing whitespace. + +Note that "s" and "S" already have valid meaning in visual mode, but it is +identical to "c". If you have muscle memory for "s" and would like to use a +different key, add your own mapping and the existing one will be disabled. +> + vmap <Leader>s <Plug>Vsurround + vmap <Leader>S <Plug>VSurround +< + *i_CTRL-G_s* *i_CTRL-G_S* +Finally, there is an experimental insert mode mapping on <C-G>s and <C-S>. +Beware that the latter won't work on terminals with flow control (if you +accidentally freeze your terminal, use <C-Q> to unfreeze it). The mapping +inserts the specified surroundings and puts the cursor between them. If, +immediately after the mapping and before the replacement, a second <C-S> or +carriage return is pressed, the prefix, cursor, and suffix will be placed on +three separate lines. <C-G>S (not <C-G>s) also exhibits this behavior. + +TARGETS *surround-targets* + +The |ds| and |cs| commands both take a target as their first argument. The +possible targets are based closely on the |text-objects| provided by Vim. +In order for a target to work, the corresponding text object must be +supported in the version of Vim used (Vim 7 adds several text objects, and +thus is highly recommended). All targets are currently just one character. + +Eight punctuation marks, (, ), {, }, [, ], <, and >, represent themselves +and their counterpart. If the opening mark is used, contained whitespace is +also trimmed. The targets b, B, r, and a are aliases for ), }, ], and > +(the first two mirror Vim; the second two are completely arbitrary and +subject to change). + +Three quote marks, ', ", `, represent themselves, in pairs. They are only +searched for on the current line. + +A t is a pair of HTML or XML tags. See |tag-blocks| for details. Remember +that you can specify a numerical argument if you want to get to a tag other +than the innermost one. + +The letters w, W, and s correspond to a |word|, a |WORD|, and a |sentence|, +respectively. These are special in that they have nothing to delete, and +used with |ds| they are a no-op. With |cs|, one could consider them a +slight shortcut for ysi (cswb == ysiwb, more or less). + +A p represents a |paragraph|. This behaves similarly to w, W, and s above; +however, newlines are sometimes added and/or removed. + +REPLACEMENTS *surround-replacements* + +A replacement argument is a single character, and is required by |cs|, |ys|, +and |vs|. Undefined replacement characters (with the exception of alphabetic +characters) default to placing themselves at the beginning and end of the +destination, which can be useful for characters like / and |. + +If either ), }, ], or > is used, the text is wrapped in the appropriate pair +of characters. Similar behavior can be found with (, {, and [ (but not <), +which append an additional space to the inside. Like with the targets above, +b, B, r, and a are aliases for ), }, ], and >. To fulfill the common need for +code blocks in C-style languages, <C-}> (which is really <C-]>) adds braces on +lines separate from the content. + +If t or < is used, Vim prompts for an HTML/XML tag to insert. You may specify +attributes here and they will be stripped from the closing tag. End your +input by pressing <CR> or >. If <C-T> is used, the tags will appear on lines +by themselves. + +A deprecated replacement of a LaTeX environment is provided on \ and l. The +name of the environment and any arguments will be input from a prompt. This +will be removed once a more fully functional customization system is +implemented. The following shows the resulting environment from +csp\tabular}{lc<CR> +> + \begin{tabular}{lc} + \end{tabular} +< +CUSTOMIZING *surround-customizing* + +The following adds a potential replacement on "-" (ASCII 45) in PHP files. +(To determine the ASCII code to use, :echo char2nr("-")). The carriage +return will be replaced by the original text. +> + autocmd FileType php let b:surround_45 = "<?php \r ?>" +< +This can be used in a PHP file as in the following example. + + Old text Command New text ~ + print "Hello *world!" yss- <?php print "Hello world!" ?> + +Additionally, one can use a global variable for globally available +replacements. +> + let g:surround_45 = "<% \r %>" + let g:surround_61 = "<%= \r %>" +< +Advanced, experimental, and subject to change: One can also prompt for +replacement text. The syntax for this is to surround the replacement in pairs +of low numbered control characters. If this sounds confusing, that's because +it is (but it makes the parsing easy). Consider the following example for a +LaTeX environment on the "l" replacement. +> + let g:surround_108 = "\\begin{\1environment: \1}\r\\end{\1\1}" +< +When this replacement is used, the user is prompted with an "environment: " +prompt for input. This input is inserted between each set of \1's. +Additional inputs up to \7 can be used. + +Furthermore, one can specify a regular expression substitution to apply. +> + let g:surround_108 = "\\begin{\1environment: \1}\r\\end{\1\r}.*\r\1}" +< +This will remove anything after the first } in the input when the text is +placed within the \end{} slot. The first \r marks where the pattern begins, +and the second where the replacement text begins. + +Here's a second example for creating an HTML <div>. The substitution cleverly +prompts for an id, but only adds id="" if it is non-blank. You may have to +read this one a few times slowly before you understand it. +> + let g:surround_{char2nr("d")} = "<div\1id: \r..*\r id=\"&\"\1>\r</div>" +< +Inputting text replacements is a proof of concept at this point. The ugly, +unintuitive interface and the brevity of the documentation reflect this. + +Finally, It is possible to always append a string to surroundings in insert +mode (and only insert mode). This is useful with certain plugins and mappings +that allow you to jump to such markings. +> + let g:surround_insert_tail = "<++>" +< +ISSUES *surround-issues* + +Vim could potentially get confused when deleting/changing occurs at the very +end of the line. Please report any repeatable instances of this. + +Do we need to use |inputsave()|/|inputrestore()| with the tag replacement? + +Indenting is handled haphazardly. Need to decide the most appropriate +behavior and implement it. Right now one can do :let b:surround_indent = 1 +(or the global equivalent) to enable automatic re-indenting by Vim via |=|; +should this be the default? + + vim:tw=78:ts=8:ft=help:norl: Added: configs/trunk/src/vim/plugin/surround.vim =================================================================== --- configs/trunk/src/vim/plugin/surround.vim (rev 0) +++ configs/trunk/src/vim/plugin/surround.vim 2010-01-25 03:44:49 UTC (rev 1555) @@ -0,0 +1,628 @@ +" surround.vim - Surroundings +" Author: Tim Pope <vim...@tp...> +" GetLatestVimScripts: 1697 1 :AutoInstall: surround.vim +" $Id: surround.vim,v 1.34 2008-02-15 21:43:42 tpope Exp $ +" +" See surround.txt for help. This can be accessed by doing +" +" :helptags ~/.vim/doc +" :help surround +" +" Licensed under the same terms as Vim itself. + +" ============================================================================ + +" Exit quickly when: +" - this plugin was already loaded or disabled +" - when 'compatible' is set +if (exists("g:loaded_surround") && g:loaded_surround) || &cp + finish +endif +let g:loaded_surround = 1 + +let s:cpo_save = &cpo +set cpo&vim + +" Input functions {{{1 + +function! s:getchar() + let c = getchar() + if c =~ '^\d\+$' + let c = nr2char(c) + endif + return c +endfunction + +function! s:inputtarget() + let c = s:getchar() + while c =~ '^\d\+$' + let c = c . s:getchar() + endwhile + if c == " " + let c = c . s:getchar() + endif + if c =~ "\<Esc>\|\<C-C>\|\0" + return "" + else + return c + endif +endfunction + +function! s:inputreplacement() + "echo '-- SURROUND --' + let c = s:getchar() + if c == " " + let c = c . s:getchar() + endif + if c =~ "\<Esc>" || c =~ "\<C-C>" + return "" + else + return c + endif +endfunction + +function! s:beep() + exe "norm! \<Esc>" + return "" +endfunction + +function! s:redraw() + redraw + return "" +endfunction + +" }}}1 + +" Wrapping functions {{{1 + +function! s:extractbefore(str) + if a:str =~ '\r' + return matchstr(a:str,'.*\ze\r') + else + return matchstr(a:str,'.*\ze\n') + endif +endfunction + +function! s:extractafter(str) + if a:str =~ '\r' + return matchstr(a:str,'\r\zs.*') + else + return matchstr(a:str,'\n\zs.*') + endif +endfunction + +function! s:repeat(str,count) + let cnt = a:count + let str = "" + while cnt > 0 + let str = str . a:str + let cnt = cnt - 1 + endwhile + return str +endfunction + +function! s:fixindent(str,spc) + let str = substitute(a:str,'\t',s:repeat(' ',&sw),'g') + let spc = substitute(a:spc,'\t',s:repeat(' ',&sw),'g') + let str = substitute(str,'\(\n\|\%^\).\@=','\1'.spc,'g') + if ! &et + let str = substitute(str,'\s\{'.&ts.'\}',"\t",'g') + endif + return str +endfunction + +function! s:process(string) + let i = 0 + while i < 7 + let i = i + 1 + let repl_{i} = '' + let m = matchstr(a:string,nr2char(i).'.\{-\}\ze'.nr2char(i)) + if m != '' + let m = substitute(strpart(m,1),'\r.*','','') + let repl_{i} = input(substitute(m,':\s*$','','').': ') + endif + endwhile + let s = "" + let i = 0 + while i < strlen(a:string) + let char = strpart(a:string,i,1) + if char2nr(char) < 8 + let next = stridx(a:string,char,i+1) + if next == -1 + let s = s . char + else + let insertion = repl_{char2nr(char)} + let subs = strpart(a:string,i+1,next-i-1) + let subs = matchstr(subs,'\r.*') + while subs =~ '^\r.*\r' + let sub = matchstr(subs,"^\r\\zs[^\r]*\r[^\r]*") + let subs = strpart(subs,strlen(sub)+1) + let r = stridx(sub,"\r") + let insertion = substitute(insertion,strpart(sub,0,r),strpart(sub,r+1),'') + endwhile + let s = s . insertion + let i = next + endif + else + let s = s . char + endif + let i = i + 1 + endwhile + return s +endfunction + +function! s:wrap(string,char,type,...) + let keeper = a:string + let newchar = a:char + let type = a:type + let linemode = type ==# 'V' ? 1 : 0 + let special = a:0 ? a:1 : 0 + let before = "" + let after = "" + if type == "V" + let initspaces = matchstr(keeper,'\%^\s*') + else + let initspaces = matchstr(getline('.'),'\%^\s*') + endif + " Duplicate b's are just placeholders (removed) + let pairs = "b()B{}r[]a<>" + let extraspace = "" + if newchar =~ '^ ' + let newchar = strpart(newchar,1) + let extraspace = ' ' + endif + let idx = stridx(pairs,newchar) + if newchar == ' ' + let before = '' + let after = '' + elseif exists("b:surround_".char2nr(newchar)) + let all = s:process(b:surround_{char2nr(newchar)}) + let before = s:extractbefore(all) + let after = s:extractafter(all) + elseif exists("g:surround_".char2nr(newchar)) + let all = s:process(g:surround_{char2nr(newchar)}) + let before = s:extractbefore(all) + let after = s:extractafter(all) + elseif newchar ==# "p" + let before = "\n" + let after = "\n\n" + elseif newchar =~# "[tT\<C-T><,]" + let dounmapp = 0 + let dounmapb = 0 + if !maparg(">","c") + let dounmapb= 1 + " Hide from AsNeeded + exe "cn"."oremap > <CR>" + exe "cn"."oremap % %<C-V>" + "cm ap > <C-R>=getcmdline() =~ '^[^%?].*[%?]$' ? "\026\076" : "\026\076\015"<CR> + endif + let default = "" + if !maparg("%","c") + " This is to help when typing things like + " <a href="/images/<%= @image.filename %>"> + " The downside is it breaks backspace, so lets disable it for now + "let dounmapp= 1 + "exe "cn"."oremap % %<C-V>" + endif + if newchar ==# "T" + if !exists("s:lastdel") + let s:lastdel = "" + endif + let default = matchstr(s:lastdel,'<\zs.\{-\}\ze>') + endif + let tag = input("<",default) + echo "<".substitute(tag,'>*$','>','') + "if dounmapr + "silent! cunmap <CR> + "endif + if dounmapb + silent! cunmap > + endif + if dounmapp + silent! cunmap % + endif + if tag != "" + let tag = substitute(tag,'>*$','','') + let before = '<'.tag.'>' + if tag =~ '/$' + let after = '' + else + let after = '</'.substitute(tag,' .*','','').'>' + endif + if newchar == "\<C-T>" || newchar == "," + if type ==# "v" || type ==# "V" + let before = before . "\n\t" + endif + if type ==# "v" + let after = "\n". after + endif + endif + endif + elseif newchar ==# 'l' || newchar == '\' + " LaTeX + let env = input('\begin{') + let env = '{' . env + let env = env . s:closematch(env) + echo '\begin'.env + if env != "" + let before = '\begin'.env + let after = '\end'.matchstr(env,'[^}]*').'}' + endif + "if type ==# 'v' || type ==# 'V' + "let before = before ."\n\t" + "endif + "if type ==# 'v' + "let after = "\n".initspaces.after + "endif + elseif newchar ==# 'f' || newchar ==# 'F' + let fnc = input('function: ') + if fnc != "" + let before = substitute(fnc,'($','','').'(' + let after = ')' + if newchar ==# 'F' + let before = before . ' ' + let after = ' ' . after + endif + endif + elseif idx >= 0 + let spc = (idx % 3) == 1 ? " " : "" + let idx = idx / 3 * 3 + let before = strpart(pairs,idx+1,1) . spc + let after = spc . strpart(pairs,idx+2,1) + elseif newchar == "\<C-[>" || newchar == "\<C-]>" + let before = "{\n\t" + let after = "\n}" + elseif newchar !~ '\a' + let before = newchar + let after = newchar + else + let before = '' + let after = '' + endif + "let before = substitute(before,'\n','\n'.initspaces,'g') + let after = substitute(after ,'\n','\n'.initspaces,'g') + "let after = substitute(after,"\n\\s*\<C-U>\\s*",'\n','g') + if type ==# 'V' || (special && type ==# "v") + let before = substitute(before,' \+$','','') + let after = substitute(after ,'^ \+','','') + if after !~ '^\n' + let after = initspaces.after + endif + if keeper !~ '\n$' && after !~ '^\n' + let keeper = keeper . "\n" + elseif keeper =~ '\n$' && after =~ '^\n' + let after = strpart(after,1) + endif + if before !~ '\n\s*$' + let before = before . "\n" + if special + let before = before . "\t" + endif + endif + endif + if type ==# 'V' + let before = initspaces.before + endif + if before =~ '\n\s*\%$' + if type ==# 'v' + let keeper = initspaces.keeper + endif + let padding = matchstr(before,'\n\zs\s\+\%$') + let before = substitute(before,'\n\s\+\%$','\n','') + let keeper = s:fixindent(keeper,padding) + endif + if type ==# 'V' + let keeper = before.keeper.after + elseif type =~ "^\<C-V>" + " Really we should be iterating over the buffer + let repl = substitute(before,'[\\~]','\\&','g').'\1'.substitute(after,'[\\~]','\\&','g') + let repl = substitute(repl,'\n',' ','g') + let keeper = substitute(keeper."\n",'\(.\{-\}\)\('.(special ? '\s\{-\}' : '').'\n\)',repl.'\n','g') + let keeper = substitute(keeper,'\n\%$','','') + else + let keeper = before.extraspace.keeper.extraspace.after + endif + return keeper +endfunction + +function! s:wrapreg(reg,char,...) + let orig = getreg(a:reg) + let type = substitute(getregtype(a:reg),'\d\+$','','') + let special = a:0 ? a:1 : 0 + let new = s:wrap(orig,a:char,type,special) + call setreg(a:reg,new,type) +endfunction +" }}}1 + +function! s:insert(...) " {{{1 + " Optional argument causes the result to appear on 3 lines, not 1 + "call inputsave() + let linemode = a:0 ? a:1 : 0 + let char = s:inputreplacement() + while char == "\<CR>" || char == "\<C-S>" + " TODO: use total count for additional blank lines + let linemode = linemode + 1 + let char = s:inputreplacement() + endwhile + "call inputrestore() + if char == "" + return "" + endif + "call inputsave() + let cb_save = &clipboard + let reg_save = @@ + call setreg('"',"\r",'v') + call s:wrapreg('"',char,linemode) + " If line mode is used and the surrounding consists solely of a suffix, + " remove the initial newline. This fits a use case of mine but is a + " little inconsistent. Is there anyone that would prefer the simpler + " behavior of just inserting the newline? + if linemode && match(getreg('"'),'^\n\s*\zs.*') == 0 + call setreg('"',matchstr(getreg('"'),'^\n\s*\zs.*'),getregtype('"')) + endif + " This can be used to append a placeholder to the end + if exists("g:surround_insert_tail") + call setreg('"',g:surround_insert_tail,"a".getregtype('"')) + endif + "if linemode + "call setreg('"',substitute(getreg('"'),'^\s\+','',''),'c') + "endif + if col('.') >= col('$') + norm! ""p + else + norm! ""P + endif + if linemode + call s:reindent() + endif + norm! `] + call search('\r','bW') + let @@ = reg_save + let &clipboard = cb_save + return "\<Del>" +endfunction " }}}1 + +function! s:reindent() " {{{1 + if exists("b:surround_indent") ? b:surround_indent : (exists("g:surround_indent") && g:surround_indent) + silent norm! '[='] + endif +endfunction " }}}1 + +function! s:dosurround(...) " {{{1 + let scount = v:count1 + let char = (a:0 ? a:1 : s:inputtarget()) + let spc = "" + if char =~ '^\d\+' + let scount = scount * matchstr(char,'^\d\+') + let char = substitute(char,'^\d\+','','') + endif + if char =~ '^ ' + let char = strpart(char,1) + let spc = 1 + endif + if char == 'a' + let char = '>' + endif + if char == 'r' + let char = ']' + endif + let newchar = "" + if a:0 > 1 + let newchar = a:2 + if newchar == "\<Esc>" || newchar == "\<C-C>" || newchar == "" + return s:beep() + endif + endif + let cb_save = &clipboard + set clipboard-=unnamed + let append = "" + let original = getreg('"') + let otype = getregtype('"') + call setreg('"',"") + let strcount = (scount == 1 ? "" : scount) + if char == '/' + exe 'norm '.strcount.'[/d'.strcount.']/' + else + exe 'norm d'.strcount.'i'.char + endif + let keeper = getreg('"') + let okeeper = keeper " for reindent below + if keeper == "" + call setreg('"',original,otype) + let &clipboard = cb_save + return "" + endif + let oldline = getline('.') + let oldlnum = line('.') + if char ==# "p" + call setreg('"','','V') + elseif char ==# "s" || char ==# "w" || char ==# "W" + " Do nothing + call setreg('"','') + elseif char =~ "[\"'`]" + exe "norm! i \<Esc>d2i".char + call setreg('"',substitute(getreg('"'),' ','','')) + elseif char == '/' + norm! "_x + call setreg('"','/**/',"c") + let keeper = substitute(substitute(keeper,'^/\*\s\=','',''),'\s\=\*$','','') + else + " One character backwards + call search('.','bW') + exe "norm da".char + endif + let removed = getreg('"') + let rem2 = substitute(removed,'\n.*','','') + let oldhead = strpart(oldline,0,strlen(oldline)-strlen(rem2)) + let oldtail = strpart(oldline, strlen(oldline)-strlen(rem2)) + let regtype = getregtype('"') + if char =~# '[\[({<T]' || spc + let keeper = substitute(keeper,'^\s\+','','') + let keeper = substitute(keeper,'\s\+$','','') + endif + if col("']") == col("$") && col('.') + 1 == col('$') + if oldhead =~# '^\s*$' && a:0 < 2 + let keeper = substitute(keeper,'\%^\n'.oldhead.'\(\s*.\{-\}\)\n\s*\%$','\1','') + endif + let pcmd = "p" + else + let pcmd = "P" + endif + if line('.') < oldlnum && regtype ==# "V" + let pcmd = "p" + endif + call setreg('"',keeper,regtype) + if newchar != "" + call s:wrapreg('"',newchar) + endif + silent exe 'norm! ""'.pcmd.'`[' + if removed =~ '\n' || okeeper =~ '\n' || getreg('"') =~ '\n' + call s:reindent() + endif + if getline('.') =~ '^\s\+$' && keeper =~ '^\s*\n' + silent norm! cc + endif + call setreg('"',removed,regtype) + let s:lastdel = removed + let &clipboard = cb_save + if newchar == "" + silent! call repeat#set("\<Plug>Dsurround".char,scount) + else + silent! call repeat#set("\<Plug>Csurround".char.newchar,scount) + endif +endfunction " }}}1 + +function! s:changesurround() " {{{1 + let a = s:inputtarget() + if a == "" + return s:beep() + endif + let b = s:inputreplacement() + if b == "" + return s:beep() + endif + call s:dosurround(a,b) +endfunction " }}}1 + +function! s:opfunc(type,...) " {{{1 + let char = s:inputreplacement() + if char == "" + return s:beep() + endif + let reg = '"' + let sel_save = &selection + let &selection = "inclusive" + let cb_save = &clipboard + set clipboard-=unnamed + let reg_save = getreg(reg) + let reg_type = getregtype(reg) + "call setreg(reg,"\n","c") + let type = a:type + if a:type == "char" + silent exe 'norm! v`[o`]"'.reg.'y' + let type = 'v' + elseif a:type == "line" + silent exe 'norm! `[V`]"'.reg.'y' + let type = 'V' + elseif a:type ==# "v" || a:type ==# "V" || a:type ==# "\<C-V>" + silent exe 'norm! gv"'.reg.'y' + elseif a:type =~ '^\d\+$' + let type = 'v' + silent exe 'norm! ^v'.a:type.'$h"'.reg.'y' + if mode() == 'v' + norm! v + return s:beep() + endif + else + let &selection = sel_save + let &clipboard = cb_save + return s:beep() + endif + let keeper = getreg(reg) + if type == "v" && a:type != "v" + let append = matchstr(keeper,'\_s\@<!\s*$') + let keeper = substitute(keeper,'\_s\@<!\s*$','','') + endif + call setreg(reg,keeper,type) + call s:wrapreg(reg,char,a:0) + if type == "v" && a:type != "v" && append != "" + call setreg(reg,append,"ac") + endif + silent exe 'norm! gv'.(reg == '"' ? '' : '"' . reg).'p`[' + if type == 'V' || (getreg(reg) =~ '\n' && type == 'v') + call s:reindent() + endif + call setreg(reg,reg_save,reg_type) + let &selection = sel_save + let &clipboard = cb_save + if a:type =~ '^\d\+$' + silent! call repeat#set("\<Plug>Y".(a:0 ? "S" : "s")."surround".char,a:type) + endif +endfunction + +function! s:opfunc2(arg) + call s:opfunc(a:arg,1) +endfunction " }}}1 + +function! s:closematch(str) " {{{1 + " Close an open (, {, [, or < on the command line. + let tail = matchstr(a:str,'.[^\[\](){}<>]*$') + if tail =~ '^\[.\+' + return "]" + elseif tail =~ '^(.\+' + return ")" + elseif tail =~ '^{.\+' + return "}" + elseif tail =~ '^<.+' + return ">" + else + return "" + endif +endfunction " }}}1 + +nnoremap <silent> <Plug>Dsurround :<C-U>call <SID>dosurround(<SID>inputtarget())<CR> +nnoremap <silent> <Plug>Csurround :<C-U>call <SID>changesurround()<CR> +nnoremap <silent> <Plug>Yssurround :<C-U>call <SID>opfunc(v:count1)<CR> +nnoremap <silent> <Plug>YSsurround :<C-U>call <SID>opfunc2(v:count1)<CR> +" <C-U> discards the numerical argument but there's not much we can do with it +nnoremap <silent> <Plug>Ysurround :<C-U>set opfunc=<SID>opfunc<CR>g@ +nnoremap <silent> <Plug>YSurround :<C-U>set opfunc=<SID>opfunc2<CR>g@ +vnoremap <silent> <Plug>Vsurround :<C-U>call <SID>opfunc(visualmode())<CR> +vnoremap <silent> <Plug>VSurround :<C-U>call <SID>opfunc2(visualmode())<CR> +inoremap <silent> <Plug>Isurround <C-R>=<SID>insert()<CR> +inoremap <silent> <Plug>ISurround <C-R>=<SID>insert(1)<CR> + +if !exists("g:surround_no_mappings") || ! g:surround_no_mappings + nmap ds <Plug>Dsurround + nmap cs <Plug>Csurround + nmap ys <Plug>Ysurround + nmap yS <Plug>YSurround + nmap yss <Plug>Yssurround + nmap ySs <Plug>YSsurround + nmap ySS <Plug>YSsurround + if !hasmapto("<Plug>Vsurround","v") + if exists(":xmap") + xmap s <Plug>Vsurround + else + vmap s <Plug>Vsurround + endif + endif + if !hasmapto("<Plug>VSurround","v") + if exists(":xmap") + xmap S <Plug>VSurround + else + vmap S <Plug>VSurround + endif + endif + if !hasmapto("<Plug>Isurround","i") && "" == mapcheck("<C-S>","i") + imap <C-S> <Plug>Isurround + endif + imap <C-G>s <Plug>Isurround + imap <C-G>S <Plug>ISurround + "Implemented internally instead + "imap <C-S><C-S> <Plug>ISurround +endif + +let &cpo = s:cpo_save + +" vim:set ft=vim sw=4 sts=4 et: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-25 03:43:41
|
Revision: 1554 http://assorted.svn.sourceforge.net/assorted/?rev=1554&view=rev Author: yangzhang Date: 2010-01-25 03:43:31 +0000 (Mon, 25 Jan 2010) Log Message: ----------- added repeat.vim Added Paths: ----------- configs/trunk/src/vim/plugin/repeat.vim Added: configs/trunk/src/vim/plugin/repeat.vim =================================================================== --- configs/trunk/src/vim/plugin/repeat.vim (rev 0) +++ configs/trunk/src/vim/plugin/repeat.vim 2010-01-25 03:43:31 UTC (rev 1554) @@ -0,0 +1,72 @@ +" repeat.vim - Let the repeat command repeat plugin maps +" Maintainer: Tim Pope +" Version: 1.0 + +" Installation: +" Place in either ~/.vim/plugin/repeat.vim (to load at start up) or +" ~/.vim/autoload/repeat.vim (to load automatically as needed). +" +" Developers: +" Basic usage is as follows: +" +" silent! call repeat#set("\<Plug>MappingToRepeatCommand",3) +" +" The first argument is the mapping that will be invoked when the |.| key is +" pressed. Typically, it will be the same as the mapping the user invoked. +" This sequence will be stuffed into the input queue literally. Thus you must +" encode special keys by prefixing them with a backslash inside double quotes. +" +" The second argument is the default count. This is the number that will be +" prefixed to the mapping if no explicit numeric argument was given. The +" value of the v:count variable is usually correct and it will be used if the +" second parameter is omitted. If your mapping doesn't accept a numeric +" argument and you never want to receive one, pass a value of -1. +" +" Make sure to call the repeat#set function _after_ making changes to the +" file. + +if exists("g:loaded_repeat") || &cp || v:version < 700 + finish +endif +let g:loaded_repeat = 1 + +let g:repeat_tick = -1 + +function! repeat#set(sequence,...) + silent exe "norm! \"=''\<CR>p" + let g:repeat_sequence = a:sequence + let g:repeat_count = a:0 ? a:1 : v:count + let g:repeat_tick = b:changedtick +endfunction + +function! s:repeat(count) + if g:repeat_tick == b:changedtick + let c = g:repeat_count + let s = g:repeat_sequence + let cnt = c == -1 ? "" : (a:count ? a:count : (c ? c : '')) + call feedkeys(cnt . s) + else + call feedkeys((a:count ? a:count : '') . '.', 'n') + endif +endfunction + +function! s:wrap(command,count) + let preserve = (g:repeat_tick == b:changedtick) + exe 'norm! '.(a:count ? a:count : '').a:command + if preserve + let g:repeat_tick = b:changedtick + endif +endfunction + +nnoremap <silent> . :<C-U>call <SID>repeat(v:count)<CR> +nnoremap <silent> u :<C-U>call <SID>wrap('u',v:count)<CR> +nnoremap <silent> U :<C-U>call <SID>wrap('U',v:count)<CR> +nnoremap <silent> <C-R> :<C-U>call <SID>wrap("\<Lt>C-R>",v:count)<CR> + +augroup repeatPlugin + autocmd! + autocmd BufLeave,BufWritePre,BufReadPre * let g:repeat_tick = (g:repeat_tick == b:changedtick || g:repeat_tick == 0) ? 0 : -1 + autocmd BufEnter,BufWritePost * if g:repeat_tick == 0|let g:repeat_tick = b:changedtick|endif +augroup END + +" vim:set ft=vim et sw=4 sts=4: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2010-01-25 03:43:04
|
Revision: 1553 http://assorted.svn.sourceforge.net/assorted/?rev=1553&view=rev Author: yangzhang Date: 2010-01-25 03:42:58 +0000 (Mon, 25 Jan 2010) Log Message: ----------- added python matchit for vim Added Paths: ----------- configs/trunk/src/vim/plugin/python_match.vim Added: configs/trunk/src/vim/plugin/python_match.vim =================================================================== --- configs/trunk/src/vim/plugin/python_match.vim (rev 0) +++ configs/trunk/src/vim/plugin/python_match.vim 2010-01-25 03:42:58 UTC (rev 1553) @@ -0,0 +1,287 @@ +" Python filetype plugin for matching with % key +" Language: Python (ft=python) +" Last Change: Thu 02 Oct 2003 12:12:20 PM EDT +" Maintainer: Benji Fisher, Ph.D. <be...@me...> +" Version: 0.5, for Vim 6.1 +" URL: http://www.vim.org/scripts/script.php?script_id=386 + +" allow user to prevent loading and prevent duplicate loading +if exists("b:loaded_py_match") || &cp + finish +endif +let b:loaded_py_match = 1 + +let s:save_cpo = &cpo +set cpo&vim + +" % for if -> elif -> else -> if, g% for else -> elif -> if -> else +nnoremap <buffer> <silent> % :<C-U>call <SID>PyMatch('%','n') <CR> +vnoremap <buffer> <silent> % :<C-U>call <SID>PyMatch('%','v') <CR>m'gv`` +onoremap <buffer> <silent> % v:<C-U>call <SID>PyMatch('%','o') <CR> +nnoremap <buffer> <silent> g% :<C-U>call <SID>PyMatch('g%','n') <CR> +vnoremap <buffer> <silent> g% :<C-U>call <SID>PyMatch('g%','v') <CR>m'gv`` +onoremap <buffer> <silent> g% v:<C-U>call <SID>PyMatch('g%','o') <CR> +" Move to the start ([%) or end (]%) of the current block. +nnoremap <buffer> <silent> [% :<C-U>call <SID>PyMatch('[%', 'n') <CR> +vnoremap <buffer> <silent> [% :<C-U>call <SID>PyMatch('[%','v') <CR>m'gv`` +onoremap <buffer> <silent> [% v:<C-U>call <SID>PyMatch('[%', 'o') <CR> +nnoremap <buffer> <silent> ]% :<C-U>call <SID>PyMatch(']%', 'n') <CR> +vnoremap <buffer> <silent> ]% :<C-U>call <SID>PyMatch(']%','v') <CR>m'gv`` +onoremap <buffer> <silent> ]% v:<C-U>call <SID>PyMatch(']%', 'o') <CR> + +" The rest of the file needs to be :sourced only once per session. +if exists("s:loaded_functions") || &cp + finish +endif +let s:loaded_functions = 1 + +" One problem with matching in Python is that so many parts are optional. +" I deal with this by matching on any known key words at the start of the +" line, if they have the same indent. +" +" Recognize try, except, finally and if, elif, else . +" keywords that start a block: +let s:ini1 = 'try\|if' +" These are special, because the matching words may not have the same indent: +let s:ini2 = 'for\|while' +" keywords that continue or end a block: +let s:tail1 = 'except\|finally' +let s:tail1 = s:tail1 . '\|elif\|else' +" These go with s:ini2 : +let s:tail2 = 'break\|continue' +" all keywords: +let s:all1 = s:ini1 . '\|' . s:tail1 +let s:all2 = s:ini2 . '\|' . s:tail2 + +fun! s:PyMatch(type, mode) range + " I have to do this before the :normal gv... + let cnt = v:count1 + " If this function was called from Visual mode, make sure that the cursor + " is at the correct end of the Visual range: + if a:mode == "v" + execute "normal! gv\<Esc>" + endif + " Use default behavior if called as % with a count. + if a:type == "%" && v:count + exe "normal! " . v:count . "%" + return s:CleanUp('', a:mode) + endif + + " Do not change these: needed for s:CleanUp() + let s:startline = line(".") + let s:startcol = col(".") + " In case we start on a comment line, ... + if a:type == '[%' || a:type == ']%' + let currline = s:NonComment(+1, s:startline-1) + else + let currline = s:startline + endif + let startindent = indent(currline) + " Set a mark before jumping. + normal! m' + + " If called as [%, find the start of the current block. + " If called as ]%, find the end of the current block. + if a:type == '[%' || a:type == ']%' + while cnt > 0 + let currline = (a:type == '[%') ? + \ s:StartOfBlock(currline) : s:EndOfBlock(currline) + let cnt = cnt - 1 + endwhile + execute currline + return s:CleanUp('', a:mode, '$') + endif + + " If called as % or g%, decide whether to bail out. + if a:type == '%' || a:type == 'g%' + let text = getline(currline) + if strpart(text, 0, col(".")) =~ '\S\s' + \ || text !~ '^\s*\%(' . s:all1 . '\|' . s:all2 . '\)' + " cursor not on the first WORD or no keyword so bail out + if a:type == '%' + normal! % + endif + return s:CleanUp('', a:mode) + endif + " If it matches s:all2, we need to find the "for" or "while". + if text =~ '^\s*\%(' . s:all2 . '\)' + let topline = currline + while getline(topline) !~ '^\s*\%(' . s:ini2 . '\)' + let temp = s:StartOfBlock(topline) + if temp == topline " there is no enclosing block. + return s:CleanUp('', a:mode) + endif + let topline = temp + endwhile + let topindent = indent(topline) + endif + endif + + " If called as %, look down for "elif" or "else" or up for "if". + if a:type == '%' && text =~ '^\s*\%('. s:all1 .'\)' + let next = s:NonComment(+1, currline) + while next > 0 && indent(next) > startindent + let next = s:NonComment(+1, next) + endwhile + if next == 0 || indent(next) < startindent + \ || getline(next) !~ '^\s*\%(' . s:tail1 . '\)' + " There are no "tail1" keywords below startline in this block. Go to + " the start of the block. + let next = (text =~ '^\s*\%(' . s:ini1 . '\)') ? + \ currline : s:StartOfBlock(currline) + endif + execute next + return s:CleanUp('', a:mode, '$') + endif + + " If called as %, look down for "break" or "continue" or up for + " "for" or "while". + if a:type == '%' && text =~ '^\s*\%(' . s:all2 . '\)' + let next = s:NonComment(+1, currline) + while next > 0 && indent(next) > topindent + \ && getline(next) !~ '^\s*\%(' . s:tail2 . '\)' + " Skip over nested "for" or "while" blocks: + if getline(next) =~ '^\s*\%(' . s:ini2 . '\)' + let next = s:EndOfBlock(next) + endif + let next = s:NonComment(+1, next) + endwhile + if indent(next) > topindent && getline(next) =~ '^\s*\%(' . s:tail2 . '\)' + execute next + else " There are no "tail2" keywords below v:startline, so go to topline. + execute topline + endif + return s:CleanUp('', a:mode, '$') + endif + + " If called as g%, look up for "if" or "elif" or "else" or down for any. + if a:type == 'g%' && text =~ '^\s*\%('. s:all1 .'\)' + " If we started at the top of the block, go down to the end of the block. + if text =~ '^\s*\(' . s:ini1 . '\)' + let next = s:EndOfBlock(currline) + else + let next = s:NonComment(-1, currline) + endif + while next > 0 && indent(next) > startindent + let next = s:NonComment(-1, next) + endwhile + if indent(next) == startindent && getline(next) =~ '^\s*\%('.s:all1.'\)' + execute next + endif + return s:CleanUp('', a:mode, '$') + endif + + " If called as g%, look up for "for" or "while" or down for any. + if a:type == 'g%' && text =~ '^\s*\%(' . s:all2 . '\)' + " Start at topline . If we started on a "for" or "while" then topline is + " the same as currline, and we want the last "break" or "continue" in the + " block. Otherwise, we want the last one before currline. + let botline = (topline == currline) ? line("$") + 1 : currline + let currline = topline + let next = s:NonComment(+1, currline) + while next < botline && indent(next) > topindent + if getline(next) =~ '^\s*\%(' . s:tail2 . '\)' + let currline = next + elseif getline(next) =~ '^\s*\%(' . s:ini2 . '\)' + " Skip over nested "for" or "while" blocks: + let next = s:EndOfBlock(next) + endif + let next = s:NonComment(+1, next) + endwhile + execute currline + return s:CleanUp('', a:mode, '$') + endif + +endfun + +" Return the line number of the next non-comment, or 0 if there is none. +" Start at the current line unless the optional second argument is given. +" The direction is specified by a:inc (normally +1 or -1 ; +" no test for a:inc == 0, which may lead to an infinite loop). +fun! s:NonComment(inc, ...) + if a:0 > 0 + let next = a:1 + a:inc + else + let next = line(".") + a:inc + endif + while 0 < next && next <= line("$") + if getline(next) !~ '^\s*\(#\|$\)' + return next + endif + let next = next + a:inc + endwhile + return 0 " If the while loop finishes, we fell off the end of the file. +endfun + +" Return the line number of the top of the block containing Line a:start . +" For most lines, this is the first previous line with smaller indent. +" For lines starting with "except", "finally", "elif", or "else", this is the +" first previous line starting with "try" or "if". +fun! s:StartOfBlock(start) + let startindent = indent(a:start) + let tailflag = (getline(a:start) =~ '^\s*\(' . s:tail1 . '\)') + let prevline = s:NonComment(-1, a:start) + while prevline > 0 + if indent(prevline) < startindent || + \ tailflag && indent(prevline) == startindent && + \ getline(prevline) =~ '^\s*\(' . s:ini1 . '\)' + " Found the start of block! + return prevline + endif + let prevline = s:NonComment(-1, prevline) + endwhile + " If the loop completes, then s:NonComment() returned 0, so we are at the + " top. + return a:start +endfun + +" Return the line number of the end of the block containing Line a:start . +" For most lines, this is the line before the next line with smaller indent. +" For lines that begin a block, go to the end of that block, with special +" treatment for "if" and "try" blocks. +fun! s:EndOfBlock(start) + let startindent = indent(a:start) + let currline = a:start + let nextline = s:NonComment(+1, currline) + let startofblock = (indent(nextline) > startindent) || + \ getline(currline) =~ '^\s*\(' . s:ini1 . '\)' + while nextline > 0 + if indent(nextline) < startindent || + \ startofblock && indent(nextline) == startindent && + \ getline(nextline) !~ '^\s*\(' . s:tail1 . '\)' + break + endif + let currline = nextline + let nextline = s:NonComment(+1, currline) + endwhile + " nextline is in the next block or after EOF, so return currline: + return currline +endfun + +" Restore options and do some special handling for Operator-pending mode. +" The optional argument is the tail of the matching group. +fun! s:CleanUp(options, mode, ...) + if strlen(a:options) + execute "set" a:options + endif + " Open folds, if appropriate. + if a:mode != "o" + if &foldopen =~ "percent" + normal! zv + endif + " In Operator-pending mode, we want to include the whole match + " (for example, d%). + " This is only a problem if we end up moving in the forward direction. + elseif s:startline < line(".") || + \ s:startline == line(".") && s:startcol < col(".") + if a:0 + " If we want to include the whole line then a:1 should be '$' . + silent! call search(a:1) + endif + endif " a:mode != "o" + return 0 +endfun + +let &cpo = s:save_cpo + +" vim:sts=2:sw=2:ff=unix: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |