change color

change color

--- graphics/001-terrain-gen/viewer.coffee
+++ graphics/001-terrain-gen/viewer.coffee
@@ -16,7 +16,8 @@
     color = (height) ->
         r = 128
         b = 192
-        r = Math.floor(height / 64) if height > 8192
+        r = Math.floor(height / 52) if height > 8192
+        r = 255 if r > 255
         b = Math.floor(320 - height / 64) if height < 8192
         g = Math.floor((r + b) / 1.5)
         g = 255 if g > 255


Atom updates

Atom updates

--- etc/atom/config.cson
+++ etc/atom/config.cson
@@ -12,8 +12,7 @@
     fontSize: 14
     showIndentGuide: true
     softWrapAtPreferredLineLength: true
-    invisibles:
-      {}
+    invisibles: {}
   core:
     disabledPackages: [
       "Zen"
@@ -35,8 +34,7 @@
     js_jslint_happy: true
   linter:
     lintOnChange: false
-  "linter-jshint":
-    {}
+  "linter-jshint": {}
   "symbols-tree-view":
     autoToggle: true
   tabs:


make sure we never request a negative length, ever!

--- SingularityUI/app/actions/log.coffee
+++ SingularityUI/app/actions/log.coffee
@@ -3,6 +3,7 @@
 { fetchTasksForRequest } = require './activeTasks'

 fetchData = (taskId, path, offset=undefined, length=0) ->
+  length = Math.max(length, 0)  # API breaks if you request a negative length
   $.ajax
     url: "#{ config.apiRoot }/sandbox/#{ taskId }/read?#{$.param({path, length, offset})}"


Fetch initial controller data

Fetch initial controller data

--- SingularityUI/app/application.coffee
+++ SingularityUI/app/application.coffee
@@ -85,6 +85,7 @@

     bootstrapController: (controller) ->
         controller.initialize()
+        controller.refresh()
         @showView controller.view

     showView: (view) ->


:fire: leftover

:fire: leftover

--- lib/motion.coffee
+++ lib/motion.coffee
@@ -1,6 +1,5 @@
 _ = require 'underscore-plus'
 {Point, Range} = require 'atom'
-Select = null

 {
   moveCursorLeft, moveCursorRight


cleanup

cleanup

--- lib/motion.coffee
+++ lib/motion.coffee
@@ -129,8 +129,9 @@
     selection.modifySelection =>
       @moveWithSaveJump(cursor)

-    if not @isMode('visual') and not @is('CurrentSelection') and
-        (if @moveSucceeded? then not @moveSucceeded else selection.isEmpty())
+    moveSucceeded = @moveSucceeded ? not selection.isEmpty()
+
+    if not @isMode('visual') and not @is('CurrentSelection') and not moveSucceeded
       return
     return if not @isInclusive() and not @isLinewise()


fix URL to include base url; update fetch params

--- src/smc-hub/kucalc/compute-client.coffee
+++ src/smc-hub/kucalc/compute-client.coffee
@@ -424,17 +424,20 @@
                 dbg("starting project if necessary...")
                 @start(cb:cb)
             (cb) =>
-                url = "http://project-#{@project_id}:6001/.smc/directory_listing/#{opts.path}"
+                # TODO: This URL is obviously very specific to KuCalc -- hardcoded port and base url.
+                url = "http://project-#{@project_id}:6001/{@project_id}/raw/.smc/directory_listing/#{opts.path}"
                 dbg("fetching listing from '#{url}'")
                 if opts.hidden
                     url += '?hidden=true'
                 misc.retry_until_success
-                    f        : (cb) =>
+                    f           : (cb) =>
                         get_json url, (err, x) =>
                             dbg('fetch returned ', err, x)
                             listing = x
                             cb(err)
-                    max_time : 30000
+                    max_time    : 30000
+                    start_delay : 2000
+                    max_delay   : 7000
         ], (err) =>
             opts.cb(err, listing)
         )
