Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

tons of changes i'm too lazy to split out

  • Loading branch information...
commit f668d7ea44c6a131d8cd508d3761c5eb4fc4e07c 1 parent 262b9a1
@bkudria authored
Showing with 16,320 additions and 37 deletions.
  1. +7 −0 .bashrc
  2. +2 −0  .emacs
  3. +1 −1  .emacs.d/color-theme-lite-brite.el
  4. +8 −7 .emacs.d/color-theme-scanner-brightly.el
  5. +6 −5 .emacs.d/init-bindings.el
  6. +1 −1  .emacs.d/init-common.el
  7. +1 −0  .emacs.d/init-functions.el
  8. +36 −11 .emacs.d/init-modes.el
  9. +3 −2 .emacs.d/init-require.el
  10. +3 −4 .emacs.d/init-x-windows.el
  11. +5 −4 .gemrc
  12. +12 −2 .gitconfig
  13. +231 −0 .hgext/autopager.py
  14. BIN  .hgext/autopager.pyc
  15. BIN  .hgext/crecord/.hg/00changelog.i
  16. +1 −0  .hgext/crecord/.hg/branch
  17. +2 −0  .hgext/crecord/.hg/branch.cache
  18. BIN  .hgext/crecord/.hg/dirstate
  19. +2 −0  .hgext/crecord/.hg/hgrc
  20. +3 −0  .hgext/crecord/.hg/requires
  21. BIN  .hgext/crecord/.hg/store/00changelog.i
  22. BIN  .hgext/crecord/.hg/store/00manifest.i
  23. BIN  .hgext/crecord/.hg/store/data/crecord.py.i
  24. BIN  .hgext/crecord/.hg/store/data/crecord/____init____.py.i
  25. BIN  .hgext/crecord/.hg/store/data/crecord/chunk__selector.py.i
  26. BIN  .hgext/crecord/.hg/store/data/crecord/crecord__core.py.i
  27. BIN  .hgext/crecord/.hg/store/data/crecord/crpatch.py.i
  28. +5 −0 .hgext/crecord/.hg/store/fncache
  29. BIN  .hgext/crecord/.hg/store/undo
  30. +1 −0  .hgext/crecord/.hg/undo.branch
  31. 0  .hgext/crecord/.hg/undo.dirstate
  32. +43 −0 .hgext/crecord/crecord/__init__.py
  33. BIN  .hgext/crecord/crecord/__init__.pyc
  34. +934 −0 .hgext/crecord/crecord/chunk_selector.py
  35. BIN  .hgext/crecord/crecord/chunk_selector.pyc
  36. +180 −0 .hgext/crecord/crecord/crecord_core.py
  37. BIN  .hgext/crecord/crecord/crecord_core.pyc
  38. +661 −0 .hgext/crecord/crecord/crpatch.py
  39. BIN  .hgext/crecord/crecord/crpatch.pyc
  40. BIN  .hgext/cutehg-stable/.hg/00changelog.i
  41. +1 −0  .hgext/cutehg-stable/.hg/branch
  42. +2 −0  .hgext/cutehg-stable/.hg/branch.cache
  43. BIN  .hgext/cutehg-stable/.hg/dirstate
  44. +2 −0  .hgext/cutehg-stable/.hg/hgrc
  45. +3 −0  .hgext/cutehg-stable/.hg/requires
  46. BIN  .hgext/cutehg-stable/.hg/store/00changelog.i
  47. BIN  .hgext/cutehg-stable/.hg/store/00manifest.i
  48. BIN  .hgext/cutehg-stable/.hg/store/data/.hgignore.i
  49. BIN  .hgext/cutehg-stable/.hg/store/data/.hgtags.i
  50. BIN  .hgext/cutehg-stable/.hg/store/data/_c_o_p_y_i_n_g.i
  51. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/____init____.py.i
  52. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/annotate.py.i
  53. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/clone.py.i
  54. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/commands.py.i
  55. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/commit.py.i
  56. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/cutehg.py.i
  57. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/____init____.py.i
  58. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/configure.png.i
  59. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/dialog-cancel.png.i
  60. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/dialog-ok.png.i
  61. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/document-revert.png.i
  62. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/edit-find.png.i
  63. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/edit-undo.png.i
  64. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/go-down-search.png.i
  65. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/go-down.png.i
  66. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/go-up-search.png.i
  67. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/go-up.png.i
  68. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/history.py.i
  69. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/history.qrc.i
  70. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/history.ui.i
  71. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/history__rc.py.i
  72. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/historyview.ui.i
  73. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/im-status-message-edit.png.i
  74. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/mainwindow.ui.i
  75. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__commit.py.i
  76. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__commit.ui.i
  77. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__conflict__resolution.py.i
  78. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__conflict__resolution.ui.i
  79. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__revision__selection.py.i
  80. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/merge__revision__selection.ui.i
  81. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/network-connect.png.i
  82. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__add.png.i
  83. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__branch.png.i
  84. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__merge.png.i
  85. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__remove.png.i
  86. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__status.png.i
  87. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/svn__switch.png.i
  88. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/synchronize.py.i
  89. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/synchronize.ui.i
  90. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/ui__history.py.i
  91. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/update.py.i
  92. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/update.ui.i
  93. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__add.png.i
  94. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__commit.png.i
  95. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__diff.png.i
  96. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__remove.png.i
  97. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__status.png.i
  98. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/vcs__update.png.i
  99. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/dialogs/view-refresh.png.i
  100. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/diff.py.i
  101. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/history.py.i
  102. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/configure.png.i
  103. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/dialog-cancel.png.i
  104. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/dialog-ok.png.i
  105. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/document-revert.png.i
  106. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/edit-find.png.i
  107. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/edit-undo.png.i
  108. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/go-down-search.png.i
  109. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/go-down.png.i
  110. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/go-up-search.png.i
  111. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/go-up.png.i
  112. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/icons.qrc.i
  113. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/im-status-message-edit.png.i
  114. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/logo-droplets-200.png.i
  115. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/network-connect.png.i
  116. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__add.png.i
  117. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__branch.png.i
  118. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__merge.png.i
  119. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__remove.png.i
  120. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__status.png.i
  121. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/svn__switch.png.i
  122. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/text-x-generic.png.i
  123. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__add.png.i
  124. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__commit.png.i
  125. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__diff.png.i
  126. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__remove.png.i
  127. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__status.png.i
  128. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/vcs__update.png.i
  129. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/view-list-text.png.i
  130. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons/view-refresh.png.i
  131. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/icons__rc.py.i
  132. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/merge.py.i
  133. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/passwordpatch.py.i
  134. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/pull.py.i
  135. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/push.py.i
  136. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/runner.py.i
  137. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/runners.py.i
  138. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/runnerui.py.i
  139. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/serve.py.i
  140. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/status.py.i
  141. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/synchronize.py.i
  142. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/annotate.ui.i
  143. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/commit.ui.i
  144. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/history.ui.i
  145. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/historywidget.ui.i
  146. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/merge__commit.ui.i
  147. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/merge__conflict__resolution.ui.i
  148. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/merge__revision__selection.ui.i
  149. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/synchronize.ui.i
  150. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui/update.ui.i
  151. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui__historyview.py.i
  152. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/ui__mainwindow.py.i
  153. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/update.py.i
  154. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/utils.py.i
  155. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/____init____.py.i
  156. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/common.py.i
  157. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/dvcsinterface.py.i
  158. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/____init____.py.i
  159. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/dvcs__hg.py.i
  160. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/hg.py.i
  161. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/historydecorator.py.i
  162. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/historygraphdelegate.py.i
  163. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/historyitem.py.i
  164. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/historymodel.py.i
  165. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/historysearch.py.i
  166. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcs/hg/passwordpatch.py.i
  167. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcscommands.py.i
  168. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/____init____.py.i
  169. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/historydecorator.py.i
  170. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/historygraphdelegate.py.i
  171. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/historyinfodelegate.py.i
  172. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/historymodel.py.i
  173. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/historysearch.py.i
  174. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsmodel/statusmodel.py.i
  175. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsview/____init____.py.i
  176. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsview/historyview.py.i
  177. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/vcsview/layouts/historylayout.ui.i
  178. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/____init____.py.i
  179. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/annotateview.py.i
  180. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/colorutil.py.i
  181. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/commitmessageview.py.i
  182. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/commitview.py.i
  183. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/diffview.py.i
  184. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/historygraphdelegate.py.i
  185. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/historyview.py.i
  186. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/layouts/annotatelayout.ui.i
  187. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/layouts/historylayout.ui.i
  188. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/layouts/statuslayout.ui.i
  189. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/____init____.py.i
  190. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/abstractmodel.py.i
  191. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/annotatemodel.py.i
  192. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/colorutil.py.i
  193. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/diffhighlighter.py.i
  194. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/diffmodel.py.i
  195. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/historydecorator.py.i
  196. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/historygraphdelegate.py.i
  197. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/historymodel.py.i
  198. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/historysearch.py.i
  199. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/searchproxy.py.i
  200. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/models/statusmodel.py.i
  201. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/qtutil.py.i
  202. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/views/statusview.py.i
  203. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/____init____.py.i
  204. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historydecorator.py.i
  205. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historygraphdelegate.py.i
  206. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historyinfodelegate.py.i
  207. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historymodel.py.i
  208. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historyrevisiondelegate.py.i
  209. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historysearch.py.i
  210. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/historyview.py.i
  211. BIN  .hgext/cutehg-stable/.hg/store/data/cutehg/widgets/simplehistoryproxy.py.i
  212. BIN  .hgext/cutehg-stable/.hg/store/data/hgext/cutehg.py.i
  213. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/clone.py.i
  214. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/commit.py.i
  215. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/dialogs/pull.ui.i
  216. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/dialogs/push.ui.i
  217. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/dialogs/synchronize.ui.i
  218. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/dialogs/update.ui.i
  219. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/history.py.i
  220. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/pull.py.i
  221. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/push.py.i
  222. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/serve.py.i
  223. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/synchronize.py.i
  224. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/update.py.i
  225. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/utils.py.i
  226. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/widgets/____init____.py.i
  227. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/widgets/historygraphdelegate.py.i
  228. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/widgets/historymodel.py.i
  229. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/widgets/historysearch.py.i
  230. BIN  .hgext/cutehg-stable/.hg/store/data/hgqt/widgets/historyview.py.i
  231. BIN  .hgext/cutehg-stable/.hg/store/data/installer/cutehg.ico.i
  232. BIN  .hgext/cutehg-stable/.hg/store/data/installer/cutehg.nsi.i
  233. BIN  .hgext/cutehg-stable/.hg/store/data/installer/devel.snap.i
  234. BIN  .hgext/cutehg-stable/.hg/store/data/installer/hg-patches/cutehg-extension.i
  235. BIN  .hgext/cutehg-stable/.hg/store/data/installer/hg-patches/cutehg-installer-no-locales.i
  236. BIN  .hgext/cutehg-stable/.hg/store/data/installer/hg-patches/cutehg-modify-installer-data.i
  237. BIN  .hgext/cutehg-stable/.hg/store/data/installer/hg-patches/cutehg-setup-fixes.i
  238. BIN  .hgext/cutehg-stable/.hg/store/data/installer/hg-patches/series.i
  239. BIN  .hgext/cutehg-stable/.hg/store/data/installer/mercurial-dist.ini.i
  240. BIN  .hgext/cutehg-stable/.hg/store/data/installer/mercurial.iss.i
  241. BIN  .hgext/cutehg-stable/.hg/store/data/license.txt.i
  242. BIN  .hgext/cutehg-stable/.hg/store/data/setup.py.i
  243. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/_library.rgs.i
  244. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/_menu.rgs.i
  245. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/_overlay.rgs.i
  246. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/common.cpp.i
  247. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/common.h.i
  248. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/cutehg.idl.i
  249. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/dllmain.cpp.i
  250. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/menu.cpp.i
  251. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/overlay.cpp.i
  252. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/shellext.def.i
  253. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/shellext.rc.i
  254. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/shellext.sln.i
  255. BIN  .hgext/cutehg-stable/.hg/store/data/shellext/shellext.vcproj.i
  256. BIN  .hgext/cutehg-stable/.hg/store/data/win32/postinstall.py.i
  257. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/_library.rgs.i
  258. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/_menu.rgs.i
  259. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/_overlay.rgs.i
  260. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/common.cpp.i
  261. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/common.h.i
  262. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/cutehg.idl.i
  263. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/dirstate.c.i
  264. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/dllmain.cpp.i
  265. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/fakeatl.cpp.i
  266. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/fakeatl.h.i
  267. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/menu.cpp.i
  268. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/overlay.cpp.i
  269. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/resource.h.i
  270. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/shellext.def.i
  271. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/shellext.rc.i
  272. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/shellext.sln.i
  273. BIN  .hgext/cutehg-stable/.hg/store/data/win32/shellext/shellext.vcproj.i
  274. +226 −0 .hgext/cutehg-stable/.hg/store/fncache
  275. BIN  .hgext/cutehg-stable/.hg/store/undo
  276. +1 −0  .hgext/cutehg-stable/.hg/undo.branch
  277. 0  .hgext/cutehg-stable/.hg/undo.dirstate
  278. +20 −0 .hgext/cutehg-stable/.hgignore
  279. +2 −0  .hgext/cutehg-stable/.hgtags
  280. +340 −0 .hgext/cutehg-stable/COPYING
  281. +179 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/__init__.py
  282. +83 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/annotate.py
  283. +22 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/clone.py
  284. +623 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/commands.py
  285. +69 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/commit.py
  286. +8 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/__init__.py
  287. +5,673 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/icons_rc.py
  288. +55 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_annotate.py
  289. +76 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_commit.py
  290. +158 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_history.py
  291. +39 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_merge_commit.py
  292. +32 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_merge_conflict_resolution.py
  293. +49 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_merge_revision_selection.py
  294. +314 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_synchronize.py
  295. +65 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/dialogs/ui_update.py
  296. +54 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/diff.py
  297. +234 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/history.py
  298. +5,673 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/icons_rc.py
  299. +70 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/merge.py
  300. +99 −0 .hgext/cutehg-stable/build/lib.linux-i686-2.6/cutehg/pull.py
