Monday Mini-Golf #2: Truncating long text

Pyth, 25 bytes

+WnzK<zeo}@zN" -"-Q2K"...

Try it online: Demonstration or Test Suite

Explanation:

+WnzK<zeo}@zN" -"-Q2K"...  implicit: z = input string, Q = input number
        o        -Q2       order the indices N in [0, 1, ..., Q-3] by
         }@zN" -"            z[T] in " -"
                           (hyphen-indices get sorted to the back)
       e                   take the last such number
     <z                    reduce z to length ^
    K                      save this string to K
+WnzK               K"...  print (K + "...") if z != K else only K

Perl, 69 59 52 bytes

51 bytes code + 1 byte command line. Assumes numerical input is allowed to be given with -i parameter.

s/.{$^I}\K.*//&&s/(^([^ -]*).|.*\K[ -].*)..$/$2.../

Usage:

echo "This-is-some-long-hyphen-separated-text." | perl -p -i"33" entry.pl

JavaScript (ES6), 123 78 67 61 bytes

I didn't expect to be able to cut this down so much, but it turns out the splice/replace combo is able to cover every case where truncation is needed.

(T,L)=>T[L]?T.slice(0,L-2).replace(/([ -][^ -]*|.)$/,'...'):T

First argument is the string, second is the length. Special thanks to edc65 for the length check optimization!

Here's the original code (123 bytes):

(T,L)=>(T.length>L?(S=T.slice(0,L)).slice(0,(m=Math.max(S.lastIndexOf` `,S.lastIndexOf`-`))<0?L-3:Math.min(L-3,m))+'...':T)