@@ -445,7 +448,7 @@
             maxsize : 3000000    # maximum file size in bytes to read
             cb      : required   # cb(err, Buffer)
         dbg = @dbg("read_file(path:'#{opts.path}')")
-        dbg("read a file or directory from disk")  # directories get zip'd
+        dbg("read a file or directory from disk")
         opts.cb?("read_file -- not implemented")

     ###


fix how kucalc compute client sets action_request

--- src/smc-hub/kucalc/compute-client.coffee
+++ src/smc-hub/kucalc/compute-client.coffee
@@ -147,8 +147,9 @@
         @_query
             jsonb_set :
                 action_request :
-                    action  : opts.action
-                    started : new Date()
+                    action   : opts.action
+                    time     : new Date()
+                    started  : undefined
                     finished : undefined
             cb          : (err) =>
                 if err


project: handling hash signs in URLs for directory listings -- issue #2400

--- src/smc-project/directory-listing.coffee
+++ src/smc-project/directory-listing.coffee
@@ -22,7 +22,9 @@
 directory_listing_http_server = (base, router) ->

     router.get base + '*', (req, res) ->
-        path = decodeURI(req.path.slice(base.length).trim())
+        # decodeURIComponent because decodeURI(misc.encode_path('asdf/te #1/')) != 'asdf/te #1/'
+        # https://github.com/sagemathinc/cocalc/issues/2400
+        path = decodeURIComponent(req.path.slice(base.length).trim())
         hidden = req.query.hidden
         exports.get_listing1 path, hidden, (err, listing) ->
             if err


Remove unused setButtonStyle function

Remove unused setButtonStyle function

--- lib/components/buttons/buttonviewwithmenu.coffee
+++ lib/components/buttons/buttonviewwithmenu.coffee
@@ -70,14 +70,6 @@
   setTitle:(title)->
     @$button.append title

-  setButtonStyle:(newStyle)->
-    {styles} = @constructor
-    for style in styles
-      @$().removeClass style
-      @$button.removeClass style
-    @$button.addClass newStyle
-    @$().addClass newStyle
-
   setIconOnly:->
     @$button.addClass('icon-only').removeClass('with-icon')
     $icon = @$('span.icon')
@@ -86,4 +78,4 @@
   disable:->
     @$button.attr "disabled",yes
   enable:->
-    @$button.attr "disabled",no+    @$button.attr "disabled",no


Remove redundant text attribute condition

--- src/trix/config/text_attributes.coffee
+++ src/trix/config/text_attributes.coffee
@@ -3,7 +3,6 @@
     tagName: "strong"
     inheritable: true
     parser: (element) ->
-      return false if /H\d$/.test(element.tagName) or element.tagName is "BR"
       style = window.getComputedStyle(element)
       style["fontWeight"] is "bold" or style["fontWeight"] >= 600


Ensure there are two ranges to compare

Ensure there are two ranges to compare

--- src/trix/models/selection_manager.coffee
+++ src/trix/models/selection_manager.coffee
@@ -71,7 +71,7 @@
   # Selection observer delegate

   selectionDidChange: (range, previousRange) ->
-    if previousRange
+    if range and previousRange
       rangeChange = new Trix.DOMRangeChange({range, previousRange, @element})

     if rangeChange?.needsAdjustment()


Fix typo

Fix typo

--- lib/ripper.coffee
+++ lib/ripper.coffee
@@ -202,7 +202,7 @@

   parse: (code, callback) ->
     if config.getSettings()['coffee-refactor']? and code.length > config.getSettings()['coffee-refactor']['disable in large files (chars)']
-      console.warn 'coffe-refactor is disabled in large file: You can cange the threshold in preference pane.'
+      console.warn 'coffee-refactor is disabled in large file: You can cange the threshold in preference pane.'
       return

     try


runner: testcase teardown will executed on a fin branch

