A related issue is that a continuation section uses `n by default. So the example code:
Code: Select all
FileAppend("
(
Line 1
Line 2
)", "test.txt")
Code: Select all
FileAppend("
(
Line 1
Line 2
)", "test.txt")
FileAppend defaults to no end-of-line translations, consistent with FileRead and FileOpen. FileAppend and FileRead both have a separate Options parameter [...]. FileAppend, FileRead and FileOpen use "`n" to enable end-of-line translations.
Source: Changes from v1.1 | AutoHotkey v2
I can barely understand what you mean, so can only guess as to why such a change wasn't made. The best explanation would probably be that I didn't even consider it; I certainly wouldn't know what you're hoping for if you didn't tell me. There was a ten year window during which such a suggestion could have been made. (Maybe it was, but I don't remember it.)just me wrote:I was hoping that v2 would get rid of the (IMO) useless EOL conversions and consistently use `r`n as EOL default.
`r`n has historically been sent as two individual Enter keystrokes (as per VkKeyScanEx for each character), although I changed that for Text mode (in v1). If `r`n was sent as a single Enter, `n vs `r`n wouldn't matter for hotstrings.Chris Mallett wrote: // The default is linefeed because:
// 1) It's the best choice for hotstrings, for which the line continuation mechanism is well suited.
// 2) It's good for FileAppend.
// 3) Minor: Saves memory in large sections by being only one character instead of two.
I think we should ignore what Windows do in this regard
Code: Select all
FileAppend
(
"this is
multiline
text that
will be appended"
), a_desktop "\test.txt", "`r" ; add CR to each new line
I dont think many functions are affected by this problem.lexikos wrote: ↑30 Nov 2023, 20:17If someone comes up with a comprehensive list of affected functions and changes needed to implement a coherent solution that satisfies everyone... I will be shocked.
@just me, I don't see any suggestions in that topic resembling what you hoped for, not that it would matter if there were.
I think I've already explained this. The pairing of FileAppend and FileRead is roughly equivalent to FileOpen followed by File.Write and File.Read. The option for FileRead is the same as for FileAppend and for FileOpen. The same logic applies to both pairs. A conversion is done to or from `n.RaptorX wrote: ↑01 Dec 2023, 15:11The other two on the other hand do something strange. When you specify the `n option you get `r`n which is somewhat unexpected.
What we are suggesting is that those two (I cant think of other functions that might benefit from this right now) take `r as the option to produce `r`n which seems a bit more logical.
Code: Select all
; This means open the file with LF line endings, but make sure to write CRLF.
f := FileOpen("temp.txt", "rw`n", "`r`n")
f := FileOpen("temp.txt", "r`n", "w`r`n") ; Maybe read and write can go in any of the two fields?
Code: Select all
FileAppend("string", "temp.txt", "`r`n") ; Write CRLF line endings
FileAppend("string", "temp.txt", "`n") ; Write LF line endings
FileAppend("string", "temp.txt", "`r") ; Write CR line endings
Code: Select all
Text := FileRead("temp.txt", "`n") ; Convert all line endings to LF
Text := FileRead("temp.txt", "`r") ; Convert all line endings to CR
Text := FileRead("temp.txt", "`r`n") ; Convert all line endings to CRLF
Code: Select all
Join`r`n ; joins with CRLF
Join`r ; joins with CR
Join`n ; joins with LF
I think this is the part that we find a bit odd (at least me and everyone who selected "yes" on the poll). When I say FileAppend text, 'file.ahk', 'UTF-8' I am not converting from UTF-8, but rather to UTF-8.
I have noticed that most of the back and forth that you and I usually have, centers around the difference in thinking between a programmer and a non-programmer.lexikos wrote: ↑08 Dec 2023, 22:04How and why were those who answered "yes" to "is the `n option "confusing"?" actually confused by the option? Were they actually even confused, or just lacking an understanding of the motivation behind the choice of character, especially after the topic title has drawn their attention to it? Is such an understanding necessary to remember and use the option effectively?
iseahound wrote: ↑09 Dec 2023, 16:07Code: Select all
; This means open the file with LF line endings, but make sure to write CRLF. f := FileOpen("temp.txt", "rw`n", "`r`n") f := FileOpen("temp.txt", "r`n", "w`r`n") ; Maybe read and write can go in any of the two fields?
Code: Select all
FileAppend("string", "temp.txt", "`r`n") ; Write CRLF line endings FileAppend("string", "temp.txt", "`n") ; Write LF line endings FileAppend("string", "temp.txt", "`r") ; Write CR line endings
This follows the current behavior of JoinCode: Select all
Text := FileRead("temp.txt", "`n") ; Convert all line endings to LF Text := FileRead("temp.txt", "`r") ; Convert all line endings to CR Text := FileRead("temp.txt", "`r`n") ; Convert all line endings to CRLF
Code: Select all
Join`r`n ; joins with CRLF Join`r ; joins with CR Join`n ; joins with LF
Code: Select all
FileAppend("string", "temp.txt", "`n") ; Write LF line endings
FileAppend("string", "temp.txt", "`r") ; Write CRLF line endings
FileOpenOptions
Type: String
`n (a linefeed character): Replaces any/all occurrences of carriage return & linefeed (`r`n) with linefeed (`n). (yep, totally expected and fair)
FileAppendEnd of line (EOL) options
Flag Dec Hex Description
`n 4 0x4 Replace `r`n with `n when reading and `n with `r`n when writing. (meh, i dont like it but i understand the logic here)
There is no consistency on what `n means between commands, and we are arguing, there should be. We shouldn't have to remember what `n means on each of the commands. If you change FileAppend's option to be EOL to mean "EOL conversion" it would make even more sense to me than `n having that meaning.Options
Type: String
`n (a linefeed character): Inserts a carriage return (`r) before each linefeed (`n) if one is not already present. (ok... lol what?!)
I understand that you mean that the `n option does a conversion in the three commands, but I think the results of that conversion varies between them, and that, is what is confusing to some of us.
You previously suggested to use `r as the option for producing `r`n, and yet "UTF-8 `r" would not convert to UTF-8 with `r as a line ending.
The default behaviour is to write whatever is given. If you want `n, you use that in the data being passed to the function. As a default behaviour, this has the least potential for surprise, and is the most efficient way to permit every kind of line ending. Defaulting to `n implies that the function will interpret and convert line endings by default. This may be unwanted, even if contrary behaviour hadn't already been established and documented.FileAppend would obviously default to one or the other. My preference is `n
The inconsistency you have demonstrated is merely in the wording of the documentation, not the meaning of the option.There is no consistency on what `n means between commands
Each option is logical within the appropriate context. Nothing can be taken out of context and retain its original meaning perfectly, by definition:In reality Join`n produces a string with `n but FileAppend with the `n option gives you a file with `r`n... And that's logical somehow.
What is not logical, is using a comparison between continuation sections (a language construct) and file I/O functions to argue that options in these disparate constructs aren't logical. You aren't just removing context, but changing the context to one which makes less sense.context: the circumstances that form the setting for an event, statement, or idea, and in terms of which it can be fully understood.
There are many more than two different ways of thinking. There are also non-programmers who properly exercise logic, and programmers who don't.I have noticed that most of the back and forth that you and I usually have, centers around the difference in thinking between a programmer and a non-programmer.
To me, "not strictly logical" is just irrational. You could arrive at a conclusion by intuitive leap, yet still rationalise and explain it with logic. If you don't understand why you arrived at a conclusion, how can you expect to communicate understanding to someone else?Most of the time, what im referring to, is not strictly logical
I don't think I did.What Lexikos is arguing is that it is irrelevant what letter we use for that option
Writing is the inverse of reading.iseahound wrote:For example, `n correctly replaces CRLF to LF when reading from an external file,but[and correctly] does the inverse when writing to the file.
Simplicity is to have a single line ending value which is either a known default or whatever the caller explicitly specified. Searching the file (if the file is even being opened with read access) adds complexity. Providing a default based on what line ending the script file uses adds more complexity, and potential for error. I see no reason to assume any there is any relation between the encoding of the script file and the encoding of the files it is processing.For simplicity, just search for the first instance of `r, `n, or `r`n. If none of these are present, the current encoding of the master script should be used instead?
In what way?RaptorX wrote:I think the results of that conversion varies between them
I'm suggesting that `r should insert `r in front of each new line. As opposed to `n inserting `r in front of each new line.
That is exactly my point. When writing code, context changes very often, in one line I'm creating a continuation section, in the next one I'm file appending. The fact that it makes "less sense" when we change the context is basically the point of the whole thread and why we want to change it so that it makes a "bit more sense".lexikos wrote: ↑16 Dec 2023, 02:22What is not logical, is using a comparison between continuation sections (a language construct) and file I/O functions to argue that options in these disparate constructs aren't logical. You aren't just removing context, but changing the context to one which makes less sense.
Completely agree.
Well, humans arent logical. We are quite irrational most of the time. I am trying to convey how that irrationality shows up in different parts of the language. It is really difficult to explain. You are biased toward strict logic. But when we are coding we dont really think strictly logically all the time.lexikos wrote: ↑16 Dec 2023, 02:22To me, "not strictly logical" is just irrational. You could arrive at a conclusion by intuitive leap, yet still rationalise and explain it with logic. If you don't understand why you arrived at a conclusion, how can you expect to communicate understanding to someone else?
Totally agree with you there.
I think you are missing my point: it has a lot to do with NOT thinking like a programmer.
Not directly but that is what you are suggesting when you say:
In the end it sounds like you are saying: Once you understand what `n does in that context, then it shouldn't confuse you.(Why) would it not be unexpected to specify `r and get `r`n? Or to specify `r and get `n, or for specifying `r to affect how `n in the data is interpreted?
Do you have trouble remembering that the option is `n? Would it be easier to remember something more arbitrary, like t or a numeric bitflag? Would such options be more or less "logical" than `n?
I hope you are not suggesting that contents := FileRead('path/to/file', 'UTF-8') would read an ANSI file and have it as UTF-8 in memory but thatWriting is the inverse of reading.
FileRead