Sorry, we could not display the entire diff because too many files (548) changed.
View
7 .bashrc
@@ -446,3 +446,10 @@ export PROMPT_COMMAND="history -a"
. ~/.bashrc.local
fi
+
+# -- start rip config -- #
+RIPDIR=/home/bkudria/.rip
+RUBYLIB="$RUBYLIB:$RIPDIR/active/lib"
+PATH="$PATH:$RIPDIR/active/bin"
+export RIPDIR RUBYLIB PATH
+# -- end rip config -- #
View
2  .emacs
@@ -37,3 +37,5 @@
(server-mode t) ; Enable server mode
+
+(put 'set-goal-column 'disabled nil)
View
2  .emacs.d/color-theme-lite-brite.el
@@ -228,7 +228,7 @@
(font-lock-doc-face ((t (:foreground "#777777"))))
(font-lock-doc-string-face ((t (:foreground "#777777"))))
(font-lock-function-name-face ((t (:foreground "#0F9FFF"))))
- (font-lock-keyword-face ((t (:foreground "#808080" :bold t))))
+ (font-lock-keyword-face ((t (:foreground "#0faf3f" :bold t))))
(font-lock-preprocessor-face ((t (:foreground "#ff00ff"))))
(font-lock-reference-face ((t (:foreground "#ff00ff"))))
(font-lock-string-face ((t (:foreground "#FF5F0F" :italic t))))
View
15 .emacs.d/color-theme-scanner-brightly.el
@@ -44,6 +44,7 @@
(defun color-theme-scanner-brightly ()
"Color theme by Benjamin Kudria <ben@kudria.net>."
(interactive)
+ (message "Loaded color theme")
(setq-default hl-paren-colors '("#bb6400" "#afbb00" "#4bbb00" "#00bb19" "#00bb7d" "#0096bb" "#0032bb" "#3200bb" "#9600bb" "#bb007d" "#bb0019" "#bb0000"))
(color-theme-install
`(color-theme-scanner-brightly
@@ -221,19 +222,19 @@
(font-lock-builtin-face ((t (:foreground "#ff00ff"))))
- (font-lock-color-constant-face ((t (:foreground "#CBFF0E"))))
+ (font-lock-color-constant-face ((t (:foreground "#00FF11"))))
(font-lock-comment-face ((t (:foreground "#9b9b9b" :italic t))))
(font-lock-comment-delimiter-face ((t (:foreground "#555555"))))
- (font-lock-constant-face ((t (:foreground "#98bb0a"))))
+ (font-lock-constant-face ((t (:foreground "#00c80d"))))
(font-lock-doc-face ((t (:foreground "#777777"))))
(font-lock-doc-string-face ((t (:foreground "#777777"))))
(font-lock-function-name-face ((t (:foreground "#0b75bb"))))
- (font-lock-keyword-face ((t (:foreground "#808080" :bold t))))
+ (font-lock-keyword-face ((t (:foreground "#404040" :bold t))))
(font-lock-preprocessor-face ((t (:foreground "#ff00ff"))))
(font-lock-reference-face ((t (:foreground "#ff00ff"))))
(font-lock-string-face ((t (:foreground "#BB450B" :italic t))))
(font-lock-type-face ((t (:foreground "#ff00ff"))))
- (font-lock-variable-name-face ((t (:foreground "#0BBBB5"))))
+ (font-lock-variable-name-face ((t (:foreground "#00bec8"))))
(font-lock-warning-face ((t (:foreground "#bb0b0b"))))
(font-lock-negation-char-face ((t (:foreground "#099191"))))
(font-lock-other-type-face ((t (:foreground "#808080" :italic t))))
@@ -244,7 +245,7 @@
(font-lock-regexp-grouping-backslash ((t (:foreground "#0bbb0b"))))
(font-lock-special-comment-face ((t (:foreground "#0bbb0b"))))
- (fringe ((t (:background "#eeeeee" :foreground nil))))
+ (fringe ((t (:background "#ffffff" :foreground "#000000"))))
;;; (header-line ((t (:box (:line-width 2
;;; :color "gray8"
@@ -355,8 +356,8 @@
(minibuffer-prompt ((t (:foreground "#00494D" :bold t))))
- (mode-line ((t (:foreground "#00494D" :background "#dddddd" :overline "#999999"))))
- (modeline ((t (:foreground "#00494D" :background "#dddddd" :overline "#999999"))))
+ (mode-line ((t (:foreground "#00494D" :background "#ffffff" :overline "#dddddd"))))
+ (modeline ((t (:foreground "#00494D" :background "#ffffff" :overline "#dddddd"))))
(mode-line-inactive ((t (:foreground "#00494D" :background "#dddddd" :overline "white"))))
(mode-line-highlight ((t (:foreground "#434343" :background "#aaaaaa"))))
View
11 .emacs.d/init-bindings.el
@@ -70,7 +70,7 @@
(global-set-key "\C-x\C-r" 'eval-and-replace)
-(global-set-key (kbd "RET") 'newline-and-indent)
+(global-set-key (kbd "RET") 'align-newline-and-indent)
(global-set-key (kbd "C-SPC") 'highlight-symbol-at-point)
@@ -93,9 +93,6 @@
(global-set-key [f7] 'kmacro-start-macro-or-insert-counter)
(global-set-key [f8] 'kmacro-end-or-call-macro)
-(define-key paredit-mode-map "\C-d" nil)
-(global-set-key "\C-d" 'comment-dwim)
-
;; multi-term
(global-set-key (kbd "<f9> t") 'multi-term)
(global-set-key (kbd "<f9> n") 'multi-term-next)
@@ -105,4 +102,8 @@
(add-hook 'haskell-mode-hook
'(lambda ()
- (define-key haskell-mode-map (kbd "\C-y") 'search-hayoo)))
+ (define-key haskell-mode-map (kbd "\C-y") 'search-hayoo)))
+
+(global-set-key "\C-x\C-d" 'ido-dired)
+
+(define-key dired-mode-map [backspace] 'dired-up-directory)
View
2  .emacs.d/init-common.el
@@ -33,4 +33,4 @@
;; Breaks dtrt-indent if t
(setq-default indent-tabs-mode nil)
-(color-theme-lite-brite)
+(color-theme-scanner-brightly)
View
1  .emacs.d/init-functions.el
@@ -60,6 +60,7 @@
(narrow-to-region (region-beginning) (region-end)))
(indent-region (point-min) (point-max) nil)
+ (align (point-min) (point-max))
(widen))
(defun eval-and-replace ()
View
47 .emacs.d/init-modes.el
@@ -9,9 +9,7 @@
(define-globalized-minor-mode global-paredit-mode paredit-mode turn-on-paredit-no-errors)
-(global-paredit-mode t)
-
-
+(autopair-global-mode t)
(ido-mode t) ; Turn on ido-mode
(setq-default ido-create-new-buffer 'always)
@@ -64,16 +62,27 @@
(setq-default whitespace-style
'(tabs spaces trailing space-before-tab indentation empty space-after-tab space-mark tab-mark))
-;; do some spooky shit to make the time display
-(display-time-mode t)
-(setq-default display-time-default-load-average 2)
-(setq-default display-time-mail-file 'none)
-(setq-default display-time-string-forms (quote ((if (and (not display-time-format) display-time-day-and-date) (format-time-string " %a %b %e " now) "") (propertize (format-time-string (or display-time-format (if display-time-24hr-format " %H:%M" "%-I:%M%p")) now) (quote help-echo) (format-time-string " %a %b %e, %Y" now)) load (if mail (concat " " (propertize display-time-mail-string (quote display) (\` (when (and display-time-use-mail-icon (display-graphic-p)) (\,@ display-time-mail-icon) (\,@ (if (and display-time-mail-face (memq (plist-get (cdr display-time-mail-icon) :type) (quote (pbm xbm)))) (let ((bg (face-attribute display-time-mail-face :background))) (if (stringp bg) (list :background bg))))))) (quote face) display-time-mail-face (quote help-echo) "You have new mail; mouse-2: Read mail" (quote mouse-face) (quote mode-line-highlight) (quote local-map) (make-mode-line-mouse-map (quote mouse-2) read-mail-command))) ""))))
-
- ; make dired slightly smarter
+;; make dired slightly smarter
(setq-default directory-free-space-program "di")
(setq-default directory-free-space-args "-Ph")
+(eval-after-load "dired"
+ ;; don't remove `other-window', the caller expects it to be there
+ '(defun dired-up-directory (&optional other-window)
+ "Run Dired on parent directory of current directory."
+ (interactive "P")
+ (let* ((dir (dired-current-directory))
+ (orig (current-buffer))
+ (up (file-name-directory (directory-file-name dir))))
+ (or (dired-goto-file (directory-file-name dir))
+ ;; Only try dired-goto-subdir if buffer has more than one dir.
+ (and (cdr dired-subdir-alist)
+ (dired-goto-subdir up))
+ (progn
+ (kill-buffer orig)
+ (dired up)
+ (dired-goto-file dir))))))
+
(tabkey2-mode t)
(setq-default tabkey2-completion-functions
'(
@@ -236,4 +245,20 @@
(arglist-close . c-lineup-arglist)
(access-label . 0)
(inher-cont . c-lineup-java-inher)
- (func-decl-cont . c-lineup-java-throws))))
+ (func-decl-cont . c-lineup-java-throws))))
+
+
+(defun flymake-erlang-init ()
+ (let* ((temp-file (flymake-init-create-temp-buffer-copy
+ 'flymake-create-temp-inplace))
+ (local-file (file-relative-name temp-file
+ (file-name-directory buffer-file-name))))
+ (list "~/bin/flymake-erlang.erl" (list local-file))))
+
+(add-to-list 'flymake-allowed-file-name-masks '("\\.erl\\'" flymake-erlang-init))
+
+
+(add-hook 'erlang-mode-hook
+ '(lambda ()
+ (flymake-mode t)
+ ))
View
5 .emacs.d/init-require.el
@@ -26,7 +26,6 @@
(require 'smooth-scrolling)
(require 'parenface)
(require 'color-theme-scanner-brightly)
-(require 'color-theme-lite-brite)
(require 'tabkey2)
(require 'dtrt-indent)
(require 'sudo-save)
@@ -42,4 +41,6 @@
(require 'tramp)
(require 'sr-speedbar)
(require 'etags)
-(require 'php-mode)
+(require 'php-mode)
+(require 'dired+)
+(require 'autopair)
View
7 .emacs.d/init-x-windows.el
@@ -9,8 +9,6 @@
(setq-default mouse-autoselect-window 0.5) ; select the window the pointer is in after 0.5 sec
(setq-default scalable-fonts-allowed t) ; allow scalable fonts
-(display-battery-mode t) ; Display battery and temp in modeline
-
(add-hook 'after-make-frame-functions 'fit-frame)
(add-hook 'temp-buffer-show-hook 'fit-frame-if-one-window 'append)
@@ -18,7 +16,7 @@
(setq-default fit-frame-empty-width 75)
(setq-default fit-frame-min-height 40)
(setq-default fit-frame-min-width 105)
-(setq-default fit-frame-max-height 100)
+(setq-default fit-frame-max-height 80)
(setq-default fit-frame-max-width 130)
(global-hl-line-mode t)
@@ -27,4 +25,5 @@
(mouse-avoidance-mode 'animate) ; Animate the mouse away from where we are typing
-(add-hook 'after-make-frame-functions 'color-theme-lite-brite)
+(add-hook 'after-make-frame-functions 'color-theme-scanner-brightly)
+
View
9 .gemrc
@@ -1,10 +1,11 @@
---
+:backtrace: false
+:benchmark: false
+:bulk_threshold: 1000
:sources:
+- http://gemcutter.org
- http://gems.rubyforge.org/
- http://gems.github.com
:update_sources: true
-:benchmark: false
-:bulk_threshold: 1000
-:backtrace: false
:verbose: true
-gem: --no-ri --no-rdoc
+gem: --no-ri --no-rdoc
View
14 .gitconfig
@@ -4,14 +4,18 @@
[github]
user = bkudria
+ token = 43cefc58c5ff6fdb90dffc731df10723
[core]
- editor = emacs-client-frame
+ editor = nano
pager = less
# change to tig when color.pager bug is fixed.
whitespace = trailing-space,space-before-tab,cr-at-eol
+[clean]
+ requireForce = false
+
[color]
diff = auto
status = auto
@@ -61,9 +65,15 @@
echo = "!echo $1; echo $1"
+ lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative
+
+ top = !eval cd "$(pwd)/$(git rev-parse --show-cdup)" && pwd
+
[gui]
- fontdiff = -family terminus -size 13 -weight normal -slant roman -underline 0 -overstrike 0
+ fontdiff = -family terminus -size 10 -weight normal -slant roman -underline 0 -overstrike 0
+ fontui = -family terminus -size 10 -weight bold -slant roman -underline 0 -overstrike 0
+ diffcontext = 3
[giggle]
compact-mode = true
main-window-maximized = true
View
231 .hgext/autopager.py
@@ -0,0 +1,231 @@
+"""pages output only if it exceeds the terminal's height
+
+On Unix, this extension uses ioctl(2) to determine the terminal's dimensions.
+On Windows, GetConsoleScreenBufferInfo is used. If neither is available or
+unable to determine the dimensions, the LINES and COLUMNS environment
+variables are used.
+
+Default settings:
+
+ [autopager]
+ ; Like in the pager extension, this helps alleviate broken pipes
+ quiet = False
+ ; The size of your shell prompt in lines
+ promptsize = 1
+ ; The pager to use
+ pager = [environment variable PAGER]
+
+If neither pager nor PAGER is set, the extension does nothing.
+
+Note: Output to stderr is sent to the pager as well. If the pager isn't
+invoked, it's preserved (instead of being sent to stdout).
+
+Paging for certain commands can be enabled or disabled:
+
+ [autopager]
+ ignore = version, help, update
+ ; or...
+ attend = log
+
+Tips for using this extension with less:
+
+* If you don't like how less clears the screen when you quit, try the
+ -X/--no-init switch. This could cause other issues depending on your
+ terminal emulator - or it could work fine.
+
+* If you're using another extension that colorizes a command's output, try
+ the -R/--RAW-CONTROL-CHARS switch. This will cause less to avoid escaping
+ color control codes.
+
+Debugging tips:
+
+* If you get an exception without the traceback, try setting the
+ DEBUGAUTOPAGER environment variable when running hg. The extension will
+ then wrap only stdout.
+"""
+
+import atexit
+import os
+import re
+import signal
+import sys
+import unicodedata
+
+from mercurial import dispatch, extensions, util
+
+def _ioctl_dimensions(fd):
+ from fcntl import ioctl
+ from struct import pack, unpack
+ from termios import TIOCGWINSZ
+ return unpack('HHHH', ioctl(fd, TIOCGWINSZ, pack('HHHH', 0, 0, 0, 0)))[:2]
+
+
+# TODO: Actually test this.
+def _win_dimensions(fd):
+ from ctypes import windll, create_string_buffer
+ handle = windll.kernel32.GetStdHandle(fd)
+ buf = create_string_buffer(22)
+ res = windll.kernel32.GetConsoleScreenBufferInfo(handle, buf)
+ if res:
+ from struct import unpack
+ left, top, right, bottom = unpack('hhhhHhhhhhh', buf.raw)[5:9]
+ return (bottom - top + 1, right - left + 1)
+
+
+def get_dimensions():
+ """Returns terminal height and width"""
+
+ height = width = 0
+ try:
+ height, width = _ioctl_dimensions(0)
+ if 0 in (height, width):
+ height, width = _ioctl_dimensions(1)
+ if 0 in (height, width):
+ height, width = _ioctl_dimensions(2)
+ except ImportError:
+ try:
+ height, width = _win_dimensions(0)
+ if 0 in (height, width):
+ height, width = _win_dimensions(1)
+ if 0 in (height, width):
+ height, width = _win_dimensions(2)
+ except ImportError:
+ pass
+ if not height:
+ try:
+ height = int(os.environ.get('LINES', 0))
+ except ValueError:
+ pass
+ if not width:
+ try:
+ width = int(os.environ.get('COLUMNS', 0))
+ except ValueError:
+ pass
+ return height, width
+
+
+def wrap_output(pager, height, width, wrap_stderr):
+ """Wraps stdout/stderr and sends output to pager if the number of lines
+ written exceeds the terminal dimensions, otherwise the buffer is flushed
+ with atexit.
+ """
+
+ buf = [[]]
+ line_count = [0]
+ col_count = [0]
+ popen = util.popen
+
+ def flush(exiting=False):
+ # This accounts for output that doesn't end with a newline whose last
+ # line is wider than the terminal width (which would increase the line
+ # count by one).
+ if (exiting and line_count[0] >= height and col_count[0] >= width
+ and buf[0]):
+ sys.stdout = popen(pager, 'wb')
+ if wrap_stderr:
+ sys.stderr = sys.stdout
+ if hasattr(sys.stdout, '_bypass'):
+ sys.stdout._bypass = True
+ if wrap_stderr:
+ sys.stderr._bypass = True
+ for is_stderr, s in buf[0]:
+ if is_stderr:
+ sys.stderr.write(s)
+ else:
+ sys.stdout.write(s)
+ buf[0] = []
+ atexit.register(flush, True)
+
+ # Flush the buffer and remove the output wrappers for interactive prompts.
+ # Note: This doesn't work if the pager is already launched.
+ def wrapper(orig, *args, **kwargs):
+ if sys.stdout != sys.__stdout__:
+ if getattr(sys.stdout, '_stream') != sys.__stdout__:
+ sys.stdout._stream.close()
+ sys.stdout = sys.__stdout__
+ sys.stderr = sys.__stderr__
+ flush()
+ return orig(*args, **kwargs)
+
+ import __builtin__
+ extensions.wrapfunction(__builtin__, 'input', wrapper)
+ extensions.wrapfunction(__builtin__, 'raw_input', wrapper)
+
+ import getpass
+ extensions.wrapfunction(getpass, 'getpass', wrapper)
+
+ from mercurial.ui import ui
+ extensions.wrapfunction(ui, 'prompt', wrapper)
+ extensions.wrapfunction(ui, 'getpass', wrapper)
+
+ # Flush the buffer/remove wrappers if a subprocess is opened
+ extensions.wrapfunction(util, 'system', wrapper)
+ extensions.wrapfunction(util, 'popen', wrapper)
+ extensions.wrapfunction(util, 'popen2', wrapper)
+ extensions.wrapfunction(util, 'popen3', wrapper)
+
+ sub_control_codes = re.compile(r'(?:[\x00-\x08]|\x1b\[[\d;]+m)').sub
+ class FileProxy(object):
+ def __init__(self, stream, is_stderr=False):
+ self._stream = stream
+ self._is_stderr = is_stderr
+ self._bypass = False
+ def __getattr__(self, name):
+ return getattr(self._stream, name)
+ def write(self, s):
+ if self._bypass:
+ return self._stream.write(s)
+ # The stream is recorded to preserve stdout/stderr if output
+ # isn't paged.
+ buf[0].append((self._is_stderr, s))
+ # Try to determine the width of the string as it would appear in
+ # the terminal.
+ try:
+ s = s.decode(util._encoding, util._encodingmode)
+ s = unicodedata.normalize('NFC', s)
+ except UnicodeError:
+ pass
+ for c in sub_control_codes('', s):
+ col_count[0] += 1
+ if c == '\n' or col_count[0] > width:
+ line_count[0] += 1
+ col_count[0] = 0
+ if line_count[0] > height:
+ sys.stdout._stream = popen(pager, 'wb')
+ if wrap_stderr:
+ sys.stderr._stream = sys.stdout._stream
+ flush()
+
+ sys.stdout = FileProxy(sys.stdout)
+ if wrap_stderr:
+ sys.stderr = FileProxy(sys.stderr, True)
+
+
+def _setup_pager(ui, pager):
+ if (pager and sys.stdout.isatty() and '--debugger' not in sys.argv
+ and ui.interactive):
+ height, width = get_dimensions()
+ if height > 0 and width > 0:
+ if ui.configbool('autopager', 'quiet'):
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+ promptsize = int(ui.config('autopager', 'promptsize', 1))
+ wrap_output(pager, height - promptsize, width,
+ 'DEBUGAUTOPAGER' not in os.environ)
+
+
+def uisetup(ui, *args, **kwargs):
+
+ pager = ui.config('autopager', 'pager', os.environ.get('PAGER'))
+ attend = ui.configlist('autopager', 'attend')
+ ignore = ui.configlist('autopager', 'ignore')
+ if attend or ignore:
+ def pagecmd(orig, ui, options, cmd, cmdfunc):
+ if (cmd in attend or (cmd not in ignore and not attend)):
+ _setup_pager(ui, pager)
+ return orig(ui, options, cmd, cmdfunc)
+ extensions.wrapfunction(dispatch, '_runcommand', pagecmd)
+ # If attend and ignore aren't present, this catches all output, not just
+ # those of named commands.
+ else:
+ _setup_pager(ui, pager)
+
View
BIN  .hgext/autopager.pyc
Binary file not shown
View
BIN  .hgext/crecord/.hg/00changelog.i
Binary file not shown
View
1  .hgext/crecord/.hg/branch
@@ -0,0 +1 @@
+default
View
2  .hgext/crecord/.hg/branch.cache
@@ -0,0 +1,2 @@
+3da2e3be73338035048a60d9f84f12e7c11f6899 43
+3da2e3be73338035048a60d9f84f12e7c11f6899 default
View
BIN  .hgext/crecord/.hg/dirstate
Binary file not shown
View
2  .hgext/crecord/.hg/hgrc
@@ -0,0 +1,2 @@
+[paths]
+default = http://bitbucket.org/edgimar/crecord/
View
3  .hgext/crecord/.hg/requires
@@ -0,0 +1,3 @@
+revlogv1
+store
+fncache
View
BIN  .hgext/crecord/.hg/store/00changelog.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/00manifest.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/data/crecord.py.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/data/crecord/____init____.py.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/data/crecord/chunk__selector.py.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/data/crecord/crecord__core.py.i
Binary file not shown
View
BIN  .hgext/crecord/.hg/store/data/crecord/crpatch.py.i
Binary file not shown
View
5 .hgext/crecord/.hg/store/fncache
@@ -0,0 +1,5 @@
+data/crecord.py.i
+data/crecord/__init__.py.i
+data/crecord/chunk_selector.py.i
+data/crecord/crecord_core.py.i
+data/crecord/crpatch.py.i
View
BIN  .hgext/crecord/.hg/store/undo
Binary file not shown
View
1  .hgext/crecord/.hg/undo.branch
@@ -0,0 +1 @@
+default
View
0  .hgext/crecord/.hg/undo.dirstate
No changes.
View
43 .hgext/crecord/crecord/__init__.py
@@ -0,0 +1,43 @@
+# crecord.py
+#
+# Copyright 2008 Mark Edgington <edgimar@gmail.com>
+#
+# This software may be used and distributed according to the terms of
+# the GNU General Public License, incorporated herein by reference.
+#
+# Much of this extension is based on Bryan O'Sullivan's record extension.
+
+'''text-gui based change selection during commit or qrefresh'''
+from mercurial.i18n import _
+from mercurial import commands, extensions
+
+from crecord_core import crecord, qcrecord
+
+cmdtable = {
+ "crecord":
+ (crecord,
+
+ # add commit options
+ commands.table['^commit|ci'][1],
+
+ _('hg crecord [OPTION]... [FILE]...')),
+}
+
+
+def extsetup():
+ try:
+ mq = extensions.find('mq')
+ except KeyError:
+ return
+
+ qcmdtable = {
+ "qcrecord":
+ (qcrecord,
+
+ # add qnew options, except '--force'
+ [opt for opt in mq.cmdtable['qnew'][1] if opt[1] != 'force'],
+
+ _('hg qcrecord [OPTION]... PATCH [FILE]...')),
+ }
+
+ cmdtable.update(qcmdtable)
View
BIN  .hgext/crecord/crecord/__init__.pyc
Binary file not shown
View
934 .hgext/crecord/crecord/chunk_selector.py
@@ -0,0 +1,934 @@
+from mercurial.i18n import gettext, _
+from mercurial import cmdutil, commands, extensions, hg, mdiff
+from mercurial import util, encoding
+import copy, cStringIO, errno, operator, os, re, tempfile
+
+
+import signal
+import locale
+from crpatch import Patch, header, hunk, HunkLine
+
+# os.name is one of: 'posix', 'nt', 'dos', 'os2', 'mac', or 'ce'
+if os.name == 'posix':
+ import curses
+else:
+ # I have no idea if wcurses works with crecord...
+ import wcurses as curses
+
+import curses.textpad
+
+try:
+ curses
+except NameError:
+ raise util.Abort(_('the python curses/wcurses module is not available/installed'))
+
+
+# deal with unicode correctly
+locale.setlocale(locale.LC_ALL, '')
+
+def chunkselector(opts, headerList):
+ """
+ Curses interface to get selection of chunks, and mark the applied flags
+ of the chosen chunks.
+
+ """
+ stdscr = curses.initscr()
+ curses.start_color()
+
+ chunkSelector = CursesChunkSelector(headerList)
+ curses.wrapper(chunkSelector.main, opts)
+
+class CursesChunkSelector(object):
+ def __init__(self, headerList):
+ # put the headers into a patch object
+ self.headerList = Patch(headerList)
+
+ # list of all chunks
+ self.chunkList = []
+ for h in headerList:
+ self.chunkList.append(h)
+ self.chunkList.extend(h.hunks)
+
+ # dictionary mapping (fgColor,bgColor) pairs to the corresponding curses
+ # color-pair value.
+ self.colorPairs = {}
+ # maps custom nicknames of color-pairs to curses color-pair values
+ self.colorPairNames = {}
+
+ # the currently selected header, hunk, or hunk-line
+ self.currentSelectedItem = self.headerList[0]
+
+ # updated when printing out patch-display -- the 'lines' here are the
+ # line positions *in the pad*, not on the screen.
+ self.selectedItemStartLine = 0
+ self.selectedItemEndLine = None
+
+ # define indentation levels
+ self.headerIndentNumChars = 0
+ self.hunkIndentNumChars = 3
+ self.hunkLineIndentNumChars = 6
+
+ # the first line of the pad to print to the screen
+ self.firstLineOfPadToPrint = 0
+
+ # keeps track of the number of lines in the pad
+ self.numPadLines = None
+
+ self.numStatusLines = 2
+
+ # keep a running count of the number of lines printed to the pad
+ # (used for determining when the selected item begins/ends)
+ self.linesPrintedToPadSoFar = 0
+
+ # the first line of the pad which is visible on the screen
+ self.firstLineOfPadToPrint = 0
+
+ # stores optional text for a commit comment provided by the user
+ self.commentText = ""
+
+ def upArrowEvent(self):
+ """
+ Try to select the previous item to the current item that has the
+ most-indented level. For example, if a hunk is selected, try to select
+ the last HunkLine of the hunk prior to the selected hunk. Or, if
+ the first HunkLine of a hunk is currently selected, then select the
+ hunk itself.
+
+ If the currently selected item is already at the top of the screen,
+ scroll the screen down to show the new-selected item.
+
+ """
+ currentItem = self.currentSelectedItem
+
+ nextItem = currentItem.prevItem(constrainLevel=False)
+
+ if nextItem is None:
+ # if no parent item (i.e. currentItem is the first header), then
+ # no change...
+ nextItem = currentItem
+
+ self.currentSelectedItem = nextItem
+
+ def upArrowShiftEvent(self):
+ """
+ Select (if possible) the previous item on the same level as the currently
+ selected item. Otherwise, select (if possible) the parent-item of the
+ currently selected item.
+
+ If the currently selected item is already at the top of the screen,
+ scroll the screen down to show the new-selected item.
+
+ """
+ currentItem = self.currentSelectedItem
+ nextItem = currentItem.prevItem()
+ # if there's no previous item on this level, try choosing the parent
+ if nextItem is None:
+ nextItem = currentItem.parentItem()
+ if nextItem is None:
+ # if no parent item (i.e. currentItem is the first header), then
+ # no change...
+ nextItem = currentItem
+
+ self.currentSelectedItem = nextItem
+
+ def downArrowEvent(self):
+ """
+ Try to select the next item to the current item that has the
+ most-indented level. For example, if a hunk is selected, select
+ the first HunkLine of the selected hunk. Or, if the last HunkLine of
+ a hunk is currently selected, then select the next hunk, if one exists,
+ or if not, the next header if one exists.
+
+ If the currently selected item is already at the bottom of the screen,
+ scroll the screen up to show the new-selected item.
+
+ """
+ #self.startPrintLine += 1 #DEBUG
+ currentItem = self.currentSelectedItem
+
+ nextItem = currentItem.nextItem(constrainLevel=False)
+ # if there's no next item, keep the selection as-is
+ if nextItem is None:
+ nextItem = currentItem
+
+ self.currentSelectedItem = nextItem
+
+ def downArrowShiftEvent(self):
+ """
+ If the cursor is already at the bottom chunk, scroll the screen up and move the cursor-position
+ to the subsequent chunk. Otherwise, only move the cursor position down one chunk.
+
+ """
+ # TODO: update docstring
+
+ currentItem = self.currentSelectedItem
+ nextItem = currentItem.nextItem()
+ # if there's no previous item on this level, try choosing the parent's
+ # nextItem.
+ if nextItem is None:
+ try:
+ nextItem = currentItem.parentItem().nextItem()
+ except AttributeError:
+ # parentItem returned None, so nextItem() can't be called
+ nextItem = None
+ if nextItem is None:
+ # if no next item on parent-level, then no change...
+ nextItem = currentItem
+
+ self.currentSelectedItem = nextItem
+
+ def rightArrowEvent(self):
+ """
+ Select (if possible) the first of this item's child-items.
+
+ """
+ currentItem = self.currentSelectedItem
+ nextItem = currentItem.firstChild()
+
+ # turn off folding if we want to show a child-item
+ if currentItem.folded:
+ self.toggleFolded(currentItem)
+
+ if nextItem is None:
+ # if no next item on parent-level, then no change...
+ nextItem = currentItem
+
+ self.currentSelectedItem = nextItem
+
+ def leftArrowEvent(self):
+ """
+ If the current item can be folded (i.e. it is an unfolded header or
+ hunk), then fold it. Otherwise try select (if possible) the parent
+ of this item.
+
+ """
+ currentItem = self.currentSelectedItem
+
+ # try to fold the item
+ if not isinstance(currentItem, HunkLine):
+ if not currentItem.folded:
+ self.toggleFolded(item=currentItem)
+ return
+
+ # if it can't be folded, try to select the parent item
+ nextItem = currentItem.parentItem()
+
+ if nextItem is None:
+ # if no item on parent-level, then no change...
+ nextItem = currentItem
+ if not nextItem.folded:
+ self.toggleFolded(item=nextItem)
+
+ self.currentSelectedItem = nextItem
+
+ def updateScroll(self):
+ "Scroll the screen in such a way to fully show the currently-selected item."
+ selStart = self.selectedItemStartLine
+ selEnd = self.selectedItemEndLine
+ #selNumLines = selEnd - selStart
+ padStart = self.firstLineOfPadToPrint
+ padEnd = padStart + self.yScreenSize - self.numStatusLines - 1
+ screenMiddleLine = self.yScreenSize / 2
+ # 'buffered' pad start/end values which scroll with a certain
+ # top/bottom context margin
+ padStartBuffered = padStart + 3
+ padEndBuffered = padEnd - 3
+
+ if selEnd > padEndBuffered:
+ self.scrollLines(selEnd - padEndBuffered)
+ elif selStart < padStartBuffered:
+ # negative values scroll in pgup direction
+ self.scrollLines(selStart - padStartBuffered)
+
+
+ def scrollLines(self, numLines):
+ "Scroll the screen up (down) by numLines when numLines >0 (<0)."
+ self.firstLineOfPadToPrint += numLines
+ if self.firstLineOfPadToPrint < 0:
+ self.firstLineOfPadToPrint = 0
+ if self.firstLineOfPadToPrint > self.numPadLines-1:
+ self.firstLineOfPadToPrint = self.numPadLines-1
+
+ def toggleApply(self, item=None):
+ """
+ Toggle the applied flag of the specified item. If no item is specified,
+ toggle the flag of the currently selected item.
+
+ """
+ if item is None:
+ item = self.currentSelectedItem
+
+ item.applied = not item.applied
+
+ if isinstance(item, header):
+ item.partial = False
+ if item.applied:
+ if not item.special():
+ # apply all its hunks
+ for hnk in item.hunks:
+ hnk.applied = True
+ # apply all their HunkLines
+ for hunkLine in hnk.changedLines:
+ hunkLine.applied = True
+ else:
+ # all children are off (but the header is on)
+ if len(item.allChildren()) > 0:
+ item.partial = True
+ else:
+ # un-apply all its hunks
+ for hnk in item.hunks:
+ hnk.applied = False
+ # un-apply all their HunkLines
+ for hunkLine in hnk.changedLines:
+ hunkLine.applied = False
+ elif isinstance(item, hunk):
+ item.partial = False
+ # apply all it's HunkLines
+ for hunkLine in item.changedLines:
+ hunkLine.applied = item.applied
+
+ siblingAppliedStatus = [hnk.applied for hnk in item.header.hunks]
+ allSiblingsApplied = not (False in siblingAppliedStatus)
+ noSiblingsApplied = not (True in siblingAppliedStatus)
+
+ siblingsPartialStatus = [hnk.partial for hnk in item.header.hunks]
+ someSiblingsPartial = (True in siblingsPartialStatus)
+
+ #cases where applied or partial should be removed from header
+
+ # if no 'sibling' hunks are applied (including this hunk)
+ if noSiblingsApplied:
+ if not item.header.special():
+ item.header.applied = False
+ item.header.partial = False
+ else: # some/all parent siblings are applied
+ item.header.applied = True
+ item.header.partial = (someSiblingsPartial or \
+ not allSiblingsApplied)
+
+ elif isinstance(item, HunkLine):
+ siblingAppliedStatus = [hnkln.applied for hnkln in item.hunk.changedLines]
+ allSiblingsApplied = not (False in siblingAppliedStatus)
+ noSiblingsApplied = not (True in siblingAppliedStatus)
+
+ # if no 'sibling' lines are applied
+ if noSiblingsApplied:
+ item.hunk.applied = False
+ item.hunk.partial = False
+ elif allSiblingsApplied:
+ item.hunk.applied = True
+ item.hunk.partial = False
+ else: # some siblings applied
+ item.hunk.applied = True
+ item.hunk.partial = True
+
+ parentSiblingsAppliedStatus = [hnk.applied for hnk in item.hunk.header.hunks]
+ noParentSiblingsApplied = not (True in parentSiblingsAppliedStatus)
+ allParentSiblingsApplied = not (False in parentSiblingsAppliedStatus)
+
+ parentSiblingsPartialStatus = [hnk.partial for hnk in item.hunk.header.hunks]
+ someParentSiblingsPartial = (True in parentSiblingsPartialStatus)
+
+ # if all parent hunks are not applied, un-apply header
+ if noParentSiblingsApplied:
+ if not item.hunk.header.special():
+ item.hunk.header.applied = False
+ item.hunk.header.partial = False
+ # set the applied and partial status of the header if needed
+ else: # some/all parent siblings are applied
+ item.hunk.header.applied = True
+ item.hunk.header.partial = (someParentSiblingsPartial or \
+ not allParentSiblingsApplied)
+ def toggleFolded(self, item=None, foldParent=False):
+ "Toggle folded flag of specified item (defaults to currently selected)"
+ if item is None:
+ item = self.currentSelectedItem
+ if foldParent or (isinstance(item, header) and item.neverUnfolded):
+ if not isinstance(item, header):
+ # we need to select the parent item in this case
+ self.currentSelectedItem = item = item.parentItem()
+ elif item.neverUnfolded:
+ item.neverUnfolded = False
+
+ # also fold any foldable children of the parent/current item
+ if isinstance(item, header): # the original OR 'new' item
+ for child in item.allChildren():
+ child.folded = not item.folded
+
+ if isinstance(item, (header, hunk)):
+ item.folded = not item.folded
+
+
+ def alignString(self, inStr, window):
+ """
+ Add whitespace to the end of a string in order to make it fill
+ the screen in the x direction. The current cursor position is
+ taken into account when making this calculation. The string can span
+ multiple lines.
+
+ """
+ y,xStart = window.getyx()
+ width = self.xScreenSize
+ # turn tabs into spaces
+ inStr = inStr.expandtabs(4)
+ strLen = len(unicode(encoding.fromlocal(inStr), 'utf-8'))
+ numSpaces = (width - ((strLen + xStart) % width) - 1)
+ return inStr + " " * numSpaces + "\n"
+
+ def printString(self, window, text, fgColor=None, bgColor=None, pair=None,
+ pairName=None, attrList=None, toWin=True, align=True, showWhtSpc=False):
+ """
+ Print the string, text, with the specified colors and attributes, to
+ the specified curses window object.
+
+ The foreground and background colors are of the form
+ curses.COLOR_XXXX, where XXXX is one of: [BLACK, BLUE, CYAN, GREEN,
+ MAGENTA, RED, WHITE, YELLOW]. If pairName is provided, a color
+ pair will be looked up in the self.colorPairNames dictionary.
+
+ attrList is a list containing text attributes in the form of
+ curses.A_XXXX, where XXXX can be: [BOLD, DIM, NORMAL, STANDOUT,
+ UNDERLINE].
+
+ If align == True, whitespace is added to the printed string such that
+ the string stretches to the right border of the window.
+
+ If showWhtSpc == True, trailing whitespace of a string is highlighted.
+
+ """
+ # preprocess the text, converting tabs to spaces
+ text = text.expandtabs(4)
+
+ if pair is not None:
+ colorPair = pair
+ elif pairName is not None:
+ colorPair = self.colorPairNames[pairName]
+ else:
+ if fgColor is None:
+ fgColor = curses.COLOR_WHITE
+ if bgColor is None:
+ bgColor = curses.COLOR_BLACK
+ if self.colorPairs.has_key((fgColor,bgColor)):
+ colorPair = self.colorPairs[(fgColor,bgColor)]
+ else:
+ colorPair = self.getColorPair(fgColor, bgColor)
+ # add attributes if possible
+ if attrList is None:
+ attrList = []
+ if colorPair < 256:
+ # then it is safe to apply all attributes
+ for textAttr in attrList:
+ colorPair |= textAttr
+ else:
+ # just apply a select few (safe?) attributes
+ for textAttr in (curses.A_UNDERLINE, curses.A_BOLD):
+ if textAttr in attrList:
+ colorPair |= textAttr
+
+ y,xStart = self.chunkpad.getyx()
+ t = "" # variable for counting lines printed
+ # if requested, show trailing whitespace
+ if showWhtSpc:
+ origLen = len(text)
+ text = text.rstrip(' \n') # tabs have already been expanded
+ strippedLen = len(text)
+ numTrailingSpaces = origLen - strippedLen
+
+ if toWin:
+ window.addstr(text, colorPair)
+ t += text
+
+ if showWhtSpc:
+ wsColorPair = colorPair | curses.A_REVERSE
+ if toWin:
+ for i in range(numTrailingSpaces):
+ window.addch(curses.ACS_CKBOARD, wsColorPair)
+ t += " " * numTrailingSpaces
+
+ if align:
+ if toWin:
+ extraWhiteSpace = self.alignString("", window)
+ window.addstr(extraWhiteSpace, colorPair)
+ else:
+ # need to use t, since the x position hasn't incremented
+ extraWhiteSpace = self.alignString(t, window)
+ t += extraWhiteSpace
+
+ # is reset to 0 at the beginning of printItem()
+
+ linesPrinted = (xStart + len(t)) / self.xScreenSize
+ self.linesPrintedToPadSoFar += linesPrinted
+ return t
+
+ def updateScreen(self):
+ self.statuswin.erase()
+ self.chunkpad.erase()
+
+ width = self.xScreenSize
+ alignString = self.alignString
+ printString = self.printString
+
+ # print out the status lines at the top
+ try:
+ printString(self.statuswin, "SELECT CHUNKS: (j/k/up/down/pgup/pgdn) move cursor; (space) toggle applied", pairName="legend")
+ printString(self.statuswin, " (f)old/unfold; (c)ommit applied; (q)uit; (?) help | [X]=hunk applied **=folded", pairName="legend")
+ except curses.error:
+ pass
+
+ # print out the patch in the remaining part of the window
+ try:
+ self.printItem()
+ self.updateScroll()
+ self.chunkpad.refresh(self.firstLineOfPadToPrint,0,self.numStatusLines,0,self.yScreenSize+1-self.numStatusLines,self.xScreenSize)
+ except curses.error:
+ pass
+
+ # refresh([pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol])
+ self.statuswin.refresh()
+
+ def getStatusPrefixString(self, item):
+ """
+ Create a string to prefix a line with which indicates whether 'item'
+ is applied and/or folded.
+
+ """
+ # create checkBox string
+ if item.applied:
+ if not isinstance(item, HunkLine) and item.partial:
+ checkBox = "[~]"
+ else:
+ checkBox = "[X]"
+ else:
+ checkBox = "[ ]"
+
+ try:
+ if item.folded:
+ checkBox += "**"
+ if isinstance(item, header):
+ # one of "M", "A", or "D" (modified, added, deleted)
+ fileStatus = item.changetype
+
+ checkBox += fileStatus + " "
+ else:
+ checkBox += " "
+ if isinstance(item, header):
+ # add two more spaces for headers
+ checkBox += " "
+ except AttributeError: # not foldable
+ checkBox += " "
+
+ return checkBox
+
+ def printHeader(self, header, selected=False, toWin=True, ignoreFolding=False):
+ """
+ Print the header to the pad. If countLines is True, don't print
+ anything, but just count the number of lines which would be printed.
+
+ """
+ outStr = ""
+ text = header.prettyStr()
+ chunkIndex = self.chunkList.index(header)
+
+ if chunkIndex != 0 and not header.folded:
+ # add separating line before headers
+ outStr += self.printString(self.chunkpad, '_'*self.xScreenSize, toWin=toWin, align=False)
+ # select color-pair based on if the header is selected
+ if selected:
+ colorPair = self.getColorPair(name="selected", attrList=[curses.A_BOLD])
+ else:
+ colorPair = self.getColorPair(name="normal", attrList=[curses.A_BOLD])
+
+ # print out each line of the chunk, expanding it to screen width
+
+ # number of characters to indent lines on this level by
+ indentNumChars = 0
+ checkBox = self.getStatusPrefixString(header)
+ if not header.folded or ignoreFolding:
+ textList = text.split("\n")
+ lineStr = checkBox + textList[0]
+ else:
+ lineStr = checkBox + header.filename()
+ outStr += self.printString(self.chunkpad, lineStr, pair=colorPair, toWin=toWin)
+ if not header.folded or ignoreFolding:
+ if len(textList) > 1:
+ for line in textList[1:]:
+ lineStr = " "*(indentNumChars + len(checkBox)) + line
+ outStr += self.printString(self.chunkpad, lineStr, pair=colorPair, toWin=toWin)
+
+ return outStr
+
+ def printHunkLinesBefore(self, hunk, selected=False, toWin=True, ignoreFolding=False):
+ "includes start/end line indicator"
+ outStr = ""
+ # where hunk is in list of siblings
+ hunkIndex = hunk.header.hunks.index(hunk)
+
+ if hunkIndex != 0:
+ # add separating line before headers
+ outStr += self.printString(self.chunkpad, ' '*self.xScreenSize, toWin=toWin, align=False)
+
+ if selected:
+ colorPair = self.getColorPair(name="selected", attrList=[curses.A_BOLD])
+ else:
+ colorPair = self.getColorPair(name="normal", attrList=[curses.A_BOLD])
+
+ # print out from-to line with checkbox
+ checkBox = self.getStatusPrefixString(hunk)
+
+ linePrefix = " "*self.hunkIndentNumChars + checkBox
+ frToLine = " " + hunk.getFromToLine().strip("\n")
+
+
+ outStr += self.printString(self.chunkpad, linePrefix, toWin=toWin, align=False) # add uncolored checkbox/indent
+ outStr += self.printString(self.chunkpad, frToLine, pair=colorPair, toWin=toWin)
+
+ if hunk.folded and not ignoreFolding:
+ # skip remainder of output
+ return outStr
+
+ # print out lines of the chunk preceeding changed-lines
+ for line in hunk.before:
+ lineStr = " "*(self.hunkLineIndentNumChars + len(checkBox)) + line.strip("\n")
+ outStr += self.printString(self.chunkpad, lineStr, toWin=toWin)
+
+ return outStr
+
+ def printHunkLinesAfter(self, hunk, toWin=True, ignoreFolding=False):
+ outStr = ""
+ if hunk.folded and not ignoreFolding:
+ return outStr
+
+ indentNumChars = self.hunkLineIndentNumChars-1
+ # a bit superfluous, but to avoid hard-coding indent amount
+ checkBox = self.getStatusPrefixString(hunk)
+ for line in hunk.after:
+ lineStr = " "*(indentNumChars + len(checkBox)) + line.strip("\n")
+ outStr += self.printString(self.chunkpad, lineStr, toWin=toWin)
+
+ return outStr
+
+ def printHunkChangedLine(self, hunkLine, selected=False, toWin=True):
+ outStr = ""
+ indentNumChars = self.hunkLineIndentNumChars
+ checkBox = self.getStatusPrefixString(hunkLine)
+
+ lineStr = hunkLine.prettyStr().strip("\n")
+
+ # select color-pair based on whether line is an addition/removal
+ if selected:
+ colorPair = self.getColorPair(name="selected")
+ elif lineStr.startswith("+"):
+ colorPair = self.getColorPair(name="addition")
+ elif lineStr.startswith("-"):
+ colorPair = self.getColorPair(name="deletion")
+ elif lineStr.startswith("\\"):
+ colorPair = self.getColorPair(name="normal")
+
+ linePrefix = " "*indentNumChars + checkBox
+ outStr += self.printString(self.chunkpad, linePrefix, toWin=toWin, align=False) # add uncolored checkbox/indent
+ outStr += self.printString(self.chunkpad, lineStr, pair=colorPair, toWin=toWin, showWhtSpc=True)
+ return outStr
+
+ def printItem(self, item=None, ignoreFolding=False, recurseChildren=True, toWin=True):
+ """
+ Use __printItem() to print the the specified item.applied.
+ If item is not specified, then print the entire patch.
+ (hiding folded elements, etc. -- see __printitem() docstring)
+ """
+ if item is None:
+ item = self.headerList
+ if recurseChildren:
+ self.linesPrintedToPadSoFar = 0
+ global outStr
+ retStr = self.__printItem(item, ignoreFolding, recurseChildren, toWin=toWin)
+ if recurseChildren:
+ # remove the string when finished, so it doesn't accumulate
+ del outStr
+
+ return retStr
+
+ def __printItem(self, item, ignoreFolding, recurseChildren, toWin=True):
+ """
+ Recursive method for printing out patch/header/hunk/hunk-line data to
+ screen. Also returns a string with all of the content of the displayed
+ patch (not including coloring, etc.).
+
+ If ignoreFolding is True, then folded items are printed out.
+
+ If recurseChildren is False, then only print the item without its
+ child items.
+
+ """
+ # keep outStr local, since we're not recursing
+ if recurseChildren:
+ global outStr
+ try:
+ outStr
+ except:
+ outStr = ""
+ else:
+ outStr = ""
+
+ selected = (item is self.currentSelectedItem)
+ if selected and recurseChildren:
+ # assumes line numbering starting from line 0
+ self.selectedItemStartLine = self.linesPrintedToPadSoFar
+ selectedItemLines = self.getNumLinesDisplayed(item, recurseChildren=False)
+ self.selectedItemEndLine = self.selectedItemStartLine + selectedItemLines - 1
+
+ # Patch object is a list of headers
+ if isinstance(item, Patch):
+ if recurseChildren:
+ for hdr in item:
+ self.__printItem(hdr, ignoreFolding, recurseChildren, toWin)
+ # TODO: eliminate all isinstance() calls
+ if isinstance(item, header):
+ outStr += self.printHeader(item, selected, toWin=toWin, ignoreFolding=ignoreFolding)
+ if recurseChildren:
+ for hnk in item.hunks:
+ self.__printItem(hnk, ignoreFolding, recurseChildren, toWin)
+ elif isinstance(item, hunk) and \
+ ((not item.header.folded) or ignoreFolding):
+ # print the hunk data which comes before the changed-lines
+ outStr += self.printHunkLinesBefore(item, selected, toWin=toWin, ignoreFolding=ignoreFolding)
+ if recurseChildren:
+ for line in item.changedLines:
+ self.__printItem(line, ignoreFolding, recurseChildren, toWin)
+ outStr += self.printHunkLinesAfter(item, toWin=toWin, ignoreFolding=ignoreFolding)
+ elif isinstance(item, HunkLine) and ((not item.hunk.folded) or ignoreFolding):
+ outStr += self.printHunkChangedLine(item, selected, toWin=toWin)
+
+ return outStr
+
+ def getNumLinesDisplayed(self, item=None, ignoreFolding=False, recurseChildren=True):
+ """
+ Return the number of lines which would be displayed if the item were
+ to be printed to the display. The item will NOT be printed to the
+ display (pad).
+ If no item is given, assume the entire patch.
+ If ignoreFolding is True, folded items will be unfolded when counting
+ the number of lines.
+
+ """
+ # temporarily disable printing to windows by printString
+ patchDisplayString = self.printItem(item, ignoreFolding, recurseChildren, toWin=False)
+ numLines = len(patchDisplayString)/self.xScreenSize
+ return numLines
+
+ def sigwinchHandler(self, n, frame):
+ "Handle window resizing"
+ try:
+ curses.endwin()
+ self.stdscr = curses.initscr()
+ self.yScreenSize, self.xScreenSize = self.stdscr.getmaxyx()
+
+ self.statuswin = curses.newwin(self.numStatusLines,self.xScreenSize,0,0)
+ except curses.error:
+ pass
+ # TODO: make resizing to a smaller width work (also for help screen)
+ # re-calculate an upper-bound on the number of lines in the pad
+ #self.numPadLines = self.getNumLinesDisplayed()
+ #self.chunkpad = curses.newpad(self.numPadLines, self.xScreenSize)
+ #self.updateScreen()
+
+ def getColorPair(self, fgColor=None, bgColor=None, name=None, attrList=None):
+ """
+ Get a curses color pair, adding it to self.colorPairs if it is not already
+ defined. An optional string, name, can be passed as a shortcut for
+ referring to the color-pair. By default, if no arguments are specified,
+ the white foreground / black background color-pair is returned.
+
+ It is expected that this function will be used exclusively for initializing
+ color pairs, and NOT curses.init_pair().
+
+ attrList is used to 'flavor' the returned color-pair. This information
+ is not stored in self.colorPairs. It contains attribute values like
+ curses.A_BOLD.
+
+ """
+ if (name is not None) and self.colorPairNames.has_key(name):
+ # then get the associated color pair and return it
+ colorPair = self.colorPairNames[name]
+ else:
+ if fgColor is None:
+ fgColor = curses.COLOR_WHITE
+ if bgColor is None:
+ bgColor = curses.COLOR_BLACK
+ if self.colorPairs.has_key((fgColor,bgColor)):
+ colorPair = self.colorPairs[(fgColor,bgColor)]
+ else:
+ pairIndex = len(self.colorPairs) + 1
+ curses.init_pair(pairIndex, fgColor, bgColor)
+ colorPair = self.colorPairs[(fgColor, bgColor)] = curses.color_pair(pairIndex)
+ if name is not None:
+ self.colorPairNames[name] = curses.color_pair(pairIndex)
+
+ # add attributes if possible
+ if attrList is None:
+ attrList = []
+ if colorPair < 256:
+ # then it is safe to apply all attributes
+ for textAttr in attrList:
+ colorPair |= textAttr
+ else:
+ # just apply a select few (safe?) attributes
+ for textAttrib in (curses.A_UNDERLINE, curses.A_BOLD):
+ if textAttrib in attrList:
+ colorPair |= textAttrib
+ return colorPair
+
+ def initColorPair(self, *args, **kwargs):
+ "Same as getColorPair."
+ self.getColorPair(*args, **kwargs)
+
+ def helpWindow(self):
+ "Print a help window to the screen. Exit after any keypress."
+ helpText = """ [press any key to return to the patch-display]
+
+crecord allows you to interactively choose among the changes you have made,
+and commit only those changes you select. After committing the selected
+changes, the unselected changes are still present in your working copy, so you
+can use crecord multiple times to split large changes into smaller changesets.
+The following are valid keystrokes:
+
+ [SPACE] : (un-)select item ([~]/[X] = partly/fully applied)
+ Up/Down-arrow [k/j] : go to previous/next unfolded item
+ PgUp/PgDn [K/J] : go to previous/next item of same type
+ Right/Left-arrow [l/h] : go to child item / parent item
+ f : fold / unfold item, hiding/revealing its children
+ F : fold / unfold parent item and all of its ancestors
+ m : edit / resume editing the commit message
+ c : commit selected changes
+ q : quit without committing (no changes will be made)
+ ? : help (what you're currently reading)"""
+
+ helpwin = curses.newwin(self.yScreenSize,0,0,0)
+ helpLines = helpText.split("\n")
+ helpLines = helpLines + [" "]*(self.yScreenSize-self.numStatusLines-len(helpLines)-1)
+ try:
+ for line in helpLines:
+ self.printString(helpwin, line, pairName="legend")
+ except curses.error:
+ pass
+ helpwin.refresh()
+ self.stdscr.getch()
+
+ def commitMessageWindow(self):
+ "Create a temporary commit message editing window on the screen."
+ # In Python versions < 2.6, there is no insert mode (only overwrite) :(
+ def keyFilter(key):
+ "provide keymappings to emacs-style keys"
+ if key in (7,):
+ # diable keys we're re-mapping
+ return ""
+ elif key in (24, 3): # CTRL-X, 3 = CTRL-C
+ return 7 # CTRL-G (i.e. exit comment window)
+ else:
+ return key
+ statusline = curses.newwin(2,0,0,0)
+ statusLineText = \
+ " Begin/resume editing commit message. CTRL-C/-X returns to patch view."
+ self.printString(statusline, statusLineText, pairName="legend")
+ statusline.refresh()
+ helpwin = curses.newwin(self.yScreenSize-1,0,1,0)
+ reversedCommentText = self.commentText[::-1]
+ for char in reversedCommentText:
+ curses.ungetch(ord(char))
+ t = curses.textpad.Textbox(helpwin)
+ curses.raw()
+ self.commentText = t.edit(keyFilter).rstrip(" \n")
+ curses.cbreak()
+
+ def confirmCommit(self):
+ "Ask for 'Y' to be pressed to confirm commit. Return True if confirmed."
+ confirmText = "Are you sure you want to commit the selected changes [yN]? "
+
+ confirmWin = curses.newwin(self.yScreenSize,0,0,0)
+ try:
+ self.printString(confirmWin, confirmText, pairName="selected")
+ except curses.error:
+ pass
+ confirmWin.refresh()
+ try:
+ response = chr(self.stdscr.getch())
+ except ValueError:
+ response = "n"
+ if response.lower().startswith("y"):
+ return True
+ else:
+ return False
+
+ def main(self, stdscr, opts):
+ """
+ Method to be wrapped by curses.wrapper() for selecting chunks.
+
+ """
+ signal.signal(signal.SIGWINCH, self.sigwinchHandler)
+ self.stdscr = stdscr
+ self.yScreenSize, self.xScreenSize = self.stdscr.getmaxyx()
+
+ # available colors: black, blue, cyan, green, magenta, white, yellow
+ # init_pair(color_id, foreground_color, background_color)
+ self.initColorPair(curses.COLOR_WHITE, curses.COLOR_BLACK, name="normal")
+ self.initColorPair(curses.COLOR_WHITE, curses.COLOR_RED, name="selected")
+ self.initColorPair(curses.COLOR_RED, curses.COLOR_BLACK, name="deletion")
+ self.initColorPair(curses.COLOR_GREEN, curses.COLOR_BLACK, name="addition")
+ self.initColorPair(curses.COLOR_WHITE, curses.COLOR_BLUE, name="legend")
+ # newwin([height, width,] begin_y, begin_x)
+ self.statuswin = curses.newwin(self.numStatusLines,0,0,0)
+
+ # figure out how much space to allocate for the chunk-pad which is
+ # used for displaying the patch
+
+ # stupid hack to prevent getNumLinesDisplayed from failing
+ self.chunkpad = curses.newpad(1,self.xScreenSize)
+
+ # add 1 so to account for last line text reaching end of line
+ self.numPadLines = self.getNumLinesDisplayed(ignoreFolding=True) + 1
+ self.chunkpad = curses.newpad(self.numPadLines, self.xScreenSize)
+
+ # initialize selecteItemEndLine (initial start-line is 0)
+ self.selectedItemEndLine = self.getNumLinesDisplayed(self.currentSelectedItem, recurseChildren=False)
+
+ try:
+ self.commentText = opts['message']
+ except KeyError:
+ pass
+
+
+ #import rpdb2; rpdb2.start_embedded_debugger("secret")
+ #import rpdb2; rpdb2.setbreak()
+
+ while True:
+ self.updateScreen()
+ self.lastKeyPressed = keyPressed = stdscr.getch()
+ if keyPressed in [ord("k"), curses.KEY_UP]:
+ self.upArrowEvent()
+ if keyPressed in [ord("K"), curses.KEY_PPAGE]:
+ self.upArrowShiftEvent()
+ elif keyPressed in [ord("j"), curses.KEY_DOWN]:
+ self.downArrowEvent()
+ elif keyPressed in [ord("J"), curses.KEY_NPAGE]:
+ self.downArrowShiftEvent()
+ elif keyPressed in [ord("l"), curses.KEY_RIGHT]:
+ self.rightArrowEvent()
+ elif keyPressed in [ord("h"), curses.KEY_LEFT]:
+ self.leftArrowEvent()
+ elif keyPressed in [ord("q")]:
+ raise util.Abort(_('user quit'))
+ elif keyPressed in [ord("c")]:
+ if self.confirmCommit():
+ break
+ elif keyPressed in [ord(' ')]:
+ self.toggleApply()
+ elif keyPressed in [ord("f")]:
+ self.toggleFolded()
+ elif keyPressed in [ord("F")]:
+ self.toggleFolded(foldParent=True)
+ elif keyPressed in [ord("?")]:
+ self.helpWindow()
+ elif keyPressed in [ord("m")]:
+ self.commitMessageWindow()
+
+ if self.commentText != "":
+ opts['message'] = self.commentText
View
BIN  .hgext/crecord/crecord/chunk_selector.pyc
Binary file not shown
View
180 .hgext/crecord/crecord/crecord_core.py
@@ -0,0 +1,180 @@
+# crecord.py
+#
+# Copyright 2008 Mark Edgington <edgimar@gmail.com>
+#
+# This software may be used and distributed according to the terms of
+# the GNU General Public License, incorporated herein by reference.
+#
+# Much of this extension is based on Bryan O'Sullivan's record extension.
+
+'''text-gui based change selection during commit or qrefresh'''
+from mercurial.i18n import _
+from mercurial import cmdutil, commands, extensions, hg, mdiff, patch
+from mercurial import util
+import cStringIO, errno, os, re, tempfile
+
+from crpatch import parsepatch, filterpatch
+from chunk_selector import chunkselector
+
+def dorecord(ui, repo, committer, *pats, **opts):
+ if not ui.interactive:
+ raise util.Abort(_('running non-interactively, use commit instead'))
+
+ def recordfunc(ui, repo, message, match, opts):
+ """This is generic record driver.
+
+ It's job is to interactively filter local changes, and accordingly
+ prepare working dir into a state, where the job can be delegated to
+ non-interactive commit command such as 'commit' or 'qrefresh'.
+
+ After the actual job is done by non-interactive command, working dir
+ state is restored to original.
+
+ In the end we'll record intresting changes, and everything else will be
+ left in place, so the user can continue his work.
+ """
+ if match.files():
+ changes = None
+ else:
+ changes = repo.status(match=match)[:3]
+ modified, added, removed = changes
+ match = cmdutil.matchfiles(repo, modified + added + removed)
+ diffopts = mdiff.diffopts(git=True, nodates=True)
+ chunks = patch.diff(repo, repo.dirstate.parents()[0], match=match,
+ changes=changes, opts=diffopts)
+ fp = cStringIO.StringIO()
+ fp.write(''.join(chunks))
+ fp.seek(0)
+
+ # 1. filter patch, so we have intending-to apply subset of it
+ if changes is not None:
+ chunks = filterpatch(opts, parsepatch(changes, fp), chunkselector)
+ else:
+ chgs = repo.status(match=match)[:3]
+ chunks = filterpatch(opts, parsepatch(chgs, fp))
+
+ del fp
+
+ contenders = {}
+ for h in chunks:
+ try: contenders.update(dict.fromkeys(h.files()))
+ except AttributeError: pass
+
+ newfiles = [f for f in match.files() if f in contenders]
+
+ if not newfiles:
+ ui.status(_('no changes to record\n'))
+ return 0
+
+ if changes is None:
+ match = cmdutil.matchfiles(repo, newfiles)
+ changes = repo.status(match=match)
+ modified = dict.fromkeys(changes[0])
+
+ # 2. backup changed files, so we can restore them in the end
+ backups = {}
+ backupdir = repo.join('record-backups')
+ try:
+ os.mkdir(backupdir)
+ except OSError, err:
+ if err.errno != errno.EEXIST:
+ raise
+ try:
+ # backup continues
+ for f in newfiles:
+ if f not in modified:
+ continue
+ fd, tmpname = tempfile.mkstemp(prefix=f.replace('/', '_')+'.',
+ dir=backupdir)
+ os.close(fd)
+ ui.debug(_('backup %r as %r\n') % (f, tmpname))
+ util.copyfile(repo.wjoin(f), tmpname)
+ backups[f] = tmpname
+
+ fp = cStringIO.StringIO()
+ for c in chunks:
+ if c.filename() in backups:
+ c.write(fp)
+ dopatch = fp.tell()
+ fp.seek(0)
+
+ # 3a. apply filtered patch to clean repo (clean)
+ if backups:
+ hg.revert(repo, repo.dirstate.parents()[0], backups.has_key)
+
+ # 3b. (apply)
+ if dopatch:
+ try:
+ ui.debug(_('applying patch\n'))
+ ui.debug(fp.getvalue())
+ patch.internalpatch(fp, ui, 1, repo.root)
+ except patch.PatchError, err:
+ s = str(err)
+ if s:
+ raise util.Abort(s)
+ else:
+ raise util.Abort(_('patch failed to apply'))
+ del fp
+
+ # 4. We prepared working directory according to filtered patch.
+ # Now is the time to delegate the job to commit/qrefresh or the like!
+
+ # it is important to first chdir to repo root -- we'll call a
+ # highlevel command with list of pathnames relative to repo root
+ cwd = os.getcwd()
+ os.chdir(repo.root)
+ try:
+ committer(ui, repo, newfiles, opts)
+ finally:
+ os.chdir(cwd)
+
+ return 0
+ finally:
+ # 5. finally restore backed-up files
+ try:
+ for realname, tmpname in backups.iteritems():
+ ui.debug(_('restoring %r to %r\n') % (tmpname, realname))
+ util.copyfile(tmpname, repo.wjoin(realname))
+ os.unlink(tmpname)
+ os.rmdir(backupdir)
+ except OSError:
+ pass
+ return cmdutil.commit(ui, repo, recordfunc, pats, opts)
+
+
+###### MAIN ENTRY POINTS FOR EXTENSION (crecord / qcrecord functions) ########
+
+def crecord(ui, repo, *pats, **opts):
+ '''interactively select changes to commit
+
+ If a list of files is omitted, all changes reported by "hg status"
+ will be candidates for recording.
+
+ See 'hg help dates' for a list of formats valid for -d/--date.
+
+ You will be shown a list of patch hunks from which you can select
+ those you would like to apply to the commit.
+
+ '''
+ def record_committer(ui, repo, pats, opts):
+ commands.commit(ui, repo, *pats, **opts)
+ dorecord(ui, repo, record_committer, *pats, **opts)
+
+
+def qcrecord(ui, repo, patch, *pats, **opts):
+ '''interactively record a new patch
+
+ see 'hg help qnew' & 'hg help record' for more information and usage
+ '''
+
+ try:
+ mq = extensions.find('mq')
+ except KeyError:
+ raise util.Abort(_("'mq' extension not loaded"))
+
+ def qrecord_committer(ui, repo, pats, opts):
+ mq.new(ui, repo, patch, *pats, **opts)
+
+ opts = opts.copy()
+ opts['force'] = True # always 'qnew -f'
+ dorecord(ui, repo, qrecord_committer, *pats, **opts)
View
BIN  .hgext/crecord/crecord/crecord_core.pyc
Binary file not shown
View
661 .hgext/crecord/crecord/crpatch.py
@@ -0,0 +1,661 @@
+# stuff related specifically to patch manipulation / parsing
+from mercurial.i18n import _
+from mercurial import patch
+
+import cStringIO
+import re
+
+lines_re = re.compile(r'@@ -(\d+),(\d+) \+(\d+),(\d+) @@\s*(.*)')
+
+def scanpatch(fp):
+ """like patch.iterhunks, but yield different events
+
+ - ('file', [header_lines + fromfile + tofile])
+ - ('context', [context_lines])
+ - ('hunk', [hunk_lines])
+ - ('range', (-start,len, +start,len, diffp))
+ """
+ lr = patch.linereader(fp)
+
+ def scanwhile(first, p):
+ """scan lr while predicate holds"""
+ lines = [first]
+ while True:
+ line = lr.readline()
+ if not line:
+ break
+ if p(line):
+ lines.append(line)
+ else:
+ lr.push(line)
+ break
+ return lines
+
+ while True:
+ line = lr.readline()
+ if not line:
+ break
+ if line.startswith('diff --git a/'):
+ def notheader(line):
+ s = line.split(None, 1)
+ return not s or s[0] not in ('---', 'diff')
+ header = scanwhile(line, notheader)
+ fromfile = lr.readline()
+ if fromfile.startswith('---'):
+ tofile = lr.readline()
+ header += [fromfile, tofile]
+ else:
+ lr.push(fromfile)
+ yield 'file', header
+ elif line[0] == ' ':
+ yield 'context', scanwhile(line, lambda l: l[0] in ' \\')
+ elif line[0] in '-+':
+ yield 'hunk', scanwhile(line, lambda l: l[0] in '-+\\')
+ else:
+ m = lines_re.match(line)
+ if m:
+ yield 'range', m.groups()
+ else:
+ raise patch.PatchError('unknown patch content: %r' % line)
+
+class PatchNode(object):
+ "Abstract Class for Patch Graph Nodes (i.e. PatchRoot, header, hunk, HunkLine)"
+
+ def firstChild(self):
+ raise NotImplementedError("method must be implemented by subclass")
+
+ def lastChild(self):
+ raise NotImplementedError("method must be implemented by subclass")
+
+ def allChildren(self):
+ "Return a list of all of the direct children of this node"
+ raise NotImplementedError("method must be implemented by subclass")
+ def nextSibling(self):
+ """
+ Return the closest next item of the same type where there are no items
+ of different types between the current item and this closest item.
+ If no such item exists, return None.
+
+ """
+ raise NotImplementedError("method must be implemented by subclass")
+
+ def prevSibling(self):
+ """
+ Return the closest previous item of the same type where there are no
+ items of different types between the current item and this closest item.
+ If no such item exists, return None.
+
+ """
+ raise NotImplementedError("method must be implemented by subclass")
+
+ def parentItem(self):
+ raise NotImplementedError("method must be implemented by subclass")
+
+
+ def nextItem(self, constrainLevel=True, skipFolded=True):
+ """
+ If constrainLevel == True, return the closest next item
+ of the same type where there are no items of different types between
+ the current item and this closest item.
+
+ If constrainLevel == False, then try to return the next item
+ closest to this item, regardless of item's type (header, hunk, or
+ HunkLine).
+
+ If skipFolded == True, and the current item is folded, then the child
+ items that are hidden due to folding will be skipped when determining
+ the next item.
+
+ If it is not possible to get the next item, return None.
+
+ """
+ try:
+ itemFolded = self.folded
+ except AttributeError:
+ itemFolded = False
+ if constrainLevel:
+ return self.nextSibling()
+ elif skipFolded and itemFolded:
+ nextItem = self.nextSibling()
+ if nextItem is None:
+ try:
+ nextItem = self.parentItem().nextSibling()
+ except AttributeError:
+ nextItem = None
+ return nextItem
+ else:
+ # try child
+ item = self.firstChild()
+ if item is not None:
+ return item
+
+ # else try next sibling
+ item = self.nextSibling()
+ if item is not None:
+ return item
+
+ try:
+ # else try parent's next sibling
+ item = self.parentItem().nextSibling()
+ if item is not None:
+ return item
+
+ # else return grandparent's next sibling (or None)
+ return self.parentItem().parentItem().nextSibling()
+
+ except AttributeError: # parent and/or grandparent was None
+ return None
+
+ def prevItem(self,