--- lib/runner.coffee
+++ lib/runner.coffee
@@ -48,8 +48,8 @@
     @_context = @testCase
       .setContext @_context
       .runTest()
-      .then => do @testCase.tearDown
       .fail @errorHandler
+      .fin => do @testCase.tearDown
       .then => do @runNextTest

     @_fileIndex++


Reformat link hint mode objects for easier diffs

This is a no-op.

--- content_scripts/link_hints.coffee
+++ content_scripts/link_hints.coffee
@@ -10,13 +10,20 @@
 #
 # The "name" property below is a short-form name to appear in the link-hints mode's name.  It's for debug only.
 #
-OPEN_IN_CURRENT_TAB = name: "curr-tab"
-OPEN_IN_NEW_BG_TAB = name: "bg-tab"
-OPEN_IN_NEW_FG_TAB = name: "fg-tab"
-OPEN_WITH_QUEUE = name: "queue"
-COPY_LINK_URL = name: "link"
-OPEN_INCOGNITO = name: "incognito"
-DOWNLOAD_LINK_URL = name: "download"
+OPEN_IN_CURRENT_TAB =
+  name: "curr-tab"
+OPEN_IN_NEW_BG_TAB =
+  name: "bg-tab"
+OPEN_IN_NEW_FG_TAB =
+  name: "fg-tab"
+OPEN_WITH_QUEUE =
+  name: "queue"
+COPY_LINK_URL =
+  name: "link"
+OPEN_INCOGNITO =
+  name: "incognito"
+DOWNLOAD_LINK_URL =
+  name: "download"

 LinkHints =
   activateMode: (count = 1, mode = OPEN_IN_CURRENT_TAB) ->


Set the eventType on the error object

Set the eventType on the error object

The handler needs access to it to display a nice message to the user.

--- src/file.coffee
+++ src/file.coffee
@@ -296,6 +296,7 @@

           handled = false
           handle = -> handled = true
+          error.eventType = eventType
           @emitter.emit('will-throw-watch-error', {error, handle})
           unless handled
             newError = new Error("Cannot read file after file `#{eventType}` event: #{@path}")


kd.Object: remove outdated chain method

kd.Object: remove outdated chain method

--- lib/core/object.coffee
+++ lib/core/object.coffee
@@ -93,8 +93,3 @@
     KD.deleteInstance @id
     # good idea but needs some refactoring
     # @[prop] = null  for own prop of this
-
-  chainNames:(options)->
-    options.chain
-    options.newLink
-    "#{options.chain}.#{options.newLink}"


gradual improvement

gradual improvement

--- lib/motion.coffee
+++ lib/motion.coffee
@@ -124,20 +124,18 @@
     tailRange = swrap(selection).getTailBufferRange()
     selection.modifySelection =>
       @moveCursor(cursor)
-
-      if @isMode('visual')
-        if cursorIsAtEndOfLineAtNonEmptyRow(cursor)
-          swrap(selection).translateSelectionEndAndClip('backward')
-      else
-        # Return here because no movement was happend, nothing to do.
-        return if cursor.getBufferPosition().isEqual(originalPoint)
-
-      unless selection.isReversed()
-        # When cursor is at empty row, we allow to wrap to next line
-        # since when we `v`, we have to select line.
-        swrap(selection).translateSelectionEndAndClip('forward', hello: 'in select inclusive')
-
-      swrap(selection).mergeBufferRange(tailRange, {preserveFolds: true})
+      cursorMoved = not cursor.getBufferPosition().isEqual(originalPoint)
+
+      if @isMode('visual') and cursorIsAtEndOfLineAtNonEmptyRow(cursor)
+        swrap(selection).translateSelectionEndAndClip('backward')
+
+      if @isMode('visual') or cursorMoved
+        unless selection.isReversed()
+          # When cursor is at empty row, we allow to wrap to next line
+          # since when we `v`, we have to select line.
+          swrap(selection).translateSelectionEndAndClip('forward', hello: 'in select inclusive')
+
+        swrap(selection).mergeBufferRange(tailRange, {preserveFolds: true})

 # Used as operator's target in visual-mode.


