Is there a straightforward way to just add a newli...
# ktor
d
Is there a straightforward way to just add a newline to the end of JSON responses (using Jackson serialization)? It's nice when using
curl
to have API responses end in newlines before the prompt. I don't see a way to teach a Jackson ObjectMapper to do that, so it seems like I'll need my own copy of JacksonConverter that just adds a single newline after calling
objectMapper.writeValue
, which seems like a lot?
I guess I can do like
Copy code
val MyMapperButWithTrailingNewlineAfterWriteValue = object : ObjectMapper(MyMapper) {
	override fun writeValue(out: OutputStream, value: Any?) {
		super.writeValue(out, value)
		out.write('\n'.code)
	}
}
b
I know for the kotlinx library you can specify pretty printing which includes a newline of memory serves.
d
Actually this doesn't even work because the super.writeValue call closes
out
e
Copy code
ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT)
d
@BryanT Hmm, good point, though we are pretty all in on Jackson in our codebase and I'm not sure switching to kotlinx.serialization for a single byte is worth it
b
What I stole from chatgpt, “Yes, by default the Jackson JSON parser adds a trailing newline character when pretty-printing JSON output. This behavior is controlled by the JsonGenerator.Feature.AUTO_CLOSE_TARGET configuration option, which is enabled by default.”
d
@ephemient Unless I'm confused, that does not add a trailing newline, though it does add lots of stuff in the middle of each object
Lol thanks ChatGPT.
b
What I had for Kotlinx, fun Application.configureSerialization() { install(ContentNegotiation) { json(Json { prettyPrint = true isLenient = true ignoreUnknownKeys = true }) }
d
(Admittedly, AUTO_CLOSE_TARGET is what I need to fix "Actually this doesn't even work because the super.writeValue call closes
out)
b
Gpt is great… unless it’s after 2021, or if it’s more technical than a code fragment, or if it gives out outdated information, or when it’s just plain wrong but answers as if it has 100% confidence.
d
Yeah it's actually sorta impressive that it stated something that is in a very tangential way related while still being not at all in the right universe of correct.
e
well, I think it's still easier to fix this client side
if you use zsh, it'll move the prompt to the next line by default if the previous command emitted a partial line, see
PROMPT_SP
and
PROMPT_EOL_MARK
d
This "works" by hardcoding the understanding of exactly what was printed
Copy code
val MyMapperButWithTrailingNewlineAfterWriteValue = object : ObjectMapper(MyMapper) {
	init {
		disable(AUTO_CLOSE_TARGET)
	}

	override fun writeValue(out: OutputStream, value: Any?) {
		super.writeValue(out, value)
		out.write('\n'.code)
		out.close()
	}
}
That's not a bad idea — I wonder if bash has something similar.
e
but is a single line of dense JSON really readable? I usually pipe
curl | jq
anyway, and then newlines don't matter
d
also fair but in this case it's a pretty small response.
Perhaps it is time to switch to bash. 20+ years of dotfiles and habits die hard...
e
what shell are you using now? really anything with customizable prompt can do this
personally I have
Copy code
__warn_missing_nl_start=$(tput -S 2>/dev/null <<END
sgr0
bold
setaf 1
END
) __warn_missing_nl_end=$(tput sgr0 2>/dev/null)
PROMPT_COMMAND="printf ${__warn_missing_nl_start@Q}'%-*s'${__warn_missing_nl_end@Q}'\\r' \"\${COLUMNS}\" '\\' 2>/dev/null${PROMPT_COMMAND:+; ${PROMPT_COMMAND}}"
in my
~/.bashrc
but really this can be customized to whatever you like