Tape Measure String

Python, 50 48 47 46 bytes

f=lambda x:x*"1"if x<2else f(x-len(`-x`))+`-x`

Explanation

Pretty simple recursive lambda solution

Our base cases are 1 and 0 which are covered by "1"*x otherwise we get the string of -x with `-x` and prepend the result of calling the function on len(`-x`) less.


Mathematica, 67 57 bytes

Thanks to Martin Ender for jettisoning 10 bytes!

""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&

Unnamed function taking a nonnegative integer argument and returning a string. Pretty much the obvious recursive algorithm: make sure the string ends with the input number preceded by a "-", and then call the function again using #0.

But there's golfy fun to be had in implementing the algorithm. ""["1"][[#]] denotes the #th argument of the expression ""["1"]: the 0th argument is the head "" and the 1st argument is visibly "1", which provides the base cases of the recursion. If # exceeds 1, then ""["1"][[#]] throws an error message and remains as an unevaluated function. But then /._@__:> is a rule that takes any unevaluated function and transforms it into the expression that comes next, which is the recursive call to the original function.

Original submission:

If[#<2,""["1"][[#]],#0[#-1-IntegerLength@#]<>"-"<>IntegerString@#]&

JavaScript (ES6), 49 bytes

f=(n,s='',t=''+-n)=>n>1?f(n-t.length,t+s):n?n+s:s
<input type=number oninput=o.value=f(this.value)><br><textarea id=o></textarea>