Social: check for message body , if contains any username

--- workers/social/lib/social/models/socialapi/message.coffee
+++ workers/social/lib/social/models/socialapi/message.coffee
@@ -91,10 +91,11 @@

   @sendPrivateMessage = permit 'send private message',
     success:  (client, data, callback)->
-      unless data.recipients?.length > 1
-        return callback message: "You should have at least one recipient"
       unless data.body
         return callback message: "Message body should be set"
+
+      unless data.body.match(/@([\w]+)/g)?.length > 0
+        return callback message: "You should have at least one recipient"
       SocialMessage.doRequest 'sendPrivateMessage', client, data, callback

   @fetchPrivateMessages = permit 'list private messages',


:art: cleanup

:art: cleanup

--- lib/motion.coffee
+++ lib/motion.coffee
@@ -938,14 +938,10 @@
   inclusive: true
   member: ["Parenthesis", "CurlyBracket", "SquareBracket"]

-  getRanges: (cursor) ->
-    {selection} = cursor
-    options = {enclosed: false, @member}
-    @new("AAnyPair", options).getRanges(selection).filter ({start, end}) ->
+  getRange: (cursor) ->
+    ranges = @new("AAnyPair", {enclosed: false, @member}).getRanges(cursor.selection)
+    ranges.filter ({start, end}) ->
       cursor.getBufferRow() in [start.row, end.row]
-
-  getRange: (cursor) ->
-    ranges = @getRanges(cursor)
     return null if ranges.length is 0

     [enclosingRanges, forwardingRanges] = _.partition ranges, (range) ->


remove console.log from spec

remove console.log from spec

--- test/canary-spec.coffee
+++ test/canary-spec.coffee
@@ -152,5 +152,4 @@
         expect(@triggerBPost.isDone).to.be.true

       it 'should have errors in stats', ->
-        console.log JSON.stringify @sut.canary.getCurrentStats(), null, 2
         expect(@sut.canary.getCurrentStats().errors?.length).to.equal 4


Update client.test.coffee

Update client.test.coffee

--- test/client.test.coffee
+++ test/client.test.coffee
@@ -5,7 +5,6 @@
 {MockPeer}      = require '../lib/ufo-mocks/peer.mock'
 {MockWebSocket} = require '../lib/ufo-mocks/websocket.mock'
 {MockList}      = require '../lib/ufo-mocks/list.mock'
-{EventEmitter}  = require 'events'

 ClientModule = null

@@ -324,4 +323,4 @@
     ClientModule.__set__ 'List', List

     testClient = new ClientModule.Client
-    testClient.densify()+    testClient.densify()


Minor: got rid of unnecessary fat arrow

Minor: got rid of unnecessary fat arrow

--- client/Login/AppView.coffee
+++ client/Login/AppView.coffee
@@ -407,7 +407,7 @@
                 title         : 'Let\'s go'
                 disabled      : yes

-    modal.once 'KDObjectWillBeDestroyed', =>
+    modal.once 'KDObjectWillBeDestroyed', ->
       mainView.unsetClass 'blur'
       form.button.hideLoader()


run digest after import

run digest after import

--- client/angular/setup.coffee
+++ client/angular/setup.coffee
@@ -101,6 +101,7 @@
 setupAngularDigest = ($rootScope, $injector) ->
   $browser = $injector.get('$browser')
   $timeout = $injector.get('$timeout')
+  Records.afterImport = -> $rootScope.$apply()
   Records.setRemoteCallbacks
     onPrepare: -> $browser.$$incOutstandingRequestCount()
     onCleanup: -> $browser.$$completeOutstandingRequest -> $timeout -> $rootScope.$apply()